codealmanac 0.2.1 → 0.2.3
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/dist/{agents-A4II4YJC.js → agents-RVYQ44DB.js} +3 -2
- package/dist/{chunk-B2AGSRXL.js → chunk-HNVOYWC2.js} +2 -2
- package/dist/{chunk-MX2EW5MR.js → chunk-NBVIEZZQ.js} +2 -2
- package/dist/chunk-PIYJQE4Z.js +102 -0
- package/dist/chunk-PIYJQE4Z.js.map +1 -0
- package/dist/{chunk-R3URPHGH.js → chunk-TWM7I2LU.js} +3 -81
- package/dist/chunk-TWM7I2LU.js.map +1 -0
- package/dist/{chunk-ZDJSJIB6.js → chunk-XNTNXEWY.js} +43 -9
- package/dist/chunk-XNTNXEWY.js.map +1 -0
- package/dist/{cli-MZEXRV6E.js → cli-6BOB6KAN.js} +8 -7
- package/dist/{cli-MZEXRV6E.js.map → cli-6BOB6KAN.js.map} +1 -1
- package/dist/codealmanac.js +1 -1
- package/dist/{doctor-3BYSF3JD.js → doctor-DD7EQGCA.js} +4 -3
- package/dist/{register-commands-DPH4ZWEE.js → register-commands-IXYE5CNZ.js} +147 -23
- package/dist/register-commands-IXYE5CNZ.js.map +1 -0
- package/dist/{uninstall-FDIOBAAR.js → uninstall-OBV4Z3JE.js} +4 -3
- package/package.json +1 -1
- package/dist/chunk-R3URPHGH.js.map +0 -1
- package/dist/chunk-ZDJSJIB6.js.map +0 -1
- package/dist/register-commands-DPH4ZWEE.js.map +0 -1
- /package/dist/{agents-A4II4YJC.js.map → agents-RVYQ44DB.js.map} +0 -0
- /package/dist/{chunk-B2AGSRXL.js.map → chunk-HNVOYWC2.js.map} +0 -0
- /package/dist/{chunk-MX2EW5MR.js.map → chunk-NBVIEZZQ.js.map} +0 -0
- /package/dist/{doctor-3BYSF3JD.js.map → doctor-DD7EQGCA.js.map} +0 -0
- /package/dist/{uninstall-FDIOBAAR.js.map → uninstall-OBV4Z3JE.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/cli/help.ts","../src/install/global.ts","../src/update/announce.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { basename } from \"node:path\";\n\nimport { Command } from \"commander\";\n\nimport { runSetup } from \"./commands/setup.js\";\nimport { configureGroupedHelp } from \"./cli/help.js\";\nimport { emit } from \"./cli/helpers.js\";\nimport { runCodealmanacBootstrap } from \"./install/global.js\";\nimport { announceUpdateIfAvailable } from \"./update/announce.js\";\nimport {\n runInternalUpdateCheck,\n scheduleBackgroundUpdateCheck,\n} from \"./update/schedule.js\";\n\n/**\n * Optional dependency overrides for `run`. Tests use these to avoid\n * spawning the real setup wizard, the real update background check,\n * and the real update banner. Production callers pass nothing.\n */\nexport interface RunDeps {\n /** Replace the setup wizard (bare `codealmanac` / `almanac setup`). */\n runSetup?: typeof runSetup;\n /** Replace the bare-`codealmanac` global install bootstrapper. */\n runCodealmanacBootstrap?: typeof runCodealmanacBootstrap;\n /** Replace the pre-command update-nag banner. */\n announceUpdate?: (stderr: NodeJS.WritableStream) => void;\n /** Replace the post-command background update check scheduler. */\n scheduleUpdateCheck?: (argv: string[]) => void;\n /** Replace the internal update-check worker (run on --internal-check-updates). */\n runInternalUpdateCheck?: () => Promise<void>;\n}\n\n/**\n * Process-level CLI entrypoint. This owns invocation-level behavior:\n * update checks, bare `codealmanac` setup routing, Commander creation,\n * grouped help, and parsing. Individual command wiring lives in\n * `src/cli/register-commands.ts`.\n */\nexport async function run(argv: string[], deps: RunDeps = {}): Promise<void> {\n const runSetupFn = deps.runSetup ?? runSetup;\n const runCodealmanacBootstrapFn =\n deps.runCodealmanacBootstrap ?? runCodealmanacBootstrap;\n const announceUpdateFn = deps.announceUpdate ?? announceUpdateIfAvailable;\n const scheduleUpdateCheckFn =\n deps.scheduleUpdateCheck ?? scheduleBackgroundUpdateCheck;\n const runInternalUpdateCheckFn =\n deps.runInternalUpdateCheck ?? runInternalUpdateCheck;\n\n if (argv.slice(2).includes(\"--internal-check-updates\")) {\n await runInternalUpdateCheckFn();\n return;\n }\n\n const programName = getProgramName(argv);\n\n announceUpdateFn(process.stderr);\n scheduleUpdateCheckFn(argv);\n\n const program = new Command();\n program\n .name(programName)\n .description(\n \"codealmanac — a living wiki for codebases, maintained by AI agents\",\n )\n .version(readPackageVersion(), \"-v, --version\", \"print version\");\n\n if (isRootVersionInvocation(argv.slice(2))) {\n await program.parseAsync(argv);\n return;\n }\n\n if (programName === \"codealmanac\") {\n const setupInvocation = tryParseSetupShortcut(argv.slice(2));\n if (setupInvocation !== null) {\n if (deps.runCodealmanacBootstrap !== undefined) {\n emit(\n await runCodealmanacBootstrapFn({\n setupOptions: setupInvocation,\n setupArgs: argv.slice(2),\n }),\n );\n } else if (deps.runSetup !== undefined) {\n emit(await runSetupFn(setupInvocation));\n } else {\n emit(\n await runCodealmanacBootstrapFn({\n setupOptions: setupInvocation,\n setupArgs: argv.slice(2),\n }),\n );\n }\n return;\n }\n }\n\n if (await tryRunSqliteFreeCommand(argv.slice(2), runSetupFn)) {\n return;\n }\n\n const { registerCommands } = await import(\"./cli/register-commands.js\");\n registerCommands(program);\n configureGroupedHelp(program);\n\n await program.parseAsync(argv);\n}\n\nfunction getProgramName(argv: string[]): \"almanac\" | \"codealmanac\" {\n const invoked = argv[1] !== undefined ? basename(argv[1]) : \"almanac\";\n return invoked === \"codealmanac\" ? \"codealmanac\" : \"almanac\";\n}\n\nfunction isRootVersionInvocation(args: string[]): boolean {\n return args.length === 1 && (args[0] === \"--version\" || args[0] === \"-v\");\n}\n\nfunction parseSetupFlags(args: string[]): {\n yes?: boolean;\n agent?: string;\n skipHook?: boolean;\n skipGuides?: boolean;\n} {\n const agentIdx = args.indexOf(\"--agent\");\n return {\n yes: args.includes(\"--yes\") || args.includes(\"-y\"),\n agent: agentIdx === -1 ? undefined : args[agentIdx + 1],\n skipHook: args.includes(\"--skip-hook\"),\n skipGuides: args.includes(\"--skip-guides\"),\n };\n}\n\nfunction parseUpdateFlags(args: string[]): {\n dismiss?: boolean;\n check?: boolean;\n enableNotifier?: boolean;\n disableNotifier?: boolean;\n} {\n return {\n dismiss: args.includes(\"--dismiss\"),\n check: args.includes(\"--check\"),\n enableNotifier: args.includes(\"--enable-notifier\"),\n disableNotifier: args.includes(\"--disable-notifier\"),\n };\n}\n\nfunction parseUninstallFlags(args: string[]): {\n yes?: boolean;\n keepHook?: boolean;\n keepGuides?: boolean;\n} {\n return {\n yes: args.includes(\"--yes\") || args.includes(\"-y\"),\n keepHook: args.includes(\"--keep-hook\"),\n keepGuides: args.includes(\"--keep-guides\"),\n };\n}\n\nfunction parseDoctorFlags(args: string[]): {\n json?: boolean;\n installOnly?: boolean;\n wikiOnly?: boolean;\n} {\n return {\n json: args.includes(\"--json\"),\n installOnly: args.includes(\"--install-only\"),\n wikiOnly: args.includes(\"--wiki-only\"),\n };\n}\n\nasync function tryRunSqliteFreeCommand(\n args: string[],\n runSetupFn: typeof runSetup,\n): Promise<boolean> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) return false;\n\n const [command, subcommand] = args;\n if (command === undefined) return false;\n\n if (command === \"setup\") {\n emit(await runSetupFn(parseSetupFlags(args.slice(1))));\n return true;\n }\n\n if (command === \"hook\") {\n const { runHookInstall, runHookStatus, runHookUninstall } = await import(\n \"./commands/hook.js\"\n );\n if (subcommand === \"install\") {\n emit(await runHookInstall({ source: parseHookSource(args.slice(2)) }));\n return true;\n }\n if (subcommand === \"uninstall\") {\n emit(await runHookUninstall());\n return true;\n }\n if (subcommand === \"status\") {\n emit(await runHookStatus());\n return true;\n }\n return false;\n }\n\n if (command === \"agents\") {\n const { runAgentsList } = await import(\"./commands/agents.js\");\n if (subcommand === \"list\" || subcommand === undefined) {\n emit(await runAgentsList());\n return true;\n }\n return false;\n }\n\n if (command === \"set\") {\n const { runSetAgentModel, runSetDefaultAgent } = await import(\n \"./commands/agents.js\"\n );\n if (subcommand === \"default-agent\") {\n emit(await runSetDefaultAgent({ provider: args[2] ?? \"\" }));\n return true;\n }\n if (subcommand === \"model\") {\n emit(await runSetAgentModel({ provider: args[2] ?? \"\", model: args[3] }));\n return true;\n }\n return false;\n }\n\n if (command === \"update\") {\n const { runUpdate } = await import(\"./commands/update.js\");\n emit(await runUpdate(parseUpdateFlags(args.slice(1))));\n return true;\n }\n\n if (command === \"doctor\") {\n const { runDoctor } = await import(\"./commands/doctor.js\");\n emit(await runDoctor({\n cwd: process.cwd(),\n ...parseDoctorFlags(args.slice(1)),\n }));\n return true;\n }\n\n if (command === \"uninstall\") {\n const { runUninstall } = await import(\"./commands/uninstall.js\");\n emit(await runUninstall(parseUninstallFlags(args.slice(1))));\n return true;\n }\n\n return false;\n}\n\nfunction parseHookSource(\n args: string[],\n): \"claude\" | \"codex\" | \"cursor\" | \"all\" | undefined {\n const idx = args.indexOf(\"--source\");\n const value = idx === -1 ? undefined : args[idx + 1];\n if (\n value === \"claude\" ||\n value === \"codex\" ||\n value === \"cursor\" ||\n value === \"all\"\n ) {\n return value;\n }\n return undefined;\n}\n\nfunction readPackageVersion(): string {\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../package.json\") as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall back to \"unknown\" rather than crashing the CLI on a broken install.\n }\n return \"unknown\";\n}\n\nexport interface SetupShortcutOptions {\n yes?: boolean;\n agent?: string;\n skipHook?: boolean;\n skipGuides?: boolean;\n}\n\n/**\n * Decide whether a bare `codealmanac [...args]` invocation should route\n * straight to `runSetup` (and if so, with which flags). Returns the\n * options object when it's a setup shortcut, or `null` when Commander\n * should parse the invocation normally.\n */\nexport function tryParseSetupShortcut(args: string[]): SetupShortcutOptions | null {\n if (args.length === 0) return {};\n\n const opts: SetupShortcutOptions = {};\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n if (arg === \"--yes\" || arg === \"-y\") {\n opts.yes = true;\n continue;\n }\n if (arg === \"--agent\") {\n opts.agent = args[i + 1];\n i += 1;\n continue;\n }\n if (arg === \"--skip-hook\") {\n opts.skipHook = true;\n continue;\n }\n if (arg === \"--skip-guides\") {\n opts.skipGuides = true;\n continue;\n }\n return null;\n }\n return opts;\n}\n","import { Command, type Help } from \"commander\";\n\nimport { BLUE, BOLD, DIM, RST } from \"../ansi.js\";\n\nconst HELP_GROUPS: Array<{ title: string; commands: string[] }> = [\n {\n title: \"Query\",\n commands: [\"search\", \"show\", \"health\", \"list\"],\n },\n {\n title: \"Edit\",\n commands: [\"tag\", \"untag\", \"topics\"],\n },\n {\n title: \"Wiki lifecycle\",\n commands: [\"bootstrap\", \"capture\", \"ps\", \"hook\", \"reindex\"],\n },\n {\n title: \"Setup\",\n commands: [\"setup\", \"uninstall\", \"doctor\", \"update\"],\n },\n];\n\n/**\n * Install a custom `formatHelp` that replaces commander's flat\n * \"Commands:\" section with grouped headings. Keeps usage + options +\n * per-command short descriptions; only the commands section changes.\n */\nexport function configureGroupedHelp(program: Command): void {\n program.configureHelp({\n formatHelp(cmd, helper): string {\n if (cmd.parent !== null) {\n return renderDefault(cmd, helper);\n }\n\n const termWidth = helper.padWidth(cmd, helper);\n const helpWidth =\n helper.helpWidth ?? process.stdout.columns ?? 80;\n const itemSepWidth = 2;\n\n const out: string[] = [];\n out.push(`${BOLD}Usage:${RST} ${helper.commandUsage(cmd)}\\n`);\n\n const description = helper.commandDescription(cmd);\n if (description.length > 0) {\n out.push(\n helper.wrap(description, helpWidth, 0) + \"\\n\",\n );\n }\n\n const optionList = helper\n .visibleOptions(cmd)\n .map((o) => {\n const term = helper.optionTerm(o);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.optionDescription(o)}${RST}`;\n });\n if (optionList.length > 0) {\n out.push(`${BOLD}Options:${RST}`);\n for (const l of optionList) out.push(` ${l}`);\n out.push(\"\");\n }\n\n const visible = helper.visibleCommands(cmd);\n const byName = new Map<string, (typeof visible)[number]>();\n for (const c of visible) byName.set(c.name(), c);\n\n for (const group of HELP_GROUPS) {\n const members = group.commands\n .map((n) => byName.get(n))\n .filter((c): c is (typeof visible)[number] => c !== undefined);\n if (members.length === 0) continue;\n out.push(`${BOLD}${group.title}:${RST}`);\n for (const c of members) {\n const term = helper.subcommandTerm(c);\n const desc = helper.subcommandDescription(c);\n const padding = Math.max(\n 0,\n termWidth - term.length + itemSepWidth,\n );\n out.push(` ${BLUE}${term}${RST}${\" \".repeat(padding)}${DIM}${desc}${RST}`);\n byName.delete(c.name());\n }\n out.push(\"\");\n }\n\n byName.delete(\"help\");\n if (byName.size > 0) {\n out.push(`${BOLD}Other:${RST}`);\n for (const c of byName.values()) {\n const term = helper.subcommandTerm(c);\n const desc = helper.subcommandDescription(c);\n const padding = Math.max(\n 0,\n termWidth - term.length + itemSepWidth,\n );\n out.push(` ${BLUE}${term}${RST}${\" \".repeat(padding)}${DIM}${desc}${RST}`);\n }\n out.push(\"\");\n }\n\n return out.join(\"\\n\");\n },\n });\n}\n\nfunction renderDefault(cmd: Command, helper: Help): string {\n const termWidth = helper.padWidth(cmd, helper);\n const helpWidth = helper.helpWidth ?? process.stdout.columns ?? 80;\n const itemSepWidth = 2;\n\n const lines: string[] = [`${BOLD}Usage:${RST} ${helper.commandUsage(cmd)}\\n`];\n const description = helper.commandDescription(cmd);\n if (description.length > 0) {\n lines.push(helper.wrap(description, helpWidth, 0) + \"\\n\");\n }\n\n const args = helper.visibleArguments(cmd).map((a) => {\n const term = helper.argumentTerm(a);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.argumentDescription(a)}${RST}`;\n });\n if (args.length > 0) {\n lines.push(`${BOLD}Arguments:${RST}`);\n for (const a of args) lines.push(` ${a}`);\n lines.push(\"\");\n }\n\n const opts = helper.visibleOptions(cmd).map((o) => {\n const term = helper.optionTerm(o);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.optionDescription(o)}${RST}`;\n });\n if (opts.length > 0) {\n lines.push(`${BOLD}Options:${RST}`);\n for (const o of opts) lines.push(` ${o}`);\n lines.push(\"\");\n }\n\n const subs = helper.visibleCommands(cmd).map((c) => {\n const term = helper.subcommandTerm(c);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.subcommandDescription(c)}${RST}`;\n });\n if (subs.length > 0) {\n lines.push(`${BOLD}Commands:${RST}`);\n for (const s of subs) lines.push(` ${s}`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","import { spawn, type SpawnOptions } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { runSetup, type SetupOptions, type SetupResult } from \"../commands/setup.js\";\nimport { isNewer } from \"../update/semver.js\";\n\n/**\n * Bare `codealmanac` is the npm bootstrap surface. When it is invoked\n * through `npx`, the running package can live in a temporary cache; if\n * setup installed hooks from that copy, the hook path could disappear\n * later. This helper makes the promise durable:\n *\n * 1. If already running from the global npm package, run setup locally.\n * 2. Otherwise ensure `npm i -g codealmanac@latest` has succeeded.\n * 3. Re-run `setup` from the global package entry point.\n */\n\nexport interface CodealmanacBootstrapOptions {\n setupOptions: SetupOptions;\n setupArgs: string[];\n\n // Injection points for tests.\n runSetup?: typeof runSetup;\n spawnFn?: typeof spawn;\n currentPackageRoot?: string;\n globalPackageRoot?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nconst SKIP_BOOTSTRAP_ENV = \"CODEALMANAC_SKIP_GLOBAL_BOOTSTRAP\";\n\nexport async function runCodealmanacBootstrap(\n opts: CodealmanacBootstrapOptions,\n): Promise<SetupResult> {\n const env = opts.env ?? process.env;\n const runSetupFn = opts.runSetup ?? runSetup;\n const currentRoot = opts.currentPackageRoot ?? findCurrentPackageRoot();\n\n if (env[SKIP_BOOTSTRAP_ENV] === \"1\") {\n return await runSetupFn(opts.setupOptions);\n }\n\n const globalRootResult =\n opts.globalPackageRoot !== undefined\n ? { ok: true as const, path: opts.globalPackageRoot }\n : await resolveGlobalPackageRoot(opts.spawnFn ?? spawn);\n\n if (!globalRootResult.ok) {\n return {\n stdout: \"\",\n stderr: globalRootResult.stderr,\n exitCode: 1,\n };\n }\n\n const globalRoot = globalRootResult.path;\n if (samePath(currentRoot, globalRoot)) {\n return await runSetupFn(opts.setupOptions);\n }\n\n if (await shouldInstallGlobal(currentRoot, globalRoot)) {\n const install = await spawnInherited(\n opts.spawnFn ?? spawn,\n \"npm\",\n [\"i\", \"-g\", \"codealmanac@latest\"],\n env,\n );\n if (install.exitCode !== 0) {\n return {\n stdout: \"\",\n stderr:\n `codealmanac: npm install failed (exit ${install.exitCode}).\\n` +\n `If you see \"EACCES\" above, try: sudo npm i -g codealmanac@latest\\n` +\n `Or install with a version manager (nvm, volta, fnm) to avoid sudo.\\n`,\n exitCode: install.exitCode,\n };\n }\n }\n\n const entry = path.join(globalRoot, \"dist\", \"codealmanac.js\");\n const rerun = await spawnInherited(\n opts.spawnFn ?? spawn,\n process.execPath,\n [entry, \"setup\", ...opts.setupArgs],\n {\n ...env,\n [SKIP_BOOTSTRAP_ENV]: \"1\",\n },\n );\n\n return {\n stdout: \"\",\n stderr: \"\",\n exitCode: rerun.exitCode,\n };\n}\n\nasync function shouldInstallGlobal(\n currentRoot: string,\n globalRoot: string,\n): Promise<boolean> {\n const globalVersion = await readPackageVersion(globalRoot);\n if (globalVersion === null) return true;\n\n const currentVersion = await readPackageVersion(currentRoot);\n if (currentVersion === null) return false;\n\n return isNewer(currentVersion, globalVersion);\n}\n\nfunction samePath(a: string, b: string): boolean {\n return path.resolve(a) === path.resolve(b);\n}\n\nasync function readPackageVersion(root: string): Promise<string | null> {\n try {\n const raw = await readFile(path.join(root, \"package.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n return typeof parsed.version === \"string\" && parsed.version.length > 0\n ? parsed.version\n : null;\n } catch {\n return null;\n }\n}\n\nfunction findCurrentPackageRoot(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n // Bundled: `.../codealmanac/dist/codealmanac.js` -> package root.\n path.resolve(here, \"..\"),\n // Source: `.../codealmanac/src/install/global.ts` -> package root.\n path.resolve(here, \"..\", \"..\"),\n ];\n\n for (const candidate of candidates) {\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(path.join(candidate, \"package.json\")) as {\n name?: unknown;\n };\n if (pkg.name === \"codealmanac\") return candidate;\n } catch {\n // Try the next layout.\n }\n }\n\n return path.resolve(here, \"..\", \"..\");\n}\n\nasync function resolveGlobalPackageRoot(\n spawnFn: typeof spawn,\n): Promise<{ ok: true; path: string } | { ok: false; stderr: string }> {\n const result = await spawnCaptured(spawnFn, \"npm\", [\"root\", \"-g\"]);\n if (result.exitCode !== 0) {\n return {\n ok: false,\n stderr:\n \"codealmanac: could not find npm's global install directory.\\n\" +\n \"Install Node.js + npm, or install codealmanac via your package manager.\\n\",\n };\n }\n\n const root = result.stdout.trim();\n if (root.length === 0) {\n return {\n ok: false,\n stderr:\n \"codealmanac: npm returned an empty global install directory.\\n\" +\n \"Try: npm root -g\\n\",\n };\n }\n\n return { ok: true, path: path.join(root, \"codealmanac\") };\n}\n\nasync function spawnInherited(\n spawnFn: typeof spawn,\n cmd: string,\n args: string[],\n env: NodeJS.ProcessEnv,\n): Promise<{ exitCode: number }> {\n return await new Promise((resolve) => {\n const child = spawnFn(cmd, args, {\n stdio: \"inherit\",\n env,\n });\n\n child.on(\"error\", () => {\n resolve({ exitCode: 1 });\n });\n child.on(\"exit\", (code) => {\n resolve({ exitCode: code ?? 1 });\n });\n });\n}\n\nasync function spawnCaptured(\n spawnFn: typeof spawn,\n cmd: string,\n args: string[],\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return await new Promise((resolve) => {\n const child = spawnFn(cmd, args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n } as SpawnOptions);\n const stdout: Buffer[] = [];\n const stderr: Buffer[] = [];\n\n child.stdout?.on(\"data\", (chunk: Buffer | string) => {\n stdout.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n child.stderr?.on(\"data\", (chunk: Buffer | string) => {\n stderr.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n child.on(\"error\", (err: NodeJS.ErrnoException) => {\n resolve({\n stdout: \"\",\n stderr: err.message,\n exitCode: 1,\n });\n });\n child.on(\"exit\", (code) => {\n resolve({\n stdout: Buffer.concat(stdout).toString(\"utf8\"),\n stderr: Buffer.concat(stderr).toString(\"utf8\"),\n exitCode: code ?? 1,\n });\n });\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\n\nimport { getConfigPath } from \"./config.js\";\nimport { isNewer } from \"./semver.js\";\nimport { getStatePath, type UpdateState } from \"./state.js\";\n\n/**\n * Pre-command update-nag banner. Runs synchronously at the very top of\n * every `run()` invocation, before commander even touches argv. Prints\n * one line to stderr if:\n *\n * 1. `~/.almanac/update-state.json` exists and parses.\n * 2. `latest_version` is strictly newer than `installed_version`.\n * 3. `latest_version` is NOT in `dismissed_versions`.\n * 4. `~/.almanac/config.json`.`update_notifier` is not `false`.\n *\n * Otherwise silent. Deliberately synchronous and filesystem-blocking:\n * this runs in the CLI critical path and waiting on a Promise would\n * force every command to become async upfront. The files are tiny\n * (<1KB each); a sync read is cheap.\n *\n * Why stderr: agents and scripts parse stdout; stderr is the\n * conventional channel for diagnostics and nags. A tool piping\n * `almanac search` into `xargs` shouldn't see the banner mixed into\n * its slug list. Users running interactively see stderr anyway, so\n * the nag is visible in practice.\n */\n\nexport interface AnnounceOptions {\n statePath?: string;\n configPath?: string;\n /** Override for tests — normally reads from package.json at import time. */\n installedVersion?: string;\n /** Enable ANSI coloring regardless of isTTY. Tests pass `false`. */\n color?: boolean;\n}\n\nconst RST = \"\\x1b[0m\";\nconst BOLD = \"\\x1b[1m\";\nconst YELLOW = \"\\x1b[33m\";\n\nexport function announceUpdateIfAvailable(\n stderr: NodeJS.WritableStream,\n opts: AnnounceOptions = {},\n): void {\n const statePath = opts.statePath ?? getStatePath();\n const configPath = opts.configPath ?? getConfigPath();\n const installed = opts.installedVersion ?? readInstalledVersion();\n\n // Config gate. Must be checked before state: a user who disabled the\n // notifier shouldn't pay even a state-file read.\n if (!shouldNotify(configPath)) return;\n\n const state = readStateSync(statePath);\n if (state === null) return;\n if (state.latest_version.length === 0) return;\n if (!isNewer(state.latest_version, installed)) return;\n if (state.dismissed_versions.includes(state.latest_version)) return;\n\n const useColor =\n opts.color ?? (process.stderr.isTTY === true && !(\"NO_COLOR\" in process.env));\n const warn = useColor ? `${YELLOW}${BOLD}\\u26a0${RST}` : \"!\";\n const cmd = useColor ? `${BOLD}almanac update${RST}` : \"almanac update\";\n stderr.write(\n `${warn} codealmanac ${state.latest_version} available ` +\n `(you're on ${installed}) — run: ${cmd}\\n`,\n );\n}\n\n/**\n * Sync-read the state file. Returns `null` when missing, empty, or\n * malformed — the announce path MUST NOT throw into the CLI critical\n * path. Avoids the `async readState` used by the worker because\n * `run()` would otherwise need `await announceUpdateIfAvailable(...)`\n * on every invocation, which turns into a multi-millisecond penalty\n * on commands that don't care.\n */\nfunction readStateSync(path: string): UpdateState | null {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n const trimmed = raw.trim();\n if (trimmed.length === 0) return null;\n try {\n const parsed = JSON.parse(trimmed) as Partial<UpdateState>;\n return {\n last_check_at:\n typeof parsed.last_check_at === \"number\" ? parsed.last_check_at : 0,\n installed_version:\n typeof parsed.installed_version === \"string\"\n ? parsed.installed_version\n : \"\",\n latest_version:\n typeof parsed.latest_version === \"string\" ? parsed.latest_version : \"\",\n dismissed_versions: Array.isArray(parsed.dismissed_versions)\n ? parsed.dismissed_versions.filter(\n (v): v is string => typeof v === \"string\",\n )\n : [],\n };\n } catch {\n return null;\n }\n}\n\nfunction shouldNotify(configPath: string): boolean {\n let raw: string;\n try {\n raw = readFileSync(configPath, \"utf8\");\n } catch {\n return true; // no config file → default notify on\n }\n const trimmed = raw.trim();\n if (trimmed.length === 0) return true;\n try {\n const parsed = JSON.parse(trimmed) as { update_notifier?: unknown };\n if (parsed.update_notifier === false) return false;\n return true;\n } catch {\n return true;\n }\n}\n\nfunction readInstalledVersion(): string {\n // Dev: `src/update/announce.ts` → `../../package.json`. Bundled:\n // `dist/codealmanac.js` → `../package.json`. Try both.\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../../package.json\") as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall through.\n }\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../package.json\") as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall through.\n }\n return \"unknown\";\n}\n"],"mappings":"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","names":["createRequire","require","createRequire","RST","BOLD","path","require","createRequire","readPackageVersion","require","createRequire"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/cli/help.ts","../src/install/global.ts","../src/update/announce.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { basename } from \"node:path\";\n\nimport { Command } from \"commander\";\n\nimport { runSetup } from \"./commands/setup.js\";\nimport { configureGroupedHelp } from \"./cli/help.js\";\nimport { emit } from \"./cli/helpers.js\";\nimport { runCodealmanacBootstrap } from \"./install/global.js\";\nimport { announceUpdateIfAvailable } from \"./update/announce.js\";\nimport {\n runInternalUpdateCheck,\n scheduleBackgroundUpdateCheck,\n} from \"./update/schedule.js\";\n\n/**\n * Optional dependency overrides for `run`. Tests use these to avoid\n * spawning the real setup wizard, the real update background check,\n * and the real update banner. Production callers pass nothing.\n */\nexport interface RunDeps {\n /** Replace the setup wizard (bare `codealmanac` / `almanac setup`). */\n runSetup?: typeof runSetup;\n /** Replace the bare-`codealmanac` global install bootstrapper. */\n runCodealmanacBootstrap?: typeof runCodealmanacBootstrap;\n /** Replace the pre-command update-nag banner. */\n announceUpdate?: (stderr: NodeJS.WritableStream) => void;\n /** Replace the post-command background update check scheduler. */\n scheduleUpdateCheck?: (argv: string[]) => void;\n /** Replace the internal update-check worker (run on --internal-check-updates). */\n runInternalUpdateCheck?: () => Promise<void>;\n}\n\n/**\n * Process-level CLI entrypoint. This owns invocation-level behavior:\n * update checks, bare `codealmanac` setup routing, Commander creation,\n * grouped help, and parsing. Individual command wiring lives in\n * `src/cli/register-commands.ts`.\n */\nexport async function run(argv: string[], deps: RunDeps = {}): Promise<void> {\n const runSetupFn = deps.runSetup ?? runSetup;\n const runCodealmanacBootstrapFn =\n deps.runCodealmanacBootstrap ?? runCodealmanacBootstrap;\n const announceUpdateFn = deps.announceUpdate ?? announceUpdateIfAvailable;\n const scheduleUpdateCheckFn =\n deps.scheduleUpdateCheck ?? scheduleBackgroundUpdateCheck;\n const runInternalUpdateCheckFn =\n deps.runInternalUpdateCheck ?? runInternalUpdateCheck;\n\n if (argv.slice(2).includes(\"--internal-check-updates\")) {\n await runInternalUpdateCheckFn();\n return;\n }\n\n const programName = getProgramName(argv);\n\n announceUpdateFn(process.stderr);\n scheduleUpdateCheckFn(argv);\n\n const program = new Command();\n program\n .name(programName)\n .description(\n \"codealmanac — a living wiki for codebases, maintained by AI agents\",\n )\n .version(readPackageVersion(), \"-v, --version\", \"print version\");\n\n if (isRootVersionInvocation(argv.slice(2))) {\n await program.parseAsync(argv);\n return;\n }\n\n if (programName === \"codealmanac\") {\n const setupInvocation = tryParseSetupShortcut(argv.slice(2));\n if (setupInvocation !== null) {\n if (deps.runCodealmanacBootstrap !== undefined) {\n emit(\n await runCodealmanacBootstrapFn({\n setupOptions: setupInvocation,\n setupArgs: argv.slice(2),\n }),\n );\n } else if (deps.runSetup !== undefined) {\n emit(await runSetupFn(setupInvocation));\n } else {\n emit(\n await runCodealmanacBootstrapFn({\n setupOptions: setupInvocation,\n setupArgs: argv.slice(2),\n }),\n );\n }\n return;\n }\n }\n\n if (await tryRunSqliteFreeCommand(argv.slice(2), runSetupFn)) {\n return;\n }\n\n const { registerCommands } = await import(\"./cli/register-commands.js\");\n registerCommands(program);\n configureGroupedHelp(program);\n\n await program.parseAsync(argv);\n}\n\nfunction getProgramName(argv: string[]): \"almanac\" | \"codealmanac\" {\n const invoked = argv[1] !== undefined ? basename(argv[1]) : \"almanac\";\n return invoked === \"codealmanac\" ? \"codealmanac\" : \"almanac\";\n}\n\nfunction isRootVersionInvocation(args: string[]): boolean {\n return args.length === 1 && (args[0] === \"--version\" || args[0] === \"-v\");\n}\n\nfunction parseSetupFlags(args: string[]): {\n yes?: boolean;\n agent?: string;\n skipHook?: boolean;\n skipGuides?: boolean;\n} {\n const agentIdx = args.indexOf(\"--agent\");\n return {\n yes: args.includes(\"--yes\") || args.includes(\"-y\"),\n agent: agentIdx === -1 ? undefined : args[agentIdx + 1],\n skipHook: args.includes(\"--skip-hook\"),\n skipGuides: args.includes(\"--skip-guides\"),\n };\n}\n\nfunction parseUpdateFlags(args: string[]): {\n dismiss?: boolean;\n check?: boolean;\n enableNotifier?: boolean;\n disableNotifier?: boolean;\n} {\n return {\n dismiss: args.includes(\"--dismiss\"),\n check: args.includes(\"--check\"),\n enableNotifier: args.includes(\"--enable-notifier\"),\n disableNotifier: args.includes(\"--disable-notifier\"),\n };\n}\n\nfunction parseUninstallFlags(args: string[]): {\n yes?: boolean;\n keepHook?: boolean;\n keepGuides?: boolean;\n} {\n return {\n yes: args.includes(\"--yes\") || args.includes(\"-y\"),\n keepHook: args.includes(\"--keep-hook\"),\n keepGuides: args.includes(\"--keep-guides\"),\n };\n}\n\nfunction parseDoctorFlags(args: string[]): {\n json?: boolean;\n installOnly?: boolean;\n wikiOnly?: boolean;\n} {\n return {\n json: args.includes(\"--json\"),\n installOnly: args.includes(\"--install-only\"),\n wikiOnly: args.includes(\"--wiki-only\"),\n };\n}\n\nasync function tryRunSqliteFreeCommand(\n args: string[],\n runSetupFn: typeof runSetup,\n): Promise<boolean> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) return false;\n\n const [command, subcommand] = args;\n if (command === undefined) return false;\n\n if (command === \"setup\") {\n emit(await runSetupFn(parseSetupFlags(args.slice(1))));\n return true;\n }\n\n if (command === \"hook\") {\n const { runHookInstall, runHookStatus, runHookUninstall } = await import(\n \"./commands/hook.js\"\n );\n if (subcommand === \"install\") {\n emit(await runHookInstall({ source: parseHookSource(args.slice(2)) }));\n return true;\n }\n if (subcommand === \"uninstall\") {\n emit(await runHookUninstall());\n return true;\n }\n if (subcommand === \"status\") {\n emit(await runHookStatus());\n return true;\n }\n return false;\n }\n\n if (command === \"agents\") {\n const { runAgentsList } = await import(\"./commands/agents.js\");\n if (subcommand === \"list\" || subcommand === undefined) {\n emit(await runAgentsList());\n return true;\n }\n return false;\n }\n\n if (command === \"set\") {\n const { runSetAgentModel, runSetDefaultAgent } = await import(\n \"./commands/agents.js\"\n );\n if (subcommand === \"default-agent\") {\n emit(await runSetDefaultAgent({ provider: args[2] ?? \"\" }));\n return true;\n }\n if (subcommand === \"model\") {\n emit(await runSetAgentModel({ provider: args[2] ?? \"\", model: args[3] }));\n return true;\n }\n return false;\n }\n\n if (command === \"update\") {\n const { runUpdate } = await import(\"./commands/update.js\");\n emit(await runUpdate(parseUpdateFlags(args.slice(1))));\n return true;\n }\n\n if (command === \"doctor\") {\n const { runDoctor } = await import(\"./commands/doctor.js\");\n emit(await runDoctor({\n cwd: process.cwd(),\n ...parseDoctorFlags(args.slice(1)),\n }));\n return true;\n }\n\n if (command === \"uninstall\") {\n const { runUninstall } = await import(\"./commands/uninstall.js\");\n emit(await runUninstall(parseUninstallFlags(args.slice(1))));\n return true;\n }\n\n return false;\n}\n\nfunction parseHookSource(\n args: string[],\n): \"claude\" | \"codex\" | \"cursor\" | \"all\" | undefined {\n const idx = args.indexOf(\"--source\");\n const value = idx === -1 ? undefined : args[idx + 1];\n if (\n value === \"claude\" ||\n value === \"codex\" ||\n value === \"cursor\" ||\n value === \"all\"\n ) {\n return value;\n }\n return undefined;\n}\n\nfunction readPackageVersion(): string {\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../package.json\") as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall back to \"unknown\" rather than crashing the CLI on a broken install.\n }\n return \"unknown\";\n}\n\nexport interface SetupShortcutOptions {\n yes?: boolean;\n agent?: string;\n skipHook?: boolean;\n skipGuides?: boolean;\n}\n\n/**\n * Decide whether a bare `codealmanac [...args]` invocation should route\n * straight to `runSetup` (and if so, with which flags). Returns the\n * options object when it's a setup shortcut, or `null` when Commander\n * should parse the invocation normally.\n */\nexport function tryParseSetupShortcut(args: string[]): SetupShortcutOptions | null {\n if (args.length === 0) return {};\n\n const opts: SetupShortcutOptions = {};\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n if (arg === \"--yes\" || arg === \"-y\") {\n opts.yes = true;\n continue;\n }\n if (arg === \"--agent\") {\n opts.agent = args[i + 1];\n i += 1;\n continue;\n }\n if (arg === \"--skip-hook\") {\n opts.skipHook = true;\n continue;\n }\n if (arg === \"--skip-guides\") {\n opts.skipGuides = true;\n continue;\n }\n return null;\n }\n return opts;\n}\n","import { Command, type Help } from \"commander\";\n\nimport { BLUE, BOLD, DIM, RST } from \"../ansi.js\";\n\nconst HELP_GROUPS: Array<{ title: string; commands: string[] }> = [\n {\n title: \"Query\",\n commands: [\"search\", \"show\", \"health\", \"list\"],\n },\n {\n title: \"Edit\",\n commands: [\"tag\", \"untag\", \"topics\"],\n },\n {\n title: \"Wiki lifecycle\",\n commands: [\"bootstrap\", \"capture\", \"ps\", \"hook\", \"reindex\"],\n },\n {\n title: \"Setup\",\n commands: [\"setup\", \"uninstall\", \"doctor\", \"update\"],\n },\n];\n\n/**\n * Install a custom `formatHelp` that replaces commander's flat\n * \"Commands:\" section with grouped headings. Keeps usage + options +\n * per-command short descriptions; only the commands section changes.\n */\nexport function configureGroupedHelp(program: Command): void {\n program.configureHelp({\n formatHelp(cmd, helper): string {\n if (cmd.parent !== null) {\n return renderDefault(cmd, helper);\n }\n\n const termWidth = helper.padWidth(cmd, helper);\n const helpWidth =\n helper.helpWidth ?? process.stdout.columns ?? 80;\n const itemSepWidth = 2;\n\n const out: string[] = [];\n out.push(`${BOLD}Usage:${RST} ${helper.commandUsage(cmd)}\\n`);\n\n const description = helper.commandDescription(cmd);\n if (description.length > 0) {\n out.push(\n helper.wrap(description, helpWidth, 0) + \"\\n\",\n );\n }\n\n const optionList = helper\n .visibleOptions(cmd)\n .map((o) => {\n const term = helper.optionTerm(o);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.optionDescription(o)}${RST}`;\n });\n if (optionList.length > 0) {\n out.push(`${BOLD}Options:${RST}`);\n for (const l of optionList) out.push(` ${l}`);\n out.push(\"\");\n }\n\n const visible = helper.visibleCommands(cmd);\n const byName = new Map<string, (typeof visible)[number]>();\n for (const c of visible) byName.set(c.name(), c);\n\n for (const group of HELP_GROUPS) {\n const members = group.commands\n .map((n) => byName.get(n))\n .filter((c): c is (typeof visible)[number] => c !== undefined);\n if (members.length === 0) continue;\n out.push(`${BOLD}${group.title}:${RST}`);\n for (const c of members) {\n const term = helper.subcommandTerm(c);\n const desc = helper.subcommandDescription(c);\n const padding = Math.max(\n 0,\n termWidth - term.length + itemSepWidth,\n );\n out.push(` ${BLUE}${term}${RST}${\" \".repeat(padding)}${DIM}${desc}${RST}`);\n byName.delete(c.name());\n }\n out.push(\"\");\n }\n\n byName.delete(\"help\");\n if (byName.size > 0) {\n out.push(`${BOLD}Other:${RST}`);\n for (const c of byName.values()) {\n const term = helper.subcommandTerm(c);\n const desc = helper.subcommandDescription(c);\n const padding = Math.max(\n 0,\n termWidth - term.length + itemSepWidth,\n );\n out.push(` ${BLUE}${term}${RST}${\" \".repeat(padding)}${DIM}${desc}${RST}`);\n }\n out.push(\"\");\n }\n\n return out.join(\"\\n\");\n },\n });\n}\n\nfunction renderDefault(cmd: Command, helper: Help): string {\n const termWidth = helper.padWidth(cmd, helper);\n const helpWidth = helper.helpWidth ?? process.stdout.columns ?? 80;\n const itemSepWidth = 2;\n\n const lines: string[] = [`${BOLD}Usage:${RST} ${helper.commandUsage(cmd)}\\n`];\n const description = helper.commandDescription(cmd);\n if (description.length > 0) {\n lines.push(helper.wrap(description, helpWidth, 0) + \"\\n\");\n }\n\n const args = helper.visibleArguments(cmd).map((a) => {\n const term = helper.argumentTerm(a);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.argumentDescription(a)}${RST}`;\n });\n if (args.length > 0) {\n lines.push(`${BOLD}Arguments:${RST}`);\n for (const a of args) lines.push(` ${a}`);\n lines.push(\"\");\n }\n\n const opts = helper.visibleOptions(cmd).map((o) => {\n const term = helper.optionTerm(o);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.optionDescription(o)}${RST}`;\n });\n if (opts.length > 0) {\n lines.push(`${BOLD}Options:${RST}`);\n for (const o of opts) lines.push(` ${o}`);\n lines.push(\"\");\n }\n\n const subs = helper.visibleCommands(cmd).map((c) => {\n const term = helper.subcommandTerm(c);\n const pad = \" \".repeat(Math.max(0, termWidth - term.length) + itemSepWidth);\n return `${BLUE}${term}${RST}${pad}${DIM}${helper.subcommandDescription(c)}${RST}`;\n });\n if (subs.length > 0) {\n lines.push(`${BOLD}Commands:${RST}`);\n for (const s of subs) lines.push(` ${s}`);\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\");\n}\n","import { spawn, type SpawnOptions } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { runSetup, type SetupOptions, type SetupResult } from \"../commands/setup.js\";\nimport { isNewer } from \"../update/semver.js\";\n\n/**\n * Bare `codealmanac` is the npm bootstrap surface. When it is invoked\n * through `npx`, the running package can live in a temporary cache; if\n * setup installed hooks from that copy, the hook path could disappear\n * later. This helper makes the promise durable:\n *\n * 1. If already running from the global npm package, run setup locally.\n * 2. Otherwise ensure `npm i -g codealmanac@latest` has succeeded.\n * 3. Re-run `setup` from the global package entry point.\n */\n\nexport interface CodealmanacBootstrapOptions {\n setupOptions: SetupOptions;\n setupArgs: string[];\n\n // Injection points for tests.\n runSetup?: typeof runSetup;\n spawnFn?: typeof spawn;\n currentPackageRoot?: string;\n globalPackageRoot?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nconst SKIP_BOOTSTRAP_ENV = \"CODEALMANAC_SKIP_GLOBAL_BOOTSTRAP\";\n\nexport async function runCodealmanacBootstrap(\n opts: CodealmanacBootstrapOptions,\n): Promise<SetupResult> {\n const env = opts.env ?? process.env;\n const runSetupFn = opts.runSetup ?? runSetup;\n const currentRoot = opts.currentPackageRoot ?? findCurrentPackageRoot();\n\n if (env[SKIP_BOOTSTRAP_ENV] === \"1\") {\n return await runSetupFn(opts.setupOptions);\n }\n\n const globalRootResult =\n opts.globalPackageRoot !== undefined\n ? { ok: true as const, path: opts.globalPackageRoot }\n : await resolveGlobalPackageRoot(opts.spawnFn ?? spawn);\n\n if (!globalRootResult.ok) {\n return {\n stdout: \"\",\n stderr: globalRootResult.stderr,\n exitCode: 1,\n };\n }\n\n const globalRoot = globalRootResult.path;\n if (samePath(currentRoot, globalRoot)) {\n return await runSetupFn(opts.setupOptions);\n }\n\n if (await shouldInstallGlobal(currentRoot, globalRoot)) {\n const install = await spawnInherited(\n opts.spawnFn ?? spawn,\n \"npm\",\n [\"i\", \"-g\", \"codealmanac@latest\"],\n env,\n );\n if (install.exitCode !== 0) {\n return {\n stdout: \"\",\n stderr:\n `codealmanac: npm install failed (exit ${install.exitCode}).\\n` +\n `If you see \"EACCES\" above, try: sudo npm i -g codealmanac@latest\\n` +\n `Or install with a version manager (nvm, volta, fnm) to avoid sudo.\\n`,\n exitCode: install.exitCode,\n };\n }\n }\n\n const entry = path.join(globalRoot, \"dist\", \"codealmanac.js\");\n const rerun = await spawnInherited(\n opts.spawnFn ?? spawn,\n process.execPath,\n [entry, \"setup\", ...opts.setupArgs],\n {\n ...env,\n [SKIP_BOOTSTRAP_ENV]: \"1\",\n },\n );\n\n return {\n stdout: \"\",\n stderr: \"\",\n exitCode: rerun.exitCode,\n };\n}\n\nasync function shouldInstallGlobal(\n currentRoot: string,\n globalRoot: string,\n): Promise<boolean> {\n const globalVersion = await readPackageVersion(globalRoot);\n if (globalVersion === null) return true;\n\n const currentVersion = await readPackageVersion(currentRoot);\n if (currentVersion === null) return false;\n\n return isNewer(currentVersion, globalVersion);\n}\n\nfunction samePath(a: string, b: string): boolean {\n return path.resolve(a) === path.resolve(b);\n}\n\nasync function readPackageVersion(root: string): Promise<string | null> {\n try {\n const raw = await readFile(path.join(root, \"package.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n return typeof parsed.version === \"string\" && parsed.version.length > 0\n ? parsed.version\n : null;\n } catch {\n return null;\n }\n}\n\nfunction findCurrentPackageRoot(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n // Bundled: `.../codealmanac/dist/codealmanac.js` -> package root.\n path.resolve(here, \"..\"),\n // Source: `.../codealmanac/src/install/global.ts` -> package root.\n path.resolve(here, \"..\", \"..\"),\n ];\n\n for (const candidate of candidates) {\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(path.join(candidate, \"package.json\")) as {\n name?: unknown;\n };\n if (pkg.name === \"codealmanac\") return candidate;\n } catch {\n // Try the next layout.\n }\n }\n\n return path.resolve(here, \"..\", \"..\");\n}\n\nasync function resolveGlobalPackageRoot(\n spawnFn: typeof spawn,\n): Promise<{ ok: true; path: string } | { ok: false; stderr: string }> {\n const result = await spawnCaptured(spawnFn, \"npm\", [\"root\", \"-g\"]);\n if (result.exitCode !== 0) {\n return {\n ok: false,\n stderr:\n \"codealmanac: could not find npm's global install directory.\\n\" +\n \"Install Node.js + npm, or install codealmanac via your package manager.\\n\",\n };\n }\n\n const root = result.stdout.trim();\n if (root.length === 0) {\n return {\n ok: false,\n stderr:\n \"codealmanac: npm returned an empty global install directory.\\n\" +\n \"Try: npm root -g\\n\",\n };\n }\n\n return { ok: true, path: path.join(root, \"codealmanac\") };\n}\n\nasync function spawnInherited(\n spawnFn: typeof spawn,\n cmd: string,\n args: string[],\n env: NodeJS.ProcessEnv,\n): Promise<{ exitCode: number }> {\n return await new Promise((resolve) => {\n const child = spawnFn(cmd, args, {\n stdio: \"inherit\",\n env,\n });\n\n child.on(\"error\", () => {\n resolve({ exitCode: 1 });\n });\n child.on(\"exit\", (code) => {\n resolve({ exitCode: code ?? 1 });\n });\n });\n}\n\nasync function spawnCaptured(\n spawnFn: typeof spawn,\n cmd: string,\n args: string[],\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n return await new Promise((resolve) => {\n const child = spawnFn(cmd, args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n } as SpawnOptions);\n const stdout: Buffer[] = [];\n const stderr: Buffer[] = [];\n\n child.stdout?.on(\"data\", (chunk: Buffer | string) => {\n stdout.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n child.stderr?.on(\"data\", (chunk: Buffer | string) => {\n stderr.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n child.on(\"error\", (err: NodeJS.ErrnoException) => {\n resolve({\n stdout: \"\",\n stderr: err.message,\n exitCode: 1,\n });\n });\n child.on(\"exit\", (code) => {\n resolve({\n stdout: Buffer.concat(stdout).toString(\"utf8\"),\n stderr: Buffer.concat(stderr).toString(\"utf8\"),\n exitCode: code ?? 1,\n });\n });\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\n\nimport { getConfigPath } from \"./config.js\";\nimport { isNewer } from \"./semver.js\";\nimport { getStatePath, type UpdateState } from \"./state.js\";\n\n/**\n * Pre-command update-nag banner. Runs synchronously at the very top of\n * every `run()` invocation, before commander even touches argv. Prints\n * one line to stderr if:\n *\n * 1. `~/.almanac/update-state.json` exists and parses.\n * 2. `latest_version` is strictly newer than `installed_version`.\n * 3. `latest_version` is NOT in `dismissed_versions`.\n * 4. `~/.almanac/config.json`.`update_notifier` is not `false`.\n *\n * Otherwise silent. Deliberately synchronous and filesystem-blocking:\n * this runs in the CLI critical path and waiting on a Promise would\n * force every command to become async upfront. The files are tiny\n * (<1KB each); a sync read is cheap.\n *\n * Why stderr: agents and scripts parse stdout; stderr is the\n * conventional channel for diagnostics and nags. A tool piping\n * `almanac search` into `xargs` shouldn't see the banner mixed into\n * its slug list. Users running interactively see stderr anyway, so\n * the nag is visible in practice.\n */\n\nexport interface AnnounceOptions {\n statePath?: string;\n configPath?: string;\n /** Override for tests — normally reads from package.json at import time. */\n installedVersion?: string;\n /** Enable ANSI coloring regardless of isTTY. Tests pass `false`. */\n color?: boolean;\n}\n\nconst RST = \"\\x1b[0m\";\nconst BOLD = \"\\x1b[1m\";\nconst YELLOW = \"\\x1b[33m\";\n\nexport function announceUpdateIfAvailable(\n stderr: NodeJS.WritableStream,\n opts: AnnounceOptions = {},\n): void {\n const statePath = opts.statePath ?? getStatePath();\n const configPath = opts.configPath ?? getConfigPath();\n const installed = opts.installedVersion ?? readInstalledVersion();\n\n // Config gate. Must be checked before state: a user who disabled the\n // notifier shouldn't pay even a state-file read.\n if (!shouldNotify(configPath)) return;\n\n const state = readStateSync(statePath);\n if (state === null) return;\n if (state.latest_version.length === 0) return;\n if (!isNewer(state.latest_version, installed)) return;\n if (state.dismissed_versions.includes(state.latest_version)) return;\n\n const useColor =\n opts.color ?? (process.stderr.isTTY === true && !(\"NO_COLOR\" in process.env));\n const warn = useColor ? `${YELLOW}${BOLD}\\u26a0${RST}` : \"!\";\n const cmd = useColor ? `${BOLD}almanac update${RST}` : \"almanac update\";\n stderr.write(\n `${warn} codealmanac ${state.latest_version} available ` +\n `(you're on ${installed}) — run: ${cmd}\\n`,\n );\n}\n\n/**\n * Sync-read the state file. Returns `null` when missing, empty, or\n * malformed — the announce path MUST NOT throw into the CLI critical\n * path. Avoids the `async readState` used by the worker because\n * `run()` would otherwise need `await announceUpdateIfAvailable(...)`\n * on every invocation, which turns into a multi-millisecond penalty\n * on commands that don't care.\n */\nfunction readStateSync(path: string): UpdateState | null {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n const trimmed = raw.trim();\n if (trimmed.length === 0) return null;\n try {\n const parsed = JSON.parse(trimmed) as Partial<UpdateState>;\n return {\n last_check_at:\n typeof parsed.last_check_at === \"number\" ? parsed.last_check_at : 0,\n installed_version:\n typeof parsed.installed_version === \"string\"\n ? parsed.installed_version\n : \"\",\n latest_version:\n typeof parsed.latest_version === \"string\" ? parsed.latest_version : \"\",\n dismissed_versions: Array.isArray(parsed.dismissed_versions)\n ? parsed.dismissed_versions.filter(\n (v): v is string => typeof v === \"string\",\n )\n : [],\n };\n } catch {\n return null;\n }\n}\n\nfunction shouldNotify(configPath: string): boolean {\n let raw: string;\n try {\n raw = readFileSync(configPath, \"utf8\");\n } catch {\n return true; // no config file → default notify on\n }\n const trimmed = raw.trim();\n if (trimmed.length === 0) return true;\n try {\n const parsed = JSON.parse(trimmed) as { update_notifier?: unknown };\n if (parsed.update_notifier === false) return false;\n return true;\n } catch {\n return true;\n }\n}\n\nfunction readInstalledVersion(): string {\n // Dev: `src/update/announce.ts` → `../../package.json`. Bundled:\n // `dist/codealmanac.js` → `../package.json`. Try both.\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../../package.json\") as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall through.\n }\n try {\n const require = createRequire(import.meta.url);\n const pkg = require(\"../package.json\") as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall through.\n }\n return \"unknown\";\n}\n"],"mappings":"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","names":["createRequire","require","createRequire","RST","BOLD","path","require","createRequire","readPackageVersion","require","createRequire"]}
|
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-6BOB6KAN.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}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runDoctor
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HNVOYWC2.js";
|
|
5
5
|
import "./chunk-V3QOQSXI.js";
|
|
6
6
|
import "./chunk-4CODZRHH.js";
|
|
7
7
|
import "./chunk-FM3VRDK7.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-XNTNXEWY.js";
|
|
9
9
|
import "./chunk-447U3GQJ.js";
|
|
10
|
+
import "./chunk-TWM7I2LU.js";
|
|
10
11
|
import "./chunk-SSYMRT4I.js";
|
|
11
12
|
import "./chunk-F53U6JQG.js";
|
|
12
13
|
import "./chunk-WRUSDYYE.js";
|
|
@@ -14,4 +15,4 @@ import "./chunk-7JUX4ADQ.js";
|
|
|
14
15
|
export {
|
|
15
16
|
runDoctor
|
|
16
17
|
};
|
|
17
|
-
//# sourceMappingURL=doctor-
|
|
18
|
+
//# sourceMappingURL=doctor-DD7EQGCA.js.map
|
|
@@ -6,11 +6,10 @@ import {
|
|
|
6
6
|
readStdin
|
|
7
7
|
} from "./chunk-P3LDTCLB.js";
|
|
8
8
|
import {
|
|
9
|
-
assertAgentAuth,
|
|
10
9
|
runAgentsList,
|
|
11
10
|
runSetAgentModel,
|
|
12
11
|
runSetDefaultAgent
|
|
13
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PIYJQE4Z.js";
|
|
14
13
|
import {
|
|
15
14
|
addEntry,
|
|
16
15
|
ancestorsInFile,
|
|
@@ -36,7 +35,7 @@ import {
|
|
|
36
35
|
} from "./chunk-KQUVMF27.js";
|
|
37
36
|
import {
|
|
38
37
|
runDoctor
|
|
39
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-HNVOYWC2.js";
|
|
40
39
|
import "./chunk-V3QOQSXI.js";
|
|
41
40
|
import "./chunk-4CODZRHH.js";
|
|
42
41
|
import {
|
|
@@ -47,15 +46,18 @@ import {
|
|
|
47
46
|
} from "./chunk-FM3VRDK7.js";
|
|
48
47
|
import {
|
|
49
48
|
runUninstall
|
|
50
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-NBVIEZZQ.js";
|
|
51
50
|
import {
|
|
52
51
|
runSetup
|
|
53
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-XNTNXEWY.js";
|
|
54
53
|
import {
|
|
55
54
|
runHookInstall,
|
|
56
55
|
runHookStatus,
|
|
57
56
|
runHookUninstall
|
|
58
57
|
} from "./chunk-447U3GQJ.js";
|
|
58
|
+
import {
|
|
59
|
+
assertAgentAuth
|
|
60
|
+
} from "./chunk-TWM7I2LU.js";
|
|
59
61
|
import {
|
|
60
62
|
resolveClaudeExecutable
|
|
61
63
|
} from "./chunk-SSYMRT4I.js";
|
|
@@ -2044,6 +2046,7 @@ function runJsonlCli(opts) {
|
|
|
2044
2046
|
let turns = 0;
|
|
2045
2047
|
let result = "";
|
|
2046
2048
|
let sessionId;
|
|
2049
|
+
let usage;
|
|
2047
2050
|
let success = false;
|
|
2048
2051
|
let finalSeen = false;
|
|
2049
2052
|
let error;
|
|
@@ -2052,6 +2055,9 @@ function runJsonlCli(opts) {
|
|
|
2052
2055
|
if (sessionId === void 0 && typeof msg.session_id === "string" && msg.session_id.length > 0) {
|
|
2053
2056
|
sessionId = msg.session_id;
|
|
2054
2057
|
}
|
|
2058
|
+
if (sessionId === void 0 && typeof msg.thread_id === "string" && msg.thread_id.length > 0) {
|
|
2059
|
+
sessionId = msg.thread_id;
|
|
2060
|
+
}
|
|
2055
2061
|
const final = opts.parseFinal(msg);
|
|
2056
2062
|
if (final === null) return;
|
|
2057
2063
|
finalSeen = true;
|
|
@@ -2059,6 +2065,7 @@ function runJsonlCli(opts) {
|
|
|
2059
2065
|
if (final.turns !== void 0) turns = final.turns;
|
|
2060
2066
|
if (final.result !== void 0) result = final.result;
|
|
2061
2067
|
if (final.sessionId !== void 0) sessionId = final.sessionId;
|
|
2068
|
+
if (final.usage !== void 0) usage = final.usage;
|
|
2062
2069
|
if (final.success !== void 0) success = final.success;
|
|
2063
2070
|
if (final.error !== void 0) error = final.error;
|
|
2064
2071
|
};
|
|
@@ -2092,6 +2099,7 @@ function runJsonlCli(opts) {
|
|
|
2092
2099
|
turns,
|
|
2093
2100
|
result,
|
|
2094
2101
|
sessionId,
|
|
2102
|
+
usage,
|
|
2095
2103
|
error: err.code === "ENOENT" ? `${opts.command} not found on PATH` : err.message
|
|
2096
2104
|
});
|
|
2097
2105
|
});
|
|
@@ -2104,7 +2112,7 @@ function runJsonlCli(opts) {
|
|
|
2104
2112
|
}
|
|
2105
2113
|
}
|
|
2106
2114
|
if (code === 0 && finalSeen && success) {
|
|
2107
|
-
resolve({ success, cost, turns, result, sessionId });
|
|
2115
|
+
resolve({ success, cost, turns, result, sessionId, usage });
|
|
2108
2116
|
return;
|
|
2109
2117
|
}
|
|
2110
2118
|
const firstStderr = stderr.trim().split("\n")[0];
|
|
@@ -2114,6 +2122,7 @@ function runJsonlCli(opts) {
|
|
|
2114
2122
|
turns,
|
|
2115
2123
|
result,
|
|
2116
2124
|
sessionId,
|
|
2125
|
+
usage,
|
|
2117
2126
|
error: error ?? (firstStderr !== void 0 && firstStderr.length > 0 ? firstStderr : `${opts.command} exited ${code ?? 1}`)
|
|
2118
2127
|
});
|
|
2119
2128
|
});
|
|
@@ -2131,7 +2140,7 @@ function parseCodexFinal(msg) {
|
|
|
2131
2140
|
return null;
|
|
2132
2141
|
}
|
|
2133
2142
|
if (msg.type === "turn.completed") {
|
|
2134
|
-
return { success: true };
|
|
2143
|
+
return { success: true, turns: 1, usage: parseUsage(msg.usage) };
|
|
2135
2144
|
}
|
|
2136
2145
|
if (msg.type === "turn.failed" || msg.type === "error") {
|
|
2137
2146
|
return {
|
|
@@ -2141,13 +2150,29 @@ function parseCodexFinal(msg) {
|
|
|
2141
2150
|
}
|
|
2142
2151
|
return null;
|
|
2143
2152
|
}
|
|
2153
|
+
function parseUsage(value) {
|
|
2154
|
+
if (value === null || typeof value !== "object") return void 0;
|
|
2155
|
+
const obj = value;
|
|
2156
|
+
return {
|
|
2157
|
+
inputTokens: numberField(obj, "input_tokens") ?? numberField(obj, "inputTokens"),
|
|
2158
|
+
cachedInputTokens: numberField(obj, "cached_input_tokens") ?? numberField(obj, "cachedInputTokens") ?? numberField(obj, "cacheReadTokens"),
|
|
2159
|
+
outputTokens: numberField(obj, "output_tokens") ?? numberField(obj, "outputTokens"),
|
|
2160
|
+
reasoningOutputTokens: numberField(obj, "reasoning_output_tokens") ?? numberField(obj, "reasoningOutputTokens")
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
function numberField(input, key) {
|
|
2164
|
+
const value = input[key];
|
|
2165
|
+
return typeof value === "number" ? value : void 0;
|
|
2166
|
+
}
|
|
2144
2167
|
function parseCursorFinal(msg) {
|
|
2145
2168
|
if (msg.type !== "result") return null;
|
|
2146
2169
|
const isError = msg.is_error === true || msg.subtype !== "success";
|
|
2147
2170
|
return {
|
|
2148
2171
|
success: !isError,
|
|
2172
|
+
turns: 1,
|
|
2149
2173
|
result: typeof msg.result === "string" ? msg.result : "",
|
|
2150
2174
|
sessionId: typeof msg.session_id === "string" ? msg.session_id : void 0,
|
|
2175
|
+
usage: parseUsage(msg.usage),
|
|
2151
2176
|
error: isError ? typeof msg.result === "string" ? msg.result : `cursor result: ${String(msg.subtype ?? "error")}` : void 0
|
|
2152
2177
|
};
|
|
2153
2178
|
}
|
|
@@ -2416,8 +2441,39 @@ async function resolveAgentSelection(args) {
|
|
|
2416
2441
|
function formatFinalLine(result, logPath, repoRoot) {
|
|
2417
2442
|
const status = result.success ? "done" : "failed";
|
|
2418
2443
|
const rel = relative(repoRoot, logPath);
|
|
2419
|
-
const
|
|
2420
|
-
return `[${status}]
|
|
2444
|
+
const usage = formatRunUsage(result);
|
|
2445
|
+
return `[${status}] ${usage} (transcript: ${rel})`;
|
|
2446
|
+
}
|
|
2447
|
+
function formatRunUsage(result) {
|
|
2448
|
+
const parts = [];
|
|
2449
|
+
if (result.cost > 0 || result.usage === void 0) {
|
|
2450
|
+
parts.push(`cost: $${result.cost.toFixed(3)}`);
|
|
2451
|
+
}
|
|
2452
|
+
parts.push(`turns: ${result.turns}`);
|
|
2453
|
+
const usage = result.usage;
|
|
2454
|
+
if (usage !== void 0) {
|
|
2455
|
+
const tokenParts = [];
|
|
2456
|
+
if (usage.inputTokens !== void 0) {
|
|
2457
|
+
tokenParts.push(`${usage.inputTokens.toLocaleString("en-US")} in`);
|
|
2458
|
+
}
|
|
2459
|
+
if (usage.outputTokens !== void 0) {
|
|
2460
|
+
tokenParts.push(`${usage.outputTokens.toLocaleString("en-US")} out`);
|
|
2461
|
+
}
|
|
2462
|
+
if (usage.cachedInputTokens !== void 0) {
|
|
2463
|
+
tokenParts.push(
|
|
2464
|
+
`${usage.cachedInputTokens.toLocaleString("en-US")} cached`
|
|
2465
|
+
);
|
|
2466
|
+
}
|
|
2467
|
+
if (usage.reasoningOutputTokens !== void 0) {
|
|
2468
|
+
tokenParts.push(
|
|
2469
|
+
`${usage.reasoningOutputTokens.toLocaleString("en-US")} reasoning`
|
|
2470
|
+
);
|
|
2471
|
+
}
|
|
2472
|
+
if (tokenParts.length > 0) {
|
|
2473
|
+
parts.push(`tokens: ${tokenParts.join(", ")}`);
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
return parts.join(", ");
|
|
2421
2477
|
}
|
|
2422
2478
|
async function countMarkdownPages(pagesDir) {
|
|
2423
2479
|
try {
|
|
@@ -2474,14 +2530,16 @@ var StreamingFormatter = class {
|
|
|
2474
2530
|
}
|
|
2475
2531
|
return;
|
|
2476
2532
|
}
|
|
2477
|
-
if (msg.type === "
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2533
|
+
if (msg.type === "item.started" && isRecord(msg.item)) {
|
|
2534
|
+
this.handleCodexItemStarted(msg.item);
|
|
2535
|
+
return;
|
|
2536
|
+
}
|
|
2537
|
+
if (msg.type === "item.completed" && isRecord(msg.item)) {
|
|
2538
|
+
this.handleCodexItemCompleted(msg.item);
|
|
2539
|
+
return;
|
|
2540
|
+
}
|
|
2541
|
+
if (msg.type === "tool_call") {
|
|
2542
|
+
this.handleCursorToolCall(msg);
|
|
2485
2543
|
return;
|
|
2486
2544
|
}
|
|
2487
2545
|
}
|
|
@@ -2496,6 +2554,33 @@ var StreamingFormatter = class {
|
|
|
2496
2554
|
}
|
|
2497
2555
|
const summary = formatToolSummary(name, input);
|
|
2498
2556
|
this.sink.write(`[${this.currentAgent}] ${summary}
|
|
2557
|
+
`);
|
|
2558
|
+
}
|
|
2559
|
+
handleCodexItemStarted(item) {
|
|
2560
|
+
if (item.type !== "command_execution") return;
|
|
2561
|
+
const command = stringField(item, "command") ?? "?";
|
|
2562
|
+
this.sink.write(`[${this.currentAgent}] bash ${truncate(command, 80)}
|
|
2563
|
+
`);
|
|
2564
|
+
}
|
|
2565
|
+
handleCodexItemCompleted(item) {
|
|
2566
|
+
if (item.type !== "file_change") return;
|
|
2567
|
+
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
2568
|
+
for (const change of changes) {
|
|
2569
|
+
if (!isRecord(change)) continue;
|
|
2570
|
+
const rawPath = stringField(change, "path") ?? "?";
|
|
2571
|
+
const kind = stringField(change, "kind") ?? "edit";
|
|
2572
|
+
const verb = kind === "add" ? "writing" : kind === "delete" ? "deleting" : "editing";
|
|
2573
|
+
this.sink.write(
|
|
2574
|
+
`[${this.currentAgent}] ${verb} ${formatCodexPath(rawPath)}
|
|
2575
|
+
`
|
|
2576
|
+
);
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
handleCursorToolCall(msg) {
|
|
2580
|
+
if (msg.subtype !== "started" || !isRecord(msg.tool_call)) return;
|
|
2581
|
+
const summary = formatCursorToolSummary(msg.tool_call);
|
|
2582
|
+
if (summary === void 0) return;
|
|
2583
|
+
this.sink.write(`[${this.currentAgent}] ${summary}
|
|
2499
2584
|
`);
|
|
2500
2585
|
}
|
|
2501
2586
|
};
|
|
@@ -2539,18 +2624,57 @@ function formatToolSummary(name, input) {
|
|
|
2539
2624
|
}
|
|
2540
2625
|
case "Bash": {
|
|
2541
2626
|
const command = stringField(input, "command") ?? "?";
|
|
2542
|
-
|
|
2543
|
-
return `bash ${trimmed}`;
|
|
2627
|
+
return `bash ${truncate(command, 80)}`;
|
|
2544
2628
|
}
|
|
2545
2629
|
default: {
|
|
2546
2630
|
return name;
|
|
2547
2631
|
}
|
|
2548
2632
|
}
|
|
2549
2633
|
}
|
|
2634
|
+
function formatCursorToolSummary(toolCall) {
|
|
2635
|
+
if (isRecord(toolCall.readToolCall)) {
|
|
2636
|
+
const args = recordField(toolCall.readToolCall, "args");
|
|
2637
|
+
return `reading ${stringField(args, "path") ?? "?"}`;
|
|
2638
|
+
}
|
|
2639
|
+
if (isRecord(toolCall.editToolCall)) {
|
|
2640
|
+
const args = recordField(toolCall.editToolCall, "args");
|
|
2641
|
+
return `editing ${formatCodexPath(stringField(args, "path") ?? "?")}`;
|
|
2642
|
+
}
|
|
2643
|
+
if (isRecord(toolCall.globToolCall)) {
|
|
2644
|
+
const args = recordField(toolCall.globToolCall, "args");
|
|
2645
|
+
return `glob ${stringField(args, "globPattern") ?? "?"}`;
|
|
2646
|
+
}
|
|
2647
|
+
if (isRecord(toolCall.grepToolCall)) {
|
|
2648
|
+
const args = recordField(toolCall.grepToolCall, "args");
|
|
2649
|
+
return `grep ${stringField(args, "pattern") ?? "?"}`;
|
|
2650
|
+
}
|
|
2651
|
+
if (isRecord(toolCall.shellToolCall)) {
|
|
2652
|
+
const args = recordField(toolCall.shellToolCall, "args");
|
|
2653
|
+
const description = stringField(toolCall.shellToolCall, "description");
|
|
2654
|
+
const command = stringField(args, "command") ?? description ?? "?";
|
|
2655
|
+
return `bash ${truncate(command, 80)}`;
|
|
2656
|
+
}
|
|
2657
|
+
return void 0;
|
|
2658
|
+
}
|
|
2659
|
+
function truncate(value, max) {
|
|
2660
|
+
return value.length > max ? `${value.slice(0, max - 3)}...` : value;
|
|
2661
|
+
}
|
|
2662
|
+
function formatCodexPath(value) {
|
|
2663
|
+
const marker = "/.almanac/";
|
|
2664
|
+
const idx = value.indexOf(marker);
|
|
2665
|
+
if (idx !== -1) {
|
|
2666
|
+
return `.almanac/${value.slice(idx + marker.length)}`;
|
|
2667
|
+
}
|
|
2668
|
+
return value;
|
|
2669
|
+
}
|
|
2550
2670
|
function stringField(input, key) {
|
|
2551
2671
|
const value = input[key];
|
|
2552
2672
|
return typeof value === "string" ? value : void 0;
|
|
2553
2673
|
}
|
|
2674
|
+
function recordField(input, key) {
|
|
2675
|
+
const value = input[key];
|
|
2676
|
+
return isRecord(value) ? value : {};
|
|
2677
|
+
}
|
|
2554
2678
|
function isRecord(value) {
|
|
2555
2679
|
return value !== null && typeof value === "object";
|
|
2556
2680
|
}
|
|
@@ -3095,12 +3219,12 @@ function diffSnapshots(before, after) {
|
|
|
3095
3219
|
}
|
|
3096
3220
|
function formatSummary2(result, delta, logPath, repoRoot) {
|
|
3097
3221
|
const rel = relative3(repoRoot, logPath);
|
|
3098
|
-
const
|
|
3222
|
+
const usage = formatRunUsage(result);
|
|
3099
3223
|
const { created, updated, archived } = delta;
|
|
3100
3224
|
if (created === 0 && updated === 0 && archived === 0) {
|
|
3101
|
-
return `[capture] no new knowledge met the notability bar (0 pages written),
|
|
3225
|
+
return `[capture] no new knowledge met the notability bar (0 pages written), ${usage} (transcript: ${rel})`;
|
|
3102
3226
|
}
|
|
3103
|
-
return `[done] ${updated} page${updated === 1 ? "" : "s"} updated, ${created} created, ${archived} archived,
|
|
3227
|
+
return `[done] ${updated} page${updated === 1 ? "" : "s"} updated, ${created} created, ${archived} archived, ${usage} (transcript: ${rel})`;
|
|
3104
3228
|
}
|
|
3105
3229
|
function formatTimestamp2(d) {
|
|
3106
3230
|
const pad = (n) => n.toString().padStart(2, "0");
|
|
@@ -3213,4 +3337,4 @@ function registerCommands(program) {
|
|
|
3213
3337
|
export {
|
|
3214
3338
|
registerCommands
|
|
3215
3339
|
};
|
|
3216
|
-
//# sourceMappingURL=register-commands-
|
|
3340
|
+
//# sourceMappingURL=register-commands-IXYE5CNZ.js.map
|