@orquentra/codebuddy 2.5.0 → 2.6.0
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/README.md +8 -0
- package/dist/{chunk-KYK6RPAJ.js → chunk-JFDRBPYF.js} +2 -2
- package/dist/{chunk-JMWJ7V6Y.js → chunk-JPHJBCZB.js} +2 -2
- package/dist/{chunk-JMWJ7V6Y.js.map → chunk-JPHJBCZB.js.map} +1 -1
- package/dist/{chunk-ROQTT5ZO.js → chunk-N34XHWBA.js} +2 -2
- package/dist/{chunk-CQPCHMBS.js → chunk-SYWJG5NA.js} +2 -2
- package/dist/{chunk-3XYQGFPB.js → chunk-U4HAJLIB.js} +2 -2
- package/dist/{chunk-JDZ3VK26.js → chunk-UN57FKQX.js} +32 -5
- package/dist/chunk-UN57FKQX.js.map +1 -0
- package/dist/{chunk-Z5QB367W.js → chunk-VAKBJV26.js} +106 -22
- package/dist/chunk-VAKBJV26.js.map +1 -0
- package/dist/{chunk-4BYGTEJT.js → chunk-XBJQKCLU.js} +2 -2
- package/dist/cli/index.js +2 -2
- package/dist/{cloud-GP6G3EAK.js → cloud-7WM3YLI4.js} +3 -3
- package/dist/index.js +7 -7
- package/dist/{lean-command-DA4ZNKG3.js → lean-command-C5YPFKHP.js} +5 -5
- package/dist/{local-3NGNESNB.js → local-OTOY56B4.js} +3 -3
- package/dist/{main-BDVQAGAS.js → main-HFHLGID4.js} +201 -55
- package/dist/main-HFHLGID4.js.map +1 -0
- package/dist/{operations-EQGOFCBD.js → operations-LOBAQRLO.js} +6 -6
- package/package.json +1 -1
- package/dist/chunk-JDZ3VK26.js.map +0 -1
- package/dist/chunk-Z5QB367W.js.map +0 -1
- package/dist/main-BDVQAGAS.js.map +0 -1
- /package/dist/{chunk-KYK6RPAJ.js.map → chunk-JFDRBPYF.js.map} +0 -0
- /package/dist/{chunk-ROQTT5ZO.js.map → chunk-N34XHWBA.js.map} +0 -0
- /package/dist/{chunk-CQPCHMBS.js.map → chunk-SYWJG5NA.js.map} +0 -0
- /package/dist/{chunk-3XYQGFPB.js.map → chunk-U4HAJLIB.js.map} +0 -0
- /package/dist/{chunk-4BYGTEJT.js.map → chunk-XBJQKCLU.js.map} +0 -0
- /package/dist/{cloud-GP6G3EAK.js.map → cloud-7WM3YLI4.js.map} +0 -0
- /package/dist/{lean-command-DA4ZNKG3.js.map → lean-command-C5YPFKHP.js.map} +0 -0
- /package/dist/{local-3NGNESNB.js.map → local-OTOY56B4.js.map} +0 -0
- /package/dist/{operations-EQGOFCBD.js.map → operations-LOBAQRLO.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/main.ts","../src/integrations/github.ts","../src/cli/commands/change.ts","../src/change/engine.ts","../src/cli/commands/claude-desktop.ts","../src/cli/commands/clients.ts","../src/clients/adapters.ts","../src/clients/cost.ts","../src/templates/install.ts","../src/hooks/hermes-plugin.ts","../src/hooks/managed-plugin.ts","../src/hooks/opencode-plugin.ts","../src/hooks/settings.ts","../src/hooks/install.ts","../src/templates/workflow.ts","../src/clients/install.ts","../src/integrations/project-mcp.ts","../src/cli/commands/codex.ts","../src/integrations/hermes-config.ts","../src/clients/global-mcp.ts","../src/clients/verify.ts","../src/cli/commands/context.ts","../src/cli/commands/dashboard.ts","../src/dashboard/server.ts","../src/dashboard/page.ts","../src/cli/commands/eval.ts","../src/eval/runner.ts","../src/cli/commands/github.ts","../src/cli/commands/hooks.ts","../src/cli/commands/indexing.ts","../src/cli/commands/llm.ts","../src/cli/commands/init-wizard.ts","../src/cli/commands/postgres-docker.ts","../src/cli/commands/learn.ts","../src/learning/outcomes.ts","../src/cli/commands/map.ts","../src/cli/commands/memory-review.ts","../src/cli/commands/models.ts","../evals/fact-relevance.json","../src/providers/calibration.ts","../src/cli/commands/plan.ts","../src/cli/commands/risk.ts","../src/cli/commands/rules.ts","../src/cli/commands/suggest.ts","../src/cli/commands/symbols.ts","../src/cli/commands/use-command.ts","../src/core/global-config.ts","../src/cli/commands/docker-autostart.ts","../src/cli/commands/worklog.ts","../src/cli/commands/zvec.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { initConfigFile, loadRuntimeConfig, redactSecrets } from \"../core/config-file.js\";\nimport { MemoryFileStore } from \"../core/memory-file-store.js\";\nimport { migrateMemoryToFiles } from \"../core/migrate-to-files.js\";\nimport { createRuntime, inspectNamespace, listFactsPage, runDoctor } from \"../core/operations.js\";\nimport { bootstrapDatabase } from \"../db/bootstrap.js\";\nimport { createDatabaseClient } from \"../db/client.js\";\nimport { runMigrations } from \"../db/migrator.js\";\nimport { installGitHubWorkflow } from \"../integrations/github.js\";\nimport { generateGraphifyGraph } from \"../integrations/graphify.js\";\nimport { startMcpServer } from \"../mcp/server.js\";\nimport { VERSION } from \"../version.js\";\nimport { registerChangeCommand } from \"./commands/change.js\";\nimport {\n installClaudeEntry,\n listClaudeEntries,\n removeClaudeEntry,\n} from \"./commands/claude-desktop.js\";\nimport { registerClientsCommands } from \"./commands/clients.js\";\nimport { installCodexEntry, listCodexEntries, removeCodexEntry } from \"./commands/codex.js\";\nimport { registerContextCommands } from \"./commands/context.js\";\nimport { registerDashboardCommand } from \"./commands/dashboard.js\";\nimport { registerEvalCommand } from \"./commands/eval.js\";\nimport { registerGitHubCommands } from \"./commands/github.js\";\nimport { registerHooksCommands } from \"./commands/hooks.js\";\nimport { registerIndexCommands } from \"./commands/indexing.js\";\nimport { runInitWizard } from \"./commands/init-wizard.js\";\nimport { registerLearnCommand } from \"./commands/learn.js\";\nimport { registerLlmCommands } from \"./commands/llm.js\";\nimport { registerMapCommands } from \"./commands/map.js\";\nimport { registerMemoryCommands } from \"./commands/memory-review.js\";\nimport { registerModelsCommands } from \"./commands/models.js\";\nimport { registerPlanCommands } from \"./commands/plan.js\";\nimport { postgresDown, postgresStatus, postgresUp } from \"./commands/postgres-docker.js\";\nimport { registerRiskCommands } from \"./commands/risk.js\";\nimport { registerRulesCommands } from \"./commands/rules.js\";\nimport { registerSuggestCommand } from \"./commands/suggest.js\";\nimport { registerSymbolsCommand } from \"./commands/symbols.js\";\nimport { runUseCommand } from \"./commands/use-command.js\";\nimport { registerWorklogCommands } from \"./commands/worklog.js\";\nimport { registerZvecCommands } from \"./commands/zvec.js\";\n\nexport function createCli(): Command {\n const program = new Command();\n\n program\n .name(\"codebuddy\")\n .description(\n \"Project memory and context for AI coding agents: recalls the right facts, files and risks on every prompt.\",\n )\n .version(VERSION);\n\n program.action(async () => {\n await runSafely(async () => {\n await runUseCommand();\n });\n });\n\n program\n .command(\"use\")\n .description(\n \"One-command setup for this folder: PostgreSQL (starts Docker if needed), migrations, embeddings, and agent wiring.\",\n )\n .argument(\"[namespace]\", \"Override the namespace (defaults to current folder name).\")\n .option(\"--postgres-url <url>\", \"Postgres URL to use for this project.\")\n .option(\"--skip-claude\", \"Do not register with Claude Desktop.\")\n .option(\"--skip-codex\", \"Do not register with Codex.\")\n .option(\"--graphify\", \"Enable Graphify setup without prompting.\")\n .option(\"--no-graphify\", \"Skip Graphify setup without prompting.\")\n .option(\n \"--docker\",\n \"Start CodeBuddy's bundled Postgres container when the default DB is unavailable.\",\n )\n .option(\"--no-docker\", \"Do not offer to start CodeBuddy's bundled Postgres container.\")\n .action(\n async (\n namespace: string | undefined,\n opts: {\n postgresUrl?: string;\n skipClaude?: boolean;\n skipCodex?: boolean;\n graphify?: boolean;\n docker?: boolean;\n },\n ) => {\n await runSafely(async () => {\n await runUseCommand({\n ...(namespace !== undefined ? { namespace } : {}),\n ...(opts.postgresUrl !== undefined ? { postgresUrl: opts.postgresUrl } : {}),\n ...(opts.skipClaude !== undefined ? { skipClaude: opts.skipClaude } : {}),\n ...(opts.skipCodex !== undefined ? { skipCodex: opts.skipCodex } : {}),\n ...(opts.graphify !== undefined ? { graphify: opts.graphify } : {}),\n ...(opts.docker !== undefined ? { useDocker: opts.docker } : {}),\n });\n });\n },\n );\n\n program\n .command(\"init\")\n .description(\"Interactive setup: config file, Postgres, migrations, Claude Desktop.\")\n .option(\"--non-interactive\", \"Skip the wizard; just create .codebuddy/config.json.\")\n .option(\"--github-action\", \"Install the GitHub PR change-safety workflow.\")\n .action(async (opts: { nonInteractive?: boolean; githubAction?: boolean }) => {\n await runSafely(async () => {\n if (opts.nonInteractive || !process.stdin.isTTY) {\n const result = await initConfigFile();\n console.log(`${result.created ? \"created\" : \"updated permissions\"} ${result.path}`);\n if (opts.githubAction) {\n const workflow = await installGitHubWorkflow();\n console.log(`${workflow.created ? \"installed\" : \"already present\"} ${workflow.path}`);\n }\n return;\n }\n await runInitWizard();\n if (opts.githubAction) {\n const workflow = await installGitHubWorkflow();\n console.log(`${workflow.created ? \"installed\" : \"already present\"} ${workflow.path}`);\n }\n });\n });\n\n const graphify = program\n .command(\"graphify\")\n .description(\"Build the local Graphify repository graph.\");\n graphify\n .command(\"index\")\n .argument(\"[projectRoot]\", \"Project root (defaults to the current directory).\")\n .option(\"--graph <path>\", \"Graph path relative to the project root.\")\n .description(\"Generate or incrementally update graphify-out/graph.json.\")\n .action(async (projectRoot: string | undefined, opts: { graph?: string }) => {\n await runSafely(async () => {\n const root = projectRoot ?? process.cwd();\n const result = await generateGraphifyGraph({\n repositoryRoot: root,\n ...(opts.graph ? { graphPath: opts.graph } : {}),\n });\n console.log(JSON.stringify(result, null, 2));\n });\n });\n\n const migrate = program\n .command(\"migrate\")\n .description(\"Apply pending database migrations.\")\n .action(async () => {\n await runSafely(async () => {\n const config = await loadRuntimeConfig();\n const client = createDatabaseClient({ postgresUrl: config.postgresUrl });\n try {\n await bootstrapDatabase(client.sql);\n await runMigrations(client);\n console.log(\"migrations applied\");\n } finally {\n await client.close();\n }\n });\n });\n migrate\n .command(\"to-files\")\n .description(\"Preview or write existing facts and summaries as Markdown files.\")\n .option(\"--write\", \"Write files. Without this flag the command is a dry run.\")\n .action(async (opts: { write?: boolean }) => {\n await withRuntime(async (runtime) => {\n const config = await loadRuntimeConfig();\n const result = await migrateMemoryToFiles({\n repository: runtime.repository,\n store: new MemoryFileStore(config.projectRoot ?? process.cwd()),\n namespace: config.namespace,\n write: opts.write ?? false,\n });\n console.log(JSON.stringify(result, null, 2));\n });\n });\n\n program\n .command(\"reindex\")\n .description(\"Rebuild fact and summary records from Markdown files.\")\n .option(\"--full\", \"Scan every Markdown memory file.\")\n .action(async (_opts: { full?: boolean }) => {\n await withRuntime(async (runtime) => {\n console.log(JSON.stringify(await runtime.memory.reindexMemory(), null, 2));\n });\n });\n\n const postgres = program\n .command(\"postgres\")\n .description(\"Manage the bundled Postgres container.\");\n postgres\n .command(\"up\")\n .description(\"Start the bundled Postgres container (docker compose up -d).\")\n .action(async () => {\n await runSafely(async () => {\n const result = await postgresUp();\n process.stdout.write(result.stdout);\n if (result.code !== 0) {\n process.stderr.write(result.stderr);\n process.exitCode = result.code;\n }\n });\n });\n\n const db = program.command(\"db\").description(\"Check database connectivity and setup health.\");\n db.command(\"doctor\")\n .description(\"Check Postgres reachability, pgvector, and namespace assumptions.\")\n .action(async () => {\n await runSafely(async () => {\n const report = await runDoctor({ skipModelCheck: true });\n printDbDoctor(report);\n if (!report.db.ok || !report.pgvector.ok || !report.namespace.ok) process.exitCode = 1;\n });\n });\n db.command(\"test\")\n .description(\"Run a simple database connectivity test.\")\n .action(async () => {\n await runSafely(async () => {\n const report = await runDoctor({ skipModelCheck: true });\n if (!report.db.ok) {\n console.log(\"database test: fail\");\n if (report.db.error) console.log(` ${report.db.error}`);\n process.exitCode = 1;\n return;\n }\n console.log(\"database test: ok\");\n });\n });\n postgres\n .command(\"down\")\n .description(\"Stop the bundled Postgres container (data volume preserved).\")\n .action(async () => {\n await runSafely(async () => {\n const result = await postgresDown();\n process.stdout.write(result.stdout);\n if (result.code !== 0) {\n process.stderr.write(result.stderr);\n process.exitCode = result.code;\n }\n });\n });\n postgres\n .command(\"status\")\n .description(\"docker compose ps for the bundled Postgres container.\")\n .action(async () => {\n await runSafely(async () => {\n const result = await postgresStatus();\n process.stdout.write(result.stdout);\n if (result.code !== 0) {\n process.stderr.write(result.stderr);\n process.exitCode = result.code;\n }\n });\n });\n\n const claude = program\n .command(\"claude\")\n .description(\"Register CodeBuddy as an MCP server in Claude Desktop.\");\n claude\n .command(\"install\")\n .option(\"--namespace <name>\", \"Namespace for this Claude Desktop entry.\")\n .option(\"--server-name <name>\", \"Override the server key. Defaults to codebuddy-<namespace>.\")\n .description(\"Add or update a codebuddy MCP entry in Claude Desktop's config.\")\n .action(async (opts: { namespace?: string; serverName?: string }) => {\n await runSafely(async () => {\n const config = await loadRuntimeConfig();\n const namespace = opts.namespace ?? config.namespace ?? \"default\";\n const install = await installClaudeEntry({\n namespace,\n projectRoot: process.cwd(),\n ...(config.provider.apiKey ? { hfToken: config.provider.apiKey } : {}),\n ...(process.env.GROQ_API_KEY ? { groqApiKey: process.env.GROQ_API_KEY } : {}),\n databaseUrl: config.postgresUrl,\n ...(opts.serverName ? { serverName: opts.serverName } : {}),\n });\n console.log(\n `${install.created ? \"added\" : \"updated\"} ${install.serverKey} in ${install.path}`,\n );\n console.log(\"Restart Claude Desktop (⌘Q) to activate.\");\n });\n });\n claude\n .command(\"list\")\n .description(\"List codebuddy entries currently registered in Claude Desktop.\")\n .action(async () => {\n await runSafely(async () => {\n const result = await listClaudeEntries();\n if (result.entries.length === 0) {\n console.log(`No codebuddy entries in ${result.path}.`);\n return;\n }\n console.log(`Claude Desktop config: ${result.path}`);\n for (const entry of result.entries) {\n console.log(\n ` ${entry.key} namespace=${entry.namespace ?? \"?\"} db=${entry.databaseUrl ?? \"?\"}`,\n );\n }\n });\n });\n claude\n .command(\"remove\")\n .argument(\"<serverKey>\", \"e.g. codebuddy-work\")\n .description(\"Remove a codebuddy entry from Claude Desktop's config.\")\n .action(async (serverKey: string) => {\n await runSafely(async () => {\n const result = await removeClaudeEntry(serverKey);\n if (result.removed) {\n console.log(`removed ${serverKey} from ${result.path}`);\n console.log(\"Restart Claude Desktop (⌘Q) for the change to take effect.\");\n } else {\n console.log(`no entry \"${serverKey}\" found in ${result.path}`);\n process.exitCode = 1;\n }\n });\n });\n\n const codex = program\n .command(\"codex\")\n .description(\"Register CodeBuddy as an MCP server in Codex.\");\n codex\n .command(\"install\")\n .option(\"--namespace <name>\", \"Namespace for this Codex entry.\")\n .option(\"--server-name <name>\", \"Override the server key. Defaults to codebuddy-<namespace>.\")\n .description(\"Add or update a codebuddy MCP entry in ~/.codex/config.toml.\")\n .action(async (opts: { namespace?: string; serverName?: string }) => {\n await runSafely(async () => {\n const config = await loadRuntimeConfig();\n const namespace = opts.namespace ?? config.namespace ?? \"default\";\n const install = await installCodexEntry({\n namespace,\n projectRoot: process.cwd(),\n ...(config.provider.apiKey ? { hfToken: config.provider.apiKey } : {}),\n databaseUrl: config.postgresUrl,\n ...(opts.serverName ? { serverName: opts.serverName } : {}),\n });\n console.log(\n `${install.created ? \"added\" : \"updated\"} ${install.serverKey} in ${install.path}`,\n );\n console.log(\"Restart Codex to activate.\");\n });\n });\n codex\n .command(\"list\")\n .description(\"List codebuddy entries currently registered in Codex.\")\n .action(async () => {\n await runSafely(async () => {\n const result = await listCodexEntries();\n if (result.entries.length === 0) {\n console.log(`No codebuddy entries in ${result.path}.`);\n return;\n }\n console.log(`Codex config: ${result.path}`);\n for (const entry of result.entries) {\n console.log(\n ` ${entry.key} namespace=${entry.namespace ?? \"?\"} db=${entry.databaseUrl ?? \"?\"}`,\n );\n }\n });\n });\n codex\n .command(\"remove\")\n .argument(\"<serverKey>\", \"e.g. codebuddy-work\")\n .description(\"Remove a codebuddy entry from Codex config.\")\n .action(async (serverKey: string) => {\n await runSafely(async () => {\n const result = await removeCodexEntry(serverKey);\n if (result.removed) {\n console.log(`removed ${serverKey} from ${result.path}`);\n console.log(\"Restart Codex for the change to take effect.\");\n } else {\n console.log(`no entry \"${serverKey}\" found in ${result.path}`);\n process.exitCode = 1;\n }\n });\n });\n\n program\n .command(\"serve\")\n .description(\"Start the CodeBuddy MCP stdio server.\")\n .action(async () => runSafely(() => startMcpServer()));\n\n program\n .command(\"inspect\")\n .argument(\"[namespace]\")\n .description(\"Inspect namespaces or a namespace.\")\n .action(async (namespace?: string) => {\n await withRuntime(async (runtime) => {\n console.log(JSON.stringify(await inspectNamespace(runtime.repository, namespace), null, 2));\n });\n });\n\n program\n .command(\"namespaces\")\n .description(\"List namespaces.\")\n .action(async () => {\n await withRuntime(async (runtime) => {\n console.log(\n JSON.stringify({ namespaces: await runtime.repository.listNamespaces() }, null, 2),\n );\n });\n });\n\n program\n .command(\"prune\")\n .requiredOption(\"--older-than <duration>\", \"Duration such as 30d, 12h, or 60m.\")\n .description(\"Delete memories older than a duration.\")\n .action(async (opts: { olderThan: string }) => {\n await withRuntime(async (runtime) => {\n // Guard the footgun: `--older-than 0m` computes cutoff=now and deletes\n // every row across all namespaces. Require a strictly positive window.\n const durationMs = parseDuration(opts.olderThan);\n if (!Number.isFinite(durationMs) || durationMs <= 0) {\n throw new Error(\"--older-than must be a positive duration (e.g. 30d, 12h, 60m).\");\n }\n const cutoff = new Date(Date.now() - durationMs);\n console.log(JSON.stringify(await runtime.repository.pruneBefore(cutoff), null, 2));\n });\n });\n\n program\n .command(\"export\")\n .argument(\"<namespace>\")\n .description(\"Export facts from a namespace as JSON.\")\n .action(async (namespace: string) => {\n await withRuntime(async (runtime) => {\n const row = await runtime.repository.getNamespaceByName(namespace);\n if (!row) throw new Error(`Namespace ${namespace} does not exist.`);\n const facts = await runtime.repository.listFacts({ namespaceId: row.id, limit: 10_000 });\n console.log(JSON.stringify({ namespace, facts }, null, 2));\n });\n });\n\n program\n .command(\"stats\")\n .description(\"Show CodeBuddy storage and usage stats.\")\n .action(async () => {\n await withRuntime(async (runtime) => {\n console.log(JSON.stringify(await runtime.repository.getStats(), null, 2));\n });\n });\n\n program\n .command(\"doctor\")\n .description(\"Check CodeBuddy environment health.\")\n .option(\"--skip-model-check\", \"Do not call Hugging Face models.\")\n .action(async (opts: { skipModelCheck?: boolean }) => {\n await runSafely(async () => {\n const report = await runDoctor({ skipModelCheck: opts.skipModelCheck ?? true });\n printDoctor(report);\n if (\n !report.db.ok ||\n !report.pgvector.ok ||\n report.config.warning ||\n !report.scaffold.policies.ok ||\n !report.scaffold.codebuddyDir.ok ||\n !report.namespace.ok\n ) {\n process.exitCode = 1;\n }\n });\n });\n\n program\n .command(\"list-facts\")\n .option(\"--subject <subject>\")\n .option(\"--limit <limit>\", \"Maximum facts to print.\", Number)\n .option(\"--cursor <cursor>\")\n .description(\"List facts from the configured namespace.\")\n .action(async (opts: { subject?: string; limit?: number; cursor?: string }) => {\n await withRuntime(async (runtime) => {\n console.log(\n JSON.stringify(await listFactsPage(runtime.memory, runtime.repository, opts), null, 2),\n );\n });\n });\n\n registerPlanCommands(program, runSafely);\n registerChangeCommand(program, runSafely);\n registerRiskCommands(program, runSafely);\n registerMapCommands(program, runSafely);\n registerContextCommands(program, runSafely);\n registerEvalCommand(program, runSafely);\n registerIndexCommands(program, runSafely);\n registerLearnCommand(program, runSafely);\n registerMemoryCommands(program, runSafely);\n registerWorklogCommands(program, runSafely);\n registerZvecCommands(program, runSafely);\n registerLlmCommands(program, runSafely);\n registerSuggestCommand(program, runSafely);\n registerRulesCommands(program, runSafely);\n registerHooksCommands(program, runSafely);\n registerModelsCommands(program, runSafely);\n registerDashboardCommand(program, runSafely);\n registerClientsCommands(program, runSafely);\n registerGitHubCommands(program, runSafely);\n registerSymbolsCommand(program, runSafely);\n\n program.action(async () => {\n await runSafely(() => runUseCommand());\n });\n\n groupHelp(program);\n return program;\n}\n\n/** Top-level `--help` in task groups instead of one 35-line list. */\nconst HELP_GROUPS: Array<[string, string[]]> = [\n [\"Get started:\", [\"use\", \"init\", \"doctor\", \"hooks\", \"clients\", \"models\", \"dashboard\"]],\n [\n \"Daily work:\",\n [\"context\", \"plan\", \"change\", \"risk\", \"suggest\", \"memory\", \"worklog\", \"map\", \"symbols\"],\n ],\n [\"Indexing and search:\", [\"index\", \"watch\", \"reindex\", \"zvec\", \"graphify\", \"llm\"]],\n [\n \"Database:\",\n [\n \"postgres\",\n \"db\",\n \"migrate\",\n \"stats\",\n \"inspect\",\n \"namespaces\",\n \"list-facts\",\n \"export\",\n \"prune\",\n ],\n ],\n [\"Integrations:\", [\"serve\", \"claude\", \"codex\", \"github\", \"rules\", \"learn\", \"eval\"]],\n];\n\nfunction groupHelp(program: Command): void {\n const groupOf = new Map(\n HELP_GROUPS.flatMap(([group, names]) => names.map((name) => [name, group])),\n );\n for (const command of program.commands) {\n command.helpGroup(groupOf.get(command.name()) ?? \"Other:\");\n }\n // Help lists groups in order of first appearance; listed order wins, then names in group order.\n const position = new Map(\n HELP_GROUPS.flatMap(([, names]) => names).map((name, index) => [name, index]),\n );\n (program.commands as Command[]).sort(\n (a, b) => (position.get(a.name()) ?? 999) - (position.get(b.name()) ?? 999),\n );\n program.addHelpText(\n \"after\",\n `\nQuick start:\n codebuddy set up this project (PostgreSQL, hooks, agent)\n codebuddy models check the embedding model and memory index\n codebuddy dashboard live page of recalls, tool calls and tokens\n codebuddy context preview \"fix the login redirect\"\n see exactly what an agent would be given`,\n );\n}\n\nasync function withRuntime(\n fn: (runtime: Awaited<ReturnType<typeof createRuntime>>) => Promise<void>,\n) {\n await runSafely(async () => {\n const runtime = await createRuntime(await loadRuntimeConfig());\n try {\n await fn(runtime);\n } finally {\n await runtime.close();\n }\n });\n}\n\nasync function runSafely(fn: () => Promise<void>) {\n try {\n await fn();\n } catch (error) {\n console.error(pc.red(String(redactSecrets((error as Error).message))));\n process.exitCode = 1;\n }\n}\n\nfunction parseDuration(value: string): number {\n const match = /^(\\d+)([dhm])$/.exec(value);\n if (!match) throw new Error(\"--older-than must look like 30d, 12h, or 60m.\");\n const amount = Number(match[1]);\n const unit = match[2];\n if (unit === \"d\") return amount * 24 * 60 * 60 * 1000;\n if (unit === \"h\") return amount * 60 * 60 * 1000;\n return amount * 60 * 1000;\n}\n\nfunction printDoctor(report: Awaited<ReturnType<typeof runDoctor>>) {\n const ok = pc.green(\"ok\");\n const bad = pc.red(\"fail\");\n const warn = pc.yellow(\"warn\");\n console.log(`scaffold root: ${report.scaffold.codebuddyDir.ok ? ok : bad}`);\n if (report.scaffold.codebuddyDir.warning)\n console.log(` ${report.scaffold.codebuddyDir.warning}`);\n console.log(`policy scaffold: ${report.scaffold.policies.ok ? ok : bad}`);\n if (report.scaffold.policies.warning) console.log(` ${report.scaffold.policies.warning}`);\n console.log(`DB connectivity: ${report.db.ok ? ok : bad}`);\n if (report.db.error) console.log(` ${report.db.error}`);\n console.log(`pgvector: ${report.pgvector.ok ? ok : bad}`);\n if (report.pgvector.error) console.log(` ${report.pgvector.error}`);\n console.log(`namespace: ${report.namespace.ok ? ok : warn}`);\n console.log(\n ` runtime=${report.namespace.runtime ?? \"unset\"} default=${report.namespace.expectedDefault}`,\n );\n if (report.namespace.warning) console.log(` ${report.namespace.warning}`);\n console.log(\n `vectors: ${report.vectors.count} index=${report.vectors.index ?? \"missing\"} tuning=${report.vectors.needsTuning ? \"recommended\" : \"not-needed\"}`,\n );\n console.log(\n `recent calls: 60s=${report.usage.last60s} hour=${report.usage.lastHour} 24h=${report.usage.last24h}`,\n );\n console.log(`estimated daily cap remaining: ${report.usage.estimatedDailyCapRemaining}`);\n if (report.usage.warning80Percent)\n console.log(pc.yellow(\"usage warning: daily cap is over 80% used\"));\n console.log(\n `config permissions: ${report.config.exists ? report.config.mode : \"missing\"} ${report.config.ok ? ok : warn}`,\n );\n if (report.config.warning) console.log(` ${report.config.warning}`);\n for (const model of report.models) {\n console.log(`model ${model.id}: ${model.status}${model.error ? ` (${model.error})` : \"\"}`);\n }\n}\n\nfunction printDbDoctor(report: Awaited<ReturnType<typeof runDoctor>>) {\n const ok = pc.green(\"ok\");\n const bad = pc.red(\"fail\");\n const warn = pc.yellow(\"warn\");\n console.log(`DB connectivity: ${report.db.ok ? ok : bad}`);\n if (report.db.postgresUrlSource) console.log(` url source: ${report.db.postgresUrlSource}`);\n if (report.db.error) console.log(` ${report.db.error}`);\n console.log(`pgvector: ${report.pgvector.ok ? ok : bad}`);\n if (report.pgvector.error) console.log(` ${report.pgvector.error}`);\n console.log(`namespace: ${report.namespace.ok ? ok : warn}`);\n console.log(` runtime=${report.namespace.runtime ?? \"unset\"}`);\n if (report.namespace.warning) console.log(` ${report.namespace.warning}`);\n}\n","import { constants } from \"node:fs\";\nimport { access, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { VERSION } from \"../version.js\";\n\nexport const CODEBUDDY_WORKFLOW_PATH = \".github/workflows/codebuddy.yml\";\n\nexport type InstallGitHubWorkflowResult = {\n path: string;\n created: boolean;\n};\n\nexport function renderGitHubWorkflow(version = VERSION): string {\n return `name: CodeBuddy Change Safety\n\non:\n pull_request:\n types: [opened, synchronize, reopened]\n\npermissions:\n contents: read\n pull-requests: write\n\njobs:\n codebuddy:\n runs-on: ubuntu-latest\n steps:\n - name: Check out pull request\n uses: actions/checkout@v4\n\n - name: Set up Node\n uses: actions/setup-node@v4\n with:\n node-version: 20\n\n - name: Install CodeBuddy\n run: npm install --global --no-audit --no-fund @orquentra/codebuddy@${version}\n\n - name: Generate change report\n run: codebuddy change --json > codebuddy-report.json\n\n - name: Publish step summary\n env:\n REPORT_PATH: codebuddy-report.json\n SUMMARY_PATH: $GITHUB_STEP_SUMMARY\n run: |\n node <<'NODE'\n const fs = require(\"fs\");\n const report = JSON.parse(fs.readFileSync(process.env.REPORT_PATH, \"utf8\"));\n const status = report.status.toUpperCase();\n const findings = (report.suggestions || []).slice(0, 8).map((item) =>\n \"- **\" + item.severity + \"** \" + item.title + \" — \" + item.detail,\n );\n const body = [\n \"<!-- codebuddy-report -->\",\n \"## CodeBuddy change report\",\n \"**Status:** \" + status,\n \"**Highest risk:** \" + report.risk.highestScore + \"/100\",\n \"**Changed paths:** \" + report.paths.length,\n \"**Direct dependents:** \" + report.architecture.totalDependents,\n findings.length ? \"\\\\n### Findings\\\\n\" + findings.join(\"\\\\n\") : \"\\\\nNo findings.\",\n ].join(\"\\\\n\");\n fs.writeFileSync(\"codebuddy-report.md\", body + \"\\\\n\");\n fs.appendFileSync(process.env.SUMMARY_PATH, body + \"\\\\n\");\n NODE\n\n - name: Comment on pull request\n uses: actions/github-script@v7\n with:\n github-token: \\${{ secrets.GITHUB_TOKEN }}\n script: |\n const fs = require(\"fs\");\n const body = fs.readFileSync(\"codebuddy-report.md\", \"utf8\");\n const { owner, repo } = context.repo;\n const issue_number = context.issue.number;\n const comments = await github.paginate(github.rest.issues.listComments, {\n owner, repo, issue_number, per_page: 100,\n });\n const existing = comments.find((comment) => comment.body?.includes(\"<!-- codebuddy-report -->\"));\n if (existing) {\n await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });\n } else {\n await github.rest.issues.createComment({ owner, repo, issue_number, body });\n }\n`;\n}\n\nexport async function installGitHubWorkflow(\n repositoryRoot = process.cwd(),\n options: { force?: boolean } = {},\n): Promise<InstallGitHubWorkflowResult> {\n const root = resolve(repositoryRoot);\n const path = join(root, CODEBUDDY_WORKFLOW_PATH);\n if (!options.force) {\n try {\n await access(path, constants.F_OK);\n return { path, created: false };\n } catch {\n // The workflow does not exist yet.\n }\n }\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, renderGitHubWorkflow(), \"utf8\");\n return { path, created: true };\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { buildChangeReport, verifyChange } from \"../../change/engine.js\";\nimport type { ChangeReport, ChangeStatus, ChangeVerificationResult } from \"../../change/types.js\";\nimport { resolveNamespaceFrom } from \"../../core/config-file.js\";\n\nexport function registerChangeCommand(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const change = program.command(\"change\").description(\"Assess and verify the current change.\");\n\n change\n .command(\"report\", { isDefault: true })\n .description(\"Report whether the current change is ready, needs review, or is blocked.\")\n .option(\"--paths <paths>\", \"Comma-separated repo-relative paths to review.\")\n .option(\"--plan <id>\", \"Review the files listed in a plan.\")\n .option(\"--no-git\", \"Do not include the current Git change set.\")\n .option(\"--graphify <path>\", \"Use a Graphify graph.json for deeper architecture edges.\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .action(async (opts: ChangeOptions) => {\n await runSafely(async () => {\n const report = await buildChangeReport(toInput(opts, await resolveNamespaceFrom()));\n if (opts.json) {\n console.log(JSON.stringify(report, null, 2));\n return;\n }\n printReport(report);\n });\n });\n\n change\n .command(\"verify\")\n .description(\"Run the detected test command and report whether the change is verified.\")\n .option(\"--paths <paths>\", \"Comma-separated repo-relative paths to review.\")\n .option(\"--plan <id>\", \"Review the files listed in a plan.\")\n .option(\"--no-git\", \"Do not include the current Git change set.\")\n .option(\"--graphify <path>\", \"Use a Graphify graph.json for deeper architecture edges.\")\n .option(\"--command <command>\", \"Override the detected test command.\")\n .option(\"--timeout <ms>\", \"Stop the test command after this many milliseconds.\", Number)\n .option(\"--json\", \"Print machine-readable JSON.\")\n .action(async (opts: VerifyOptions) => {\n await runSafely(async () => {\n const result = await verifyChange({\n ...toInput(opts, await resolveNamespaceFrom()),\n ...(opts.command ? { command: opts.command } : {}),\n ...(opts.timeout !== undefined ? { timeoutMs: opts.timeout } : {}),\n });\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n printVerification(result);\n }\n if (result.test.status !== \"passed\") process.exitCode = 1;\n });\n });\n}\n\ntype ChangeOptions = {\n paths?: string;\n plan?: string;\n git?: boolean;\n json?: boolean;\n graphify?: string;\n};\n\ntype VerifyOptions = ChangeOptions & {\n command?: string;\n timeout?: number;\n};\n\nfunction toInput(opts: ChangeOptions, namespace: string) {\n return {\n namespace,\n ...(opts.paths ? { paths: parsePaths(opts.paths) } : {}),\n ...(opts.plan ? { planId: opts.plan } : {}),\n ...(opts.git !== undefined ? { useGit: opts.git } : {}),\n ...(opts.graphify ? { graphifyPath: opts.graphify } : {}),\n };\n}\n\nfunction parsePaths(value: string): string[] {\n return value\n .split(\",\")\n .map((path) => path.trim())\n .filter(Boolean);\n}\n\nfunction printReport(report: ChangeReport): void {\n console.log(`${statusBadge(report.status)} ${pc.bold(\"change report\")}`);\n if (report.paths.length === 0) {\n console.log(pc.dim(\" no changed paths detected\"));\n return;\n }\n console.log(` ${report.paths.length} path(s): ${report.paths.join(\", \")}`);\n console.log(` highest risk: ${report.risk.highestScore}`);\n console.log(\n ` architecture: ${report.architecture.totalDependents} direct dependent edge(s) across the change set (${report.architecture.source})`,\n );\n if (report.architecture.warning) console.log(pc.yellow(` ${report.architecture.warning}`));\n if (report.plan) {\n console.log(` plan: ${report.plan.id} ${report.plan.title} (${report.plan.status})`);\n if (report.plan.unexpectedPaths.length > 0)\n console.log(` plan drift: ${report.plan.unexpectedPaths.join(\", \")}`);\n if (report.plan.missingPlannedTests.length > 0)\n console.log(` planned tests still missing: ${report.plan.missingPlannedTests.join(\", \")}`);\n } else {\n console.log(pc.dim(\" plan: no active plan\"));\n }\n console.log(\n ` verification: ${report.verification.changedTestFiles.length} test file(s) changed; ${report.verification.uncoveredCodeFiles.length} code file(s) without a discovered test`,\n );\n if (report.suggestions.length > 0) {\n console.log(\"\\n findings:\");\n for (const suggestion of report.suggestions.slice(0, 8)) {\n console.log(` ${severityBadge(suggestion.severity)} ${suggestion.title}`);\n console.log(pc.dim(` ${suggestion.detail}`));\n }\n } else {\n console.log(pc.dim(\"\\n findings: none\"));\n }\n}\n\nfunction printVerification(result: ChangeVerificationResult): void {\n printReport(result.report);\n console.log(`\\n${testBadge(result.test.status)} verification`);\n console.log(` command: ${result.test.command ?? \"none detected\"}`);\n if (result.test.durationMs > 0) console.log(` duration: ${result.test.durationMs}ms`);\n if (result.test.output) {\n console.log(\" output:\");\n for (const line of result.test.output.split(\"\\n\")) console.log(` ${line}`);\n }\n}\n\nfunction statusBadge(status: ChangeStatus): string {\n if (status === \"blocked\") return pc.red(\"[blocked]\");\n if (status === \"review\") return pc.yellow(\"[review ]\");\n if (status === \"ready\") return pc.green(\"[ready ]\");\n return pc.dim(\"[no diff ]\");\n}\n\nfunction severityBadge(severity: string): string {\n if (severity === \"high\") return pc.red(\"[high]\");\n if (severity === \"medium\") return pc.yellow(\"[med ]\");\n return pc.dim(`[${severity.padEnd(5)}]`);\n}\n\nfunction testBadge(status: ChangeVerificationResult[\"test\"][\"status\"]): string {\n if (status === \"passed\") return pc.green(\"[passed ]\");\n if (status === \"timed_out\") return pc.red(\"[timeout]\");\n if (status === \"failed\") return pc.red(\"[failed ]\");\n return pc.yellow(\"[not run]\");\n}\n","import { spawn } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { access, readFile } from \"node:fs/promises\";\nimport { extname, join } from \"node:path\";\nimport { PlanFileStore, type PlanSpec } from \"../core/plan-file-store.js\";\nimport { PlanLifecycle } from \"../core/plan-lifecycle.js\";\nimport { loadGraphifyMap } from \"../map/graphify.js\";\nimport { buildArchitectureMap } from \"../map/indexer.js\";\nimport type { ArchitectureMap } from \"../map/types.js\";\nimport { assessRisk, resolveRiskPaths } from \"../risk/service.js\";\nimport type { Assessment } from \"../risk/types.js\";\nimport { generateSuggestions } from \"../suggest/engine.js\";\nimport type { SuggestResult } from \"../suggest/types.js\";\nimport type {\n ChangePlanSummary,\n ChangeReport,\n ChangeTestResult,\n ChangeVerification,\n ChangeVerificationResult,\n TestCommandSource,\n} from \"./types.js\";\n\nconst CODE_EXTENSIONS = new Set([\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"]);\nconst DEFAULT_TEST_TIMEOUT_MS = 120_000;\nconst MAX_TEST_OUTPUT_CHARS = 12_000;\n\nexport type ChangeReportInput = {\n repositoryRoot?: string;\n namespace: string;\n paths?: string[];\n planId?: string;\n useGit?: boolean;\n graphifyPath?: string;\n};\n\nexport type ChangeVerifyInput = ChangeReportInput & {\n command?: string;\n timeoutMs?: number;\n};\n\n/**\n * Compose the signals CodeBuddy already owns into one change-readiness report.\n * This is deliberately read-only: it is safe to run before every commit or in CI.\n */\nexport async function buildChangeReport(input: ChangeReportInput): Promise<ChangeReport> {\n const repositoryRoot = input.repositoryRoot ?? process.cwd();\n const hasExplicitSelection = (input.paths?.length ?? 0) > 0 || input.planId !== undefined;\n const paths =\n input.useGit === false && !hasExplicitSelection\n ? []\n : await resolveRiskPaths({\n repositoryRoot,\n ...(input.paths !== undefined ? { paths: input.paths } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n ...(input.useGit !== undefined ? { useGit: input.useGit } : { useGit: true }),\n });\n\n const planStore = new PlanFileStore(repositoryRoot);\n const [risk, suggestions, plan, architecture] = await Promise.all([\n paths.length === 0\n ? Promise.resolve(emptyAssessment())\n : assessRisk({\n repositoryRoot,\n namespace: input.namespace,\n paths,\n ...(input.useGit !== undefined ? { useGit: input.useGit } : {}),\n ...(input.planId !== undefined ? { planId: input.planId } : {}),\n }),\n paths.length === 0\n ? Promise.resolve(emptySuggestions())\n : generateSuggestions({ repositoryRoot, namespace: input.namespace, paths }),\n resolveRelevantPlan(planStore, input.namespace, input.planId),\n input.graphifyPath\n ? loadGraphifyMapOrFallback(input.graphifyPath, repositoryRoot)\n : buildArchitectureMap(repositoryRoot).then((map) => ({ map, warning: null })),\n ]);\n\n const planSummary = summarizePlan(plan, paths);\n const verification = buildVerification(paths, planSummary, suggestions);\n const { map, warning: graphifyWarning } = architecture;\n const dependentsByPath = countDependents(map.edges, paths);\n const highestScore = risk.items.reduce((highest, item) => Math.max(highest, item.score), 0);\n const status = getStatus(paths, highestScore, suggestions, verification);\n\n return {\n status,\n paths,\n plan: planSummary,\n risk: { highestScore, items: risk.items },\n architecture: {\n dependentsByPath,\n totalDependents: Object.values(dependentsByPath).reduce((sum, count) => sum + count, 0),\n source: input.graphifyPath && !graphifyWarning ? \"graphify\" : \"imports\",\n ...(graphifyWarning ? { warning: graphifyWarning } : {}),\n },\n suggestions: suggestions.suggestions,\n verification,\n };\n}\n\n/** Run the repository's verification command after producing the change report. */\nexport async function verifyChange(input: ChangeVerifyInput): Promise<ChangeVerificationResult> {\n const report = await buildChangeReport(input);\n const detected = input.command\n ? { command: input.command, source: \"explicit\" as const }\n : await detectTestCommand(input.repositoryRoot ?? process.cwd());\n\n if (!detected) {\n return {\n report,\n test: {\n status: \"not_run\",\n command: null,\n source: null,\n exitCode: null,\n signal: null,\n durationMs: 0,\n output: \"No test command found. Pass --command or add a test script to package.json.\",\n },\n };\n }\n\n return {\n report,\n test: await runTestCommand(\n detected.command,\n detected.source,\n input.repositoryRoot ?? process.cwd(),\n input.timeoutMs ?? DEFAULT_TEST_TIMEOUT_MS,\n ),\n };\n}\n\nasync function detectTestCommand(\n repositoryRoot: string,\n): Promise<{ command: string; source: TestCommandSource } | null> {\n const packagePath = join(repositoryRoot, \"package.json\");\n try {\n const packageJson = JSON.parse(await readFile(packagePath, \"utf8\")) as {\n scripts?: { test?: unknown };\n packageManager?: unknown;\n };\n if (typeof packageJson.scripts?.test === \"string\") {\n return {\n command: `${packageManagerName(packageJson.packageManager)} test`,\n source: \"package_script\",\n };\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n }\n\n for (const candidate of [\n [\"pnpm-lock.yaml\", \"pnpm test\"],\n [\"yarn.lock\", \"yarn test\"],\n [\"bun.lockb\", \"bun test\"],\n [\"bun.lock\", \"bun test\"],\n [\"package-lock.json\", \"npm test\"],\n ] as const) {\n try {\n await access(join(repositoryRoot, candidate[0]), constants.F_OK);\n return { command: candidate[1], source: \"package_manager\" };\n } catch {\n // Try the next package-manager marker.\n }\n }\n return null;\n}\n\nfunction packageManagerName(value: unknown): string {\n if (typeof value !== \"string\") return \"npm\";\n const name = value.split(/[\\s@]/, 1)[0] ?? \"npm\";\n return [\"npm\", \"pnpm\", \"yarn\", \"bun\"].includes(name) ? name : \"npm\";\n}\n\nfunction runTestCommand(\n command: string,\n source: TestCommandSource,\n repositoryRoot: string,\n timeoutMs: number,\n): Promise<ChangeTestResult> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new Error(\"--timeout must be a positive number of milliseconds.\");\n }\n return new Promise((resolve) => {\n const startedAt = Date.now();\n const child = spawn(command, {\n cwd: repositoryRoot,\n env: process.env,\n shell: true,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let output = \"\";\n let timedOut = false;\n const append = (chunk: Buffer | string) => {\n output += chunk.toString();\n if (output.length > MAX_TEST_OUTPUT_CHARS) {\n output = `[output truncated; showing last ${MAX_TEST_OUTPUT_CHARS} characters]\\n${output.slice(-MAX_TEST_OUTPUT_CHARS)}`;\n }\n };\n child.stdout.on(\"data\", append);\n child.stderr.on(\"data\", append);\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n }, timeoutMs);\n child.on(\"close\", (exitCode, signal) => {\n clearTimeout(timer);\n resolve({\n status: timedOut ? \"timed_out\" : exitCode === 0 ? \"passed\" : \"failed\",\n command,\n source,\n exitCode,\n signal,\n durationMs: Date.now() - startedAt,\n output: output.trim(),\n });\n });\n child.on(\"error\", (error) => {\n clearTimeout(timer);\n resolve({\n status: \"failed\",\n command,\n source,\n exitCode: null,\n signal: null,\n durationMs: Date.now() - startedAt,\n output: `${output.trim()}\\n${error.message}`.trim(),\n });\n });\n });\n}\n\n/**\n * An explicit `--graphify <path>` that cannot be read must not sink the whole\n * report: fall back to the import scan and carry the reason into the report, so\n * the failure is visible rather than silently swallowed.\n */\nasync function loadGraphifyMapOrFallback(\n graphifyPath: string,\n repositoryRoot: string,\n): Promise<{ map: ArchitectureMap; warning: string | null }> {\n try {\n return { map: await loadGraphifyMap(graphifyPath, repositoryRoot), warning: null };\n } catch (error) {\n return {\n map: await buildArchitectureMap(repositoryRoot),\n warning: `Graphify graph unusable, fell back to the import scan: ${(error as Error).message}`,\n };\n }\n}\n\nfunction emptyAssessment(): Assessment {\n return {\n items: [],\n stats: { pathsConsidered: 0, itemsProduced: 0, signalsRun: 0, perSignal: [] },\n };\n}\n\nfunction emptySuggestions(): SuggestResult {\n return {\n suggestions: [],\n stats: { pathsConsidered: 0, produced: 0, byCategory: {}, bySeverity: {} },\n };\n}\n\nasync function resolveRelevantPlan(\n store: PlanFileStore,\n namespace: string,\n planId?: string,\n): Promise<PlanSpec | null> {\n if (planId) {\n try {\n return await store.readPlan(planId);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n }\n return new PlanLifecycle(store).current(namespace);\n}\n\nfunction summarizePlan(plan: PlanSpec | null, paths: string[]): ChangePlanSummary | null {\n if (!plan) return null;\n const plannedPaths = plan.filesToTouch.map((file) => file.path).sort();\n const plannedSet = new Set(plannedPaths);\n const unexpectedPaths = paths.filter((path) => !plannedSet.has(path));\n const plannedTests = plan.testsToAdd.map((test) => test.path).sort();\n const changed = new Set(paths);\n const missingPlannedTests = plannedTests.filter((path) => !changed.has(path));\n return {\n id: plan.id,\n title: plan.title,\n status: plan.status,\n plannedPaths,\n unexpectedPaths,\n plannedTests,\n missingPlannedTests,\n };\n}\n\nfunction buildVerification(\n paths: string[],\n plan: ChangePlanSummary | null,\n suggestions: { suggestions: ChangeReport[\"suggestions\"] },\n): ChangeVerification {\n const changedTestFiles = paths.filter(isTestFile);\n const changedCodeFiles = paths.filter((path) => isCodeFile(path) && !isTestFile(path));\n const uncovered = new Set(\n suggestions.suggestions\n .filter((suggestion) => suggestion.category === \"missing_test\" && suggestion.path)\n .map((suggestion) => suggestion.path as string),\n );\n const plannedTests = plan?.plannedTests ?? [];\n const missingPlannedTests = plan?.missingPlannedTests ?? [];\n return {\n changedCodeFiles,\n changedTestFiles,\n uncoveredCodeFiles: changedCodeFiles.filter((path) => uncovered.has(path)),\n plannedTests,\n missingPlannedTests,\n readyToVerify: changedTestFiles.length > 0 || changedCodeFiles.length === 0,\n };\n}\n\nfunction countDependents(\n edges: Array<{ from: string; to: string }>,\n paths: string[],\n): Record<string, number> {\n const targets = new Set(paths);\n const counts: Record<string, number> = {};\n for (const path of paths) counts[path] = 0;\n for (const edge of edges) {\n if (targets.has(edge.to)) counts[edge.to] = (counts[edge.to] ?? 0) + 1;\n }\n return counts;\n}\n\nfunction getStatus(\n paths: string[],\n highestRisk: number,\n suggestions: { suggestions: ChangeReport[\"suggestions\"] },\n verification: ChangeVerification,\n): ChangeReport[\"status\"] {\n if (paths.length === 0) return \"no_changes\";\n if (highestRisk >= 75 || suggestions.suggestions.some((item) => item.severity === \"high\")) {\n return \"blocked\";\n }\n if (\n highestRisk >= 50 ||\n suggestions.suggestions.some((item) => item.severity === \"medium\") ||\n verification.uncoveredCodeFiles.length > 0 ||\n verification.missingPlannedTests.length > 0\n ) {\n return \"review\";\n }\n return \"ready\";\n}\n\nfunction isCodeFile(path: string): boolean {\n return CODE_EXTENSIONS.has(extname(path).toLowerCase());\n}\n\nfunction isTestFile(path: string): boolean {\n return /(^|\\/)(__tests__\\/|.*\\.(test|spec)\\.)/.test(path);\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { writeAtomic } from \"../../core/markdown-store-fs.js\";\n\nexport type ClaudeDesktopEntry = {\n command: string;\n args: string[];\n env?: Record<string, string>;\n};\n\nexport type ClaudeDesktopConfig = {\n mcpServers?: Record<string, ClaudeDesktopEntry>;\n};\n\nexport function claudeDesktopConfigPath(home = process.env.HOME ?? \"\"): string {\n if (process.platform === \"darwin\") {\n return join(home, \"Library\", \"Application Support\", \"Claude\", \"claude_desktop_config.json\");\n }\n if (process.platform === \"win32\") {\n return join(process.env.APPDATA ?? home, \"Claude\", \"claude_desktop_config.json\");\n }\n return join(home, \".config\", \"Claude\", \"claude_desktop_config.json\");\n}\n\nexport async function readClaudeConfig(path: string): Promise<ClaudeDesktopConfig> {\n if (!existsSync(path)) return {};\n try {\n return JSON.parse(await readFile(path, \"utf8\")) as ClaudeDesktopConfig;\n } catch (error) {\n throw new Error(\n `Failed to parse Claude Desktop config at ${path}: ${(error as Error).message}`,\n );\n }\n}\n\nexport async function writeClaudeConfig(path: string, config: ClaudeDesktopConfig): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n // Atomic + 0600: this config carries env secrets (HF token, DATABASE_URL).\n // A crash mid-write must never truncate the user's other MCP entries.\n await writeAtomic(path, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n}\n\n/**\n * Resolve the absolute path to this codebuddy install's CLI entrypoint.\n *\n * Has to cope with three layouts:\n * - dev: `tsx src/cli/index.ts` — argv[1] is the .ts file\n * - built locally: `node dist/cli/index.js serve` — argv[1] is dist/cli/index.js\n * - npm bin: `/usr/local/bin/codebuddy ...` — argv[1] is the resolved bin\n *\n * `process.argv[1]` is the file Node was invoked with, which IS the CLI entry\n * in every supported case. We use it as the source of truth. import.meta.url\n * is unreliable here because tsup bundles src/cli/* into a single dist file,\n * so the source-relative path math (`..`) lands on the SDK barrel\n * (dist/index.js) instead of the CLI (dist/cli/index.js).\n */\nexport function resolveCliEntrypoint(): string {\n const fromArgv = process.argv[1];\n if (fromArgv && existsSync(fromArgv)) return fromArgv;\n\n // Fallback for the unlikely case where argv[1] is missing (eval'd, embedded\n // host, etc): walk the source layout.\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n resolve(here, \"index.js\"), // bundled: here = dist/cli/\n resolve(here, \"..\", \"cli\", \"index.js\"), // source: here = src/cli/commands/\n resolve(here, \"..\", \"index.js\"),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n // Last resort — return argv[1] even if it doesn't exist, so the error\n // surfaces with the real path the caller saw rather than a stale guess.\n return fromArgv ?? candidates[0] ?? \"\";\n}\n\nexport type InstallEntryOptions = {\n namespace: string;\n projectRoot?: string;\n hfToken?: string;\n groqApiKey?: string;\n databaseUrl?: string;\n serverName?: string;\n};\n\nexport function buildEntry(options: InstallEntryOptions): ClaudeDesktopEntry {\n const env: Record<string, string> = {\n CODEBUDDY_NAMESPACE: options.namespace,\n CODEBUDDY_PROJECT_ROOT: resolve(options.projectRoot ?? process.cwd()),\n };\n if (options.hfToken) env.HF_TOKEN = options.hfToken;\n if (options.groqApiKey) env.GROQ_API_KEY = options.groqApiKey;\n if (options.databaseUrl) env.DATABASE_URL = options.databaseUrl;\n return {\n command: \"node\",\n args: [resolveCliEntrypoint(), \"serve\"],\n env,\n };\n}\n\nexport type InstallResult = {\n path: string;\n serverKey: string;\n created: boolean;\n};\n\nexport async function installClaudeEntry(options: InstallEntryOptions): Promise<InstallResult> {\n const path = claudeDesktopConfigPath();\n const config = await readClaudeConfig(path);\n config.mcpServers ??= {};\n const serverKey = options.serverName ?? `codebuddy-${options.namespace}`;\n const existed = config.mcpServers[serverKey] !== undefined;\n config.mcpServers[serverKey] = buildEntry(options);\n await writeClaudeConfig(path, config);\n return { path, serverKey, created: !existed };\n}\n\nexport async function removeClaudeEntry(\n serverKey: string,\n): Promise<{ removed: boolean; path: string }> {\n const path = claudeDesktopConfigPath();\n const config = await readClaudeConfig(path);\n if (!config.mcpServers || !(serverKey in config.mcpServers)) {\n return { removed: false, path };\n }\n delete config.mcpServers[serverKey];\n await writeClaudeConfig(path, config);\n return { removed: true, path };\n}\n\nexport async function listClaudeEntries(): Promise<{\n path: string;\n entries: Array<{ key: string; namespace: string | null; databaseUrl: string | null }>;\n}> {\n const path = claudeDesktopConfigPath();\n const config = await readClaudeConfig(path);\n const entries = Object.entries(config.mcpServers ?? {})\n .filter(([key]) => key === \"codebuddy\" || key.startsWith(\"codebuddy-\"))\n .map(([key, entry]) => ({\n key,\n namespace: entry.env?.CODEBUDDY_NAMESPACE ?? null,\n databaseUrl: entry.env?.DATABASE_URL ?? null,\n }));\n return { path, entries };\n}\n","import { relative } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n AUTOMATION_MODES,\n CLIENT_ADAPTERS,\n CLIENT_IDS,\n LIFECYCLE_EVENTS,\n MODE_LABELS,\n parseClient,\n parseMode,\n supportedModes,\n} from \"../../clients/adapters.js\";\nimport { measureClientCosts } from \"../../clients/cost.js\";\nimport {\n type ClientReport,\n detectClient,\n installClient,\n uninstallClient,\n} from \"../../clients/install.js\";\nimport { verifyClient } from \"../../clients/verify.js\";\nimport { estimateTokens } from \"../../savings/tokens.js\";\nimport { renderManagedBlock } from \"../../templates/install.js\";\n\n/**\n * `codebuddy clients` selects one explicit automation mode per coding agent and\n * reports, per host, which lifecycle events CodeBuddy automates and which are\n * missing. Install/uninstall are idempotent and only touch CodeBuddy's entries.\n */\nexport function registerClientsCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const clients = program\n .command(\"clients\")\n .description(\"Client adapters: capabilities and explicit automation modes per coding agent.\");\n\n clients\n .command(\"list\")\n .option(\"--namespace <name>\", \"Namespace whose MCP entries to look for.\")\n .description(\"Show each client's surfaces, lifecycle coverage, and mode in this repo.\")\n .action(async (opts: { namespace?: string }) => {\n await runSafely(async () => {\n for (const client of CLIENT_IDS) {\n const adapter = CLIENT_ADAPTERS[client];\n const status = await detectClient(client, process.cwd(), opts.namespace);\n const mcp = \"file\" in adapter.mcp ? adapter.mcp.file : \"global (--global)\";\n const lifecycle = LIFECYCLE_EVENTS.map((event) =>\n adapter.hookEvents.includes(event) ? pc.green(event) : pc.dim(`${event}✗`),\n ).join(\" \");\n const ruleCost = supportedModes(adapter)\n .flatMap((mode) =>\n mode === \"mcp-only\"\n ? []\n : [`${mode} ~${estimateTokens(renderManagedBlock(client, mode))}`],\n )\n .join(\", \");\n console.log(\n `${pc.bold(adapter.name)} (${client}) ${pc.dim(`verified ${adapter.host.bin} ${adapter.host.verified}`)}`,\n );\n console.log(\n ` rules ${adapter.rulesFile} · mcp ${mcp} · modes ${supportedModes(adapter).join(\"|\")}`,\n );\n console.log(` lifecycle: ${lifecycle}`);\n console.log(` rules block tokens: ${ruleCost}`);\n console.log(\n ` this repo: ${status.mode === \"none\" ? pc.dim(\"not installed\") : pc.cyan(status.mode)}`,\n );\n if (adapter.gap) console.log(pc.dim(` missing: ${adapter.gap}`));\n if (adapter.note) console.log(pc.dim(` note: ${adapter.note}`));\n for (const warning of status.warnings) console.log(pc.yellow(` ! ${warning}`));\n }\n console.log(pc.dim(\"Per-turn token cost per client: codebuddy clients cost\"));\n });\n });\n\n clients\n .command(\"install\")\n .argument(\"<client>\", `One of: ${CLIENT_IDS.join(\", \")}.`)\n .requiredOption(\"--mode <mode>\", `One of: ${AUTOMATION_MODES.join(\", \")}.`)\n .option(\"--namespace <name>\", \"Namespace for the MCP entry (defaults to config/folder).\")\n .option(\"--global\", \"Also add the MCP entry to the global config (Codex, Hermes).\")\n .description(\"Apply one automation mode: rules block, hooks, and MCP config.\")\n .action(\n async (client: string, opts: { mode: string; namespace?: string; global?: boolean }) => {\n await runSafely(async () => {\n const mode = parseMode(opts.mode);\n const report = await installClient({\n client: parseClient(client),\n mode,\n ...(opts.namespace ? { namespace: opts.namespace } : {}),\n ...(opts.global ? { global: true } : {}),\n });\n printReport(report, `${MODE_LABELS[mode]} mode`);\n });\n },\n );\n\n clients\n .command(\"uninstall\")\n .argument(\"<client>\", `One of: ${CLIENT_IDS.join(\", \")}.`)\n .option(\"--namespace <name>\", \"Namespace of the MCP entry to remove.\")\n .option(\"--global\", \"Also remove the MCP entry from the global config (Codex, Hermes).\")\n .description(\"Remove CodeBuddy's rules block, hooks, and MCP entry (user config untouched).\")\n .action(async (client: string, opts: { namespace?: string; global?: boolean }) => {\n await runSafely(async () => {\n const report = await uninstallClient({\n client: parseClient(client),\n ...(opts.namespace ? { namespace: opts.namespace } : {}),\n ...(opts.global ? { global: true } : {}),\n });\n printReport(report, \"uninstalled\");\n });\n });\n\n clients\n .command(\"verify\")\n .argument(\"[client]\", `One of: ${CLIENT_IDS.join(\", \")} (default: all).`)\n .option(\"--namespace <name>\", \"Namespace whose MCP entries to look for.\")\n .description(\n \"Compare installed hosts with the verified versions; run no-model conformance checks.\",\n )\n .action(async (client: string | undefined, opts: { namespace?: string }) => {\n await runSafely(async () => {\n const targets = client ? [parseClient(client)] : CLIENT_IDS;\n for (const id of targets) {\n const report = await verifyClient(\n id,\n opts.namespace ? { namespace: opts.namespace } : {},\n );\n const drift =\n report.drift === \"match\"\n ? pc.green(\"match\")\n : report.drift === \"drift\"\n ? pc.yellow(`drift (installed ${report.installed})`)\n : pc.dim(\"not installed\");\n console.log(\n `${pc.bold(CLIENT_ADAPTERS[id].name)}: verified ${report.verified} · ${drift}`,\n );\n console.log(\n ` events: ${report.events.map(({ event, wired }) => (wired ? pc.green(event) : pc.dim(`${event}✗`))).join(\" \")}`,\n );\n for (const check of report.checks) {\n const label =\n check.status === \"pass\"\n ? pc.green(\"pass\")\n : check.status === \"fail\"\n ? pc.red(\"fail\")\n : pc.dim(\"skip\");\n console.log(` ${label} ${check.name}: ${check.detail}`);\n }\n }\n });\n });\n\n clients\n .command(\"cost\")\n .option(\"--namespace <name>\", \"Namespace to measure (defaults to config/folder).\")\n .option(\"--json\", \"Print the measurements as JSON.\")\n .description(\"Measured per-turn CodeBuddy token cost per client and mode, for this repo.\")\n .action(async (opts: { namespace?: string; json?: boolean }) => {\n await runSafely(async () => {\n const costs = await measureClientCosts(process.cwd(), opts.namespace);\n if (opts.json) {\n console.log(JSON.stringify(costs, null, 2));\n return;\n }\n console.log(\n \"client mode rules mcp-schema block(1st) block(later) turn(1st) turn(later)\",\n );\n for (const cost of costs) {\n const fixed = cost.rules + cost.mcpSchema;\n console.log(\n [\n cost.client.padEnd(10),\n cost.mode.padEnd(7),\n String(cost.rules).padStart(5),\n String(cost.mcpSchema).padStart(11),\n String(cost.firstBlock).padStart(11),\n String(cost.laterBlock).padStart(13),\n String(fixed + cost.firstBlock).padStart(10),\n String(fixed + cost.laterBlock).padStart(12),\n ].join(\" \"),\n );\n }\n console.log(\n pc.dim(\n \"Measured with the cl100k estimator on the generated rules block, the MCP tools/list payload and this repo's hook block. Host framing (host-dependent, not measured):\",\n ),\n );\n for (const id of CLIENT_IDS) console.log(pc.dim(` ${id}: ${CLIENT_ADAPTERS[id].framing}`));\n });\n });\n}\n\nfunction printReport(report: ClientReport, title: string): void {\n console.log(`${pc.bold(CLIENT_ADAPTERS[report.client].name)}: ${title}`);\n for (const step of report.steps) {\n const where = relative(process.cwd(), step.target) || step.target;\n const label = step.action === \"unchanged\" ? pc.dim(step.action) : pc.green(step.action);\n console.log(` ${step.surface.padEnd(5)} ${label} ${where}`);\n }\n for (const note of report.notes) console.log(pc.dim(` ${note}`));\n}\n","/**\n * Client adapters: the one place that says, per coding agent, where its rules\n * file lives, how its MCP config is written, and which lifecycle events\n * CodeBuddy can wire automatically. Everything else (rules install, hooks,\n * `codebuddy clients`) reads this table instead of branching on client names.\n *\n * Capabilities are what CodeBuddy actually implements today, not what the host\n * might support: a host with plugin events but no CodeBuddy bridge reports its\n * lifecycle as missing, with the reason in `gap`.\n */\n\nexport const AUTOMATION_MODES = [\"agent\", \"hooks\", \"mcp-only\", \"lean\"] as const;\nexport type AutomationMode = (typeof AUTOMATION_MODES)[number];\n\nexport const MODE_LABELS: Record<AutomationMode, string> = {\n agent: \"agent-driven\",\n hooks: \"hook-driven\",\n \"mcp-only\": \"MCP-only\",\n lean: \"Lean (token reduction)\",\n};\n\nexport const LIFECYCLE_EVENTS = [\"prompt\", \"edit\", \"turn-end\", \"compaction\"] as const;\nexport type LifecycleEvent = (typeof LIFECYCLE_EVENTS)[number];\n\n/**\n * Project-local JSON MCP config CodeBuddy writes, or a global config file it\n * edits only with `clients install --global` (otherwise `manual` is shown).\n */\nexport type McpTarget =\n | { file: string; format: \"mcpServers\" | \"opencode\" }\n | { global: \"codex\" | \"hermes\"; manual: string };\n\n/** Where a client's CodeBuddy lifecycle hooks are installed (see `hooks/install.ts`). */\nexport type HookSurface = \"claude-settings\" | \"opencode-plugin\" | \"hermes-plugin\";\n\nexport type ClientAdapter = {\n name: string;\n /** Host binary and the version (or source commit) this adapter was verified against. */\n host: { bin: string; verified: string };\n rulesFile: \"CLAUDE.md\" | \"AGENTS.md\";\n mcp: McpTarget;\n /** Lifecycle events CodeBuddy hooks handle automatically for this client. */\n hookEvents: readonly LifecycleEvent[];\n /** Set exactly when `hookEvents` is non-empty. */\n hooks?: HookSurface;\n /** Why lifecycle automation is missing (verified host surface, not certification). */\n gap?: string;\n /** Host-side caveat that is not a missing lifecycle event. */\n note?: string;\n /** How the host frames CodeBuddy's per-turn costs (source- or live-verified, not measured). */\n framing: string;\n /** The host drops an injected context block after the turn, so each prompt gets it in full. */\n ephemeralContext?: true;\n /** The host lists MCP tools by name and loads a schema only when a tool is used. */\n defersMcpSchemas?: true;\n};\n\nexport const CLIENT_IDS = [\"claude\", \"codex\", \"opencode\", \"freebuff\", \"hermes\"] as const;\nexport type ClientId = (typeof CLIENT_IDS)[number];\n\nexport const CLIENT_ADAPTERS: Record<ClientId, ClientAdapter> = {\n claude: {\n name: \"Claude Code\",\n host: { bin: \"claude\", verified: \"2.1.287\" },\n rulesFile: \"CLAUDE.md\",\n mcp: { file: \".mcp.json\", format: \"mcpServers\" },\n hookEvents: LIFECYCLE_EVENTS,\n hooks: \"claude-settings\",\n framing:\n \"UserPromptSubmit stdout is added to the prompt as hook context (wrapper is host-defined); unchanged lines are not resent; MCP schemas may be deferred by tool search\",\n defersMcpSchemas: true,\n },\n codex: {\n name: \"Codex\",\n host: { bin: \"codex\", verified: \"0.163.0\" },\n rulesFile: \"AGENTS.md\",\n mcp: { global: \"codex\", manual: \"codebuddy codex install (global ~/.codex/config.toml)\" },\n hookEvents: [],\n gap: \"no CodeBuddy hook adapter for Codex yet\",\n framing: \"agent mode only; AGENTS.md is part of the instructions every request\",\n },\n opencode: {\n name: \"OpenCode\",\n host: { bin: \"opencode\", verified: \"1.18.32\" },\n rulesFile: \"AGENTS.md\",\n // opencode.jsonc is used instead when it is the only one present.\n mcp: { file: \"opencode.json\", format: \"opencode\" },\n // Plugin bridge: chat.message (prompt), tool.execute.after (edit),\n // session.idle (turn-end), session.compacted.\n hookEvents: LIFECYCLE_EVENTS,\n hooks: \"opencode-plugin\",\n framing:\n \"block appended verbatim as a synthetic text part that stays in history; unchanged lines are not resent\",\n },\n freebuff: {\n name: \"Freebuff\",\n // Not installed; checked against source CodebuffAI/freebuff@f9ae64dd.\n host: { bin: \"freebuff\", verified: \"source f9ae64dd\" },\n rulesFile: \"AGENTS.md\",\n mcp: { file: \".agents/mcp.json\", format: \"mcpServers\" },\n hookEvents: [],\n gap: \"no lifecycle surface at CodebuffAI/freebuff@f9ae64dd: no user hook config, and the SDK run_file_change_hooks tool is a no-op (sdk/src/tools/run-file-change-hooks.ts)\",\n note: \"reads AGENTS.md, and CLAUDE.md only in a directory without one (common/src/constants/knowledge.ts)\",\n framing:\n \"agent mode only; AGENTS.md is sent as a fenced block under a fixed project-instructions header\",\n },\n hermes: {\n name: \"Hermes Agent\",\n host: { bin: \"hermes\", verified: \"0.17.0\" },\n rulesFile: \"AGENTS.md\",\n mcp: {\n global: \"hermes\",\n manual: \"add a codebuddy entry under mcp_servers in ~/.hermes/config.yaml\",\n },\n // Project Python plugin: pre_llm_call (prompt), post_tool_call (edit),\n // on_session_end (turn-end). Compaction has no plugin hook; the context is\n // resent in full every turn and the session ledger reset with it.\n hookEvents: LIFECYCLE_EVENTS,\n hooks: \"hermes-plugin\",\n ephemeralContext: true,\n framing:\n \"block appended to this turn's user message only and never persisted, so it is resent in full every turn\",\n note: \"hooks load only with HERMES_ENABLE_PROJECT_PLUGINS=1 and codebuddy in plugins.enabled of ~/.hermes/config.yaml; .hermes.md takes precedence over AGENTS.md\",\n },\n};\n\nexport function parseClient(value: string | undefined): ClientId {\n const client = value ?? \"claude\";\n if (!(CLIENT_IDS as readonly string[]).includes(client)) {\n throw new Error(`Unknown client \"${client}\". Use one of: ${CLIENT_IDS.join(\", \")}.`);\n }\n return client as ClientId;\n}\n\nexport function parseMode(value: string): AutomationMode {\n if (!(AUTOMATION_MODES as readonly string[]).includes(value)) {\n throw new Error(`Unknown mode \"${value}\". Use one of: ${AUTOMATION_MODES.join(\", \")}.`);\n }\n return value as AutomationMode;\n}\n\n/** Hook-driven mode needs every lifecycle event wired; partial coverage would drop captures. */\nexport function supportedModes(adapter: ClientAdapter): AutomationMode[] {\n return adapter.hookEvents.length === LIFECYCLE_EVENTS.length\n ? [...AUTOMATION_MODES]\n : [\"agent\", \"mcp-only\"];\n}\n\n/** Other clients that read the same rules file (a managed block there serves all of them). */\nexport function sharedRulesReaders(client: ClientId): ClientId[] {\n const file = CLIENT_ADAPTERS[client].rulesFile;\n return CLIENT_IDS.filter((id) => id !== client && CLIENT_ADAPTERS[id].rulesFile === file);\n}\n","import { mkdtemp, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { buildBeforeEditContext, buildBootstrapContext } from \"../context/engine.js\";\nimport { SessionCapsuleLedger } from \"../context/session-ledger.js\";\nimport { resolveNamespaceFrom } from \"../core/config-file.js\";\nimport { renderLeanBlock } from \"../hooks/lean.js\";\nimport { renderContextBlock } from \"../hooks/runtime.js\";\nimport { registerCodeBuddyTools } from \"../mcp/tools/index.js\";\nimport { estimateTokens } from \"../savings/tokens.js\";\nimport { renderManagedBlock } from \"../templates/install.js\";\nimport { VERSION } from \"../version.js\";\nimport { CLIENT_ADAPTERS, CLIENT_IDS, type ClientId, supportedModes } from \"./adapters.js\";\n\n/**\n * Per-turn CodeBuddy token cost per client, measured on the real generated\n * artifacts with the shared cl100k estimator: the managed rules block, the MCP\n * `tools/list` payload, and the hook context block for this repo on the first\n * prompt and on a later prompt with nothing changed. Nothing is estimated by\n * hand; what the host adds or drops around them is the adapter's `framing`.\n */\n\nexport type ClientCost = {\n client: ClientId;\n mode: \"agent\" | \"hooks\" | \"lean\";\n rules: number;\n mcpSchema: number;\n /** Hook context block on the first prompt of a session (0 in agent mode). */\n firstBlock: number;\n /** Hook context block on a later prompt with nothing changed. */\n laterBlock: number;\n};\n\n/**\n * The MCP server's tools/list payload as a client receives it (`full`), and the\n * name listing a schema-deferring host sends instead (`listing`).\n */\nasync function mcpSchemaTokens(\n root: string,\n namespace: string,\n): Promise<{ full: number; listing: number }> {\n const server = new McpServer({ name: \"codebuddy\", version: VERSION });\n registerCodeBuddyTools(server, {\n config: { namespace, projectRoot: root },\n database: {\n get: () => Promise.reject(new Error(\"not used\")),\n status: () => ({ available: false, state: \"idle\" }),\n },\n });\n const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();\n const client = new Client({ name: \"codebuddy-cost\", version: VERSION });\n await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);\n try {\n const { tools } = await client.listTools();\n return {\n full: estimateTokens(tools),\n listing: estimateTokens(tools.map((tool) => tool.name).join(\"\\n\")),\n };\n } finally {\n await client.close();\n }\n}\n\n/**\n * The hook block for this repo on a first and a repeated prompt, ledger kept in\n * a temp dir; `lean` is the lean pointer block for the same targets.\n */\nasync function hookBlockTokens(\n root: string,\n namespace: string,\n): Promise<{ first: number; later: number; lean: { first: number; later: number } }> {\n const bootstrap = await buildBootstrapContext({ repositoryRoot: root, namespace });\n const beforeEdit = await buildBeforeEditContext({\n repositoryRoot: root,\n namespace,\n useGit: true,\n }).catch(() => null);\n const scratch = await mkdtemp(join(tmpdir(), \"codebuddy-cost-\"));\n try {\n const ledger = new SessionCapsuleLedger(scratch);\n const render = () => renderContextBlock(bootstrap, beforeEdit, ledger, \"cost\", true);\n const first = await render();\n await ledger.markSent(\"cost\", first.emitted);\n const later = await render();\n const pointers = (beforeEdit?.targetPaths ?? []).map((path) => ({ path, symbols: [] }));\n const renderLean = () =>\n renderLeanBlock({ repositoryRoot: root, prompt: \"\", pointers, ledger, sessionId: \"lean\" });\n const leanFirst = await renderLean();\n await ledger.markSent(\"lean\", leanFirst.emitted);\n const leanLater = await renderLean();\n return {\n first: estimateTokens(first.text),\n later: estimateTokens(later.text),\n lean: { first: estimateTokens(leanFirst.text), later: estimateTokens(leanLater.text) },\n };\n } finally {\n await rm(scratch, { recursive: true, force: true });\n }\n}\n\nexport async function measureClientCosts(\n projectRoot = process.cwd(),\n namespace?: string,\n): Promise<ClientCost[]> {\n const root = resolve(projectRoot);\n const ns = namespace ?? (await resolveNamespaceFrom(root));\n const mcpSchema = await mcpSchemaTokens(root, ns);\n const block = await hookBlockTokens(root, ns);\n return CLIENT_IDS.flatMap((client) => {\n const adapter = CLIENT_ADAPTERS[client];\n return supportedModes(adapter).flatMap((mode): ClientCost[] => {\n if (mode === \"mcp-only\") return [];\n if (mode === \"lean\") {\n // Lean sends no rules and registers no MCP server: only the pointer line.\n const later = adapter.ephemeralContext ? block.lean.first : block.lean.later;\n return [\n { client, mode, rules: 0, mcpSchema: 0, firstBlock: block.lean.first, laterBlock: later },\n ];\n }\n const hooks = mode === \"hooks\";\n const later = adapter.ephemeralContext ? block.first : block.later;\n return [\n {\n client,\n mode,\n rules: estimateTokens(renderManagedBlock(client, mode)),\n mcpSchema: adapter.defersMcpSchemas ? mcpSchema.listing : mcpSchema.full,\n firstBlock: hooks ? block.first : 0,\n laterBlock: hooks ? later : 0,\n },\n ];\n });\n });\n}\n","import { readFile, rm } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport type { AutomationMode } from \"../clients/adapters.js\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\nimport { rulesFileHooked } from \"../hooks/install.js\";\nimport {\n defaultRulesFile,\n parseWorkflowMode,\n renderWorkflowTemplate,\n type WorkflowClient,\n} from \"./workflow.js\";\n\n/**\n * Safe, visible install of the workflow template into a client's Markdown rules\n * file. The template is written inside HTML-comment markers so:\n * - updates are idempotent (the block is replaced, not appended again);\n * - the user's own content around the block is preserved untouched;\n * - the markers make it obvious exactly what CodeBuddy manages.\n * No hidden mutation: the caller sees the resolved path and the action taken.\n */\n\nconst START_MARKER = \"<!-- codebuddy:workflow:start -->\";\nconst END_MARKER = \"<!-- codebuddy:workflow:end -->\";\n\nexport type InstallAction = \"created\" | \"added\" | \"updated\" | \"removed\" | \"unchanged\";\n\nexport type InstallResult = {\n path: string;\n client: WorkflowClient;\n action: InstallAction;\n};\n\nexport type InstallRulesOptions = {\n client: WorkflowClient;\n projectRoot?: string;\n /** Override the target file (defaults to CLAUDE.md / AGENTS.md). */\n targetPath?: string;\n /** `mcp-only` removes the managed block. Defaults to `defaultRulesMode`. */\n mode?: AutomationMode;\n /** Only rewrite an existing managed block; never add one (mode reconciliation). */\n onlyIfManaged?: boolean;\n};\n\nexport function renderManagedBlock(\n client: WorkflowClient,\n mode: Exclude<AutomationMode, \"mcp-only\"> = \"agent\",\n): string {\n return `${START_MARKER}\\n${renderWorkflowTemplate(client, mode)}\\n${END_MARKER}\\n`;\n}\n\nexport async function installWorkflowRules(options: InstallRulesOptions): Promise<InstallResult> {\n const projectRoot = resolve(options.projectRoot ?? process.cwd());\n const path = options.targetPath ?? join(projectRoot, defaultRulesFile(options.client));\n\n const existing = await readIfPresent(path);\n const mode = options.mode ?? (await defaultRulesMode(options.client, projectRoot));\n if (options.onlyIfManaged && (existing === null || !hasManagedBlock(existing))) {\n return { path, client: options.client, action: \"unchanged\" };\n }\n if (mode === \"mcp-only\") {\n const content = existing === null ? null : removeBlock(existing);\n if (content === null || content === existing) {\n return { path, client: options.client, action: \"unchanged\" };\n }\n // Leave no empty file behind when CodeBuddy's block was all it held.\n if (content.trim() === \"\") await rm(path, { force: true });\n else await writeAtomic(path, content, { mode: 0o644 });\n return { path, client: options.client, action: \"removed\" };\n }\n const { content, action } = upsertBlock(existing, renderManagedBlock(options.client, mode));\n\n if (action === \"unchanged\") return { path, client: options.client, action };\n // Atomic: a crash mid-write must never truncate the user's CLAUDE.md/AGENTS.md.\n await writeAtomic(path, content, { mode: 0o644 });\n return { path, client: options.client, action };\n}\n\n/** Compute the new file content and what changed, without touching disk. */\nexport function upsertBlock(\n existing: string | null,\n block: string,\n): { content: string; action: InstallAction } {\n if (existing === null) return { content: block, action: \"created\" };\n\n const start = existing.indexOf(START_MARKER);\n const end = existing.indexOf(END_MARKER);\n if (start !== -1 && end !== -1 && end > start) {\n const before = existing.slice(0, start);\n const after = existing.slice(end + END_MARKER.length).replace(/^\\n/, \"\");\n const replaced = `${before}${block}${after}`;\n return { content: replaced, action: replaced === existing ? \"unchanged\" : \"updated\" };\n }\n\n // No managed block yet — append, keeping the user's content intact.\n const separator =\n existing.length === 0 || existing.endsWith(\"\\n\\n\")\n ? \"\"\n : existing.endsWith(\"\\n\")\n ? \"\\n\"\n : \"\\n\\n\";\n return { content: `${existing}${separator}${block}`, action: \"added\" };\n}\n\n/**\n * Rules follow the installed hooks: hook-driven when CodeBuddy hooks are present\n * for any client reading this rules file, agent-driven otherwise (the hook-driven\n * block tells hookless agents to use the agent flow). Every caller that installs rules\n * without an explicit mode (rules install, `codebuddy use`) gets this, so a\n * re-run never re-adds agent-driven calls the hooks already make.\n */\nexport async function defaultRulesMode(\n client: WorkflowClient,\n projectRoot = process.cwd(),\n): Promise<\"agent\" | \"hooks\"> {\n return (await rulesFileHooked(projectRoot, client)) ? \"hooks\" : \"agent\";\n}\n\n/** The mode of the managed block in a rules file, or null when there is none. */\nexport async function readManagedMode(path: string): Promise<AutomationMode | null> {\n const existing = await readIfPresent(path);\n if (existing === null || !hasManagedBlock(existing)) return null;\n return parseWorkflowMode(existing.slice(existing.indexOf(START_MARKER)));\n}\n\nfunction hasManagedBlock(content: string): boolean {\n const start = content.indexOf(START_MARKER);\n return start !== -1 && content.indexOf(END_MARKER) > start;\n}\n\n/** Drop the managed block (and the blank line that separated it), keeping user text. */\nexport function removeBlock(existing: string): string {\n if (!hasManagedBlock(existing)) return existing;\n const start = existing.indexOf(START_MARKER);\n const end = existing.indexOf(END_MARKER) + END_MARKER.length;\n const before = existing.slice(0, start).replace(/\\n\\n$/, \"\\n\");\n const after = existing.slice(end).replace(/^\\n/, \"\");\n return `${before}${after}`;\n}\n\nasync function readIfPresent(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type ManagedPlugin, managedPluginInstalled, setManagedPlugin } from \"./managed-plugin.js\";\nimport type { HookVariant } from \"./settings.js\";\n\n/**\n * Hermes Agent lifecycle bridge. Hermes loads project plugins from\n * `./.hermes/plugins/<name>/` (plugin.yaml + `__init__.py` with `register(ctx)`),\n * so CodeBuddy writes one managed Python plugin there. Like the OpenCode\n * bridge it only forwards: each hook runs the fail-soft `codebuddy hooks\n * <command>` runtime with a normalized JSON payload on stdin.\n *\n * Verified against Hermes Agent v0.17.0 (hermes_cli/plugins.py, agent/turn_context.py,\n * agent/turn_finalizer.py, model_tools.py, agent/conversation_compression.py):\n * - Project plugins load only with HERMES_ENABLE_PROJECT_PLUGINS=1 and the\n * plugin key in `plugins.enabled` of ~/.hermes/config.yaml. `hermes plugins\n * enable` only knows bundled and user plugins, so that entry is a manual\n * edit (or `clients install --global`).\n * - pre_llm_call: a returned {\"context\"} is appended to this turn's user\n * message at API-call time and never persisted, so the bridge asks for a\n * full block every turn (`ephemeral_context`).\n * - post_tool_call: write_file / patch (`path`, or V4A `patch` text) are\n * staged; terminal commands keep the JSON result's `exit_code`.\n * - post_llm_call: the final assistant text, used as the capture summary.\n * - on_session_end: fires at the end of every turn → capture.\n * - Compaction has no plugin hook and can rotate the session id mid-turn, so\n * a turn keeps the id it started with, and the per-turn full resend (which\n * also resets the session ledger) stands in for a compaction reset.\n */\n\nexport const HERMES_PLUGIN_MARKER = \"# codebuddy-managed: hermes-plugin\";\n\nexport const HERMES_PLUGIN_MANIFEST = `${HERMES_PLUGIN_MARKER} v1\nname: codebuddy\nversion: 1.0.0\nkind: standalone\ndescription: CodeBuddy recall and capture bridge (codebuddy clients install hermes --mode hooks).\nprovides_hooks:\n - pre_llm_call\n - post_tool_call\n - post_llm_call\n - on_session_end\n`;\n\nconst HERMES_LEAN_MANIFEST = `${HERMES_PLUGIN_MARKER} v1 lean\nname: codebuddy\nversion: 1.0.0\nkind: standalone\ndescription: CodeBuddy lean bridge (codebuddy clients install hermes --mode lean).\nprovides_hooks:\n - pre_llm_call\n`;\n\nconst HERMES_HOOK_FN = `def _hook(command, payload):\n \"\"\"Run one fail-soft CodeBuddy hook; its stdout, or \"\" on any failure.\"\"\"\n try:\n done = subprocess.run(\n [\"codebuddy\", \"hooks\", command],\n input=json.dumps({\"cwd\": ROOT, **payload}),\n capture_output=True,\n text=True,\n timeout=TIMEOUT_S[command],\n cwd=ROOT,\n )\n except Exception:\n return \"\"\n return done.stdout if done.returncode == 0 else \"\"\n\n\n`;\n\n/** The generated plugin: `full` bridges every lifecycle event, `lean` only prompts. */\nexport function renderHermesPlugin(variant: HookVariant): string {\n return variant === \"lean\"\n ? `${HERMES_PLUGIN_MARKER} v1 lean\n# Generated by \"codebuddy clients install hermes --mode lean\"; removed by\n# \"codebuddy clients uninstall hermes\". Local edits are overwritten.\n\"\"\"CodeBuddy lean bridge: forwards each prompt to \"codebuddy hooks lean\".\"\"\"\n\nimport json\nimport subprocess\nfrom pathlib import Path\n\n# <root>/.hermes/plugins/codebuddy/__init__.py\nROOT = str(Path(__file__).absolute().parents[3])\nTIMEOUT_S = {\"lean\": 2}\n\n\n${HERMES_HOOK_FN}def _pre_llm_call(session_id=\"\", user_message=\"\", **_):\n if not isinstance(user_message, str) or not user_message.strip():\n return None\n payload = {\n \"session_id\": session_id,\n \"hook_event_name\": \"pre_llm_call\",\n \"ephemeral_context\": True,\n \"prompt\": user_message,\n }\n block = _hook(\"lean\", payload).strip()\n return {\"context\": block} if block else None\n\n\ndef register(ctx):\n ctx.register_hook(\"pre_llm_call\", _pre_llm_call)\n`\n : `${HERMES_PLUGIN_MARKER} v1\n# Generated by \"codebuddy clients install hermes --mode hooks\"; removed by\n# \"codebuddy clients uninstall hermes\". Local edits are overwritten.\n\"\"\"CodeBuddy lifecycle bridge: forwards Hermes hooks to \"codebuddy hooks <command>\".\"\"\"\n\nimport json\nimport subprocess\nimport threading\nfrom pathlib import Path\n\n# <root>/.hermes/plugins/codebuddy/__init__.py\nROOT = str(Path(__file__).absolute().parents[3])\nEDIT_TOOLS = {\"write_file\", \"patch\"}\nTIMEOUT_S = {\"context\": 20, \"stage\": 10, \"capture\": 60}\n_lock = threading.Lock()\n_turns = {}\n\n\n${HERMES_HOOK_FN}def _turn(turn_id, session_id):\n # Compression can rotate the session id mid-turn; a turn keeps its first id.\n with _lock:\n return _turns.setdefault(\n turn_id or session_id, {\"session\": session_id, \"text\": \"\", \"commands\": []}\n )\n\n\ndef _pre_llm_call(session_id=\"\", turn_id=\"\", user_message=\"\", **_):\n _turn(turn_id, session_id)\n payload = {\"session_id\": session_id, \"hook_event_name\": \"pre_llm_call\", \"ephemeral_context\": True}\n if isinstance(user_message, str) and user_message.strip():\n payload[\"prompt\"] = user_message\n block = _hook(\"context\", payload).strip()\n return {\"context\": block} if block else None\n\n\ndef _post_tool_call(tool_name=\"\", args=None, result=None, session_id=\"\", turn_id=\"\", **_):\n turn = _turn(turn_id, session_id)\n args = args if isinstance(args, dict) else {}\n if tool_name in EDIT_TOOLS:\n # Paths only: write_file content never needs to cross the pipe.\n tool_input = {k: args[k] for k in (\"path\", \"mode\", \"patch\") if k in args}\n _hook(\"stage\", {\n \"session_id\": turn[\"session\"],\n \"hook_event_name\": \"post_tool_call\",\n \"tool_name\": tool_name,\n \"tool_input\": tool_input,\n })\n elif tool_name == \"terminal\" and isinstance(args.get(\"command\"), str):\n exit_code = None\n if not args.get(\"background\"): # a background process has not finished\n try:\n exit_code = json.loads(result).get(\"exit_code\")\n except Exception:\n pass\n turn[\"commands\"].append({\n \"command\": args[\"command\"],\n \"exit_code\": exit_code if type(exit_code) is int else None,\n })\n\n\ndef _post_llm_call(session_id=\"\", turn_id=\"\", assistant_response=\"\", **_):\n if isinstance(assistant_response, str) and assistant_response.strip():\n _turn(turn_id, session_id)[\"text\"] = assistant_response\n\n\ndef _on_session_end(session_id=\"\", turn_id=\"\", **_):\n with _lock:\n turn = _turns.pop(turn_id or session_id, None)\n turn = turn or {\"session\": session_id, \"text\": \"\", \"commands\": []}\n payload = {\"session_id\": turn[\"session\"], \"hook_event_name\": \"on_session_end\"}\n if turn[\"text\"]:\n payload[\"last_assistant_message\"] = turn[\"text\"]\n if turn[\"commands\"]:\n payload[\"shell_commands\"] = turn[\"commands\"][-20:]\n _hook(\"capture\", payload)\n\n\ndef register(ctx):\n ctx.register_hook(\"pre_llm_call\", _pre_llm_call)\n ctx.register_hook(\"post_tool_call\", _post_tool_call)\n ctx.register_hook(\"post_llm_call\", _post_llm_call)\n ctx.register_hook(\"on_session_end\", _on_session_end)\n`;\n}\n\nexport const HERMES_PLUGIN_SOURCE = renderHermesPlugin(\"full\");\n\nexport function hermesPluginDir(repositoryRoot: string): string {\n return join(resolve(repositoryRoot), \".hermes\", \"plugins\", \"codebuddy\");\n}\n\nfunction plugin(repositoryRoot: string, variant: HookVariant = \"full\"): ManagedPlugin {\n const dir = hermesPluginDir(repositoryRoot);\n return {\n marker: HERMES_PLUGIN_MARKER,\n files: [\n {\n path: join(dir, \"plugin.yaml\"),\n content: variant === \"lean\" ? HERMES_LEAN_MANIFEST : HERMES_PLUGIN_MANIFEST,\n },\n { path: join(dir, \"__init__.py\"), content: renderHermesPlugin(variant) },\n ],\n dirs: [dir, dirname(dir), dirname(dirname(dir))],\n };\n}\n\nexport function hermesPluginInstalled(repositoryRoot: string): Promise<boolean> {\n return managedPluginInstalled(plugin(repositoryRoot));\n}\n\nexport function setHermesPlugin(\n repositoryRoot: string,\n enabled: boolean,\n variant: HookVariant = \"full\",\n): Promise<boolean> {\n return setManagedPlugin(plugin(repositoryRoot, variant), enabled);\n}\n\n/** Which plugin variant is installed, or null when CodeBuddy's plugin is absent. */\nexport async function hermesPluginVariant(repositoryRoot: string): Promise<HookVariant | null> {\n if (!(await hermesPluginInstalled(repositoryRoot))) return null;\n const source = await readFile(join(hermesPluginDir(repositoryRoot), \"__init__.py\"), \"utf8\");\n return source.startsWith(`${HERMES_PLUGIN_MARKER} v1 lean`) ? \"lean\" : \"full\";\n}\n","import { mkdir, readFile, rm, rmdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\n\n/**\n * A host plugin CodeBuddy owns: files that each start with `marker`. Install\n * and uninstall are idempotent, and a file at one of these paths without the\n * marker is never overwritten or removed.\n */\nexport type ManagedPlugin = {\n marker: string;\n files: Array<{ path: string; content: string }>;\n /** Directories install may create, innermost first; uninstall removes them only while empty. */\n dirs: string[];\n};\n\nasync function read(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n}\n\nexport async function managedPluginInstalled(plugin: ManagedPlugin): Promise<boolean> {\n for (const file of plugin.files) {\n if (!(await read(file.path))?.startsWith(plugin.marker)) return false;\n }\n return true;\n}\n\n/** Write or remove the plugin; returns whether anything changed. */\nexport async function setManagedPlugin(plugin: ManagedPlugin, enabled: boolean): Promise<boolean> {\n const current = await Promise.all(plugin.files.map((file) => read(file.path)));\n const foreign = plugin.files.find((_, i) => {\n const text = current[i];\n return text != null && !text.startsWith(plugin.marker);\n });\n if (foreign) {\n if (!enabled) return false;\n throw new Error(\n `${foreign.path} exists and is not managed by CodeBuddy; move it aside and re-run.`,\n );\n }\n let changed = false;\n for (const [i, file] of plugin.files.entries()) {\n if (enabled && current[i] !== file.content) {\n await mkdir(dirname(file.path), { recursive: true });\n await writeAtomic(file.path, file.content, { mode: 0o644 });\n changed = true;\n } else if (!enabled && current[i] != null) {\n await rm(file.path, { force: true });\n changed = true;\n }\n }\n if (!enabled && changed) {\n for (const dir of plugin.dirs) await rmdir(dir).catch(() => {});\n }\n return changed;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type ManagedPlugin, managedPluginInstalled, setManagedPlugin } from \"./managed-plugin.js\";\nimport type { HookVariant } from \"./settings.js\";\n\n/**\n * OpenCode lifecycle bridge. OpenCode loads project plugins from\n * `.opencode/{plugin,plugins}/*.{ts,js}`, so CodeBuddy writes one managed JS\n * plugin there. It only forwards events: each one spawns the same fail-soft\n * `codebuddy hooks <command>` runtime Claude Code uses, with a normalized\n * Claude-shaped JSON payload on stdin. All logic stays in the shared services.\n *\n * Verified against OpenCode 1.18.32 (binary) and @opencode-ai/plugin 1.17.9 types:\n * - chat.message: mutated `output.parts` are saved with the user message and\n * non-ignored text parts reach the model, so the context block is appended\n * as a synthetic text part (prompt-time injection).\n * - tool.execute.after: edit/write (`filePath`), apply_patch/patch (`patchText`)\n * are staged; bash commands and `metadata.exit` feed turn verification.\n * - experimental.text.complete: the latest assistant text, used as the\n * capture summary (OpenCode has no transcript file).\n * - event session.idle → capture; session.compacted → reset.\n * The module must export only plugin functions: OpenCode calls every export.\n */\n\nexport const OPENCODE_PLUGIN_MARKER = \"// codebuddy-managed: opencode-plugin\";\n\nconst OPENCODE_RUNTIME = `const ID_CHARS = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\nlet lastMs = 0;\nlet counter = 0;\n\n/** Run one fail-soft CodeBuddy hook; resolves to its stdout, \"\" on any failure. */\nfunction hook(command, payload) {\n return new Promise((done) => {\n let out = \"\";\n let child;\n try {\n child = spawn(\"codebuddy\", [\"hooks\", command], {\n cwd: payload.cwd,\n stdio: [\"pipe\", \"pipe\", \"ignore\"],\n });\n } catch {\n done(\"\");\n return;\n }\n const timer = setTimeout(() => child.kill(), TIMEOUT_MS[command]);\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk) => {\n out += chunk;\n });\n child.on(\"error\", () => {\n clearTimeout(timer);\n done(\"\");\n });\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n done(code === 0 ? out : \"\");\n });\n child.stdin.on(\"error\", () => {});\n child.stdin.end(JSON.stringify(payload));\n });\n}\n\n/** An ascending OpenCode part id (prt_ + 48-bit time/counter hex + 14 base62). */\nfunction partId() {\n const now = Date.now();\n if (now !== lastMs) {\n lastMs = now;\n counter = 0;\n }\n counter += 1;\n const time = (BigInt(now) * 4096n + BigInt(counter)) & 0xffffffffffffn;\n let random = \"\";\n for (const byte of crypto.getRandomValues(new Uint8Array(14))) random += ID_CHARS[byte % 62];\n return \"prt_\" + time.toString(16).padStart(12, \"0\") + random;\n}\n\n`;\n\n/** The generated plugin: `full` bridges every lifecycle event, `lean` only prompts and compaction. */\nexport function renderOpencodePlugin(variant: HookVariant): string {\n return variant === \"lean\"\n ? `${OPENCODE_PLUGIN_MARKER} v1 lean\n// Generated by \\`codebuddy clients install opencode --mode lean\\`; removed by\n// \\`codebuddy clients uninstall opencode\\`. Local edits are overwritten.\nimport { spawn } from \"node:child_process\";\n\nconst TIMEOUT_MS = { lean: 2000, reset: 10000 };\n${OPENCODE_RUNTIME}/** @type {import(\"@opencode-ai/plugin\").Plugin} */\nexport const CodeBuddyPlugin = async ({ directory }) => {\n const base = (sessionID, event) => ({ session_id: sessionID, cwd: directory, hook_event_name: event });\n\n return {\n \"chat.message\": async (input, output) => {\n const prompt = output.parts\n .flatMap((part) => (part.type === \"text\" && !part.synthetic ? [part.text] : []))\n .join(\"\\\\n\")\n .trim();\n if (!prompt) return;\n const block = (await hook(\"lean\", { ...base(input.sessionID, \"chat.message\"), prompt })).trim();\n if (!block) return;\n output.parts.push({\n id: partId(),\n sessionID: input.sessionID,\n messageID: output.message.id,\n type: \"text\",\n text: block,\n synthetic: true,\n });\n },\n event: async ({ event }) => {\n if (event.type === \"session.compacted\") {\n await hook(\"reset\", { ...base(event.properties.sessionID, \"session.compacted\"), source: \"compact\" });\n }\n },\n };\n};\n`\n : `${OPENCODE_PLUGIN_MARKER} v1\n// Generated by \\`codebuddy clients install opencode --mode hooks\\`; removed by\n// \\`codebuddy clients uninstall opencode\\`. Local edits are overwritten.\nimport { spawn } from \"node:child_process\";\n\nconst EDIT_TOOLS = new Set([\"edit\", \"write\", \"patch\", \"apply_patch\"]);\nconst TIMEOUT_MS = { context: 20000, stage: 10000, capture: 60000, reset: 10000 };\n${OPENCODE_RUNTIME}/** @type {import(\"@opencode-ai/plugin\").Plugin} */\nexport const CodeBuddyPlugin = async ({ directory }) => {\n /** @type {Map<string, { text: string, commands: Array<{ command: string, exit_code: number | null }> }>} */\n const turns = new Map();\n const turn = (sessionID) => {\n if (!turns.has(sessionID)) turns.set(sessionID, { text: \"\", commands: [] });\n return turns.get(sessionID);\n };\n const base = (sessionID, event) => ({ session_id: sessionID, cwd: directory, hook_event_name: event });\n\n return {\n \"chat.message\": async (input, output) => {\n turns.delete(input.sessionID);\n const prompt = output.parts\n .flatMap((part) => (part.type === \"text\" && !part.synthetic ? [part.text] : []))\n .join(\"\\\\n\")\n .trim();\n const block = (\n await hook(\"context\", { ...base(input.sessionID, \"chat.message\"), ...(prompt ? { prompt } : {}) })\n ).trim();\n if (!block) return;\n output.parts.push({\n id: partId(),\n sessionID: input.sessionID,\n messageID: output.message.id,\n type: \"text\",\n text: block,\n synthetic: true,\n });\n },\n \"tool.execute.after\": async (input, output) => {\n if (EDIT_TOOLS.has(input.tool)) {\n await hook(\"stage\", {\n ...base(input.sessionID, \"tool.execute.after\"),\n tool_name: input.tool,\n tool_input: input.args,\n });\n } else if (input.tool === \"bash\" && typeof input.args?.command === \"string\") {\n const exit = output.metadata?.exit;\n turn(input.sessionID).commands.push({\n command: input.args.command,\n exit_code: typeof exit === \"number\" ? exit : null,\n });\n }\n },\n \"experimental.text.complete\": async (input, output) => {\n if (output.text.trim()) turn(input.sessionID).text = output.text;\n },\n event: async ({ event }) => {\n if (event.type === \"session.idle\") {\n const sessionID = event.properties.sessionID;\n const current = turns.get(sessionID);\n turns.delete(sessionID);\n await hook(\"capture\", {\n ...base(sessionID, \"session.idle\"),\n ...(current?.text ? { last_assistant_message: current.text } : {}),\n ...(current?.commands.length ? { shell_commands: current.commands.slice(-20) } : {}),\n });\n } else if (event.type === \"session.compacted\") {\n await hook(\"reset\", { ...base(event.properties.sessionID, \"session.compacted\"), source: \"compact\" });\n }\n },\n };\n};\n`;\n}\n\nexport const OPENCODE_PLUGIN_SOURCE = renderOpencodePlugin(\"full\");\n\nexport function opencodePluginPath(repositoryRoot: string): string {\n return join(resolve(repositoryRoot), \".opencode\", \"plugins\", \"codebuddy.js\");\n}\n\nfunction plugin(repositoryRoot: string, variant: HookVariant = \"full\"): ManagedPlugin {\n const path = opencodePluginPath(repositoryRoot);\n return {\n marker: OPENCODE_PLUGIN_MARKER,\n files: [{ path, content: renderOpencodePlugin(variant) }],\n dirs: [dirname(path), dirname(dirname(path))],\n };\n}\n\nexport function opencodePluginInstalled(repositoryRoot: string): Promise<boolean> {\n return managedPluginInstalled(plugin(repositoryRoot));\n}\n\n/** Write or remove CodeBuddy's plugin; a same-named file without the marker is never touched. */\nexport function setOpencodePlugin(\n repositoryRoot: string,\n enabled: boolean,\n variant: HookVariant = \"full\",\n): Promise<boolean> {\n return setManagedPlugin(plugin(repositoryRoot, variant), enabled);\n}\n\n/** Which plugin variant is installed, or null when CodeBuddy's plugin is absent. */\nexport async function opencodePluginVariant(repositoryRoot: string): Promise<HookVariant | null> {\n if (!(await opencodePluginInstalled(repositoryRoot))) return null;\n const source = await readFile(opencodePluginPath(repositoryRoot), \"utf8\");\n return source.startsWith(`${OPENCODE_PLUGIN_MARKER} v1 lean`) ? \"lean\" : \"full\";\n}\n","import { mkdir, readFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\n\n/**\n * Installs CodeBuddy's lifecycle hooks into a client's settings JSON. Unlike the\n * Markdown workflow templates, settings files are JSON, so we can't use comment\n * markers — instead every CodeBuddy hook command starts with `codebuddy hooks`,\n * which is how we recognise (and cleanly remove) our own entries. Install is\n * idempotent and never touches hooks the user added themselves.\n *\n * Claude Code hooks fire deterministically, independent of the model's choices:\n * - UserPromptSubmit → `codebuddy hooks context` (recall, injected into prompt)\n * - PostToolUse(Edit|Write|MultiEdit) → `codebuddy hooks stage` (track edits)\n * - Stop → `codebuddy hooks capture` (capture durable memory at turn end)\n * - SessionStart(compact|clear) → `codebuddy hooks reset` (forget what was sent)\n * - PreToolUse(Read|Grep) → `codebuddy hooks pretool` (outline big Reads, cap Greps;\n * both variants, never grants permission)\n */\n\nexport const HOOK_COMMAND_PREFIX = \"codebuddy hooks\";\n\nexport type HookCommand = { type: \"command\"; command: string };\nexport type HookGroup = { matcher?: string; hooks: HookCommand[] };\nexport type HookSettings = { hooks?: Record<string, HookGroup[]> } & Record<string, unknown>;\n\ntype HookDef = { event: string; command: string; matcher?: string };\n\n/** Token guard for tool output; independent of memory, so lean installs it too. */\nconst TOOL_GUARD_DEF: HookDef = {\n event: \"PreToolUse\",\n matcher: \"Read|Grep\",\n command: `${HOOK_COMMAND_PREFIX} pretool`,\n};\n\nconst HOOK_DEFS: HookDef[] = [\n { event: \"UserPromptSubmit\", command: `${HOOK_COMMAND_PREFIX} context` },\n {\n event: \"PostToolUse\",\n matcher: \"Edit|Write|MultiEdit\",\n command: `${HOOK_COMMAND_PREFIX} stage`,\n },\n { event: \"Stop\", command: `${HOOK_COMMAND_PREFIX} capture` },\n // After compaction or /clear the model no longer holds earlier context, so\n // capsules the session ledger marked as sent must be sent again.\n { event: \"SessionStart\", matcher: \"compact|clear\", command: `${HOOK_COMMAND_PREFIX} reset` },\n TOOL_GUARD_DEF,\n];\n\n/** Lean mode: prompt pointers only, plus the reset that keeps their dedupe correct. */\nconst LEAN_HOOK_DEFS: HookDef[] = [\n { event: \"UserPromptSubmit\", command: `${HOOK_COMMAND_PREFIX} lean` },\n { event: \"SessionStart\", matcher: \"compact|clear\", command: `${HOOK_COMMAND_PREFIX} reset` },\n TOOL_GUARD_DEF,\n];\n\nexport type HookVariant = \"full\" | \"lean\";\n\nexport function claudeSettingsPath(repositoryRoot = process.cwd()): string {\n return join(resolve(repositoryRoot), \".claude\", \"settings.json\");\n}\n\n/** Merge CodeBuddy's hook entries into a settings object. Idempotent. */\nexport function upsertHooks(\n settings: HookSettings,\n variant: HookVariant = \"full\",\n): { settings: HookSettings; changed: boolean } {\n const defs = variant === \"lean\" ? LEAN_HOOK_DEFS : HOOK_DEFS;\n const wanted = new Set(defs.map((def) => def.command));\n const next: HookSettings = { ...settings, hooks: { ...(settings.hooks ?? {}) } };\n const hooks = next.hooks as Record<string, HookGroup[]>;\n let changed = false;\n\n // Switching variants: drop the other variant's CodeBuddy commands, keep the user's.\n for (const event of Object.keys(hooks)) {\n const groups: HookGroup[] = [];\n for (const group of hooks[event] ?? []) {\n const kept = (group.hooks ?? []).filter(\n (hook) => !hook.command?.startsWith(HOOK_COMMAND_PREFIX) || wanted.has(hook.command),\n );\n if (kept.length !== (group.hooks ?? []).length) changed = true;\n if (kept.length > 0) groups.push({ ...group, hooks: kept });\n }\n if (groups.length > 0) hooks[event] = groups;\n else delete hooks[event];\n }\n\n for (const def of defs) {\n const groups = [...(hooks[def.event] ?? [])];\n const existingIndex = groups.findIndex((group) =>\n group.hooks?.some((hook) => hook.command === def.command),\n );\n if (existingIndex === -1) {\n groups.push({\n ...(def.matcher ? { matcher: def.matcher } : {}),\n hooks: [{ type: \"command\", command: def.command }],\n });\n changed = true;\n } else {\n // The command exists, but possibly under a stale matcher (e.g. an older\n // install with matcher:\"Edit\" before MultiEdit coverage). Reconcile the\n // group's matcher so coverage matches the current contract.\n const existing = groups[existingIndex];\n if (existing && (def.matcher ?? undefined) !== (existing.matcher ?? undefined)) {\n const { matcher: _oldMatcher, ...rest } = existing;\n groups[existingIndex] = def.matcher ? { ...rest, matcher: def.matcher } : rest;\n changed = true;\n }\n }\n hooks[def.event] = groups;\n }\n\n return { settings: next, changed };\n}\n\n/** Remove every CodeBuddy hook entry, leaving user hooks intact. */\nexport function removeHooks(settings: HookSettings): { settings: HookSettings; changed: boolean } {\n if (!settings.hooks) return { settings, changed: false };\n const next: HookSettings = { ...settings, hooks: { ...settings.hooks } };\n const hooks = next.hooks as Record<string, HookGroup[]>;\n let changed = false;\n\n for (const event of Object.keys(hooks)) {\n const keptGroups: HookGroup[] = [];\n for (const group of hooks[event] ?? []) {\n // Filter INSIDE groups: a user group mixing our hook with their own\n // commands must keep theirs. Dropping whole groups used to silently\n // delete user hooks that happened to share a group with ours.\n const keptHooks = (group.hooks ?? []).filter(\n (hook) => !hook.command?.startsWith(HOOK_COMMAND_PREFIX),\n );\n if (keptHooks.length !== (group.hooks ?? []).length) changed = true;\n if (keptHooks.length === 0) continue; // group was entirely ours\n keptGroups.push({ ...group, hooks: keptHooks });\n }\n if (keptGroups.length === 0) delete hooks[event];\n else hooks[event] = keptGroups;\n }\n\n return { settings: next, changed };\n}\n\nexport function hooksInstalled(settings: HookSettings): boolean {\n const hooks = settings.hooks ?? {};\n return Object.values(hooks).some((groups) =>\n groups.some((group) => group.hooks?.some((h) => h.command?.startsWith(HOOK_COMMAND_PREFIX))),\n );\n}\n\n/** Which CodeBuddy hook set is installed, or null when none is. */\nexport function hooksVariant(settings: HookSettings): HookVariant | null {\n if (!hooksInstalled(settings)) return null;\n const leanCommand = `${HOOK_COMMAND_PREFIX} lean`;\n const lean = Object.values(settings.hooks ?? {}).some((groups) =>\n groups.some((group) => group.hooks?.some((hook) => hook.command === leanCommand)),\n );\n return lean ? \"lean\" : \"full\";\n}\n\nexport async function readSettings(path: string): Promise<HookSettings> {\n try {\n return JSON.parse(await readFile(path, \"utf8\")) as HookSettings;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw error;\n }\n}\n\nexport async function writeSettings(path: string, settings: HookSettings): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n // Atomic so a crash mid-write can never truncate the user's settings.json.\n await writeAtomic(path, `${JSON.stringify(settings, null, 2)}\\n`, { mode: 0o644 });\n}\n","import {\n CLIENT_ADAPTERS,\n CLIENT_IDS,\n type ClientId,\n type HookSurface,\n} from \"../clients/adapters.js\";\nimport {\n hermesPluginDir,\n hermesPluginInstalled,\n hermesPluginVariant,\n setHermesPlugin,\n} from \"./hermes-plugin.js\";\nimport {\n opencodePluginInstalled,\n opencodePluginPath,\n opencodePluginVariant,\n setOpencodePlugin,\n} from \"./opencode-plugin.js\";\nimport {\n claudeSettingsPath,\n type HookVariant,\n hooksInstalled,\n hooksVariant,\n readSettings,\n removeHooks,\n upsertHooks,\n writeSettings,\n} from \"./settings.js\";\n\n/**\n * One install/detect contract per hook surface in the adapter table, so callers\n * (clients install, hooks install, rules mode) never branch on client names.\n */\nconst SURFACES: Record<\n HookSurface,\n {\n path: (root: string) => string;\n installed: (root: string) => Promise<boolean>;\n variant: (root: string) => Promise<HookVariant | null>;\n /** Returns whether anything changed. */\n set: (root: string, enabled: boolean, variant: HookVariant) => Promise<boolean>;\n }\n> = {\n \"claude-settings\": {\n path: claudeSettingsPath,\n installed: async (root) => hooksInstalled(await readSettings(claudeSettingsPath(root))),\n variant: async (root) => hooksVariant(await readSettings(claudeSettingsPath(root))),\n set: async (root, enabled, variant) => {\n const path = claudeSettingsPath(root);\n const current = await readSettings(path);\n const { settings, changed } = enabled ? upsertHooks(current, variant) : removeHooks(current);\n if (changed) await writeSettings(path, settings);\n return changed;\n },\n },\n \"opencode-plugin\": {\n path: opencodePluginPath,\n installed: opencodePluginInstalled,\n variant: opencodePluginVariant,\n set: setOpencodePlugin,\n },\n \"hermes-plugin\": {\n path: hermesPluginDir,\n installed: hermesPluginInstalled,\n variant: hermesPluginVariant,\n set: setHermesPlugin,\n },\n};\n\n/** Install or remove a client's CodeBuddy hooks; null when the client has none. */\nexport async function setClientHooks(\n root: string,\n client: ClientId,\n enabled: boolean,\n variant: HookVariant = \"full\",\n): Promise<{ target: string; changed: boolean } | null> {\n const surface = CLIENT_ADAPTERS[client].hooks;\n if (!surface) return null;\n const { path, set } = SURFACES[surface];\n return { target: path(root), changed: await set(root, enabled, variant) };\n}\n\n/** Which CodeBuddy hook variant a client has; null when the client has no hook surface. */\nexport async function clientHooksVariant(\n root: string,\n client: ClientId,\n): Promise<HookVariant | null | undefined> {\n const surface = CLIENT_ADAPTERS[client].hooks;\n if (!surface) return undefined;\n return SURFACES[surface].variant(root);\n}\n\n/** Whether a client's CodeBuddy hooks are installed; null when the client has none. */\nexport async function clientHooksInstalled(\n root: string,\n client: ClientId,\n): Promise<boolean | null> {\n const surface = CLIENT_ADAPTERS[client].hooks;\n return surface ? SURFACES[surface].installed(root) : null;\n}\n\n/**\n * Clients other than `client` that read the same rules file and have hooks\n * installed. Their rules block must stay hook-driven, or they retrieve and\n * capture twice; the hook-driven block already tells hookless agents to fall\n * back to the agent-driven flow.\n */\nexport async function hookedRulesSiblings(root: string, client: ClientId): Promise<ClientId[]> {\n const file = CLIENT_ADAPTERS[client].rulesFile;\n const hooked: ClientId[] = [];\n for (const id of CLIENT_IDS) {\n if (\n id !== client &&\n CLIENT_ADAPTERS[id].rulesFile === file &&\n (await clientHooksInstalled(root, id))\n )\n hooked.push(id);\n }\n return hooked;\n}\n\n/** Whether any client reading `client`'s rules file (itself included) has hooks installed. */\nexport async function rulesFileHooked(root: string, client: ClientId): Promise<boolean> {\n return (\n (await clientHooksInstalled(root, client)) === true ||\n (await hookedRulesSiblings(root, client)).length > 0\n );\n}\n","/**\n * Client workflow templates (Proposal 04 Phase 04.7). These are the concrete\n * rules that make CodeBuddy's automatic context flow reliable in Claude Code and\n * Codex: they say exactly which MCP tool to call, when, and what to do when a\n * tool or service is unavailable. The text references only tools that actually\n * ship (04.2–04.6): context_pack, context_bootstrap, context_before_edit,\n * context_after_turn, code_suggestions.\n *\n * Templates are installed into a client's Markdown rules file inside a clearly\n * delimited managed block (see `install.ts`) so updates are idempotent and the\n * user can always see exactly what CodeBuddy added.\n *\n * The automation mode decides who drives retrieval and capture. Agent-driven\n * rules ask the model to call the tools; hook-driven rules defer to the\n * lifecycle hooks so a turn is not retrieved or captured twice.\n */\n\nimport {\n type AutomationMode,\n CLIENT_ADAPTERS,\n CLIENT_IDS,\n type ClientId,\n MODE_LABELS,\n} from \"../clients/adapters.js\";\n\nexport const WORKFLOW_CLIENTS = CLIENT_IDS;\nexport type WorkflowClient = ClientId;\n\n/** The shared body, split where the automation mode changes who acts. */\nconst INTRO = [\n \"You have CodeBuddy available as a local, MCP-backed project-context engine.\",\n \"Use it to work like a careful senior engineer, not to dump broad context.\",\n \"\",\n];\n\nconst START_AGENT = [\n \"## At the start of a substantive coding turn\",\n \"\",\n \"1. When project context is needed, call `context_pack` with the user's task and a token budget (start\",\n \" with 4000). It automatically finds relevant files and returns bounded symbols,\",\n \" plan, policy, incidents, risks, architecture neighbours, and team facts.\",\n \" Reuse evidence already present. For a clearly identified small edit, read the\",\n \" needed source directly; fetch context for unknown dependencies or project constraints.\",\n \" Read missing function bodies before editing. If safety evidence was omitted,\",\n \" narrow the targets or increase the budget before proceeding.\",\n \"2. Use `context_bootstrap` only when you need broad project orientation beyond\",\n \" the task pack. Use `context_before_edit` when you already have exact paths\",\n \" or a plan and need a narrower follow-up.\",\n \"3. Prior work from earlier chats arrives as `handoffs` with freshness\",\n \" (`changedSince`, `missing`); re-check those files before relying on it.\",\n \"4. On repeated context calls in one conversation, pass a stable `sessionId` and\",\n \" the previous response's `delivery.deliveryId` as `ack`. Unchanged sections\",\n \" are then omitted and listed in `delivery.unchanged`. If earlier output is no\",\n \" longer in your context (e.g. after compaction), pass `full: true`.\",\n \"\",\n];\n\nconst START_HOOKS = [\n \"## At the start of a substantive coding turn\",\n \"\",\n \"CodeBuddy hooks inject a `CodeBuddy project context (auto-recalled)` block into\",\n \"each prompt: project, plan, policies, facts, incidents, handoffs, current\",\n \"changes, and risk. Agents without CodeBuddy hooks (no such block in the prompt)\",\n \"follow the agent-driven flow: `context_pack` first, `context_after_turn` last.\",\n \"\",\n \"1. Start from the injected block; do not call `context_bootstrap` for orientation\",\n \" it already covers.\",\n \"2. Call `context_pack` (or `context_before_edit` with exact paths) only when the\",\n \" task needs symbols, neighbours, or file-level evidence the block lacks. Pass the\",\n \" block's `session` value as `sessionId` and the previous `delivery.deliveryId`\",\n \" as `ack` so unchanged sections are not resent.\",\n \"3. Prior work from earlier chats arrives as handoffs with freshness; re-check\",\n \" those files before relying on it.\",\n \"\",\n];\n\nconst MIDDLE = [\n \"## While implementing\",\n \"\",\n \"- Prefer the smallest sufficient set of edits; preserve existing behavior.\",\n \"- Honor risk warnings and policy rules for the files you touch; call out risk\",\n \" before editing sensitive areas.\",\n \"- Do not re-request broad context if the task pack already suffices.\",\n \"\",\n \"## Before finalizing\",\n \"\",\n \"- Consider calling `code_suggestions` (with `paths`, `planId`, or `useGit`) for\",\n \" read-only, evidence-backed quality findings; resolve high-severity ones.\",\n \"- Run the smallest relevant verification (tests, lint, typecheck) and fix\",\n \" failures before presenting completion.\",\n \"\",\n];\n\nconst AFTER_AGENT = [\n \"## After a meaningful turn\",\n \"\",\n \"- Call `context_after_turn` with a concise `summary`, the `changedFiles`, and a\",\n \" `planId` if one is active, plus `verification` (commands run and results)\",\n \" so the turn's worklog handoff records it. CodeBuddy auto-saves confident facts, decisions,\",\n \" and incidents, queues uncertain or sensitive items for review, and drops\",\n \" chatter. Never paste secrets, tokens, or credentials into the summary.\",\n \"\",\n];\n\nconst AFTER_HOOKS = [\n \"## After a meaningful turn\",\n \"\",\n \"- Do not call `context_after_turn`: the turn-end hook captures the turn once, from\",\n \" the real change set and the verification commands you ran. A second capture\",\n \" would record a divergent worklog entry.\",\n \"- Never paste secrets, tokens, or credentials into your final message; it is the\",\n \" capture summary.\",\n \"\",\n];\n\nconst TAIL = [\n \"## If a tool or service is unavailable (degraded mode)\",\n \"\",\n \"- A CodeBuddy MCP tool errors or is missing: proceed using the repository\",\n \" itself as the source of truth; do not block on it.\",\n \"- Postgres is unreachable: the file-based tools (context, plan, risk, map,\",\n \" suggest) still work; recall and embeddings may be degraded — say so instead\",\n \" of inventing remembered facts.\",\n \"- Retrieval returns no context: read the relevant files directly rather than\",\n \" guessing; the working tree is authoritative.\",\n \"\",\n \"## Never\",\n \"\",\n \"- Invent behavior the codebase does not support.\",\n \"- Ignore failing tests or lint.\",\n \"- Make speculative, wide changes without evidence.\",\n \"- Save low-confidence project memory as a durable fact.\",\n];\n\nfunction renderBody(mode: Exclude<AutomationMode, \"mcp-only\">): string {\n return [\n ...INTRO,\n ...(mode === \"hooks\" ? START_HOOKS : START_AGENT),\n ...MIDDLE,\n ...(mode === \"hooks\" ? AFTER_HOOKS : AFTER_AGENT),\n ...TAIL,\n ].join(\"\\n\");\n}\n\n/** Clients whose rules live in the same file share one managed block. */\nfunction rulesReaders(file: string): string {\n return CLIENT_IDS.filter((id) => CLIENT_ADAPTERS[id].rulesFile === file)\n .map((id) => CLIENT_ADAPTERS[id].name)\n .join(\", \");\n}\n\n/**\n * Render the full template (heading + body). The text depends only on the\n * rules file and mode, so clients sharing AGENTS.md install an identical block.\n */\nexport function renderWorkflowTemplate(\n client: WorkflowClient,\n mode: Exclude<AutomationMode, \"mcp-only\"> = \"agent\",\n): string {\n const file = CLIENT_ADAPTERS[client].rulesFile;\n return [\n `# CodeBuddy workflow (${rulesReaders(file)})`,\n \"\",\n \"This section is managed by CodeBuddy (`codebuddy clients install <client> --mode <mode>`)\",\n `and lives in \\`${file}\\`. Edit outside the managed markers to customize.`,\n `Automation mode: \\`${mode}\\` (${MODE_LABELS[mode]}).`,\n \"\",\n renderBody(mode),\n ].join(\"\\n\");\n}\n\n/** The mode recorded in a rendered block; blocks from before modes existed are agent-driven. */\nexport function parseWorkflowMode(block: string): AutomationMode {\n return block.match(/Automation mode: `(hooks|agent)`/)?.[1] === \"hooks\" ? \"hooks\" : \"agent\";\n}\n\nexport function defaultRulesFile(client: WorkflowClient): string {\n return CLIENT_ADAPTERS[client].rulesFile;\n}\n\nexport function clientDisplayName(client: WorkflowClient): string {\n return CLIENT_ADAPTERS[client].name;\n}\n","import { access } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { resolveNamespaceFrom } from \"../core/config-file.js\";\nimport {\n clientHooksInstalled,\n clientHooksVariant,\n hookedRulesSiblings,\n setClientHooks,\n} from \"../hooks/install.js\";\nimport type { HookVariant } from \"../hooks/settings.js\";\nimport { indexRepository } from \"../indexer/engine.js\";\nimport {\n codebuddyMcpServer,\n formatEntry,\n hasMcpServer,\n projectMcpPath,\n removeMcpServer,\n upsertMcpServer,\n} from \"../integrations/project-mcp.js\";\nimport { installWorkflowRules, readManagedMode } from \"../templates/install.js\";\nimport {\n type AutomationMode,\n CLIENT_ADAPTERS,\n type ClientId,\n MODE_LABELS,\n sharedRulesReaders,\n supportedModes,\n} from \"./adapters.js\";\nimport { globalMcpPath, hasGlobalMcp, setGlobalMcp } from \"./global-mcp.js\";\n\n/**\n * Applies one explicit automation mode to one client, across every surface its\n * adapter declares (rules block, lifecycle hooks, project MCP config). Each step\n * reuses the existing idempotent installer and reports what it did, so a re-run\n * is all `unchanged` and `uninstallClient` reverses it without touching user config.\n */\n\nexport type ClientStep = {\n surface: \"rules\" | \"hooks\" | \"mcp\" | \"index\";\n target: string;\n action: string;\n};\nexport type ClientReport = { client: ClientId; steps: ClientStep[]; notes: string[] };\n\ntype ClientOptions = {\n client: ClientId;\n projectRoot?: string;\n namespace?: string;\n /** Also write/remove the entry in the client's global MCP config (Codex, Hermes). */\n global?: boolean;\n};\n\nexport async function installClient(\n options: ClientOptions & { mode: AutomationMode },\n): Promise<ClientReport> {\n const adapter = CLIENT_ADAPTERS[options.client];\n if (!supportedModes(adapter).includes(options.mode)) {\n throw new Error(\n `${adapter.name} does not support ${MODE_LABELS[options.mode]} mode: ${adapter.gap ?? \"no lifecycle hooks\"}.`,\n );\n }\n return apply(options, options.mode, options.mode !== \"lean\");\n}\n\n/** Lean has no MCP server to index the repo, so install builds the index the hook reads. */\nasync function ensureIndex(root: string): Promise<ClientStep> {\n const target = join(root, \".codebuddy\", \"cache\", \"index.json\");\n const existed = await access(target).then(\n () => true,\n () => false,\n );\n if (!existed) await indexRepository({ repositoryRoot: root });\n return { surface: \"index\", target, action: existed ? \"unchanged\" : \"built\" };\n}\n\n/** Remove every CodeBuddy surface for a client; user rules, hooks and servers stay. */\nexport async function uninstallClient(options: ClientOptions): Promise<ClientReport> {\n return apply(options, \"mcp-only\", false);\n}\n\nasync function apply(\n options: ClientOptions,\n mode: AutomationMode,\n keepMcp: boolean,\n): Promise<ClientReport> {\n const root = resolve(options.projectRoot ?? process.cwd());\n const adapter = CLIENT_ADAPTERS[options.client];\n const steps: ClientStep[] = [];\n const notes: string[] = [];\n\n const namespace = options.namespace ?? (await resolveNamespaceFrom(root));\n const name = `codebuddy-${namespace}`;\n const shared = sharedRulesReaders(options.client);\n // Removing the block would strip the workflow from a sibling client that still\n // has its MCP entry for this namespace (project or global config).\n const liveSiblings =\n mode === \"mcp-only\" || mode === \"lean\" ? await installedWithMcp(root, shared, namespace) : [];\n if (liveSiblings.length > 0) {\n const path = join(root, adapter.rulesFile);\n steps.push({ surface: \"rules\", target: path, action: \"kept\" });\n notes.push(\n `Kept the CodeBuddy block in ${adapter.rulesFile}: still used by ${liveSiblings.map((id) => CLIENT_ADAPTERS[id].name).join(\", \")}.`,\n );\n } else {\n // An agent-driven block would make a hooked sibling retrieve and capture twice.\n const hooked = mode === \"agent\" ? await hookedRulesSiblings(root, options.client) : [];\n const rules = await installWorkflowRules({\n client: options.client,\n projectRoot: root,\n // Lean sends no rules: the block would cost tokens every turn and shadow AGENTS.md.\n mode: mode === \"lean\" ? \"mcp-only\" : hooked.length > 0 ? \"hooks\" : mode,\n });\n steps.push({ surface: \"rules\", target: rules.path, action: rules.action });\n if (hooked.length > 0) {\n notes.push(\n `Kept ${adapter.rulesFile} hook-driven: ${hooked.map((id) => CLIENT_ADAPTERS[id].name).join(\", \")} hooks are installed; agents without hooks follow its agent-driven fallback.`,\n );\n }\n }\n if (shared.length > 0) {\n notes.push(\n `${adapter.rulesFile} is also read by ${shared.map((id) => CLIENT_ADAPTERS[id].name).join(\", \")}.`,\n );\n }\n\n const hooks = await setHooks(\n root,\n mode === \"hooks\" || mode === \"lean\",\n options.client,\n mode === \"lean\" ? \"lean\" : \"full\",\n );\n if (hooks) steps.push(hooks);\n if (mode === \"lean\") steps.push(await ensureIndex(root));\n\n if (\"file\" in adapter.mcp) {\n const path = await projectMcpPath(root, adapter.mcp.file, adapter.mcp.format);\n const action = keepMcp\n ? await upsertMcpServer(path, adapter.mcp.format, name, codebuddyMcpServer(root, namespace))\n : await removeMcpServer(path, adapter.mcp.format, name);\n steps.push({ surface: \"mcp\", target: path, action });\n if (action === \"manual\") {\n notes.push(\n `${path} has comments CodeBuddy will not rewrite; ${keepMcp ? \"add\" : \"remove\"} the \"${name}\" entry under \"mcp\" by hand${keepMcp ? `: ${JSON.stringify(formatEntry(adapter.mcp.format, codebuddyMcpServer(root, namespace)))}` : \"\"}.`,\n );\n }\n } else if (options.global) {\n const target = globalMcpPath(adapter.mcp.global);\n const action = await setGlobalMcp(adapter.mcp.global, {\n name,\n root,\n namespace,\n enabled: keepMcp,\n });\n steps.push({ surface: \"mcp\", target, action });\n if (action === \"manual\") {\n notes.push(\n `${target} is not a YAML map CodeBuddy can edit safely; ${keepMcp ? \"add\" : \"remove\"} the \"${name}\" entry under mcp_servers by hand.`,\n );\n }\n } else {\n notes.push(\n `MCP config is global; ${keepMcp ? \"add\" : \"remove\"} it with --global, or: ${adapter.mcp.manual}.`,\n );\n }\n if (adapter.note && mode !== \"mcp-only\") notes.push(`${adapter.name}: ${adapter.note}.`);\n return { client: options.client, steps, notes };\n}\n\nasync function installedWithMcp(\n root: string,\n clients: ClientId[],\n namespace: string,\n): Promise<ClientId[]> {\n const live: ClientId[] = [];\n for (const id of clients) {\n if ((await detectClient(id, root, namespace)).mcp) live.push(id);\n }\n return live;\n}\n\n/** Install or remove a client's CodeBuddy lifecycle hooks; null when it has none. */\nexport async function setHooks(\n root: string,\n enabled: boolean,\n client: ClientId = \"claude\",\n variant: HookVariant = \"full\",\n): Promise<ClientStep | null> {\n const result = await setClientHooks(root, client, enabled, variant);\n if (!result) return null;\n const action = result.changed ? (enabled ? \"installed\" : \"removed\") : \"unchanged\";\n return { surface: \"hooks\", target: result.target, action };\n}\n\nexport type ClientStatus = {\n client: ClientId;\n /** The effective mode in this repo; \"none\" when nothing project-local is installed. */\n mode: AutomationMode | \"none\";\n rulesMode: AutomationMode | null;\n /** null = this client has no CodeBuddy hook adapter. */\n hooks: boolean | null;\n /** Project MCP entry, or for Codex/Hermes the entry in their global config. */\n mcp: boolean;\n warnings: string[];\n};\n\nexport async function detectClient(\n client: ClientId,\n projectRoot = process.cwd(),\n namespace?: string,\n): Promise<ClientStatus> {\n const root = resolve(projectRoot);\n const adapter = CLIENT_ADAPTERS[client];\n const rulesMode = await readManagedMode(join(root, adapter.rulesFile));\n const hooks = await clientHooksInstalled(root, client);\n const name = `codebuddy-${namespace ?? (await resolveNamespaceFrom(root))}`;\n const mcp =\n \"file\" in adapter.mcp\n ? await hasMcpServer(\n await projectMcpPath(root, adapter.mcp.file, adapter.mcp.format),\n adapter.mcp.format,\n name,\n )\n : await hasGlobalMcp(adapter.mcp.global, name).catch(() => false);\n\n const warnings: string[] = [];\n if (hooks && rulesMode === \"agent\") {\n warnings.push(\n `hooks are installed but ${adapter.rulesFile} is agent-driven: retrieval and capture run twice. Run \\`codebuddy clients install ${client} --mode hooks\\`.`,\n );\n }\n if (rulesMode === \"hooks\" && hooks === false) {\n warnings.push(\n `${adapter.rulesFile} is hook-driven but hooks are not installed: turns are not captured.`,\n );\n }\n // A hookless client reading a hook-driven block follows its agent-driven fallback.\n const effectiveRules = hooks === null && rulesMode === \"hooks\" ? \"agent\" : rulesMode;\n const mode: ClientStatus[\"mode\"] = hooks\n ? (await clientHooksVariant(root, client)) === \"lean\"\n ? \"lean\"\n : \"hooks\"\n : (effectiveRules ?? (mcp ? \"mcp-only\" : \"none\"));\n return { client, mode, rulesMode, hooks, mcp, warnings };\n}\n","import { access, mkdir, readFile, rm } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\n\nexport type ProjectMcpServer = {\n command: string;\n args: string[];\n env?: Record<string, string>;\n};\n\nexport type ProjectMcpConfig = {\n mcpServers?: Record<string, ProjectMcpServer>;\n};\n\nexport type WriteProjectMcpConfigOptions = {\n repositoryRoot: string;\n namespace: string;\n graphify: boolean;\n graphPath?: string;\n};\n\n/** Add CodeBuddy and, optionally, Graphify to the project's MCP config. */\nexport async function writeProjectMcpConfig(\n options: WriteProjectMcpConfigOptions,\n): Promise<{ path: string; servers: string[] }> {\n const path = join(options.repositoryRoot, \".mcp.json\");\n const current = await readProjectMcpConfig(path);\n current.mcpServers ??= {};\n current.mcpServers[`codebuddy-${options.namespace}`] = codebuddyMcpServer(\n options.repositoryRoot,\n options.namespace,\n );\n if (options.graphify) {\n current.mcpServers.graphify = {\n command: \"python\",\n args: [\n \"-m\",\n \"graphify.serve\",\n resolve(options.repositoryRoot, options.graphPath ?? \"graphify-out/graph.json\"),\n ],\n env: { CODEBUDDY_PROJECT_ROOT: options.repositoryRoot },\n };\n } else if (current.mcpServers.graphify) {\n delete current.mcpServers.graphify;\n }\n await writeAtomic(path, `${JSON.stringify(current, null, 2)}\\n`, { mode: 0o644 });\n return { path, servers: Object.keys(current.mcpServers).sort() };\n}\n\n/**\n * Project-local MCP config shapes: the common `mcpServers` map (Claude Code\n * `.mcp.json`, Freebuff `.agents/mcp.json`) and OpenCode's `mcp` map of\n * `{ type: \"local\", command: [...], environment }`.\n */\nexport type McpConfigFormat = \"mcpServers\" | \"opencode\";\n\nconst OPENCODE_SCHEMA = \"https://opencode.ai/config.json\";\n\nexport function codebuddyMcpServer(repositoryRoot: string, namespace: string): ProjectMcpServer {\n return {\n command: \"codebuddy\",\n args: [\"serve\"],\n env: {\n CODEBUDDY_PROJECT_ROOT: repositoryRoot,\n CODEBUDDY_NAMESPACE: namespace,\n CODEBUDDY_TOOL_PROFILE: \"core\",\n },\n };\n}\n\n/**\n * The config file to use: OpenCode reads `opencode.jsonc` too, so when only\n * that one exists it is edited instead of creating a second `opencode.json`.\n */\nexport async function projectMcpPath(\n root: string,\n file: string,\n format: McpConfigFormat,\n): Promise<string> {\n const path = join(root, file);\n if (format !== \"opencode\" || (await exists(path))) return path;\n return (await exists(`${path}c`)) ? `${path}c` : path;\n}\n\nasync function exists(path: string): Promise<boolean> {\n return access(path).then(\n () => true,\n () => false,\n );\n}\n\nexport function formatEntry(format: McpConfigFormat, server: ProjectMcpServer): unknown {\n if (format === \"mcpServers\") return server;\n return {\n type: \"local\",\n command: [server.command, ...server.args],\n ...(server.env ? { environment: server.env } : {}),\n enabled: true,\n };\n}\n\nfunction serversKey(format: McpConfigFormat): \"mcpServers\" | \"mcp\" {\n return format === \"opencode\" ? \"mcp\" : \"mcpServers\";\n}\n\n/**\n * Add or update one named server, keeping every other key the user has. Idempotent.\n * \"manual\" = the file has comments a rewrite would destroy, so nothing was written.\n */\nexport async function upsertMcpServer(\n path: string,\n format: McpConfigFormat,\n name: string,\n server: ProjectMcpServer,\n): Promise<\"created\" | \"updated\" | \"unchanged\" | \"manual\"> {\n const existed = await exists(path);\n const { config, comments } = await readConfig(path);\n const key = serversKey(format);\n const servers = { ...((config[key] as Record<string, unknown> | undefined) ?? {}) };\n const entry = formatEntry(format, server);\n if (JSON.stringify(servers[name]) === JSON.stringify(entry)) return \"unchanged\";\n if (comments) return \"manual\";\n servers[name] = entry;\n const next =\n format === \"opencode\" && !existed\n ? { $schema: OPENCODE_SCHEMA, ...config, [key]: servers }\n : { ...config, [key]: servers };\n await mkdir(dirname(path), { recursive: true });\n await writeAtomic(path, `${JSON.stringify(next, null, 2)}\\n`, { mode: 0o644 });\n return existed ? \"updated\" : \"created\";\n}\n\n/** Remove one named server; delete the file if CodeBuddy's entry was all it held. */\nexport async function removeMcpServer(\n path: string,\n format: McpConfigFormat,\n name: string,\n): Promise<\"removed\" | \"unchanged\" | \"manual\"> {\n const { config, comments } = await readConfig(path);\n const key = serversKey(format);\n const servers = { ...((config[key] as Record<string, unknown> | undefined) ?? {}) };\n if (!(name in servers)) return \"unchanged\";\n if (comments) return \"manual\";\n delete servers[name];\n const next = { ...config, [key]: servers };\n const leftover = Object.keys(next).filter((k) => k !== key && k !== \"$schema\");\n if (Object.keys(servers).length === 0 && leftover.length === 0) await rm(path, { force: true });\n else await writeAtomic(path, `${JSON.stringify(next, null, 2)}\\n`, { mode: 0o644 });\n return \"removed\";\n}\n\nexport async function hasMcpServer(\n path: string,\n format: McpConfigFormat,\n name: string,\n): Promise<boolean> {\n const { config } = await readConfig(path);\n return name in ((config[serversKey(format)] as Record<string, unknown> | undefined) ?? {});\n}\n\n/**\n * Parse JSON with comments and trailing commas (OpenCode accepts both in\n * opencode.json and opencode.jsonc). Strings match first, so `//` or `,}`\n * inside a string value are left alone.\n */\nexport function parseJsonc(raw: string): { value: unknown; comments: boolean } {\n let comments = false;\n const json = raw\n .replace(/\"(?:[^\"\\\\]|\\\\.)*\"|\\/\\/[^\\n]*|\\/\\*[\\s\\S]*?\\*\\//g, (match) => {\n if (match.startsWith('\"')) return match;\n comments = true;\n return \" \";\n })\n .replace(/\"(?:[^\"\\\\]|\\\\.)*\"|,(\\s*[}\\]])/g, (match, tail: string | undefined) => tail ?? match);\n return { value: JSON.parse(json), comments };\n}\n\nasync function readConfig(\n path: string,\n): Promise<{ config: Record<string, unknown>; comments: boolean }> {\n try {\n const { value, comments } = parseJsonc(await readFile(path, \"utf8\"));\n const config = value && typeof value === \"object\" ? (value as Record<string, unknown>) : {};\n return { config, comments };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { config: {}, comments: false };\n throw new Error(`Could not read ${path}: ${(error as Error).message}`);\n }\n}\n\nasync function readProjectMcpConfig(path: string): Promise<ProjectMcpConfig> {\n return (await readConfig(path)).config as ProjectMcpConfig;\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { writeAtomic } from \"../../core/markdown-store-fs.js\";\nimport { buildEntry, type ClaudeDesktopEntry } from \"./claude-desktop.js\";\n\nexport type CodexConfigEntry = ClaudeDesktopEntry;\n\nexport function codexConfigPath(home = homedir()): string {\n return join(home, \".codex\", \"config.toml\");\n}\n\nexport async function readCodexConfig(path: string): Promise<string> {\n if (!existsSync(path)) return \"\";\n return readFile(path, \"utf8\");\n}\n\nexport async function writeCodexConfig(path: string, content: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n // Atomic + 0600: the TOML carries env secrets (HF token, DATABASE_URL).\n await writeAtomic(path, content, { mode: 0o600 });\n}\n\nexport type InstallCodexEntryOptions = {\n namespace: string;\n projectRoot?: string;\n hfToken?: string;\n databaseUrl?: string;\n serverName?: string;\n toolProfile?: \"core\" | \"full\";\n};\n\nexport type InstallCodexResult = {\n path: string;\n serverKey: string;\n created: boolean;\n changed: boolean;\n};\n\nexport async function installCodexEntry(\n options: InstallCodexEntryOptions,\n): Promise<InstallCodexResult> {\n const path = codexConfigPath();\n const serverKey = options.serverName ?? `codebuddy-${options.namespace}`;\n const current = await readCodexConfig(path);\n const existed = hasServerBlock(current, serverKey);\n const entry = buildEntry(options);\n if (options.toolProfile)\n entry.env = { ...entry.env, CODEBUDDY_TOOL_PROFILE: options.toolProfile };\n const next = upsertServerBlock(current, serverKey, entry);\n if (next !== current) await writeCodexConfig(path, next);\n return { path, serverKey, created: !existed, changed: next !== current };\n}\n\nexport async function removeCodexEntry(\n serverKey: string,\n): Promise<{ removed: boolean; path: string }> {\n const path = codexConfigPath();\n const current = await readCodexConfig(path);\n const next = removeServerBlock(current, serverKey);\n const removed = next !== current;\n // Drop the blank separator install added, so install + remove is a no-op.\n const trimmed = next.trimEnd();\n if (removed) await writeCodexConfig(path, trimmed ? `${trimmed}\\n` : \"\");\n return { removed, path };\n}\n\nexport async function listCodexEntries(): Promise<{\n path: string;\n entries: Array<{ key: string; namespace: string | null; databaseUrl: string | null }>;\n}> {\n const path = codexConfigPath();\n const config = await readCodexConfig(path);\n const entries = Array.from(config.matchAll(/^\\[mcp_servers\\.\"([^\"]+)\"\\]\\s*$/gm))\n .flatMap((match) => (match[1] ? [match[1]] : []))\n .filter((key) => key === \"codebuddy\" || key.startsWith(\"codebuddy-\"))\n .map((key) => {\n const block = getServerBlock(config, key);\n return {\n key,\n namespace: readEnvValue(block, \"CODEBUDDY_NAMESPACE\"),\n databaseUrl: readEnvValue(block, \"DATABASE_URL\"),\n };\n });\n return { path, entries };\n}\n\nfunction upsertServerBlock(config: string, serverKey: string, entry: CodexConfigEntry): string {\n const trimmed = removeServerBlock(config, serverKey).trimEnd();\n const block = formatServerBlock(serverKey, entry);\n return `${trimmed}${trimmed ? \"\\n\\n\" : \"\"}${block}\\n`;\n}\n\nfunction removeServerBlock(config: string, serverKey: string): string {\n const escaped = escapeRegExp(serverKey);\n const end = String.raw`(?![\\s\\S])`;\n const sectionPattern = String.raw`^\\[mcp_servers\\.\"${escaped}\"\\][\\s\\S]*?(?=^\\[[^\\]]+\\]\\s*$|${end})`;\n const envPattern = String.raw`^\\[mcp_servers\\.\"${escaped}\"\\.env\\][\\s\\S]*?(?=^\\[[^\\]]+\\]\\s*$|${end})`;\n return config\n .replace(new RegExp(sectionPattern, \"gm\"), \"\")\n .replace(new RegExp(envPattern, \"gm\"), \"\");\n}\n\nfunction getServerBlock(config: string, serverKey: string): string {\n const escaped = escapeRegExp(serverKey);\n const end = String.raw`(?![\\s\\S])`;\n const pattern = String.raw`^\\[mcp_servers\\.\"${escaped}\"\\][\\s\\S]*?(?=^\\[mcp_servers\\.\"${escaped}\"\\.env\\][\\s\\S]*?(?=^\\[[^\\]]+\\]\\s*$|${end})|^\\[[^\\]]+\\]\\s*$|${end})`;\n const server = config.match(new RegExp(pattern, \"m\"))?.[0] ?? \"\";\n const env =\n config.match(\n new RegExp(\n String.raw`^\\[mcp_servers\\.\"${escaped}\"\\.env\\][\\s\\S]*?(?=^\\[[^\\]]+\\]\\s*$|${end})`,\n \"m\",\n ),\n )?.[0] ?? \"\";\n return `${server}\\n${env}`;\n}\n\nfunction hasServerBlock(config: string, serverKey: string): boolean {\n return new RegExp(String.raw`^\\[mcp_servers\\.\"${escapeRegExp(serverKey)}\"\\]\\s*$`, \"m\").test(\n config,\n );\n}\n\nfunction formatServerBlock(serverKey: string, entry: CodexConfigEntry): string {\n const lines = [\n `[mcp_servers.${tomlKey(serverKey)}]`,\n `command = ${tomlString(entry.command)}`,\n `args = ${tomlArray(entry.args)}`,\n ];\n if (entry.env && Object.keys(entry.env).length > 0) {\n lines.push(\"\", `[mcp_servers.${tomlKey(serverKey)}.env]`);\n for (const [key, value] of Object.entries(entry.env).sort(([left], [right]) =>\n left.localeCompare(right),\n )) {\n lines.push(`${key} = ${tomlString(value)}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction readEnvValue(block: string, key: string): string | null {\n return block.match(new RegExp(`^${escapeRegExp(key)}\\\\s*=\\\\s*\"([^\"]*)\"`, \"m\"))?.[1] ?? null;\n}\n\nfunction tomlKey(key: string): string {\n return `\"${key.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"')}\"`;\n}\n\nfunction tomlString(value: string): string {\n return JSON.stringify(value);\n}\n\nfunction tomlArray(values: string[]): string {\n return `[${values.map(tomlString).join(\", \")}]`;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { mkdir, readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { writeAtomic } from \"../core/markdown-store-fs.js\";\nimport type { ProjectMcpServer } from \"./project-mcp.js\";\n\n/**\n * Key-scoped edits of Hermes' global `config.yaml`. A YAML round-trip would\n * refold the user's long strings and drop formatting, so only the lines of\n * one `mcp_servers.<name>` entry are rewritten; every other line and comment\n * stays byte-for-byte. Each edit is re-parsed and must equal the old config\n * with exactly that entry changed, otherwise nothing is written (\"manual\").\n */\n\n/** Hermes honours HERMES_HOME, like `hermes` itself. */\nexport function hermesConfigPath(home = homedir()): string {\n return join(process.env.HERMES_HOME ?? join(home, \".hermes\"), \"config.yaml\");\n}\n\ntype Config = Record<string, unknown>;\n\nasync function readRaw(path: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return \"\";\n throw error;\n }\n}\n\n/** The parsed top-level map, or null when the file is not a YAML map CodeBuddy can reason about. */\nfunction parseConfig(raw: string): Config | null {\n try {\n const value = parseYaml(raw) ?? {};\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as Config) : null;\n } catch {\n return null;\n }\n}\n\nfunction servers(config: Config): Record<string, unknown> {\n const value = config.mcp_servers;\n return value && typeof value === \"object\" ? (value as Record<string, unknown>) : {};\n}\n\nconst isItem = (line: string) => line.trim() !== \"\" && !line.trim().startsWith(\"#\");\nconst indentOf = (line: string) => line.length - line.trimStart().length;\n\n/** Text edit of `mcp_servers.<name>`; `entry` null removes it. */\nexport function editMcpServers(raw: string, name: string, entry: unknown | null): string {\n const lines = raw.split(\"\\n\");\n const header = lines.findIndex((line) => /^mcp_servers:\\s*(#.*)?$/.test(line));\n const render = (indent: number) =>\n stringifyYaml({ [name]: entry })\n .trimEnd()\n .split(\"\\n\")\n .map((line) => `${\" \".repeat(indent)}${line}`);\n\n if (header === -1) {\n if (entry === null) return raw;\n // No separator line, so removing the entry restores the file byte-for-byte.\n const body = raw === \"\" || raw.endsWith(\"\\n\") ? raw : `${raw}\\n`;\n return `${body}mcp_servers:\\n${render(2).join(\"\\n\")}\\n`;\n }\n // The block runs until the next line that starts at column 0.\n let end = header + 1;\n while (end < lines.length && !/^\\S/.test(lines[end] ?? \"\")) end++;\n const block = Array.from({ length: end - header - 1 }, (_, i) => header + 1 + i);\n const items = block.filter((i) => isItem(lines[i] ?? \"\"));\n const indent = items.length > 0 ? indentOf(lines[items[0] as number] ?? \"\") : 2;\n const quoted = name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const keyLine = new RegExp(`^ {${indent}}(?:${quoted}|\"${quoted}\"|'${quoted}'):\\\\s*(#.*)?$`);\n const start = items.find((i) => keyLine.test(lines[i] ?? \"\"));\n\n if (start === undefined) {\n if (entry === null) return raw;\n const at = (items.at(-1) ?? header) + 1;\n lines.splice(at, 0, ...render(indent));\n return lines.join(\"\\n\");\n }\n // Our entry ends at the next sibling key or sibling-level comment (the user's).\n const next = block.find(\n (i) => i > start && (lines[i] ?? \"\").trim() !== \"\" && indentOf(lines[i] ?? \"\") <= indent,\n );\n let stop = next ?? end;\n while (stop > start + 1 && (lines[stop - 1] ?? \"\").trim() === \"\") stop--;\n lines.splice(start, stop - start, ...(entry === null ? [] : render(indent)));\n // Removing the only entry leaves `mcp_servers:` null; drop the header as well.\n if (entry === null && items.length > 0 && items.every((i) => i >= start && i < stop)) {\n lines.splice(header, 1);\n }\n return lines.join(\"\\n\");\n}\n\nexport type HermesMcpAction = \"created\" | \"updated\" | \"unchanged\" | \"removed\" | \"manual\";\n\n/** Add, update (entry) or remove (null) CodeBuddy's server; never touches anything else. */\nexport async function setHermesMcpServer(\n path: string,\n name: string,\n entry: ProjectMcpServer | null,\n): Promise<HermesMcpAction> {\n const raw = await readRaw(path);\n const before = parseConfig(raw);\n if (!before) return \"manual\";\n const current = servers(before)[name];\n if (entry === null ? current === undefined : isDeepStrictEqual(current, entry)) {\n return \"unchanged\";\n }\n const nextServers = { ...servers(before) };\n if (entry === null) delete nextServers[name];\n else nextServers[name] = entry;\n const { mcp_servers: _, ...rest } = before;\n const expected =\n Object.keys(nextServers).length > 0 ? { ...rest, mcp_servers: nextServers } : rest;\n\n const next = editMcpServers(raw, name, entry);\n if (!isDeepStrictEqual(parseConfig(next), expected)) return \"manual\";\n await mkdir(dirname(path), { recursive: true });\n // Atomic + 0600: Hermes keeps provider keys in this file.\n await writeAtomic(path, next, { mode: 0o600 });\n return entry === null ? \"removed\" : current === undefined ? \"created\" : \"updated\";\n}\n\nexport async function readHermesConfig(path: string): Promise<Config | null> {\n return parseConfig(await readRaw(path));\n}\n\nexport async function hasHermesMcpServer(path: string, name: string): Promise<boolean> {\n const config = await readHermesConfig(path);\n return config !== null && name in servers(config);\n}\n","import {\n codexConfigPath,\n installCodexEntry,\n listCodexEntries,\n removeCodexEntry,\n} from \"../cli/commands/codex.js\";\nimport {\n hasHermesMcpServer,\n hermesConfigPath,\n setHermesMcpServer,\n} from \"../integrations/hermes-config.js\";\nimport { codebuddyMcpServer } from \"../integrations/project-mcp.js\";\n\n/**\n * The CodeBuddy server entry in a client's global MCP config, written only on\n * explicit opt-in (`clients install|uninstall --global`). Codex reuses the\n * `codebuddy codex install` TOML editor; Hermes gets a key-scoped YAML edit.\n */\nexport type GlobalMcp = \"codex\" | \"hermes\";\n\nexport function globalMcpPath(target: GlobalMcp): string {\n return target === \"codex\" ? codexConfigPath() : hermesConfigPath();\n}\n\nexport async function setGlobalMcp(\n target: GlobalMcp,\n options: { name: string; root: string; namespace: string; enabled: boolean },\n): Promise<string> {\n const { name, root, namespace, enabled } = options;\n if (target === \"hermes\") {\n return setHermesMcpServer(\n hermesConfigPath(),\n name,\n enabled ? codebuddyMcpServer(root, namespace) : null,\n );\n }\n if (!enabled) return (await removeCodexEntry(name)).removed ? \"removed\" : \"unchanged\";\n const result = await installCodexEntry({\n namespace,\n projectRoot: root,\n serverName: name,\n toolProfile: \"core\",\n });\n return result.created ? \"created\" : result.changed ? \"updated\" : \"unchanged\";\n}\n\nexport async function hasGlobalMcp(target: GlobalMcp, name: string): Promise<boolean> {\n if (target === \"hermes\") return hasHermesMcpServer(hermesConfigPath(), name);\n return (await listCodexEntries()).entries.some((entry) => entry.key === name);\n}\n","import { execFile } from \"node:child_process\";\nimport { readFile, realpath } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { resolveNamespaceFrom } from \"../core/config-file.js\";\nimport { hermesPluginInstalled } from \"../hooks/hermes-plugin.js\";\nimport { clientHooksInstalled } from \"../hooks/install.js\";\nimport { hermesConfigPath, readHermesConfig } from \"../integrations/hermes-config.js\";\nimport {\n CLIENT_ADAPTERS,\n type ClientId,\n LIFECYCLE_EVENTS,\n type LifecycleEvent,\n} from \"./adapters.js\";\n\n/**\n * `codebuddy clients verify`: compares the installed host with the version\n * its adapter was verified against, and runs the conformance checks that need\n * no model call (version, config/plugin/MCP listings). Offline-safe and\n * fail-soft: a missing host or a failing command is a reported result.\n */\n\nexport type HostRun = { ok: boolean; stdout: string };\nexport type HostRunner = (bin: string, args: string[], cwd: string) => Promise<HostRun>;\n\n/** Run a host CLI with a timeout; never throws. */\nexport const runHost: HostRunner = (bin, args, cwd) =>\n new Promise((done) => {\n execFile(bin, args, { cwd, timeout: 15_000, maxBuffer: 8 * 1024 * 1024 }, (error, stdout) =>\n done({ ok: !error, stdout: String(stdout ?? \"\") }),\n );\n });\n\nexport type Check = { name: string; status: \"pass\" | \"fail\" | \"skip\"; detail: string };\n\nexport type ClientVerification = {\n client: ClientId;\n /** Detected host version; null when the host is not installed. */\n installed: string | null;\n verified: string;\n drift: \"match\" | \"drift\" | \"not-installed\";\n events: Array<{ event: LifecycleEvent; wired: boolean }>;\n checks: Check[];\n};\n\ntype Context = { root: string; name: string; run: HostRunner; env: NodeJS.ProcessEnv };\n\nconst pass = (name: string, detail: string): Check => ({ name, status: \"pass\", detail });\nconst fail = (name: string, detail: string): Check => ({ name, status: \"fail\", detail });\nconst skip = (name: string, detail: string): Check => ({ name, status: \"skip\", detail });\n\nfunction json(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\n/** Host-specific checks, run only when the host is installed. */\nconst CONFORMANCE: Partial<Record<ClientId, (ctx: Context) => Promise<Check[]>>> = {\n claude: async ({ root, name, run }) => {\n const hooks = (await clientHooksInstalled(root, \"claude\"))\n ? pass(\"hooks\", \".claude/settings.json has the CodeBuddy hooks\")\n : skip(\"hooks\", \"not installed in this repo\");\n const mcp = await run(\"claude\", [\"mcp\", \"get\", name], root);\n return [\n hooks,\n mcp.ok\n ? pass(\"mcp\", `claude mcp get ${name}: ${mcp.stdout.match(/Scope: (.+)/)?.[1] ?? \"found\"}`)\n : skip(\"mcp\", `claude mcp get ${name}: not configured`),\n ];\n },\n opencode: async ({ root, name, run }) => {\n const result = await run(\"opencode\", [\"debug\", \"config\"], root);\n const config = json(result.stdout) as {\n plugin?: string[];\n mcp?: Record<string, unknown>;\n } | null;\n if (!config) return [fail(\"config\", \"opencode debug config returned no JSON\")];\n const installed = await clientHooksInstalled(root, \"opencode\");\n const href = pathToFileURL(\n join(await realpath(root).catch(() => root), \".opencode\", \"plugins\", \"codebuddy.js\"),\n ).href;\n const loaded = config.plugin?.includes(href) === true;\n return [\n installed\n ? loaded\n ? pass(\"plugin\", \"opencode debug config loads .opencode/plugins/codebuddy.js\")\n : fail(\"plugin\", \"plugin file is installed but opencode does not load it\")\n : skip(\"plugin\", \"not installed in this repo\"),\n config.mcp?.[name]\n ? pass(\"mcp\", `opencode resolves the ${name} MCP entry`)\n : skip(\"mcp\", `no ${name} entry in the resolved config`),\n ];\n },\n codex: async ({ root, name, run }) => {\n const result = await run(\"codex\", [\"mcp\", \"list\", \"--json\"], root);\n const servers = json(result.stdout);\n if (!Array.isArray(servers)) return [fail(\"mcp\", \"codex mcp list --json returned no JSON\")];\n return [\n servers.some((server) => (server as { name?: string }).name === name)\n ? pass(\"mcp\", `codex mcp list has ${name}`)\n : skip(\"mcp\", `no ${name} entry (clients install codex --global adds it)`),\n ];\n },\n hermes: async ({ root, name, run, env }) => {\n const checks: Check[] = [];\n const listed = await run(\"hermes\", [\"mcp\", \"list\"], root);\n checks.push(\n listed.ok && listed.stdout.includes(name)\n ? pass(\"mcp\", `hermes mcp list has ${name}`)\n : skip(\"mcp\", `no ${name} entry (clients install hermes --global adds it)`),\n );\n if (!(await hermesPluginInstalled(root))) {\n checks.push(skip(\"plugin\", \"not installed in this repo\"));\n return checks;\n }\n const projectPlugins =\n /^(1|true|yes|on)$/i.test(env.HERMES_ENABLE_PROJECT_PLUGINS ?? \"\") ||\n /^\\s*HERMES_ENABLE_PROJECT_PLUGINS\\s*=\\s*[\"']?(1|true|yes|on)/im.test(\n await readFile(join(hermesConfigPath(), \"..\", \".env\"), \"utf8\").catch(() => \"\"),\n );\n const plugins = (await readHermesConfig(hermesConfigPath()))?.plugins as\n | { enabled?: unknown }\n | undefined;\n const enabled = Array.isArray(plugins?.enabled) && plugins.enabled.includes(\"codebuddy\");\n checks.push(\n projectPlugins\n ? pass(\"project-plugins\", \"HERMES_ENABLE_PROJECT_PLUGINS is set\")\n : fail(\"project-plugins\", \"set HERMES_ENABLE_PROJECT_PLUGINS=1 (shell or ~/.hermes/.env)\"),\n enabled\n ? pass(\"plugin-enabled\", \"codebuddy is in plugins.enabled\")\n : fail(\"plugin-enabled\", \"add codebuddy to plugins.enabled in ~/.hermes/config.yaml\"),\n );\n return checks;\n },\n};\n\nexport async function verifyClient(\n client: ClientId,\n options: { root?: string; namespace?: string; run?: HostRunner; env?: NodeJS.ProcessEnv } = {},\n): Promise<ClientVerification> {\n const root = resolve(options.root ?? process.cwd());\n const run = options.run ?? runHost;\n const adapter = CLIENT_ADAPTERS[client];\n const version = await run(adapter.host.bin, [\"--version\"], root);\n const installed = version.ok ? (version.stdout.match(/\\d+\\.\\d+\\.\\d+/)?.[0] ?? null) : null;\n const events = LIFECYCLE_EVENTS.map((event) => ({\n event,\n wired: adapter.hookEvents.includes(event),\n }));\n if (!installed) {\n return {\n client,\n installed: null,\n verified: adapter.host.verified,\n drift: \"not-installed\",\n events,\n checks: [skip(\"host\", `${adapter.host.bin} not found or printed no version`)],\n };\n }\n const name = `codebuddy-${options.namespace ?? (await resolveNamespaceFrom(root))}`;\n const conformance = CONFORMANCE[client];\n const checks = conformance\n ? await conformance({ root, name, run, env: options.env ?? process.env }).catch(\n (error: Error) => [fail(\"conformance\", error.message)],\n )\n : [];\n return {\n client,\n installed,\n verified: adapter.host.verified,\n drift: installed === adapter.host.verified ? \"match\" : \"drift\",\n events,\n checks: [pass(\"host\", `${adapter.host.bin} ${installed}`), ...checks],\n };\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { buildBeforeEditContext, buildBootstrapContext } from \"../../context/engine.js\";\nimport type { BeforeEditContext, BootstrapContext } from \"../../context/types.js\";\nimport { readConfigFile, resolveNamespaceFrom } from \"../../core/config-file.js\";\nimport { openHookSemantics } from \"../../hooks/semantic.js\";\n\n/**\n * Context previews are file-based (plan store, risk service, architecture map,\n * Markdown memory) so they run without a database connection — the same\n * lightweight path the plan and risk commands use.\n */\n\nasync function resolveTokenBudget(cwd = process.cwd()): Promise<number | undefined> {\n const file = await readConfigFile(cwd);\n return file.tokenBudget;\n}\n\nfunction parsePaths(value: string): string[] {\n return value\n .split(\",\")\n .map((path) => path.trim())\n .filter(Boolean);\n}\n\nexport function registerContextCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const context = program\n .command(\"context\")\n .description(\"Preview the compact project context CodeBuddy would send to an agent.\");\n\n context\n .command(\"bootstrap\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"Show start-of-turn project awareness (plan, policy, incidents, architecture).\")\n .action(async (opts: { json?: boolean }) => {\n await runSafely(async () => {\n const [namespace, tokenBudget] = await Promise.all([\n resolveNamespaceFrom(),\n resolveTokenBudget(),\n ]);\n const result = await buildBootstrapContext({\n namespace,\n ...(tokenBudget !== undefined ? { tokenBudget } : {}),\n });\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n printBootstrap(result);\n });\n });\n\n context\n .command(\"preview\")\n .argument(\"[task...]\", \"The task you are about to work on.\")\n .option(\"--paths <paths>\", \"Comma-separated repo-relative paths to target.\")\n .option(\"--plan <id>\", \"Resolve target files from a CodeBuddy plan.\")\n .option(\"--git\", \"Resolve target files from current git changes.\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"Show the context CodeBuddy would assemble before editing the given files.\")\n .action(\n async (\n taskParts: string[],\n opts: { paths?: string; plan?: string; git?: boolean; json?: boolean },\n ) => {\n await runSafely(async () => {\n const result = await runBeforeEdit(taskParts, opts);\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n printBeforeEdit(result);\n });\n },\n );\n\n context\n .command(\"explain\")\n .argument(\"[task...]\", \"The task you are about to work on.\")\n .option(\"--paths <paths>\", \"Comma-separated repo-relative paths to target.\")\n .option(\"--plan <id>\", \"Resolve target files from a CodeBuddy plan.\")\n .option(\"--git\", \"Resolve target files from current git changes.\")\n .description(\"Explain why each piece of before-edit context was included.\")\n .action(async (taskParts: string[], opts: { paths?: string; plan?: string; git?: boolean }) => {\n await runSafely(async () => {\n const result = await runBeforeEdit(taskParts, opts);\n console.log(pc.bold(`context for ${result.targetPaths.length} target path(s):`));\n for (const line of result.explain) console.log(` ${pc.dim(\"•\")} ${line}`);\n });\n });\n}\n\nasync function runBeforeEdit(\n taskParts: string[],\n opts: { paths?: string; plan?: string; git?: boolean },\n): Promise<BeforeEditContext> {\n const [namespace, tokenBudget] = await Promise.all([\n resolveNamespaceFrom(),\n resolveTokenBudget(),\n ]);\n const task = taskParts.join(\" \").trim();\n // Same recall as the prompt hook: dense evidence and the configured reranker.\n const semantics = task ? await openHookSemantics(process.cwd()) : null;\n try {\n return await buildBeforeEditContext({\n namespace,\n ...(task ? { task } : {}),\n ...(semantics?.semanticRanker ? { semanticRanker: semantics.semanticRanker } : {}),\n ...(semantics?.reranker ? { reranker: semantics.reranker } : {}),\n ...(opts.paths ? { paths: parsePaths(opts.paths) } : {}),\n ...(opts.plan ? { planId: opts.plan } : {}),\n ...(opts.git !== undefined ? { useGit: opts.git } : {}),\n ...(tokenBudget !== undefined ? { tokenBudget } : {}),\n });\n } finally {\n await semantics?.close();\n }\n}\n\nfunction printBootstrap(ctx: BootstrapContext): void {\n console.log(`${pc.bold(\"project\")} ${ctx.project.namespace} ${pc.dim(ctx.project.root)}`);\n console.log(\n `${pc.bold(\"plan\")} ${ctx.plan ? `${ctx.plan.title} (${ctx.plan.status})` : pc.dim(\"none\")} ${pc.dim(`policy=${ctx.policy}`)}`,\n );\n if (ctx.policyRules.length > 0) {\n console.log(pc.bold(\"policy rules:\"));\n for (const rule of ctx.policyRules) {\n console.log(` ${rule.id} (${rule.weight}) ${pc.dim(rule.pattern)}`);\n }\n }\n if (ctx.incidents.length > 0) {\n console.log(pc.bold(\"incident hotspots:\"));\n for (const incident of ctx.incidents) {\n console.log(\n ` ${severityColor(incident.severity)} ${incident.subject} ${pc.dim(incident.summary)}`,\n );\n }\n }\n printMemory(ctx);\n console.log(\n `${pc.bold(\"architecture\")} ${ctx.architecture.moduleCount} modules, ${ctx.architecture.edgeCount} edges`,\n );\n for (const hotspot of ctx.architecture.hotspots) {\n console.log(` ${hotspot.path} ${pc.dim(`in=${hotspot.inbound} out=${hotspot.outbound}`)}`);\n }\n printTokens(ctx);\n}\n\nfunction printBeforeEdit(ctx: BeforeEditContext): void {\n console.log(\n `${pc.bold(\"targets\")} ${ctx.targetPaths.length} path(s) ${pc.dim(`(source: ${ctx.pathSource})`)}`,\n );\n for (const path of ctx.targetPaths) console.log(` ${path}`);\n if (ctx.plan) console.log(`${pc.bold(\"plan\")} ${ctx.plan.title} (${ctx.plan.status})`);\n if (ctx.policyRules.length > 0) {\n console.log(pc.bold(\"matching policy rules:\"));\n for (const rule of ctx.policyRules) console.log(` ${rule.id} ${pc.dim(rule.pattern)}`);\n }\n if (ctx.incidents.length > 0) {\n console.log(pc.bold(\"incidents on target paths:\"));\n for (const incident of ctx.incidents) {\n console.log(` ${severityColor(incident.severity)} ${incident.subject}`);\n }\n }\n printMemory(ctx);\n if (ctx.risks.items.length > 0) {\n console.log(pc.bold(\"risk:\"));\n for (const item of ctx.risks.items) {\n console.log(` ${item.path} ${scoreColor(item.score)} ${pc.dim(item.reason)}`);\n }\n }\n if (ctx.neighbours.length > 0) {\n console.log(pc.bold(\"import neighbours:\"));\n for (const neighbour of ctx.neighbours) {\n console.log(\n ` ${neighbour.path} ${pc.dim(`→${neighbour.dependsOn.length} ←${neighbour.dependedOnBy.length}`)}`,\n );\n }\n }\n if (ctx.symbols.length > 0) {\n console.log(pc.bold(\"symbols (signatures, in place of full source):\"));\n for (const file of ctx.symbols) {\n console.log(` ${file.path} ${pc.dim(`${file.signatures.length} symbol(s)`)}`);\n }\n }\n if (ctx.diffs.length > 0) {\n console.log(pc.bold(\"changed hunks:\"));\n for (const diff of ctx.diffs) {\n console.log(` ${diff.path}${diff.truncated ? pc.dim(\" (truncated)\") : \"\"}`);\n for (const line of diff.patch.split(\"\\n\").slice(-8)) console.log(pc.dim(` ${line}`));\n }\n }\n printTokens(ctx);\n}\n\n/** Durable facts and worklog handoffs: the same memory the MCP tools return. */\nfunction printMemory(ctx: BootstrapContext | BeforeEditContext): void {\n if (ctx.facts.length > 0) {\n console.log(pc.bold(\"facts:\"));\n for (const fact of ctx.facts) {\n console.log(` ${fact.summary} ${pc.dim(`(${fact.confidence.toFixed(2)}, ${fact.reason})`)}`);\n }\n }\n if (ctx.handoffs.length > 0) {\n console.log(pc.bold(\"prior work:\"));\n for (const handoff of ctx.handoffs) {\n const drift =\n handoff.changedSince.length > 0\n ? `, ${handoff.changedSince.length} file(s) changed since`\n : \"\";\n console.log(\n ` ${handoff.summary.replace(/\\s+/g, \" \").slice(0, 160)} ${pc.dim(`(${handoff.ageDays}d ago${drift})`)}`,\n );\n }\n }\n}\n\nfunction printTokens(ctx: BootstrapContext | BeforeEditContext): void {\n const { returnedEstimate, budget } = ctx.tokens;\n console.log(pc.dim(`\\n~${returnedEstimate} tokens returned (budget ${budget})`));\n}\n\nfunction severityColor(severity: string): string {\n if (severity === \"critical\") return pc.red(severity);\n if (severity === \"high\") return pc.red(severity);\n if (severity === \"medium\") return pc.yellow(severity);\n return pc.dim(severity);\n}\n\nfunction scoreColor(score: number): string {\n if (score >= 75) return pc.red(String(score));\n if (score >= 50) return pc.yellow(String(score));\n return pc.green(String(score));\n}\n","import { spawn } from \"node:child_process\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { startDashboard } from \"../../dashboard/server.js\";\nimport { readTraces, tracePath } from \"../../tracing/log.js\";\n\n/** Open a URL in the default browser; best-effort, the URL is printed either way. */\nfunction openBrowser(url: string): void {\n const [command, args] =\n process.platform === \"darwin\"\n ? [\"open\", [url]]\n : process.platform === \"win32\"\n ? [\"cmd\", [\"/c\", \"start\", \"\", url]]\n : [\"xdg-open\", [url]];\n try {\n spawn(command, args, { detached: true, stdio: \"ignore\" })\n .on(\"error\", () => undefined)\n .unref();\n } catch {\n // No browser launcher: the printed URL still works.\n }\n}\n\nexport function registerDashboardCommand(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n program\n .command(\"dashboard\")\n .description(\"Open a live local page of prompts recalled, MCP tool calls, tokens and latency.\")\n .option(\n \"--port <port>\",\n \"Port on 127.0.0.1 (the next free one is used if taken).\",\n Number,\n 4777,\n )\n .option(\"--no-open\", \"Print the URL without opening a browser.\")\n .action(async (opts: { port: number; open: boolean }) => {\n await runSafely(async () => {\n const root = process.cwd();\n const dashboard = await startDashboard({ repositoryRoot: root, port: opts.port });\n const recorded = (await readTraces(root)).length;\n console.log(`${pc.green(\"●\")} CodeBuddy dashboard ${pc.bold(dashboard.url)}`);\n console.log(\n pc.dim(\n recorded > 0\n ? ` ${recorded} event(s) in ${tracePath(root)}; new ones appear live.`\n : \" No traces yet: they appear as your agent uses CodeBuddy (hooks or MCP tools).\",\n ),\n );\n console.log(pc.dim(\" Ctrl+C to stop.\"));\n if (opts.open) openBrowser(dashboard.url);\n await new Promise<void>((resolve) => {\n const stop = () => void dashboard.close().then(resolve);\n process.once(\"SIGINT\", stop);\n process.once(\"SIGTERM\", stop);\n });\n });\n });\n}\n","import { unwatchFile, watchFile } from \"node:fs\";\nimport { open, stat } from \"node:fs/promises\";\nimport { createServer, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { basename } from \"node:path\";\nimport { parseTraceLines, readTraces, tracePath } from \"../tracing/log.js\";\nimport { DASHBOARD_HTML } from \"./page.js\";\n\n/**\n * `codebuddy dashboard`: a read-only page on 127.0.0.1 that shows the\n * project's usage traces and updates itself. `/api/traces` serves the latest\n * events; `/events` streams new ones (Server-Sent Events) as hooks and MCP\n * tools append them to `.codebuddy/cache/traces.jsonl`.\n */\n\nexport type DashboardHandle = { url: string; close(): Promise<void> };\n\nexport async function startDashboard(options: {\n repositoryRoot: string;\n port?: number;\n /** How often the trace file is checked for new lines. */\n pollMs?: number;\n}): Promise<DashboardHandle> {\n const { repositoryRoot } = options;\n const path = tracePath(repositoryRoot);\n const clients = new Set<ServerResponse>();\n let offset = (await stat(path).catch(() => null))?.size ?? 0;\n let reading = false;\n\n // Send only the bytes appended since the last check; a shrink (rotation) means start over.\n const onChange = async () => {\n if (reading) return;\n reading = true;\n try {\n const size = (await stat(path).catch(() => null))?.size ?? 0;\n if (size < offset) {\n offset = 0;\n broadcast(\"reset\", \"{}\");\n }\n if (size > offset) {\n const handle = await open(path, \"r\");\n try {\n const buffer = Buffer.alloc(size - offset);\n await handle.read(buffer, 0, buffer.length, offset);\n const text = buffer.toString(\"utf8\");\n // Keep a trailing partial line for the next round.\n const complete = text.slice(0, text.lastIndexOf(\"\\n\") + 1);\n offset += Buffer.byteLength(complete);\n for (const event of parseTraceLines(complete)) broadcast(\"trace\", JSON.stringify(event));\n } finally {\n await handle.close();\n }\n }\n } finally {\n reading = false;\n }\n };\n const broadcast = (event: string, data: string) => {\n for (const client of clients) client.write(`event: ${event}\\ndata: ${data}\\n\\n`);\n };\n watchFile(path, { interval: options.pollMs ?? 1_000 }, () => void onChange());\n\n const server = createServer(async (request, response) => {\n const url = new URL(request.url ?? \"/\", \"http://localhost\");\n if (request.method !== \"GET\") {\n response.writeHead(405).end();\n return;\n }\n if (url.pathname === \"/\") {\n response.writeHead(200, {\n \"content-type\": \"text/html; charset=utf-8\",\n \"cache-control\": \"no-store\",\n });\n response.end(DASHBOARD_HTML);\n return;\n }\n if (url.pathname === \"/api/traces\") {\n const limit = Math.min(10_000, Math.max(1, Number(url.searchParams.get(\"limit\")) || 2_000));\n response.writeHead(200, { \"content-type\": \"application/json\", \"cache-control\": \"no-store\" });\n response.end(\n JSON.stringify({\n project: basename(repositoryRoot),\n path,\n events: await readTraces(repositoryRoot, limit),\n }),\n );\n return;\n }\n if (url.pathname === \"/events\") {\n response.writeHead(200, {\n \"content-type\": \"text/event-stream\",\n \"cache-control\": \"no-store\",\n connection: \"keep-alive\",\n });\n response.write(\": connected\\n\\n\");\n clients.add(response);\n request.on(\"close\", () => clients.delete(response));\n return;\n }\n response.writeHead(404, { \"content-type\": \"text/plain\" }).end(\"Not found\");\n });\n\n const port = await listen(server, options.port ?? 4777);\n // Keep idle SSE connections from timing out.\n const heartbeat = setInterval(() => {\n for (const client of clients) client.write(\": ping\\n\\n\");\n }, 25_000);\n heartbeat.unref();\n\n return {\n url: `http://127.0.0.1:${port}/`,\n close: () =>\n new Promise((resolve) => {\n clearInterval(heartbeat);\n unwatchFile(path);\n for (const client of clients) client.end();\n server.closeAllConnections();\n server.close(() => resolve());\n }),\n };\n}\n\n/** Bind to 127.0.0.1 only; if the port is taken, try the next nine. Port 0 = any free port. */\nasync function listen(server: ReturnType<typeof createServer>, port: number): Promise<number> {\n for (let attempt = 0; attempt < 10; attempt += 1) {\n const candidate = port === 0 ? 0 : port + attempt;\n try {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(candidate, \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n return (server.address() as AddressInfo).port;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EADDRINUSE\" || port === 0) throw error;\n }\n }\n throw new Error(`Ports ${port}-${port + 9} are in use; pass --port.`);\n}\n","/**\n * The dashboard page: self-contained (no CDN, works offline), reads\n * `/api/traces` once and then follows `/events`. Teal = prompt recall,\n * orange = MCP tool calls, in both themes. Every value shown is escaped.\n */\nexport const DASHBOARD_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>CodeBuddy Traces</title>\n<style>\n:root {\n --bg: #f3f5f7; --panel: #ffffff; --fg: #141a21; --muted: #5d6874; --line: #dde3e8;\n --recall: #0a8f80; --tool: #c2410c; --recall-soft: #e0f2ef; --tool-soft: #fbeae2;\n --bad: #b42318; --bad-soft: #fdecea; --capture: #4b5563;\n --sans: ui-sans-serif, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n --mono: ui-monospace, \"SF Mono\", Menlo, Consolas, monospace;\n}\n@media (prefers-color-scheme: dark) { :root {\n --bg: #0e1116; --panel: #161b22; --fg: #e6eaee; --muted: #94a0ad; --line: #28303a;\n --recall: #0d9488; --tool: #ea580c; --recall-soft: #10302c; --tool-soft: #3a1e12;\n --bad: #f97066; --bad-soft: #3b1715; --capture: #9aa4ae; color-scheme: dark } }\n* { box-sizing: border-box; }\nbody { margin: 0; background: var(--bg); color: var(--fg); font: 14px/1.5 var(--sans); }\n.wrap { max-width: 1280px; margin: 0 auto; padding: 20px 20px 48px; display: grid; gap: 16px; }\nheader { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }\nh1 { font-size: 18px; margin: 0; letter-spacing: -.01em; }\nh1 small { font: 500 13px var(--mono); color: var(--muted); margin-left: 8px; }\nh2 { font-size: 13px; margin: 0 0 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 600; }\n.live { display: inline-flex; align-items: center; gap: 6px; font: 12px var(--mono); color: var(--muted); }\n.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }\n.live.on .dot { background: var(--recall); box-shadow: 0 0 0 3px var(--recall-soft); }\n.spacer { flex: 1; }\n.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--panel); }\n.seg button { border: 0; background: none; color: var(--muted); font: 500 12px var(--sans); padding: 6px 12px; cursor: pointer; }\n.seg button + button { border-left: 1px solid var(--line); }\n.seg button[aria-pressed=\"true\"] { background: var(--fg); color: var(--bg); }\n.seg button:focus-visible { outline: 2px solid var(--recall); outline-offset: -2px; }\n.wrap > * { min-width: 0; }\n.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }\n.kpi { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; }\n.kpi .label { font-size: 12px; color: var(--muted); }\n.kpi .value { font: 600 24px/1.2 var(--mono); font-variant-numeric: tabular-nums; margin-top: 4px; }\n.kpi .sub { font-size: 12px; color: var(--muted); margin-top: 2px; }\n.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; min-width: 0; }\n.cols { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 16px; }\n@media (max-width: 900px) { .cols { grid-template-columns: 1fr; } }\n.legend { display: flex; gap: 16px; font-size: 12px; color: var(--muted); margin-bottom: 6px; }\n.sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 6px; vertical-align: -1px; }\nsvg text { fill: var(--muted); font: 11px var(--mono); }\n.scroll { overflow-x: auto; }\ntable { width: 100%; border-collapse: collapse; font-size: 13px; }\nth { text-align: left; font: 600 11px var(--sans); text-transform: uppercase; letter-spacing: .06em; color: var(--muted); padding: 6px 8px; border-bottom: 1px solid var(--line); white-space: nowrap; }\ntd { padding: 7px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }\ntr:last-child td { border-bottom: 0; }\ntd.n { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }\nth.n { text-align: right; }\n.chip { display: inline-block; font: 600 10px var(--mono); text-transform: uppercase; letter-spacing: .06em; padding: 2px 6px; border-radius: 4px; }\n.chip.recall { background: var(--recall-soft); color: var(--recall); }\n.chip.tool { background: var(--tool-soft); color: var(--tool); }\n.chip.capture, .chip.sync, .chip.kw { background: var(--line); color: var(--capture); }\n.chip.err { background: var(--bad-soft); color: var(--bad); }\n.feed { display: grid; gap: 10px; max-height: 520px; overflow: auto; }\n.prompt { border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; }\n.prompt .q { font-weight: 500; overflow-wrap: anywhere; }\n.prompt .meta { font: 12px var(--mono); color: var(--muted); margin-top: 4px; display: flex; flex-wrap: wrap; gap: 4px 12px; overflow-wrap: anywhere; }\n.prompt ul { margin: 6px 0 0; padding-left: 18px; font-size: 13px; }\n.prompt .none { font-size: 13px; color: var(--muted); margin-top: 6px; }\n.mono { font-family: var(--mono); }\n.muted { color: var(--muted); }\n.empty { padding: 40px 16px; text-align: center; color: var(--muted); }\n.empty code { font-family: var(--mono); background: var(--line); padding: 2px 6px; border-radius: 4px; color: var(--fg); }\n.log { max-height: 420px; overflow: auto; }\n@media (prefers-reduced-motion: no-preference) { tr.fresh td { animation: flash 1.2s ease-out; } }\n@keyframes flash { from { background: var(--recall-soft); } to { background: transparent; } }\n</style>\n</head>\n<body>\n<div class=\"wrap\">\n <header>\n <h1>CodeBuddy traces<small id=\"project\"></small></h1>\n <span class=\"live\" id=\"live\"><span class=\"dot\"></span><span id=\"liveText\">connecting</span></span>\n <span class=\"spacer\"></span>\n <div class=\"seg\" role=\"group\" aria-label=\"Time range\" id=\"range\">\n <button data-range=\"3600000\">1 hour</button>\n <button data-range=\"86400000\" aria-pressed=\"true\">24 hours</button>\n <button data-range=\"604800000\">7 days</button>\n <button data-range=\"0\">All</button>\n </div>\n </header>\n\n <section class=\"kpis\" id=\"kpis\" aria-label=\"Summary\"></section>\n\n <section class=\"panel\">\n <h2>Tokens delivered to the agent</h2>\n <div class=\"legend\"><span><span class=\"sw\" style=\"background:var(--recall)\"></span>prompt recall (hook)</span><span><span class=\"sw\" style=\"background:var(--tool)\"></span>MCP tool results</span></div>\n <div class=\"scroll\" id=\"chart\"></div>\n </section>\n\n <div class=\"cols\">\n <section class=\"panel\">\n <h2>Recent prompts and what was recalled</h2>\n <div class=\"feed\" id=\"feed\"></div>\n </section>\n <section class=\"panel\">\n <h2>MCP tools</h2>\n <div class=\"scroll\" id=\"tools\"></div>\n </section>\n </div>\n\n <section class=\"panel\">\n <h2>Activity</h2>\n <div class=\"log scroll\" id=\"log\"></div>\n </section>\n <p class=\"muted\" style=\"margin:0;font-size:12px;overflow-wrap:anywhere\">Token counts are cl100k estimates of the text exchanged. Traces stay on this machine in <span class=\"mono\" id=\"path\"></span>. Turn them off with <span class=\"mono\">CODEBUDDY_TRACE=0</span>.</p>\n</div>\n<script>\n(function () {\n var events = [];\n var range = 86400000;\n var fresh = new Set();\n var pending = false;\n\n function esc(value) {\n return String(value == null ? \"\" : value).replace(/[&<>\"']/g, function (c) {\n return { \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" }[c];\n });\n }\n function num(n) { return Math.round(n).toLocaleString(); }\n function compact(n) { return n >= 1e6 ? (n / 1e6).toFixed(1) + \"M\" : n >= 1e4 ? (n / 1e3).toFixed(1) + \"k\" : num(n); }\n function pct(sorted, p) { if (!sorted.length) return 0; return sorted[Math.min(sorted.length - 1, Math.floor(p * sorted.length))]; }\n function ms(n) { return n >= 1000 ? (n / 1000).toFixed(1) + \" s\" : Math.round(n) + \" ms\"; }\n function ago(ts) {\n var s = Math.max(0, (Date.now() - Date.parse(ts)) / 1000);\n return s < 60 ? Math.floor(s) + \"s ago\" : s < 3600 ? Math.floor(s / 60) + \"m ago\" : s < 86400 ? Math.floor(s / 3600) + \"h ago\" : Math.floor(s / 86400) + \"d ago\";\n }\n function visible() {\n if (!range) return events;\n var since = Date.now() - range;\n return events.filter(function (e) { return Date.parse(e.ts) >= since; });\n }\n\n function kpis(list) {\n var recalls = list.filter(function (e) { return e.kind === \"recall\"; });\n var tools = list.filter(function (e) { return e.kind === \"tool\"; });\n var delivered = list.reduce(function (s, e) { return s + (e.kind === \"recall\" || e.kind === \"tool\" ? e.tokensOut || 0 : 0); }, 0);\n var withFacts = recalls.filter(function (e) { return e.detail && e.detail.facts && e.detail.facts.length; });\n var factCount = withFacts.reduce(function (s, e) { return s + e.detail.facts.length; }, 0);\n var dense = recalls.reduce(function (s, e) { return s + ((e.detail && e.detail.dense) || 0); }, 0);\n var lat = recalls.map(function (e) { return e.ms; }).sort(function (a, b) { return a - b; });\n var errors = list.filter(function (e) { return !e.ok; }).length;\n var captures = list.filter(function (e) { return e.kind === \"capture\"; });\n var saved = captures.reduce(function (s, e) { return s + ((e.detail && e.detail.saved) || 0); }, 0);\n var tiles = [\n [\"Prompts recalled\", num(recalls.length), recalls.length ? Math.round(100 * withFacts.length / recalls.length) + \"% got facts\" : \"no prompts yet\"],\n [\"Facts injected\", num(factCount), factCount ? Math.round(100 * dense / factCount) + \"% matched by meaning\" : \"-\"],\n [\"Tokens delivered\", compact(delivered), recalls.length + tools.length ? \"≈ \" + num(delivered / (recalls.length + tools.length)) + \" per event\" : \"-\"],\n [\"MCP tool calls\", num(tools.length), tools.length ? new Set(tools.map(function (e) { return e.name; })).size + \" distinct tools\" : \"-\"],\n [\"Recall latency\", lat.length ? ms(pct(lat, 0.5)) : \"-\", lat.length ? \"p95 \" + ms(pct(lat, 0.95)) : \"-\"],\n [\"Memories saved\", num(saved), captures.length + \" capture\" + (captures.length === 1 ? \"\" : \"s\")],\n [\"Errors\", num(errors), errors ? \"see Activity\" : \"all good\"],\n ];\n document.getElementById(\"kpis\").innerHTML = tiles.map(function (t) {\n return '<div class=\"kpi\"><div class=\"label\">' + esc(t[0]) + '</div><div class=\"value\">' + esc(t[1]) + '</div><div class=\"sub\">' + esc(t[2]) + \"</div></div>\";\n }).join(\"\");\n }\n\n function chart(list) {\n var el = document.getElementById(\"chart\");\n var points = list.filter(function (e) { return (e.kind === \"recall\" || e.kind === \"tool\") && e.tokensOut; });\n if (!points.length) { el.innerHTML = '<div class=\"empty\">No tokens delivered in this range yet.</div>'; return; }\n var end = Date.now();\n // Zoom to the data: a few minutes of traces should not be one sliver of a 24-hour axis.\n var first = Date.parse(points[0].ts);\n var start = Math.max(range ? end - range : first, first - 60000);\n var buckets = 48, size = Math.max(10000, (end - start) / buckets);\n buckets = Math.ceil((end - start) / size);\n var rows = [];\n for (var i = 0; i < buckets; i++) rows.push({ recall: 0, tool: 0, n: 0 });\n points.forEach(function (e) {\n var i = Math.min(buckets - 1, Math.max(0, Math.floor((Date.parse(e.ts) - start) / size)));\n rows[i][e.kind] += e.tokensOut; rows[i].n += 1;\n });\n var max = Math.max.apply(null, rows.map(function (r) { return r.recall + r.tool; })) || 1;\n var W = 960, H = 200, L = 52, B = 22, T = 8, plotW = W - L - 8, plotH = H - B - T;\n var bw = plotW / buckets;\n var step = Math.pow(10, Math.floor(Math.log10(max)));\n var tick = max / step > 5 ? step * 2 : step;\n var svg = '<svg viewBox=\"0 0 ' + W + \" \" + H + '\" style=\"width:100%;min-width:560px;height:auto\" role=\"img\" aria-label=\"Tokens delivered over time\">';\n for (var v = 0; v <= max; v += tick) {\n var y = T + plotH - (v / max) * plotH;\n svg += '<line x1=\"' + L + '\" x2=\"' + (W - 8) + '\" y1=\"' + y + '\" y2=\"' + y + '\" stroke=\"var(--line)\"/><text x=\"' + (L - 6) + '\" y=\"' + (y + 4) + '\" text-anchor=\"end\">' + compact(v) + \"</text>\";\n }\n rows.forEach(function (r, i) {\n var x = L + i * bw + 1, w = Math.max(1, bw - 2);\n var hr = (r.recall / max) * plotH, ht = (r.tool / max) * plotH;\n var when = new Date(start + i * size);\n var label = when.toLocaleString() + \": \" + num(r.recall) + \" recall + \" + num(r.tool) + \" tool tokens (\" + r.n + \" events)\";\n if (r.recall) svg += '<rect x=\"' + x + '\" y=\"' + (T + plotH - hr) + '\" width=\"' + w + '\" height=\"' + hr + '\" rx=\"2\" fill=\"var(--recall)\"><title>' + esc(label) + \"</title></rect>\";\n if (r.tool) svg += '<rect x=\"' + x + '\" y=\"' + (T + plotH - hr - ht - (r.recall ? 2 : 0)) + '\" width=\"' + w + '\" height=\"' + ht + '\" rx=\"2\" fill=\"var(--tool)\"><title>' + esc(label) + \"</title></rect>\";\n });\n [0, Math.floor(buckets / 2), buckets - 1].forEach(function (i) {\n var d = new Date(start + i * size);\n var text = end - start <= 86400000 ? d.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" }) : d.toLocaleDateString([], { month: \"short\", day: \"numeric\" });\n svg += '<text x=\"' + (L + i * bw + bw / 2) + '\" y=\"' + (H - 6) + '\" text-anchor=\"middle\">' + esc(text) + \"</text>\";\n });\n el.innerHTML = svg + \"</svg>\";\n }\n\n function feed(list) {\n var recalls = list.filter(function (e) { return e.kind === \"recall\"; }).slice(-30).reverse();\n var el = document.getElementById(\"feed\");\n if (!recalls.length) {\n el.innerHTML = '<div class=\"empty\">No prompts yet. Run <code>codebuddy hooks install</code>, restart your agent, and send a prompt.</div>';\n return;\n }\n el.innerHTML = recalls.map(function (e) {\n var d = e.detail || {};\n var facts = d.facts || [];\n return '<div class=\"prompt\"><div class=\"q\">' + (esc(d.prompt) || '<span class=\"muted\">(no prompt text)</span>') + '</div>' +\n '<div class=\"meta\"><span>' + ago(e.ts) + \"</span><span>\" + ms(e.ms) + \"</span><span>≈\" + num(e.tokensOut || 0) + \" tokens injected</span>\" +\n (d.dense ? '<span class=\"chip recall\">' + d.dense + \" by meaning</span>\" : \"\") +\n (d.lexical ? '<span class=\"chip kw\">' + d.lexical + \" by keyword</span>\" : \"\") +\n (e.ok ? \"\" : '<span class=\"chip err\">' + esc(d.dropped || \"dropped\") + \"</span>\") + \"</div>\" +\n (facts.length ? \"<ul>\" + facts.map(function (f) { return \"<li>\" + esc(f) + \"</li>\"; }).join(\"\") + \"</ul>\" : '<div class=\"none\">No new facts: nothing matched, or already sent this session.</div>') +\n (d.files && d.files.length ? '<div class=\"meta\">files: ' + d.files.map(esc).join(\", \") + \"</div>\" : \"\") +\n \"</div>\";\n }).join(\"\");\n }\n\n function tools(list) {\n var by = {};\n list.filter(function (e) { return e.kind === \"tool\"; }).forEach(function (e) {\n var t = by[e.name] || (by[e.name] = { calls: 0, errors: 0, lat: [], out: 0 });\n t.calls++; if (!e.ok) t.errors++; t.lat.push(e.ms); t.out += e.tokensOut || 0;\n });\n var names = Object.keys(by).sort(function (a, b) { return by[b].calls - by[a].calls; });\n var el = document.getElementById(\"tools\");\n if (!names.length) { el.innerHTML = '<div class=\"empty\">No MCP tool calls in this range.</div>'; return; }\n el.innerHTML = '<table><thead><tr><th>Tool</th><th class=\"n\">Calls</th><th class=\"n\">p50</th><th class=\"n\">p95</th><th class=\"n\">Tokens out</th><th class=\"n\">Errors</th></tr></thead><tbody>' +\n names.map(function (n) {\n var t = by[n], lat = t.lat.sort(function (a, b) { return a - b; });\n return '<tr><td class=\"mono\">' + esc(n) + '</td><td class=\"n\">' + t.calls + '</td><td class=\"n\">' + ms(pct(lat, 0.5)) + '</td><td class=\"n\">' + ms(pct(lat, 0.95)) + '</td><td class=\"n\">' + compact(t.out) + '</td><td class=\"n\">' + (t.errors ? '<span class=\"chip err\">' + t.errors + \"</span>\" : \"0\") + \"</td></tr>\";\n }).join(\"\") + \"</tbody></table>\";\n }\n\n function summary(e) {\n var d = e.detail || {};\n if (e.kind === \"recall\") return (d.facts ? d.facts.length : 0) + \" fact(s), \" + (d.files ? d.files.length : 0) + \" file(s)\";\n if (e.kind === \"capture\") return (d.saved || 0) + \" saved, \" + (d.queued || 0) + \" queued, \" + (d.changedFiles || 0) + \" changed file(s)\";\n if (e.kind === \"sync\") return (d.imported || 0) + \" new, \" + (d.updated || 0) + \" updated\" + (d.reembedding ? \", \" + d.reembedding + \" re-embedding\" : \"\");\n return e.session ? \"session \" + e.session.slice(0, 12) : \"\";\n }\n\n function log(list) {\n var rows = list.slice(-200).reverse();\n var el = document.getElementById(\"log\");\n if (!rows.length) { el.innerHTML = '<div class=\"empty\">Nothing recorded in this range.</div>'; return; }\n el.innerHTML = '<table><thead><tr><th>When</th><th>Kind</th><th>Name</th><th>Details</th><th class=\"n\">Time</th><th class=\"n\">In</th><th class=\"n\">Out</th></tr></thead><tbody>' +\n rows.map(function (e) {\n var key = e.ts + e.name;\n return '<tr class=\"' + (fresh.has(key) ? \"fresh\" : \"\") + '\"><td class=\"mono muted\" title=\"' + esc(e.ts) + '\">' + ago(e.ts) + '</td><td><span class=\"chip ' + (e.ok ? esc(e.kind) : \"err\") + '\">' + esc(e.ok ? e.kind : e.kind + \" failed\") + '</span></td><td class=\"mono\">' + esc(e.name) + \"</td><td>\" + esc(summary(e)) + '</td><td class=\"n\">' + ms(e.ms) + '</td><td class=\"n\">' + num(e.tokensIn || 0) + '</td><td class=\"n\">' + num(e.tokensOut || 0) + \"</td></tr>\";\n }).join(\"\") + \"</tbody></table>\";\n fresh.clear();\n }\n\n function render() {\n pending = false;\n var list = visible();\n kpis(list); chart(list); feed(list); tools(list); log(list);\n }\n function schedule() { if (!pending) { pending = true; requestAnimationFrame(render); } }\n\n function load() {\n return fetch(\"/api/traces?limit=10000\").then(function (r) { return r.json(); }).then(function (data) {\n events = data.events || [];\n document.getElementById(\"project\").textContent = data.project || \"\";\n document.getElementById(\"path\").textContent = data.path || \"\";\n document.title = \"CodeBuddy Traces · \" + (data.project || \"\");\n schedule();\n });\n }\n\n document.getElementById(\"range\").addEventListener(\"click\", function (event) {\n var button = event.target.closest(\"button\");\n if (!button) return;\n range = Number(button.dataset.range);\n this.querySelectorAll(\"button\").forEach(function (b) { b.setAttribute(\"aria-pressed\", String(b === button)); });\n schedule();\n });\n\n function connect() {\n var live = document.getElementById(\"live\"), text = document.getElementById(\"liveText\");\n var source = new EventSource(\"/events\");\n source.onopen = function () { live.classList.add(\"on\"); text.textContent = \"live\"; };\n source.onerror = function () { live.classList.remove(\"on\"); text.textContent = \"reconnecting\"; };\n source.addEventListener(\"trace\", function (message) {\n var e = JSON.parse(message.data);\n events.push(e); fresh.add(e.ts + e.name);\n if (events.length > 10000) events = events.slice(-10000);\n schedule();\n });\n source.addEventListener(\"reset\", function () { load(); });\n }\n\n load().then(connect);\n // Relative times (\"2m ago\") keep moving even when nothing new arrives.\n setInterval(schedule, 30000);\n})();\n</script>\n</body>\n</html>`;\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { runEvaluation } from \"../../eval/runner.js\";\nimport type { EvaluationResult } from \"../../eval/types.js\";\n\nexport function registerEvalCommand(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n program\n .command(\"eval\")\n .argument(\"[dataset]\", \"Evaluation dataset JSON path.\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"Run the committed change-readiness evaluation dataset.\")\n .action(async (dataset: string | undefined, opts: { json?: boolean }) => {\n await runSafely(async () => {\n const result = await runEvaluation(dataset ? { datasetPath: dataset } : {});\n if (opts.json) console.log(JSON.stringify(result, null, 2));\n else printEvaluation(result);\n if (!result.passed) process.exitCode = 1;\n });\n });\n}\n\nfunction printEvaluation(result: EvaluationResult): void {\n console.log(\n `${result.passed ? pc.green(\"passed\") : pc.red(\"failed\")} ${result.summary.passed}/${result.summary.total} evaluation cases`,\n );\n for (const item of result.cases) {\n console.log(` ${item.passed ? pc.green(\"✓\") : pc.red(\"×\")} ${item.id}`);\n if (!item.passed) for (const failure of item.failures) console.log(pc.dim(` ${failure}`));\n }\n console.log(pc.dim(`dataset: ${result.datasetPath}`));\n}\n","import { readFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { buildChangeReport } from \"../change/engine.js\";\nimport type { EvaluationDataset, EvaluationResult } from \"./types.js\";\n\nexport type RunEvaluationInput = { datasetPath?: string; repositoryRoot?: string };\n\nexport async function runEvaluation(input: RunEvaluationInput = {}): Promise<EvaluationResult> {\n const datasetPath = resolve(\n input.datasetPath ?? join(process.cwd(), \"evals\", \"change-readiness.json\"),\n );\n const dataset = JSON.parse(await readFile(datasetPath, \"utf8\")) as EvaluationDataset;\n if (dataset.version !== 1 || !Array.isArray(dataset.cases)) {\n throw new Error(`Unsupported evaluation dataset: ${datasetPath}`);\n }\n\n const datasetDirectory = dirname(datasetPath);\n const results = await Promise.all(\n dataset.cases.map(async (evaluationCase) => {\n const fixtureRoot = isAbsolute(evaluationCase.fixture)\n ? evaluationCase.fixture\n : resolve(input.repositoryRoot ?? datasetDirectory, evaluationCase.fixture);\n const report = await buildChangeReport({\n repositoryRoot: fixtureRoot,\n namespace: `eval:${evaluationCase.id}`,\n paths: evaluationCase.paths,\n useGit: false,\n });\n const failures: string[] = [];\n if (report.status !== evaluationCase.expectedStatus) {\n failures.push(`status expected ${evaluationCase.expectedStatus}, got ${report.status}`);\n }\n if (\n evaluationCase.minimumRisk !== undefined &&\n report.risk.highestScore < evaluationCase.minimumRisk\n ) {\n failures.push(\n `risk expected >= ${evaluationCase.minimumRisk}, got ${report.risk.highestScore}`,\n );\n }\n const categories: string[] = [\n ...new Set(report.suggestions.map((suggestion) => suggestion.category)),\n ];\n for (const category of evaluationCase.requiredCategories ?? []) {\n if (!categories.includes(category)) failures.push(`missing category ${category}`);\n }\n return {\n id: evaluationCase.id,\n description: evaluationCase.description,\n passed: failures.length === 0,\n expectedStatus: evaluationCase.expectedStatus,\n actualStatus: report.status,\n highestRisk: report.risk.highestScore,\n categories,\n failures,\n };\n }),\n );\n const passed = results.filter((result) => result.passed).length;\n return {\n datasetPath,\n passed: passed === results.length,\n cases: results,\n summary: { total: results.length, passed, failed: results.length - passed },\n };\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { installGitHubWorkflow } from \"../../integrations/github.js\";\n\nexport function registerGitHubCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const github = program.command(\"github\").description(\"Install GitHub workflow integrations.\");\n github\n .command(\"install\")\n .option(\"--force\", \"Replace an existing CodeBuddy workflow.\")\n .description(\"Install the PR change-safety report workflow.\")\n .action(async (opts: { force?: boolean }) => {\n await runSafely(async () => {\n const result = await installGitHubWorkflow(process.cwd(), {\n ...(opts.force !== undefined ? { force: opts.force } : {}),\n });\n console.log(`${result.created ? \"installed\" : \"already present\"} ${pc.dim(result.path)}`);\n if (result.created) console.log(\"Commit this workflow to enable CodeBuddy PR reports.\");\n });\n });\n}\n","import { spawn } from \"node:child_process\";\nimport { relative } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n CLIENT_ADAPTERS,\n type ClientId,\n parseClient,\n supportedModes,\n} from \"../../clients/adapters.js\";\nimport { setHooks } from \"../../clients/install.js\";\nimport { clientHooksInstalled } from \"../../hooks/install.js\";\nimport { runLeanHookCommand } from \"../../hooks/lean-command.js\";\nimport { runPreToolHookCommand } from \"../../hooks/pretool-command.js\";\nimport {\n runCaptureHook,\n runContextHook,\n runResetHook,\n runStageHook,\n runSyncHook,\n} from \"../../hooks/runtime.js\";\nimport { failSoft, readHookInput, writeStdout } from \"../../hooks/stdio.js\";\nimport { installWorkflowRules } from \"../../templates/install.js\";\n\n/**\n * `codebuddy hooks` makes recall and capture deterministic by wiring CodeBuddy\n * into a client's lifecycle hooks. The management commands (install/\n * uninstall/status) edit `.claude/settings.json` or write the managed OpenCode/Hermes\n * plugins, idempotently and visibly. The runtime commands\n * (context/stage/capture/reset) are what the hooks invoke — they read\n * the hook payload on stdin and are strictly fail-soft: a hook must never break\n * the user's turn, so they always exit 0.\n */\nexport function registerHooksCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const hooks = program\n .command(\"hooks\")\n .description(\"Enforce automatic recall/capture via client lifecycle hooks.\");\n\n hooks\n .command(\"install\")\n .option(\n \"--client <client>\",\n \"Client with a CodeBuddy hook adapter (claude, opencode, hermes).\",\n \"claude\",\n )\n .description(\n \"Add CodeBuddy's recall/capture hooks (.claude/settings.json, .opencode/plugins/codebuddy.js or .hermes/plugins/codebuddy/).\",\n )\n .action(async (opts: { client?: string }) => {\n await runSafely(async () => {\n const client = assertHookClient(opts.client);\n const step = await setHooks(process.cwd(), true, client);\n if (!step) return;\n const where = relative(process.cwd(), step.target) || step.target;\n const changed = step.action !== \"unchanged\";\n console.log(\n `${changed ? pc.green(\"installed\") : pc.dim(\"unchanged\")} CodeBuddy hooks in ${where}`,\n );\n await reconcileRules(client, \"hooks\");\n // Index existing memory and download the local models now, not on the first prompt.\n syncInBackground(process.cwd());\n console.log(\n pc.dim(\n ` prompt→recall · edit→stage · turn end→capture · compaction→reset. Restart ${CLIENT_ADAPTERS[client].name} to activate.`,\n ),\n );\n });\n });\n\n hooks\n .command(\"uninstall\")\n .option(\n \"--client <client>\",\n \"Client with a CodeBuddy hook adapter (claude, opencode, hermes).\",\n \"claude\",\n )\n .description(\"Remove CodeBuddy's hooks for a client (user hooks untouched).\")\n .action(async (opts: { client?: string }) => {\n await runSafely(async () => {\n const client = assertHookClient(opts.client);\n const changed = (await setHooks(process.cwd(), false, client))?.action === \"removed\";\n console.log(\n changed ? pc.yellow(\"removed CodeBuddy hooks\") : pc.dim(\"no CodeBuddy hooks found\"),\n );\n await reconcileRules(client, \"agent\");\n });\n });\n\n hooks\n .command(\"status\")\n .option(\n \"--client <client>\",\n \"Client with a CodeBuddy hook adapter (claude, opencode, hermes).\",\n \"claude\",\n )\n .description(\"Report whether CodeBuddy hooks are installed.\")\n .action(async (opts: { client?: string }) => {\n await runSafely(async () => {\n const installed = await clientHooksInstalled(process.cwd(), parseClient(opts.client));\n console.log(\n installed\n ? pc.green(\"CodeBuddy hooks: installed\")\n : pc.dim(\"CodeBuddy hooks: not installed\"),\n );\n });\n });\n\n // ── runtime commands invoked by the hooks (read stdin, fail-soft) ──\n\n hooks\n .command(\"context\")\n .description(\"[hook] Emit compact project context for injection at prompt submit.\")\n .action(async () => {\n await failSoft(async () => {\n const input = await readHookInput();\n await runContextHook(input, writeStdout);\n });\n });\n\n hooks\n .command(\"lean\")\n .description(\"[hook] Emit ranked file pointers (lean mode).\")\n .action(async () => {\n await runLeanHookCommand();\n });\n\n hooks\n .command(\"stage\")\n .description(\"[hook] Record the files an edit tool just changed.\")\n .action(async () => {\n await failSoft(async () => {\n const input = await readHookInput();\n await runStageHook(input);\n });\n });\n\n hooks\n .command(\"capture\")\n .description(\"[hook] Capture durable memory from the turn's change set.\")\n .action(async () => {\n await failSoft(async () => {\n const input = await readHookInput();\n const { changedFiles, result } = await runCaptureHook(input);\n if (result) {\n process.stderr.write(\n `codebuddy: captured from ${changedFiles.length} changed file(s) — ` +\n `${result.saved.length} saved, ${result.queuedForReview.length} queued\\n`,\n );\n if (result.saved.length > 0) syncInBackground(input.cwd ?? process.cwd());\n }\n });\n });\n\n hooks\n .command(\"sync\")\n .description(\n \"[hook] Reindex Markdown memory into PostgreSQL and embed it locally (runs detached after capture).\",\n )\n .action(async () => {\n await failSoft(async () => {\n const result = await runSyncHook(process.cwd());\n process.stderr.write(\n result\n ? `codebuddy: synced ${result.reindex.facts.imported} new / ${result.reindex.facts.updated} updated fact(s)` +\n `${result.reindex.reembedding ? `, ${result.reindex.reembedding} re-embedding` : \"\"}` +\n `${result.drained ? \"\" : \" (embeddings still pending)\"}\\n`\n : \"codebuddy: no PostgreSQL configured; nothing to sync\\n\",\n );\n });\n });\n\n hooks\n .command(\"pretool\")\n .description(\n \"[hook] Outline large unranged Reads and cap content Greps (never grants permission).\",\n )\n .action(async () => {\n await runPreToolHookCommand();\n });\n\n hooks\n .command(\"reset\")\n .description(\"[hook] Forget what context was sent this session (after compaction or /clear).\")\n .action(async () => {\n await failSoft(async () => {\n await runResetHook(await readHookInput());\n });\n });\n}\n\nfunction assertHookClient(value: string | undefined): ClientId {\n const client = parseClient(value);\n const adapter = CLIENT_ADAPTERS[client];\n if (!supportedModes(adapter).includes(\"hooks\")) {\n throw new Error(\n `${adapter.name} has no CodeBuddy hook adapter: ${adapter.gap ?? \"unsupported\"}.`,\n );\n }\n return client;\n}\n\n/**\n * Keep an existing managed rules block in step with the hooks, so the model is\n * not also told to call context_pack/context_after_turn the hooks already run.\n */\nasync function reconcileRules(client: ClientId, mode: \"agent\" | \"hooks\"): Promise<void> {\n const result = await installWorkflowRules({ client, mode, onlyIfManaged: true });\n if (result.action !== \"unchanged\") {\n const where = relative(process.cwd(), result.path) || result.path;\n console.log(\n `${pc.cyan(\"updated\")} ${where} workflow to ${mode === \"hooks\" ? \"hook\" : \"agent\"}-driven mode`,\n );\n }\n}\n\n/**\n * Run `codebuddy hooks sync` in the background: the turn (or install) never\n * waits for indexing or a model download. The same entry point and loader\n * flags as this process, so it works from `dist/` and under `tsx` alike.\n */\nexport function syncInBackground(cwd: string): void {\n const entry = process.argv[1];\n if (!entry) return;\n try {\n spawn(process.execPath, [...process.execArgv, entry, \"hooks\", \"sync\"], {\n cwd,\n detached: true,\n stdio: \"ignore\",\n }).unref();\n } catch {\n // Best-effort: the next sync (or `codebuddy reindex`) catches up.\n }\n}\n\n/**\n * Runtime hook commands must never fail the user's turn. Swallow everything and\n * exit 0; surface problems on stderr only.\n */\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { indexRepository } from \"../../indexer/engine.js\";\nimport type { IndexResult } from \"../../indexer/types.js\";\nimport { watchRepository } from \"../../indexer/watch.js\";\nimport { summarizeAfterIndex } from \"./llm.js\";\n\n/**\n * `index` and `watch` are file-based (they read the working tree and write a\n * cache manifest) and need no database connection.\n */\nexport function registerIndexCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n program\n .command(\"index\")\n .option(\"--full\", \"Re-summarize every file, ignoring existing content hashes.\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"Index the repository: content hashes and lightweight file summaries.\")\n .action(async (opts: { full?: boolean; json?: boolean }) => {\n await runSafely(async () => {\n const result = await indexRepository({ ...(opts.full ? { full: true } : {}) });\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n printResult(result);\n });\n });\n\n program\n .command(\"watch\")\n .option(\"--debounce <ms>\", \"Coalesce file-change bursts within this window.\", Number)\n .option(\"--no-llm\", \"Do not write BYOK model summaries after index passes.\")\n .description(\"Watch the repository and incrementally re-index on change (Ctrl+C to stop).\")\n .action(async (opts: { debounce?: number; llm: boolean }) => {\n await runSafely(async () => {\n const controller = new AbortController();\n const stop = () => controller.abort();\n process.once(\"SIGINT\", stop);\n process.once(\"SIGTERM\", stop);\n console.log(pc.dim(\"watching for changes… press Ctrl+C to stop\"));\n await watchRepository({\n ...(opts.debounce !== undefined ? { debounceMs: opts.debounce } : {}),\n signal: controller.signal,\n onIndex: (result) => {\n printResult(result, true);\n if (!opts.llm || result.added + result.changed === 0) return;\n // One summary batch per pass, after the index; never blocks indexing.\n void summarizeAfterIndex(process.cwd())\n .then((summary) => {\n if (summary && summary.summarized > 0)\n console.log(pc.dim(` llm: ${summary.summarized} file(s) summarized`));\n })\n .catch((error) => console.error(pc.red(`llm: ${(error as Error).message}`)));\n },\n onError: (error) => console.error(pc.red(error.message)),\n });\n console.log(pc.dim(\"stopped watching\"));\n });\n });\n}\n\nfunction printResult(result: IndexResult, compact = false): void {\n const summary = `${result.totalIndexed} indexed (${pc.green(`+${result.added}`)} ${pc.yellow(`~${result.changed}`)} ${pc.dim(`=${result.unchanged}`)} ${pc.red(`-${result.removed}`)}) in ${result.durationMs}ms`;\n console.log(compact ? pc.dim(summary) : summary);\n if (result.skipped > 0)\n console.log(pc.dim(` ${result.skipped} skipped (too large or unreadable)`));\n for (const error of result.errors) console.log(pc.red(` ${error.path}: ${error.error}`));\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { z } from \"zod\";\nimport { readConfigFile, setLlmEnabled } from \"../../core/config-file.js\";\nimport { loadFreshIndex } from \"../../indexer/engine.js\";\nimport { coolingDown, usageToday } from \"../../llm/budget.js\";\nimport { chatJson } from \"../../llm/client.js\";\nimport { resolveLlmConfig } from \"../../llm/config.js\";\nimport {\n loadLlmSummaries,\n type SummarizeResult,\n summarizeRepository,\n} from \"../../llm/summaries.js\";\n\n/**\n * Bring-your-own-key small-model layer (Groq / OpenRouter free tiers). Keys\n * are read from GROQ_API_KEY / OPENROUTER_API_KEY and never stored or printed.\n */\nconst KEY_ENV = { groq: \"GROQ_API_KEY\", openrouter: \"OPENROUTER_API_KEY\" } as const;\n/** Files summarized after each `watch` index pass: one request. */\nconst WATCH_BATCH = 8;\n\nexport type LlmStatusReport = {\n enabled: boolean;\n reason: string;\n provider: \"groq\" | \"openrouter\";\n model: string | null;\n keyEnv: string;\n keyPresent: boolean;\n features: { summaries: boolean; rerank: boolean; memory: boolean } | null;\n usageToday: number;\n dailyTokenBudget: number;\n cooldownMs: number;\n summaries: { covered: number; indexed: number };\n};\n\nexport async function llmStatusReport(\n root: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<LlmStatusReport> {\n const block = (await readConfigFile(root)).llm;\n const provider = block?.provider ?? \"groq\";\n const config = await resolveLlmConfig(root, env);\n const model = config.enabled ? config.model : (block?.model ?? null);\n const key = `${provider}:${model}`;\n const { manifest } = await loadFreshIndex(root);\n return {\n enabled: config.enabled,\n reason: config.enabled ? \"on\" : config.reason,\n provider,\n model,\n keyEnv: env.CODEBUDDY_LLM_API_KEY ? \"CODEBUDDY_LLM_API_KEY\" : KEY_ENV[provider],\n keyPresent: Boolean(env.CODEBUDDY_LLM_API_KEY || env[KEY_ENV[provider]]),\n features: config.enabled ? config.features : null,\n usageToday: (await usageToday(root))[key] ?? 0,\n dailyTokenBudget: config.enabled\n ? config.dailyTokenBudget\n : (block?.dailyTokenBudget ?? 400_000),\n cooldownMs: await coolingDown(root, key),\n summaries: {\n covered: (await loadLlmSummaries(root, manifest)).size,\n indexed: Object.keys(manifest.entries).length,\n },\n };\n}\n\nexport function formatLlmStatus(report: LlmStatusReport): string {\n const features = report.features\n ? Object.entries(report.features)\n .map(([name, on]) => `${name} ${on ? \"on\" : \"off\"}`)\n .join(\", \")\n : \"-\";\n return [\n `status: ${report.enabled ? \"on\" : `off (${report.reason})`}`,\n `provider: ${report.provider}${report.model ? ` ${report.model}` : \"\"}`,\n `key: ${report.keyPresent ? \"present\" : \"missing\"} (${report.keyEnv})`,\n `features: ${features}`,\n `usage today: ${report.usageToday} / ${report.dailyTokenBudget} tokens`,\n ...(report.cooldownMs > 0\n ? [`cooldown: rate limited, ${Math.ceil(report.cooldownMs / 1000)} s left`]\n : []),\n `summaries: ${report.summaries.covered} / ${report.summaries.indexed} files`,\n ].join(\"\\n\");\n}\n\n/** One summary batch after a `watch` index pass; null when the layer is off. */\nexport async function summarizeAfterIndex(\n root: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<SummarizeResult | null> {\n const config = await resolveLlmConfig(root, env);\n if (!config.enabled || !config.features.summaries) return null;\n return summarizeRepository(root, { config, limit: WATCH_BATCH, pace: false });\n}\n\nexport function registerLlmCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const llm = program\n .command(\"llm\")\n .description(\n \"Optional bring-your-own-key small model (Groq/OpenRouter) for summaries, rerank and memory.\",\n );\n\n llm\n .command(\"status\", { isDefault: true })\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\n \"Show provider, key presence (never the key), usage, cooldown and summary coverage.\",\n )\n .action(async (opts: { json?: boolean }) => {\n await runSafely(async () => {\n const report = await llmStatusReport(process.cwd());\n console.log(opts.json ? JSON.stringify(report, null, 2) : formatLlmStatus(report));\n if (!report.keyPresent) console.log(pc.dim(`next: export ${report.keyEnv}=<your key>`));\n });\n });\n\n llm\n .command(\"enable\")\n .option(\"--provider <provider>\", \"groq or openrouter\", \"groq\")\n .option(\"--model <model>\", \"Model id (default: llama-3.1-8b-instant on groq).\")\n .description(\"Turn the layer on in .codebuddy/config.json (the key stays in your environment).\")\n .action(async (opts: { provider: string; model?: string }) => {\n await runSafely(async () => {\n if (opts.provider !== \"groq\" && opts.provider !== \"openrouter\") {\n throw new Error(\"--provider must be groq or openrouter\");\n }\n await setLlmEnabled(true, {\n provider: opts.provider,\n ...(opts.model ? { model: opts.model } : {}),\n });\n console.log(formatLlmStatus(await llmStatusReport(process.cwd())));\n });\n });\n\n llm\n .command(\"disable\")\n .description(\"Turn the layer off; CodeBuddy falls back to deterministic retrieval and capture.\")\n .action(async () => {\n await runSafely(async () => {\n await setLlmEnabled(false);\n console.log(\"llm layer disabled\");\n });\n });\n\n llm\n .command(\"test\")\n .description(\"Send one tiny request and print the model and latency.\")\n .action(async () => {\n await runSafely(async () => {\n const config = await resolveLlmConfig(process.cwd());\n if (!config.enabled) throw new Error(`llm layer is off: ${config.reason}`);\n const result = await chatJson(config, {\n system: 'Answer with JSON only: {\"ok\":true}.',\n user: \"ping\",\n schema: z.object({ ok: z.boolean() }),\n maxTokens: 10,\n deadlineMs: 10_000,\n purpose: \"prompt\",\n repositoryRoot: process.cwd(),\n });\n if (!result.ok) throw new Error(`${result.reason}: ${result.detail}`);\n console.log(`ok: ${result.model} answered in ${result.latencyMs} ms`);\n });\n });\n\n llm\n .command(\"summarize\")\n .option(\"--limit <n>\", \"Summarize at most this many files.\", Number)\n .description(\n \"Write one-line summaries of changed files now (resumable; paced to the free tier).\",\n )\n .action(async (opts: { limit?: number }) => {\n await runSafely(async () => {\n const controller = new AbortController();\n process.once(\"SIGINT\", () => controller.abort());\n const result = await summarizeRepository(process.cwd(), {\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n signal: controller.signal,\n onProgress: (done, total) => console.log(pc.dim(`summarized ${done}/${total}`)),\n });\n console.log(\n `${result.summarized} summarized, ${result.skipped} skipped, ${result.remaining} remaining (${result.stoppedBy})`,\n );\n });\n });\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { confirm, isCancel, log, note, password, spinner, text } from \"@clack/prompts\";\nimport { configPath, defaultNamespaceForCwd, initConfigFile } from \"../../core/config-file.js\";\nimport { bootstrapDatabase } from \"../../db/bootstrap.js\";\nimport { createDatabaseClient, pingDatabase } from \"../../db/client.js\";\nimport { runMigrations } from \"../../db/migrator.js\";\nimport { installClaudeEntry } from \"./claude-desktop.js\";\nimport { postgresUp } from \"./postgres-docker.js\";\n\nexport type WizardResult = {\n configPath: string;\n databaseReady: boolean;\n claudeInstalled: boolean;\n};\n\nfunction bail(): never {\n log.warn(\"Aborted. No config was written.\");\n process.exit(1);\n}\n\nfunction unwrap<T>(value: T | symbol): T {\n if (isCancel(value)) bail();\n return value as T;\n}\n\nasync function pingOnce(databaseUrl: string): Promise<boolean> {\n const client = createDatabaseClient({ postgresUrl: databaseUrl });\n try {\n return await pingDatabase(client);\n } catch {\n return false;\n } finally {\n await client.close().catch(() => undefined);\n }\n}\n\nexport async function runInitWizard(): Promise<WizardResult> {\n const projectRoot = process.cwd();\n // Trap Ctrl-C cleanly so partial writes don't leave the user wedged.\n const sigintHandler = () => bail();\n process.on(\"SIGINT\", sigintHandler);\n\n try {\n note(\n \"Sets up your config file, checks Postgres, applies migrations, and (optionally) wires Claude Desktop.\",\n \"CodeBuddy init\",\n );\n\n // ── Hugging Face token (optional: embeddings run locally by default) ──\n const hfToken = unwrap(\n await password({\n message: \"Hugging Face token (optional; only for hosted embeddings)\",\n }),\n );\n\n // ── Postgres URL ────────────────────────────────────────────────\n const databaseUrl = unwrap(\n await text({\n message: \"Postgres URL\",\n initialValue:\n process.env.DATABASE_URL ?? \"postgres://codebuddy:codebuddy@localhost:5432/codebuddy\",\n validate: (value) => (value && value.length > 0 ? undefined : \"Postgres URL is required.\"),\n }),\n );\n\n // ── Namespace ───────────────────────────────────────────────────\n const namespace = unwrap(\n await text({\n message: \"Default namespace\",\n initialValue: process.env.CODEBUDDY_NAMESPACE ?? defaultNamespaceForCwd(projectRoot),\n validate: (value) =>\n value && /^[a-zA-Z0-9_.:-]+$/.test(value) ? undefined : \"Letters, digits, _ . : - only.\",\n }),\n );\n\n // ── Probe Postgres ──────────────────────────────────────────────\n const dbSpinner = spinner();\n dbSpinner.start(\"Checking Postgres connection\");\n let connected = await pingOnce(databaseUrl);\n dbSpinner.stop(connected ? \"Postgres reachable.\" : \"Postgres did not respond.\");\n\n if (!connected) {\n const startDocker = unwrap(\n await confirm({\n message: \"Start the bundled Postgres container with docker compose?\",\n initialValue: true,\n }),\n );\n if (startDocker) {\n const dockerSpinner = spinner();\n dockerSpinner.start(\"docker compose up -d\");\n try {\n const result = await postgresUp();\n if (result.code === 0) {\n dockerSpinner.stop(\"Postgres container started.\");\n // Give Postgres a few seconds to accept connections.\n for (let attempt = 0; attempt < 10 && !connected; attempt++) {\n await new Promise((resolve) => setTimeout(resolve, 500));\n connected = await pingOnce(databaseUrl);\n }\n if (!connected) {\n log.warn(\"Container started but did not accept connections in time.\");\n }\n } else {\n dockerSpinner.stop(`docker compose failed: ${result.stderr || result.stdout}`);\n }\n } catch (error) {\n dockerSpinner.stop(`docker compose failed: ${(error as Error).message}`);\n }\n }\n }\n\n // ── Migrations (only if DB is reachable) ────────────────────────\n if (connected) {\n const migrateSpinner = spinner();\n migrateSpinner.start(\"Enabling pgvector and applying migrations\");\n const client = createDatabaseClient({ postgresUrl: databaseUrl });\n try {\n await bootstrapDatabase(client.sql);\n await runMigrations(client);\n migrateSpinner.stop(\"Migrations applied.\");\n } catch (error) {\n migrateSpinner.stop(`Migration error: ${(error as Error).message}`);\n } finally {\n await client.close().catch(() => undefined);\n }\n } else {\n log.warn(\"Skipping migrations — Postgres is not reachable. Run `codebuddy migrate` later.\");\n }\n\n // ── Write config (last so failures above don't leave a half-config) ──\n const initialised = await initConfigFile();\n const fileConfig = {\n postgresUrl: databaseUrl,\n namespace,\n provider: { type: \"local\" as const, ...(hfToken ? { apiKey: hfToken } : {}) },\n tokenBudget: 4000,\n };\n await writeFile(initialised.path, `${JSON.stringify(fileConfig, null, 2)}\\n`, {\n mode: 0o600,\n });\n log.success(`Config written to ${initialised.path}`);\n\n // ── Claude Desktop registration (optional) ──────────────────────\n let claudeInstalled = false;\n const wireClaude = unwrap(\n await confirm({\n message: \"Register this namespace with Claude Desktop now?\",\n initialValue: true,\n }),\n );\n if (wireClaude) {\n try {\n const install = await installClaudeEntry({\n namespace,\n projectRoot,\n hfToken,\n databaseUrl,\n });\n claudeInstalled = true;\n log.success(\n `Added \"${install.serverKey}\" to ${install.path}. Restart Claude Desktop (⌘Q) to activate.`,\n );\n } catch (error) {\n log.warn(`Claude Desktop install failed: ${(error as Error).message}`);\n }\n }\n\n return {\n configPath: configPath(),\n databaseReady: connected,\n claudeInstalled,\n };\n } finally {\n process.off(\"SIGINT\", sigintHandler);\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport type ComposeCommand =\n | { kind: \"v2\"; bin: \"docker\"; args: string[] }\n | { kind: \"v1\"; bin: \"docker-compose\"; args: string[] };\n\nexport function resolveBundledComposeFile(): string {\n const here = dirname(fileURLToPath(import.meta.url));\n // Candidates are ordered most-specific first so a published package's bundled\n // file wins over a stray docker-compose.yml in the user's cwd.\n const candidates = [\n // installed package: dist/cli/commands/ -> root\n resolve(here, \"..\", \"..\", \"..\", \"docker-compose.yml\"),\n // source layout: src/cli/commands/ -> root\n resolve(here, \"..\", \"..\", \"..\", \"..\", \"docker-compose.yml\"),\n resolve(here, \"..\", \"..\", \"docker-compose.yml\"),\n resolve(process.cwd(), \"docker-compose.yml\"),\n ];\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n throw new Error(`Could not locate docker-compose.yml. Looked in:\\n ${candidates.join(\"\\n \")}`);\n}\n\nexport type DockerComposeResult = {\n code: number;\n stdout: string;\n stderr: string;\n};\n\nexport type RunDockerComposeOptions = {\n /** Override spawn for tests. */\n spawnImpl?: typeof spawn;\n};\n\n/**\n * Try `docker compose` (v2 — bundled with Docker Desktop) first, then fall back\n * to the legacy standalone `docker-compose` (v1) for older installs.\n */\nexport async function runDockerCompose(\n args: string[],\n options: RunDockerComposeOptions = {},\n): Promise<DockerComposeResult> {\n const spawnImpl = options.spawnImpl ?? spawn;\n const composeFile = resolveBundledComposeFile();\n const attempts: ComposeCommand[] = [\n { kind: \"v2\", bin: \"docker\", args: [\"compose\", \"-f\", composeFile, ...args] },\n { kind: \"v1\", bin: \"docker-compose\", args: [\"-f\", composeFile, ...args] },\n ];\n\n let lastSpawnError: NodeJS.ErrnoException | null = null;\n\n for (const attempt of attempts) {\n try {\n return await spawnOnce(spawnImpl, attempt);\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n // ENOENT means the binary isn't on PATH — try the next candidate.\n // Any other error is propagated immediately.\n if (err.code !== \"ENOENT\") throw err;\n lastSpawnError = err;\n }\n }\n\n throw new Error(\n `Could not find docker. Install Docker Desktop (or docker-compose v1) and ensure it is on your PATH. (${lastSpawnError?.message ?? \"spawn ENOENT\"})`,\n );\n}\n\nfunction spawnOnce(spawnImpl: typeof spawn, attempt: ComposeCommand): Promise<DockerComposeResult> {\n return new Promise((resolvePromise, rejectPromise) => {\n const child = spawnImpl(attempt.bin, attempt.args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", (error) => {\n rejectPromise(error);\n });\n child.on(\"close\", (code) => {\n resolvePromise({ code: code ?? 0, stdout, stderr });\n });\n });\n}\n\nexport async function postgresUp(options?: RunDockerComposeOptions): Promise<DockerComposeResult> {\n return runDockerCompose([\"up\", \"-d\"], options ?? {});\n}\n\nexport async function postgresDown(\n options?: RunDockerComposeOptions,\n): Promise<DockerComposeResult> {\n return runDockerCompose([\"down\"], options ?? {});\n}\n\nexport async function postgresStatus(\n options?: RunDockerComposeOptions,\n): Promise<DockerComposeResult> {\n return runDockerCompose([\"ps\"], options ?? {});\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { resolveNamespaceFrom } from \"../../core/config-file.js\";\nimport { recordChangeOutcome } from \"../../learning/outcomes.js\";\n\nexport function registerLearnCommand(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const learn = program.command(\"learn\").description(\"Record verified team change outcomes.\");\n learn\n .command(\"outcome\")\n .requiredOption(\"--outcome <outcome>\", \"safe or regression\")\n .requiredOption(\"--paths <paths>\", \"Comma-separated repo-relative paths.\")\n .requiredOption(\"--summary <summary>\", \"What happened and why it matters.\")\n .option(\"--severity <severity>\", \"Incident severity: low, medium, high, or critical.\")\n .option(\"--commit <sha>\", \"Commit associated with the outcome.\")\n .option(\"--plan <id>\", \"Plan associated with the outcome.\")\n .description(\"Write an explicit, reviewable outcome into shared Markdown memory.\")\n .action(\n async (opts: {\n outcome: string;\n paths: string;\n summary: string;\n severity?: \"low\" | \"medium\" | \"high\" | \"critical\";\n commit?: string;\n plan?: string;\n }) => {\n await runSafely(async () => {\n if (opts.outcome !== \"safe\" && opts.outcome !== \"regression\") {\n throw new Error(\"--outcome must be safe or regression.\");\n }\n const result = await recordChangeOutcome({\n namespace: await resolveNamespaceFrom(),\n outcome: opts.outcome,\n paths: opts.paths\n .split(\",\")\n .map((path) => path.trim())\n .filter(Boolean),\n summary: opts.summary,\n ...(opts.severity ? { severity: opts.severity } : {}),\n ...(opts.commit ? { commit: opts.commit } : {}),\n ...(opts.plan ? { planId: opts.plan } : {}),\n });\n console.log(`${pc.green(\"recorded\")} ${result.id} (${result.category})`);\n console.log(pc.dim(result.path));\n });\n },\n );\n}\n","import { computeFactHash, generateEntityId } from \"../core/ids.js\";\nimport { type IncidentSeverity, MemoryFileStore } from \"../core/memory-file-store.js\";\nimport { redactPersisted } from \"../memory-extract/sensitive.js\";\n\nexport type ChangeOutcome = \"safe\" | \"regression\";\n\nexport type RecordChangeOutcomeInput = {\n repositoryRoot?: string;\n namespace: string;\n outcome: ChangeOutcome;\n paths: string[];\n summary: string;\n severity?: IncidentSeverity;\n commit?: string;\n planId?: string;\n now?: Date;\n};\n\nexport type RecordChangeOutcomeResult = {\n id: string;\n path: string;\n category: \"general\" | \"incident\";\n};\n\nexport async function recordChangeOutcome(\n input: RecordChangeOutcomeInput,\n): Promise<RecordChangeOutcomeResult> {\n if (input.paths.length === 0) throw new Error(\"At least one path is required.\");\n if (!input.summary.trim()) throw new Error(\"A non-empty outcome summary is required.\");\n const now = input.now ?? new Date();\n const category = input.outcome === \"regression\" ? \"incident\" : \"general\";\n const id = generateEntityId(\"fact\", now.getTime());\n const object = input.outcome === \"regression\" ? \"regression observed\" : \"verified safe\";\n const content = [\n `Change outcome: ${input.outcome}`,\n `Paths: ${input.paths.join(\", \")}`,\n `Summary: ${input.summary.trim()}`,\n ...(input.commit ? [`Commit: ${input.commit}`] : []),\n ].join(\"\\n\");\n const store = new MemoryFileStore(input.repositoryRoot);\n const subject = `change outcome for ${input.paths[0]}`;\n const predicate = input.outcome === \"regression\" ? \"caused\" : \"survived\";\n // Fingerprint the form that is actually persisted, never the raw text.\n const persisted = redactPersisted({ subject, predicate, object, content });\n const path = await store.writeFact({\n id,\n namespace: input.namespace,\n subject,\n predicate,\n object,\n confidence: input.outcome === \"regression\" ? 0.95 : 0.85,\n createdAt: now.toISOString(),\n createdByAgent: \"codebuddy:learn\",\n sourceInteractionId: null,\n sourceDeleted: false,\n category,\n paths: input.paths,\n ...(input.outcome === \"regression\" ? { severity: input.severity ?? \"high\" } : {}),\n ...(input.commit ? { introducedBy: input.commit } : {}),\n ...(input.planId ? { sourcePlanId: input.planId } : {}),\n verification: [\"explicit change outcome recorded by a project owner\"],\n fingerprint: computeFactHash(input.namespace, persisted.content),\n content,\n });\n return { id, path, category };\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { buildArchitectureMap, neighbours, queryMap } from \"../../map/indexer.js\";\n\nexport function registerMapCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const map = program.command(\"map\").description(\"Query the lightweight architecture map.\");\n\n map\n .command(\"build\")\n .description(\"Scan the current repository and summarize the module graph.\")\n .action(async () => {\n await runSafely(async () => {\n const graph = await buildArchitectureMap();\n console.log(\n JSON.stringify({ modules: graph.modules.length, edges: graph.edges.length }, null, 2),\n );\n });\n });\n\n map\n .command(\"deps\")\n .argument(\"<path>\", \"Repo-relative module path.\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"List modules imported by a file.\")\n .action(async (path: string, opts: { json?: boolean }) => {\n await runSafely(async () => {\n const graph = await buildArchitectureMap();\n const edges = queryMap(graph, { from: path });\n if (opts.json) {\n console.log(JSON.stringify({ edges }, null, 2));\n return;\n }\n if (edges.length === 0) {\n console.log(pc.dim(\"no dependencies found\"));\n return;\n }\n for (const edge of edges) console.log(`${edge.from} -> ${edge.to}`);\n });\n });\n\n map\n .command(\"dependents\")\n .argument(\"<path>\", \"Repo-relative module path.\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"List modules that import a file.\")\n .action(async (path: string, opts: { json?: boolean }) => {\n await runSafely(async () => {\n const graph = await buildArchitectureMap();\n const result = neighbours(graph, path, \"in\");\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (result.edges.length === 0) {\n console.log(pc.dim(\"no dependents found\"));\n return;\n }\n for (const edge of result.edges) console.log(`${edge.from} -> ${edge.to}`);\n });\n });\n}\n","import { spawn } from \"node:child_process\";\nimport { relative } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { approveReviewItem } from \"../../memory-extract/engine.js\";\nimport { type ReviewItem, ReviewStore } from \"../../memory-extract/review-store.js\";\n\n/**\n * The review queue is file-based Markdown under `.codebuddy/memory/review/`;\n * these commands need no database. Approving promotes an item to a durable\n * fact; rejecting deletes it. Nothing is ever committed automatically.\n */\nexport function registerMemoryCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const memory = program.command(\"memory\").description(\"Inspect and curate CodeBuddy memory.\");\n const review = memory\n .command(\"review\")\n .description(\"Review memory candidates captured automatically after turns.\");\n\n review\n .command(\"list\", { isDefault: true })\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"List pending review candidates.\")\n .action(async (opts: { json?: boolean }) => {\n await runSafely(async () => {\n const items = await new ReviewStore().list();\n if (opts.json) {\n console.log(JSON.stringify(items, null, 2));\n return;\n }\n if (items.length === 0) {\n console.log(pc.dim(\"no pending review items\"));\n return;\n }\n for (const item of items) console.log(renderRow(item));\n console.log(pc.dim(`\\n${items.length} pending. approve <id> | reject <id> | show <id>`));\n });\n });\n\n review\n .command(\"show\")\n .argument(\"<id>\")\n .description(\"Show a single review candidate.\")\n .action(async (id: string) => {\n await runSafely(async () => {\n console.log(renderItem(await new ReviewStore().read(id)));\n });\n });\n\n review\n .command(\"approve\")\n .argument(\"<id>\")\n .option(\"--incident <id>\", \"For a queued incident resolution: the incident to resolve.\")\n .description(\"Promote a review candidate to a durable fact and remove it from the queue.\")\n .action(async (id: string, opts: { incident?: string }) => {\n await runSafely(async () => {\n const factId = await approveReviewItem(id, {\n ...(opts.incident !== undefined ? { incidentId: opts.incident } : {}),\n });\n console.log(`${pc.green(\"approved\")} ${id} → ${factId}`);\n });\n });\n\n review\n .command(\"reject\")\n .argument(\"<id>\")\n .description(\"Discard a review candidate without saving it.\")\n .action(async (id: string) => {\n await runSafely(async () => {\n const store = new ReviewStore();\n await store.read(id); // Validate existence for a clear error.\n await store.delete(id);\n console.log(`${pc.yellow(\"rejected\")} ${id}`);\n });\n });\n\n review\n .command(\"edit\")\n .argument(\"<id>\")\n .description(\"Open a review candidate in $EDITOR and re-validate on save.\")\n .action(async (id: string) => {\n await runSafely(async () => {\n const store = new ReviewStore();\n const item = await store.read(id);\n await openEditor(item.path);\n await store.read(id); // Re-parse to reject malformed edits loudly.\n console.log(pc.dim(\"saved and validated\"));\n });\n });\n}\n\nfunction renderRow(item: ReviewItem): string {\n const flag = item.sensitive ? pc.red(\" ⚠ sensitive\") : \"\";\n return `${classColor(item.class)} ${pc.dim(item.id)} ${truncate(item.content, 70)}${flag}`;\n}\n\nfunction renderItem(item: ReviewItem): string {\n const lines = [\n `${classColor(item.class)} ${pc.dim(item.id)}`,\n `${pc.bold(\"reason:\")} ${item.reason}`,\n `${pc.bold(\"confidence:\")} ${item.confidence.toFixed(2)}`,\n `${pc.bold(\"triple:\")} ${item.subject} · ${item.predicate} · ${item.object}`,\n ];\n if (item.paths.length > 0) lines.push(`${pc.bold(\"paths:\")} ${item.paths.join(\", \")}`);\n if (item.severity) lines.push(`${pc.bold(\"severity:\")} ${item.severity}`);\n if (item.resolvesIncidents) {\n lines.push(\n `${pc.bold(\"resolves:\")} ${item.resolvesIncidents.join(\", \") || \"(no candidate; approve with --incident <id>)\"}`,\n );\n }\n if (item.sensitive) lines.push(pc.red(`⚠ sensitive: ${item.sensitiveReasons.join(\", \")}`));\n lines.push(\"\", item.content, \"\", pc.dim(relative(process.cwd(), item.path)));\n return lines.join(\"\\n\");\n}\n\nfunction classColor(memoryClass: ReviewItem[\"class\"]): string {\n switch (memoryClass) {\n case \"incident\":\n return pc.red(memoryClass);\n case \"decision\":\n return pc.cyan(memoryClass);\n case \"fact\":\n return pc.green(memoryClass);\n case \"note\":\n return pc.yellow(memoryClass);\n default:\n return pc.dim(memoryClass);\n }\n}\n\nfunction truncate(value: string, max: number): string {\n const trimmed = value.trim();\n return trimmed.length <= max ? trimmed : `${trimmed.slice(0, max - 1)}…`;\n}\n\nfunction openEditor(path: string): Promise<void> {\n const editor = process.env.EDITOR ?? process.env.VISUAL ?? \"vi\";\n return new Promise((resolvePromise, reject) => {\n const child = spawn(editor, [path], { stdio: \"inherit\" });\n child.on(\"error\", reject);\n child.on(\"close\", () => resolvePromise());\n });\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { spinner } from \"@clack/prompts\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { buildProviderFromConfig } from \"../../core/codebuddy.js\";\nimport {\n loadRuntimeConfig,\n readConfigFile,\n redactSecrets,\n setConfigBlock,\n} from \"../../core/config-file.js\";\nimport { createDatabaseClient } from \"../../db/client.js\";\nimport { calibrateEmbedder } from \"../../providers/calibration.js\";\nimport { embeddingSpaceKey } from \"../../providers/embedding-space.js\";\nimport { modelCacheDir } from \"../../providers/local.js\";\nimport {\n DEFAULT_CLOUD_EMBEDDING_MODELS,\n DEFAULT_RERANK_MODELS,\n getModelDefinition,\n LOCAL_EMBEDDING_MODEL,\n} from \"../../providers/models.js\";\nimport { syncInBackground } from \"./hooks.js\";\n\n/**\n * `codebuddy models`: which embedding model and reranker power per-prompt\n * memory recall, whether they are ready, and switching between local\n * (default, no key) and hosted ones (Hugging Face, OpenRouter).\n */\n\nconst EMBEDDERS = [\"local\", \"huggingface\", \"openrouter\"] as const;\nconst RERANKERS = [\"off\", \"local\", \"huggingface\", \"openrouter\"] as const;\ntype Embedder = (typeof EMBEDDERS)[number];\ntype RerankChoice = (typeof RERANKERS)[number];\nconst KEY_ENV = { huggingface: \"HF_TOKEN\", openrouter: \"OPENROUTER_API_KEY\" } as const;\n\nconst ok = (text: string) => `${pc.green(\"✓\")} ${text}`;\nconst warn = (text: string) => `${pc.yellow(\"!\")} ${text}`;\nconst row = (label: string, value: string) => ` ${pc.dim(label.padEnd(11))}${value}`;\n\n/** Run `work` under a spinner that always stops, so a failure never leaves the process hanging. */\nasync function withSpinner<T>(\n label: string,\n work: () => Promise<T>,\n done: (value: T) => string,\n): Promise<T> {\n const progress = spinner();\n progress.start(label);\n try {\n const value = await work();\n progress.stop(done(value));\n return value;\n } catch (error) {\n progress.stop(pc.red(`✗ ${label}`), 1);\n throw error;\n }\n}\n\nfunction keyPresent(provider: \"huggingface\" | \"openrouter\", apiKey?: string): boolean {\n return Boolean(process.env[KEY_ENV[provider]] || (provider === \"huggingface\" && apiKey));\n}\n\nfunction localModelDownloaded(id: string, revision?: string): boolean {\n const dir = join(modelCacheDir(), id, ...(revision ? [revision] : []));\n return existsSync(join(dir, \"onnx\", \"model_quantized.onnx\"));\n}\n\nasync function vectorCounts(\n postgresUrl: string,\n namespace: string,\n space: string | undefined,\n): Promise<{ ready: number; pending: number; failed: number; other: number } | string> {\n const client = createDatabaseClient({ postgresUrl, maxConnections: 1, connectTimeoutSeconds: 3 });\n try {\n const [counts] = await client.sql<\n Array<{ ready: number; pending: number; failed: number; other: number }>\n >`\n select\n count(*) filter (where e.status = 'ready' and e.embedding_space = ${space ?? \"\"})::int as ready,\n count(*) filter (where e.status in ('pending', 'processing'))::int as pending,\n count(*) filter (where e.status = 'failed')::int as failed,\n count(*) filter (where e.status = 'ready' and e.embedding_space is distinct from ${space ?? \"\"})::int as other\n from embeddings e join namespaces n on n.id = e.namespace_id\n where n.name = ${namespace}\n `;\n return counts ?? { ready: 0, pending: 0, failed: 0, other: 0 };\n } catch (error) {\n return String(redactSecrets((error as Error).message)).split(\"\\n\")[0] ?? \"unreachable\";\n } finally {\n await client.close().catch(() => undefined);\n }\n}\n\nasync function printStatus(): Promise<void> {\n const file = await readConfigFile();\n const config = await loadRuntimeConfig(process.cwd(), { requireDatabase: false });\n const provider = config.provider;\n const embedder = buildProviderFromConfig(config.provider);\n const space = embedder.space;\n const model =\n provider.type === \"local\"\n ? LOCAL_EMBEDDING_MODEL.id\n : (provider.model ?? DEFAULT_CLOUD_EMBEDDING_MODELS[provider.type]);\n const floor = provider.relevanceFloor ?? getModelDefinition(model)?.relevanceFloor;\n const next: string[] = [];\n\n console.log(pc.bold(\"Embeddings\"));\n console.log(row(\"provider\", `${provider.type} ${pc.dim(model)}`));\n if (provider.type === \"local\") {\n const ready = localModelDownloaded(LOCAL_EMBEDDING_MODEL.id, LOCAL_EMBEDDING_MODEL.revision);\n console.log(\n row(\n \"model\",\n ready ? ok(`downloaded ${pc.dim(modelCacheDir())}`) : warn(\"not downloaded yet (~90 MB)\"),\n ),\n );\n if (!ready) next.push(\"codebuddy models pull\");\n } else {\n const present = keyPresent(provider.type, provider.apiKey);\n console.log(\n row(\n \"key\",\n present ? ok(KEY_ENV[provider.type]) : warn(`${KEY_ENV[provider.type]} is not set`),\n ),\n );\n if (!present) next.push(`export ${KEY_ENV[provider.type]}=…`);\n }\n console.log(\n row(\n \"floor\",\n floor !== undefined\n ? `${floor} ${pc.dim(provider.relevanceFloor !== undefined ? \"(calibrated for this project)\" : \"(built-in)\")}`\n : warn(\"not calibrated: dense recall is off for this model\"),\n ),\n );\n if (floor === undefined) next.push(\"codebuddy models calibrate\");\n\n const rerank = file.rerank?.provider ?? \"off\";\n console.log(pc.bold(\"Reranker\"));\n if (rerank === \"off\") {\n console.log(\n row(\"provider\", `off ${pc.dim(\"(default: no reranker beat dense order in evals)\")}`),\n );\n } else {\n console.log(\n row(\n \"provider\",\n `${rerank} ${pc.dim(file.rerank?.model ?? DEFAULT_RERANK_MODELS[rerank].id)}`,\n ),\n );\n if (rerank !== \"local\") {\n const present = keyPresent(rerank, file.provider?.apiKey);\n console.log(\n row(\n \"key\",\n present\n ? ok(KEY_ENV[rerank])\n : warn(`${KEY_ENV[rerank]} is not set; reranking is skipped`),\n ),\n );\n }\n }\n\n console.log(pc.bold(\"Memory index\"));\n if (process.env.CODEBUDDY_SEMANTIC === \"0\") {\n console.log(row(\"recall\", warn(\"CODEBUDDY_SEMANTIC=0: lexical only\")));\n }\n if (!config.postgresUrl) {\n console.log(row(\"postgres\", warn(\"not configured: recall is lexical only\")));\n next.push(\"codebuddy use (sets up PostgreSQL)\");\n } else {\n const counts = await vectorCounts(\n config.postgresUrl,\n config.namespace,\n space ? embeddingSpaceKey(space) : undefined,\n );\n if (typeof counts === \"string\") {\n console.log(row(\"postgres\", warn(`unreachable: ${counts}`)));\n next.push(\"codebuddy postgres up\");\n } else {\n console.log(row(\"postgres\", ok(`namespace ${config.namespace}`)));\n console.log(\n row(\n \"vectors\",\n `${counts.ready} ready` +\n (counts.pending ? `, ${counts.pending} pending` : \"\") +\n (counts.failed ? pc.red(`, ${counts.failed} failed`) : \"\") +\n (counts.other ? pc.yellow(`, ${counts.other} from another model`) : \"\"),\n ),\n );\n if (counts.pending || counts.other)\n next.push(\"codebuddy hooks sync (embeds pending and re-embeds old vectors)\");\n }\n }\n console.log(\n next.length > 0\n ? `\\n${pc.bold(\"Next\")}\\n${next.map((step) => ` ${pc.cyan(step)}`).join(\"\\n\")}`\n : `\\n${ok(\"Semantic recall is ready.\")} ${pc.dim('Try: codebuddy context preview \"<task>\"')}`,\n );\n}\n\nexport function registerModelsCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const models = program\n .command(\"models\")\n .description(\"Embedding model and reranker behind per-prompt memory recall.\")\n .action(async () => runSafely(printStatus));\n\n models\n .command(\"status\")\n .description(\"Show the embedding model, reranker, keys and vector index health.\")\n .action(async () => runSafely(printStatus));\n\n models\n .command(\"use\")\n .argument(\"<provider>\", `Embedding provider: ${EMBEDDERS.join(\" | \")}.`)\n .option(\"--model <id>\", \"Hosted model id (must return 384-d vectors).\")\n .option(\n \"--floor <cosine>\",\n \"Relevance floor; otherwise built-in or `models calibrate`.\",\n Number,\n )\n .description(\"Choose where embeddings run: local (default, no key) or a hosted API.\")\n .addHelpText(\n \"after\",\n `\nExamples:\n codebuddy models use local\n codebuddy models use openrouter # ${DEFAULT_CLOUD_EMBEDDING_MODELS.openrouter}, needs OPENROUTER_API_KEY\n codebuddy models use openrouter --model nvidia/nemotron-3.5-embed-1b:free\n codebuddy models use huggingface # ${DEFAULT_CLOUD_EMBEDDING_MODELS.huggingface}, needs HF_TOKEN`,\n )\n .action(async (choice: string, opts: { model?: string; floor?: number }) => {\n await runSafely(async () => {\n if (!EMBEDDERS.includes(choice as Embedder)) {\n throw new Error(`Unknown provider \"${choice}\". Use one of: ${EMBEDDERS.join(\", \")}.`);\n }\n const type = choice as Embedder;\n if (type === \"local\" && opts.model) {\n throw new Error(\n \"The local provider has one built-in model; --model is for hosted providers.\",\n );\n }\n const current = (await readConfigFile()).provider;\n await setConfigBlock(\"provider\", {\n type,\n ...(current?.apiKey ? { apiKey: current.apiKey } : {}),\n ...(opts.model ? { model: opts.model } : {}),\n ...(opts.floor !== undefined ? { relevanceFloor: opts.floor } : {}),\n });\n const model =\n type === \"local\"\n ? LOCAL_EMBEDDING_MODEL.id\n : (opts.model ?? DEFAULT_CLOUD_EMBEDDING_MODELS[type]);\n console.log(ok(`Embeddings: ${type} ${pc.dim(model)}`));\n const missingKey = type !== \"local\" && !keyPresent(type, current?.apiKey);\n if (missingKey) {\n console.log(\n warn(\n `Set ${KEY_ENV[type]} in your shell (keys are never stored in config), then run ${pc.cyan(\"codebuddy hooks sync\")}.`,\n ),\n );\n console.log(pc.dim(\" Existing vectors keep working until the new model can embed.\"));\n }\n if (opts.floor === undefined && getModelDefinition(model)?.relevanceFloor === undefined) {\n console.log(\n warn(\n `No floor for ${model} yet: run ${pc.cyan(\"codebuddy models calibrate\")} to turn on dense recall.`,\n ),\n );\n }\n if (!missingKey) {\n syncInBackground(process.cwd());\n console.log(\n pc.dim(\" Re-embedding existing memory in the background (codebuddy hooks sync).\"),\n );\n }\n });\n });\n\n models\n .command(\"rerank\")\n .argument(\"<provider>\", `Reranker: ${RERANKERS.join(\" | \")}.`)\n .option(\"--model <id>\", \"Cross-encoder model id.\")\n .description(\"Optionally reorder recalled facts with a cross-encoder (off by default).\")\n .addHelpText(\n \"after\",\n `\nDefaults: local ${DEFAULT_RERANK_MODELS.local.id} · huggingface ${DEFAULT_RERANK_MODELS.huggingface.id}\n openrouter ${DEFAULT_RERANK_MODELS.openrouter.id} (paid per search)\nIn CodeBuddy's eval, no reranker beat the dense order; measure on your data\nbefore keeping one on. A reranker never admits a fact, it only orders them.`,\n )\n .action(async (choice: string, opts: { model?: string }) => {\n await runSafely(async () => {\n if (!RERANKERS.includes(choice as RerankChoice)) {\n throw new Error(`Unknown reranker \"${choice}\". Use one of: ${RERANKERS.join(\", \")}.`);\n }\n await setConfigBlock(\"rerank\", {\n provider: choice,\n ...(opts.model ? { model: opts.model } : {}),\n });\n if (choice === \"off\") {\n console.log(ok(\"Reranker off: facts keep their fused (keyword + vector) order.\"));\n return;\n }\n const reranker = choice as Exclude<RerankChoice, \"off\">;\n console.log(\n ok(`Reranker: ${reranker} ${pc.dim(opts.model ?? DEFAULT_RERANK_MODELS[reranker].id)}`),\n );\n if (\n reranker !== \"local\" &&\n !keyPresent(reranker, (await readConfigFile()).provider?.apiKey)\n ) {\n console.log(warn(`Set ${KEY_ENV[reranker]}; without it reranking is skipped.`));\n }\n if (reranker === \"local\")\n console.log(pc.dim(\" Run codebuddy models pull to download it now.\"));\n });\n });\n\n models\n .command(\"pull\")\n .description(\"Download the local models now instead of on first use.\")\n .action(async () => {\n await runSafely(async () => {\n const { LocalModelProvider, rerankLocally } = await import(\"../../providers/local.js\");\n const file = await readConfigFile();\n let started = Date.now();\n await withSpinner(\n `Downloading ${LOCAL_EMBEDDING_MODEL.id}`,\n () => new LocalModelProvider().embed({ input: \"warm up\" }),\n () => ok(`${LOCAL_EMBEDDING_MODEL.id} ready ${pc.dim(`${Date.now() - started} ms`)}`),\n );\n if (file.rerank?.provider === \"local\") {\n const id = file.rerank.model ?? DEFAULT_RERANK_MODELS.local.id;\n const revision =\n id === DEFAULT_RERANK_MODELS.local.id\n ? DEFAULT_RERANK_MODELS.local.revision\n : undefined;\n started = Date.now();\n await withSpinner(\n `Downloading ${id}`,\n () => rerankLocally({ id, ...(revision ? { revision } : {}) }, \"warm\", [\"up\"]),\n () => ok(`${id} ready ${pc.dim(`${Date.now() - started} ms`)}`),\n );\n }\n console.log(pc.dim(` Cache: ${modelCacheDir()}`));\n });\n });\n\n models\n .command(\"calibrate\")\n .option(\"--dry-run\", \"Measure only; do not save the floor.\")\n .description(\n \"Measure the configured embedder on a built-in task set and save its recall floor.\",\n )\n .action(async (opts: { dryRun?: boolean }) => {\n await runSafely(async () => {\n const config = await loadRuntimeConfig(process.cwd(), { requireDatabase: false });\n const embedder = buildProviderFromConfig(config.provider);\n const result = await withSpinner(\n `Embedding 44 calibration texts with ${embedder.space?.model ?? config.provider.type}`,\n () =>\n calibrateEmbedder(async (texts) => (await embedder.embed({ input: texts })).vectors),\n () => ok(\"Measured\"),\n );\n const pct = (value: number) => `${Math.round(value * 100)}%`;\n console.log(\n row(\n \"ranking\",\n `AUC ${result.auc.toFixed(3)} · right fact first ${pct(result.recallAt1)} ${pc.dim(\"(held-out tasks)\")}`,\n ),\n );\n console.log(\n row(\n \"floor\",\n `${result.best.floor}: precision ${pct(result.test.precision)}, recall ${pct(result.test.recall)}, ` +\n `silent on ${pct(result.test.abstain)} of unrelated tasks ${pc.dim(\"(chosen on dev, measured on test)\")}`,\n ),\n );\n if (opts.dryRun) return;\n const file = await readConfigFile();\n await setConfigBlock(\"provider\", {\n ...(file.provider ?? { type: config.provider.type }),\n relevanceFloor: result.best.floor,\n });\n console.log(ok(`Saved relevanceFloor ${result.best.floor} to .codebuddy/config.json`));\n });\n });\n}\n","{\n \"version\": 2,\n \"note\": \"Task prompts vs durable project facts. Queries are paraphrased so most share few or no words with their fact; every unlisted (query, fact) pair is irrelevant. Hard negatives share a subsystem with a relevant fact but do not answer its task. Queries alternate dev/test by position (even index = dev): floors are chosen on dev and reported on test.\",\n \"facts\": {\n \"cookie\": \"OAuth callback breaks unless the session cookie is SameSite=Lax; Strict drops it on the cross-site redirect.\",\n \"pool\": \"Postgres connections go through one bounded pool of 10; never open ad-hoc clients in request handlers.\",\n \"release\": \"npm releases are published from CI with provenance; never publish from a laptop.\",\n \"biome\": \"Biome owns formatting and import order; run biome check --write before committing.\",\n \"hook\": \"Prompt hooks must answer within 15 seconds or the host drops the injected block.\",\n \"migration\": \"Migrations must create the pgvector extension before 0003 adds the vector column.\",\n \"redaction\": \"Secrets are redacted before a memory is written; the content hash is computed after redaction.\",\n \"ledger\": \"The session ledger keeps the last 8 acknowledged versions per section so a task switch back is not resent.\",\n \"zvec\": \"zvec-grep is optional; any failure falls back to keyword ranking with a retrieval explain line.\",\n \"tests\": \"Integration tests skip unless CODEBUDDY_TEST_DATABASE_URL points at a live Postgres.\",\n \"esm\": \"Source imports use .js specifiers even for TypeScript files because the package is ESM.\",\n \"stdout\": \"Never log to stdout in the MCP server: stdout carries JSON-RPC and any stray line corrupts it.\",\n \"budget\": \"The BYOK LLM layer stops background calls at 70% of the daily budget and backs off after a 429.\",\n \"worktree\": \"Use a temporary WIP commit instead of git stash; the stash stack is shared across worktrees.\",\n \"rateLimit\": \"The public API allows 100 requests per minute per token; bursts above it get HTTP 429.\",\n \"timezone\": \"All timestamps are stored in UTC and converted to the user's zone only for display.\",\n \"avatar\": \"Profile images are resized to 256px and stored as WebP in the media bucket.\",\n \"flags\": \"Feature flags are read once at boot; changing one requires a restart of the worker.\",\n \"pagination\": \"List endpoints use cursor pagination with an opaque base64url cursor of createdAt and id.\",\n \"i18n\": \"UI strings live in locales/en.json; never hard-code user-facing text in components.\",\n \"cookieDomain\": \"Session cookies are scoped to the app subdomain; never set them on the apex domain.\",\n \"poolMetrics\": \"Database pool metrics are exported to Prometheus under the codebuddy_pool_ prefix.\",\n \"releaseNotes\": \"Release notes are drafted from merged pull request titles by the changelog script.\",\n \"hookInstall\": \"Hooks are written to .claude/settings.json and merged idempotently with the user's own hooks.\",\n \"migrationNaming\": \"Migration files are numbered by drizzle-kit; never rename or edit a migration that has been applied.\",\n \"testsParallel\": \"Vitest runs test files in parallel, so every test must use its own temporary directory.\",\n \"logsStderr\": \"Server logs go to stderr through pino; never log full request bodies.\",\n \"retry5xx\": \"The HTTP client retries 5xx responses twice with jittered backoff.\",\n \"dateFormat\": \"Dates in the UI are formatted with the user's locale through Intl.DateTimeFormat.\",\n \"flagNames\": \"Feature flag names use kebab-case and are declared in flags.yaml.\"\n },\n \"queries\": [\n {\n \"q\": \"users get bounced back to sign-in forever after the identity provider returns\",\n \"relevant\": [\"cookie\"]\n },\n {\n \"q\": \"handlers are exhausting connections to the database under load\",\n \"relevant\": [\"pool\"]\n },\n {\n \"q\": \"cut a new version and push the package to the registry\",\n \"relevant\": [\"release\"]\n },\n {\n \"q\": \"the injected block sometimes never shows up in the chat\",\n \"relevant\": [\"hook\"]\n },\n {\n \"q\": \"fresh database setup fails on the embedding column\",\n \"relevant\": [\"migration\"]\n },\n {\n \"q\": \"an API key ended up in a saved note\",\n \"relevant\": [\"redaction\"]\n },\n {\n \"q\": \"context is sent again after I switch tasks and come back\",\n \"relevant\": [\"ledger\"]\n },\n {\n \"q\": \"semantic code search crashes and the agent gets no files\",\n \"relevant\": [\"zvec\"]\n },\n {\n \"q\": \"why do the db tests not run on my machine\",\n \"relevant\": [\"tests\"]\n },\n {\n \"q\": \"module not found when importing a sibling ts file at runtime\",\n \"relevant\": [\"esm\"]\n },\n {\n \"q\": \"Claude Desktop says Unexpected token in the server response\",\n \"relevant\": [\"stdout\"]\n },\n {\n \"q\": \"the summarizer quietly stopped calling Groq in the afternoon\",\n \"relevant\": [\"budget\"]\n },\n {\n \"q\": \"my uncommitted changes vanished after another session ran\",\n \"relevant\": [\"worktree\"]\n },\n {\n \"q\": \"clients see too many requests errors during the import job\",\n \"relevant\": [\"rateLimit\"]\n },\n {\n \"q\": \"meeting times show up one hour off for users in Berlin\",\n \"relevant\": [\"timezone\"]\n },\n {\n \"q\": \"uploaded profile pictures look blurry\",\n \"relevant\": [\"avatar\"]\n },\n {\n \"q\": \"I toggled the new checkout switch but nothing changed\",\n \"relevant\": [\"flags\"]\n },\n {\n \"q\": \"infinite scroll repeats items on the second page\",\n \"relevant\": [\"pagination\"]\n },\n {\n \"q\": \"translate the onboarding screen to German\",\n \"relevant\": [\"i18n\"]\n },\n {\n \"q\": \"format the code before I commit\",\n \"relevant\": [\"biome\"]\n },\n {\n \"q\": \"make the sidebar collapsible\",\n \"relevant\": []\n },\n {\n \"q\": \"add dark mode to the dashboard\",\n \"relevant\": []\n },\n {\n \"q\": \"write a haiku about the project\",\n \"relevant\": []\n },\n {\n \"q\": \"rename the button label on the settings page\",\n \"relevant\": []\n },\n {\n \"q\": \"where do I declare a new feature flag\",\n \"relevant\": [\"flagNames\"]\n },\n {\n \"q\": \"show dates in the user's own language and order\",\n \"relevant\": [\"dateFormat\"]\n },\n {\n \"q\": \"can I tidy up the name of the 0004 migration file\",\n \"relevant\": [\"migrationNaming\"]\n },\n {\n \"q\": \"tests interfere with each other when the whole suite runs\",\n \"relevant\": [\"testsParallel\"]\n },\n {\n \"q\": \"where can I see how busy the connection pool is\",\n \"relevant\": [\"poolMetrics\"]\n },\n {\n \"q\": \"how is the text for the changelog produced\",\n \"relevant\": [\"releaseNotes\"]\n },\n {\n \"q\": \"the login cookie shows up on example.com instead of app.example.com\",\n \"relevant\": [\"cookieDomain\"]\n },\n {\n \"q\": \"is it fine to print the incoming payload for debugging\",\n \"relevant\": [\"logsStderr\"]\n },\n {\n \"q\": \"our hook setup appears twice in the Claude settings file\",\n \"relevant\": [\"hookInstall\"]\n },\n {\n \"q\": \"flaky upstream 502s should not fail the request on the first try\",\n \"relevant\": [\"retry5xx\"]\n },\n {\n \"q\": \"rewrite the marketing copy on the landing page\",\n \"relevant\": []\n },\n {\n \"q\": \"upgrade React to the next major version\",\n \"relevant\": []\n },\n {\n \"q\": \"add a CSV export button to the reports table\",\n \"relevant\": []\n }\n ]\n}\n","import dataset from \"../../evals/fact-relevance.json\" with { type: \"json\" };\n\n/**\n * Measures an embedder on `evals/fact-relevance.json` (paraphrased coding\n * tasks vs project facts, with hard negatives and unrelated tasks) and picks\n * its relevance floor: the cosine that maximizes F0.5, precision-weighted\n * because a missed memory is cheaper than a false one.\n *\n * Queries alternate dev/test by position. The floor is chosen on dev only;\n * every reported number (AUC, Recall@1, MRR, precision/recall at the floor)\n * is measured on the held-out test queries, so it is not fitted to itself.\n * Used by `codebuddy models calibrate` and `npm run eval:semantic`.\n */\n\nexport type FloorPoint = {\n floor: number;\n precision: number;\n recall: number;\n f05: number;\n /** Share of unrelated tasks for which no fact clears the floor. */\n abstain: number;\n};\n\nexport type Split = \"dev\" | \"test\";\n\nexport type Calibration = {\n /** Held-out (test) ranking quality. */\n auc: number;\n recallAt1: number;\n mrr: number;\n /** The floor chosen on dev, with its dev metrics. */\n best: FloorPoint;\n /** The same floor measured on the held-out test queries. */\n test: FloorPoint;\n at(floor: number, split?: Split): FloorPoint;\n};\n\ntype Dataset = { facts: Record<string, string>; queries: Array<{ q: string; relevant: string[] }> };\n\nexport function splitOf(index: number): Split {\n return index % 2 === 0 ? \"dev\" : \"test\";\n}\n\nexport async function calibrateEmbedder(\n embed: (texts: string[]) => Promise<number[][]>,\n): Promise<Calibration> {\n const data = dataset as Dataset;\n const factIds = Object.keys(data.facts);\n const factVectors = await embed(Object.values(data.facts));\n const queryVectors = await embed(data.queries.map(({ q }) => q));\n const dot = (a: number[], b: number[]) =>\n a.reduce((sum, value, index) => sum + value * (b[index] ?? 0), 0);\n const scores = queryVectors.map((query) => factVectors.map((fact) => dot(query, fact)));\n const relevant = (qi: number, fi: number) =>\n data.queries[qi]?.relevant.includes(factIds[fi] ?? \"\") ?? false;\n const answerable = (qi: number) => (data.queries[qi]?.relevant.length ?? 0) > 0;\n const rows = (split: Split) =>\n scores.flatMap((row, qi) => (splitOf(qi) === split ? [{ row, qi }] : []));\n\n const positives: number[] = [];\n const negatives: number[] = [];\n let hits = 0;\n let reciprocal = 0;\n let answered = 0;\n for (const { row, qi } of rows(\"test\")) {\n for (const [fi, score] of row.entries()) (relevant(qi, fi) ? positives : negatives).push(score);\n if (!answerable(qi)) continue;\n answered += 1;\n const order = row.map((score, fi) => ({ score, fi })).sort((a, b) => b.score - a.score);\n const rank = order.findIndex(({ fi }) => relevant(qi, fi)) + 1;\n if (rank === 1) hits += 1;\n reciprocal += 1 / rank;\n }\n const auc =\n positives.reduce((wins, p) => wins + negatives.filter((n) => p > n).length, 0) /\n (positives.length * negatives.length);\n\n const at = (floor: number, split: Split = \"test\"): FloorPoint => {\n let tp = 0;\n let fp = 0;\n let relevantPairs = 0;\n let abstained = 0;\n let unrelated = 0;\n for (const { row, qi } of rows(split)) {\n relevantPairs += data.queries[qi]?.relevant.length ?? 0;\n const admitted = row.flatMap((score, fi) => (score >= floor ? [fi] : []));\n for (const fi of admitted) {\n if (relevant(qi, fi)) tp += 1;\n else fp += 1;\n }\n if (!answerable(qi)) {\n unrelated += 1;\n if (admitted.length === 0) abstained += 1;\n }\n }\n const precision = tp + fp === 0 ? 1 : tp / (tp + fp);\n const recall = relevantPairs === 0 ? 0 : tp / relevantPairs;\n const f05 =\n precision + recall === 0 ? 0 : (1.25 * precision * recall) / (0.25 * precision + recall);\n return { floor, precision, recall, f05, abstain: unrelated === 0 ? 1 : abstained / unrelated };\n };\n // Cosine ranges differ widely by model (MiniLM ~0.2–0.6, granite ~0.6–0.9).\n const sweep = Array.from({ length: 96 }, (_, i) =>\n at(Math.round((0.05 + i * 0.01) * 100) / 100, \"dev\"),\n );\n const best = sweep.reduce((left, right) => (right.f05 > left.f05 ? right : left));\n return {\n auc,\n recallAt1: answered === 0 ? 0 : hits / answered,\n mrr: answered === 0 ? 0 : reciprocal / answered,\n best,\n test: at(best.floor, \"test\"),\n at,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport { relative } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n loadPlanPolicy,\n PLAN_POLICIES,\n type PlanPolicy,\n resolveNamespaceFrom,\n setPlanPolicy,\n} from \"../../core/config-file.js\";\nimport { PlanFileStore, type PlanSpec, type PlanStatus } from \"../../core/plan-file-store.js\";\nimport { PlanLifecycle } from \"../../core/plan-lifecycle.js\";\n\n/**\n * Resolve the active namespace for plan commands without requiring a\n * database connection — plans are file-based, so a developer can author\n * and inspect them with no Postgres running.\n */\n\nfunction makeLifecycle(cwd = process.cwd()): { store: PlanFileStore; lifecycle: PlanLifecycle } {\n const store = new PlanFileStore(cwd);\n return { store, lifecycle: new PlanLifecycle(store) };\n}\n\nfunction statusColor(status: PlanStatus): string {\n switch (status) {\n case \"draft\":\n return pc.dim(status);\n case \"approved\":\n return pc.cyan(status);\n case \"executing\":\n return pc.yellow(status);\n case \"complete\":\n return pc.green(status);\n case \"abandoned\":\n return pc.red(status);\n }\n}\n\nfunction renderPlan(plan: PlanSpec): string {\n const lines: string[] = [];\n lines.push(`${pc.bold(plan.title)} ${statusColor(plan.status)}`);\n lines.push(pc.dim(plan.id));\n lines.push(\"\");\n lines.push(`${pc.bold(\"Brief:\")} ${plan.brief}`);\n if (plan.filesToTouch.length > 0) {\n lines.push(\"\");\n lines.push(pc.bold(\"Files to touch:\"));\n for (const file of plan.filesToTouch) {\n lines.push(` ${file.action.padEnd(6)} ${file.path}${file.notes ? ` — ${file.notes}` : \"\"}`);\n }\n }\n if (plan.testsToAdd.length > 0) {\n lines.push(\"\");\n lines.push(pc.bold(\"Tests to add:\"));\n for (const test of plan.testsToAdd) {\n lines.push(` ${test.path}${test.description ? ` — ${test.description}` : \"\"}`);\n }\n }\n if (plan.outOfScope.length > 0) {\n lines.push(\"\");\n lines.push(pc.bold(\"Out of scope:\"));\n for (const item of plan.outOfScope) lines.push(` - ${item}`);\n }\n if (plan.risks.length > 0) {\n lines.push(\"\");\n lines.push(pc.bold(\"Risks:\"));\n for (const item of plan.risks) lines.push(` - ${item}`);\n }\n if (plan.commitSha) {\n lines.push(\"\");\n lines.push(`${pc.bold(\"Commit:\")} ${plan.commitSha}`);\n }\n lines.push(\"\");\n lines.push(pc.dim(\"─\".repeat(40)));\n lines.push(plan.body);\n return lines.join(\"\\n\");\n}\n\nfunction openEditor(path: string): Promise<void> {\n const editor = process.env.EDITOR ?? process.env.VISUAL ?? \"vi\";\n return new Promise((resolve, reject) => {\n const child = spawn(editor, [path], { stdio: \"inherit\" });\n child.on(\"error\", reject);\n child.on(\"close\", () => resolve());\n });\n}\n\nfunction runGit(args: string[]): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"git\", args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (c) => {\n stdout += String(c);\n });\n child.stderr.on(\"data\", (c) => {\n stderr += String(c);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => resolve({ code: code ?? 0, stdout, stderr }));\n });\n}\n\nexport function registerPlanCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const plan = program.command(\"plan\").description(\"Author and manage durable Markdown plans.\");\n\n // ── 02.4 read/create ──────────────────────────────────────────────\n plan\n .command(\"new\")\n .argument(\"<brief...>\", \"One-line description of the work.\")\n .option(\"--title <title>\", \"Plan title (defaults to the brief).\")\n .option(\"--no-edit\", \"Skip opening $EDITOR after creating the draft.\")\n .description(\"Create a draft plan and open it in $EDITOR.\")\n .action(async (briefParts: string[], opts: { title?: string; edit?: boolean }) => {\n await runSafely(async () => {\n const { lifecycle } = makeLifecycle();\n const namespace = await resolveNamespaceFrom();\n const brief = briefParts.join(\" \");\n const created = await lifecycle.create({\n namespace,\n title: opts.title ?? brief,\n brief,\n });\n console.log(`${pc.green(\"created\")} ${created.id} (${statusColor(created.status)})`);\n if (opts.edit !== false && process.stdin.isTTY) {\n await openEditor(created.path);\n // Re-read to validate the developer's edits.\n const { store } = makeLifecycle();\n await store.readPlan(created.id);\n console.log(pc.dim(\"saved and validated\"));\n }\n console.log(pc.dim(relative(process.cwd(), created.path)));\n });\n });\n\n plan\n .command(\"list\")\n .option(\"--status <status>\", \"Filter by status.\")\n .option(\"--all\", \"Include completed and abandoned plans.\")\n .description(\"List plans in the current namespace.\")\n .action(async (opts: { status?: string; all?: boolean }) => {\n await runSafely(async () => {\n const { store } = makeLifecycle();\n const namespace = await resolveNamespaceFrom();\n let plans = (await store.listPlans()).filter((p) => p.namespace === namespace);\n if (opts.status) plans = plans.filter((p) => p.status === opts.status);\n else if (!opts.all)\n plans = plans.filter((p) => p.status !== \"complete\" && p.status !== \"abandoned\");\n if (plans.length === 0) {\n console.log(pc.dim(\"no plans\"));\n return;\n }\n for (const p of plans) {\n console.log(`${statusColor(p.status).padEnd(20)} ${pc.bold(p.title)} ${pc.dim(p.id)}`);\n }\n });\n });\n\n plan\n .command(\"show\")\n .argument(\"<id>\")\n .description(\"Show a single plan.\")\n .action(async (id: string) => {\n await runSafely(async () => {\n const { store } = makeLifecycle();\n console.log(renderPlan(await store.readPlan(id)));\n });\n });\n\n plan\n .command(\"edit\")\n .argument(\"<id>\")\n .description(\"Open a plan in $EDITOR and validate on save.\")\n .action(async (id: string) => {\n await runSafely(async () => {\n const { store } = makeLifecycle();\n const existing = await store.readPlan(id);\n await openEditor(existing.path);\n await store.readPlan(id);\n console.log(pc.dim(\"saved and validated\"));\n });\n });\n\n // ── 02.5 lifecycle ────────────────────────────────────────────────\n plan\n .command(\"approve\")\n .argument(\"<id>\")\n .description(\"Promote a draft to approved (one active plan per namespace).\")\n .action(async (id: string) => {\n await runSafely(async () => {\n const { lifecycle } = makeLifecycle();\n const next = await lifecycle.approve(id);\n console.log(`${next.id} → ${statusColor(next.status)}`);\n });\n });\n\n plan\n .command(\"start\")\n .argument(\"<id>\")\n .description(\"Move an approved plan to executing.\")\n .action(async (id: string) => {\n await runSafely(async () => {\n const { lifecycle } = makeLifecycle();\n const next = await lifecycle.start(id);\n console.log(`${next.id} → ${statusColor(next.status)}`);\n });\n });\n\n plan\n .command(\"complete\")\n .argument(\"<id>\")\n .option(\"--commit <sha>\", \"Git commit the plan was completed in.\")\n .option(\"--notes <text>\", \"Completion notes.\")\n .description(\"Mark an executing plan complete.\")\n .action(async (id: string, opts: { commit?: string; notes?: string }) => {\n await runSafely(async () => {\n const { lifecycle } = makeLifecycle();\n const next = await lifecycle.complete(id, {\n ...(opts.commit ? { commitSha: opts.commit } : {}),\n ...(opts.notes ? { notes: opts.notes } : {}),\n });\n if (!opts.commit) console.log(pc.yellow(\"note: no --commit supplied\"));\n console.log(`${next.id} → ${statusColor(next.status)}`);\n });\n });\n\n plan\n .command(\"abandon\")\n .argument(\"<id>\")\n .option(\"--reason <text>\", \"Why the plan was abandoned.\")\n .description(\"Abandon a plan without completing it.\")\n .action(async (id: string, opts: { reason?: string }) => {\n await runSafely(async () => {\n const { lifecycle } = makeLifecycle();\n const next = await lifecycle.abandon(id, opts.reason ? { reason: opts.reason } : {});\n console.log(`${next.id} → ${statusColor(next.status)}`);\n });\n });\n\n plan\n .command(\"diff\")\n .argument(\"<id>\")\n .option(\"--from <ref>\", \"Git ref to compare from.\", \"HEAD\")\n .option(\"--to <ref>\", \"Git ref to compare to.\")\n .description(\"Show the git diff of a plan file between two revisions.\")\n .action(async (id: string, opts: { from: string; to?: string }) => {\n await runSafely(async () => {\n const { store } = makeLifecycle();\n const plan = await store.readPlan(id);\n const relPath = relative(process.cwd(), plan.path);\n const args = [\"diff\", opts.from, ...(opts.to ? [opts.to] : []), \"--\", relPath];\n const result = await runGit(args);\n if (result.stdout.trim().length === 0) {\n console.log(pc.dim(\"no changes\"));\n } else {\n process.stdout.write(result.stdout);\n }\n if (result.code !== 0 && result.stderr) process.stderr.write(result.stderr);\n });\n });\n\n // ── 02.7 policy ───────────────────────────────────────────────────\n plan\n .command(\"policy\")\n .argument(\"[mode]\", `One of: ${PLAN_POLICIES.join(\", \")}. Omit to read the current value.`)\n .description(\"Read or set the plan policy (off | suggest | required).\")\n .action(async (mode: string | undefined) => {\n await runSafely(async () => {\n if (mode === undefined) {\n console.log(await loadPlanPolicy());\n return;\n }\n if (!(PLAN_POLICIES as readonly string[]).includes(mode)) {\n throw new Error(`Invalid policy \"${mode}\". Use one of: ${PLAN_POLICIES.join(\", \")}.`);\n }\n await setPlanPolicy(mode as PlanPolicy);\n console.log(`${pc.green(\"plan policy\")} = ${mode}`);\n });\n });\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { resolveNamespaceFrom } from \"../../core/config-file.js\";\nimport { assessRisk } from \"../../risk/service.js\";\nimport type { Assessment, Evidence } from \"../../risk/types.js\";\n\nexport function registerRiskCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const risk = program.command(\"risk\").description(\"Assess evidence-backed change risk.\");\n\n risk\n .command(\"assess\")\n .option(\"--plan <id>\", \"Assess paths listed in a CodeBuddy plan.\")\n .option(\"--paths <paths>\", \"Comma-separated repo-relative paths to assess.\")\n .option(\"--git\", \"Assess staged, unstaged, and untracked git changes.\")\n .option(\"--limit <n>\", \"Maximum risk items to show.\", Number)\n .option(\"--json\", \"Print machine-readable JSON.\")\n .option(\"--explain\", \"Show evidence for each risk item.\")\n .description(\"Assess risk for a plan, explicit paths, or current git changes.\")\n .action(\n async (opts: {\n plan?: string;\n paths?: string;\n git?: boolean;\n limit?: number;\n json?: boolean;\n explain?: boolean;\n }) => {\n await runSafely(async () => {\n const namespace = await resolveNamespaceFrom();\n const assessment = await assessRisk({\n namespace,\n ...(opts.plan ? { planId: opts.plan } : {}),\n ...(opts.paths ? { paths: parsePaths(opts.paths) } : {}),\n ...(opts.git !== undefined ? { useGit: opts.git } : {}),\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n });\n if (opts.json) {\n console.log(JSON.stringify(assessment, null, 2));\n return;\n }\n printAssessment(assessment, opts.explain ?? false);\n });\n },\n );\n}\n\nfunction parsePaths(value: string): string[] {\n return value\n .split(\",\")\n .map((path) => path.trim())\n .filter(Boolean);\n}\n\nfunction printAssessment(assessment: Assessment, explain: boolean): void {\n if (assessment.items.length === 0) {\n console.log(pc.dim(\"no risk evidence found\"));\n return;\n }\n for (const item of assessment.items) {\n console.log(\n `${pc.bold(item.path)} score ${scoreColor(item.score)} category ${pc.cyan(item.category)}`,\n );\n console.log(` ${item.reason}`);\n if (explain) {\n for (const evidence of item.evidence) console.log(` ↳ ${formatEvidence(evidence)}`);\n } else {\n console.log(pc.dim(` ${item.evidence.length} evidence item(s)`));\n }\n }\n console.log(\n pc.dim(\n `\\n${assessment.stats.itemsProduced} item(s), ${assessment.stats.signalsRun} signal(s), ${assessment.stats.pathsConsidered} path(s) considered`,\n ),\n );\n}\n\nfunction scoreColor(score: number): string {\n if (score >= 75) return pc.red(String(score));\n if (score >= 50) return pc.yellow(String(score));\n return pc.green(String(score));\n}\n\nfunction formatEvidence(evidence: Evidence): string {\n switch (evidence.kind) {\n case \"memory_fact\":\n return `memory ${evidence.factId}: ${truncate(evidence.content, 90)}`;\n case \"git_commit\":\n return `commit ${evidence.sha.slice(0, 7)} ${evidence.ts}: ${evidence.message}`;\n case \"policy_rule\":\n return `policy ${evidence.ruleId}: ${evidence.pattern}`;\n case \"dependent_module\":\n return `dependent ${evidence.path} depth=${evidence.depth}`;\n case \"ci_failure\":\n return `ci ${evidence.runId} ${evidence.conclusion} ${evidence.ts}`;\n }\n}\n\nfunction truncate(value: string, max: number): string {\n return value.length <= max ? value : `${value.slice(0, max - 1)}…`;\n}\n","import { relative } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n AUTOMATION_MODES,\n CLIENT_ADAPTERS,\n parseClient,\n parseMode,\n supportedModes,\n} from \"../../clients/adapters.js\";\nimport { defaultRulesMode, installWorkflowRules } from \"../../templates/install.js\";\nimport {\n clientDisplayName,\n renderWorkflowTemplate,\n WORKFLOW_CLIENTS,\n type WorkflowClient,\n} from \"../../templates/workflow.js\";\n\n/**\n * Without `--mode`, follow the installed hooks: hook-driven rules when this\n * client's CodeBuddy hooks are present, agent-driven otherwise.\n */\nasync function resolveMode(client: WorkflowClient, value: string | undefined) {\n if (value) {\n const mode = parseMode(value);\n if (!supportedModes(CLIENT_ADAPTERS[client]).includes(mode)) {\n throw new Error(`${clientDisplayName(client)} does not support --mode ${mode}.`);\n }\n return mode;\n }\n return defaultRulesMode(client);\n}\n\n/**\n * `codebuddy rules` prints and installs the client workflow templates. Install\n * is file-based and visible: it writes a clearly-marked managed block into the\n * client's Markdown rules file (CLAUDE.md / AGENTS.md) and reports exactly what\n * changed. The user stays in control of their client config.\n */\nexport function registerRulesCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const rules = program\n .command(\"rules\")\n .description(\"Print or install the client workflow templates (CLAUDE.md / AGENTS.md).\");\n\n rules\n .command(\"show\")\n .option(\"--client <client>\", `One of: ${WORKFLOW_CLIENTS.join(\", \")}.`, \"claude\")\n .option(\"--mode <mode>\", \"agent or hooks (default: follows installed hooks).\")\n .description(\"Print the workflow template for a client.\")\n .action(async (opts: { client?: string; mode?: string }) => {\n await runSafely(async () => {\n const client = parseClient(opts.client);\n const mode = await resolveMode(client, opts.mode);\n if (mode === \"mcp-only\") {\n console.log(\"MCP-only mode installs no workflow rules.\");\n return;\n }\n console.log(renderWorkflowTemplate(client, mode));\n });\n });\n\n rules\n .command(\"install\")\n .option(\"--client <client>\", `One of: ${WORKFLOW_CLIENTS.join(\", \")}.`, \"claude\")\n .option(\"--path <file>\", \"Override the target rules file.\")\n .option(\n \"--mode <mode>\",\n `One of: ${AUTOMATION_MODES.join(\", \")} (default: follows installed hooks; mcp-only removes the block).`,\n )\n .description(\"Install/update the workflow template in the client's rules file (managed block).\")\n .action(async (opts: { client?: string; path?: string; mode?: string }) => {\n await runSafely(async () => {\n const client = parseClient(opts.client);\n const result = await installWorkflowRules({\n client,\n mode: await resolveMode(client, opts.mode),\n ...(opts.path ? { targetPath: opts.path } : {}),\n });\n const where = relative(process.cwd(), result.path) || result.path;\n console.log(\n `${actionLabel(result.action)} ${clientDisplayName(client)} workflow in ${where}`,\n );\n if (result.action !== \"unchanged\") {\n console.log(pc.dim(\" managed block between codebuddy:workflow markers; safe to re-run\"));\n }\n });\n });\n}\n\nfunction actionLabel(action: string): string {\n switch (action) {\n case \"created\":\n return pc.green(\"created\");\n case \"added\":\n return pc.green(\"added\");\n case \"updated\":\n return pc.cyan(\"updated\");\n case \"removed\":\n return pc.yellow(\"removed\");\n default:\n return pc.dim(\"unchanged\");\n }\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { resolveNamespaceFrom } from \"../../core/config-file.js\";\nimport { generateSuggestions } from \"../../suggest/engine.js\";\nimport type { Suggestion, SuggestionSeverity } from \"../../suggest/types.js\";\n\n/**\n * `codebuddy suggest` is read-only and file-based (risk, plan, map, memory),\n * so it runs without a database — the same lightweight path as risk/context.\n */\n\nfunction parsePaths(value: string): string[] {\n return value\n .split(\",\")\n .map((path) => path.trim())\n .filter(Boolean);\n}\n\nexport function registerSuggestCommand(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n program\n .command(\"suggest\")\n .option(\"--paths <paths>\", \"Comma-separated repo-relative paths to review.\")\n .option(\"--plan <id>\", \"Review the files listed in a plan.\")\n .option(\"--git\", \"Review current git changes.\")\n .option(\"--limit <n>\", \"Maximum suggestions to show.\", Number)\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"Suggest evidence-backed, read-only code-quality improvements.\")\n .action(\n async (opts: {\n paths?: string;\n plan?: string;\n git?: boolean;\n limit?: number;\n json?: boolean;\n }) => {\n await runSafely(async () => {\n const namespace = await resolveNamespaceFrom();\n const result = await generateSuggestions({\n namespace,\n ...(opts.paths ? { paths: parsePaths(opts.paths) } : {}),\n ...(opts.plan ? { planId: opts.plan } : {}),\n ...(opts.git !== undefined ? { useGit: opts.git } : {}),\n ...(opts.limit !== undefined ? { limit: opts.limit } : {}),\n });\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n printSuggestions(result.suggestions);\n console.log(\n pc.dim(\n `\\n${result.stats.produced} suggestion(s) across ${result.stats.pathsConsidered} path(s)`,\n ),\n );\n });\n },\n );\n}\n\nfunction printSuggestions(suggestions: Suggestion[]): void {\n if (suggestions.length === 0) {\n console.log(pc.dim(\"no suggestions — nothing high-signal to report\"));\n return;\n }\n for (const suggestion of suggestions) {\n console.log(`${severityBadge(suggestion.severity)} ${pc.bold(suggestion.title)}`);\n console.log(` ${suggestion.detail}`);\n for (const evidence of suggestion.evidence) {\n console.log(pc.dim(` ↳ ${evidence.kind}: ${evidence.detail}`));\n }\n if (suggestion.commandHint) console.log(pc.dim(` → ${suggestion.commandHint}`));\n }\n}\n\nfunction severityBadge(severity: SuggestionSeverity): string {\n switch (severity) {\n case \"high\":\n return pc.red(\"[high]\");\n case \"medium\":\n return pc.yellow(\"[med ]\");\n case \"low\":\n return pc.cyan(\"[low ]\");\n default:\n return pc.dim(\"[info]\");\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { extractSymbolTable, supportsSymbols } from \"../../indexer/symbols.js\";\n\n/**\n * `codebuddy symbols <path>` inspects a file's symbol table — the basis for\n * symbol-level context (Roadmap N.3, shipped). File-based; no database.\n */\nexport function registerSymbolsCommand(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n program\n .command(\"symbols\")\n .argument(\"<path>\", \"Repo-relative or absolute path to a code file.\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"List a file's top-level symbols (functions, classes, types, exports).\")\n .action(async (path: string, opts: { json?: boolean }) => {\n await runSafely(async () => {\n if (!supportsSymbols(path)) {\n console.log(pc.dim(`no symbol extraction for ${path} (unsupported language)`));\n return;\n }\n const content = await readFile(resolve(path), \"utf8\");\n const table = extractSymbolTable(content);\n\n if (opts.json) {\n console.log(JSON.stringify({ path, symbols: table }, null, 2));\n return;\n }\n\n if (table.length === 0) {\n console.log(pc.dim(\"no top-level symbols found\"));\n return;\n }\n for (const symbol of table) {\n const badge = symbol.exported ? pc.green(\"export\") : pc.dim(\"local \");\n console.log(\n `${badge} ${pc.cyan(symbol.kind.padEnd(9))} ${pc.bold(symbol.name)} ${pc.dim(`L${symbol.startLine}-${symbol.endLine}`)}`,\n );\n }\n console.log(pc.dim(`\\n${table.length} symbol(s)`));\n });\n });\n}\n","import { basename } from \"node:path\";\nimport { confirm, isCancel, log, note, password, select, spinner, text } from \"@clack/prompts\";\nimport pc from \"picocolors\";\nimport { initProjectScaffold, readConfigFile, writeConfigFile } from \"../../core/config-file.js\";\nimport { mergeGlobalConfig, readGlobalConfig } from \"../../core/global-config.js\";\nimport { bootstrapDatabase } from \"../../db/bootstrap.js\";\nimport { createDatabaseClient, pingDatabase } from \"../../db/client.js\";\nimport { runMigrations } from \"../../db/migrator.js\";\nimport { indexRepository } from \"../../indexer/engine.js\";\nimport { setupGraphify } from \"../../integrations/graphify.js\";\nimport { writeProjectMcpConfig } from \"../../integrations/project-mcp.js\";\nimport { installWorkflowRules } from \"../../templates/install.js\";\nimport { installClaudeEntry } from \"./claude-desktop.js\";\nimport { installCodexEntry } from \"./codex.js\";\nimport {\n isDockerDaemonRunning,\n tryStartDockerDesktop,\n waitForDockerDaemon,\n} from \"./docker-autostart.js\";\nimport { postgresUp } from \"./postgres-docker.js\";\n\nexport type UseCommandOptions = {\n namespace?: string;\n postgresUrl?: string;\n skipClaude?: boolean;\n skipCodex?: boolean;\n graphify?: boolean;\n useDocker?: boolean;\n};\n\nfunction bail(): never {\n log.warn(\"Aborted.\");\n process.exit(1);\n}\n\nfunction unwrap<T>(value: T | symbol): T {\n if (isCancel(value)) bail();\n return value as T;\n}\n\nasync function pingOnce(databaseUrl: string): Promise<boolean> {\n const client = createDatabaseClient({ postgresUrl: databaseUrl });\n try {\n return await pingDatabase(client);\n } catch {\n return false;\n } finally {\n await client.close().catch(() => undefined);\n }\n}\n\nfunction sanitizeNamespace(input: string): string {\n return input.replace(/[^a-zA-Z0-9_.:-]/g, \"-\").slice(0, 128) || \"default\";\n}\n\nconst DEFAULT_DB_URL = \"postgres://codebuddy:codebuddy@localhost:5432/codebuddy\";\n\n/**\n * One-command setup for a project folder. Reuses any HF token + Postgres URL\n * the user has already saved in ~/.codebuddy/global.json; prompts only for\n * what is genuinely missing. Auto-starts Docker Desktop if needed, brings up\n * the bundled Postgres container, applies migrations, and (unless suppressed)\n * registers per-folder Claude Desktop and Codex entries.\n */\nexport async function runUseCommand(options: UseCommandOptions = {}): Promise<void> {\n const sigintHandler = () => bail();\n process.on(\"SIGINT\", sigintHandler);\n\n try {\n const folderName = basename(process.cwd());\n const namespace = sanitizeNamespace(options.namespace ?? folderName);\n await initProjectScaffold();\n const graphifyEnabled =\n options.graphify ??\n unwrap(\n await confirm({\n message: \"Set up Graphify for richer architecture context?\",\n initialValue: true,\n }),\n );\n note(\n `Project folder: ${pc.bold(process.cwd())}\\nNamespace: ${pc.bold(namespace)}`,\n \"codebuddy use\",\n );\n\n const stored = await readGlobalConfig();\n\n // ── Embeddings: local by default; hosted only when chosen ─────────\n const projectConfig = await readConfigFile();\n let embeddings = projectConfig.provider?.type;\n if (embeddings) {\n log.info(`Embeddings: ${embeddings} (change with ${pc.cyan(\"codebuddy models use\")}).`);\n } else {\n embeddings = unwrap(\n await select({\n message: \"Where should memory embeddings run?\",\n initialValue: \"local\" as const,\n options: [\n {\n value: \"local\" as const,\n label: \"On this machine\",\n hint: \"recommended · no key · ~90 MB once\",\n },\n {\n value: \"openrouter\" as const,\n label: \"OpenRouter\",\n hint: \"OPENROUTER_API_KEY · free models listed\",\n },\n {\n value: \"huggingface\" as const,\n label: \"Hugging Face\",\n hint: \"HF_TOKEN · small free monthly credit\",\n },\n ],\n }),\n );\n if (embeddings === \"openrouter\" && !process.env.OPENROUTER_API_KEY) {\n log.warn(\n \"Export OPENROUTER_API_KEY before your agent starts; keys are never stored in config.\",\n );\n }\n }\n\n let hfToken: string | undefined;\n if (embeddings !== \"huggingface\") {\n hfToken = process.env.HF_TOKEN ?? stored.hfToken;\n } else if (process.env.HF_TOKEN) {\n hfToken = process.env.HF_TOKEN;\n log.info(\"Using HF_TOKEN from environment.\");\n } else if (stored.hfToken) {\n hfToken = stored.hfToken;\n log.info(`Reusing saved Hugging Face token (${pc.dim(\"~/.codebuddy/global.json\")}).`);\n } else {\n hfToken = unwrap(\n await password({\n message: \"Hugging Face token (for hosted embeddings)\",\n }),\n );\n if (!hfToken) log.warn(\"No token: hosted embeddings will fail until HF_TOKEN is set.\");\n }\n\n // ── Postgres URL ────────────────────────────────────────────────\n const initialUrl =\n options.postgresUrl ?? process.env.DATABASE_URL ?? stored.databaseUrl ?? DEFAULT_DB_URL;\n const databaseUrl = unwrap(\n await text({\n message: \"Postgres URL (press Enter to accept)\",\n initialValue: initialUrl,\n validate: (value) => (value && value.length > 0 ? undefined : \"Postgres URL is required.\"),\n }),\n );\n\n // ── Make sure Postgres is reachable; spin Docker up if not ──────\n const dbSpinner = spinner();\n dbSpinner.start(\"Checking Postgres\");\n let connected = await pingOnce(databaseUrl);\n if (connected) dbSpinner.stop(\"Local Postgres reachable.\");\n\n if (!connected && databaseUrl === DEFAULT_DB_URL) {\n dbSpinner.stop(\"Postgres unreachable on the default local URL.\");\n }\n\n const shouldUseDocker =\n !connected &&\n databaseUrl === DEFAULT_DB_URL &&\n (options.useDocker ??\n unwrap(\n await confirm({\n message: \"Postgres is unavailable. Start the bundled Docker database now?\",\n initialValue: true,\n }),\n ));\n\n if (shouldUseDocker) {\n if (!(await isDockerDaemonRunning())) {\n const dockerSpinner = spinner();\n dockerSpinner.start(\"Starting Docker Desktop\");\n await tryStartDockerDesktop();\n const ready = await waitForDockerDaemon(60_000);\n if (!ready) {\n dockerSpinner.stop(\"Docker daemon did not start in 60s. Aborting.\");\n bail();\n }\n dockerSpinner.stop(\"Docker daemon is up.\");\n }\n const composeSpinner = spinner();\n composeSpinner.start(\"docker compose up -d\");\n try {\n const result = await postgresUp();\n if (result.code === 0) {\n composeSpinner.stop(\"Postgres container started.\");\n for (let attempt = 0; attempt < 12 && !connected; attempt++) {\n await new Promise((resolve) => setTimeout(resolve, 500));\n connected = await pingOnce(databaseUrl);\n }\n if (!connected) {\n log.warn(\"Container running but Postgres did not accept connections in time.\");\n }\n } else {\n composeSpinner.stop(`docker compose failed: ${result.stderr || result.stdout}`);\n }\n } catch (error) {\n composeSpinner.stop(`docker compose failed: ${(error as Error).message}`);\n }\n } else if (!connected) {\n dbSpinner.stop(connected ? \"Postgres reachable.\" : \"Postgres unreachable at this URL.\");\n log.warn(\n \"Local Postgres is required. Start it, set DATABASE_URL, pass --postgres-url, or allow the bundled Docker database.\",\n );\n bail();\n }\n\n if (!connected) bail();\n\n // ── pgvector + migrations ───────────────────────────────────────\n const migrateSpinner = spinner();\n migrateSpinner.start(\"Enabling pgvector + applying migrations\");\n {\n const client = createDatabaseClient({ postgresUrl: databaseUrl });\n try {\n await bootstrapDatabase(client.sql);\n await runMigrations(client);\n migrateSpinner.stop(\"Database ready.\");\n } catch (error) {\n migrateSpinner.stop(`Migration error: ${(error as Error).message}`);\n bail();\n } finally {\n await client.close().catch(() => undefined);\n }\n }\n\n // ── Persist defaults so the next project is even faster ─────────\n await mergeGlobalConfig({\n ...(hfToken ? { hfToken } : {}),\n databaseUrl,\n installPath: process.argv[1] ?? undefined,\n });\n\n const existingConfig = await readConfigFile();\n const indexSpinner = spinner();\n indexSpinner.start(\"Indexing the existing repository\");\n try {\n const result = await indexRepository({ repositoryRoot: process.cwd() });\n indexSpinner.stop(`Repository indexed (${result.totalIndexed} files).`);\n } catch (error) {\n indexSpinner.stop(`Repository indexing skipped: ${(error as Error).message}`);\n }\n const graphifySetup = graphifyEnabled\n ? await setupGraphify({ repositoryRoot: process.cwd() })\n : null;\n const graphifyConfigured = graphifySetup?.available === true && graphifySetup.generated;\n await writeConfigFile({\n ...existingConfig,\n postgresUrl: databaseUrl,\n namespace,\n provider: {\n ...existingConfig.provider,\n type: embeddings,\n ...(hfToken ? { apiKey: hfToken } : {}),\n },\n tokenBudget: existingConfig.tokenBudget ?? 4000,\n graphify: { enabled: graphifyConfigured, graphPath: \"graphify-out/graph.json\" },\n });\n\n const graphifyMessage =\n graphifySetup?.message ?? \"Graphify disabled; CodeBuddy MCP remains available.\";\n await writeProjectMcpConfig({\n repositoryRoot: process.cwd(),\n namespace,\n graphify: graphifyConfigured,\n ...(graphifySetup?.graphPath ? { graphPath: graphifySetup.graphPath } : {}),\n });\n await installWorkflowRules({ client: \"claude\", projectRoot: process.cwd() });\n await installWorkflowRules({ client: \"codex\", projectRoot: process.cwd() });\n\n // ── Wire Claude Desktop unless suppressed ───────────────────────\n if (!options.skipClaude) {\n try {\n const install = await installClaudeEntry({\n namespace,\n projectRoot: process.cwd(),\n ...(hfToken ? { hfToken } : {}),\n databaseUrl,\n });\n log.success(\n `Registered ${pc.bold(install.serverKey)} in Claude Desktop. Restart with ⌘Q to activate.`,\n );\n } catch (error) {\n log.warn(`Claude Desktop registration skipped: ${(error as Error).message}`);\n }\n }\n\n // ── Wire Codex unless suppressed ────────────────────────────────\n if (!options.skipCodex) {\n try {\n const install = await installCodexEntry({\n namespace,\n projectRoot: process.cwd(),\n ...(hfToken ? { hfToken } : {}),\n databaseUrl,\n });\n log.success(\n `Registered ${pc.bold(install.serverKey)} in Codex. Restart Codex to activate.`,\n );\n } catch (error) {\n log.warn(`Codex registration skipped: ${(error as Error).message}`);\n }\n }\n\n note(\n [\n `${pc.green(\"✓\")} CodeBuddy is ready for ${pc.bold(folderName)}.`,\n `${pc.green(\"✓\")} Scaffolded ${pc.cyan(\".codebuddy/policies.yaml\")} for project-specific guardrails.`,\n `${pc.green(\"✓\")} ${graphifyMessage}`,\n `${pc.green(\"✓\")} Added agent workflow instructions to ${pc.cyan(\"CLAUDE.md\")} and ${pc.cyan(\"AGENTS.md\")}.`,\n ``,\n `Next:`,\n ` 1. Restart Claude Desktop and Codex.`,\n ` 2. Ask Claude or Codex to use the ${pc.cyan(\"context_pack\")} tool for each coding task.`,\n ` 3. Indexing, Graphify, Markdown memory import, and embeddings now update automatically while the MCP server is running.`,\n ` 4. Run ${pc.cyan(\"codebuddy doctor\")} or ${pc.cyan(\"codebuddy db doctor\")} if you want a full health check.`,\n ``,\n `Manage:`,\n ` codebuddy claude list ${pc.dim(\"# see every project wired up\")}`,\n ` codebuddy codex list ${pc.dim(\"# see Codex entries\")}`,\n ` codebuddy db test ${pc.dim(\"# quick Postgres connectivity check\")}`,\n ` codebuddy claude remove codebuddy-${namespace}`,\n ` codebuddy codex remove codebuddy-${namespace}`,\n ` codebuddy postgres down ${pc.dim(\"# stop the DB (data preserved)\")}`,\n ].join(\"\\n\"),\n \"Done\",\n );\n } finally {\n process.off(\"SIGINT\", sigintHandler);\n }\n}\n","import { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { z } from \"zod\";\n\n/**\n * User-level configuration shared across all projects on this machine.\n * Stored at ~/.codebuddy/global.json with 0600 permissions so the HF token\n * is never world-readable. Per-project namespace is NOT stored here — that\n * is implicit in the directory the user runs `codebuddy use` from.\n */\n\nexport const GLOBAL_DIR = \".codebuddy\";\nexport const GLOBAL_FILE = \"global.json\";\n\nconst globalConfigSchema = z.object({\n hfToken: z.string().min(1).optional(),\n databaseUrl: z.string().min(1).optional(),\n // Where the codebuddy install lives on this machine. Cached so future\n // `codebuddy use` calls in unrelated projects can find the CLI entry\n // without re-resolving via process.argv every time.\n installPath: z.string().optional(),\n});\n\nexport type GlobalConfig = z.infer<typeof globalConfigSchema>;\n\nexport function globalConfigPath(home = homedir()): string {\n return join(home, GLOBAL_DIR, GLOBAL_FILE);\n}\n\nexport async function readGlobalConfig(home = homedir()): Promise<GlobalConfig> {\n const path = globalConfigPath(home);\n try {\n const raw = await readFile(path, \"utf8\");\n return globalConfigSchema.parse(JSON.parse(raw));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw error;\n }\n}\n\nexport async function writeGlobalConfig(\n next: GlobalConfig,\n home = homedir(),\n): Promise<{ path: string }> {\n const path = globalConfigPath(home);\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n await writeFile(path, `${JSON.stringify(next, null, 2)}\\n`, { mode: 0o600 });\n await chmod(path, 0o600);\n return { path };\n}\n\nexport async function mergeGlobalConfig(\n patch: GlobalConfig,\n home = homedir(),\n): Promise<{ path: string; merged: GlobalConfig }> {\n const current = await readGlobalConfig(home);\n const merged: GlobalConfig = { ...current, ...patch };\n const { path } = await writeGlobalConfig(merged, home);\n return { path, merged };\n}\n","import { spawn } from \"node:child_process\";\n\n/**\n * `docker info` exits 0 when the daemon is reachable, non-zero otherwise.\n */\nexport async function isDockerDaemonRunning(): Promise<boolean> {\n return new Promise((resolve) => {\n const child = spawn(\"docker\", [\"info\"], { stdio: \"ignore\" });\n child.on(\"error\", () => resolve(false));\n child.on(\"close\", (code) => resolve(code === 0));\n });\n}\n\n/**\n * Try to start Docker Desktop on macOS. No-op on other platforms because\n * Linux Docker is typically a system service the user has to manage.\n */\nexport async function tryStartDockerDesktop(): Promise<{ started: boolean }> {\n if (process.platform !== \"darwin\") return { started: false };\n return new Promise((resolve) => {\n const child = spawn(\"open\", [\"-ga\", \"Docker\"], { stdio: \"ignore\" });\n child.on(\"error\", () => resolve({ started: false }));\n child.on(\"close\", (code) => resolve({ started: code === 0 }));\n });\n}\n\n/**\n * Wait up to `timeoutMs` for the Docker daemon to accept connections.\n * Polls `docker info` every second. Returns true if it came up in time.\n */\nexport async function waitForDockerDaemon(timeoutMs = 60_000): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (await isDockerDaemonRunning()) return true;\n await new Promise((resolve) => setTimeout(resolve, 1_000));\n }\n return false;\n}\n","import { relative } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { type WorklogEntry, WorklogStore } from \"../../worklog/store.js\";\n\n/**\n * The worklog is file-based Markdown under `.codebuddy/worklog/`; these\n * commands need no database. Entries are written automatically after turns\n * that changed files, so a new chat can see what earlier chats did.\n */\nexport function registerWorklogCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const worklog = program\n .command(\"worklog\")\n .description(\"Inspect the cross-chat worklog of completed turns.\");\n\n worklog\n .command(\"list\", { isDefault: true })\n .option(\"--limit <n>\", \"Maximum entries to show.\", \"20\")\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"List worklog entries, newest first.\")\n .action(async (opts: { limit: string; json?: boolean }) => {\n await runSafely(async () => {\n const entries = (await new WorklogStore().list()).slice(0, Number(opts.limit) || 20);\n if (opts.json) {\n console.log(JSON.stringify(entries, null, 2));\n return;\n }\n if (entries.length === 0) {\n console.log(pc.dim(\"no worklog entries yet\"));\n return;\n }\n for (const entry of entries) console.log(renderRow(entry));\n });\n });\n\n worklog\n .command(\"show\")\n .argument(\"<id>\")\n .description(\"Show a single worklog entry.\")\n .action(async (id: string) => {\n await runSafely(async () => {\n console.log(renderEntry(await new WorklogStore().read(id)));\n });\n });\n\n worklog\n .command(\"latest\")\n .description(\"Show the most recent worklog entry.\")\n .action(async () => {\n await runSafely(async () => {\n const [entry] = await new WorklogStore().list();\n console.log(entry ? renderEntry(entry) : pc.dim(\"no worklog entries yet\"));\n });\n });\n}\n\nfunction renderRow(entry: WorklogEntry): string {\n const summary = entry.summary.replace(/\\s+/g, \" \");\n const short = summary.length <= 70 ? summary : `${summary.slice(0, 69)}…`;\n return `${pc.dim(entry.createdAt.slice(0, 16))} ${pc.dim(entry.id)} ${short} ${pc.dim(`(${entry.files.length} file(s))`)}`;\n}\n\nfunction renderEntry(entry: WorklogEntry): string {\n const lines = [`${pc.bold(entry.id)} ${pc.dim(entry.createdAt)} ${pc.dim(entry.namespace)}`];\n if (entry.sourceSessionId) lines.push(`${pc.bold(\"session:\")} ${entry.sourceSessionId}`);\n if (entry.sourcePlanId) lines.push(`${pc.bold(\"plan:\")} ${entry.sourcePlanId}`);\n if (entry.commitSha) lines.push(`${pc.bold(\"commit:\")} ${entry.commitSha}`);\n if (entry.files.length > 0) lines.push(`${pc.bold(\"files:\")} ${entry.files.join(\", \")}`);\n if (entry.verification.length > 0) {\n lines.push(`${pc.bold(\"verification:\")}`, ...entry.verification.map((line) => ` - ${line}`));\n }\n if (entry.savedMemory.length > 0) {\n lines.push(`${pc.bold(\"saved memory:\")} ${entry.savedMemory.join(\", \")}`);\n }\n if (entry.queuedForReview.length > 0) {\n lines.push(`${pc.bold(\"queued for review:\")} ${entry.queuedForReview.join(\", \")}`);\n }\n lines.push(\"\", entry.summary, \"\", pc.dim(relative(process.cwd(), entry.path)));\n return lines.join(\"\\n\");\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { setZvecEnabled } from \"../../core/config-file.js\";\nimport { buildZvecIndex, DEFAULT_ZVEC_MODEL, zvecStatus } from \"../../retrieval/zvec.js\";\n\n/**\n * Optional zvec-grep semantic retrieval. CodeBuddy never builds a zg index on\n * its own; `codebuddy zvec index` is the explicit step.\n */\nexport function registerZvecCommands(\n program: Command,\n runSafely: (fn: () => Promise<void>) => Promise<void>,\n): void {\n const zvec = program\n .command(\"zvec\")\n .description(\"Optional zvec-grep semantic file discovery for the context tools.\");\n\n zvec\n .command(\"status\", { isDefault: true })\n .option(\"--json\", \"Print machine-readable JSON.\")\n .description(\"Show whether zvec-grep is enabled, installed, supported and indexed.\")\n .action(async (opts: { json?: boolean }) => {\n await runSafely(async () => {\n const report = await zvecStatus(process.cwd());\n if (opts.json) {\n console.log(JSON.stringify(report, null, 2));\n return;\n }\n const mark = (ok: boolean) => (ok ? pc.green(\"yes\") : pc.yellow(\"no\"));\n console.log(`enabled: ${mark(report.enabled)}`);\n console.log(`binary: ${report.binary}`);\n console.log(\n `version: ${report.version ?? pc.yellow(\"not found\")}${report.version && !report.supported ? pc.yellow(\" (unsupported; need 0.2.x)\") : \"\"}`,\n );\n console.log(`index ready: ${mark(report.indexReady)}`);\n console.log(\n `zg server: ${report.server} ${pc.dim(\"(running = faster queries; optional)\")}`,\n );\n console.log(`status: ${report.reason}`);\n if (!report.version) console.log(pc.dim(\"install: npm install -g @zvec/zvec-grep\"));\n else if (report.supported && !report.indexReady)\n console.log(pc.dim(\"next: codebuddy zvec index\"));\n else if (report.indexReady && !report.enabled)\n console.log(pc.dim(\"next: codebuddy zvec enable\"));\n });\n });\n\n zvec\n .command(\"index\")\n .option(\"--model <model>\", \"Embedding model for a new index.\", DEFAULT_ZVEC_MODEL)\n .option(\"--rebuild\", \"Rebuild the index from scratch (e.g. after changing model).\")\n .description(\"Build or refresh the zg index for this repository (explicit; never automatic).\")\n .action(async (opts: { model: string; rebuild?: boolean }) => {\n await runSafely(async () => {\n const code = await buildZvecIndex(process.cwd(), {\n model: opts.model,\n ...(opts.rebuild ? { rebuild: true } : {}),\n });\n if (code !== 0) throw new Error(`zg index exited with code ${code}`);\n console.log(\n pc.dim(\"tip: add .zvec-grep/ to .gitignore; enable with `codebuddy zvec enable`\"),\n );\n });\n });\n\n zvec\n .command(\"enable\")\n .description(\"Use zvec-grep candidates in context_pack / context_before_edit.\")\n .action(async () => {\n await runSafely(async () => {\n await setZvecEnabled(true);\n console.log(\n `${pc.green(\"enabled\")} zvec-grep retrieval (falls back to keywords if unavailable)`,\n );\n });\n });\n\n zvec\n .command(\"disable\")\n .description(\"Stop using zvec-grep; keyword ranking only.\")\n .action(async () => {\n await runSafely(async () => {\n await setZvecEnabled(false);\n console.log(`${pc.yellow(\"disabled\")} zvec-grep retrieval`);\n });\n });\n}\n"],"mappings":"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","names":["pc","constants","access","join","map","join","access","constants","resolve","runSafely","mkdir","readFile","dirname","join","resolve","join","readFile","mkdir","dirname","resolve","pc","rm","join","resolve","readFile","rm","join","resolve","readFile","dirname","join","resolve","mkdir","readFile","dirname","readFile","plugin","text","mkdir","dirname","join","resolve","dirname","readFile","readFile","dirname","join","resolve","join","resolve","plugin","dirname","readFile","mkdir","readFile","dirname","join","resolve","join","resolve","readFile","mkdir","dirname","resolve","join","content","rm","readFile","join","rm","resolve","later","access","join","resolve","access","mkdir","readFile","rm","dirname","join","resolve","join","resolve","access","servers","mkdir","dirname","rm","json","readFile","existsSync","mkdir","readFile","dirname","join","join","existsSync","readFile","mkdir","dirname","mkdir","readFile","homedir","dirname","join","homedir","join","readFile","indent","mkdir","dirname","join","access","resolve","readFile","join","resolve","text","join","servers","readFile","resolve","runSafely","pc","printReport","note","pc","parsePaths","runSafely","pc","spawn","pc","text","resolve","spawn","runSafely","pc","resolve","pc","readFile","dirname","join","resolve","resolve","join","readFile","dirname","runSafely","pc","pc","runSafely","pc","spawn","relative","pc","runSafely","relative","pc","spawn","pc","pc","runSafely","pc","runSafely","pc","writeFile","spawn","existsSync","dirname","resolve","fileURLToPath","resolve","writeFile","pc","runSafely","pc","pc","runSafely","pc","spawn","relative","pc","runSafely","pc","relative","spawn","existsSync","join","spinner","pc","row","KEY_ENV","text","pc","spinner","join","existsSync","runSafely","spawn","relative","pc","pc","openEditor","resolve","spawn","runSafely","relative","plan","pc","runSafely","parsePaths","pc","scoreColor","truncate","relative","pc","runSafely","relative","pc","pc","parsePaths","runSafely","pc","severityBadge","readFile","resolve","pc","runSafely","pc","readFile","resolve","basename","confirm","isCancel","log","note","password","spinner","text","pc","mkdir","readFile","writeFile","homedir","dirname","join","z","spawn","resolve","bail","log","unwrap","isCancel","pingOnce","basename","confirm","note","pc","password","text","spinner","resolve","relative","pc","runSafely","pc","renderRow","relative","pc","runSafely","ok","pc","row","pc","ok","warn"]}
|