codealmanac 0.2.5 → 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.
Files changed (53) hide show
  1. package/COMMERCIAL.md +9 -0
  2. package/LICENSE +133 -21
  3. package/README.md +11 -11
  4. package/dist/{agents-RVTQYE6A.js → agents-HYRWRHRX.js} +4 -4
  5. package/dist/{chunk-TT6ZP4GS.js → chunk-2BNDNGUR.js} +8 -4
  6. package/dist/{chunk-TT6ZP4GS.js.map → chunk-2BNDNGUR.js.map} +1 -1
  7. package/dist/{chunk-P5WGG4FJ.js → chunk-3E7JNMTZ.js} +28 -3
  8. package/dist/chunk-3E7JNMTZ.js.map +1 -0
  9. package/dist/{chunk-SMIK2YLU.js → chunk-DW32TL5W.js} +117 -83
  10. package/dist/chunk-DW32TL5W.js.map +1 -0
  11. package/dist/{chunk-6BJUYZ43.js → chunk-GPFVEF6V.js} +28 -18
  12. package/dist/chunk-GPFVEF6V.js.map +1 -0
  13. package/dist/{chunk-TILAKDN6.js → chunk-HJ3WREGP.js} +2 -2
  14. package/dist/{chunk-BGUID5BS.js → chunk-J7DNV2DH.js} +219 -26
  15. package/dist/chunk-J7DNV2DH.js.map +1 -0
  16. package/dist/{chunk-DL5BXZCX.js → chunk-K2JBCB7R.js} +40 -54
  17. package/dist/chunk-K2JBCB7R.js.map +1 -0
  18. package/dist/{chunk-MRRX4UQB.js → chunk-ODJAAJGZ.js} +2 -2
  19. package/dist/{chunk-447U3GQJ.js → chunk-PDFS5VFE.js} +17 -5
  20. package/dist/chunk-PDFS5VFE.js.map +1 -0
  21. package/dist/{chunk-GFUB57IT.js → chunk-VXDPUOQ5.js} +384 -207
  22. package/dist/chunk-VXDPUOQ5.js.map +1 -0
  23. package/dist/{cli-CL4ID7EO.js → cli-MKXCNEMW.js} +14 -14
  24. package/dist/codealmanac.js +1 -1
  25. package/dist/{config-ML2RCR7J.js → config-F7FKEQ7F.js} +3 -3
  26. package/dist/doctor-37UH3HT5.js +17 -0
  27. package/dist/{hook-2NP3UE7U.js → hook-4SVX446M.js} +4 -2
  28. package/dist/{register-commands-FBJ6XQ3L.js → register-commands-2F6SXLDI.js} +30 -21
  29. package/dist/register-commands-2F6SXLDI.js.map +1 -0
  30. package/dist/uninstall-C62ZOK32.js +17 -0
  31. package/dist/{update-P2IPG7RO.js → update-2UGOFN5C.js} +3 -3
  32. package/guides/mini.md +3 -3
  33. package/guides/reference.md +7 -7
  34. package/package.json +4 -3
  35. package/dist/chunk-447U3GQJ.js.map +0 -1
  36. package/dist/chunk-6BJUYZ43.js.map +0 -1
  37. package/dist/chunk-BGUID5BS.js.map +0 -1
  38. package/dist/chunk-DL5BXZCX.js.map +0 -1
  39. package/dist/chunk-GFUB57IT.js.map +0 -1
  40. package/dist/chunk-P5WGG4FJ.js.map +0 -1
  41. package/dist/chunk-SMIK2YLU.js.map +0 -1
  42. package/dist/doctor-DOLJRGS4.js +0 -17
  43. package/dist/register-commands-FBJ6XQ3L.js.map +0 -1
  44. package/dist/uninstall-DX6LFKMX.js +0 -15
  45. /package/dist/{agents-RVTQYE6A.js.map → agents-HYRWRHRX.js.map} +0 -0
  46. /package/dist/{chunk-TILAKDN6.js.map → chunk-HJ3WREGP.js.map} +0 -0
  47. /package/dist/{chunk-MRRX4UQB.js.map → chunk-ODJAAJGZ.js.map} +0 -0
  48. /package/dist/{cli-CL4ID7EO.js.map → cli-MKXCNEMW.js.map} +0 -0
  49. /package/dist/{config-ML2RCR7J.js.map → config-F7FKEQ7F.js.map} +0 -0
  50. /package/dist/{doctor-DOLJRGS4.js.map → doctor-37UH3HT5.js.map} +0 -0
  51. /package/dist/{hook-2NP3UE7U.js.map → hook-4SVX446M.js.map} +0 -0
  52. /package/dist/{uninstall-DX6LFKMX.js.map → uninstall-C62ZOK32.js.map} +0 -0
  53. /package/dist/{update-P2IPG7RO.js.map → update-2UGOFN5C.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  readStateForDoctor
4
- } from "./chunk-TILAKDN6.js";
4
+ } from "./chunk-HJ3WREGP.js";
5
5
  import {
6
6
  formatDuration
7
7
  } from "./chunk-4CODZRHH.js";
@@ -14,18 +14,21 @@ import {
14
14
  RST
15
15
  } from "./chunk-FM3VRDK7.js";
16
16
  import {
17
- IMPORT_LINE
18
- } from "./chunk-GFUB57IT.js";
17
+ IMPORT_LINE,
18
+ hasCodexInstructions,
19
+ resolveCodexAgentsPath
20
+ } from "./chunk-VXDPUOQ5.js";
19
21
  import {
20
22
  buildProviderSetupView,
21
23
  checkClaudeAuth
22
- } from "./chunk-BGUID5BS.js";
24
+ } from "./chunk-J7DNV2DH.js";
23
25
  import {
24
26
  isNewer
25
27
  } from "./chunk-F53U6JQG.js";
26
28
  import {
29
+ isCursorEnabled,
27
30
  readConfig
28
- } from "./chunk-P5WGG4FJ.js";
31
+ } from "./chunk-3E7JNMTZ.js";
29
32
 
30
33
  // src/commands/doctor-checks/format.ts
31
34
  function formatReport(report, options) {
@@ -164,6 +167,13 @@ function probeBetterSqlite3() {
164
167
  return { ok: false, summary: firstLine };
165
168
  }
166
169
  }
