akm-cli 0.8.6 → 0.8.14

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 (324) hide show
  1. package/CHANGELOG.md +442 -0
  2. package/dist/assets/help/help-proposals.md +1 -2
  3. package/dist/assets/hints/cli-hints-full.md +34 -19
  4. package/dist/assets/hints/cli-hints-short.md +1 -1
  5. package/dist/assets/profiles/catchup.json +13 -0
  6. package/dist/assets/profiles/consolidate.json +13 -0
  7. package/dist/assets/profiles/frequent.json +13 -0
  8. package/dist/assets/tasks/core/backup.yml +4 -0
  9. package/dist/assets/tasks/core/extract.yml +4 -0
  10. package/dist/assets/tasks/core/improve.yml +4 -0
  11. package/dist/assets/tasks/core/index-refresh.yml +4 -0
  12. package/dist/assets/tasks/core/sync.yml +4 -0
  13. package/dist/assets/tasks/core/update-stashes.yml +4 -0
  14. package/dist/assets/tasks/core/version-check.yml +4 -0
  15. package/dist/assets/templates/html/default.html +78 -0
  16. package/dist/assets/templates/html/health.html +560 -0
  17. package/dist/assets/templates/html/vendor/echarts.min.js +45 -0
  18. package/dist/cli/config-migrate.js +6 -6
  19. package/dist/cli/config-validate.js +4 -4
  20. package/dist/cli/confirm.js +3 -3
  21. package/dist/cli/parse-args.js +1 -1
  22. package/dist/cli/shared.js +72 -19
  23. package/dist/cli-node.mjs +26 -0
  24. package/dist/cli.js +206 -3866
  25. package/dist/commands/{agent-dispatch.js → agent/agent-dispatch.js} +6 -6
  26. package/dist/commands/{agent-support.js → agent/agent-support.js} +2 -2
  27. package/dist/commands/agent/contribute-cli.js +200 -0
  28. package/dist/commands/completions.js +1 -1
  29. package/dist/commands/config-cli.js +230 -3
  30. package/dist/commands/db-cli.js +2 -2
  31. package/dist/commands/env/env-cli.js +529 -0
  32. package/dist/commands/env/env.js +410 -0
  33. package/dist/commands/env/secret-cli.js +259 -0
  34. package/dist/commands/{secret.js → env/secret.js} +6 -47
  35. package/dist/commands/events.js +4 -4
  36. package/dist/commands/feedback-cli.js +18 -34
  37. package/dist/commands/graph/graph-cli.js +132 -0
  38. package/dist/commands/{graph.js → graph/graph.js} +22 -16
  39. package/dist/commands/health/checks.js +279 -0
  40. package/dist/commands/health/html-report.js +448 -0
  41. package/dist/commands/health.js +189 -266
  42. package/dist/commands/{consolidate.js → improve/consolidate.js} +63 -38
  43. package/dist/commands/{distill-promotion-policy.js → improve/distill-promotion-policy.js} +3 -3
  44. package/dist/commands/{distill.js → improve/distill.js} +39 -18
  45. package/dist/commands/{eval-cases.js → improve/eval-cases.js} +1 -1
  46. package/dist/commands/{extract-cli.js → improve/extract-cli.js} +4 -4
  47. package/dist/commands/{extract-prompt.js → improve/extract-prompt.js} +2 -2
  48. package/dist/commands/{extract.js → improve/extract.js} +221 -26
  49. package/dist/commands/{improve-auto-accept.js → improve/improve-auto-accept.js} +30 -4
  50. package/dist/commands/{improve-cli.js → improve/improve-cli.js} +44 -22
  51. package/dist/commands/{improve-profiles.js → improve/improve-profiles.js} +13 -7
  52. package/dist/commands/{improve-result-file.js → improve/improve-result-file.js} +1 -1
  53. package/dist/commands/{improve.js → improve/improve.js} +672 -292
  54. package/dist/{core → commands/improve/memory}/memory-belief.js +2 -2
  55. package/dist/{core → commands/improve/memory}/memory-contradiction-detect.js +5 -5
  56. package/dist/{core → commands/improve/memory}/memory-improve.js +4 -4
  57. package/dist/commands/improve/reflect-noise.js +0 -0
  58. package/dist/commands/{reflect.js → improve/reflect.js} +58 -28
  59. package/dist/commands/improve/session-asset.js +248 -0
  60. package/dist/commands/lint/agent-linter.js +1 -1
  61. package/dist/commands/lint/base-linter.js +55 -37
  62. package/dist/commands/lint/command-linter.js +1 -1
  63. package/dist/commands/lint/default-linter.js +1 -1
  64. package/dist/commands/lint/env-key-rules.js +1 -1
  65. package/dist/commands/lint/index.js +19 -25
  66. package/dist/commands/lint/knowledge-linter.js +1 -1
  67. package/dist/commands/lint/memory-linter.js +1 -1
  68. package/dist/commands/lint/registry.js +8 -8
  69. package/dist/commands/lint/skill-linter.js +1 -1
  70. package/dist/commands/lint/task-linter.js +1 -1
  71. package/dist/commands/lint/workflow-linter.js +1 -1
  72. package/dist/commands/lint.js +1 -1
  73. package/dist/commands/observability-cli.js +244 -0
  74. package/dist/commands/proposal/drain-policies.js +3 -3
  75. package/dist/commands/proposal/drain.js +87 -15
  76. package/dist/commands/proposal/proposal-cli.js +490 -0
  77. package/dist/commands/{proposal.js → proposal/proposal.js} +17 -6
  78. package/dist/commands/{propose.js → proposal/propose.js} +11 -11
  79. package/dist/{core → commands/proposal/validators}/proposal-quality-validators.js +8 -3
  80. package/dist/{core → commands/proposal/validators}/proposal-validators.js +5 -5
  81. package/dist/{core → commands/proposal/validators}/proposals.js +374 -345
  82. package/dist/commands/{curate.js → read/curate.js} +7 -7
  83. package/dist/commands/{knowledge.js → read/knowledge.js} +22 -9
  84. package/dist/commands/{registry-search.js → read/registry-search.js} +5 -5
  85. package/dist/commands/{remember-cli.js → read/remember-cli.js} +15 -7
  86. package/dist/commands/read/search-cli.js +207 -0
  87. package/dist/commands/{search.js → read/search.js} +22 -27
  88. package/dist/commands/{show.js → read/show.js} +31 -45
  89. package/dist/commands/registry-cli.js +8 -8
  90. package/dist/commands/remember.js +14 -10
  91. package/dist/commands/sources/add-cli.js +293 -0
  92. package/dist/commands/{history.js → sources/history.js} +27 -25
  93. package/dist/commands/{info.js → sources/info.js} +6 -6
  94. package/dist/commands/{init.js → sources/init.js} +6 -6
  95. package/dist/commands/{installed-stashes.js → sources/installed-stashes.js} +12 -12
  96. package/dist/commands/{migration-help.js → sources/migration-help.js} +3 -2
  97. package/dist/commands/{schema-repair.js → sources/schema-repair.js} +8 -8
  98. package/dist/commands/{self-update.js → sources/self-update.js} +10 -9
  99. package/dist/commands/{source-add.js → sources/source-add.js} +10 -10
  100. package/dist/commands/{source-clone.js → sources/source-clone.js} +7 -7
  101. package/dist/commands/{source-manage.js → sources/source-manage.js} +4 -4
  102. package/dist/commands/sources/sources-cli.js +305 -0
  103. package/dist/commands/sources/stash-cli.js +219 -0
  104. package/dist/commands/{stash-skeleton.js → sources/stash-skeleton.js} +2 -1
  105. package/dist/commands/tasks/default-tasks.js +173 -0
  106. package/dist/commands/tasks/tasks-cli.js +210 -0
  107. package/dist/commands/{tasks.js → tasks/tasks.js} +14 -14
  108. package/dist/commands/wiki-cli.js +307 -0
  109. package/dist/commands/workflow-cli.js +329 -0
  110. package/dist/core/action-contributors.js +1 -1
  111. package/dist/core/assert.js +40 -0
  112. package/dist/core/asset/asset-create.js +54 -0
  113. package/dist/core/{asset-ref.js → asset/asset-ref.js} +21 -4
  114. package/dist/core/{asset-registry.js → asset/asset-registry.js} +3 -3
  115. package/dist/core/{asset-spec.js → asset/asset-spec.js} +17 -31
  116. package/dist/core/{markdown.js → asset/markdown.js} +1 -1
  117. package/dist/core/{stash-meta.js → asset/stash-meta.js} +1 -1
  118. package/dist/core/best-effort.js +64 -0
  119. package/dist/core/common.js +32 -18
  120. package/dist/core/{config-io.js → config/config-io.js} +29 -19
  121. package/dist/core/{config-migration.js → config/config-migration.js} +11 -9
  122. package/dist/core/{config-schema.js → config/config-schema.js} +50 -7
  123. package/dist/core/config/config-types.js +16 -0
  124. package/dist/core/{config-walker.js → config/config-walker.js} +2 -2
  125. package/dist/core/{config.js → config/config.js} +10 -8
  126. package/dist/core/env-secret-ref.js +90 -0
  127. package/dist/core/errors.js +13 -3
  128. package/dist/core/events.js +27 -4
  129. package/dist/core/file-lock.js +1 -1
  130. package/dist/core/improve-types.js +48 -0
  131. package/dist/core/lesson-lint.js +2 -2
  132. package/dist/core/logs-db.js +304 -0
  133. package/dist/core/paths.js +2 -2
  134. package/dist/core/ripgrep/install.js +2 -2
  135. package/dist/core/ripgrep/resolve.js +2 -2
  136. package/dist/core/state-db.js +195 -60
  137. package/dist/core/text-truncation.js +148 -0
  138. package/dist/core/time.js +1 -1
  139. package/dist/core/write-source.js +98 -85
  140. package/dist/indexer/{db-backup.js → db/db-backup.js} +9 -24
  141. package/dist/indexer/{db.js → db/db.js} +128 -118
  142. package/dist/indexer/{graph-db.js → db/graph-db.js} +9 -4
  143. package/dist/indexer/{llm-cache.js → db/llm-cache.js} +15 -12
  144. package/dist/indexer/ensure-index.js +4 -4
  145. package/dist/indexer/{graph-boost.js → graph/graph-boost.js} +1 -1
  146. package/dist/indexer/{graph-extraction.js → graph/graph-extraction.js} +55 -13
  147. package/dist/indexer/indexer.js +37 -30
  148. package/dist/indexer/init.js +54 -0
  149. package/dist/indexer/manifest.js +10 -10
  150. package/dist/indexer/{memory-inference.js → passes/memory-inference.js} +141 -33
  151. package/dist/indexer/{metadata-contributors.js → passes/metadata-contributors.js} +10 -8
  152. package/dist/indexer/{metadata.js → passes/metadata.js} +15 -19
  153. package/dist/indexer/{staleness-detect.js → passes/staleness-detect.js} +53 -12
  154. package/dist/indexer/{db-search.js → search/db-search.js} +28 -16
  155. package/dist/indexer/{ranking-contributors.js → search/ranking-contributors.js} +1 -1
  156. package/dist/indexer/{ranking.js → search/ranking.js} +2 -2
  157. package/dist/indexer/{search-hit-enrichers.js → search/search-hit-enrichers.js} +3 -3
  158. package/dist/indexer/{search-source.js → search/search-source.js} +8 -8
  159. package/dist/indexer/{semantic-status.js → search/semantic-status.js} +3 -3
  160. package/dist/indexer/usage/unmigrated-vaults-guard.js +94 -0
  161. package/dist/indexer/{usage-events.js → usage/usage-events.js} +32 -0
  162. package/dist/indexer/{file-context.js → walk/file-context.js} +10 -15
  163. package/dist/indexer/{matchers.js → walk/matchers.js} +13 -9
  164. package/dist/indexer/{path-resolver.js → walk/path-resolver.js} +6 -6
  165. package/dist/indexer/{project-context.js → walk/project-context.js} +1 -1
  166. package/dist/indexer/{walker.js → walk/walker.js} +4 -3
  167. package/dist/integrations/agent/builder-shared.js +39 -0
  168. package/dist/integrations/agent/builders.js +14 -81
  169. package/dist/integrations/agent/config.js +6 -4
  170. package/dist/integrations/agent/detect.js +1 -1
  171. package/dist/integrations/agent/index.js +23 -8
  172. package/dist/integrations/agent/prompts.js +2 -3
  173. package/dist/integrations/agent/runner.js +22 -3
  174. package/dist/integrations/agent/spawn.js +9 -10
  175. package/dist/integrations/harnesses/claude/agent-builder.js +48 -0
  176. package/dist/integrations/harnesses/claude/config-import.js +70 -0
  177. package/dist/integrations/harnesses/claude/index.js +64 -0
  178. package/dist/integrations/{session-logs/providers/claude-code.js → harnesses/claude/session-log.js} +32 -5
  179. package/dist/integrations/harnesses/index.js +144 -0
  180. package/dist/integrations/harnesses/opencode/agent-builder.js +43 -0
  181. package/dist/integrations/harnesses/opencode/config-import.js +82 -0
  182. package/dist/integrations/harnesses/opencode/index.js +59 -0
  183. package/dist/integrations/{session-logs/providers/opencode.js → harnesses/opencode/session-log.js} +1 -1
  184. package/dist/integrations/harnesses/opencode-sdk/index.js +49 -0
  185. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +234 -0
  186. package/dist/integrations/harnesses/types.js +43 -0
  187. package/dist/integrations/lockfile.js +7 -16
  188. package/dist/integrations/session-logs/index.js +82 -9
  189. package/dist/llm/call-ai.js +4 -4
  190. package/dist/llm/client.js +146 -6
  191. package/dist/llm/embedder.js +6 -6
  192. package/dist/llm/embedders/local.js +9 -22
  193. package/dist/llm/embedders/remote.js +2 -2
  194. package/dist/llm/embedders/types.js +1 -1
  195. package/dist/llm/graph-extract.js +31 -12
  196. package/dist/llm/index-passes.js +1 -1
  197. package/dist/llm/memory-infer.js +12 -5
  198. package/dist/llm/metadata-enhance.js +2 -2
  199. package/dist/llm/usage-persist.js +77 -0
  200. package/dist/llm/usage-telemetry.js +103 -0
  201. package/dist/output/context.js +9 -46
  202. package/dist/output/html-render.js +73 -0
  203. package/dist/output/renderers.js +88 -58
  204. package/dist/output/shapes/curate.js +7 -3
  205. package/dist/output/shapes/distill.js +7 -3
  206. package/dist/output/shapes/env-list.js +18 -16
  207. package/dist/output/shapes/events.js +5 -4
  208. package/dist/output/shapes/helpers.js +19 -5
  209. package/dist/output/shapes/history.js +7 -3
  210. package/dist/output/shapes/passthrough.js +8 -11
  211. package/dist/output/shapes/{proposal-accept.js → proposal/accept.js} +7 -3
  212. package/dist/output/shapes/{proposal-diff.js → proposal/diff.js} +7 -3
  213. package/dist/output/shapes/{proposal-list.js → proposal/list.js} +7 -3
  214. package/dist/output/shapes/{proposal-producer.js → proposal/producer.js} +5 -4
  215. package/dist/output/shapes/{proposal-reject.js → proposal/reject.js} +7 -3
  216. package/dist/output/shapes/{proposal-show.js → proposal/show.js} +7 -3
  217. package/dist/output/shapes/registry-search.js +7 -3
  218. package/dist/output/shapes/registry.js +12 -0
  219. package/dist/output/shapes/search.js +7 -3
  220. package/dist/output/shapes/secret-list.js +18 -16
  221. package/dist/output/shapes/show.js +7 -3
  222. package/dist/output/shapes.js +55 -30
  223. package/dist/output/text/add.js +2 -3
  224. package/dist/output/text/clone.js +2 -3
  225. package/dist/output/text/config.js +2 -3
  226. package/dist/output/text/curate.js +4 -3
  227. package/dist/output/text/distill.js +2 -3
  228. package/dist/output/text/enable-disable.js +5 -4
  229. package/dist/output/text/env.js +13 -0
  230. package/dist/output/text/events.js +5 -4
  231. package/dist/output/text/feedback.js +4 -3
  232. package/dist/output/text/helpers.js +123 -40
  233. package/dist/output/text/history.js +2 -3
  234. package/dist/output/text/import.js +2 -3
  235. package/dist/output/text/index.js +2 -3
  236. package/dist/output/text/info.js +2 -3
  237. package/dist/output/text/init.js +2 -3
  238. package/dist/output/text/list.js +2 -3
  239. package/dist/output/text/proposal/producer.js +9 -0
  240. package/dist/output/text/proposal/proposal.js +13 -0
  241. package/dist/output/text/registry-commands.js +8 -7
  242. package/dist/output/text/registry.js +12 -0
  243. package/dist/output/text/remember.js +4 -3
  244. package/dist/output/text/remove.js +2 -3
  245. package/dist/output/text/save.js +2 -3
  246. package/dist/output/text/search.js +4 -3
  247. package/dist/output/text/show.js +4 -3
  248. package/dist/output/text/update.js +2 -3
  249. package/dist/output/text/upgrade.js +2 -3
  250. package/dist/output/text/wiki.js +12 -11
  251. package/dist/output/text/workflow.js +12 -10
  252. package/dist/output/text.js +66 -32
  253. package/dist/registry/build-index.js +11 -10
  254. package/dist/registry/factory.js +1 -1
  255. package/dist/registry/origin-resolve.js +1 -1
  256. package/dist/registry/providers/index.js +2 -2
  257. package/dist/registry/providers/skills-sh.js +91 -72
  258. package/dist/registry/providers/static-index.js +75 -52
  259. package/dist/registry/resolve.js +3 -3
  260. package/dist/runtime.js +242 -0
  261. package/dist/scripts/migrate-storage.js +1654 -683
  262. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +254 -168
  263. package/dist/setup/detect.js +311 -9
  264. package/dist/setup/harness-config-import.js +6 -120
  265. package/dist/setup/setup.js +454 -43
  266. package/dist/sources/include.js +1 -1
  267. package/dist/sources/provider-factory.js +2 -2
  268. package/dist/sources/providers/filesystem.js +3 -3
  269. package/dist/sources/providers/git.js +9 -9
  270. package/dist/sources/providers/index.js +4 -4
  271. package/dist/sources/providers/npm.js +6 -6
  272. package/dist/sources/providers/provider-utils.js +13 -20
  273. package/dist/sources/providers/sync-from-ref.js +5 -5
  274. package/dist/sources/providers/tar-utils.js +2 -2
  275. package/dist/sources/providers/website.js +2 -2
  276. package/dist/sources/resolve.js +5 -5
  277. package/dist/sources/website-ingest.js +5 -5
  278. package/dist/storage/database.js +102 -0
  279. package/dist/storage/engines/sqlite-migrations.js +42 -0
  280. package/dist/storage/locations.js +25 -0
  281. package/dist/storage/repositories/index-db.js +43 -0
  282. package/dist/storage/repositories/workflow-runs-repository.js +141 -0
  283. package/dist/tasks/backends/cron.js +4 -4
  284. package/dist/tasks/backends/exec-utils.js +32 -0
  285. package/dist/tasks/backends/index.js +3 -3
  286. package/dist/tasks/backends/launchd.js +7 -14
  287. package/dist/tasks/backends/schtasks.js +7 -16
  288. package/dist/tasks/embedded.js +71 -0
  289. package/dist/tasks/parser.js +2 -2
  290. package/dist/tasks/resolveAkmBin.js +1 -1
  291. package/dist/tasks/runner.js +127 -31
  292. package/dist/tasks/schedule.js +1 -1
  293. package/dist/tasks/validator.js +7 -7
  294. package/dist/text-import-hook.mjs +51 -0
  295. package/dist/version.js +2 -1
  296. package/dist/wiki/wiki.js +7 -7
  297. package/dist/workflows/{authoring.js → authoring/authoring.js} +6 -6
  298. package/dist/workflows/{scope-key.js → authoring/scope-key.js} +1 -1
  299. package/dist/workflows/cli.js +1 -1
  300. package/dist/workflows/db.js +54 -32
  301. package/dist/workflows/parser.js +4 -4
  302. package/dist/workflows/renderer.js +5 -5
  303. package/dist/workflows/runtime/agent-identity.js +56 -0
  304. package/dist/workflows/runtime/checkin.js +57 -0
  305. package/dist/workflows/{runs.js → runtime/runs.js} +197 -101
  306. package/dist/workflows/validate-summary.js +82 -0
  307. package/docs/README.md +1 -1
  308. package/docs/data-and-telemetry.md +6 -6
  309. package/package.json +17 -8
  310. package/dist/commands/add-cli.js +0 -279
  311. package/dist/commands/env.js +0 -213
  312. package/dist/integrations/agent/sdk-runner.js +0 -126
  313. package/dist/output/shapes/vault-list.js +0 -19
  314. package/dist/output/text/proposal-producer.js +0 -8
  315. package/dist/output/text/proposal.js +0 -12
  316. package/dist/output/text/vault.js +0 -16
  317. /package/dist/core/{asset-serialize.js → asset/asset-serialize.js} +0 -0
  318. /package/dist/core/{frontmatter.js → asset/frontmatter.js} +0 -0
  319. /package/dist/core/{config-sources.js → config/config-sources.js} +0 -0
  320. /package/dist/indexer/{graph-dedup.js → graph/graph-dedup.js} +0 -0
  321. /package/dist/{core/config-types.js → indexer/passes/pass-context.js} +0 -0
  322. /package/dist/indexer/{search-fields.js → search/search-fields.js} +0 -0
  323. /package/dist/indexer/{index-context.js → walk/index-context.js} +0 -0
  324. /package/dist/workflows/{document-cache.js → runtime/document-cache.js} +0 -0
