codealmanac 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -20
- package/dist/{agents-RVTQYE6A.js → agents-V2ZOIACP.js} +6 -5
- package/dist/{chunk-P5WGG4FJ.js → chunk-5BWUMAOX.js} +2 -2
- package/dist/chunk-5BWUMAOX.js.map +1 -0
- package/dist/{chunk-KQUVMF27.js → chunk-BFIG2CXM.js} +2 -516
- package/dist/chunk-BFIG2CXM.js.map +1 -0
- package/dist/{chunk-DL5BXZCX.js → chunk-BQY5L3DL.js} +3 -53
- package/dist/chunk-BQY5L3DL.js.map +1 -0
- package/dist/{chunk-F53U6JQG.js → chunk-CQJVM34R.js} +2 -2
- package/dist/chunk-FUBE6KCO.js +124 -0
- package/dist/chunk-FUBE6KCO.js.map +1 -0
- package/dist/chunk-IZBXXAVL.js +524 -0
- package/dist/chunk-IZBXXAVL.js.map +1 -0
- package/dist/{chunk-7JUX4ADQ.js → chunk-IZT6RBHS.js} +1 -1
- package/dist/{chunk-SMIK2YLU.js → chunk-JLQZELHQ.js} +82 -88
- package/dist/chunk-JLQZELHQ.js.map +1 -0
- package/dist/{chunk-TT6ZP4GS.js → chunk-KZXWPG4P.js} +2 -2
- package/dist/{chunk-6BJUYZ43.js → chunk-QIA22IAM.js} +8 -16
- package/dist/chunk-QIA22IAM.js.map +1 -0
- package/dist/{chunk-BGUID5BS.js → chunk-RALBM6HZ.js} +20 -139
- package/dist/chunk-RALBM6HZ.js.map +1 -0
- package/dist/{chunk-TILAKDN6.js → chunk-U5DLLWIC.js} +3 -3
- package/dist/chunk-WL4UE7Q6.js +1386 -0
- package/dist/chunk-WL4UE7Q6.js.map +1 -0
- package/dist/{chunk-GFUB57IT.js → chunk-ZUQN5Y3K.js} +48 -124
- package/dist/chunk-ZUQN5Y3K.js.map +1 -0
- package/dist/{chunk-MRRX4UQB.js → chunk-ZZLLOAI6.js} +3 -3
- package/dist/{cli-CL4ID7EO.js → cli-XWPNARA6.js} +35 -18
- package/dist/cli-XWPNARA6.js.map +1 -0
- package/dist/codealmanac.js +1 -1
- package/dist/{config-ML2RCR7J.js → config-KH3JUMG6.js} +4 -4
- package/dist/doctor-ENJT665Z.js +18 -0
- package/dist/paths-O5CZADP2.js +14 -0
- package/dist/process-KFSLENL3.js +61 -0
- package/dist/{register-commands-FBJ6XQ3L.js → register-commands-LULZUSPO.js} +993 -1015
- package/dist/register-commands-LULZUSPO.js.map +1 -0
- package/dist/uninstall-BD4MMQ7M.js +16 -0
- package/dist/uninstall-BD4MMQ7M.js.map +1 -0
- package/dist/update-XSKPDFMJ.js +11 -0
- package/dist/update-XSKPDFMJ.js.map +1 -0
- package/dist/{wiki-IGNRNLUZ.js → wiki-O4RWMAE6.js} +8 -6
- package/dist/wiki-O4RWMAE6.js.map +1 -0
- package/guides/mini.md +11 -9
- package/guides/reference.md +96 -39
- package/hooks/almanac-capture.sh +7 -8
- package/package.json +1 -1
- package/prompts/agents/.gitkeep +1 -0
- package/prompts/base/notability.md +139 -0
- package/prompts/base/purpose.md +85 -0
- package/prompts/base/syntax.md +114 -0
- package/prompts/operations/absorb.md +43 -0
- package/prompts/operations/build.md +49 -0
- package/prompts/operations/garden.md +51 -0
- package/dist/chunk-6BJUYZ43.js.map +0 -1
- package/dist/chunk-BGUID5BS.js.map +0 -1
- package/dist/chunk-DL5BXZCX.js.map +0 -1
- package/dist/chunk-GFUB57IT.js.map +0 -1
- package/dist/chunk-KQUVMF27.js.map +0 -1
- package/dist/chunk-P5WGG4FJ.js.map +0 -1
- package/dist/chunk-SMIK2YLU.js.map +0 -1
- package/dist/cli-CL4ID7EO.js.map +0 -1
- package/dist/doctor-DOLJRGS4.js +0 -17
- package/dist/register-commands-FBJ6XQ3L.js.map +0 -1
- package/dist/uninstall-DX6LFKMX.js +0 -15
- package/dist/update-P2IPG7RO.js +0 -11
- package/dist/wiki-IGNRNLUZ.js.map +0 -1
- package/prompts/bootstrap.md +0 -176
- package/prompts/reviewer.md +0 -129
- package/prompts/writer.md +0 -134
- /package/dist/{agents-RVTQYE6A.js.map → agents-V2ZOIACP.js.map} +0 -0
- /package/dist/{chunk-F53U6JQG.js.map → chunk-CQJVM34R.js.map} +0 -0
- /package/dist/{chunk-7JUX4ADQ.js.map → chunk-IZT6RBHS.js.map} +0 -0
- /package/dist/{chunk-TT6ZP4GS.js.map → chunk-KZXWPG4P.js.map} +0 -0
- /package/dist/{chunk-TILAKDN6.js.map → chunk-U5DLLWIC.js.map} +0 -0
- /package/dist/{chunk-MRRX4UQB.js.map → chunk-ZZLLOAI6.js.map} +0 -0
- /package/dist/{config-ML2RCR7J.js.map → config-KH3JUMG6.js.map} +0 -0
- /package/dist/{doctor-DOLJRGS4.js.map → doctor-ENJT665Z.js.map} +0 -0
- /package/dist/{uninstall-DX6LFKMX.js.map → paths-O5CZADP2.js.map} +0 -0
- /package/dist/{update-P2IPG7RO.js.map → process-KFSLENL3.js.map} +0 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
readStateForDoctor
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-U5DLLWIC.js";
|
|
5
|
+
import {
|
|
6
|
+
isNewer
|
|
7
|
+
} from "./chunk-CQJVM34R.js";
|
|
5
8
|
import {
|
|
6
9
|
formatDuration
|
|
7
10
|
} from "./chunk-4CODZRHH.js";
|
|
@@ -15,17 +18,16 @@ import {
|
|
|
15
18
|
} from "./chunk-FM3VRDK7.js";
|
|
16
19
|
import {
|
|
17
20
|
IMPORT_LINE
|
|
18
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ZUQN5Y3K.js";
|
|
19
22
|
import {
|
|
20
|
-
buildProviderSetupView
|
|
21
|
-
|
|
22
|
-
} from "./chunk-BGUID5BS.js";
|
|
23
|
+
buildProviderSetupView
|
|
24
|
+
} from "./chunk-RALBM6HZ.js";
|
|
23
25
|
import {
|
|
24
|
-
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
checkClaudeAuth
|
|
27
|
+
} from "./chunk-FUBE6KCO.js";
|
|
26
28
|
import {
|
|
27
29
|
readConfig
|
|
28
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-5BWUMAOX.js";
|
|
29
31
|
|
|
30
32
|
// src/commands/doctor-checks/format.ts
|
|
31
33
|
function formatReport(report, options) {
|
|
@@ -164,6 +166,13 @@ function probeBetterSqlite3() {
|
|
|
164
166
|
return { ok: false, summary: firstLine };
|
|
165
167
|
}
|
|
166
168
|
}
|
|
169
|
+
async function safeCheckAuth(spawnCli) {
|
|
170
|
+
try {
|
|
171
|
+
return await checkClaudeAuth(spawnCli);
|
|
172
|
+
} catch {
|
|
173
|
+
return { loggedIn: false };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
167
176
|
function readPackageVersion() {
|
|
168
177
|
const candidates = [
|
|
169
178
|
"../../../package.json",
|
|
@@ -196,12 +205,13 @@ async function gatherInstallChecks(options) {
|
|
|
196
205
|
message: sqlite.ok ? `better-sqlite3 native binding OK (Node ${nodeVersion})` : `better-sqlite3 native binding failed: ${sqlite.summary}`,
|
|
197
206
|
fix: sqlite.ok ? void 0 : "run: npm rebuild better-sqlite3 (in the install directory)"
|
|
198
207
|
});
|
|
199
|
-
|
|
208
|
+
const auth = await safeCheckAuth(options.spawnCli);
|
|
209
|
+
checks.push(describeAuth(auth));
|
|
200
210
|
const settingsPath = options.settingsPath ?? path2.join(homedir2(), ".claude", "settings.json");
|
|
201
211
|
checks.push(await describeHook(settingsPath));
|
|
202
212
|
const claudeDir = options.claudeDir ?? path2.join(homedir2(), ".claude");
|
|
203
|
-
checks.push(describeGuides(claudeDir
|
|
204
|
-
checks.push(await
|
|
213
|
+
checks.push(describeGuides(claudeDir));
|
|
214
|
+
checks.push(await describeImportLine(claudeDir));
|
|
205
215
|
return checks;
|
|
206
216
|
}
|
|
207
217
|
function describeInstallPath(installPath, isEphemeral) {
|
|
@@ -220,12 +230,35 @@ function describeInstallPath(installPath, isEphemeral) {
|
|
|
220
230
|
fix: isEphemeral ? "run: npm install -g codealmanac (to make the install permanent)" : void 0
|
|
221
231
|
};
|
|
222
232
|
}
|
|
223
|
-
function
|
|
233
|
+
function describeAuth(auth) {
|
|
234
|
+
if (auth.loggedIn) {
|
|
235
|
+
if (auth.authMethod === "apiKey") {
|
|
236
|
+
return {
|
|
237
|
+
status: "ok",
|
|
238
|
+
key: "install.auth",
|
|
239
|
+
message: "claude auth: ANTHROPIC_API_KEY set"
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const who = auth.email ?? "Claude account";
|
|
243
|
+
const plan = auth.subscriptionType !== void 0 ? ` (${auth.subscriptionType} subscription)` : "";
|
|
244
|
+
return {
|
|
245
|
+
status: "ok",
|
|
246
|
+
key: "install.auth",
|
|
247
|
+
message: `claude auth: ${who}${plan}`
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (process.env.ANTHROPIC_API_KEY !== void 0 && process.env.ANTHROPIC_API_KEY.length > 0) {
|
|
251
|
+
return {
|
|
252
|
+
status: "ok",
|
|
253
|
+
key: "install.auth",
|
|
254
|
+
message: "claude auth: ANTHROPIC_API_KEY set"
|
|
255
|
+
};
|
|
256
|
+
}
|
|
224
257
|
return {
|
|
225
|
-
status: "
|
|
258
|
+
status: "problem",
|
|
226
259
|
key: "install.auth",
|
|
227
|
-
message: "
|
|
228
|
-
fix: "run:
|
|
260
|
+
message: "claude auth: not signed in",
|
|
261
|
+
fix: "run: claude auth login --claudeai (or export ANTHROPIC_API_KEY)"
|
|
229
262
|
};
|
|
230
263
|
}
|
|
231
264
|
async function describeHook(settingsPath) {
|
|
@@ -275,7 +308,7 @@ async function describeHook(settingsPath) {
|
|
|
275
308
|
};
|
|
276
309
|
}
|
|
277
310
|
}
|
|
278
|
-
function describeGuides(claudeDir
|
|
311
|
+
function describeGuides(claudeDir) {
|
|
279
312
|
const mini = path2.join(claudeDir, "codealmanac.md");
|
|
280
313
|
const ref = path2.join(claudeDir, "codealmanac-reference.md");
|
|
281
314
|
const haveMini = existsSync2(mini);
|
|
@@ -284,24 +317,7 @@ function describeGuides(claudeDir, cwd) {
|
|
|
284
317
|
return {
|
|
285
318
|
status: "ok",
|
|
286
319
|
key: "install.guides",
|
|
287
|
-
message: `Agent guides installed
|
|
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)"
|
|
320
|
+
message: `Agent guides installed (${path2.basename(mini)}, ${path2.basename(ref)})`
|
|
305
321
|
};
|
|
306
322
|
}
|
|
307
323
|
const missing = [
|
|
@@ -315,68 +331,46 @@ function describeGuides(claudeDir, cwd) {
|
|
|
315
331
|
fix: "run: almanac setup --yes"
|
|
316
332
|
};
|
|
317
333
|
}
|
|
318
|
-
async function
|
|
334
|
+
async function describeImportLine(claudeDir) {
|
|
319
335
|
const claudeMd = path2.join(claudeDir, "CLAUDE.md");
|
|
320
|
-
if (existsSync2(claudeMd)) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
return {
|
|
340
|
-
status: "problem",
|
|
341
|
-
key: "install.import",
|
|
342
|
-
message: `could not read ${claudeMd}: ${msg}`
|
|
343
|
-
};
|
|
344
|
-
}
|
|
336
|
+
if (!existsSync2(claudeMd)) {
|
|
337
|
+
return {
|
|
338
|
+
status: "problem",
|
|
339
|
+
key: "install.import",
|
|
340
|
+
message: "CLAUDE.md import not present (no ~/.claude/CLAUDE.md)",
|
|
341
|
+
fix: "run: almanac setup --yes"
|
|
342
|
+
};
|
|
345
343
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
if (
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
} catch (err) {
|
|
358
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
344
|
+
try {
|
|
345
|
+
const contents = await readFile(claudeMd, "utf8");
|
|
346
|
+
const lines = contents.split(/\r?\n/).map((l) => l.trim());
|
|
347
|
+
const present = lines.some((line) => {
|
|
348
|
+
if (line === IMPORT_LINE) return true;
|
|
349
|
+
if (!line.startsWith(IMPORT_LINE)) return false;
|
|
350
|
+
const next = line[IMPORT_LINE.length];
|
|
351
|
+
return next === " " || next === " ";
|
|
352
|
+
});
|
|
353
|
+
if (present) {
|
|
359
354
|
return {
|
|
360
|
-
status: "
|
|
355
|
+
status: "ok",
|
|
361
356
|
key: "install.import",
|
|
362
|
-
message:
|
|
357
|
+
message: "CLAUDE.md import present"
|
|
363
358
|
};
|
|
364
359
|
}
|
|
365
|
-
}
|
|
366
|
-
const cursorRule = path2.join(cwd, ".cursor", "rules", "codealmanac.mdc");
|
|
367
|
-
if (existsSync2(cursorRule)) {
|
|
368
360
|
return {
|
|
369
|
-
status: "
|
|
361
|
+
status: "problem",
|
|
370
362
|
key: "install.import",
|
|
371
|
-
message: "
|
|
363
|
+
message: "CLAUDE.md import line missing",
|
|
364
|
+
fix: "run: almanac setup --yes"
|
|
365
|
+
};
|
|
366
|
+
} catch (err) {
|
|
367
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
368
|
+
return {
|
|
369
|
+
status: "problem",
|
|
370
|
+
key: "install.import",
|
|
371
|
+
message: `could not read ${claudeMd}: ${msg}`
|
|
372
372
|
};
|
|
373
373
|
}
|
|
374
|
-
return {
|
|
375
|
-
status: "problem",
|
|
376
|
-
key: "install.import",
|
|
377
|
-
message: "provider guide activation missing",
|
|
378
|
-
fix: "run: almanac setup --yes"
|
|
379
|
-
};
|
|
380
374
|
}
|
|
381
375
|
|
|
382
376
|
// src/commands/doctor-checks/agents.ts
|
|
@@ -513,7 +507,7 @@ async function runDoctor(options) {
|
|
|
513
507
|
}
|
|
514
508
|
async function safeGatherWikiChecks(options) {
|
|
515
509
|
try {
|
|
516
|
-
const { gatherWikiChecks } = await import("./wiki-
|
|
510
|
+
const { gatherWikiChecks } = await import("./wiki-O4RWMAE6.js");
|
|
517
511
|
return await gatherWikiChecks(options);
|
|
518
512
|
} catch (err) {
|
|
519
513
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -531,4 +525,4 @@ async function safeGatherWikiChecks(options) {
|
|
|
531
525
|
export {
|
|
532
526
|
runDoctor
|
|
533
527
|
};
|
|
534
|
-
//# sourceMappingURL=chunk-
|
|
528
|
+
//# sourceMappingURL=chunk-JLQZELHQ.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 { IMPORT_LINE } 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\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","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 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 return [\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 id: \"cursor\",\n installed: false,\n authenticated: false,\n detail: \"cursor-agent status not injected\",\n },\n ];\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"]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
readConfig,
|
|
9
9
|
readConfigWithOrigins,
|
|
10
10
|
serializeConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5BWUMAOX.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/config.ts
|
|
14
14
|
import { mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
@@ -279,4 +279,4 @@ export {
|
|
|
279
279
|
runConfigSet,
|
|
280
280
|
runConfigUnset
|
|
281
281
|
};
|
|
282
|
-
//# sourceMappingURL=chunk-
|
|
282
|
+
//# sourceMappingURL=chunk-KZXWPG4P.js.map
|
|
@@ -2,23 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
buildProviderSetupView,
|
|
4
4
|
parseAgentSelection
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RALBM6HZ.js";
|
|
6
6
|
import {
|
|
7
7
|
isAgentProviderId,
|
|
8
8
|
readConfig,
|
|
9
9
|
writeConfig
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5BWUMAOX.js";
|
|
11
11
|
|
|
12
12
|
// src/commands/agents.ts
|
|
13
13
|
async function runAgentsList() {
|
|
14
14
|
const view = await buildProviderSetupView();
|
|
15
|
-
const
|
|
16
|
-
const activeModel = active?.effectiveModel ?? "provider default";
|
|
17
|
-
const lines = [
|
|
18
|
-
"codealmanac agents",
|
|
19
|
-
`current: ${view.defaultProvider} (model: ${activeModel})`,
|
|
20
|
-
""
|
|
21
|
-
];
|
|
15
|
+
const lines = ["codealmanac agents\n"];
|
|
22
16
|
for (const choice of view.choices) {
|
|
23
17
|
const selected = choice.selected ? "*" : " ";
|
|
24
18
|
const recommended = choice.recommended ? "recommended" : "";
|
|
@@ -36,10 +30,8 @@ async function runAgentsList() {
|
|
|
36
30
|
);
|
|
37
31
|
}
|
|
38
32
|
lines.push(
|
|
39
|
-
"",
|
|
40
|
-
"
|
|
41
|
-
"Set model: almanac agents model <provider> <model>",
|
|
42
|
-
"Reset model: almanac agents model <provider> --default"
|
|
33
|
+
"\nUse: almanac agents use <claude|codex|cursor>",
|
|
34
|
+
"Set model: almanac agents model <provider> <model>"
|
|
43
35
|
);
|
|
44
36
|
return { stdout: `${lines.join("\n")}
|
|
45
37
|
`, stderr: "", exitCode: 0 };
|
|
@@ -100,8 +92,8 @@ async function setDefaultAgent(opts) {
|
|
|
100
92
|
};
|
|
101
93
|
await writeConfig(next);
|
|
102
94
|
return {
|
|
103
|
-
stdout: parsed.model === void 0 ? `codealmanac: default
|
|
104
|
-
` : `codealmanac: default
|
|
95
|
+
stdout: parsed.model === void 0 ? `codealmanac: default agent set to ${provider}.
|
|
96
|
+
` : `codealmanac: default agent set to ${provider}; ${provider} model set to ${parsed.model}.
|
|
105
97
|
`,
|
|
106
98
|
stderr: "",
|
|
107
99
|
exitCode: 0
|
|
@@ -192,4 +184,4 @@ export {
|
|
|
192
184
|
runDeprecatedSetAgentModel,
|
|
193
185
|
runAgentsModel
|
|
194
186
|
};
|
|
195
|
-
//# sourceMappingURL=chunk-
|
|
187
|
+
//# sourceMappingURL=chunk-QIA22IAM.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 isAgentProviderId,\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 <claude|codex|cursor>\",\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: claude, codex, cursor.\\n\",\n exitCode: 1,\n };\n }\n const provider = parsed.provider;\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: claude, codex, cursor.\\n\",\n exitCode: 1,\n };\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 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":[]}
|
|
@@ -1,129 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
assertClaudeAuth,
|
|
4
|
+
checkClaudeAuth,
|
|
5
|
+
resolveClaudeExecutable
|
|
6
|
+
} from "./chunk-FUBE6KCO.js";
|
|
2
7
|
import {
|
|
3
8
|
AGENT_PROVIDER_IDS,
|
|
4
9
|
isAgentProviderId,
|
|
5
10
|
readConfig
|
|
6
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5BWUMAOX.js";
|
|
7
12
|
|
|
8
13
|
// src/agent/providers/claude/index.ts
|
|
9
14
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
10
|
-
|
|
11
|
-
// src/agent/providers/claude/auth.ts
|
|
12
|
-
import { spawn, spawnSync } from "child_process";
|
|
13
|
-
import { createRequire } from "module";
|
|
14
|
-
import { dirname, join } from "path";
|
|
15
|
-
var AUTH_TIMEOUT_MS = 1e4;
|
|
16
|
-
function resolveClaudeExecutable() {
|
|
17
|
-
const result = spawnSync("sh", ["-lc", "command -v claude"], {
|
|
18
|
-
encoding: "utf8"
|
|
19
|
-
});
|
|
20
|
-
if (result.status !== 0) return void 0;
|
|
21
|
-
const found = result.stdout.trim().split("\n")[0]?.trim();
|
|
22
|
-
return found !== void 0 && found.length > 0 ? found : void 0;
|
|
23
|
-
}
|
|
24
|
-
function resolveCliJsPath() {
|
|
25
|
-
const require2 = createRequire(import.meta.url);
|
|
26
|
-
const entry = require2.resolve("@anthropic-ai/claude-agent-sdk");
|
|
27
|
-
return join(dirname(entry), "cli.js");
|
|
28
|
-
}
|
|
29
|
-
var defaultSpawnCli = (args) => {
|
|
30
|
-
const command = resolveClaudeExecutable() ?? "claude";
|
|
31
|
-
const child = spawn(command, args, {
|
|
32
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
33
|
-
});
|
|
34
|
-
return child;
|
|
35
|
-
};
|
|
36
|
-
var legacySdkSpawnCli = (args) => {
|
|
37
|
-
const cliPath = resolveCliJsPath();
|
|
38
|
-
const child = spawn(process.execPath, [cliPath, ...args], {
|
|
39
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
40
|
-
});
|
|
41
|
-
return child;
|
|
42
|
-
};
|
|
43
|
-
async function checkClaudeAuth(spawnCli = defaultSpawnCli) {
|
|
44
|
-
if (spawnCli === defaultSpawnCli) {
|
|
45
|
-
const status = await checkClaudeAuthWith(defaultSpawnCli);
|
|
46
|
-
if (status.loggedIn) return status;
|
|
47
|
-
return await checkClaudeAuthWith(legacySdkSpawnCli);
|
|
48
|
-
}
|
|
49
|
-
return await checkClaudeAuthWith(spawnCli);
|
|
50
|
-
}
|
|
51
|
-
async function checkClaudeAuthWith(spawnCli) {
|
|
52
|
-
let child;
|
|
53
|
-
try {
|
|
54
|
-
child = spawnCli(["auth", "status", "--json"]);
|
|
55
|
-
} catch {
|
|
56
|
-
return { loggedIn: false };
|
|
57
|
-
}
|
|
58
|
-
return new Promise((resolve) => {
|
|
59
|
-
let stdout = "";
|
|
60
|
-
let stderr = "";
|
|
61
|
-
let settled = false;
|
|
62
|
-
const settle = (value) => {
|
|
63
|
-
if (settled) return;
|
|
64
|
-
settled = true;
|
|
65
|
-
clearTimeout(timer);
|
|
66
|
-
resolve(value);
|
|
67
|
-
};
|
|
68
|
-
const timer = setTimeout(() => {
|
|
69
|
-
try {
|
|
70
|
-
child.kill("SIGTERM");
|
|
71
|
-
} catch {
|
|
72
|
-
}
|
|
73
|
-
settle({ loggedIn: false });
|
|
74
|
-
}, AUTH_TIMEOUT_MS);
|
|
75
|
-
child.stdout.on("data", (data) => {
|
|
76
|
-
stdout += data.toString();
|
|
77
|
-
});
|
|
78
|
-
child.stderr.on("data", (data) => {
|
|
79
|
-
stderr += data.toString();
|
|
80
|
-
});
|
|
81
|
-
child.on("error", () => {
|
|
82
|
-
settle({ loggedIn: false });
|
|
83
|
-
});
|
|
84
|
-
child.on("close", (code) => {
|
|
85
|
-
if (code !== 0 && stdout.trim().length === 0) {
|
|
86
|
-
void stderr;
|
|
87
|
-
settle({ loggedIn: false });
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
try {
|
|
91
|
-
settle(parseClaudeAuthStatus(stdout.trim()));
|
|
92
|
-
} catch {
|
|
93
|
-
settle({ loggedIn: false });
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
function parseClaudeAuthStatus(raw) {
|
|
99
|
-
const parsed = JSON.parse(raw);
|
|
100
|
-
const loggedIn = parsed.loggedIn === true;
|
|
101
|
-
const out = { loggedIn };
|
|
102
|
-
if (typeof parsed.email === "string") out.email = parsed.email;
|
|
103
|
-
if (typeof parsed.subscriptionType === "string") {
|
|
104
|
-
out.subscriptionType = parsed.subscriptionType;
|
|
105
|
-
}
|
|
106
|
-
if (typeof parsed.authMethod === "string") {
|
|
107
|
-
out.authMethod = parsed.authMethod;
|
|
108
|
-
}
|
|
109
|
-
return out;
|
|
110
|
-
}
|
|
111
|
-
var UNAUTHENTICATED_MESSAGE = "not authenticated to Claude.\n\nOption 1 \u2014 use your Claude subscription (Pro/Max):\n claude auth login --claudeai\n\nOption 2 \u2014 use a pay-per-token API key:\n Get one at https://console.anthropic.com\n export ANTHROPIC_API_KEY=sk-ant-...\n\nVerify with: claude auth status";
|
|
112
|
-
async function assertClaudeAuth(spawnCli = defaultSpawnCli) {
|
|
113
|
-
const status = await checkClaudeAuth(spawnCli);
|
|
114
|
-
if (status.loggedIn) {
|
|
115
|
-
return status;
|
|
116
|
-
}
|
|
117
|
-
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
118
|
-
if (apiKey !== void 0 && apiKey.length > 0) {
|
|
119
|
-
return { loggedIn: true, authMethod: "apiKey" };
|
|
120
|
-
}
|
|
121
|
-
const err = new Error(UNAUTHENTICATED_MESSAGE);
|
|
122
|
-
err.code = "CLAUDE_AUTH_MISSING";
|
|
123
|
-
throw err;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// src/agent/providers/claude/index.ts
|
|
127
15
|
var DEFAULT_AGENT_MODEL = "claude-sonnet-4-6";
|
|
128
16
|
var metadata = {
|
|
129
17
|
id: "claude",
|
|
@@ -216,10 +104,10 @@ async function assertReady(spawnCli) {
|
|
|
216
104
|
}
|
|
217
105
|
|
|
218
106
|
// src/agent/providers/cli-status.ts
|
|
219
|
-
import { spawn
|
|
107
|
+
import { spawn, spawnSync } from "child_process";
|
|
220
108
|
var STATUS_TIMEOUT_MS = 3e3;
|
|
221
109
|
function commandExists(command) {
|
|
222
|
-
const result =
|
|
110
|
+
const result = spawnSync("sh", ["-lc", `command -v ${command}`], {
|
|
223
111
|
encoding: "utf8"
|
|
224
112
|
});
|
|
225
113
|
return result.status === 0 && result.stdout.trim().length > 0;
|
|
@@ -237,7 +125,7 @@ function runStatusCommand(command, args) {
|
|
|
237
125
|
resolve(value);
|
|
238
126
|
};
|
|
239
127
|
try {
|
|
240
|
-
child =
|
|
128
|
+
child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
241
129
|
} catch (err) {
|
|
242
130
|
const msg = err instanceof Error ? err.message : String(err);
|
|
243
131
|
resolve({ ok: false, detail: msg });
|
|
@@ -279,10 +167,10 @@ ${stderr}`.trim();
|
|
|
279
167
|
}
|
|
280
168
|
|
|
281
169
|
// src/agent/providers/jsonl-cli.ts
|
|
282
|
-
import { spawn as
|
|
170
|
+
import { spawn as spawn2 } from "child_process";
|
|
283
171
|
function runJsonlCli(opts) {
|
|
284
172
|
return new Promise((resolve) => {
|
|
285
|
-
const child =
|
|
173
|
+
const child = spawn2(opts.command, opts.args, {
|
|
286
174
|
cwd: opts.cwd,
|
|
287
175
|
env: opts.env,
|
|
288
176
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -391,18 +279,20 @@ function numberField(input, key) {
|
|
|
391
279
|
|
|
392
280
|
// src/agent/providers/prompt.ts
|
|
393
281
|
function combinedPrompt(opts, metadata4) {
|
|
394
|
-
const
|
|
395
|
-
return `${opts.systemPrompt}${
|
|
282
|
+
const agentFallback = buildAgentFallback(opts, metadata4);
|
|
283
|
+
return `${opts.systemPrompt}${agentFallback}
|
|
396
284
|
|
|
397
285
|
---
|
|
398
286
|
|
|
399
287
|
${opts.prompt}`;
|
|
400
288
|
}
|
|
401
|
-
function
|
|
289
|
+
function buildAgentFallback(opts, metadata4) {
|
|
402
290
|
if (metadata4.capabilities.supportsProgrammaticSubagents) return "";
|
|
403
|
-
const
|
|
404
|
-
if (
|
|
405
|
-
return "\n\nNon-Claude provider note: this runtime does not receive Claude's nested Agent tool contract.
|
|
291
|
+
const agents = Object.entries(opts.agents ?? {});
|
|
292
|
+
if (agents.length === 0) return "";
|
|
293
|
+
return "\n\nNon-Claude provider note: this runtime does not receive Claude's nested Agent tool contract. If the operation prompt asks you to invoke a helper agent, perform that helper work inline before final edits. Treat these helper prompts as read-only guidance:\n\n" + agents.map(([name, agent]) => `## ${name}
|
|
294
|
+
|
|
295
|
+
${agent.prompt}`).join("\n\n");
|
|
406
296
|
}
|
|
407
297
|
|
|
408
298
|
// src/agent/providers/codex-cli.ts
|
|
@@ -588,9 +478,6 @@ function parseCursorFinal(msg) {
|
|
|
588
478
|
}
|
|
589
479
|
|
|
590
480
|
// src/agent/providers/status.ts
|
|
591
|
-
async function assertAgentAuth(args) {
|
|
592
|
-
await getAgentProvider(args.provider).assertReady(args.spawnCli);
|
|
593
|
-
}
|
|
594
481
|
async function listProviderStatuses(spawnCli) {
|
|
595
482
|
const out = [];
|
|
596
483
|
for (const id of AGENT_PROVIDER_IDS) {
|
|
@@ -753,14 +640,8 @@ function missingStatus(id) {
|
|
|
753
640
|
}
|
|
754
641
|
|
|
755
642
|
export {
|
|
756
|
-
checkClaudeAuth,
|
|
757
|
-
DEFAULT_AGENT_MODEL,
|
|
758
|
-
assertAgentAuth,
|
|
759
|
-
getAgentProvider,
|
|
760
|
-
getProviderLabel,
|
|
761
|
-
getProviderDefaultModel,
|
|
762
643
|
buildProviderSetupView,
|
|
763
644
|
buildProviderModelChoices,
|
|
764
645
|
parseAgentSelection
|
|
765
646
|
};
|
|
766
|
-
//# sourceMappingURL=chunk-
|
|
647
|
+
//# sourceMappingURL=chunk-RALBM6HZ.js.map
|