170
+ async function safeCheckAuth(spawnCli) {
171
+ try {
172
+ return await checkClaudeAuth(spawnCli);
173
+ } catch {
174
+ return { loggedIn: false };
175
+ }
176
+ }
167
177
  function readPackageVersion() {
168
178
  const candidates = [
169
179
  "../../../package.json",
@@ -196,12 +206,15 @@ async function gatherInstallChecks(options) {
196
206
  message: sqlite.ok ? `better-sqlite3 native binding OK (Node ${nodeVersion})` : `better-sqlite3 native binding failed: ${sqlite.summary}`,
197
207
  fix: sqlite.ok ? void 0 : "run: npm rebuild better-sqlite3 (in the install directory)"
198
208
  });
199
- checks.push(describeProviderAuthSurface());
209
+ const auth = await safeCheckAuth(options.spawnCli);
210
+ checks.push(describeAuth(auth));
200
211
  const settingsPath = options.settingsPath ?? path2.join(homedir2(), ".claude", "settings.json");
201
212
  checks.push(await describeHook(settingsPath));
202
213
  const claudeDir = options.claudeDir ?? path2.join(homedir2(), ".claude");
203
- checks.push(describeGuides(claudeDir, options.cwd));
204
- checks.push(await describeGuideActivation(claudeDir, options.cwd));
214
+ checks.push(describeGuides(claudeDir));
215
+ checks.push(await describeImportLine(claudeDir));
216
+ const codexDir = options.codexDir ?? path2.join(homedir2(), ".codex");
217
+ checks.push(await describeCodexInstructions(codexDir));
205
218
  return checks;
206
219
  }
207
220
  function describeInstallPath(installPath, isEphemeral) {
@@ -220,12 +233,35 @@ function describeInstallPath(installPath, isEphemeral) {
220
233
  fix: isEphemeral ? "run: npm install -g codealmanac (to make the install permanent)" : void 0
221
234
  };
222
235
  }
223
- function describeProviderAuthSurface() {
236
+ function describeAuth(auth) {
237
+ if (auth.loggedIn) {
238
+ if (auth.authMethod === "apiKey") {
239
+ return {
240
+ status: "ok",
241
+ key: "install.auth",
242
+ message: "claude auth: ANTHROPIC_API_KEY set"
243
+ };
244
+ }
245
+ const who = auth.email ?? "Claude account";
246
+ const plan = auth.subscriptionType !== void 0 ? ` (${auth.subscriptionType} subscription)` : "";
247
+ return {
248
+ status: "ok",
249
+ key: "install.auth",
250
+ message: `claude auth: ${who}${plan}`
251
+ };
252
+ }
253
+ if (process.env.ANTHROPIC_API_KEY !== void 0 && process.env.ANTHROPIC_API_KEY.length > 0) {
254
+ return {
255
+ status: "ok",
256
+ key: "install.auth",
257
+ message: "claude auth: ANTHROPIC_API_KEY set"
258
+ };
259
+ }
224
260
  return {
225
- status: "info",
261
+ status: "problem",
226
262
  key: "install.auth",
227
- message: "provider auth is reported under Agents",
228
- fix: "run: almanac agents list"
263
+ message: "claude auth: not signed in",
264
+ fix: "run: claude auth login --claudeai (or export ANTHROPIC_API_KEY)"
229
265
  };
230
266
  }
231
267
  async function describeHook(settingsPath) {
@@ -275,7 +311,7 @@ async function describeHook(settingsPath) {
275
311
  };
276
312
  }
277
313
  }