@@ -12,88 +12,21 @@
12
12
  * Adding a new platform: implement `AgentCommandBuilder`, add to
13
13
  * `BUILTIN_BUILDERS`. Nothing else changes.
14
14
  */
15
- import { UsageError } from "../../core/errors";
16
- import { resolveModel } from "./model-aliases";
17
- // ── Validation helpers ────────────────────────────────────────────────────────
18
- /**
19
- * Guard against values that start with `--`, which would be mis-interpreted as
20
- * CLI flags by the spawned process when used as flag values (model, systemPrompt).
21
- * Bun.spawn uses array argv so there is no shell injection, but a `--`-prefixed
22
- * value passed as the argument to `--model` or `--system-prompt` can still
23
- * confuse the CLI parser of the target process.
24
- */
25
- function assertNotFlag(value, field) {
26
- if (value?.trimStart().startsWith("--")) {
27
- throw new UsageError(`${field} must not start with "--": ${JSON.stringify(value.slice(0, 60))}`, "INVALID_FLAG_VALUE");
28
- }
29
- }
30
- // ── Tool normalization ────────────────────────────────────────────────────────
31
- /**
32
- * Normalize a toolPolicy value to a comma-separated string suitable for a
33
- * CLI flag. Structured policy objects are JSON-serialized.
34
- */
35
- function normalizeTools(tools) {
36
- if (typeof tools === "string")
37
- return tools;
38
- if (Array.isArray(tools))
39
- return tools.join(",");
40
- return JSON.stringify(tools);
41
- }
15
+ import { claudeBuilder } from "../harnesses/claude/agent-builder.js";
16
+ import { opencodeBuilder } from "../harnesses/opencode/agent-builder.js";
17
+ // Types + shared validation helpers live in the leaf module `builder-shared.ts`
18
+ // so per-harness builders (harnesses/claude/agent-builder.ts) can depend on them
19
+ // without importing this file back avoiding an init-order cycle through
20
+ // BUILTIN_BUILDERS (#563). Re-exported here so existing `agent/builders` import
21
+ // sites keep working.
22
+ import { assertNotFlag } from "./builder-shared.js";
23
+ import { resolveModel } from "./model-aliases.js";
24
+ export { assertNotFlag, normalizeTools } from "./builder-shared.js";
42
25
  // ── Platform builders ─────────────────────────────────────────────────────────
