codealmanac 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMMERCIAL.md +9 -0
- package/LICENSE +133 -21
- package/README.md +2 -2
- package/dist/{agents-4Y7X24WW.js → agents-HYRWRHRX.js} +4 -4
- package/dist/{chunk-TT6ZP4GS.js → chunk-2BNDNGUR.js} +8 -4
- package/dist/{chunk-TT6ZP4GS.js.map → chunk-2BNDNGUR.js.map} +1 -1
- package/dist/{chunk-P5WGG4FJ.js → chunk-3E7JNMTZ.js} +28 -3
- package/dist/chunk-3E7JNMTZ.js.map +1 -0
- package/dist/{chunk-CW4HRLMS.js → chunk-DW32TL5W.js} +53 -11
- package/dist/chunk-DW32TL5W.js.map +1 -0
- package/dist/{chunk-UU6FBRQO.js → chunk-GPFVEF6V.js} +24 -6
- package/dist/chunk-GPFVEF6V.js.map +1 -0
- package/dist/{chunk-TILAKDN6.js → chunk-HJ3WREGP.js} +2 -2
- package/dist/{chunk-BF2J4XTC.js → chunk-J7DNV2DH.js} +219 -26
- package/dist/chunk-J7DNV2DH.js.map +1 -0
- package/dist/{chunk-H6QKCB7M.js → chunk-K2JBCB7R.js} +43 -7
- package/dist/chunk-K2JBCB7R.js.map +1 -0
- package/dist/{chunk-MRRX4UQB.js → chunk-ODJAAJGZ.js} +2 -2
- package/dist/{chunk-447U3GQJ.js → chunk-PDFS5VFE.js} +17 -5
- package/dist/chunk-PDFS5VFE.js.map +1 -0
- package/dist/{chunk-QRK3JLFX.js → chunk-VXDPUOQ5.js} +381 -126
- package/dist/chunk-VXDPUOQ5.js.map +1 -0
- package/dist/{cli-MYMZ66EN.js → cli-MKXCNEMW.js} +14 -14
- package/dist/codealmanac.js +1 -1
- package/dist/{config-ML2RCR7J.js → config-F7FKEQ7F.js} +3 -3
- package/dist/doctor-37UH3HT5.js +17 -0
- package/dist/{hook-2NP3UE7U.js → hook-4SVX446M.js} +4 -2
- package/dist/{register-commands-XTK2G2FB.js → register-commands-2F6SXLDI.js} +28 -19
- package/dist/register-commands-2F6SXLDI.js.map +1 -0
- package/dist/uninstall-C62ZOK32.js +17 -0
- package/dist/{update-P2IPG7RO.js → update-2UGOFN5C.js} +3 -3
- package/package.json +4 -3
- package/dist/chunk-447U3GQJ.js.map +0 -1
- package/dist/chunk-BF2J4XTC.js.map +0 -1
- package/dist/chunk-CW4HRLMS.js.map +0 -1
- package/dist/chunk-H6QKCB7M.js.map +0 -1
- package/dist/chunk-P5WGG4FJ.js.map +0 -1
- package/dist/chunk-QRK3JLFX.js.map +0 -1
- package/dist/chunk-UU6FBRQO.js.map +0 -1
- package/dist/doctor-W5KQQLAX.js +0 -17
- package/dist/register-commands-XTK2G2FB.js.map +0 -1
- package/dist/uninstall-N7JY7ZV2.js +0 -15
- /package/dist/{agents-4Y7X24WW.js.map → agents-HYRWRHRX.js.map} +0 -0
- /package/dist/{chunk-TILAKDN6.js.map → chunk-HJ3WREGP.js.map} +0 -0
- /package/dist/{chunk-MRRX4UQB.js.map → chunk-ODJAAJGZ.js.map} +0 -0
- /package/dist/{cli-MYMZ66EN.js.map → cli-MKXCNEMW.js.map} +0 -0
- /package/dist/{config-ML2RCR7J.js.map → config-F7FKEQ7F.js.map} +0 -0
- /package/dist/{doctor-W5KQQLAX.js.map → doctor-37UH3HT5.js.map} +0 -0
- /package/dist/{hook-2NP3UE7U.js.map → hook-4SVX446M.js.map} +0 -0
- /package/dist/{uninstall-N7JY7ZV2.js.map → uninstall-C62ZOK32.js.map} +0 -0
- /package/dist/{update-P2IPG7RO.js.map → update-2UGOFN5C.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/doctor-checks/format.ts","../src/commands/doctor-checks/install.ts","../src/commands/doctor-checks/probes.ts","../src/commands/doctor-checks/agents.ts","../src/commands/doctor-checks/updates.ts","../src/commands/doctor.ts"],"sourcesContent":["import { BLUE, BOLD, DIM, GREEN, RED, RST } from \"../../ansi.js\";\nimport type {\n AgentDoctorCheck,\n Check,\n CheckStatus,\n DoctorOptions,\n DoctorReport,\n} from \"./types.js\";\n\nexport function formatReport(\n report: DoctorReport,\n options: DoctorOptions,\n): string {\n const color = options.stdout === undefined && process.stdout.isTTY === true;\n const lines: string[] = [];\n lines.push(`codealmanac v${report.version}`);\n lines.push(\"\");\n if (report.install.length > 0) {\n lines.push(color ? `${BOLD}## Install${RST}` : \"## Install\");\n for (const c of report.install) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n if (report.agents.length > 0) {\n lines.push(color ? `${BOLD}## Agents${RST}` : \"## Agents\");\n for (const c of report.agents.map(agentToCheck)) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n if (report.updates.length > 0) {\n lines.push(color ? `${BOLD}## Updates${RST}` : \"## Updates\");\n for (const c of report.updates) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n if (report.wiki.length > 0) {\n lines.push(color ? `${BOLD}## Current wiki${RST}` : \"## Current wiki\");\n for (const c of report.wiki) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction agentToCheck(agent: AgentDoctorCheck): Check {\n const message = [\n agent.label,\n agent.selected ? \"(default)\" : null,\n agent.recommended ? \"(recommended)\" : null,\n agent.status === \"ok\" ? \"ready\" : readinessMessage(agent),\n `model: ${agent.model ?? \"provider default\"}`,\n agent.account,\n ].filter((part): part is string => part !== null).join(\" \");\n return {\n status: agent.status,\n key: `agents.${agent.id}`,\n message,\n fix: agent.fix,\n };\n}\n\nfunction readinessMessage(agent: AgentDoctorCheck): string {\n if (!agent.installed) return \"missing\";\n if (!agent.authenticated) return `not ready: ${agent.detail}`;\n return agent.detail;\n}\n\nfunction formatCheck(c: Check, color: boolean): string {\n const { icon, tint } = iconFor(c.status, color);\n const head = ` ${tint}${icon}${color ? RST : \"\"} ${c.message}`;\n if (c.fix === undefined) return head;\n const fixLine = color\n ? ` ${DIM}${c.fix}${RST}`\n : ` ${c.fix}`;\n return `${head}\\n${fixLine}`;\n}\n\nfunction iconFor(\n status: CheckStatus,\n color: boolean,\n): { icon: string; tint: string } {\n switch (status) {\n case \"ok\":\n return { icon: \"\\u2713\", tint: color ? GREEN : \"\" };\n case \"problem\":\n return { icon: \"\\u2717\", tint: color ? RED : \"\" };\n case \"info\":\n return { icon: \"\\u25c7\", tint: color ? BLUE : \"\" };\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\n\nimport type { ClaudeAuthStatus } from \"../../agent/providers/claude/index.js\";\nimport {\n hasCodexInstructions,\n resolveCodexAgentsPath,\n} from \"../../agent/providers/codex-instructions.js\";\nimport {\n IMPORT_LINE,\n} from \"../setup.js\";\nimport {\n classifyInstallPath,\n detectInstallPath,\n probeBetterSqlite3,\n safeCheckAuth,\n} from \"./probes.js\";\nimport type { Check, DoctorOptions } from \"./types.js\";\n\nexport async function gatherInstallChecks(\n options: DoctorOptions,\n): Promise<Check[]> {\n const checks: Check[] = [];\n\n const rawPath = options.installPath ?? detectInstallPath();\n const { installPath, isEphemeral } = classifyInstallPath(rawPath);\n checks.push(describeInstallPath(installPath, isEphemeral));\n\n const nodeVersion = options.nodeVersion ?? process.version;\n const sqlite = options.sqliteProbe ?? probeBetterSqlite3();\n checks.push({\n status: sqlite.ok ? \"ok\" : \"problem\",\n key: \"install.sqlite\",\n message: sqlite.ok\n ? `better-sqlite3 native binding OK (Node ${nodeVersion})`\n : `better-sqlite3 native binding failed: ${sqlite.summary}`,\n fix: sqlite.ok\n ? undefined\n : \"run: npm rebuild better-sqlite3 (in the install directory)\",\n });\n\n const auth = await safeCheckAuth(options.spawnCli);\n checks.push(describeAuth(auth));\n\n const settingsPath =\n options.settingsPath ?? path.join(homedir(), \".claude\", \"settings.json\");\n checks.push(await describeHook(settingsPath));\n\n const claudeDir = options.claudeDir ?? path.join(homedir(), \".claude\");\n checks.push(describeGuides(claudeDir));\n checks.push(await describeImportLine(claudeDir));\n const codexDir = options.codexDir ?? path.join(homedir(), \".codex\");\n checks.push(await describeCodexInstructions(codexDir));\n\n return checks;\n}\n\nfunction describeInstallPath(\n installPath: string | null,\n isEphemeral: boolean,\n): Check {\n if (installPath === null) {\n return {\n status: \"problem\",\n key: \"install.path\",\n message: \"could not detect codealmanac install path\",\n fix: \"reinstall with: npm install -g codealmanac\",\n };\n }\n return {\n status: isEphemeral ? \"info\" : \"ok\",\n key: \"install.path\",\n message: isEphemeral\n ? `codealmanac running from ephemeral npx location: ${installPath}`\n : `codealmanac installed at ${installPath}`,\n fix: isEphemeral\n ? \"run: npm install -g codealmanac (to make the install permanent)\"\n : undefined,\n };\n}\n\nfunction describeAuth(auth: ClaudeAuthStatus): Check {\n if (auth.loggedIn) {\n if (auth.authMethod === \"apiKey\") {\n return {\n status: \"ok\",\n key: \"install.auth\",\n message: \"claude auth: ANTHROPIC_API_KEY set\",\n };\n }\n const who = auth.email ?? \"Claude account\";\n const plan =\n auth.subscriptionType !== undefined\n ? ` (${auth.subscriptionType} subscription)`\n : \"\";\n return {\n status: \"ok\",\n key: \"install.auth\",\n message: `claude auth: ${who}${plan}`,\n };\n }\n if (\n process.env.ANTHROPIC_API_KEY !== undefined &&\n process.env.ANTHROPIC_API_KEY.length > 0\n ) {\n return {\n status: \"ok\",\n key: \"install.auth\",\n message: \"claude auth: ANTHROPIC_API_KEY set\",\n };\n }\n return {\n status: \"problem\",\n key: \"install.auth\",\n message: \"claude auth: not signed in\",\n fix: \"run: claude auth login --claudeai (or export ANTHROPIC_API_KEY)\",\n };\n}\n\nasync function describeHook(settingsPath: string): Promise<Check> {\n if (!existsSync(settingsPath)) {\n return {\n status: \"problem\",\n key: \"install.hook\",\n message: \"SessionEnd hook not installed\",\n fix: \"run: almanac setup --yes\",\n };\n }\n try {\n const raw = await readFile(settingsPath, \"utf8\");\n const parsed = JSON.parse(raw) as {\n hooks?: {\n SessionEnd?: {\n command?: string;\n hooks?: { command?: string }[];\n }[];\n };\n };\n const entries = parsed.hooks?.SessionEnd ?? [];\n const found = entries.some((e) => {\n if (\n typeof e?.command === \"string\" &&\n e.command.endsWith(\"almanac-capture.sh\")\n ) {\n return true;\n }\n if (Array.isArray(e?.hooks)) {\n return e.hooks.some(\n (h) =>\n typeof h?.command === \"string\" &&\n h.command.endsWith(\"almanac-capture.sh\"),\n );\n }\n return false;\n });\n if (!found) {\n return {\n status: \"problem\",\n key: \"install.hook\",\n message: \"SessionEnd hook not installed\",\n fix: \"run: almanac setup --yes\",\n };\n }\n return {\n status: \"ok\",\n key: \"install.hook\",\n message: `SessionEnd hook installed at ${settingsPath}`,\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"problem\",\n key: \"install.hook\",\n message: `could not read ${settingsPath}: ${msg}`,\n fix: \"check the file for malformed JSON\",\n };\n }\n}\n\nfunction describeGuides(claudeDir: string): Check {\n const mini = path.join(claudeDir, \"codealmanac.md\");\n const ref = path.join(claudeDir, \"codealmanac-reference.md\");\n const haveMini = existsSync(mini);\n const haveRef = existsSync(ref);\n if (haveMini && haveRef) {\n return {\n status: \"ok\",\n key: \"install.guides\",\n message: `Agent guides installed (${path.basename(mini)}, ${path.basename(ref)})`,\n };\n }\n const missing = [\n haveMini ? null : \"codealmanac.md\",\n haveRef ? null : \"codealmanac-reference.md\",\n ].filter((s): s is string => s !== null);\n return {\n status: \"problem\",\n key: \"install.guides\",\n message: `Agent guides missing (${missing.join(\", \")})`,\n fix: \"run: almanac setup --yes\",\n };\n}\n\nasync function describeImportLine(claudeDir: string): Promise<Check> {\n const claudeMd = path.join(claudeDir, \"CLAUDE.md\");\n if (!existsSync(claudeMd)) {\n return {\n status: \"problem\",\n key: \"install.import\",\n message: \"CLAUDE.md import not present (no ~/.claude/CLAUDE.md)\",\n fix: \"run: almanac setup --yes\",\n };\n }\n try {\n const contents = await readFile(claudeMd, \"utf8\");\n const lines = contents.split(/\\r?\\n/).map((l) => l.trim());\n const present = lines.some((line) => {\n if (line === IMPORT_LINE) return true;\n if (!line.startsWith(IMPORT_LINE)) return false;\n const next = line[IMPORT_LINE.length];\n return next === \" \" || next === \"\\t\";\n });\n if (present) {\n return {\n status: \"ok\",\n key: \"install.import\",\n message: \"CLAUDE.md import present\",\n };\n }\n return {\n status: \"problem\",\n key: \"install.import\",\n message: \"CLAUDE.md import line missing\",\n fix: \"run: almanac setup --yes\",\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"problem\",\n key: \"install.import\",\n message: `could not read ${claudeMd}: ${msg}`,\n };\n }\n}\n\nasync function describeCodexInstructions(codexDir: string): Promise<Check> {\n const agentsFile = await resolveCodexAgentsPath(codexDir);\n if (!existsSync(agentsFile)) {\n return {\n status: \"problem\",\n key: \"install.codexInstructions\",\n message: `Codex AGENTS instructions missing (${path.basename(agentsFile)} not found)`,\n fix: \"run: almanac setup --yes\",\n };\n }\n try {\n const contents = await readFile(agentsFile, \"utf8\");\n if (hasCodexInstructions(contents)) {\n return {\n status: \"ok\",\n key: \"install.codexInstructions\",\n message: `Codex AGENTS instructions present (${path.basename(agentsFile)})`,\n };\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"problem\",\n key: \"install.codexInstructions\",\n message: `could not read ${agentsFile}: ${msg}`,\n };\n }\n\n return {\n status: \"problem\",\n key: \"install.codexInstructions\",\n message: `Codex AGENTS instructions missing (${path.basename(agentsFile)})`,\n fix: \"run: almanac setup --yes\",\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport {\n checkClaudeAuth,\n type ClaudeAuthStatus,\n type SpawnCliFn,\n} from \"../../agent/providers/claude/index.js\";\nimport type { SqliteProbeResult } from \"./types.js\";\n\n// Single `createRequire` instance — used by package/binding probes.\nconst req = createRequire(import.meta.url);\n\n/**\n * Detect where codealmanac is installed by walking up from the running\n * module until we find a `package.json` whose `name` is `codealmanac`.\n */\nexport function detectInstallPath(): string | null {\n try {\n const here = fileURLToPath(import.meta.url);\n let dir = path.dirname(here);\n for (let i = 0; i < 6; i++) {\n const pkgPath = path.join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const raw = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw) as { name?: unknown };\n if (pkg.name === \"codealmanac\") return dir;\n } catch {\n // ignore — keep walking\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Classify the detected install path as permanent or ephemeral.\n * Ephemeral locations (npm npx cache, pnpm dlx cache, /tmp/) are valid\n * installs but will disappear when the cache is evicted or the machine\n * reboots. Doctor reports them as `info` rather than `ok`.\n */\nexport function classifyInstallPath(\n raw: string | null,\n): { installPath: string | null; isEphemeral: boolean } {\n if (raw === null) return { installPath: null, isEphemeral: false };\n const home = homedir();\n const ephemeralPrefixes = [\n path.join(home, \".npm\", \"_npx\"),\n path.join(home, \".local\", \"share\", \"pnpm\", \"dlx\"),\n \"/tmp/\",\n \"/var/folders/\",\n ];\n const isEphemeral = ephemeralPrefixes.some((p) => raw.startsWith(p));\n return { installPath: raw, isEphemeral };\n}\n\n/**\n * Probe the better-sqlite3 native binding by opening an in-memory DB.\n */\nexport function probeBetterSqlite3(): SqliteProbeResult {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const Database = req(\"better-sqlite3\") as typeof import(\"better-sqlite3\");\n const db = new Database(\":memory:\");\n db.close();\n return { ok: true, summary: \"native binding loads cleanly\" };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n const firstLine = msg.split(\"\\n\")[0] ?? msg;\n return { ok: false, summary: firstLine };\n }\n}\n\nexport async function safeCheckAuth(\n spawnCli?: SpawnCliFn,\n): Promise<ClaudeAuthStatus> {\n try {\n return await checkClaudeAuth(spawnCli);\n } catch {\n return { loggedIn: false };\n }\n}\n\nexport function readPackageVersion(): string | null {\n const candidates = [\n \"../../../package.json\",\n \"../../package.json\",\n \"../package.json\",\n ];\n for (const candidate of candidates) {\n try {\n const pkg = req(candidate) as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall through to the next runtime layout candidate.\n }\n }\n return null;\n}\n","import { buildProviderSetupView } from \"../../agent/provider-view.js\";\nimport { checkClaudeAuth } from \"../../agent/providers/claude/index.js\";\nimport type { ProviderStatus } from \"../../agent/types.js\";\nimport { isCursorEnabled } from \"../../update/config.js\";\nimport type { AgentDoctorCheck, DoctorOptions } from \"./types.js\";\n\nexport async function gatherAgentChecks(\n options: DoctorOptions,\n): Promise<AgentDoctorCheck[]> {\n const view = await buildProviderSetupView({\n spawnCli: options.spawnCli,\n statuses:\n options.providerStatuses ??\n (options.spawnCli === undefined\n ? undefined\n : await injectedProviderStatuses(options)),\n });\n return view.choices.map((choice) => {\n return {\n status: choice.ready ? \"ok\" : \"problem\",\n id: choice.id,\n label: choice.label,\n readiness: choice.readiness,\n selected: choice.selected,\n recommended: choice.recommended,\n installed: choice.installed,\n authenticated: choice.authenticated,\n model: choice.effectiveModel,\n providerDefaultModel: choice.providerDefaultModel,\n configuredModel: choice.configuredModel,\n account: choice.account,\n detail: choice.detail,\n fix: choice.fixCommand ?? undefined,\n };\n });\n}\n\nasync function injectedProviderStatuses(\n options: DoctorOptions,\n): Promise<ProviderStatus[]> {\n const auth = await checkClaudeAuth(options.spawnCli);\n const hasApiKey =\n process.env.ANTHROPIC_API_KEY !== undefined &&\n process.env.ANTHROPIC_API_KEY.length > 0;\n const claudeReady = auth.loggedIn || hasApiKey;\n const statuses: ProviderStatus[] = [\n {\n id: \"claude\",\n installed: true,\n authenticated: claudeReady,\n detail: claudeReady\n ? auth.email ?? (hasApiKey ? \"ANTHROPIC_API_KEY set\" : \"logged in\")\n : \"not logged in\",\n },\n {\n id: \"codex\",\n installed: false,\n authenticated: false,\n detail: \"codex status not injected\",\n },\n ];\n if (isCursorEnabled()) {\n statuses.push({\n id: \"cursor\",\n installed: false,\n authenticated: false,\n detail: \"cursor-agent status not injected\",\n });\n }\n return statuses;\n}\n","import { readConfig } from \"../../update/config.js\";\nimport { readStateForDoctor } from \"../../update/schedule.js\";\nimport { isNewer } from \"../../update/semver.js\";\nimport { formatDuration } from \"./duration.js\";\nimport type { Check, DoctorOptions } from \"./types.js\";\n\nexport async function gatherUpdateChecks(\n options: DoctorOptions,\n installedVersion: string,\n): Promise<Check[]> {\n const checks: Check[] = [];\n const state = readStateForDoctor(options.updateStatePath);\n const config = await readConfig(options.updateConfigPath);\n\n if (state === null || state.latest_version.length === 0) {\n checks.push({\n status: \"info\",\n key: \"update.status\",\n message: `on ${installedVersion}; no update check has run yet`,\n fix: \"run: almanac update --check\",\n });\n } else if (isNewer(state.latest_version, installedVersion)) {\n const dismissed = state.dismissed_versions.includes(state.latest_version)\n ? \" (dismissed — run `almanac update` to install anyway)\"\n : \"\";\n checks.push({\n status: \"problem\",\n key: \"update.status\",\n message:\n `${state.latest_version} available (you're on ${installedVersion})${dismissed}`,\n fix: \"run: almanac update\",\n });\n } else {\n checks.push({\n status: \"ok\",\n key: \"update.status\",\n message: `on latest (${installedVersion})`,\n });\n }\n\n if (state !== null && state.last_check_at > 0) {\n const now = (options.now?.() ?? new Date()).getTime();\n const ageMs = now - state.last_check_at * 1000;\n const failedSuffix =\n state.last_fetch_failed_at !== undefined &&\n state.last_fetch_failed_at === state.last_check_at\n ? \" (last attempt failed — will retry next invocation)\"\n : \"\";\n checks.push({\n status: \"info\",\n key: \"update.last_check\",\n message: `last checked: ${formatDuration(ageMs)} ago${failedSuffix}`,\n });\n } else {\n checks.push({\n status: \"info\",\n key: \"update.last_check\",\n message: \"last checked: never\",\n });\n }\n\n checks.push({\n status: \"info\",\n key: \"update.notifier\",\n message: `update notifier: ${config.update_notifier ? \"enabled\" : \"disabled\"}`,\n fix: config.update_notifier\n ? undefined\n : \"run: almanac config set update_notifier true\",\n });\n\n if (state !== null && state.dismissed_versions.length > 0) {\n checks.push({\n status: \"info\",\n key: \"update.dismissed\",\n message: `dismissed versions: ${state.dismissed_versions.join(\", \")}`,\n });\n }\n\n return checks;\n}\n","import { formatReport } from \"./doctor-checks/format.js\";\nimport { gatherInstallChecks } from \"./doctor-checks/install.js\";\nimport { readPackageVersion } from \"./doctor-checks/probes.js\";\nimport type {\n Check,\n CheckStatus,\n AgentDoctorCheck,\n DoctorOptions,\n DoctorReport,\n DoctorResult,\n SqliteProbeResult,\n} from \"./doctor-checks/types.js\";\nimport { gatherAgentChecks } from \"./doctor-checks/agents.js\";\nimport { gatherUpdateChecks } from \"./doctor-checks/updates.js\";\n\nexport type {\n Check,\n CheckStatus,\n DoctorOptions,\n DoctorReport,\n DoctorResult,\n SqliteProbeResult,\n};\n\n/**\n * `almanac doctor` — install + wiki health report.\n *\n * Separate from `almanac health` (which checks graph integrity of a\n * specific wiki). `doctor` answers the \"is this install even set up\n * correctly?\" question that users hit when first trying the tool or when\n * sessions silently stop getting captured.\n *\n * This file is the command composition root. The section-specific probes\n * and formatting live in `doctor-checks/` so each durable fact has one\n * obvious owner.\n */\nexport async function runDoctor(\n options: DoctorOptions,\n): Promise<DoctorResult> {\n const version =\n options.versionOverride ?? readPackageVersion() ?? \"unknown\";\n\n const install: Check[] = options.wikiOnly === true\n ? []\n : await gatherInstallChecks(options);\n\n const agents: AgentDoctorCheck[] = options.wikiOnly === true\n ? []\n : await gatherAgentChecks(options);\n\n const updates: Check[] = options.wikiOnly === true\n ? []\n : await gatherUpdateChecks(options, version);\n\n const wiki: Check[] = options.installOnly === true\n ? []\n : await safeGatherWikiChecks(options);\n\n const report: DoctorReport = { version, install, agents, updates, wiki };\n\n if (options.json === true) {\n return {\n stdout: `${JSON.stringify(report, null, 2)}\\n`,\n stderr: \"\",\n exitCode: 0,\n };\n }\n\n return {\n stdout: formatReport(report, options),\n stderr: \"\",\n exitCode: 0,\n };\n}\n\nasync function safeGatherWikiChecks(\n options: DoctorOptions,\n): Promise<Check[]> {\n try {\n const { gatherWikiChecks } = await import(\"./doctor-checks/wiki.js\");\n return await gatherWikiChecks(options);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return [\n {\n status: \"problem\",\n key: \"wiki.checks\",\n message: `could not run wiki checks: ${msg.split(\"\\n\")[0] ?? msg}`,\n fix: \"run: npm rebuild better-sqlite3 (in the install directory)\",\n },\n ];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASO,SAAS,aACd,QACA,SACQ;AACR,QAAM,QAAQ,QAAQ,WAAW,UAAa,QAAQ,OAAO,UAAU;AACvE,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,gBAAgB,OAAO,OAAO,EAAE;AAC3C,QAAM,KAAK,EAAE;AACb,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,UAAM,KAAK,QAAQ,GAAG,IAAI,aAAa,GAAG,KAAK,YAAY;AAC3D,eAAW,KAAK,OAAO,SAAS;AAC9B,YAAM,KAAK,YAAY,GAAG,KAAK,CAAC;AAAA,IAClC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,KAAK,QAAQ,GAAG,IAAI,YAAY,GAAG,KAAK,WAAW;AACzD,eAAW,KAAK,OAAO,OAAO,IAAI,YAAY,GAAG;AAC/C,YAAM,KAAK,YAAY,GAAG,KAAK,CAAC;AAAA,IAClC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,UAAM,KAAK,QAAQ,GAAG,IAAI,aAAa,GAAG,KAAK,YAAY;AAC3D,eAAW,KAAK,OAAO,SAAS;AAC9B,YAAM,KAAK,YAAY,GAAG,KAAK,CAAC;AAAA,IAClC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,OAAO,KAAK,SAAS,GAAG;AAC1B,UAAM,KAAK,QAAQ,GAAG,IAAI,kBAAkB,GAAG,KAAK,iBAAiB;AACrE,eAAW,KAAK,OAAO,MAAM;AAC3B,YAAM,KAAK,YAAY,GAAG,KAAK,CAAC;AAAA,IAClC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAC5B;AAEA,SAAS,aAAa,OAAgC;AACpD,QAAM,UAAU;AAAA,IACd,MAAM;AAAA,IACN,MAAM,WAAW,cAAc;AAAA,IAC/B,MAAM,cAAc,kBAAkB;AAAA,IACtC,MAAM,WAAW,OAAO,UAAU,iBAAiB,KAAK;AAAA,IACxD,UAAU,MAAM,SAAS,kBAAkB;AAAA,IAC3C,MAAM;AAAA,EACR,EAAE,OAAO,CAAC,SAAyB,SAAS,IAAI,EAAE,KAAK,GAAG;AAC1D,SAAO;AAAA,IACL,QAAQ,MAAM;AAAA,IACd,KAAK,UAAU,MAAM,EAAE;AAAA,IACvB;AAAA,IACA,KAAK,MAAM;AAAA,EACb;AACF;AAEA,SAAS,iBAAiB,OAAiC;AACzD,MAAI,CAAC,MAAM,UAAW,QAAO;AAC7B,MAAI,CAAC,MAAM,cAAe,QAAO,cAAc,MAAM,MAAM;AAC3D,SAAO,MAAM;AACf;AAEA,SAAS,YAAY,GAAU,OAAwB;AACrD,QAAM,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,QAAQ,KAAK;AAC9C,QAAM,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,QAAQ,MAAM,EAAE,IAAI,EAAE,OAAO;AAC7D,MAAI,EAAE,QAAQ,OAAW,QAAO;AAChC,QAAM,UAAU,QACZ,OAAO,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,KACxB,OAAO,EAAE,GAAG;AAChB,SAAO,GAAG,IAAI;AAAA,EAAK,OAAO;AAC5B;AAEA,SAAS,QACP,QACA,OACgC;AAChC,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,EAAE,MAAM,UAAU,MAAM,QAAQ,QAAQ,GAAG;AAAA,IACpD,KAAK;AACH,aAAO,EAAE,MAAM,UAAU,MAAM,QAAQ,MAAM,GAAG;AAAA,IAClD,KAAK;AACH,aAAO,EAAE,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG;AAAA,EACrD;AACF;;;AC7FA,SAAS,cAAAA,mBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,WAAAC,gBAAe;AACxB,OAAOC,WAAU;;;ACHjB,SAAS,YAAY,oBAAoB;AACzC,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAU9B,IAAM,MAAM,cAAc,YAAY,GAAG;AAMlC,SAAS,oBAAmC;AACjD,MAAI;AACF,UAAM,OAAO,cAAc,YAAY,GAAG;AAC1C,QAAI,MAAM,KAAK,QAAQ,IAAI;AAC3B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,UAAU,KAAK,KAAK,KAAK,cAAc;AAC7C,UAAI,WAAW,OAAO,GAAG;AACvB,YAAI;AACF,gBAAM,MAAM,aAAa,SAAS,OAAO;AACzC,gBAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,cAAI,IAAI,SAAS,cAAe,QAAO;AAAA,QACzC,QAAQ;AAAA,QAER;AAAA,MACF;AACA,YAAM,SAAS,KAAK,QAAQ,GAAG;AAC/B,UAAI,WAAW,IAAK;AACpB,YAAM;AAAA,IACR;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,SAAS,oBACd,KACsD;AACtD,MAAI,QAAQ,KAAM,QAAO,EAAE,aAAa,MAAM,aAAa,MAAM;AACjE,QAAM,OAAO,QAAQ;AACrB,QAAM,oBAAoB;AAAA,IACxB,KAAK,KAAK,MAAM,QAAQ,MAAM;AAAA,IAC9B,KAAK,KAAK,MAAM,UAAU,SAAS,QAAQ,KAAK;AAAA,IAChD;AAAA,IACA;AAAA,EACF;AACA,QAAM,cAAc,kBAAkB,KAAK,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC;AACnE,SAAO,EAAE,aAAa,KAAK,YAAY;AACzC;AAKO,SAAS,qBAAwC;AACtD,MAAI;AAEF,UAAM,WAAW,IAAI,gBAAgB;AACrC,UAAM,KAAK,IAAI,SAAS,UAAU;AAClC,OAAG,MAAM;AACT,WAAO,EAAE,IAAI,MAAM,SAAS,+BAA+B;AAAA,EAC7D,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAM,YAAY,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK;AACxC,WAAO,EAAE,IAAI,OAAO,SAAS,UAAU;AAAA,EACzC;AACF;AAEA,eAAsB,cACpB,UAC2B;AAC3B,MAAI;AACF,WAAO,MAAM,gBAAgB,QAAQ;AAAA,EACvC,QAAQ;AACN,WAAO,EAAE,UAAU,MAAM;AAAA,EAC3B;AACF;AAEO,SAAS,qBAAoC;AAClD,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,aAAa,YAAY;AAClC,QAAI;AACF,YAAM,MAAM,IAAI,SAAS;AACzB,UAAI,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,SAAS,GAAG;AAC7D,eAAO,IAAI;AAAA,MACb;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;;;ADzFA,eAAsB,oBACpB,SACkB;AAClB,QAAM,SAAkB,CAAC;AAEzB,QAAM,UAAU,QAAQ,eAAe,kBAAkB;AACzD,QAAM,EAAE,aAAa,YAAY,IAAI,oBAAoB,OAAO;AAChE,SAAO,KAAK,oBAAoB,aAAa,WAAW,CAAC;AAEzD,QAAM,cAAc,QAAQ,eAAe,QAAQ;AACnD,QAAM,SAAS,QAAQ,eAAe,mBAAmB;AACzD,SAAO,KAAK;AAAA,IACV,QAAQ,OAAO,KAAK,OAAO;AAAA,IAC3B,KAAK;AAAA,IACL,SAAS,OAAO,KACZ,0CAA0C,WAAW,MACrD,yCAAyC,OAAO,OAAO;AAAA,IAC3D,KAAK,OAAO,KACR,SACA;AAAA,EACN,CAAC;AAED,QAAM,OAAO,MAAM,cAAc,QAAQ,QAAQ;AACjD,SAAO,KAAK,aAAa,IAAI,CAAC;AAE9B,QAAM,eACJ,QAAQ,gBAAgBC,MAAK,KAAKC,SAAQ,GAAG,WAAW,eAAe;AACzE,SAAO,KAAK,MAAM,aAAa,YAAY,CAAC;AAE5C,QAAM,YAAY,QAAQ,aAAaD,MAAK,KAAKC,SAAQ,GAAG,SAAS;AACrE,SAAO,KAAK,eAAe,SAAS,CAAC;AACrC,SAAO,KAAK,MAAM,mBAAmB,SAAS,CAAC;AAC/C,QAAM,WAAW,QAAQ,YAAYD,MAAK,KAAKC,SAAQ,GAAG,QAAQ;AAClE,SAAO,KAAK,MAAM,0BAA0B,QAAQ,CAAC;AAErD,SAAO;AACT;AAEA,SAAS,oBACP,aACA,aACO;AACP,MAAI,gBAAgB,MAAM;AACxB,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AAAA,EACF;AACA,SAAO;AAAA,IACL,QAAQ,cAAc,SAAS;AAAA,IAC/B,KAAK;AAAA,IACL,SAAS,cACL,oDAAoD,WAAW,KAC/D,4BAA4B,WAAW;AAAA,IAC3C,KAAK,cACD,qEACA;AAAA,EACN;AACF;AAEA,SAAS,aAAa,MAA+B;AACnD,MAAI,KAAK,UAAU;AACjB,QAAI,KAAK,eAAe,UAAU;AAChC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,SAAS;AAAA,MACX;AAAA,IACF;AACA,UAAM,MAAM,KAAK,SAAS;AAC1B,UAAM,OACJ,KAAK,qBAAqB,SACtB,KAAK,KAAK,gBAAgB,mBAC1B;AACN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,gBAAgB,GAAG,GAAG,IAAI;AAAA,IACrC;AAAA,EACF;AACA,MACE,QAAQ,IAAI,sBAAsB,UAClC,QAAQ,IAAI,kBAAkB,SAAS,GACvC;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS;AAAA,IACX;AAAA,EACF;AACA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS;AAAA,IACT,KAAK;AAAA,EACP;AACF;AAEA,eAAe,aAAa,cAAsC;AAChE,MAAI,CAACC,YAAW,YAAY,GAAG;AAC7B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AAAA,EACF;AACA,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,cAAc,MAAM;AAC/C,UAAM,SAAS,KAAK,MAAM,GAAG;AAQ7B,UAAM,UAAU,OAAO,OAAO,cAAc,CAAC;AAC7C,UAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM;AAChC,UACE,OAAO,GAAG,YAAY,YACtB,EAAE,QAAQ,SAAS,oBAAoB,GACvC;AACA,eAAO;AAAA,MACT;AACA,UAAI,MAAM,QAAQ,GAAG,KAAK,GAAG;AAC3B,eAAO,EAAE,MAAM;AAAA,UACb,CAAC,MACC,OAAO,GAAG,YAAY,YACtB,EAAE,QAAQ,SAAS,oBAAoB;AAAA,QAC3C;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC;AACD,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,SAAS;AAAA,QACT,KAAK;AAAA,MACP;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,gCAAgC,YAAY;AAAA,IACvD;AAAA,EACF,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,kBAAkB,YAAY,KAAK,GAAG;AAAA,MAC/C,KAAK;AAAA,IACP;AAAA,EACF;AACF;AAEA,SAAS,eAAe,WAA0B;AAChD,QAAM,OAAOF,MAAK,KAAK,WAAW,gBAAgB;AAClD,QAAM,MAAMA,MAAK,KAAK,WAAW,0BAA0B;AAC3D,QAAM,WAAWE,YAAW,IAAI;AAChC,QAAM,UAAUA,YAAW,GAAG;AAC9B,MAAI,YAAY,SAAS;AACvB,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,2BAA2BF,MAAK,SAAS,IAAI,CAAC,KAAKA,MAAK,SAAS,GAAG,CAAC;AAAA,IAChF;AAAA,EACF;AACA,QAAM,UAAU;AAAA,IACd,WAAW,OAAO;AAAA,IAClB,UAAU,OAAO;AAAA,EACnB,EAAE,OAAO,CAAC,MAAmB,MAAM,IAAI;AACvC,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS,yBAAyB,QAAQ,KAAK,IAAI,CAAC;AAAA,IACpD,KAAK;AAAA,EACP;AACF;AAEA,eAAe,mBAAmB,WAAmC;AACnE,QAAM,WAAWA,MAAK,KAAK,WAAW,WAAW;AACjD,MAAI,CAACE,YAAW,QAAQ,GAAG;AACzB,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AAAA,EACF;AACA,MAAI;AACF,UAAM,WAAW,MAAM,SAAS,UAAU,MAAM;AAChD,UAAM,QAAQ,SAAS,MAAM,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACzD,UAAM,UAAU,MAAM,KAAK,CAAC,SAAS;AACnC,UAAI,SAAS,YAAa,QAAO;AACjC,UAAI,CAAC,KAAK,WAAW,WAAW,EAAG,QAAO;AAC1C,YAAM,OAAO,KAAK,YAAY,MAAM;AACpC,aAAO,SAAS,OAAO,SAAS;AAAA,IAClC,CAAC;AACD,QAAI,SAAS;AACX,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,SAAS;AAAA,MACX;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AAAA,EACF,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,kBAAkB,QAAQ,KAAK,GAAG;AAAA,IAC7C;AAAA,EACF;AACF;AAEA,eAAe,0BAA0B,UAAkC;AACzE,QAAM,aAAa,MAAM,uBAAuB,QAAQ;AACxD,MAAI,CAACA,YAAW,UAAU,GAAG;AAC3B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,sCAAsCF,MAAK,SAAS,UAAU,CAAC;AAAA,MACxE,KAAK;AAAA,IACP;AAAA,EACF;AACA,MAAI;AACF,UAAM,WAAW,MAAM,SAAS,YAAY,MAAM;AAClD,QAAI,qBAAqB,QAAQ,GAAG;AAClC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,SAAS,sCAAsCA,MAAK,SAAS,UAAU,CAAC;AAAA,MAC1E;AAAA,IACF;AAAA,EACF,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,kBAAkB,UAAU,KAAK,GAAG;AAAA,IAC/C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS,sCAAsCA,MAAK,SAAS,UAAU,CAAC;AAAA,IACxE,KAAK;AAAA,EACP;AACF;;;AEnRA,eAAsB,kBACpB,SAC6B;AAC7B,QAAM,OAAO,MAAM,uBAAuB;AAAA,IACxC,UAAU,QAAQ;AAAA,IAClB,UACE,QAAQ,qBACP,QAAQ,aAAa,SAClB,SACA,MAAM,yBAAyB,OAAO;AAAA,EAC9C,CAAC;AACD,SAAO,KAAK,QAAQ,IAAI,CAAC,WAAW;AAClC,WAAO;AAAA,MACL,QAAQ,OAAO,QAAQ,OAAO;AAAA,MAC9B,IAAI,OAAO;AAAA,MACX,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,UAAU,OAAO;AAAA,MACjB,aAAa,OAAO;AAAA,MACpB,WAAW,OAAO;AAAA,MAClB,eAAe,OAAO;AAAA,MACtB,OAAO,OAAO;AAAA,MACd,sBAAsB,OAAO;AAAA,MAC7B,iBAAiB,OAAO;AAAA,MACxB,SAAS,OAAO;AAAA,MAChB,QAAQ,OAAO;AAAA,MACf,KAAK,OAAO,cAAc;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;AAEA,eAAe,yBACb,SAC2B;AAC3B,QAAM,OAAO,MAAM,gBAAgB,QAAQ,QAAQ;AACnD,QAAM,YACJ,QAAQ,IAAI,sBAAsB,UAClC,QAAQ,IAAI,kBAAkB,SAAS;AACzC,QAAM,cAAc,KAAK,YAAY;AACrC,QAAM,WAA6B;AAAA,IACjC;AAAA,MACE,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,eAAe;AAAA,MACf,QAAQ,cACJ,KAAK,UAAU,YAAY,0BAA0B,eACrD;AAAA,IACN;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,eAAe;AAAA,MACf,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI,gBAAgB,GAAG;AACrB,aAAS,KAAK;AAAA,MACZ,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,eAAe;AAAA,MACf,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;AChEA,eAAsB,mBACpB,SACA,kBACkB;AAClB,QAAM,SAAkB,CAAC;AACzB,QAAM,QAAQ,mBAAmB,QAAQ,eAAe;AACxD,QAAM,SAAS,MAAM,WAAW,QAAQ,gBAAgB;AAExD,MAAI,UAAU,QAAQ,MAAM,eAAe,WAAW,GAAG;AACvD,WAAO,KAAK;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,MAAM,gBAAgB;AAAA,MAC/B,KAAK;AAAA,IACP,CAAC;AAAA,EACH,WAAW,QAAQ,MAAM,gBAAgB,gBAAgB,GAAG;AAC1D,UAAM,YAAY,MAAM,mBAAmB,SAAS,MAAM,cAAc,IACpE,+DACA;AACJ,WAAO,KAAK;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SACE,GAAG,MAAM,cAAc,yBAAyB,gBAAgB,IAAI,SAAS;AAAA,MAC/E,KAAK;AAAA,IACP,CAAC;AAAA,EACH,OAAO;AACL,WAAO,KAAK;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,cAAc,gBAAgB;AAAA,IACzC,CAAC;AAAA,EACH;AAEA,MAAI,UAAU,QAAQ,MAAM,gBAAgB,GAAG;AAC7C,UAAM,OAAO,QAAQ,MAAM,KAAK,oBAAI,KAAK,GAAG,QAAQ;AACpD,UAAM,QAAQ,MAAM,MAAM,gBAAgB;AAC1C,UAAM,eACJ,MAAM,yBAAyB,UAC/B,MAAM,yBAAyB,MAAM,gBACjC,6DACA;AACN,WAAO,KAAK;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,iBAAiB,eAAe,KAAK,CAAC,OAAO,YAAY;AAAA,IACpE,CAAC;AAAA,EACH,OAAO;AACL,WAAO,KAAK;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,SAAO,KAAK;AAAA,IACV,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS,oBAAoB,OAAO,kBAAkB,YAAY,UAAU;AAAA,IAC5E,KAAK,OAAO,kBACR,SACA;AAAA,EACN,CAAC;AAED,MAAI,UAAU,QAAQ,MAAM,mBAAmB,SAAS,GAAG;AACzD,WAAO,KAAK;AAAA,MACV,QAAQ;AAAA,MACR,KAAK;AAAA,MACL,SAAS,uBAAuB,MAAM,mBAAmB,KAAK,IAAI,CAAC;AAAA,IACrE,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC3CA,eAAsB,UACpB,SACuB;AACvB,QAAM,UACJ,QAAQ,mBAAmB,mBAAmB,KAAK;AAErD,QAAM,UAAmB,QAAQ,aAAa,OAC1C,CAAC,IACD,MAAM,oBAAoB,OAAO;AAErC,QAAM,SAA6B,QAAQ,aAAa,OACpD,CAAC,IACD,MAAM,kBAAkB,OAAO;AAEnC,QAAM,UAAmB,QAAQ,aAAa,OAC1C,CAAC,IACD,MAAM,mBAAmB,SAAS,OAAO;AAE7C,QAAM,OAAgB,QAAQ,gBAAgB,OAC1C,CAAC,IACD,MAAM,qBAAqB,OAAO;AAEtC,QAAM,SAAuB,EAAE,SAAS,SAAS,QAAQ,SAAS,KAAK;AAEvE,MAAI,QAAQ,SAAS,MAAM;AACzB,WAAO;AAAA,MACL,QAAQ,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA;AAAA,MAC1C,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,aAAa,QAAQ,OAAO;AAAA,IACpC,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACF;AAEA,eAAe,qBACb,SACkB;AAClB,MAAI;AACF,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,oBAAyB;AACnE,WAAO,MAAM,iBAAiB,OAAO;AAAA,EACvC,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,WAAO;AAAA,MACL;AAAA,QACE,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,SAAS,8BAA8B,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,GAAG;AAAA,QAChE,KAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;","names":["existsSync","homedir","path","path","homedir","existsSync"]}
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
buildProviderSetupView,
|
|
4
4
|
parseAgentSelection
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-J7DNV2DH.js";
|
|
6
6
|
import {
|
|
7
|
+
disabledAgentProviderMessage,
|
|
8
|
+
formatEnabledAgentProviderList,
|
|
7
9
|
isAgentProviderId,
|
|
10
|
+
isEnabledAgentProviderId,
|
|
8
11
|
readConfig,
|
|
9
12
|
writeConfig
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-3E7JNMTZ.js";
|
|
11
14
|
|
|
12
15
|
// src/commands/agents.ts
|
|
13
16
|
async function runAgentsList() {
|
|
@@ -30,7 +33,8 @@ async function runAgentsList() {
|
|
|
30
33
|
);
|
|
31
34
|
}
|
|
32
35
|
lines.push(
|
|
33
|
-
|
|
36
|
+
`
|
|
37
|
+
Use: almanac agents use <${formatEnabledAgentProviderList().replaceAll(", ", "|")}>`,
|
|
34
38
|
"Set model: almanac agents model <provider> <model>"
|
|
35
39
|
);
|
|
36
40
|
return { stdout: `${lines.join("\n")}
|
|
@@ -72,12 +76,15 @@ async function setDefaultAgent(opts) {
|
|
|
72
76
|
if (parsed.provider === null) {
|
|
73
77
|
return {
|
|
74
78
|
stdout: "",
|
|
75
|
-
stderr: `almanac: unknown agent '${opts.provider}'. Expected one of:
|
|
79
|
+
stderr: `almanac: unknown agent '${opts.provider}'. Expected one of: ${formatEnabledAgentProviderList()}.
|
|
76
80
|
`,
|
|
77
81
|
exitCode: 1
|
|
78
82
|
};
|
|
79
83
|
}
|
|
80
84
|
const provider = parsed.provider;
|
|
85
|
+
if (!isEnabledAgentProviderId(provider)) {
|
|
86
|
+
return disabledProviderResult(provider);
|
|
87
|
+
}
|
|
81
88
|
const config = await readConfig();
|
|
82
89
|
const next = {
|
|
83
90
|
...config,
|
|
@@ -116,11 +123,14 @@ async function setProviderModel(opts) {
|
|
|
116
123
|
if (!isAgentProviderId(opts.provider)) {
|
|
117
124
|
return {
|
|
118
125
|
stdout: "",
|
|
119
|
-
stderr: `almanac: unknown agent '${opts.provider}'. Expected one of:
|
|
126
|
+
stderr: `almanac: unknown agent '${opts.provider}'. Expected one of: ${formatEnabledAgentProviderList()}.
|
|
120
127
|
`,
|
|
121
128
|
exitCode: 1
|
|
122
129
|
};
|
|
123
130
|
}
|
|
131
|
+
if (!isEnabledAgentProviderId(opts.provider)) {
|
|
132
|
+
return disabledProviderResult(opts.provider);
|
|
133
|
+
}
|
|
124
134
|
if (opts.defaultModel !== true && (opts.model === void 0 || opts.model.length === 0)) {
|
|
125
135
|
return {
|
|
126
136
|
stdout: "",
|
|
@@ -156,6 +166,14 @@ function normalizeRequestedModel(opts) {
|
|
|
156
166
|
if (opts.model === "default" || opts.model === "null") return null;
|
|
157
167
|
return opts.model;
|
|
158
168
|
}
|
|
169
|
+
function disabledProviderResult(provider) {
|
|
170
|
+
return {
|
|
171
|
+
stdout: "",
|
|
172
|
+
stderr: `almanac: ${disabledAgentProviderMessage(provider)}
|
|
173
|
+
`,
|
|
174
|
+
exitCode: 1
|
|
175
|
+
};
|
|
176
|
+
}
|
|
159
177
|
function readinessLabel(readiness) {
|
|
160
178
|
switch (readiness) {
|
|
161
179
|
case "ready":
|
|
@@ -184,4 +202,4 @@ export {
|
|
|
184
202
|
runDeprecatedSetAgentModel,
|
|
185
203
|
runAgentsModel
|
|
186
204
|
};
|
|
187
|
-
//# sourceMappingURL=chunk-
|
|
205
|
+
//# sourceMappingURL=chunk-GPFVEF6V.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/agents.ts"],"sourcesContent":["import {\n buildProviderSetupView,\n parseAgentSelection,\n type ProviderReadiness,\n} from \"../agent/provider-view.js\";\nimport {\n disabledAgentProviderMessage,\n formatEnabledAgentProviderList,\n isAgentProviderId,\n isEnabledAgentProviderId,\n readConfig,\n writeConfig,\n type AgentProviderId,\n} from \"../update/config.js\";\n\nexport interface AgentsResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport async function runAgentsList(): Promise<AgentsResult> {\n const view = await buildProviderSetupView();\n const lines = [\"codealmanac agents\\n\"];\n for (const choice of view.choices) {\n const selected = choice.selected ? \"*\" : \" \";\n const recommended = choice.recommended ? \"recommended\" : \"\";\n const model = choice.effectiveModel ?? \"provider default\";\n const detail = choice.account ?? choice.fixCommand ?? choice.detail;\n lines.push(\n [\n selected,\n choice.label.padEnd(6),\n readinessLabel(choice.readiness).padEnd(15),\n recommended.padEnd(11),\n `model: ${model}`.padEnd(31),\n detail,\n ].join(\" \").trimEnd(),\n );\n }\n lines.push(\n `\\nUse: almanac agents use <${formatEnabledAgentProviderList().replaceAll(\", \", \"|\")}>`,\n \"Set model: almanac agents model <provider> <model>\",\n );\n return { stdout: `${lines.join(\"\\n\")}\\n`, stderr: \"\", exitCode: 0 };\n}\n\nexport async function runAgentsDoctor(): Promise<AgentsResult> {\n const view = await buildProviderSetupView();\n const lines = [\"codealmanac agent doctor\\n\"];\n for (const choice of view.choices) {\n lines.push(`${choice.ready ? \"✓\" : \"✗\"} ${choice.label}`);\n lines.push(` status: ${readinessLabel(choice.readiness)}`);\n lines.push(` model: ${choice.effectiveModel ?? \"provider default\"}`);\n if (choice.account !== null) {\n lines.push(` account: ${choice.account}`);\n } else if (choice.detail.length > 0) {\n lines.push(` detail: ${choice.detail}`);\n }\n if (choice.fixCommand !== null) lines.push(` fix: ${choice.fixCommand}`);\n lines.push(\"\");\n }\n return { stdout: `${lines.join(\"\\n\").trimEnd()}\\n`, stderr: \"\", exitCode: 0 };\n}\n\nexport interface SetDefaultAgentOptions {\n provider: string;\n}\n\nexport async function runSetDefaultAgent(\n opts: SetDefaultAgentOptions,\n): Promise<AgentsResult> {\n return setDefaultAgent(opts);\n}\n\nexport async function runDeprecatedSetDefaultAgent(\n opts: SetDefaultAgentOptions,\n): Promise<AgentsResult> {\n return withDeprecation(\n await setDefaultAgent(opts),\n \"almanac set default-agent <provider>\",\n \"almanac agents use <provider>\",\n );\n}\n\nexport async function runAgentsUse(opts: SetDefaultAgentOptions): Promise<AgentsResult> {\n return setDefaultAgent(opts);\n}\n\nasync function setDefaultAgent(\n opts: SetDefaultAgentOptions,\n): Promise<AgentsResult> {\n const parsed = parseAgentSelection(opts.provider);\n if (parsed.provider === null) {\n return {\n stdout: \"\",\n stderr:\n `almanac: unknown agent '${opts.provider}'. ` +\n `Expected one of: ${formatEnabledAgentProviderList()}.\\n`,\n exitCode: 1,\n };\n }\n const provider = parsed.provider;\n if (!isEnabledAgentProviderId(provider)) {\n return disabledProviderResult(provider);\n }\n const config = await readConfig();\n const next = {\n ...config,\n agent: {\n ...config.agent,\n default: provider,\n models:\n parsed.model === undefined\n ? config.agent.models\n : {\n ...config.agent.models,\n [provider]: parsed.model,\n },\n },\n };\n await writeConfig(next);\n return {\n stdout:\n parsed.model === undefined\n ? `codealmanac: default agent set to ${provider}.\\n`\n : `codealmanac: default agent set to ${provider}; ${provider} model set to ${parsed.model}.\\n`,\n stderr: \"\",\n exitCode: 0,\n };\n}\n\nexport async function runSetAgentModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n return setProviderModel(opts);\n}\n\nexport async function runDeprecatedSetAgentModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n return withDeprecation(\n await setProviderModel(opts),\n \"almanac set model <provider> <model>\",\n \"almanac agents model <provider> <model>\",\n );\n}\n\nexport async function runAgentsModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n return setProviderModel(opts);\n}\n\nasync function setProviderModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n if (!isAgentProviderId(opts.provider)) {\n return {\n stdout: \"\",\n stderr:\n `almanac: unknown agent '${opts.provider}'. ` +\n `Expected one of: ${formatEnabledAgentProviderList()}.\\n`,\n exitCode: 1,\n };\n }\n if (!isEnabledAgentProviderId(opts.provider)) {\n return disabledProviderResult(opts.provider);\n }\n if (\n opts.defaultModel !== true &&\n (opts.model === undefined || opts.model.length === 0)\n ) {\n return {\n stdout: \"\",\n stderr:\n `almanac: missing model for ${opts.provider}. ` +\n \"Pass a model id or --default.\\n\",\n exitCode: 1,\n };\n }\n const provider = opts.provider as AgentProviderId;\n const config = await readConfig();\n const model = normalizeRequestedModel(opts);\n await writeConfig({\n ...config,\n agent: {\n ...config.agent,\n models: {\n ...config.agent.models,\n [provider]: model,\n },\n },\n });\n return {\n stdout:\n model === null\n ? `codealmanac: ${provider} model reset to provider default.\\n`\n : `codealmanac: ${provider} model set to ${model}.\\n`,\n stderr: \"\",\n exitCode: 0,\n };\n}\n\nfunction normalizeRequestedModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): string | null {\n if (opts.defaultModel === true) return null;\n if (opts.model === undefined || opts.model.length === 0) return null;\n if (opts.model === \"default\" || opts.model === \"null\") return null;\n return opts.model;\n}\n\nfunction disabledProviderResult(provider: string): AgentsResult {\n return {\n stdout: \"\",\n stderr: `almanac: ${disabledAgentProviderMessage(provider)}\\n`,\n exitCode: 1,\n };\n}\n\nfunction readinessLabel(readiness: ProviderReadiness): string {\n switch (readiness) {\n case \"ready\":\n return \"ready\";\n case \"missing\":\n return \"missing\";\n case \"not-authenticated\":\n return \"not ready\";\n }\n}\n\nfunction withDeprecation(\n result: AgentsResult,\n oldUsage: string,\n newUsage: string,\n): AgentsResult {\n return {\n ...result,\n stderr:\n `almanac: warning: \\`${oldUsage}\\` is deprecated; use \\`${newUsage}\\`.\\n` +\n result.stderr,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getConfigPath,
|
|
8
8
|
getLegacyConfigPath,
|
|
9
9
|
parseConfigText
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3E7JNMTZ.js";
|
|
11
11
|
|
|
12
12
|
// src/update/schedule.ts
|
|
13
13
|
import { spawn } from "child_process";
|
|
@@ -86,4 +86,4 @@ export {
|
|
|
86
86
|
runInternalUpdateCheck,
|
|
87
87
|
readStateForDoctor
|
|
88
88
|
};
|
|
89
|
-
//# sourceMappingURL=chunk-
|
|
89
|
+
//# sourceMappingURL=chunk-HJ3WREGP.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
getEnabledAgentProviderIds,
|
|
4
4
|
isAgentProviderId,
|
|
5
5
|
readConfig
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3E7JNMTZ.js";
|
|
7
7
|
|
|
8
8
|
// src/agent/providers/claude/index.ts
|
|
9
9
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -147,8 +147,52 @@ var claudeProvider = {
|
|
|
147
147
|
metadata,
|
|
148
148
|
checkStatus,
|
|
149
149
|
assertReady,
|
|
150
|
-
run
|
|
150
|
+
run,
|
|
151
|
+
modelChoices
|
|
151
152
|
};
|
|
153
|
+
var CLAUDE_MODELS = [
|
|
154
|
+
{
|
|
155
|
+
value: "claude-opus-4-7",
|
|
156
|
+
label: "Opus 4.7",
|
|
157
|
+
recommended: false
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
value: "claude-sonnet-4-6",
|
|
161
|
+
label: "Sonnet 4.6",
|
|
162
|
+
recommended: true
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
value: "claude-haiku-4-5-20251001",
|
|
166
|
+
label: "Haiku 4.5",
|
|
167
|
+
recommended: false
|
|
168
|
+
}
|
|
169
|
+
];
|
|
170
|
+
function modelChoices(args) {
|
|
171
|
+
const choices = [];
|
|
172
|
+
if (args.configuredModel !== null && !CLAUDE_MODELS.some((model) => model.value === args.configuredModel)) {
|
|
173
|
+
choices.push({
|
|
174
|
+
value: args.configuredModel,
|
|
175
|
+
label: args.configuredModel,
|
|
176
|
+
recommended: false,
|
|
177
|
+
source: "configured"
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
for (const model of CLAUDE_MODELS) {
|
|
181
|
+
choices.push({
|
|
182
|
+
value: model.value,
|
|
183
|
+
label: model.label,
|
|
184
|
+
recommended: model.recommended,
|
|
185
|
+
source: "catalog"
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
choices.push({
|
|
189
|
+
value: "__custom__",
|
|
190
|
+
label: "Enter a model name",
|
|
191
|
+
recommended: false,
|
|
192
|
+
source: "custom"
|
|
193
|
+
});
|
|
194
|
+
return choices;
|
|
195
|
+
}
|
|
152
196
|
async function run(opts) {
|
|
153
197
|
const claudeExecutable = resolveClaudeExecutable();
|
|
154
198
|
const q = query({
|
|
@@ -277,6 +321,47 @@ ${stderr}`.trim();
|
|
|
277
321
|
});
|
|
278
322
|
});
|
|
279
323
|
}
|
|
324
|
+
function runInjectedStatusCommand(spawnCli, args) {
|
|
325
|
+
return new Promise((resolve) => {
|
|
326
|
+
let stdout = "";
|
|
327
|
+
let stderr = "";
|
|
328
|
+
let settled = false;
|
|
329
|
+
const settle = (value) => {
|
|
330
|
+
if (settled) return;
|
|
331
|
+
settled = true;
|
|
332
|
+
resolve(value);
|
|
333
|
+
};
|
|
334
|
+
try {
|
|
335
|
+
const child = spawnCli(args);
|
|
336
|
+
child.stdout.on("data", (chunk) => {
|
|
337
|
+
stdout += chunk.toString();
|
|
338
|
+
});
|
|
339
|
+
child.stderr.on("data", (chunk) => {
|
|
340
|
+
stderr += chunk.toString();
|
|
341
|
+
});
|
|
342
|
+
child.on("error", (err) => {
|
|
343
|
+
settle({
|
|
344
|
+
ok: false,
|
|
345
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
child.on("close", (codeOrError) => {
|
|
349
|
+
const code = typeof codeOrError === "number" ? codeOrError : 1;
|
|
350
|
+
const text = `${stdout}
|
|
351
|
+
${stderr}`.trim();
|
|
352
|
+
settle({
|
|
353
|
+
ok: code === 0,
|
|
354
|
+
detail: text.split("\n").find((line) => line.trim().length > 0)?.trim() ?? (code === 0 ? "ready" : `${args[0] ?? "command"} exited ${code}`)
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
} catch (err) {
|
|
358
|
+
settle({
|
|
359
|
+
ok: false,
|
|
360
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
280
365
|
|
|
281
366
|
// src/agent/providers/jsonl-cli.ts
|
|
282
367
|
import { spawn as spawn3 } from "child_process";
|
|
@@ -428,8 +513,100 @@ var codexProvider = {
|
|
|
428
513
|
metadata: metadata2,
|
|
429
514
|
checkStatus: checkStatus2,
|
|
430
515
|
assertReady: assertReady2,
|
|
431
|
-
run: run2
|
|
516
|
+
run: run2,
|
|
517
|
+
modelChoices: modelChoices2
|
|
432
518
|
};
|
|
519
|
+
var CODEX_MODEL_ORDER = [
|
|
520
|
+
"gpt-5.5",
|
|
521
|
+
"gpt-5.4",
|
|
522
|
+
"gpt-5.4-mini",
|
|
523
|
+
"gpt-5.3-codex"
|
|
524
|
+
];
|
|
525
|
+
var CODEX_MODEL_LABELS = {
|
|
526
|
+
"gpt-5.5": "GPT-5.5",
|
|
527
|
+
"gpt-5.4": "GPT-5.4",
|
|
528
|
+
"gpt-5.4-mini": "GPT-5.4 Mini",
|
|
529
|
+
"gpt-5.3-codex": "GPT-5.3 Codex"
|
|
530
|
+
};
|
|
531
|
+
async function modelChoices2(args) {
|
|
532
|
+
const catalog = await readCodexModelCatalog(args.spawnCli);
|
|
533
|
+
const choices = [];
|
|
534
|
+
if (args.configuredModel !== null) {
|
|
535
|
+
choices.push({
|
|
536
|
+
value: args.configuredModel,
|
|
537
|
+
label: modelLabel(args.configuredModel, catalog),
|
|
538
|
+
recommended: false,
|
|
539
|
+
source: "configured"
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
for (const slug of CODEX_MODEL_ORDER) {
|
|
543
|
+
if (choices.some((choice) => choice.value === slug)) continue;
|
|
544
|
+
if (catalog !== void 0 && !catalog.some((model) => model.slug === slug)) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
choices.push({
|
|
548
|
+
value: slug,
|
|
549
|
+
label: modelLabel(slug, catalog),
|
|
550
|
+
recommended: slug === "gpt-5.4",
|
|
551
|
+
source: "catalog"
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
choices.push({
|
|
555
|
+
value: "__custom__",
|
|
556
|
+
label: "Enter a model name",
|
|
557
|
+
recommended: false,
|
|
558
|
+
source: "custom"
|
|
559
|
+
});
|
|
560
|
+
return choices;
|
|
561
|
+
}
|
|
562
|
+
async function readCodexModelCatalog(spawnCli) {
|
|
563
|
+
if (spawnCli === void 0) return void 0;
|
|
564
|
+
try {
|
|
565
|
+
const result = await collectSpawn(spawnCli(["codex", "debug", "models"]));
|
|
566
|
+
if (result.code !== 0) return void 0;
|
|
567
|
+
const parsed = JSON.parse(result.stdout);
|
|
568
|
+
if (parsed === null || typeof parsed !== "object") return void 0;
|
|
569
|
+
const models = parsed.models;
|
|
570
|
+
if (!Array.isArray(models)) return void 0;
|
|
571
|
+
const out = [];
|
|
572
|
+
for (const model of models) {
|
|
573
|
+
if (model === null || typeof model !== "object") continue;
|
|
574
|
+
const record = model;
|
|
575
|
+
if (record.visibility !== "list") continue;
|
|
576
|
+
if (typeof record.slug !== "string") continue;
|
|
577
|
+
out.push({
|
|
578
|
+
slug: record.slug,
|
|
579
|
+
displayName: typeof record.display_name === "string" ? record.display_name : record.slug
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
return out;
|
|
583
|
+
} catch {
|
|
584
|
+
return void 0;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
function collectSpawn(child) {
|
|
588
|
+
return new Promise((resolve) => {
|
|
589
|
+
let stdout = "";
|
|
590
|
+
let settled = false;
|
|
591
|
+
const settle = (code) => {
|
|
592
|
+
if (settled) return;
|
|
593
|
+
settled = true;
|
|
594
|
+
resolve({ stdout, code });
|
|
595
|
+
};
|
|
596
|
+
child.stdout.on("data", (chunk) => {
|
|
597
|
+
stdout += chunk.toString();
|
|
598
|
+
});
|
|
599
|
+
child.on("error", () => {
|
|
600
|
+
settle(1);
|
|
601
|
+
});
|
|
602
|
+
child.on("close", (codeOrError) => {
|
|
603
|
+
settle(typeof codeOrError === "number" ? codeOrError ?? 1 : 1);
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
function modelLabel(slug, catalog) {
|
|
608
|
+
return CODEX_MODEL_LABELS[slug] ?? catalog?.find((model) => model.slug === slug)?.displayName ?? slug;
|
|
609
|
+
}
|
|
433
610
|
async function run2(opts) {
|
|
434
611
|
const args = [
|
|
435
612
|
"exec",
|
|
@@ -453,8 +630,8 @@ async function run2(opts) {
|
|
|
453
630
|
parseFinal: parseCodexFinal
|
|
454
631
|
});
|
|
455
632
|
}
|
|
456
|
-
async function checkStatus2() {
|
|
457
|
-
if (!commandExists(metadata2.executable)) {
|
|
633
|
+
async function checkStatus2(spawnCli) {
|
|
634
|
+
if (spawnCli === void 0 && !commandExists(metadata2.executable)) {
|
|
458
635
|
return {
|
|
459
636
|
id: metadata2.id,
|
|
460
637
|
installed: false,
|
|
@@ -462,7 +639,11 @@ async function checkStatus2() {
|
|
|
462
639
|
detail: `${metadata2.executable} not found on PATH`
|
|
463
640
|
};
|
|
464
641
|
}
|
|
465
|
-
const auth = await
|
|
642
|
+
const auth = spawnCli !== void 0 ? await runInjectedStatusCommand(spawnCli, [
|
|
643
|
+
metadata2.executable,
|
|
644
|
+
"login",
|
|
645
|
+
"status"
|
|
646
|
+
]) : await runStatusCommand(metadata2.executable, ["login", "status"]);
|
|
466
647
|
return {
|
|
467
648
|
id: metadata2.id,
|
|
468
649
|
installed: true,
|
|
@@ -470,8 +651,8 @@ async function checkStatus2() {
|
|
|
470
651
|
detail: auth.detail
|
|
471
652
|
};
|
|
472
653
|
}
|
|
473
|
-
async function assertReady2() {
|
|
474
|
-
const status = await checkStatus2();
|
|
654
|
+
async function assertReady2(spawnCli) {
|
|
655
|
+
const status = await checkStatus2(spawnCli);
|
|
475
656
|
if (!status.installed || !status.authenticated) {
|
|
476
657
|
const err = new Error(`${status.id} not ready: ${status.detail}`);
|
|
477
658
|
err.code = "AGENT_AUTH_MISSING";
|
|
@@ -549,8 +730,8 @@ async function run3(opts) {
|
|
|
549
730
|
parseFinal: parseCursorFinal
|
|
550
731
|
});
|
|
551
732
|
}
|
|
552
|
-
async function checkStatus3() {
|
|
553
|
-
if (!commandExists(metadata3.executable)) {
|
|
733
|
+
async function checkStatus3(spawnCli) {
|
|
734
|
+
if (spawnCli === void 0 && !commandExists(metadata3.executable)) {
|
|
554
735
|
return {
|
|
555
736
|
id: metadata3.id,
|
|
556
737
|
installed: false,
|
|
@@ -558,7 +739,10 @@ async function checkStatus3() {
|
|
|
558
739
|
detail: `${metadata3.executable} not found on PATH`
|
|
559
740
|
};
|
|
560
741
|
}
|
|
561
|
-
const auth = await
|
|
742
|
+
const auth = spawnCli !== void 0 ? await runInjectedStatusCommand(spawnCli, [
|
|
743
|
+
metadata3.executable,
|
|
744
|
+
"status"
|
|
745
|
+
]) : await runStatusCommand(metadata3.executable, ["status"]);
|
|
562
746
|
return {
|
|
563
747
|
id: metadata3.id,
|
|
564
748
|
installed: true,
|
|
@@ -566,8 +750,8 @@ async function checkStatus3() {
|
|
|
566
750
|
detail: auth.detail
|
|
567
751
|
};
|
|
568
752
|
}
|
|
569
|
-
async function assertReady3() {
|
|
570
|
-
const status = await checkStatus3();
|
|
753
|
+
async function assertReady3(spawnCli) {
|
|
754
|
+
const status = await checkStatus3(spawnCli);
|
|
571
755
|
if (!status.installed || !status.authenticated) {
|
|
572
756
|
const err = new Error(`${status.id} not ready: ${status.detail}`);
|
|
573
757
|
err.code = "AGENT_AUTH_MISSING";
|
|
@@ -593,7 +777,7 @@ async function assertAgentAuth(args) {
|
|
|
593
777
|
}
|
|
594
778
|
async function listProviderStatuses(spawnCli) {
|
|
595
779
|
const out = [];
|
|
596
|
-
for (const id of
|
|
780
|
+
for (const id of getEnabledAgentProviderIds()) {
|
|
597
781
|
out.push(await getAgentProvider(id).checkStatus(spawnCli));
|
|
598
782
|
}
|
|
599
783
|
return out;
|
|
@@ -636,13 +820,14 @@ async function buildProviderSetupView(opts = {}) {
|
|
|
636
820
|
const statuses = opts.statuses ?? await listProviderStatuses(opts.spawnCli);
|
|
637
821
|
const statusById = new Map(statuses.map((status) => [status.id, status]));
|
|
638
822
|
const recommendedProvider = chooseRecommendedProvider(statuses);
|
|
639
|
-
const choices =
|
|
823
|
+
const choices = [];
|
|
824
|
+
for (const id of getEnabledAgentProviderIds()) {
|
|
640
825
|
const status = statusById.get(id) ?? missingStatus(id);
|
|
641
826
|
const readiness = getReadiness(status);
|
|
642
827
|
const configuredModel = normalizeModel(config.agent.models[id]);
|
|
643
828
|
const providerDefaultModel = getProviderDefaultModel(id);
|
|
644
829
|
const effectiveModel = configuredModel ?? providerDefaultModel;
|
|
645
|
-
|
|
830
|
+
choices.push({
|
|
646
831
|
id,
|
|
647
832
|
label: getProviderLabel(id),
|
|
648
833
|
selected: id === config.agent.default,
|
|
@@ -657,16 +842,22 @@ async function buildProviderSetupView(opts = {}) {
|
|
|
657
842
|
account: status.authenticated ? accountFromDetail(status.detail) : null,
|
|
658
843
|
detail: status.detail,
|
|
659
844
|
fixCommand: fixFor(id, readiness),
|
|
660
|
-
modelChoices: buildProviderModelChoices(id, configuredModel
|
|
661
|
-
|
|
662
|
-
|
|
845
|
+
modelChoices: await buildProviderModelChoices(id, configuredModel, {
|
|
846
|
+
spawnCli: opts.spawnCli
|
|
847
|
+
})
|
|
848
|
+
});
|
|
849
|
+
}
|
|
663
850
|
return {
|
|
664
851
|
defaultProvider: config.agent.default,
|
|
665
852
|
recommendedProvider,
|
|
666
853
|
choices
|
|
667
854
|
};
|
|
668
855
|
}
|
|
669
|
-
function buildProviderModelChoices(id, configuredModel = null) {
|
|
856
|
+
function buildProviderModelChoices(id, configuredModel = null, opts = {}) {
|
|
857
|
+
const provider = getAgentProvider(id);
|
|
858
|
+
if (provider.modelChoices !== void 0) {
|
|
859
|
+
return provider.modelChoices({ configuredModel, spawnCli: opts.spawnCli });
|
|
860
|
+
}
|
|
670
861
|
const choices = [];
|
|
671
862
|
if (configuredModel !== null) {
|
|
672
863
|
choices.push({
|
|
@@ -698,16 +889,16 @@ function buildProviderModelChoices(id, configuredModel = null) {
|
|
|
698
889
|
}
|
|
699
890
|
choices.push({
|
|
700
891
|
value: "__custom__",
|
|
701
|
-
label: "
|
|
892
|
+
label: "Enter a model name",
|
|
702
893
|
recommended: false,
|
|
703
894
|
source: "custom"
|
|
704
895
|
});
|
|
705
896
|
return choices;
|
|
706
897
|
}
|
|
707
898
|
function chooseRecommendedProvider(statuses) {
|
|
708
|
-
const ready = statuses.filter((status) => status
|
|
899
|
+
const ready = statuses.filter((status) => getReadiness(status) === "ready").map((status) => status.id);
|
|
709
900
|
if (ready.includes("claude")) return "claude";
|
|
710
|
-
for (const id of
|
|
901
|
+
for (const id of getEnabledAgentProviderIds()) {
|
|
711
902
|
if (ready.includes(id)) return id;
|
|
712
903
|
}
|
|
713
904
|
return "claude";
|
|
@@ -725,6 +916,9 @@ function parseAgentSelection(value) {
|
|
|
725
916
|
}
|
|
726
917
|
function getReadiness(status) {
|
|
727
918
|
if (!status.installed) return "missing";
|
|
919
|
+
if (/not (logged|signed) in|not authenticated/i.test(status.detail)) {
|
|
920
|
+
return "not-authenticated";
|
|
921
|
+
}
|
|
728
922
|
if (!status.authenticated) return "not-authenticated";
|
|
729
923
|
return "ready";
|
|
730
924
|
}
|
|
@@ -754,7 +948,6 @@ function missingStatus(id) {
|
|
|
754
948
|
|
|
755
949
|
export {
|
|
756
950
|
checkClaudeAuth,
|
|
757
|
-
UNAUTHENTICATED_MESSAGE,
|
|
758
951
|
DEFAULT_AGENT_MODEL,
|
|
759
952
|
assertAgentAuth,
|
|
760
953
|
getAgentProvider,
|
|
@@ -763,4 +956,4 @@ export {
|
|
|
763
956
|
buildProviderModelChoices,
|
|
764
957
|
parseAgentSelection
|
|
765
958
|
};
|
|
766
|
-
//# sourceMappingURL=chunk-
|
|
959
|
+
//# sourceMappingURL=chunk-J7DNV2DH.js.map
|