fix(doctor): oMoMoMoMo branding, remove providers check, fix comment-checker detection

Rename header to oMoMoMoMo Doctor to match installation guide branding.
Remove providers check entirely — no longer meaningful for diagnostics.
Fix comment-checker detection by resolving @code-yeongyu/comment-checker package path
in addition to PATH lookup.
This commit is contained in:
YeonGyu-Kim
2026-02-13 17:35:36 +09:00
parent fe5c0ad8c2
commit 71eadc5a4b
12 changed files with 36 additions and 188 deletions
+21 -3
View File
@@ -1,3 +1,7 @@
import { existsSync } from "node:fs"
import { createRequire } from "node:module"
import { dirname, join } from "node:path"
import type { DependencyInfo } from "../types"
async function checkBinaryExists(binary: string): Promise<{ exists: boolean; path: string | null }> {
@@ -98,10 +102,24 @@ export async function checkAstGrepNapi(): Promise<DependencyInfo> {
}
}
function findCommentCheckerPackageBinary(): string | null {
const binaryName = process.platform === "win32" ? "comment-checker.exe" : "comment-checker"
try {
const require = createRequire(import.meta.url)
const pkgPath = require.resolve("@code-yeongyu/comment-checker/package.json")
const binaryPath = join(dirname(pkgPath), "bin", binaryName)
if (existsSync(binaryPath)) return binaryPath
} catch {
// intentionally empty - package not installed
}
return null
}
export async function checkCommentChecker(): Promise<DependencyInfo> {
const binaryCheck = await checkBinaryExists("comment-checker")
const resolvedPath = binaryCheck.exists ? binaryCheck.path : findCommentCheckerPackageBinary()
if (!binaryCheck.exists) {
if (!resolvedPath) {
return {
name: "Comment Checker",
required: false,
@@ -112,14 +130,14 @@ export async function checkCommentChecker(): Promise<DependencyInfo> {
}
}
const version = await getBinaryVersion("comment-checker")
const version = await getBinaryVersion(resolvedPath)
return {
name: "Comment Checker",
required: false,
installed: true,
version,
path: binaryCheck.path,
path: resolvedPath,
}
}
+1 -7
View File
@@ -2,13 +2,12 @@ import type { CheckDefinition } from "../types"
import { CHECK_IDS, CHECK_NAMES } from "../constants"
import { checkSystem, gatherSystemInfo } from "./system"
import { checkConfig } from "./config"
import { checkProviders, gatherProviderStatuses } from "./providers"
import { checkTools, gatherToolsSummary } from "./tools"
import { checkModels } from "./model-resolution"
export type { CheckDefinition }
export * from "./model-resolution-types"
export { gatherSystemInfo, gatherProviderStatuses, gatherToolsSummary }
export { gatherSystemInfo, gatherToolsSummary }
export function getAllCheckDefinitions(): CheckDefinition[] {
return [
@@ -23,11 +22,6 @@ export function getAllCheckDefinitions(): CheckDefinition[] {
name: CHECK_NAMES[CHECK_IDS.CONFIG],
check: checkConfig,
},
{
id: CHECK_IDS.PROVIDERS,
name: CHECK_NAMES[CHECK_IDS.PROVIDERS],
check: checkProviders,
},
{
id: CHECK_IDS.TOOLS,
name: CHECK_NAMES[CHECK_IDS.TOOLS],
-101
View File
@@ -1,101 +0,0 @@
import { existsSync, readFileSync } from "node:fs"
import { AGENT_MODEL_REQUIREMENTS } from "../../../shared/model-requirements"
import { getOpenCodeConfigPaths, parseJsonc } from "../../../shared"
import { AUTH_ENV_VARS, AUTH_PLUGINS, CHECK_IDS, CHECK_NAMES } from "../constants"
import type { CheckResult, DoctorIssue, ProviderStatus } from "../types"
interface OpenCodeConfigShape {
plugin?: string[]
}
function loadOpenCodePlugins(): string[] {
const configPaths = getOpenCodeConfigPaths({ binary: "opencode", version: null })
const targetPath = existsSync(configPaths.configJsonc)
? configPaths.configJsonc
: configPaths.configJson
if (!existsSync(targetPath)) return []
try {
const content = readFileSync(targetPath, "utf-8")
const parsed = parseJsonc<OpenCodeConfigShape>(content)
return parsed.plugin ?? []
} catch {
return []
}
}
function hasProviderPlugin(plugins: string[], providerId: string): boolean {
const definition = AUTH_PLUGINS[providerId]
if (!definition) return false
if (definition.plugin === "builtin") return true
return plugins.some((plugin) => plugin === definition.plugin || plugin.startsWith(`${definition.plugin}@`))
}
function hasProviderEnvVar(providerId: string): boolean {
const envVarNames = AUTH_ENV_VARS[providerId] ?? []
return envVarNames.some((envVarName) => Boolean(process.env[envVarName]))
}
function getAffectedAgents(providerId: string): string[] {
const affectedAgents: string[] = []
for (const [agentName, requirement] of Object.entries(AGENT_MODEL_REQUIREMENTS)) {
const usesProvider = requirement.fallbackChain.some((entry) => entry.providers.includes(providerId))
if (usesProvider) {
affectedAgents.push(agentName)
}
}
return affectedAgents
}
export function gatherProviderStatuses(): ProviderStatus[] {
const plugins = loadOpenCodePlugins()
return Object.entries(AUTH_PLUGINS).map(([providerId, definition]) => {
const hasPlugin = hasProviderPlugin(plugins, providerId)
const hasEnvVar = hasProviderEnvVar(providerId)
return {
id: providerId,
name: definition.name,
available: hasPlugin && hasEnvVar,
hasPlugin,
hasEnvVar,
}
})
}
export async function checkProviders(): Promise<CheckResult> {
const statuses = gatherProviderStatuses()
const issues: DoctorIssue[] = []
for (const status of statuses) {
if (status.available) continue
const missingParts: string[] = []
if (!status.hasPlugin) missingParts.push("auth plugin")
if (!status.hasEnvVar) missingParts.push("environment variable")
issues.push({
title: `${status.name} authentication missing`,
description: `Missing ${missingParts.join(" and ")} for ${status.name}.`,
fix: `Configure ${status.name} provider in OpenCode and set ${(AUTH_ENV_VARS[status.id] ?? []).join(" or ")}`,
affects: getAffectedAgents(status.id),
severity: "warning",
})
}
const status = issues.length === 0 ? "pass" : "warn"
return {
name: CHECK_NAMES[CHECK_IDS.PROVIDERS],
status,
message: issues.length === 0 ? "All provider auth checks passed" : `${issues.length} provider issue(s) detected`,
details: statuses.map(
(providerStatus) =>
`${providerStatus.name}: plugin=${providerStatus.hasPlugin ? "yes" : "no"}, env=${providerStatus.hasEnvVar ? "yes" : "no"}`
),
issues,
}
}