43
- /**
44
- * OpenCode builder.
45
- * Command shape: opencode run [--system-prompt "..."] [--model <m>] "<prompt>"
46
- *
47
- * Tool policy is omitted — opencode manages tool access through its own agent
48
- * config files, not via CLI flags.
49
- */
50
- const opencodeBuilder = {
51
- platform: "opencode",
52
- build(profile, req) {
53
- assertNotFlag(req.systemPrompt, "systemPrompt");
54
- assertNotFlag(req.model, "model");
55
- const args = [...profile.args]; // starts with ["run"]
56
- if (req.systemPrompt) {
57
- args.push("--system-prompt", req.systemPrompt);
58
- }
59
- if (req.model) {
60
- const resolved = resolveModel(req.model, "opencode", profile.modelAliases);
61
- args.push("--model", resolved);
62
- }
63
- args.push("--");
64
- args.push(req.prompt);
65
- return { argv: [profile.bin, ...args] };
66
- },
67
- };
68
- /**
69
- * Claude Code builder.
70
- * Command shape: claude [--system-prompt "..."] [--model <m>] [--allowedTools <t>] --print "<prompt>"
71
- *
72
- * --print switches Claude Code to non-interactive captured output mode.
73
- */
74
- const claudeBuilder = {
75
- platform: "claude",
76
- build(profile, req) {
77
- assertNotFlag(req.systemPrompt, "systemPrompt");
78
- assertNotFlag(req.model, "model");
79
- const args = [...profile.args];
80
- if (req.systemPrompt) {
81
- args.push("--system-prompt", req.systemPrompt);
82
- }
83
- if (req.model) {
84
- const resolved = resolveModel(req.model, "claude", profile.modelAliases);
85
- args.push("--model", resolved);
86
- }
87
- if (req.tools) {
88
- args.push("--allowedTools", normalizeTools(req.tools));
89
- }
90
- // --print = non-interactive, outputs to stdout — required for captured mode
91
- args.push("--print");
92
- args.push("--");
93
- args.push(req.prompt);
94
- return { argv: [profile.bin, ...args] };
95
- },
96
- };
26
+ // The OpenCode builder was migrated to its harness directory in #564
27
+ // (`harnesses/opencode/agent-builder.ts`) and the Claude Code builder in #563
28
+ // (`harnesses/claude/agent-builder.ts`). Both are imported back into
29
+ // BUILTIN_BUILDERS below so platform routing is unchanged.
97
30
  /**
98
31
  * Default builder — used for custom profiles and any platform without a
99
32
  * dedicated builder. Passes systemPrompt and model via the same flags as
@@ -1,9 +1,10 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { ConfigError } from "../../core/errors";
5
- import { warn } from "../../core/warn";
6
- import { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles";
4
+ import { VALID_HARNESS_IDS } from "../../core/config/config.js";
5
+ import { ConfigError } from "../../core/errors.js";
6
+ import { warn } from "../../core/warn.js";
7
+ import { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles.js";
7
8
  /**
8
9
  * Default hard timeout for an agent CLI (60s — matches the value used in
9
10
  * `docs/configuration.md`).
@@ -141,7 +142,8 @@ export function parseAgentProfilesMapV2(value) {
141
142
  if (typeof value !== "object" || value === null || Array.isArray(value))
142
143
  return undefined;
143
144
  const out = {};
144
- const VALID_PLATFORMS = ["opencode", "claude", "opencode-sdk"];
145
+ // Derives from the canonical harness-id source of truth (#565).
146
+ const VALID_PLATFORMS = VALID_HARNESS_IDS;
145
147
  for (const [name, raw] of Object.entries(value)) {
146
148
  if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
147
149
  warn(`[akm] Ignoring profiles.agent["${name}"]: expected an object.`);
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import fs from "node:fs";
17
17
  import path from "node:path";
18
- import { listResolvedAgentProfiles } from "./config";
18
+ import { listResolvedAgentProfiles } from "./config.js";
19
19
  /**
20
20
  * Default PATH lookup. Walks `process.env.PATH` and returns the first
21
21
  * existing executable file. Returns `undefined` when the bin is not on
@@ -1,11 +1,26 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- export { getCommandBuilder } from "./builders";
5
- export { DEFAULT_AGENT_TIMEOUT_MS, listAgentProfileNames, listResolvedAgentProfiles, parseAgentConfig, requireAgentProfile, resolveAgentProfile, resolveDefaultProfileName, resolveProfileFromConfig, } from "./config";
6
- export { defaultWhich, detectAgentCliProfiles, pickDefaultAgentProfile } from "./detect";
7
- export { listBuiltinModelAliases, resolveModel } from "./model-aliases";
8
- export { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles";
9
- export { buildProposePrompt, buildReflectPrompt, buildSchemaRepairPrompt, extractDraftConfidence, parseAgentProposalPayload, stripJsonFences, } from "./prompts";
10
- export { runAgentSdk } from "./sdk-runner";
11
- export { runAgent } from "./spawn";
4
+ /**
5
+ * Internal entry point for the `agent` integration. CLI-only project no
6
+ * public exports map. Other akm modules import from this barrel for the
7
+ * sake of grouping imports.
8
+ *
9
+ * Surface:
10
+ * • Types: AgentProfile, AgentConfig, AgentRunResult, AgentFailureReason.
11
+ * • Profiles: getBuiltinAgentProfile, listBuiltinAgentProfiles, BUILTIN_AGENT_PROFILE_NAMES.
12
+ * • Config: parseAgentConfig, resolveProfileFromConfig, requireAgentProfile, listResolvedAgentProfiles, listAgentProfileNames.
13
+ * • Spawn: runAgent. Builders: getCommandBuilder, AgentCommandBuilder, AgentDispatchRequest — platform-specific argv construction.
14
+ * • Detection: detectAgentCliProfiles, pickDefaultAgentProfile, defaultWhich.
15
+ */
16
+ // The OpenCode SDK runner moved to its harness directory in #564
17
+ // (`harnesses/opencode-sdk/`). Re-exported here so existing `agent/index`
18
+ // import sites keep working.
19
+ export { runAgentSdk } from "../harnesses/opencode-sdk/index.js";
20
+ export { getCommandBuilder } from "./builders.js";
21
+ export { DEFAULT_AGENT_TIMEOUT_MS, listAgentProfileNames, listResolvedAgentProfiles, parseAgentConfig, requireAgentProfile, resolveAgentProfile, resolveDefaultProfileName, resolveProfileFromConfig, } from "./config.js";
22
+ export { defaultWhich, detectAgentCliProfiles, pickDefaultAgentProfile } from "./detect.js";
23
+ export { listBuiltinModelAliases, resolveModel } from "./model-aliases.js";
24
+ export { BUILTIN_AGENT_PROFILE_NAMES, getBuiltinAgentProfile, listBuiltinAgentProfiles, } from "./profiles.js";
25
+ export { buildProposePrompt, buildReflectPrompt, buildSchemaRepairPrompt, extractDraftConfidence, parseAgentProposalPayload, stripJsonFences, } from "./prompts.js";
26
+ export { runAgent } from "./spawn.js";
@@ -25,8 +25,8 @@
25
25
  * `frontmatter` is optional — the proposal queue parses it from `content`