278
- function describeGuides(claudeDir, cwd) {
314
+ function describeGuides(claudeDir) {
279
315
  const mini = path2.join(claudeDir, "codealmanac.md");
280
316
  const ref = path2.join(claudeDir, "codealmanac-reference.md");
281
317
  const haveMini = existsSync2(mini);
@@ -284,24 +320,7 @@ function describeGuides(claudeDir, cwd) {
284
320
  return {
285
321
  status: "ok",
286
322
  key: "install.guides",
287
- message: `Agent guides installed for Claude (${path2.basename(mini)}, ${path2.basename(ref)})`
288
- };
289
- }
290
- const codexMini = path2.join(homedir2(), ".codex", "codealmanac.md");
291
- const codexRef = path2.join(homedir2(), ".codex", "codealmanac-reference.md");
292
- if (existsSync2(codexMini) && existsSync2(codexRef)) {
293
- return {
294
- status: "ok",
295
- key: "install.guides",
296
- message: "Agent guides installed for Codex (codealmanac.md, codealmanac-reference.md)"
297
- };
298
- }
299
- const cursorRule = path2.join(cwd, ".cursor", "rules", "codealmanac.mdc");
300
- if (existsSync2(cursorRule)) {
301
- return {
302
- status: "ok",
303
- key: "install.guides",
304
- message: "Agent guide installed for Cursor (.cursor/rules/codealmanac.mdc)"
323
+ message: `Agent guides installed (${path2.basename(mini)}, ${path2.basename(ref)})`
305
324
  };
306
325
  }
307
326
  const missing = [
@@ -315,66 +334,78 @@ function describeGuides(claudeDir, cwd) {
315
334
  fix: "run: almanac setup --yes"
316
335
  };
317
336
  }
318
- async function describeGuideActivation(claudeDir, cwd) {
337
+ async function describeImportLine(claudeDir) {
319
338
  const claudeMd = path2.join(claudeDir, "CLAUDE.md");
320
- if (existsSync2(claudeMd)) {
321
- try {
322
- const contents = await readFile(claudeMd, "utf8");
323
- const lines = contents.split(/\r?\n/).map((l) => l.trim());
324
- const present = lines.some((line) => {
325
- if (line === IMPORT_LINE) return true;
326
- if (!line.startsWith(IMPORT_LINE)) return false;
327
- const next = line[IMPORT_LINE.length];
328
- return next === " " || next === " ";
329
- });
330
- if (present) {
331
- return {
332
- status: "ok",
333
- key: "install.import",
334
- message: "Claude guide import present"
335
- };
336
- }
337
- } catch (err) {
338
- const msg = err instanceof Error ? err.message : String(err);
339
+ if (!existsSync2(claudeMd)) {
340
+ return {
341
+ status: "problem",
342
+ key: "install.import",
343
+ message: "CLAUDE.md import not present (no ~/.claude/CLAUDE.md)",
344
+ fix: "run: almanac setup --yes"
345
+ };
346
+ }
347
+ try {
348
+ const contents = await readFile(claudeMd, "utf8");
349
+ const lines = contents.split(/\r?\n/).map((l) => l.trim());
350
+ const present = lines.some((line) => {
351
+ if (line === IMPORT_LINE) return true;
352
+ if (!line.startsWith(IMPORT_LINE)) return false;
353
+ const next = line[IMPORT_LINE.length];
354
+ return next === " " || next === " ";
355
+ });
356
+ if (present) {
339
357
  return {
340
- status: "problem",
358
+ status: "ok",
341
359
  key: "install.import",
342
- message: `could not read ${claudeMd}: ${msg}`
360
+ message: "CLAUDE.md import present"
343
361
  };
344
362
  }
363
+ return {
364
+ status: "problem",
365
+ key: "install.import",
366
+ message: "CLAUDE.md import line missing",
367
+ fix: "run: almanac setup --yes"
368
+ };
369
+ } catch (err) {
370
+ const msg = err instanceof Error ? err.message : String(err);
371
+ return {
372
+ status: "problem",
373
+ key: "install.import",
374
+ message: `could not read ${claudeMd}: ${msg}`
375
+ };
345
376
  }
346
- const codexAgents = path2.join(homedir2(), ".codex", "AGENTS.md");
347
- if (existsSync2(codexAgents)) {
348
- try {
349
- const contents = await readFile(codexAgents, "utf8");
350
- if (contents.includes("<!-- codealmanac:start -->") && contents.includes("<!-- codealmanac:end -->")) {
351
- return {
352
- status: "ok",
353
- key: "install.import",
354
- message: "Codex guide block present"
355
- };
356
- }
357
- } catch (err) {
358
- const msg = err instanceof Error ? err.message : String(err);
377
+ }
378
+ async function describeCodexInstructions(codexDir) {
379
+ const agentsFile = await resolveCodexAgentsPath(codexDir);
380
+ if (!existsSync2(agentsFile)) {
381
+ return {
382
+ status: "problem",
383
+ key: "install.codexInstructions",
384
+ message: `Codex AGENTS instructions missing (${path2.basename(agentsFile)} not found)`,
385
+ fix: "run: almanac setup --yes"
386
+ };
387
+ }
388
+ try {
389
+ const contents = await readFile(agentsFile, "utf8");
390
+ if (hasCodexInstructions(contents)) {
359
391
  return {
360
- status: "problem",
361
- key: "install.import",
362
- message: `could not read ${codexAgents}: ${msg}`
392
+ status: "ok",
393
+ key: "install.codexInstructions",
394
+ message: `Codex AGENTS instructions present (${path2.basename(agentsFile)})`
363
395
  };
364
396
  }
365
- }
366
- const cursorRule = path2.join(cwd, ".cursor", "rules", "codealmanac.mdc");
367
- if (existsSync2(cursorRule)) {
397
+ } catch (err) {
398
+ const msg = err instanceof Error ? err.message : String(err);
368
399
  return {
369
- status: "ok",
370
- key: "install.import",
371
- message: "Cursor guide rule present"
400
+ status: "problem",
401
+ key: "install.codexInstructions",
402
+ message: `could not read ${agentsFile}: ${msg}`
372
403
  };
373
404
  }
374
405
  return {
375
406
  status: "problem",
376
- key: "install.import",
377
- message: "provider guide activation missing",
407
+ key: "install.codexInstructions",
408
+ message: `Codex AGENTS instructions missing (${path2.basename(agentsFile)})`,
378
409
  fix: "run: almanac setup --yes"
379
410
  };
380
411
  }
@@ -408,7 +439,7 @@ async function injectedProviderStatuses(options) {
408
439
  const auth = await checkClaudeAuth(options.spawnCli);
409
440
  const hasApiKey = process.env.ANTHROPIC_API_KEY !== void 0 && process.env.ANTHROPIC_API_KEY.length > 0;
410
441
  const claudeReady = auth.loggedIn || hasApiKey;
411
- return [
442
+ const statuses = [
412
443
  {
413
444
  id: "claude",
414
445
  installed: true,
@@ -420,14 +451,17 @@ async function injectedProviderStatuses(options) {
420
451
  installed: false,
421
452
  authenticated: false,
422
453
  detail: "codex status not injected"
423
- },
424
- {
454
+ }
455
+ ];
456
+ if (isCursorEnabled()) {
457
+ statuses.push({
425
458
  id: "cursor",
426
459
  installed: false,
427
460
  authenticated: false,
428
461
  detail: "cursor-agent status not injected"
429
- }
430
- ];
462
+ });
463
+ }
464
+ return statuses;
431
465
  }
432
466
 
433
467
  // src/commands/doctor-checks/updates.ts
@@ -531,4 +565,4 @@ async function safeGatherWikiChecks(options) {
531
565
  export {
532
566
  runDoctor
533
567
  };
534
- //# sourceMappingURL=chunk-SMIK2YLU.js.map
568
+ //# sourceMappingURL=chunk-DW32TL5W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/doctor-checks/format.ts","../src/commands/doctor-checks/install.ts","../src/commands/doctor-checks/probes.ts","../src/commands/doctor-checks/agents.ts","../src/commands/doctor-checks/updates.ts","../src/commands/doctor.ts"],"sourcesContent":["import { BLUE, BOLD, DIM, GREEN, RED, RST } from \"../../ansi.js\";\nimport type {\n AgentDoctorCheck,\n Check,\n CheckStatus,\n DoctorOptions,\n DoctorReport,\n} from \"./types.js\";\n\nexport function formatReport(\n report: DoctorReport,\n options: DoctorOptions,\n): string {\n const color = options.stdout === undefined && process.stdout.isTTY === true;\n const lines: string[] = [];\n lines.push(`codealmanac v${report.version}`);\n lines.push(\"\");\n if (report.install.length > 0) {\n lines.push(color ? `${BOLD}## Install${RST}` : \"## Install\");\n for (const c of report.install) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n if (report.agents.length > 0) {\n lines.push(color ? `${BOLD}## Agents${RST}` : \"## Agents\");\n for (const c of report.agents.map(agentToCheck)) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n if (report.updates.length > 0) {\n lines.push(color ? `${BOLD}## Updates${RST}` : \"## Updates\");\n for (const c of report.updates) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n if (report.wiki.length > 0) {\n lines.push(color ? `${BOLD}## Current wiki${RST}` : \"## Current wiki\");\n for (const c of report.wiki) {\n lines.push(formatCheck(c, color));\n }\n lines.push(\"\");\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction agentToCheck(agent: AgentDoctorCheck): Check {\n const message = [\n agent.label,\n agent.selected ? \"(default)\" : null,\n agent.recommended ? \"(recommended)\" : null,\n agent.status === \"ok\" ? \"ready\" : readinessMessage(agent),\n `model: ${agent.model ?? \"provider default\"}`,\n agent.account,\n ].filter((part): part is string => part !== null).join(\" \");\n return {\n status: agent.status,\n key: `agents.${agent.id}`,\n message,\n fix: agent.fix,\n };\n}\n\nfunction readinessMessage(agent: AgentDoctorCheck): string {\n if (!agent.installed) return \"missing\";\n if (!agent.authenticated) return `not ready: ${agent.detail}`;\n return agent.detail;\n}\n\nfunction formatCheck(c: Check, color: boolean): string {\n const { icon, tint } = iconFor(c.status, color);\n const head = ` ${tint}${icon}${color ? RST : \"\"} ${c.message}`;\n if (c.fix === undefined) return head;\n const fixLine = color\n ? ` ${DIM}${c.fix}${RST}`\n : ` ${c.fix}`;\n return `${head}\\n${fixLine}`;\n}\n\nfunction iconFor(\n status: CheckStatus,\n color: boolean,\n): { icon: string; tint: string } {\n switch (status) {\n case \"ok\":\n return { icon: \"\\u2713\", tint: color ? GREEN : \"\" };\n case \"problem\":\n return { icon: \"\\u2717\", tint: color ? RED : \"\" };\n case \"info\":\n return { icon: \"\\u25c7\", tint: color ? BLUE : \"\" };\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\n\nimport type { ClaudeAuthStatus } from \"../../agent/providers/claude/index.js\";\nimport {\n hasCodexInstructions,\n resolveCodexAgentsPath,\n} from \"../../agent/providers/codex-instructions.js\";\nimport {\n IMPORT_LINE,\n} from \"../setup.js\";\nimport {\n classifyInstallPath,\n detectInstallPath,\n probeBetterSqlite3,\n safeCheckAuth,\n} from \"./probes.js\";\nimport type { Check, DoctorOptions } from \"./types.js\";\n\nexport async function gatherInstallChecks(\n options: DoctorOptions,\n): Promise<Check[]> {\n const checks: Check[] = [];\n\n const rawPath = options.installPath ?? detectInstallPath();\n const { installPath, isEphemeral } = classifyInstallPath(rawPath);\n checks.push(describeInstallPath(installPath, isEphemeral));\n\n const nodeVersion = options.nodeVersion ?? process.version;\n const sqlite = options.sqliteProbe ?? probeBetterSqlite3();\n checks.push({\n status: sqlite.ok ? \"ok\" : \"problem\",\n key: \"install.sqlite\",\n message: sqlite.ok\n ? `better-sqlite3 native binding OK (Node ${nodeVersion})`\n : `better-sqlite3 native binding failed: ${sqlite.summary}`,\n fix: sqlite.ok\n ? undefined\n : \"run: npm rebuild better-sqlite3 (in the install directory)\",\n });\n\n const auth = await safeCheckAuth(options.spawnCli);\n checks.push(describeAuth(auth));\n\n const settingsPath =\n options.settingsPath ?? path.join(homedir(), \".claude\", \"settings.json\");\n checks.push(await describeHook(settingsPath));\n\n const claudeDir = options.claudeDir ?? path.join(homedir(), \".claude\");\n checks.push(describeGuides(claudeDir));\n checks.push(await describeImportLine(claudeDir));\n const codexDir = options.codexDir ?? path.join(homedir(), \".codex\");\n checks.push(await describeCodexInstructions(codexDir));\n\n return checks;\n}\n\nfunction describeInstallPath(\n installPath: string | null,\n isEphemeral: boolean,\n): Check {\n if (installPath === null) {\n return {\n status: \"problem\",\n key: \"install.path\",\n message: \"could not detect codealmanac install path\",\n fix: \"reinstall with: npm install -g codealmanac\",\n };\n }\n return {\n status: isEphemeral ? \"info\" : \"ok\",\n key: \"install.path\",\n message: isEphemeral\n ? `codealmanac running from ephemeral npx location: ${installPath}`\n : `codealmanac installed at ${installPath}`,\n fix: isEphemeral\n ? \"run: npm install -g codealmanac (to make the install permanent)\"\n : undefined,\n };\n}\n\nfunction describeAuth(auth: ClaudeAuthStatus): Check {\n if (auth.loggedIn) {\n if (auth.authMethod === \"apiKey\") {\n return {\n status: \"ok\",\n key: \"install.auth\",\n message: \"claude auth: ANTHROPIC_API_KEY set\",\n };\n }\n const who = auth.email ?? \"Claude account\";\n const plan =\n auth.subscriptionType !== undefined\n ? ` (${auth.subscriptionType} subscription)`\n : \"\";\n return {\n status: \"ok\",\n key: \"install.auth\",\n message: `claude auth: ${who}${plan}`,\n };\n }\n if (\n process.env.ANTHROPIC_API_KEY !== undefined &&\n process.env.ANTHROPIC_API_KEY.length > 0\n ) {\n return {\n status: \"ok\",\n key: \"install.auth\",\n message: \"claude auth: ANTHROPIC_API_KEY set\",\n };\n }\n return {\n status: \"problem\",\n key: \"install.auth\",\n message: \"claude auth: not signed in\",\n fix: \"run: claude auth login --claudeai (or export ANTHROPIC_API_KEY)\",\n };\n}\n\nasync function describeHook(settingsPath: string): Promise<Check> {\n if (!existsSync(settingsPath)) {\n return {\n status: \"problem\",\n key: \"install.hook\",\n message: \"SessionEnd hook not installed\",\n fix: \"run: almanac setup --yes\",\n };\n }\n try {\n const raw = await readFile(settingsPath, \"utf8\");\n const parsed = JSON.parse(raw) as {\n hooks?: {\n SessionEnd?: {\n command?: string;\n hooks?: { command?: string }[];\n }[];\n };\n };\n const entries = parsed.hooks?.SessionEnd ?? [];\n const found = entries.some((e) => {\n if (\n typeof e?.command === \"string\" &&\n e.command.endsWith(\"almanac-capture.sh\")\n ) {\n return true;\n }\n if (Array.isArray(e?.hooks)) {\n return e.hooks.some(\n (h) =>\n typeof h?.command === \"string\" &&\n h.command.endsWith(\"almanac-capture.sh\"),\n );\n }\n return false;\n });\n if (!found) {\n return {\n status: \"problem\",\n key: \"install.hook\",\n message: \"SessionEnd hook not installed\",\n fix: \"run: almanac setup --yes\",\n };\n }\n return {\n status: \"ok\",\n key: \"install.hook\",\n message: `SessionEnd hook installed at ${settingsPath}`,\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"problem\",\n key: \"install.hook\",\n message: `could not read ${settingsPath}: ${msg}`,\n fix: \"check the file for malformed JSON\",\n };\n }\n}\n\nfunction describeGuides(claudeDir: string): Check {\n const mini = path.join(claudeDir, \"codealmanac.md\");\n const ref = path.join(claudeDir, \"codealmanac-reference.md\");\n const haveMini = existsSync(mini);\n const haveRef = existsSync(ref);\n if (haveMini && haveRef) {\n return {\n status: \"ok\",\n key: \"install.guides\",\n message: `Agent guides installed (${path.basename(mini)}, ${path.basename(ref)})`,\n };\n }\n const missing = [\n haveMini ? null : \"codealmanac.md\",\n haveRef ? null : \"codealmanac-reference.md\",\n ].filter((s): s is string => s !== null);\n return {\n status: \"problem\",\n key: \"install.guides\",\n message: `Agent guides missing (${missing.join(\", \")})`,\n fix: \"run: almanac setup --yes\",\n };\n}\n\nasync function describeImportLine(claudeDir: string): Promise<Check> {\n const claudeMd = path.join(claudeDir, \"CLAUDE.md\");\n if (!existsSync(claudeMd)) {\n return {\n status: \"problem\",\n key: \"install.import\",\n message: \"CLAUDE.md import not present (no ~/.claude/CLAUDE.md)\",\n fix: \"run: almanac setup --yes\",\n };\n }\n try {\n const contents = await readFile(claudeMd, \"utf8\");\n const lines = contents.split(/\\r?\\n/).map((l) => l.trim());\n const present = lines.some((line) => {\n if (line === IMPORT_LINE) return true;\n if (!line.startsWith(IMPORT_LINE)) return false;\n const next = line[IMPORT_LINE.length];\n return next === \" \" || next === \"\\t\";\n });\n if (present) {\n return {\n status: \"ok\",\n key: \"install.import\",\n message: \"CLAUDE.md import present\",\n };\n }\n return {\n status: \"problem\",\n key: \"install.import\",\n message: \"CLAUDE.md import line missing\",\n fix: \"run: almanac setup --yes\",\n };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"problem\",\n key: \"install.import\",\n message: `could not read ${claudeMd}: ${msg}`,\n };\n }\n}\n\nasync function describeCodexInstructions(codexDir: string): Promise<Check> {\n const agentsFile = await resolveCodexAgentsPath(codexDir);\n if (!existsSync(agentsFile)) {\n return {\n status: \"problem\",\n key: \"install.codexInstructions\",\n message: `Codex AGENTS instructions missing (${path.basename(agentsFile)} not found)`,\n fix: \"run: almanac setup --yes\",\n };\n }\n try {\n const contents = await readFile(agentsFile, \"utf8\");\n if (hasCodexInstructions(contents)) {\n return {\n status: \"ok\",\n key: \"install.codexInstructions\",\n message: `Codex AGENTS instructions present (${path.basename(agentsFile)})`,\n };\n }\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return {\n status: \"problem\",\n key: \"install.codexInstructions\",\n message: `could not read ${agentsFile}: ${msg}`,\n };\n }\n\n return {\n status: \"problem\",\n key: \"install.codexInstructions\",\n message: `Codex AGENTS instructions missing (${path.basename(agentsFile)})`,\n fix: \"run: almanac setup --yes\",\n };\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport {\n checkClaudeAuth,\n type ClaudeAuthStatus,\n type SpawnCliFn,\n} from \"../../agent/providers/claude/index.js\";\nimport type { SqliteProbeResult } from \"./types.js\";\n\n// Single `createRequire` instance — used by package/binding probes.\nconst req = createRequire(import.meta.url);\n\n/**\n * Detect where codealmanac is installed by walking up from the running\n * module until we find a `package.json` whose `name` is `codealmanac`.\n */\nexport function detectInstallPath(): string | null {\n try {\n const here = fileURLToPath(import.meta.url);\n let dir = path.dirname(here);\n for (let i = 0; i < 6; i++) {\n const pkgPath = path.join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const raw = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw) as { name?: unknown };\n if (pkg.name === \"codealmanac\") return dir;\n } catch {\n // ignore — keep walking\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Classify the detected install path as permanent or ephemeral.\n * Ephemeral locations (npm npx cache, pnpm dlx cache, /tmp/) are valid\n * installs but will disappear when the cache is evicted or the machine\n * reboots. Doctor reports them as `info` rather than `ok`.\n */\nexport function classifyInstallPath(\n raw: string | null,\n): { installPath: string | null; isEphemeral: boolean } {\n if (raw === null) return { installPath: null, isEphemeral: false };\n const home = homedir();\n const ephemeralPrefixes = [\n path.join(home, \".npm\", \"_npx\"),\n path.join(home, \".local\", \"share\", \"pnpm\", \"dlx\"),\n \"/tmp/\",\n \"/var/folders/\",\n ];\n const isEphemeral = ephemeralPrefixes.some((p) => raw.startsWith(p));\n return { installPath: raw, isEphemeral };\n}\n\n/**\n * Probe the better-sqlite3 native binding by opening an in-memory DB.\n */\nexport function probeBetterSqlite3(): SqliteProbeResult {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const Database = req(\"better-sqlite3\") as typeof import(\"better-sqlite3\");\n const db = new Database(\":memory:\");\n db.close();\n return { ok: true, summary: \"native binding loads cleanly\" };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n const firstLine = msg.split(\"\\n\")[0] ?? msg;\n return { ok: false, summary: firstLine };\n }\n}\n\nexport async function safeCheckAuth(\n spawnCli?: SpawnCliFn,\n): Promise<ClaudeAuthStatus> {\n try {\n return await checkClaudeAuth(spawnCli);\n } catch {\n return { loggedIn: false };\n }\n}\n\nexport function readPackageVersion(): string | null {\n const candidates = [\n \"../../../package.json\",\n \"../../package.json\",\n \"../package.json\",\n ];\n for (const candidate of candidates) {\n try {\n const pkg = req(candidate) as { version?: unknown };\n if (typeof pkg.version === \"string\" && pkg.version.length > 0) {\n return pkg.version;\n }\n } catch {\n // Fall through to the next runtime layout candidate.\n }\n }\n return null;\n}\n","import { buildProviderSetupView } from \"../../agent/provider-view.js\";\nimport { checkClaudeAuth } from \"../../agent/providers/claude/index.js\";\nimport type { ProviderStatus } from \"../../agent/types.js\";\nimport { isCursorEnabled } from \"../../update/config.js\";\nimport type { AgentDoctorCheck, DoctorOptions } from \"./types.js\";\n\nexport async function gatherAgentChecks(\n options: DoctorOptions,\n): Promise<AgentDoctorCheck[]> {\n const view = await buildProviderSetupView({\n spawnCli: options.spawnCli,\n statuses:\n options.providerStatuses ??\n (options.spawnCli === undefined\n ? undefined\n : await injectedProviderStatuses(options)),\n });\n return view.choices.map((choice) => {\n return {\n status: choice.ready ? \"ok\" : \"problem\",\n id: choice.id,\n label: choice.label,\n readiness: choice.readiness,\n selected: choice.selected,\n recommended: choice.recommended,\n installed: choice.installed,\n authenticated: choice.authenticated,\n model: choice.effectiveModel,\n providerDefaultModel: choice.providerDefaultModel,\n configuredModel: choice.configuredModel,\n account: choice.account,\n detail: choice.detail,\n fix: choice.fixCommand ?? undefined,\n };\n });\n}\n\nasync function injectedProviderStatuses(\n options: DoctorOptions,\n): Promise<ProviderStatus[]> {\n const auth = await checkClaudeAuth(options.spawnCli);\n const hasApiKey =\n process.env.ANTHROPIC_API_KEY !== undefined &&\n process.env.ANTHROPIC_API_KEY.length > 0;\n const claudeReady = auth.loggedIn || hasApiKey;\n const statuses: ProviderStatus[] = [\n {\n id: \"claude\",\n installed: true,\n authenticated: claudeReady,\n detail: claudeReady\n ? auth.email ?? (hasApiKey ? \"ANTHROPIC_API_KEY set\" : \"logged in\")\n : \"not logged in\",\n },\n {\n id: \"codex\",\n installed: false,\n authenticated: false,\n detail: \"codex status not injected\",\n },\n ];\n if (isCursorEnabled()) {\n statuses.push({\n id: \"cursor\",\n installed: false,\n authenticated: false,\n detail: \"cursor-agent status not injected\",\n });\n }\n return statuses;\n}\n","import { readConfig } from \"../../update/config.js\";\nimport { readStateForDoctor } from \"../../update/schedule.js\";\nimport { isNewer } from \"../../update/semver.js\";\nimport { formatDuration } from \"./duration.js\";\nimport type { Check, DoctorOptions } from \"./types.js\";\n\nexport async function gatherUpdateChecks(\n options: DoctorOptions,\n installedVersion: string,\n): Promise<Check[]> {\n const checks: Check[] = [];\n const state = readStateForDoctor(options.updateStatePath);\n const config = await readConfig(options.updateConfigPath);\n\n if (state === null || state.latest_version.length === 0) {\n checks.push({\n status: \"info\",\n key: \"update.status\",\n message: `on ${installedVersion}; no update check has run yet`,\n fix: \"run: almanac update --check\",\n });\n } else if (isNewer(state.latest_version, installedVersion)) {\n const dismissed = state.dismissed_versions.includes(state.latest_version)\n ? \" (dismissed — run `almanac update` to install anyway)\"\n : \"\";\n checks.push({\n status: \"problem\",\n key: \"update.status\",\n message:\n `${state.latest_version} available (you're on ${installedVersion})${dismissed}`,\n fix: \"run: almanac update\",\n });\n } else {\n checks.push({\n status: \"ok\",\n key: \"update.status\",\n message: `on latest (${installedVersion})`,\n });\n }\n\n if (state !== null && state.last_check_at > 0) {\n const now = (options.now?.() ?? new Date()).getTime();\n const ageMs = now - state.last_check_at * 1000;\n const failedSuffix =\n state.last_fetch_failed_at !== undefined &&\n state.last_fetch_failed_at === state.last_check_at\n ? \" (last attempt failed — will retry next invocation)\"\n : \"\";\n checks.push({\n status: \"info\",\n key: \"update.last_check\",\n message: `last checked: ${formatDuration(ageMs)} ago${failedSuffix}`,\n });\n } else {\n checks.push({\n status: \"info\",\n key: \"update.last_check\",\n message: \"last checked: never\",\n });\n }\n\n checks.push({\n status: \"info\",\n key: \"update.notifier\",\n message: `update notifier: ${config.update_notifier ? \"enabled\" : \"disabled\"}`,\n fix: config.update_notifier\n ? undefined\n : \"run: almanac config set update_notifier true\",\n });\n\n if (state !== null && state.dismissed_versions.length > 0) {\n checks.push({\n status: \"info\",\n key: \"update.dismissed\",\n message: `dismissed versions: ${state.dismissed_versions.join(\", \")}`,\n });\n }\n\n return checks;\n}\n","import { formatReport } from \"./doctor-checks/format.js\";\nimport { gatherInstallChecks } from \"./doctor-checks/install.js\";\nimport { readPackageVersion } from \"./doctor-checks/probes.js\";\nimport type {\n Check,\n CheckStatus,\n AgentDoctorCheck,\n DoctorOptions,\n DoctorReport,\n DoctorResult,\n SqliteProbeResult,\n} from \"./doctor-checks/types.js\";\nimport { gatherAgentChecks } from \"./doctor-checks/agents.js\";\nimport { gatherUpdateChecks } from \"./doctor-checks/updates.js\";\n\nexport type {\n Check,\n CheckStatus,\n DoctorOptions,\n DoctorReport,\n DoctorResult,\n SqliteProbeResult,\n};\n\n/**\n * `almanac doctor` — install + wiki health report.\n *\n * Separate from `almanac health` (which checks graph integrity of a\n * specific wiki). `doctor` answers the \"is this install even set up\n * correctly?\" question that users hit when first trying the tool or when\n * sessions silently stop getting captured.\n *\n * This file is the command composition root. The section-specific probes\n * and formatting live in `doctor-checks/` so each durable fact has one\n * obvious owner.\n */\nexport async function runDoctor(\n options: DoctorOptions,\n): Promise<DoctorResult> {\n const version =\n options.versionOverride ?? readPackageVersion() ?? \"unknown\";\n\n const install: Check[] = options.wikiOnly === true\n ? []\n : await gatherInstallChecks(options);\n\n const agents: AgentDoctorCheck[] = options.wikiOnly === true\n ? []\n : await gatherAgentChecks(options);\n\n const updates: Check[] = options.wikiOnly === true\n ? []\n : await gatherUpdateChecks(options, version);\n\n const wiki: Check[] = options.installOnly === true\n ? []\n : await safeGatherWikiChecks(options);\n\n const report: DoctorReport = { version, install, agents, updates, wiki };\n\n if (options.json === true) {\n return {\n stdout: `${JSON.stringify(report, null, 2)}\\n`,\n stderr: \"\",\n exitCode: 0,\n };\n }\n\n return {\n stdout: formatReport(report, options),\n stderr: \"\",\n exitCode: 0,\n };\n}\n\nasync function safeGatherWikiChecks(\n options: DoctorOptions,\n): Promise<Check[]> {\n try {\n const { gatherWikiChecks } = await import(\"./doctor-checks/wiki.js\");\n return await gatherWikiChecks(options);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return [\n {\n status: \"problem\",\n key: \"wiki.checks\",\n message: `could not run wiki checks: ${msg.split(\"\\n\")[0] ?? msg}`,\n fix: \"run: npm rebuild better-sqlite3 (in the install directory)\",\n },\n ];\n }\n}\n"],"mappings":"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","names":["existsSync","homedir","path","path","homedir","existsSync"]}
@@ -2,23 +2,20 @@
2
2
  import {
3
3
  buildProviderSetupView,
4
4
  parseAgentSelection
5
- } from "./chunk-BGUID5BS.js";
5
+ } from "./chunk-J7DNV2DH.js";
6
6
  import {
7
+ disabledAgentProviderMessage,
8
+ formatEnabledAgentProviderList,
7
9
  isAgentProviderId,
10
+ isEnabledAgentProviderId,
8
11
  readConfig,
9
12
  writeConfig
10
- } from "./chunk-P5WGG4FJ.js";
13
+ } from "./chunk-3E7JNMTZ.js";
11
14
 
12
15
  // src/commands/agents.ts
13
16
  async function runAgentsList() {
14
17
  const view = await buildProviderSetupView();
15
- const active = view.choices.find((choice) => choice.selected);
16
- const activeModel = active?.effectiveModel ?? "provider default";
17
- const lines = [
18
- "codealmanac agents",
19
- `current: ${view.defaultProvider} (model: ${activeModel})`,
20
- ""
21
- ];
18
+ const lines = ["codealmanac agents\n"];
22
19
  for (const choice of view.choices) {
23
20
  const selected = choice.selected ? "*" : " ";
24
21
  const recommended = choice.recommended ? "recommended" : "";
@@ -36,10 +33,9 @@ async function runAgentsList() {
36
33
  );
37
34
  }
38
35
  lines.push(
39
- "",
40
- "Change provider: almanac agents use <claude|codex|cursor>",
41
- "Set model: almanac agents model <provider> <model>",
42
- "Reset model: almanac agents model <provider> --default"
36
+ `
37
+ Use: almanac agents use <${formatEnabledAgentProviderList().replaceAll(", ", "|")}>`,
38
+ "Set model: almanac agents model <provider> <model>"
43
39
  );
44
40
  return { stdout: `${lines.join("\n")}
45
41
  `, stderr: "", exitCode: 0 };
@@ -80,12 +76,15 @@ async function setDefaultAgent(opts) {
80
76
  if (parsed.provider === null) {
81
77
  return {
82
78
  stdout: "",
83
- stderr: `almanac: unknown agent '${opts.provider}'. Expected one of: claude, codex, cursor.
79
+ stderr: `almanac: unknown agent '${opts.provider}'. Expected one of: ${formatEnabledAgentProviderList()}.
84
80
  `,
85
81
  exitCode: 1
86
82
  };
87
83
  }
88
84
  const provider = parsed.provider;
85
+ if (!isEnabledAgentProviderId(provider)) {
86
+ return disabledProviderResult(provider);
87
+ }
89
88
  const config = await readConfig();
90
89
  const next = {
91
90
  ...config,
@@ -100,8 +99,8 @@ async function setDefaultAgent(opts) {
100
99
  };
101
100
  await writeConfig(next);
102
101
  return {
103
- stdout: parsed.model === void 0 ? `codealmanac: default provider set to ${provider}.
104
- ` : `codealmanac: default provider set to ${provider}; ${provider} model set to ${parsed.model}.
102
+ stdout: parsed.model === void 0 ? `codealmanac: default agent set to ${provider}.
103
+ ` : `codealmanac: default agent set to ${provider}; ${provider} model set to ${parsed.model}.
105
104
  `,
106
105
  stderr: "",
107
106
  exitCode: 0
@@ -124,11 +123,14 @@ async function setProviderModel(opts) {
124
123
  if (!isAgentProviderId(opts.provider)) {
125
124
  return {
126
125
  stdout: "",
127
- stderr: `almanac: unknown agent '${opts.provider}'. Expected one of: claude, codex, cursor.
126
+ stderr: `almanac: unknown agent '${opts.provider}'. Expected one of: ${formatEnabledAgentProviderList()}.
128
127
  `,
129
128
  exitCode: 1
130
129
  };
131
130
  }
131
+ if (!isEnabledAgentProviderId(opts.provider)) {
132
+ return disabledProviderResult(opts.provider);
133
+ }
132
134
  if (opts.defaultModel !== true && (opts.model === void 0 || opts.model.length === 0)) {
133
135
  return {
134
136
  stdout: "",
@@ -164,6 +166,14 @@ function normalizeRequestedModel(opts) {
164
166
  if (opts.model === "default" || opts.model === "null") return null;
165
167
  return opts.model;
166
168
  }
169
+ function disabledProviderResult(provider) {
170
+ return {
171
+ stdout: "",
172
+ stderr: `almanac: ${disabledAgentProviderMessage(provider)}
173
+ `,
174
+ exitCode: 1
175
+ };
176
+ }
167
177
  function readinessLabel(readiness) {
168
178
  switch (readiness) {
169
179
  case "ready":
@@ -192,4 +202,4 @@ export {
192
202
  runDeprecatedSetAgentModel,
193
203
  runAgentsModel
194
204
  };
195
- //# sourceMappingURL=chunk-6BJUYZ43.js.map
205
+ //# sourceMappingURL=chunk-GPFVEF6V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/agents.ts"],"sourcesContent":["import {\n buildProviderSetupView,\n parseAgentSelection,\n type ProviderReadiness,\n} from \"../agent/provider-view.js\";\nimport {\n disabledAgentProviderMessage,\n formatEnabledAgentProviderList,\n isAgentProviderId,\n isEnabledAgentProviderId,\n readConfig,\n writeConfig,\n type AgentProviderId,\n} from \"../update/config.js\";\n\nexport interface AgentsResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport async function runAgentsList(): Promise<AgentsResult> {\n const view = await buildProviderSetupView();\n const lines = [\"codealmanac agents\\n\"];\n for (const choice of view.choices) {\n const selected = choice.selected ? \"*\" : \" \";\n const recommended = choice.recommended ? \"recommended\" : \"\";\n const model = choice.effectiveModel ?? \"provider default\";\n const detail = choice.account ?? choice.fixCommand ?? choice.detail;\n lines.push(\n [\n selected,\n choice.label.padEnd(6),\n readinessLabel(choice.readiness).padEnd(15),\n recommended.padEnd(11),\n `model: ${model}`.padEnd(31),\n detail,\n ].join(\" \").trimEnd(),\n );\n }\n lines.push(\n `\\nUse: almanac agents use <${formatEnabledAgentProviderList().replaceAll(\", \", \"|\")}>`,\n \"Set model: almanac agents model <provider> <model>\",\n );\n return { stdout: `${lines.join(\"\\n\")}\\n`, stderr: \"\", exitCode: 0 };\n}\n\nexport async function runAgentsDoctor(): Promise<AgentsResult> {\n const view = await buildProviderSetupView();\n const lines = [\"codealmanac agent doctor\\n\"];\n for (const choice of view.choices) {\n lines.push(`${choice.ready ? \"✓\" : \"✗\"} ${choice.label}`);\n lines.push(` status: ${readinessLabel(choice.readiness)}`);\n lines.push(` model: ${choice.effectiveModel ?? \"provider default\"}`);\n if (choice.account !== null) {\n lines.push(` account: ${choice.account}`);\n } else if (choice.detail.length > 0) {\n lines.push(` detail: ${choice.detail}`);\n }\n if (choice.fixCommand !== null) lines.push(` fix: ${choice.fixCommand}`);\n lines.push(\"\");\n }\n return { stdout: `${lines.join(\"\\n\").trimEnd()}\\n`, stderr: \"\", exitCode: 0 };\n}\n\nexport interface SetDefaultAgentOptions {\n provider: string;\n}\n\nexport async function runSetDefaultAgent(\n opts: SetDefaultAgentOptions,\n): Promise<AgentsResult> {\n return setDefaultAgent(opts);\n}\n\nexport async function runDeprecatedSetDefaultAgent(\n opts: SetDefaultAgentOptions,\n): Promise<AgentsResult> {\n return withDeprecation(\n await setDefaultAgent(opts),\n \"almanac set default-agent <provider>\",\n \"almanac agents use <provider>\",\n );\n}\n\nexport async function runAgentsUse(opts: SetDefaultAgentOptions): Promise<AgentsResult> {\n return setDefaultAgent(opts);\n}\n\nasync function setDefaultAgent(\n opts: SetDefaultAgentOptions,\n): Promise<AgentsResult> {\n const parsed = parseAgentSelection(opts.provider);\n if (parsed.provider === null) {\n return {\n stdout: \"\",\n stderr:\n `almanac: unknown agent '${opts.provider}'. ` +\n `Expected one of: ${formatEnabledAgentProviderList()}.\\n`,\n exitCode: 1,\n };\n }\n const provider = parsed.provider;\n if (!isEnabledAgentProviderId(provider)) {\n return disabledProviderResult(provider);\n }\n const config = await readConfig();\n const next = {\n ...config,\n agent: {\n ...config.agent,\n default: provider,\n models:\n parsed.model === undefined\n ? config.agent.models\n : {\n ...config.agent.models,\n [provider]: parsed.model,\n },\n },\n };\n await writeConfig(next);\n return {\n stdout:\n parsed.model === undefined\n ? `codealmanac: default agent set to ${provider}.\\n`\n : `codealmanac: default agent set to ${provider}; ${provider} model set to ${parsed.model}.\\n`,\n stderr: \"\",\n exitCode: 0,\n };\n}\n\nexport async function runSetAgentModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n return setProviderModel(opts);\n}\n\nexport async function runDeprecatedSetAgentModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n return withDeprecation(\n await setProviderModel(opts),\n \"almanac set model <provider> <model>\",\n \"almanac agents model <provider> <model>\",\n );\n}\n\nexport async function runAgentsModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n return setProviderModel(opts);\n}\n\nasync function setProviderModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): Promise<AgentsResult> {\n if (!isAgentProviderId(opts.provider)) {\n return {\n stdout: \"\",\n stderr:\n `almanac: unknown agent '${opts.provider}'. ` +\n `Expected one of: ${formatEnabledAgentProviderList()}.\\n`,\n exitCode: 1,\n };\n }\n if (!isEnabledAgentProviderId(opts.provider)) {\n return disabledProviderResult(opts.provider);\n }\n if (\n opts.defaultModel !== true &&\n (opts.model === undefined || opts.model.length === 0)\n ) {\n return {\n stdout: \"\",\n stderr:\n `almanac: missing model for ${opts.provider}. ` +\n \"Pass a model id or --default.\\n\",\n exitCode: 1,\n };\n }\n const provider = opts.provider as AgentProviderId;\n const config = await readConfig();\n const model = normalizeRequestedModel(opts);\n await writeConfig({\n ...config,\n agent: {\n ...config.agent,\n models: {\n ...config.agent.models,\n [provider]: model,\n },\n },\n });\n return {\n stdout:\n model === null\n ? `codealmanac: ${provider} model reset to provider default.\\n`\n : `codealmanac: ${provider} model set to ${model}.\\n`,\n stderr: \"\",\n exitCode: 0,\n };\n}\n\nfunction normalizeRequestedModel(opts: {\n provider: string;\n model?: string;\n defaultModel?: boolean;\n}): string | null {\n if (opts.defaultModel === true) return null;\n if (opts.model === undefined || opts.model.length === 0) return null;\n if (opts.model === \"default\" || opts.model === \"null\") return null;\n return opts.model;\n}\n\nfunction disabledProviderResult(provider: string): AgentsResult {\n return {\n stdout: \"\",\n stderr: `almanac: ${disabledAgentProviderMessage(provider)}\\n`,\n exitCode: 1,\n };\n}\n\nfunction readinessLabel(readiness: ProviderReadiness): string {\n switch (readiness) {\n case \"ready\":\n return \"ready\";\n case \"missing\":\n return \"missing\";\n case \"not-authenticated\":\n return \"not ready\";\n }\n}\n\nfunction withDeprecation(\n result: AgentsResult,\n oldUsage: string,\n newUsage: string,\n): AgentsResult {\n return {\n ...result,\n stderr:\n `almanac: warning: \\`${oldUsage}\\` is deprecated; use \\`${newUsage}\\`.\\n` +\n result.stderr,\n };\n}\n"],"mappings":"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","names":[]}
@@ -7,7 +7,7 @@ import {
7
7
  getConfigPath,
8
8
  getLegacyConfigPath,
9
9
  parseConfigText
10
- } from "./chunk-P5WGG4FJ.js";
10
+ } from "./chunk-3E7JNMTZ.js";
11
11
 
12
12
  // src/update/schedule.ts
13
13
  import { spawn } from "child_process";
@@ -86,4 +86,4 @@ export {
86
86
  runInternalUpdateCheck,
87
87
  readStateForDoctor
88
88
  };
89
- //# sourceMappingURL=chunk-TILAKDN6.js.map
89
+ //# sourceMappingURL=chunk-HJ3WREGP.js.map