codealmanac 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMMERCIAL.md +9 -0
- package/LICENSE +133 -21
- package/README.md +2 -2
- package/dist/{agents-4Y7X24WW.js → agents-HYRWRHRX.js} +4 -4
- package/dist/{chunk-TT6ZP4GS.js → chunk-2BNDNGUR.js} +8 -4
- package/dist/{chunk-TT6ZP4GS.js.map → chunk-2BNDNGUR.js.map} +1 -1
- package/dist/{chunk-P5WGG4FJ.js → chunk-3E7JNMTZ.js} +28 -3
- package/dist/chunk-3E7JNMTZ.js.map +1 -0
- package/dist/{chunk-CW4HRLMS.js → chunk-DW32TL5W.js} +53 -11
- package/dist/chunk-DW32TL5W.js.map +1 -0
- package/dist/{chunk-UU6FBRQO.js → chunk-GPFVEF6V.js} +24 -6
- package/dist/chunk-GPFVEF6V.js.map +1 -0
- package/dist/{chunk-TILAKDN6.js → chunk-HJ3WREGP.js} +2 -2
- package/dist/{chunk-BF2J4XTC.js → chunk-J7DNV2DH.js} +219 -26
- package/dist/chunk-J7DNV2DH.js.map +1 -0
- package/dist/{chunk-H6QKCB7M.js → chunk-K2JBCB7R.js} +43 -7
- package/dist/chunk-K2JBCB7R.js.map +1 -0
- package/dist/{chunk-MRRX4UQB.js → chunk-ODJAAJGZ.js} +2 -2
- package/dist/{chunk-447U3GQJ.js → chunk-PDFS5VFE.js} +17 -5
- package/dist/chunk-PDFS5VFE.js.map +1 -0
- package/dist/{chunk-QRK3JLFX.js → chunk-VXDPUOQ5.js} +381 -126
- package/dist/chunk-VXDPUOQ5.js.map +1 -0
- package/dist/{cli-MYMZ66EN.js → cli-MKXCNEMW.js} +14 -14
- package/dist/codealmanac.js +1 -1
- package/dist/{config-ML2RCR7J.js → config-F7FKEQ7F.js} +3 -3
- package/dist/doctor-37UH3HT5.js +17 -0
- package/dist/{hook-2NP3UE7U.js → hook-4SVX446M.js} +4 -2
- package/dist/{register-commands-XTK2G2FB.js → register-commands-2F6SXLDI.js} +28 -19
- package/dist/register-commands-2F6SXLDI.js.map +1 -0
- package/dist/uninstall-C62ZOK32.js +17 -0
- package/dist/{update-P2IPG7RO.js → update-2UGOFN5C.js} +3 -3
- package/package.json +4 -3
- package/dist/chunk-447U3GQJ.js.map +0 -1
- package/dist/chunk-BF2J4XTC.js.map +0 -1
- package/dist/chunk-CW4HRLMS.js.map +0 -1
- package/dist/chunk-H6QKCB7M.js.map +0 -1
- package/dist/chunk-P5WGG4FJ.js.map +0 -1
- package/dist/chunk-QRK3JLFX.js.map +0 -1
- package/dist/chunk-UU6FBRQO.js.map +0 -1
- package/dist/doctor-W5KQQLAX.js +0 -17
- package/dist/register-commands-XTK2G2FB.js.map +0 -1
- package/dist/uninstall-N7JY7ZV2.js +0 -15
- /package/dist/{agents-4Y7X24WW.js.map → agents-HYRWRHRX.js.map} +0 -0
- /package/dist/{chunk-TILAKDN6.js.map → chunk-HJ3WREGP.js.map} +0 -0
- /package/dist/{chunk-MRRX4UQB.js.map → chunk-ODJAAJGZ.js.map} +0 -0
- /package/dist/{cli-MYMZ66EN.js.map → cli-MKXCNEMW.js.map} +0 -0
- /package/dist/{config-ML2RCR7J.js.map → config-F7FKEQ7F.js.map} +0 -0
- /package/dist/{doctor-W5KQQLAX.js.map → doctor-37UH3HT5.js.map} +0 -0
- /package/dist/{hook-2NP3UE7U.js.map → hook-4SVX446M.js.map} +0 -0
- /package/dist/{uninstall-N7JY7ZV2.js.map → uninstall-C62ZOK32.js.map} +0 -0
- /package/dist/{update-P2IPG7RO.js.map → update-2UGOFN5C.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent/providers/codex-instructions.ts","../src/commands/setup.ts","../src/commands/setup/install-path.ts","../src/commands/setup/next-steps.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const CODEX_INSTRUCTIONS_START = \"<!-- codealmanac:start -->\";\nexport const CODEX_INSTRUCTIONS_END = \"<!-- codealmanac:end -->\";\n\nconst CODEX_INSTRUCTIONS_BODY = `${CODEX_INSTRUCTIONS_START}\n## codealmanac\n\nUse codealmanac before answering codebase questions:\n- Search the wiki for relevant context.\n- Read matching pages before making claims about the codebase.\n- Update the wiki when implementation decisions, workflows, invariants, or gotchas change.\n\n${CODEX_INSTRUCTIONS_END}`;\n\nexport async function ensureCodexInstructions(\n codexDir: string,\n): Promise<boolean> {\n await mkdir(codexDir, { recursive: true });\n const agentsPath = await resolveCodexAgentsPath(codexDir);\n let existing = \"\";\n if (existsSync(agentsPath)) {\n existing = await readFile(agentsPath, \"utf8\");\n }\n\n const next = upsertManagedBlock(\n existing,\n CODEX_INSTRUCTIONS_START,\n CODEX_INSTRUCTIONS_END,\n CODEX_INSTRUCTIONS_BODY,\n );\n if (next === existing) return false;\n await writeFile(agentsPath, next, \"utf8\");\n return true;\n}\n\nexport async function resolveCodexAgentsPath(\n codexDir: string,\n): Promise<string> {\n const overridePath = path.join(codexDir, \"AGENTS.override.md\");\n if (existsSync(overridePath)) {\n try {\n const body = await readFile(overridePath, \"utf8\");\n if (body.trim().length > 0) return overridePath;\n } catch {\n // Fall through to AGENTS.md and let the read/write surface errors.\n }\n }\n return path.join(codexDir, \"AGENTS.md\");\n}\n\nexport function hasCodexInstructions(contents: string): boolean {\n return (\n contents.includes(CODEX_INSTRUCTIONS_START) &&\n contents.includes(CODEX_INSTRUCTIONS_END)\n );\n}\n\nfunction upsertManagedBlock(\n contents: string,\n start: string,\n end: string,\n block: string,\n): string {\n const startIndex = contents.indexOf(start);\n const endIndex = contents.indexOf(end);\n if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {\n const afterEnd = endIndex + end.length;\n return `${contents.slice(0, startIndex)}${block}${contents.slice(afterEnd)}`;\n }\n\n const sep =\n contents.length === 0 ? \"\" : contents.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return `${contents}${sep}${block}\\n`;\n}\n","import { existsSync } from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport {\n copyFile,\n mkdir,\n readFile,\n writeFile,\n} from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport {\n type SpawnCliFn,\n} from \"../agent/providers/claude/index.js\";\nimport {\n buildProviderModelChoices,\n buildProviderSetupView,\n parseAgentSelection,\n} from \"../agent/provider-view.js\";\nimport type {\n ProviderSetupView,\n} from \"../agent/provider-view.js\";\nimport type { ProviderModelChoice } from \"../agent/types.js\";\nimport {\n ensureCodexInstructions,\n hasCodexInstructions,\n CODEX_INSTRUCTIONS_END,\n CODEX_INSTRUCTIONS_START,\n} from \"../agent/providers/codex-instructions.js\";\nimport {\n disabledAgentProviderMessage,\n formatEnabledAgentProviderList,\n isAgentProviderId,\n isEnabledAgentProviderId,\n readConfig,\n writeConfig,\n type AgentProviderId,\n} from \"../update/config.js\";\nimport { runHookInstall } from \"./hook.js\";\nimport {\n detectCurrentInstallPath,\n detectEphemeral,\n spawnGlobalInstall,\n} from \"./setup/install-path.js\";\nimport {\n countExistingPages,\n printNextSteps,\n} from \"./setup/next-steps.js\";\n\n/**\n * `codealmanac setup` — the MCP-style branded TUI that runs when a user\n * invokes the bare `codealmanac` binary (or `almanac setup` / `codealmanac\n * setup` explicitly).\n *\n * Model: `mcp-ts/src/setup.ts` from openalmanac. Same ASCII banner + badge\n * + step-indicator style, same interactive + `--yes` + non-interactive\n * modes.\n *\n * Setup installs:\n *\n * 1. Agent hooks (delegated to\n * `runHookInstall` from `./hook.ts`).\n * 2. The short \"how to use codealmanac\" guide at\n * `~/.claude/codealmanac.md`, sourced from `guides/mini.md` in the\n * package.\n * 3. The full reference at `~/.claude/codealmanac-reference.md`,\n * sourced from `guides/reference.md`.\n * 4. An `@~/.claude/codealmanac.md` import line in `~/.claude/CLAUDE.md`\n * so Claude Code picks up the short guide globally.\n * 5. An inline managed codealmanac section in `~/.codex/AGENTS.md`\n * (or `AGENTS.override.md` when that is the active non-empty file),\n * so Codex picks up the same guidance without relying on Claude's\n * `@file` import syntax.\n *\n * Everything is idempotent — running setup again is safe. `--skip-hook`\n * and `--skip-guides` opt out of the individual installs. `--yes` or a\n * non-TTY stdin skips all prompts and installs everything.\n */\n\nexport interface SetupOptions {\n /** Install everything without prompting. */\n yes?: boolean;\n /** Don't install the SessionEnd hook. */\n skipHook?: boolean;\n /** Don't install the CLAUDE.md guides. */\n skipGuides?: boolean;\n /** Set the default agent provider during setup. */\n agent?: string;\n /** Set the default model for the selected provider during setup. */\n model?: string;\n\n // ─── Injection points (tests only) ────────────────────────────────\n /** Override the subprocess spawner for `claude auth status`. */\n spawnCli?: SpawnCliFn;\n /** Override `~/.claude/settings.json` path. */\n settingsPath?: string;\n /** Override the bundled hook script path. */\n hookScriptPath?: string;\n /** Override the stable hooks directory for the hook script copy. */\n stableHooksDir?: string;\n /** Override `~/.claude/` dir for guide install. */\n claudeDir?: string;\n /** Override `~/.codex/` dir for Codex instruction install. */\n codexDir?: string;\n /** Override the directory containing `mini.md` / `reference.md`. */\n guidesDir?: string;\n /** Override interactivity; defaults to `process.stdin.isTTY`. */\n isTTY?: boolean;\n /** Stdout sink; defaults to `process.stdout`. */\n stdout?: NodeJS.WritableStream;\n /**\n * Override the install-path probe result. When `null` the probe is\n * bypassed (tests that don't care about the ephemeral-path step).\n * When a string it's treated as the detected install path.\n */\n installPath?: string | null;\n /**\n * Override the npm global install spawner (tests inject a no-op to\n * avoid actually spawning npm during CI).\n */\n spawnGlobalInstall?: () => Promise<void>;\n}\n\nexport interface SetupResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n// ─── ANSI helpers ────────────────────────────────────────────────────\n\nconst RST = \"\\x1b[0m\";\nconst DIM = \"\\x1b[2m\";\nconst WHITE_BOLD = \"\\x1b[1;37m\";\nconst BLUE = \"\\x1b[38;5;75m\";\nconst ACCENT_BG = \"\\x1b[48;5;252m\\x1b[38;5;16m\";\n\nconst GRADIENT = [\n \"\\x1b[38;5;255m\",\n \"\\x1b[38;5;253m\",\n \"\\x1b[38;5;251m\",\n \"\\x1b[38;5;249m\",\n \"\\x1b[38;5;246m\",\n \"\\x1b[38;5;243m\",\n];\n\n// `codealmanac` 11-letter ASCII banner. Chosen for tasteful rendering —\n// same banner used in the MCP setup wizard design, retooled letters for\n// the word \"codealmanac\". Each glyph is 6 lines tall.\n//\n// If you tweak this, keep it to ≤80 visual columns wide so it fits in\n// narrow terminals (80 cols is the classic default).\nconst LOGO_LINES = [\n \" ___ ___ ___ ___ _ _ __ __ _ _ _ _ ___ \",\n \" / __/ _ \\\\| \\\\| __| /_\\\\ | | | \\\\/ | /_\\\\ | \\\\| | /_\\\\ / __|\",\n \"| (_| (_) | |) | _| / _ \\\\| |__| |\\\\/| |/ _ \\\\| .` |/ _ \\\\ (__ \",\n \" \\\\___\\\\___/|___/|___/_/ \\\\_\\\\____|_| |_/_/ \\\\_\\\\_|\\\\_/_/ \\\\_\\\\___|\",\n \" \",\n \" a living wiki for codebases, for your agent \",\n];\n\nconst BAR = ` ${DIM}\\u2502${RST}`;\n\nfunction printBanner(out: NodeJS.WritableStream): void {\n out.write(\"\\n\");\n for (let i = 0; i < LOGO_LINES.length; i++) {\n const color = GRADIENT[Math.min(i, GRADIENT.length - 1)] ?? \"\";\n out.write(`${color}${LOGO_LINES[i]}${RST}\\n`);\n }\n out.write(`\\n${WHITE_BOLD} Set up your automatic codebase wiki${RST}\\n`);\n}\n\nfunction printBadge(out: NodeJS.WritableStream): void {\n out.write(`\\n ${ACCENT_BG} codealmanac ${RST}\\n\\n`);\n}\n\nfunction stepDone(out: NodeJS.WritableStream, msg: string): void {\n out.write(` ${BLUE}\\u25c7${RST} ${msg}\\n`);\n}\n\nfunction stepActive(out: NodeJS.WritableStream, msg: string): void {\n out.write(` ${BLUE}\\u25c6${RST} ${msg}\\n`);\n}\n\nfunction stepSkipped(out: NodeJS.WritableStream, msg: string): void {\n out.write(` ${DIM}\\u25cb ${msg}${RST}\\n`);\n}\n\n// ─── Entry point ─────────────────────────────────────────────────────\n\nexport async function runSetup(\n options: SetupOptions = {},\n): Promise<SetupResult> {\n const out = options.stdout ?? process.stdout;\n const isTTY =\n options.isTTY ?? (process.stdin.isTTY === true);\n const interactive = isTTY && options.yes !== true;\n\n // No-op fast path. When the caller explicitly skipped every install\n // step, rendering the full banner + step markers + \"Setup complete\"\n // box is actively misleading — nothing was actually set up. Emit a\n // single terse line and exit so the user gets honest feedback and\n // piped callers (CI, scripts) don't parse through nine lines of ANSI\n // to conclude nothing happened.\n if (options.skipHook === true && options.skipGuides === true) {\n out.write(\n \"codealmanac: nothing to install — use --help to see what setup does\\n\",\n );\n return { stdout: \"\", stderr: \"\", exitCode: 0 };\n }\n\n printBanner(out);\n printBadge(out);\n\n let agentChoice: AgentChoice;\n try {\n agentChoice = await chooseDefaultAgent({\n out,\n interactive,\n requested: options.agent,\n requestedModel: options.model,\n spawnCli: options.spawnCli,\n });\n } catch (err: unknown) {\n if (isSetupInterrupted(err)) {\n return {\n stdout: \"\",\n stderr: \"almanac: setup cancelled\\n\",\n exitCode: 130,\n };\n }\n throw err;\n }\n if (!agentChoice.ok) {\n return {\n stdout: \"\",\n stderr: `almanac: ${agentChoice.error}\\n`,\n exitCode: 1,\n };\n }\n stepDone(\n out,\n `Agent: ${WHITE_BOLD}${agentChoice.provider}${RST}` +\n ` (${agentChoice.model ?? \"provider default\"})`,\n );\n out.write(BAR + \"\\n\");\n\n // Step 1b: ephemeral install detection. When codealmanac was invoked via\n // `npx codealmanac` (no prior `npm i -g`), the binary lives inside an\n // npx cache directory or pnpm store that can be evicted at any time.\n // `almanac` is also not on PATH, so the user can't use it after setup.\n //\n // When we detect an ephemeral location, we offer (or, on --yes, perform)\n // a `npm install -g codealmanac` to make the install permanent.\n //\n // This is Bug #2 from codealmanac-known-bugs.md.\n const ephem = options.installPath !== undefined\n ? (options.installPath !== null\n ? detectEphemeral(options.installPath)\n : false)\n : detectEphemeral(detectCurrentInstallPath());\n if (ephem) {\n let globalAction: InstallDecision = \"install\";\n if (interactive) {\n globalAction = await confirm(\n out,\n `Running from an ephemeral npx location. Install globally so 'almanac' stays on PATH?`,\n true,\n );\n }\n if (globalAction === \"install\") {\n stepActive(out, \"Installing codealmanac globally…\");\n try {\n await (options.spawnGlobalInstall ?? spawnGlobalInstall)();\n stepDone(out, \"codealmanac installed globally (almanac now on PATH)\");\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n stepActive(out, `Global install failed: ${msg}`);\n out.write(\n ` ${DIM}You can retry manually: npm install -g codealmanac${RST}\\n`,\n );\n }\n } else {\n stepSkipped(\n out,\n `Global install ${DIM}skipped — almanac will not be on PATH after this session${RST}`,\n );\n }\n out.write(BAR + \"\\n\");\n }\n\n // Step 2: install the hook (default yes).\n let hookAction: InstallDecision = \"install\";\n if (options.skipHook === true) {\n hookAction = \"skip\";\n } else if (interactive) {\n hookAction = await confirm(\n out,\n \"Keep your codebase wiki up to date automatically?\",\n true,\n );\n }\n\n let hookResultLine = \"\";\n if (hookAction === \"install\") {\n const res = await runHookInstall({\n source: \"all\",\n settingsPath: options.settingsPath,\n hookScriptPath: options.hookScriptPath,\n stableHooksDir: options.stableHooksDir,\n });\n if (res.exitCode !== 0) {\n stepActive(out, `SessionEnd hook: ${res.stderr.trim()}`);\n return {\n stdout: \"\",\n stderr: res.stderr,\n exitCode: res.exitCode,\n };\n }\n hookResultLine = res.stdout.includes(\"already installed\")\n ? `Auto-capture hooks ${DIM}already installed${RST}`\n : `Auto-capture installed`;\n stepDone(out, hookResultLine);\n } else {\n stepSkipped(out, `Auto-capture ${DIM}skipped${RST}`);\n }\n out.write(BAR + \"\\n\");\n\n // Step 3: install the guides.\n let guidesAction: InstallDecision = \"install\";\n if (options.skipGuides === true) {\n guidesAction = \"skip\";\n } else if (interactive) {\n guidesAction = await confirm(\n out,\n \"Add codealmanac instructions for your AI agents?\",\n true,\n );\n }\n\n let guidesSummary: string;\n if (guidesAction === \"install\") {\n try {\n const summary = await installGuides({\n claudeDir: options.claudeDir ?? path.join(homedir(), \".claude\"),\n codexDir: options.codexDir ?? path.join(homedir(), \".codex\"),\n guidesDir: options.guidesDir ?? resolveGuidesDir(),\n });\n guidesSummary = summary.anyChanges\n ? `Agent instructions added`\n : `Agent instructions ${DIM}already added${RST}`;\n stepDone(out, guidesSummary);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n stdout: \"\",\n stderr: `almanac: guide install failed: ${msg}\\n`,\n exitCode: 1,\n };\n }\n } else {\n stepSkipped(out, `Agent instructions ${DIM}skipped${RST}`);\n }\n out.write(BAR + \"\\n\");\n\n stepDone(out, `${BLUE}Setup complete${RST}`);\n out.write(\"\\n\");\n\n // Detect whether the current working directory is inside a repo that\n // already has a wiki with pages. This fixes Bug #6 from\n // codealmanac-known-bugs.md: Engineer B clones a repo that already has\n // `.almanac/pages/` (committed by Engineer A) and gets told to run\n // `almanac bootstrap`, which is wrong — the wiki already exists.\n const existingPageCount = countExistingPages(process.cwd());\n printNextSteps(out, existingPageCount);\n\n return { stdout: \"\", stderr: \"\", exitCode: 0 };\n}\n\ntype AgentChoice =\n | { ok: true; provider: AgentProviderId; model: string | null }\n | { ok: false; error: string };\n\nasync function chooseDefaultAgent(args: {\n out: NodeJS.WritableStream;\n interactive: boolean;\n requested?: string;\n requestedModel?: string;\n spawnCli?: SpawnCliFn;\n}): Promise<AgentChoice> {\n const config = await readConfig();\n let view: ProviderSetupView | null = null;\n let selected = args.requested ?? config.agent.default;\n if (args.interactive || args.requested !== undefined) {\n view = await buildProviderSetupView({ config, spawnCli: args.spawnCli });\n }\n if (args.interactive && args.requested === undefined && view !== null) {\n while (true) {\n const choice = await selectChoice({\n out: args.out,\n title: \"Choose your agent\",\n help: \"Choose the AI agent codealmanac should use.\",\n choices: view.choices.map((choice) => ({\n value: choice,\n line: formatProviderChoice(choice),\n aliases: [choice.id, choice.label.toLowerCase()],\n })),\n defaultIndex: Math.max(\n 0,\n view.choices.findIndex((choice) =>\n choice.id === view?.recommendedProvider\n ),\n ),\n });\n if (choice.ready) {\n selected = choice.id;\n break;\n }\n if (choice.readiness === \"not-authenticated\" && choice.fixCommand !== null) {\n const command = choice.fixCommand.startsWith(\"run: \")\n ? choice.fixCommand.slice(\"run: \".length)\n : choice.fixCommand;\n const runLogin = await confirm(\n args.out,\n `${choice.label} sign-in is needed. Run '${command}' now?`,\n true,\n );\n if (runLogin === \"install\") {\n const login = await runLoginCommand(command);\n if (!login.ok) {\n stepActive(args.out, `${choice.label} login failed: ${login.error}`);\n }\n view = await buildProviderSetupView({ config, spawnCli: args.spawnCli });\n const refreshed = view.choices.find((next) => next.id === choice.id);\n if (refreshed?.ready === true) {\n selected = refreshed.id;\n break;\n }\n }\n continue;\n }\n showUnavailableProvider(args.out, choice);\n await waitForEnter(args.out, \"Press Enter to choose a different agent.\");\n }\n }\n const parsed = parseAgentSelection(selected);\n if (parsed.provider === null || !isAgentProviderId(parsed.provider)) {\n return {\n ok: false,\n error:\n `unknown agent '${selected}'. Expected one of: ${formatEnabledAgentProviderList()}.`,\n };\n }\n const provider = parsed.provider;\n if (!isEnabledAgentProviderId(provider)) {\n return {\n ok: false,\n error: disabledAgentProviderMessage(provider),\n };\n }\n let selectedChoice = view?.choices.find((choice) => choice.id === provider);\n if (\n args.interactive &&\n selectedChoice !== undefined &&\n !selectedChoice.ready &&\n selectedChoice.fixCommand?.startsWith(\"run: \") === true\n ) {\n const command = selectedChoice.fixCommand.slice(\"run: \".length);\n const runLogin = await confirm(\n args.out,\n `${selectedChoice.label} is not ready. Run '${command}' now?`,\n true,\n );\n if (runLogin === \"install\") {\n const login = await runLoginCommand(command);\n if (login.ok) {\n view = await buildProviderSetupView({ config, spawnCli: args.spawnCli });\n selectedChoice = view.choices.find((choice) => choice.id === provider);\n } else {\n stepActive(args.out, `${selectedChoice.label} login failed: ${login.error}`);\n }\n }\n }\n if (selectedChoice !== undefined && !selectedChoice.ready) {\n return {\n ok: false,\n error: `${selectedChoice.label} is not ready: ${\n selectedChoice.fixCommand ?? selectedChoice.detail\n }`,\n };\n }\n const requestedModel = args.requestedModel ?? parsed.model;\n const model = requestedModel ?? await chooseProviderModel({\n out: args.out,\n interactive: args.interactive,\n provider,\n choice: selectedChoice,\n configuredModel: config.agent.models[provider] ?? null,\n });\n await writeConfig({\n ...config,\n agent: {\n ...config.agent,\n default: provider,\n models: {\n ...config.agent.models,\n [provider]: model,\n },\n },\n });\n if ((!args.interactive || args.requested !== undefined) && selectedChoice !== undefined) {\n const detail = selectedChoice?.ready === true\n ? \"ready\"\n : selectedChoice?.fixCommand ?? selectedChoice?.detail ?? \"status unknown\";\n stepDone(args.out, `Agent readiness: ${detail}`);\n }\n return { ok: true, provider, model };\n}\n\nasync function chooseProviderModel(args: {\n out: NodeJS.WritableStream;\n interactive: boolean;\n provider: AgentProviderId;\n choice?: ProviderSetupView[\"choices\"][number];\n configuredModel: string | null;\n}): Promise<string | null> {\n const choices =\n args.choice?.modelChoices ??\n await buildProviderModelChoices(args.provider, args.configuredModel);\n const recommended =\n choices.find((choice) => choice.recommended) ??\n choices.find((choice) => choice.source === \"provider-default\");\n if (!args.interactive) {\n return args.configuredModel ?? recommended?.value ?? null;\n }\n\n const currentIndex = choices.findIndex((choice) =>\n choice.value === args.configuredModel\n );\n const recommendedIndex = choices.findIndex((choice) => choice.recommended);\n const defaultIndex = Math.max(0,\n currentIndex >= 0\n ? currentIndex\n : recommendedIndex >= 0\n ? recommendedIndex\n : 0);\n const modelChoice = await selectChoice({\n out: args.out,\n title: `Choose ${providerDisplayName(args.provider)} model`,\n choices: choices.map((choice) => ({\n value: choice,\n line: formatModelChoice(choice, args.configuredModel),\n aliases: choice.value === null\n ? [\"default\", \"provider default\"]\n : [String(choice.value)],\n })),\n defaultIndex,\n });\n if (modelChoice?.source === \"custom\") {\n const custom = await promptText(args.out, \"Model name\", \"\");\n return custom.length > 0 ? custom : recommended?.value ?? null;\n }\n return modelChoice?.value ?? recommended?.value ?? null;\n}\n\ninterface SelectChoice<T> {\n value: T;\n line: string;\n aliases?: string[];\n}\n\nasync function selectChoice<T>(args: {\n out: NodeJS.WritableStream;\n title: string;\n help?: string;\n choices: SelectChoice<T>[];\n defaultIndex: number;\n}): Promise<T> {\n const selected = clampIndex(args.defaultIndex, args.choices.length);\n if (canUseRawSelect()) {\n return await selectChoiceRaw({ ...args, defaultIndex: selected });\n }\n renderSelect(args.out, {\n title: args.title,\n help: args.help,\n choices: args.choices,\n selected,\n raw: false,\n });\n const answer = await promptText(args.out, \"Select\", String(selected + 1));\n const index = Number.parseInt(answer, 10);\n if (\n Number.isInteger(index) &&\n index >= 1 &&\n index <= args.choices.length\n ) {\n return args.choices[index - 1]!.value;\n }\n const normalized = answer.trim().toLowerCase();\n const matched = args.choices.find((choice) =>\n choice.aliases?.some((alias) => alias.toLowerCase() === normalized)\n );\n return (matched ?? args.choices[selected])!.value;\n}\n\nasync function selectChoiceRaw<T>(args: {\n out: NodeJS.WritableStream;\n title: string;\n help?: string;\n choices: SelectChoice<T>[];\n defaultIndex: number;\n}): Promise<T> {\n return new Promise((resolve, reject) => {\n let selected = args.defaultIndex;\n let renderedLines = 0;\n const input = process.stdin as NodeJS.ReadStream & {\n setRawMode?: (mode: boolean) => void;\n };\n const render = (): void => {\n if (renderedLines > 0) {\n args.out.write(`\\x1b[${renderedLines}A\\x1b[0J`);\n }\n renderedLines = renderSelect(args.out, {\n title: args.title,\n help: args.help,\n choices: args.choices,\n selected,\n raw: true,\n });\n };\n const cleanup = (): void => {\n input.removeListener(\"data\", onData);\n input.setRawMode?.(false);\n input.pause();\n };\n const onData = (chunk: Buffer): void => {\n const key = chunk.toString(\"utf8\");\n if (key === \"\\u0003\") {\n cleanup();\n args.out.write(\"\\n\");\n reject(new SetupInterruptedError());\n return;\n }\n if (key === \"\\r\" || key === \"\\n\") {\n cleanup();\n args.out.write(\"\\n\");\n resolve(args.choices[selected]!.value);\n return;\n }\n if (key === \"\\u001b[A\") {\n selected = selected === 0 ? args.choices.length - 1 : selected - 1;\n render();\n } else if (key === \"\\u001b[B\") {\n selected = selected === args.choices.length - 1 ? 0 : selected + 1;\n render();\n }\n };\n input.setRawMode?.(true);\n input.resume();\n input.on(\"data\", onData);\n render();\n });\n}\n\nfunction renderSelect<T>(\n out: NodeJS.WritableStream,\n args: {\n title: string;\n help?: string;\n choices: SelectChoice<T>[];\n selected: number;\n raw: boolean;\n },\n): number {\n let lines = 0;\n out.write(` ${WHITE_BOLD}${args.title}${RST}\\n`);\n lines++;\n if (args.help !== undefined) {\n out.write(` ${DIM}${args.help}${RST}\\n`);\n lines++;\n }\n out.write(\"\\n\");\n lines++;\n args.choices.forEach((choice, index) => {\n const pointer = index === args.selected ? `${BLUE}\\u203a${RST}` : \" \";\n out.write(` ${pointer} ${choice.line}\\n`);\n lines++;\n });\n const hint = args.raw\n ? `Use \\u2191/\\u2193 to move, Enter to select`\n : `Type a number or name, then press Enter`;\n out.write(`\\n ${DIM}${hint}${RST}\\n`);\n lines += 2;\n return lines;\n}\n\nclass SetupInterruptedError extends Error {\n constructor() {\n super(\"setup interrupted\");\n }\n}\n\nfunction isSetupInterrupted(err: unknown): boolean {\n return err instanceof SetupInterruptedError;\n}\n\nfunction canUseRawSelect(): boolean {\n const input = process.stdin as NodeJS.ReadStream & {\n setRawMode?: (mode: boolean) => void;\n };\n return process.stdin.isTTY === true && typeof input.setRawMode === \"function\";\n}\n\nfunction clampIndex(index: number, length: number): number {\n if (length <= 0) return 0;\n if (index < 0) return 0;\n if (index >= length) return length - 1;\n return index;\n}\n\nfunction formatProviderChoice(\n choice: ProviderSetupView[\"choices\"][number],\n): string {\n const status = providerStatusLabel(choice);\n const detail = providerDetailLabel(choice);\n const tag = choice.recommended ? ` ${DIM}recommended${RST}` : \"\";\n return `${choice.label.padEnd(8)} ${status.padEnd(15)} ${detail}${tag}`;\n}\n\nfunction providerStatusLabel(\n choice: ProviderSetupView[\"choices\"][number],\n): string {\n if (choice.ready) {\n return choice.detail === \"ANTHROPIC_API_KEY set\" ? \"API key set\" : \"signed in\";\n }\n return choice.readiness === \"missing\" ? \"not installed\" : \"sign in needed\";\n}\n\nfunction providerDetailLabel(\n choice: ProviderSetupView[\"choices\"][number],\n): string {\n if (choice.ready) return choice.account ?? choice.detail;\n if (choice.fixCommand === null) return choice.detail;\n return choice.fixCommand.startsWith(\"run: \")\n ? choice.fixCommand.slice(\"run: \".length)\n : choice.fixCommand;\n}\n\nfunction showUnavailableProvider(\n out: NodeJS.WritableStream,\n choice: ProviderSetupView[\"choices\"][number],\n): void {\n if (choice.readiness === \"missing\") {\n out.write(\n `\\n ${WHITE_BOLD}${choice.label} is not installed.${RST}\\n` +\n ` ${providerDetailLabel(choice)}\\n\\n`,\n );\n return;\n }\n out.write(\n `\\n ${WHITE_BOLD}${choice.label} is not signed in.${RST}\\n` +\n ` Run: ${providerDetailLabel(choice)}\\n\\n`,\n );\n}\n\nfunction formatModelChoice(\n choice: ProviderModelChoice,\n configuredModel: string | null,\n): string {\n const marker = choice.recommended\n ? ` ${DIM}recommended${RST}`\n : choice.value === configuredModel\n ? ` ${DIM}current${RST}`\n : \"\";\n const label = choice.source === \"provider-default\" && choice.value !== null\n ? friendlyModelLabel(choice.value)\n : choice.label;\n return `${label}${marker}`;\n}\n\nfunction friendlyModelLabel(value: string): string {\n if (value === \"claude-sonnet-4-6\") return \"Sonnet 4.6\";\n if (value === \"claude-opus-4-7\") return \"Opus 4.7\";\n if (value === \"claude-haiku-4-5-20251001\") return \"Haiku 4.5\";\n return value;\n}\n\nfunction providerDisplayName(provider: AgentProviderId): string {\n if (provider === \"claude\") return \"Claude\";\n if (provider === \"codex\") return \"Codex\";\n return \"Cursor\";\n}\n\nasync function runLoginCommand(command: string): Promise<\n | { ok: true }\n | { ok: false; error: string }\n> {\n return new Promise((resolve) => {\n const child = spawn(command, {\n shell: true,\n stdio: \"inherit\",\n });\n child.on(\"error\", (err) => {\n resolve({ ok: false, error: err.message });\n });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ ok: true });\n return;\n }\n resolve({ ok: false, error: `exited ${code ?? 1}` });\n });\n });\n}\n\n// ─── Guide installation ──────────────────────────────────────────────\n\ninterface InstallGuidesOptions {\n claudeDir: string;\n codexDir: string;\n guidesDir: string;\n}\n\ninterface InstallGuidesResult {\n anyChanges: boolean;\n filesWritten: string[];\n}\n\n/**\n * Copy the two Claude guide files into `~/.claude/`, append an `@import`\n * line to `~/.claude/CLAUDE.md`, and add inline Codex guidance to the\n * active global Codex AGENTS file. Every step is idempotent:\n *\n * - Guide files are compared by bytes before we write. If the content\n * matches the bundled version, we skip (so `setup` doesn't cause a\n * spurious mtime bump on every invocation).\n * - The import line is appended only if `CLAUDE.md` doesn't already\n * contain the exact `@~/.claude/codealmanac.md` token on a line by\n * itself. We don't try to parse the file — any mention of the token\n * on a non-comment line is treated as \"already present\".\n *\n * Returns a summary the caller uses to decide whether to say \"installed\"\n * or \"already installed\" in the TUI.\n */\nasync function installGuides(\n options: InstallGuidesOptions,\n): Promise<InstallGuidesResult> {\n await mkdir(options.claudeDir, { recursive: true });\n\n const srcMini = path.join(options.guidesDir, \"mini.md\");\n const srcRef = path.join(options.guidesDir, \"reference.md\");\n if (!existsSync(srcMini)) {\n throw new Error(`missing bundled guide: ${srcMini}`);\n }\n if (!existsSync(srcRef)) {\n throw new Error(`missing bundled guide: ${srcRef}`);\n }\n\n const destMini = path.join(options.claudeDir, \"codealmanac.md\");\n const destRef = path.join(options.claudeDir, \"codealmanac-reference.md\");\n\n const miniChanged = await copyIfChanged(srcMini, destMini);\n const refChanged = await copyIfChanged(srcRef, destRef);\n\n const claudeMd = path.join(options.claudeDir, \"CLAUDE.md\");\n const importChanged = await ensureImport(claudeMd);\n const codexChanged = await ensureCodexInstructions(options.codexDir);\n\n const filesWritten: string[] = [];\n if (miniChanged) filesWritten.push(\"codealmanac.md\");\n if (refChanged) filesWritten.push(\"codealmanac-reference.md\");\n if (importChanged) filesWritten.push(\"CLAUDE.md\");\n if (codexChanged) filesWritten.push(\"AGENTS.md\");\n\n return { anyChanges: filesWritten.length > 0, filesWritten };\n}\n\nasync function copyIfChanged(src: string, dest: string): Promise<boolean> {\n const srcBytes = await readFile(src);\n if (existsSync(dest)) {\n try {\n const destBytes = await readFile(dest);\n if (srcBytes.equals(destBytes)) return false;\n } catch {\n // Fall through to write.\n }\n }\n await copyFile(src, dest);\n return true;\n}\n\n/** The exact import line we manage. Changing this requires updating\n * uninstall too. */\nexport const IMPORT_LINE = \"@~/.claude/codealmanac.md\";\n\n/**\n * Append the import line to `~/.claude/CLAUDE.md` if it isn't already\n * present. Creates the file if absent. Returns true when we wrote, false\n * when the line was already there.\n *\n * We match on `@~/.claude/codealmanac.md` appearing on any non-empty\n * line (trimmed). This catches both the bare line we write and any\n * user-edited variant (comments, trailing whitespace). We deliberately\n * do NOT try to repair a user who deleted the newline — that's their\n * file to shape.\n */\nasync function ensureImport(claudeMdPath: string): Promise<boolean> {\n let existing = \"\";\n if (existsSync(claudeMdPath)) {\n existing = await readFile(claudeMdPath, \"utf8\");\n }\n if (hasImportLine(existing)) return false;\n\n const sep =\n existing.length === 0 ? \"\" : existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n const body = `${existing}${sep}${IMPORT_LINE}\\n`;\n await writeFile(claudeMdPath, body, \"utf8\");\n return true;\n}\n\nexport function hasImportLine(contents: string): boolean {\n // Match line-starts-with-token rather than exact-line equality so a\n // user who annotated the import line (`@~/.claude/codealmanac.md #\n // codealmanac`) doesn't cause us to re-append a duplicate below.\n // The trailing-character check rules out accidental matches on a\n // longer line like `@~/.claude/codealmanac.md-extra`.\n const lines = contents.split(/\\r?\\n/).map((l) => l.trim());\n return lines.some((line) => {\n if (line === IMPORT_LINE) return true;\n if (!line.startsWith(IMPORT_LINE)) return false;\n const next = line[IMPORT_LINE.length];\n return next === \" \" || next === \"\\t\";\n });\n}\n\nexport {\n CODEX_INSTRUCTIONS_END,\n CODEX_INSTRUCTIONS_START,\n hasCodexInstructions,\n};\n\n// ─── Interactive prompt ──────────────────────────────────────────────\n\ntype InstallDecision = \"install\" | \"skip\";\n\n/**\n * Minimal `[Y/n]` prompt. No raw mode, no cursor — just readline. The\n * MCP setup uses a fancy arrow-key TUI for multi-choice; we only have\n * binary decisions here, so a line-reader prompt is clearer and doesn't\n * fight with the step-indicator rendering above it.\n */\nfunction confirm(\n out: NodeJS.WritableStream,\n question: string,\n defaultYes: boolean,\n): Promise<InstallDecision> {\n return new Promise((resolve) => {\n const hint = defaultYes ? \"[Y/n]\" : \"[y/N]\";\n out.write(` ${BLUE}\\u25c6${RST} ${question} ${DIM}${hint}${RST} `);\n\n let buf = \"\";\n const onData = (chunk: Buffer): void => {\n buf += chunk.toString(\"utf8\");\n const nl = buf.indexOf(\"\\n\");\n if (nl === -1) return;\n process.stdin.removeListener(\"data\", onData);\n process.stdin.pause();\n\n const answer = buf.slice(0, nl).trim().toLowerCase();\n const accepted =\n answer.length === 0\n ? defaultYes\n : answer === \"y\" || answer === \"yes\";\n resolve(accepted ? \"install\" : \"skip\");\n };\n\n process.stdin.resume();\n process.stdin.on(\"data\", onData);\n });\n}\n\nfunction promptText(\n out: NodeJS.WritableStream,\n question: string,\n defaultValue: string,\n): Promise<string> {\n return new Promise((resolve) => {\n out.write(\n ` ${BLUE}\\u25c6${RST} ${question} ${DIM}[${defaultValue}]${RST} `,\n );\n\n let buf = \"\";\n const onData = (chunk: Buffer): void => {\n buf += chunk.toString(\"utf8\");\n const nl = buf.indexOf(\"\\n\");\n if (nl === -1) return;\n process.stdin.removeListener(\"data\", onData);\n process.stdin.pause();\n\n const answer = buf.slice(0, nl).trim();\n resolve(answer.length === 0 ? defaultValue : answer);\n };\n\n process.stdin.resume();\n process.stdin.on(\"data\", onData);\n });\n}\n\nasync function waitForEnter(\n out: NodeJS.WritableStream,\n message: string,\n): Promise<void> {\n await promptText(out, message, \"\");\n}\n\n// ─── Guides path resolution ──────────────────────────────────────────\n\n/**\n * Locate `guides/` relative to the installed package. Mirrors\n * `resolvePromptsDir` from `src/agent/prompts.ts`.\n *\n * Two runtime layouts to handle:\n *\n * 1. **Bundled dist.** `dist/codealmanac.js` → walk one level up →\n * `guides/`.\n * 2. **Source (tests / tsx).** `src/commands/setup.ts` → walk two\n * levels up → `guides/`.\n *\n * We also try `createRequire` to resolve the package root from the\n * `codealmanac/package.json` manifest, as a belt-and-suspenders fallback\n * for unusual install layouts (monorepo hoisting, etc.). That path is\n * only exercised when the direct walk-up fails.\n */\nexport function resolveGuidesDir(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, \"..\", \"guides\"), // dist layout\n path.resolve(here, \"..\", \"..\", \"guides\"), // src layout\n path.resolve(here, \"..\", \"..\", \"..\", \"guides\"),\n ];\n for (const dir of candidates) {\n if (looksLikeGuidesDir(dir)) return dir;\n }\n // Fallback: resolve via the package.json of the currently-running\n // codealmanac. createRequire lets us ask Node's resolver rather than\n // guessing at directory layouts.\n try {\n const require = createRequire(import.meta.url);\n const pkgJson = require.resolve(\"codealmanac/package.json\");\n const guides = path.join(path.dirname(pkgJson), \"guides\");\n if (looksLikeGuidesDir(guides)) return guides;\n } catch {\n // Ignore — we'll throw with the candidate list below.\n }\n throw new Error(\n \"could not locate bundled guides/ directory. Tried:\\n\" +\n candidates.map((c) => ` - ${c}`).join(\"\\n\"),\n );\n}\n\nfunction looksLikeGuidesDir(dir: string): boolean {\n return existsSync(path.join(dir, \"mini.md\"));\n}\n","import { execFile } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Return the directory of the currently-running codealmanac install by\n * walking up from this module's file to the nearest `package.json` whose\n * `name` is `codealmanac`. Returns the empty string when the walk fails.\n */\nexport function detectCurrentInstallPath(): string {\n try {\n const req = createRequire(import.meta.url);\n const here = fileURLToPath(import.meta.url);\n let dir = path.dirname(here);\n for (let i = 0; i < 6; i++) {\n const pkgPath = path.join(dir, \"package.json\");\n try {\n const raw = req(\"fs\").readFileSync(pkgPath, \"utf-8\") as string;\n const pkg = JSON.parse(raw) as { name?: unknown };\n if (pkg.name === \"codealmanac\") return dir;\n } catch {\n // keep walking\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // import.meta.url unavailable — not ephemeral for our purposes.\n }\n return \"\";\n}\n\n/**\n * Return true when the given install path looks ephemeral.\n *\n * Ephemeral locations we recognize:\n * - `~/.npm/_npx/` — npm's npx cache (GC'd on version bumps or\n * `npm cache clean`)\n * - `~/.local/share/pnpm/dlx/` — pnpm's dlx (like npx) cache\n * - `/tmp/` or `/var/folders/` — common CI / temp paths\n *\n * A global install (`~/.nvm/.../lib/node_modules/`, `/usr/local/lib/...`,\n * `~/.local/lib/node_modules/`) is NOT ephemeral.\n */\nexport function detectEphemeral(installPath: string): boolean {\n if (installPath.length === 0) return false;\n const home = homedir();\n if (installPath.startsWith(path.join(home, \".npm\", \"_npx\"))) return true;\n if (\n installPath.startsWith(path.join(home, \".local\", \"share\", \"pnpm\", \"dlx\"))\n ) return true;\n if (installPath.startsWith(\"/tmp/\")) return true;\n if (installPath.startsWith(\"/var/folders/\")) return true;\n return false;\n}\n\n/**\n * Spawn `npm install -g codealmanac@latest` in a child process and wait\n * for it to finish. Rejects on non-zero exit or spawn error.\n */\nexport function spawnGlobalInstall(): Promise<void> {\n return new Promise((resolve, reject) => {\n execFile(\n \"npm\",\n [\"install\", \"-g\", \"codealmanac@latest\"],\n { shell: false },\n (err, _stdout, stderr) => {\n if (err !== null) {\n reject(\n new Error(\n stderr.length > 0\n ? stderr.trim().split(\"\\n\")[0] ?? err.message\n : err.message,\n ),\n );\n } else {\n resolve();\n }\n },\n );\n });\n}\n","import { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst RST = \"\\x1b[0m\";\nconst BOLD = \"\\x1b[1m\";\nconst DIM = \"\\x1b[2m\";\nconst WHITE_BOLD = \"\\x1b[1;37m\";\nconst BLUE = \"\\x1b[38;5;75m\";\nconst BLUE_DIM = \"\\x1b[38;5;69m\";\n\n/**\n * Print the \"Next steps\" box. When `existingPageCount` is greater than 0,\n * the current working directory already has a wiki with committed pages.\n * In that case we skip the `almanac bootstrap` step and tell the user to\n * start querying.\n */\nexport function printNextSteps(\n out: NodeJS.WritableStream,\n existingPageCount: number,\n): void {\n const innerW = 62;\n const vis = (s: string): number =>\n s.replace(/\\x1b\\[[0-9;]*m/g, \"\").length;\n const row = (content: string): string => {\n const padding = Math.max(0, innerW - vis(content));\n return ` ${BLUE_DIM}\\u2502${RST}${content}${\" \".repeat(padding)}${BLUE_DIM}\\u2502${RST}\\n`;\n };\n const empty = row(\"\");\n\n out.write(` ${BLUE_DIM}\\u256d${\"─\".repeat(innerW)}\\u256e${RST}\\n`);\n out.write(empty);\n out.write(row(` ${WHITE_BOLD}Next steps${RST}`));\n out.write(empty);\n\n if (existingPageCount > 0) {\n out.write(\n row(\n ` ${BLUE}\\u25c7${RST} This repo already has a wiki ${DIM}(${existingPageCount} page${existingPageCount === 1 ? \"\" : \"s\"})${RST}`,\n ),\n );\n out.write(empty);\n out.write(row(` ${BLUE}1.${RST} Start querying your wiki:`));\n out.write(row(` ${BOLD}almanac search --mentions <file>${RST}`));\n out.write(\n row(` ${BLUE}2.${RST} Work normally — capture runs on session end`),\n );\n } else {\n out.write(\n row(` ${BLUE}1.${RST} ${BOLD}cd${RST} into a repo you want to document`),\n );\n out.write(\n row(\n ` ${BLUE}2.${RST} ${BOLD}almanac bootstrap${RST} ${DIM}# scaffold the wiki${RST}`,\n ),\n );\n out.write(\n row(` ${BLUE}3.${RST} Work normally — capture runs on session end`),\n );\n }\n\n out.write(empty);\n out.write(` ${BLUE_DIM}\\u2570${\"─\".repeat(innerW)}\\u256f${RST}\\n\\n`);\n}\n\n/**\n * Count `.md` files in `.almanac/pages/` under the current working\n * directory or any parent. Returns 0 when no wiki is found or the pages\n * directory is empty.\n */\nexport function countExistingPages(cwd: string): number {\n try {\n let dir = cwd;\n for (let i = 0; i < 10; i++) {\n const pagesDir = path.join(dir, \".almanac\", \"pages\");\n if (existsSync(pagesDir)) {\n try {\n const entries = readdirSync(pagesDir);\n return entries.filter((e) => e.endsWith(\".md\")).length;\n } catch {\n return 0;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch {\n // Swallow — never crash setup because of this.\n }\n return 0;\n}\n"],"mappings":"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","names":["existsSync","mkdir","readFile","writeFile","createRequire","homedir","path","fileURLToPath","path","existsSync","path","RST","DIM","WHITE_BOLD","BLUE","path","homedir","choice","mkdir","existsSync","readFile","writeFile","BLUE","RST","DIM","path","fileURLToPath","require","createRequire","existsSync"]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
runInternalUpdateCheck,
|
|
7
7
|
scheduleBackgroundUpdateCheck
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HJ3WREGP.js";
|
|
9
9
|
import {
|
|
10
10
|
BLUE,
|
|
11
11
|
BOLD,
|
|
@@ -14,9 +14,9 @@ import {
|
|
|
14
14
|
} from "./chunk-FM3VRDK7.js";
|
|
15
15
|
import {
|
|
16
16
|
runSetup
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-VXDPUOQ5.js";
|
|
18
|
+
import "./chunk-PDFS5VFE.js";
|
|
19
|
+
import "./chunk-J7DNV2DH.js";
|
|
20
20
|
import {
|
|
21
21
|
getStatePath,
|
|
22
22
|
isNewer
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
getConfigPath,
|
|
26
26
|
getLegacyConfigPath,
|
|
27
27
|
parseConfigText
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-3E7JNMTZ.js";
|
|
29
29
|
import "./chunk-7JUX4ADQ.js";
|
|
30
30
|
|
|
31
31
|
// src/cli.ts
|
|
@@ -461,7 +461,7 @@ async function run(argv, deps = {}) {
|
|
|
461
461
|
if (await tryRunSqliteFreeCommand(argv.slice(2), runSetupFn)) {
|
|
462
462
|
return;
|
|
463
463
|
}
|
|
464
|
-
const { registerCommands } = await import("./register-commands-
|
|
464
|
+
const { registerCommands } = await import("./register-commands-2F6SXLDI.js");
|
|
465
465
|
registerCommands(program);
|
|
466
466
|
configureGroupedHelp(program);
|
|
467
467
|
await program.parseAsync(argv);
|
|
@@ -514,7 +514,7 @@ async function tryRunSqliteFreeCommand(args, runSetupFn) {
|
|
|
514
514
|
return true;
|
|
515
515
|
}
|
|
516
516
|
if (command === "hook") {
|
|
517
|
-
const { runHookInstall, runHookStatus, runHookUninstall } = await import("./hook-
|
|
517
|
+
const { runHookInstall, runHookStatus, runHookUninstall } = await import("./hook-4SVX446M.js");
|
|
518
518
|
if (subcommand === "install") {
|
|
519
519
|
emit(await runHookInstall({ source: parseHookSource(args.slice(2)) }));
|
|
520
520
|
return true;
|
|
@@ -535,7 +535,7 @@ async function tryRunSqliteFreeCommand(args, runSetupFn) {
|
|
|
535
535
|
runAgentsList,
|
|
536
536
|
runAgentsModel,
|
|
537
537
|
runAgentsUse
|
|
538
|
-
} = await import("./agents-
|
|
538
|
+
} = await import("./agents-HYRWRHRX.js");
|
|
539
539
|
if (subcommand === "list" || subcommand === void 0) {
|
|
540
540
|
emit(await runAgentsList());
|
|
541
541
|
return true;
|
|
@@ -564,7 +564,7 @@ async function tryRunSqliteFreeCommand(args, runSetupFn) {
|
|
|
564
564
|
runConfigList,
|
|
565
565
|
runConfigSet,
|
|
566
566
|
runConfigUnset
|
|
567
|
-
} = await import("./config-
|
|
567
|
+
} = await import("./config-F7FKEQ7F.js");
|
|
568
568
|
if (subcommand === "list" || subcommand === void 0) {
|
|
569
569
|
emit(await runConfigList({
|
|
570
570
|
json: args.includes("--json"),
|
|
@@ -600,7 +600,7 @@ async function tryRunSqliteFreeCommand(args, runSetupFn) {
|
|
|
600
600
|
return false;
|
|
601
601
|
}
|
|
602
602
|
if (command === "set") {
|
|
603
|
-
const { runDeprecatedSetAgentModel, runDeprecatedSetDefaultAgent } = await import("./agents-
|
|
603
|
+
const { runDeprecatedSetAgentModel, runDeprecatedSetDefaultAgent } = await import("./agents-HYRWRHRX.js");
|
|
604
604
|
if (subcommand === "default-agent") {
|
|
605
605
|
emit(await runDeprecatedSetDefaultAgent({ provider: args[2] ?? "" }));
|
|
606
606
|
return true;
|
|
@@ -615,12 +615,12 @@ async function tryRunSqliteFreeCommand(args, runSetupFn) {
|
|
|
615
615
|
return false;
|
|
616
616
|
}
|
|
617
617
|
if (command === "update") {
|
|
618
|
-
const { runUpdate } = await import("./update-
|
|
618
|
+
const { runUpdate } = await import("./update-2UGOFN5C.js");
|
|
619
619
|
emit(await runUpdate(parseUpdateFlags(args.slice(1))));
|
|
620
620
|
return true;
|
|
621
621
|
}
|
|
622
622
|
if (command === "doctor") {
|
|
623
|
-
const { runDoctor } = await import("./doctor-
|
|
623
|
+
const { runDoctor } = await import("./doctor-37UH3HT5.js");
|
|
624
624
|
emit(await runDoctor({
|
|
625
625
|
cwd: process.cwd(),
|
|
626
626
|
...parseDoctorFlags(args.slice(1))
|
|
@@ -628,7 +628,7 @@ async function tryRunSqliteFreeCommand(args, runSetupFn) {
|
|
|
628
628
|
return true;
|
|
629
629
|
}
|
|
630
630
|
if (command === "uninstall") {
|
|
631
|
-
const { runUninstall } = await import("./uninstall-
|
|
631
|
+
const { runUninstall } = await import("./uninstall-C62ZOK32.js");
|
|
632
632
|
emit(await runUninstall(parseUninstallFlags(args.slice(1))));
|
|
633
633
|
return true;
|
|
634
634
|
}
|
|
@@ -695,4 +695,4 @@ export {
|
|
|
695
695
|
run,
|
|
696
696
|
tryParseSetupShortcut
|
|
697
697
|
};
|
|
698
|
-
//# sourceMappingURL=cli-
|
|
698
|
+
//# sourceMappingURL=cli-MKXCNEMW.js.map
|
package/dist/codealmanac.js
CHANGED
|
@@ -59,7 +59,7 @@ if (shouldCheckSqliteAbi(process.argv)) {
|
|
|
59
59
|
process.exit(1);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
var { run } = await import("./cli-
|
|
62
|
+
var { run } = await import("./cli-MKXCNEMW.js");
|
|
63
63
|
run(process.argv).catch((err) => {
|
|
64
64
|
const message = err instanceof Error ? err.message : String(err);
|
|
65
65
|
process.stderr.write(`almanac: ${message}
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
runConfigList,
|
|
5
5
|
runConfigSet,
|
|
6
6
|
runConfigUnset
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-2BNDNGUR.js";
|
|
8
|
+
import "./chunk-3E7JNMTZ.js";
|
|
9
9
|
import "./chunk-7JUX4ADQ.js";
|
|
10
10
|
export {
|
|
11
11
|
runConfigGet,
|
|
@@ -13,4 +13,4 @@ export {
|
|
|
13
13
|
runConfigSet,
|
|
14
14
|
runConfigUnset
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=config-
|
|
16
|
+
//# sourceMappingURL=config-F7FKEQ7F.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
runDoctor
|
|
4
|
+
} from "./chunk-DW32TL5W.js";
|
|
5
|
+
import "./chunk-HJ3WREGP.js";
|
|
6
|
+
import "./chunk-4CODZRHH.js";
|
|
7
|
+
import "./chunk-FM3VRDK7.js";
|
|
8
|
+
import "./chunk-VXDPUOQ5.js";
|
|
9
|
+
import "./chunk-PDFS5VFE.js";
|
|
10
|
+
import "./chunk-J7DNV2DH.js";
|
|
11
|
+
import "./chunk-F53U6JQG.js";
|
|
12
|
+
import "./chunk-3E7JNMTZ.js";
|
|
13
|
+
import "./chunk-7JUX4ADQ.js";
|
|
14
|
+
export {
|
|
15
|
+
runDoctor
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=doctor-37UH3HT5.js.map
|
|
@@ -3,10 +3,12 @@ import {
|
|
|
3
3
|
runHookInstall,
|
|
4
4
|
runHookStatus,
|
|
5
5
|
runHookUninstall
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PDFS5VFE.js";
|
|
7
|
+
import "./chunk-3E7JNMTZ.js";
|
|
8
|
+
import "./chunk-7JUX4ADQ.js";
|
|
7
9
|
export {
|
|
8
10
|
runHookInstall,
|
|
9
11
|
runHookStatus,
|
|
10
12
|
runHookUninstall
|
|
11
13
|
};
|
|
12
|
-
//# sourceMappingURL=hook-
|
|
14
|
+
//# sourceMappingURL=hook-4SVX446M.js.map
|
|
@@ -14,13 +14,13 @@ import {
|
|
|
14
14
|
runAgentsUse,
|
|
15
15
|
runDeprecatedSetAgentModel,
|
|
16
16
|
runDeprecatedSetDefaultAgent
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GPFVEF6V.js";
|
|
18
18
|
import {
|
|
19
19
|
runConfigGet,
|
|
20
20
|
runConfigList,
|
|
21
21
|
runConfigSet,
|
|
22
22
|
runConfigUnset
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-2BNDNGUR.js";
|
|
24
24
|
import {
|
|
25
25
|
addEntry,
|
|
26
26
|
ancestorsInFile,
|
|
@@ -46,8 +46,8 @@ import {
|
|
|
46
46
|
} from "./chunk-KQUVMF27.js";
|
|
47
47
|
import {
|
|
48
48
|
runDoctor
|
|
49
|
-
} from "./chunk-
|
|
50
|
-
import "./chunk-
|
|
49
|
+
} from "./chunk-DW32TL5W.js";
|
|
50
|
+
import "./chunk-HJ3WREGP.js";
|
|
51
51
|
import "./chunk-4CODZRHH.js";
|
|
52
52
|
import {
|
|
53
53
|
BLUE,
|
|
@@ -57,30 +57,33 @@ import {
|
|
|
57
57
|
} from "./chunk-FM3VRDK7.js";
|
|
58
58
|
import {
|
|
59
59
|
runUninstall
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-K2JBCB7R.js";
|
|
61
61
|
import {
|
|
62
62
|
runSetup
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-VXDPUOQ5.js";
|
|
64
64
|
import {
|
|
65
65
|
runHookInstall,
|
|
66
66
|
runHookStatus,
|
|
67
67
|
runHookUninstall
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-PDFS5VFE.js";
|
|
69
69
|
import {
|
|
70
70
|
DEFAULT_AGENT_MODEL,
|
|
71
71
|
assertAgentAuth,
|
|
72
72
|
getAgentProvider,
|
|
73
73
|
getProviderDefaultModel,
|
|
74
74
|
parseAgentSelection
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-J7DNV2DH.js";
|
|
76
76
|
import {
|
|
77
77
|
runUpdate
|
|
78
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-ODJAAJGZ.js";
|
|
79
79
|
import "./chunk-F53U6JQG.js";
|
|
80
80
|
import {
|
|
81
|
+
disabledAgentProviderMessage,
|
|
82
|
+
formatEnabledAgentProviderList,
|
|
81
83
|
isAgentProviderId,
|
|
84
|
+
isEnabledAgentProviderId,
|
|
82
85
|
readConfig
|
|
83
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-3E7JNMTZ.js";
|
|
84
87
|
import {
|
|
85
88
|
findNearestAlmanacDir,
|
|
86
89
|
getRepoAlmanacDir
|
|
@@ -1790,16 +1793,16 @@ function registerQueryCommands(program) {
|
|
|
1790
1793
|
// src/cli/register-setup-commands.ts
|
|
1791
1794
|
function registerSetupCommands(program) {
|
|
1792
1795
|
const agents = program.command("agents").description("list supported AI agent providers and readiness");
|
|
1793
|
-
agents.command("list").description("show Claude
|
|
1796
|
+
agents.command("list").description("show Claude and Codex provider status").action(async () => {
|
|
1794
1797
|
emit(await runAgentsList());
|
|
1795
1798
|
});
|
|
1796
1799
|
agents.command("doctor").description("diagnose supported AI agent providers").action(async () => {
|
|
1797
1800
|
emit(await runAgentsDoctor());
|
|
1798
1801
|
});
|
|
1799
|
-
agents.command("use").description("set the default AI agent provider").argument("<provider>", "claude, codex,
|
|
1802
|
+
agents.command("use").description("set the default AI agent provider").argument("<provider>", "claude, codex, or claude/<model>").action(async (provider) => {
|
|
1800
1803
|
emit(await runAgentsUse({ provider }));
|
|
1801
1804
|
});
|
|
1802
|
-
agents.command("model").description("set or reset a provider model").argument("<provider>", "claude
|
|
1805
|
+
agents.command("model").description("set or reset a provider model").argument("<provider>", "claude or codex").argument("[model]", "provider-specific model id").option("--default", "reset to provider default").action(async (provider, model, opts) => {
|
|
1803
1806
|
emit(await runAgentsModel({
|
|
1804
1807
|
provider,
|
|
1805
1808
|
model,
|
|
@@ -1837,7 +1840,7 @@ function registerSetupCommands(program) {
|
|
|
1837
1840
|
exitCode: 1
|
|
1838
1841
|
});
|
|
1839
1842
|
});
|
|
1840
|
-
program.command("setup").description("
|
|
1843
|
+
program.command("setup").description("set up codealmanac for Claude and Codex").option("-y, --yes", "skip prompts; install everything").option("--agent <agent>", "default agent: claude or codex").option("--model <model>", "default model for the selected agent").option("--skip-hook", "opt out of the SessionEnd hook").option("--skip-guides", "opt out of the CLAUDE.md guides").action(
|
|
1841
1844
|
async (opts) => {
|
|
1842
1845
|
const result = await runSetup({
|
|
1843
1846
|
yes: opts.yes,
|
|
@@ -1955,10 +1958,16 @@ async function resolveAgentSelection(args) {
|
|
|
1955
1958
|
if (parsed.provider === null || !isAgentProviderId(parsed.provider)) {
|
|
1956
1959
|
return {
|
|
1957
1960
|
ok: false,
|
|
1958
|
-
error: `unknown agent '${rawAgent}'. Expected one of:
|
|
1961
|
+
error: `unknown agent '${rawAgent}'. Expected one of: ${formatEnabledAgentProviderList()}.`
|
|
1959
1962
|
};
|
|
1960
1963
|
}
|
|
1961
1964
|
const provider = parsed.provider;
|
|
1965
|
+
if (!isEnabledAgentProviderId(provider)) {
|
|
1966
|
+
return {
|
|
1967
|
+
ok: false,
|
|
1968
|
+
error: disabledAgentProviderMessage(provider)
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1962
1971
|
const configuredModel = config.agent.models[provider] ?? void 0;
|
|
1963
1972
|
const model = args.model !== void 0 ? args.model : parsed.model !== void 0 && agentSource === "flag" ? parsed.model : process.env.ALMANAC_MODEL !== void 0 ? process.env.ALMANAC_MODEL : parsed.model !== void 0 ? parsed.model : configuredModel === null ? void 0 : configuredModel;
|
|
1964
1973
|
return { ok: true, provider, model };
|
|
@@ -3146,7 +3155,7 @@ async function runReindex(options) {
|
|
|
3146
3155
|
function registerWikiLifecycleCommands(program) {
|
|
3147
3156
|
program.command("bootstrap").description(
|
|
3148
3157
|
"scaffold a wiki in this repo via an AI agent (requires ANTHROPIC_API_KEY or Claude subscription)"
|
|
3149
|
-
).option("--quiet", "suppress per-tool streaming; print only the final line").option("--agent <agent>", "agent provider: claude
|
|
3158
|
+
).option("--quiet", "suppress per-tool streaming; print only the final line").option("--agent <agent>", "agent provider: claude or codex").option("--model <model>", "override the agent model").option("--force", "overwrite an existing populated wiki (default: refuse)").option("--json", "emit structured CommandOutcome JSON").action(
|
|
3150
3159
|
async (opts) => {
|
|
3151
3160
|
const result = await runBootstrap({
|
|
3152
3161
|
cwd: process.cwd(),
|
|
@@ -3159,7 +3168,7 @@ function registerWikiLifecycleCommands(program) {
|
|
|
3159
3168
|
emit(result);
|
|
3160
3169
|
}
|
|
3161
3170
|
);
|
|
3162
|
-
const capture = program.command("capture [transcript]").alias("c").description("run the writer/reviewer pipeline on a session (usually automatic)").option("--session <id>", "target a specific session by ID").option("--quiet", "suppress per-tool streaming; print only the final summary").option("--agent <agent>", "agent provider: claude
|
|
3171
|
+
const capture = program.command("capture [transcript]").alias("c").description("run the writer/reviewer pipeline on a session (usually automatic)").option("--session <id>", "target a specific session by ID").option("--quiet", "suppress per-tool streaming; print only the final summary").option("--agent <agent>", "agent provider: claude or codex").option("--model <model>", "override the agent model").option("--json", "emit structured CommandOutcome JSON").action(
|
|
3163
3172
|
async (transcript, opts) => {
|
|
3164
3173
|
await autoRegisterIfNeeded(process.cwd());
|
|
3165
3174
|
const result = await runCapture({
|
|
@@ -3194,7 +3203,7 @@ function registerWikiLifecycleCommands(program) {
|
|
|
3194
3203
|
));
|
|
3195
3204
|
});
|
|
3196
3205
|
const hook = program.command("hook").description("manage the SessionEnd auto-capture hook");
|
|
3197
|
-
hook.command("install").description("add a SessionEnd entry that runs 'almanac capture' on session end").option("--source <source>", "claude, codex,
|
|
3206
|
+
hook.command("install").description("add a SessionEnd entry that runs 'almanac capture' on session end").option("--source <source>", "claude, codex, or all").action(async (opts) => {
|
|
3198
3207
|
const result = await runHookInstall({
|
|
3199
3208
|
source: normalizeHookSource(opts.source)
|
|
3200
3209
|
});
|
|
@@ -3235,4 +3244,4 @@ function registerCommands(program) {
|
|
|
3235
3244
|
export {
|
|
3236
3245
|
registerCommands
|
|
3237
3246
|
};
|
|
3238
|
-
//# sourceMappingURL=register-commands-
|
|
3247
|
+
//# sourceMappingURL=register-commands-2F6SXLDI.js.map
|