26
26
  * during validation. We carry it through if the agent supplies it.
27
27
  */
28
- import { TYPE_DIRS } from "../../core/asset-spec";
29
- import { parseEmbeddedJsonResponse, stripCodeFences, stripThinkBlocks } from "../../core/parse";
28
+ import { TYPE_DIRS } from "../../core/asset/asset-spec.js";
29
+ import { parseEmbeddedJsonResponse, stripCodeFences, stripThinkBlocks } from "../../core/parse.js";
30
30
  /**
31
31
  * Per-asset-type frontmatter / authoring hints surfaced in the prompt so
32
32
  * the agent can produce content that passes proposal validation. Kept tiny:
@@ -42,7 +42,6 @@ const TYPE_HINTS = {
42
42
  workflow: "workflow assets are markdown describing a multi-step process. Include `# <Title>` and ordered `## Step N` sections.",
43
43
  script: "script assets are executable text files. Include a shebang and minimal usage comment.",
44
44
  env: "env assets are `.env` files holding a group of related CONFIGURATION for an app/service (KEY=VALUE pairs, `#` comments) — URLs, flags, and any credentials it needs. Values may or may not be sensitive; all are protected (key names discoverable, values stay on disk). Inject with `akm env run env:<name> -- <cmd>` (the safe path — values never reach stdout/your context); do NOT run `akm env export` and read its output, as that prints values. For a single sensitive value used on its own for authentication (token, key, cert) use a `secret` instead. Never echo values back to the user.",
45
- vault: "vault assets are DEPRECATED (use env). They store environment variables (KEY=VALUE pairs); comments use `#`. Never echo secret values back to the user.",
46
45
  wiki: "wiki assets are markdown reference pages with `# Title` and structured headings.",
47
46
  };
48
47
  function hintForType(type) {
@@ -1,8 +1,27 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { ConfigError } from "../../core/errors";
5
- import { warn } from "../../core/warn";
4
+ import { ConfigError } from "../../core/errors.js";
5
+ import { warn } from "../../core/warn.js";
6
+ // ── RunnerSpec capability predicates (H1) ───────────────────────────────────
7
+ // The `RunnerSpec` union is dispatched ad-hoc across the improve slice. These
8
+ // predicates co-locate the capability questions with the union definition so
9
+ // callers stop hand-inlining `kind !== "llm"` (which couples the call site to
10
+ // the exact shape of the union). They are typed as TypeScript type guards so
11
+ // narrowing flows through to the `connection` / `profile` accessors.
12
+ /** The in-tree LLM HTTP runner (`chatCompletion`); has no filesystem access. */
13
+ export function runnerIsLlm(runner) {
14
+ return runner.kind === "llm";
15
+ }
16
+ /**
17
+ * Whether this runner can honour the file-write contract. Agent CLI + OpenCode
18
+ * SDK runners both have filesystem access; the direct LLM HTTP runner does NOT
19
+ * (see `src/llm/call-ai.ts`). Equivalent to `!runnerIsLlm(runner)` but names
20
+ * the capability the callers actually care about.
21
+ */
22
+ export function runnerSupportsFileWrite(runner) {
23
+ return runner.kind !== "llm";
24
+ }
6
25
  function resolveEffectiveMode(entry, profileName, config) {
7
26
  if (entry.mode)
8
27
  return entry.mode;
@@ -205,4 +224,4 @@ export function getStalenessDetectionThresholdDays(config) {
205
224
  }
206
225
  // Re-export `isProcessEnabled` from feature-gate.ts so callers that previously
207
226
  // imported it from runner.ts continue to work.
208
- export { isProcessEnabled } from "../../llm/feature-gate";
227
+ export { isProcessEnabled } from "../../llm/feature-gate.js";
@@ -17,8 +17,9 @@
17
17
  import fs from "node:fs";
18
18
  import os from "node:os";
19
19
  import path from "node:path";
20
- import { getCommandBuilder } from "./builders";
21
- import { DEFAULT_AGENT_TIMEOUT_MS } from "./config";
20
+ import { spawn as runtimeSpawn } from "../../runtime.js";
21
+ import { getCommandBuilder } from "./builders.js";
22
+ import { DEFAULT_AGENT_TIMEOUT_MS } from "./config.js";
22
23
  /**
23
24
  * Kill the process group of `proc` with `signal`, falling back to
24
25
  * `proc.kill(signal)` when `proc.pid` is unavailable (e.g. test fakes).
@@ -103,12 +104,10 @@ function pathCandidatesForCurrentPlatform(home) {
103
104
  function resolveSpawnFn(options) {
104
105
  if (options.spawn)
105
106
  return options.spawn;
106
- // Pull from globalThis so tests that swap it out at module level are honoured.
107
- const bun = globalThis.Bun;
108
- if (!bun?.spawn) {
109
- throw new Error("Bun.spawn is unavailable; pass options.spawn for non-Bun environments.");
110
- }
111
- return bun.spawn.bind(bun);
107
+ // Default to the runtime-boundary spawn, which delegates to the native
108
+ // subprocess API on each runtime. Tests inject `options.spawn` to avoid
109
+ // poking real binaries.
110
+ return runtimeSpawn;
112
111
  }
113
112
  /**
114
113
  * Build the child env. Starts empty and copies through:
@@ -169,7 +168,7 @@ async function readStream(stream, opts) {
169
168
  *
170
169
  * Failure modes (see {@link AgentFailureReason}):
171
170
  *
172
- * • `spawn_failed` — `Bun.spawn` threw synchronously.
171
+ * • `spawn_failed` — the spawn call threw synchronously.
173
172
  * • `timeout` — exceeded the resolved timeout.
174
173
  * • `non_zero_exit` — child exited with a non-zero code.
175
174
  * • `parse_error` — `parseOutput === "json"` and stdout was not JSON.
@@ -233,7 +232,7 @@ export async function runAgent(profile, prompt, options = {}) {
233
232
  };
234
233
  }
235
234
  // Hard timeout. We prefer SIGTERM, then SIGKILL if SIGTERM is ignored,
236
- // but Bun.spawn only exposes a single .kill() — one signal is enough
235
+ // but the subprocess only exposes a single .kill() — one signal is enough
237
236
  // for the structured-failure contract.
238
237
  //
239
238
  // BUG-M3: only flag `timedOut` when the child has not already exited. A
@@ -0,0 +1,48 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Claude Code agent command builder (migrated from `agent/builders.ts`, #563).
6
+ *
7
+ * Translates a platform-agnostic {@link AgentDispatchRequest} into the exact
8
+ * argv the `claude` CLI expects. This is the Claude-specific slice of the
9
+ * builder strategy; the shared infrastructure (`AgentCommandBuilder`,
10
+ * `getCommandBuilder`, the OpenCode/default builders, flag/tool helpers) stays
11
+ * in `agent/builders.ts`, which imports this builder back into
12
+ * `BUILTIN_BUILDERS`.
13
+ *
14
+ * Behaviour-preserving relocation: the produced argv is byte-identical to the
15
+ * pre-migration `claudeBuilder`. The builder's `platform` stays `'claude'` (the
16
+ * canonical harness id).
17
+ */
18
+ import { assertNotFlag, normalizeTools } from "../../agent/builder-shared.js";
19
+ import { resolveModel } from "../../agent/model-aliases.js";
20
+ /**
21
+ * Claude Code builder.
22
+ * Command shape: claude [--system-prompt "..."] [--model <m>] [--allowedTools <t>] --print "<prompt>"
23
+ *
24
+ * --print switches Claude Code to non-interactive captured output mode.
25
+ */
26
+ export const claudeBuilder = {
27
+ platform: "claude",
28
+ build(profile, req) {
29
+ assertNotFlag(req.systemPrompt, "systemPrompt");
30
+ assertNotFlag(req.model, "model");
31
+ const args = [...profile.args];
32
+ if (req.systemPrompt) {
33
+ args.push("--system-prompt", req.systemPrompt);
34
+ }
35
+ if (req.model) {
36
+ const resolved = resolveModel(req.model, "claude", profile.modelAliases);
37
+ args.push("--model", resolved);
38
+ }
39
+ if (req.tools) {
40
+ args.push("--allowedTools", normalizeTools(req.tools));
41
+ }
42
+ // --print = non-interactive, outputs to stdout — required for captured mode
43
+ args.push("--print");
44
+ args.push("--");
45
+ args.push(req.prompt);
46
+ return { argv: [profile.bin, ...args] };
47
+ },
48
+ };
@@ -0,0 +1,70 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Claude Code LLM-config importer (migrated from `setup/harness-config-import.ts`,
6
+ * #563).
7
+ *
8
+ * Detects a Claude Code installation (filesystem only, no network) and reads
9
+ * its config to extract LLM connection details. API key VALUES are never
10
+ * stored — only the env var name that holds them. The pluggable registry
11
+ * (`HARNESS_CONFIG_IMPORTERS`) and the OpenCode importer stay in
12
+ * `setup/harness-config-import.ts`, which imports this importer back.
13
+ *
14
+ * Behaviour-preserving relocation.
15
+ */
16
+ import fs from "node:fs";
17
+ import path from "node:path";
18
+ function homeDir() {
19
+ return process.env.HOME ?? process.env.USERPROFILE ?? "";
20
+ }
21
+ /**
22
+ * Imports LLM config from a Claude Code installation.
23
+ *
24
+ * Claude Code stores settings in `~/.claude/settings.json` or `~/.claude.json`.
25
+ * The model field may appear at the root or under `env.ANTHROPIC_MODEL`.
26
+ * The API key is always `ANTHROPIC_API_KEY`.
27
+ */
28
+ export const claudeCodeImporter = {
29
+ harnessName: "Claude Code",
30
+ detect() {
31
+ const home = homeDir();
32
+ // Claude Code is installed if the ~/.claude/ directory exists
33
+ return fs.existsSync(path.join(home, ".claude"));
34
+ },
35
+ importConfig() {
36
+ const home = homeDir();
37
+ // Try ~/.claude/settings.json, then ~/.claude.json
38
+ const candidates = [path.join(home, ".claude", "settings.json"), path.join(home, ".claude.json")];
39
+ for (const filePath of candidates) {
40
+ try {
41
+ if (!fs.existsSync(filePath))
42
+ continue;
43
+ const raw = JSON.parse(fs.readFileSync(filePath, "utf8"));
44
+ // Claude Code settings: model may be at root or nested under env
45
+ const envBlock = raw.env;
46
+ const model = typeof raw.model === "string"
47
+ ? raw.model
48
+ : typeof envBlock?.ANTHROPIC_MODEL === "string"
49
+ ? String(envBlock.ANTHROPIC_MODEL)
50
+ : undefined;
51
+ return {
52
+ harnessName: "Claude Code",
53
+ provider: "anthropic",
54
+ model: model ?? "claude-sonnet-4-5",
55
+ apiKeyEnvVar: "ANTHROPIC_API_KEY",
56
+ };
57
+ }
58
+ catch {
59
+ // try next candidate
60
+ }
61
+ }
62
+ // ~/.claude exists but no readable settings — still return basic Anthropic config
63
+ return {
64
+ harnessName: "Claude Code",
65
+ provider: "anthropic",
66
+ model: "claude-sonnet-4-5",
67
+ apiKeyEnvVar: "ANTHROPIC_API_KEY",
68
+ };
69
+ },
70
+ };
@@ -0,0 +1,64 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Claude Code harness (#563).
6
+ *
7
+ * This is the per-harness barrel that gathers the Claude Code integration
8
+ * surfaces that were previously scattered across the codebase:
9
+ * - session-log reader → ./session-log.ts (ClaudeCodeProvider)
10
+ * - agent command builder → ./agent-builder.ts (claudeBuilder)
11
+ * - config importer → ./config-import.ts (claudeCodeImporter)
12
+ *
13
+ * It also defines {@link ClaudeHarness}, the {@link AkmHarness} descriptor that
14
+ * `HARNESS_REGISTRY` registers.
15
+ *
16
+ * ## id normalization bridge ('claude' vs 'claude-code')
17
+ *
18
+ * The canonical, persisted id is `'claude'` (used by the agent runner, agent
19
+ * profiles, the Zod config schema and `--type` resolution after normalization).
20
+ * `'claude-code'` is the historical RUNTIME identity — the string stamped on
21
+ * session-log events/refs, the extracted-session dedup key, and the value
22
+ * `resolveAgentIdentity` reports. It is registered as an `alias` and exposed as
23
+ * `runtimeId` so BOTH directions round-trip via `normalizeHarnessId()` /
24
+ * `denormalizeRuntimeIdentity()`. Existing persisted configs and session logs
25
+ * that say `'claude-code'` keep working unchanged.
26
+ */
27
+ import { BaseHarness } from "../types.js";
28
+ export { claudeBuilder } from "./agent-builder.js";
29
+ export { claudeCodeImporter } from "./config-import.js";
30
+ export { ClaudeCodeProvider } from "./session-log.js";
31
+ function caps(c) {
32
+ return {
33
+ sessionLogs: false,
34
+ agentDispatch: false,
35
+ detection: false,
36
+ configImport: false,
37
+ runtimeIdentity: false,
38
+ v1Migration: false,
39
+ ...c,
40
+ };
41
+ }
42
+ /**
43
+ * Claude Code.
44
+ *
45
+ * Canonical id is `'claude'`; `'claude-code'` is the runtime/session-log
46
+ * identity and is registered as an alias so both directions round-trip.
47
+ */
48
+ export class ClaudeHarness extends BaseHarness {
49
+ id = "claude";
50
+ displayName = "Claude Code";
51
+ aliases = ["claude-code"];
52
+ runtimeId = "claude-code";
53
+ // Home-relative config dir scanned by `akm setup` (#567). Claude Code has a
54
+ // session-log provider, so offering it as a stash source is functional.
55
+ setupDetectionDir = ".claude";
56
+ capabilities = caps({
57
+ sessionLogs: true,
58
+ agentDispatch: true,
59
+ detection: true,
60
+ configImport: true,
61
+ runtimeIdentity: true,
62
+ v1Migration: true,
63
+ });
64
+ }
@@ -4,8 +4,20 @@
4
4
  import fs from "node:fs";
5
5
  import os from "node:os";
6
6
  import path from "node:path";
7
- import { extractInlineRefMentions } from "../inline-refs";
8
- const CLAUDE_PROJECTS_DIR = path.join(os.homedir(), ".claude", "projects");
7
+ import { extractInlineRefMentions } from "../../session-logs/inline-refs.js";
8
+ /**
9
+ * Root directory holding Claude Code's per-project JSONL session logs.
10
+ *
11
+ * Resolved per call (not memoized at module load) so the `AKM_CLAUDE_PROJECTS_DIR`
12
+ * override can be set after import. The override exists so tests — and the
13
+ * isolated-storage sandbox — can point the scan at an empty fixture directory
14
+ * instead of the real `~/.claude/projects`, which on an actively-used machine
15
+ * holds many large session files and would make `akm health` (which scans it
16
+ * synchronously) slow and non-hermetic.
17
+ */
18
+ function claudeProjectsDir() {
19
+ return process.env.AKM_CLAUDE_PROJECTS_DIR ?? path.join(os.homedir(), ".claude", "projects");
20
+ }
9
21
  /**
10
22
  * Parse a single Claude Code JSONL event into a normalized {@link SessionEvent}.
11
23
  * Returns `undefined` for events that don't carry textual content (file
@@ -75,14 +87,29 @@ function parseClaudeEvent(entry, sessionId, filePath, fallbackTsMs) {
75
87
  filePath,
76
88
  };
77
89
  }
90
+ /**
91
+ * Claude Code native session-log reader.
92
+ *
93
+ * id-normalization note (#563): the canonical harness id is `'claude'`, but
94
+ * the provider's `name` — which is STAMPED onto every {@link SessionEvent} /
95
+ * {@link SessionRef} (`harness: this.name`), used as the extracted-session
96
+ * dedup key, and embedded in `session:<harness>:<id>` proposal refs — stays
97
+ * `'claude-code'` (the harness runtimeId). Changing it would silently break
98
+ * round-tripping of already-persisted session-tracking rows and refs. Registry
99
+ * lookups normalize `'claude-code'` → `'claude'` via the #562 bridge
100
+ * (`getHarness`), and the `--type` flag accepts both, so the canonical id and
101
+ * the persisted runtime string coexist without drift.
102
+ */
78
103
  export class ClaudeCodeProvider {
104
+ // Runtime identity (NOT the canonical id) — see class doc. Equals
105
+ // HARNESS_BY_ID.get("claude").runtimeId.
79
106
  name = "claude-code";
80
107
  isAvailable() {
81
- return fs.existsSync(CLAUDE_PROJECTS_DIR);
108
+ return fs.existsSync(claudeProjectsDir());
82
109
  }
83
110
  *readEvents(input) {
84
111
  try {
85
- for (const jsonlPath of this.#walkJsonl(CLAUDE_PROJECTS_DIR)) {
112
+ for (const jsonlPath of this.#walkJsonl(claudeProjectsDir())) {
86
113
  const stat = fs.statSync(jsonlPath);
87
114
  if (stat.mtimeMs < input.sinceMs)
88
115
  continue;
@@ -113,7 +140,7 @@ export class ClaudeCodeProvider {
113
140
  }
114
141
  }
115
142
  listSessions(input = {}) {
116
- const root = input.location ?? CLAUDE_PROJECTS_DIR;
143
+ const root = input.location ?? claudeProjectsDir();
117
144
  const sinceMs = input.sinceMs ?? 0;
118
145
  const summaries = [];
119
146
  try {