akm-cli 0.8.1 → 0.9.0-beta.0

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 (318) hide show
  1. package/CHANGELOG.md +258 -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/stash-skeleton/README.md +76 -0
  9. package/dist/assets/tasks/core/backup.yml +4 -0
  10. package/dist/assets/tasks/core/extract.yml +4 -0
  11. package/dist/assets/tasks/core/improve.yml +4 -0
  12. package/dist/assets/tasks/core/index-refresh.yml +4 -0
  13. package/dist/assets/tasks/core/sync.yml +4 -0
  14. package/dist/assets/tasks/core/update-stashes.yml +4 -0
  15. package/dist/assets/tasks/core/version-check.yml +4 -0
  16. package/dist/cli/config-migrate.js +6 -6
  17. package/dist/cli/config-validate.js +4 -4
  18. package/dist/cli/confirm.js +3 -3
  19. package/dist/cli/parse-args.js +1 -1
  20. package/dist/cli/shared.js +51 -14
  21. package/dist/cli-node.mjs +26 -0
  22. package/dist/cli.js +171 -3857
  23. package/dist/commands/{agent-dispatch.js → agent/agent-dispatch.js} +6 -6
  24. package/dist/commands/{agent-support.js → agent/agent-support.js} +2 -2
  25. package/dist/commands/agent/contribute-cli.js +200 -0
  26. package/dist/commands/completions.js +1 -1
  27. package/dist/commands/config-cli.js +240 -3
  28. package/dist/commands/config-edit.js +344 -0
  29. package/dist/commands/db-cli.js +2 -2
  30. package/dist/commands/env/env-cli.js +529 -0
  31. package/dist/commands/env/env.js +410 -0
  32. package/dist/commands/env/secret-cli.js +259 -0
  33. package/dist/commands/{secret.js → env/secret.js} +6 -47
  34. package/dist/commands/events.js +4 -4
  35. package/dist/commands/feedback-cli.js +18 -34
  36. package/dist/commands/graph/graph-cli.js +132 -0
  37. package/dist/commands/{graph.js → graph/graph.js} +22 -16
  38. package/dist/commands/health/checks.js +279 -0
  39. package/dist/commands/health.js +101 -249
  40. package/dist/commands/{consolidate.js → improve/consolidate.js} +52 -40
  41. package/dist/commands/{distill-promotion-policy.js → improve/distill-promotion-policy.js} +3 -3
  42. package/dist/commands/{distill.js → improve/distill.js} +39 -18
  43. package/dist/commands/{eval-cases.js → improve/eval-cases.js} +1 -1
  44. package/dist/commands/{extract-cli.js → improve/extract-cli.js} +4 -4
  45. package/dist/commands/{extract-prompt.js → improve/extract-prompt.js} +2 -2
  46. package/dist/commands/{extract.js → improve/extract.js} +185 -26
  47. package/dist/commands/{improve-auto-accept.js → improve/improve-auto-accept.js} +4 -4
  48. package/dist/commands/{improve-cli.js → improve/improve-cli.js} +45 -23
  49. package/dist/commands/{improve-profiles.js → improve/improve-profiles.js} +13 -7
  50. package/dist/commands/{improve-result-file.js → improve/improve-result-file.js} +10 -5
  51. package/dist/commands/{improve.js → improve/improve.js} +536 -248
  52. package/dist/{core → commands/improve/memory}/memory-belief.js +2 -2
  53. package/dist/{core → commands/improve/memory}/memory-contradiction-detect.js +5 -5
  54. package/dist/{core → commands/improve/memory}/memory-improve.js +4 -4
  55. package/dist/commands/{reflect.js → improve/reflect.js} +33 -28
  56. package/dist/commands/improve/session-asset.js +248 -0
  57. package/dist/commands/lint/agent-linter.js +1 -1
  58. package/dist/commands/lint/base-linter.js +55 -37
  59. package/dist/commands/lint/command-linter.js +1 -1
  60. package/dist/commands/lint/default-linter.js +1 -1
  61. package/dist/commands/lint/env-key-rules.js +1 -1
  62. package/dist/commands/lint/index.js +19 -25
  63. package/dist/commands/lint/knowledge-linter.js +1 -1
  64. package/dist/commands/lint/memory-linter.js +1 -1
  65. package/dist/commands/lint/registry.js +8 -8
  66. package/dist/commands/lint/skill-linter.js +1 -1
  67. package/dist/commands/lint/task-linter.js +1 -1
  68. package/dist/commands/lint/workflow-linter.js +1 -1
  69. package/dist/commands/lint.js +1 -1
  70. package/dist/commands/observability-cli.js +244 -0
  71. package/dist/commands/{proposal-drain-policies.js → proposal/drain-policies.js} +3 -3
  72. package/dist/commands/{proposal-drain.js → proposal/drain.js} +15 -10
  73. package/dist/commands/proposal/proposal-cli.js +478 -0
  74. package/dist/commands/{proposal.js → proposal/proposal.js} +5 -5
  75. package/dist/commands/{propose.js → proposal/propose.js} +11 -11
  76. package/dist/{core → commands/proposal/validators}/proposal-quality-validators.js +8 -3
  77. package/dist/{core → commands/proposal/validators}/proposal-validators.js +5 -5
  78. package/dist/{core → commands/proposal/validators}/proposals.js +13 -7
  79. package/dist/commands/{curate.js → read/curate.js} +7 -7
  80. package/dist/commands/{knowledge.js → read/knowledge.js} +22 -9
  81. package/dist/commands/{registry-search.js → read/registry-search.js} +5 -5
  82. package/dist/commands/{remember-cli.js → read/remember-cli.js} +15 -7
  83. package/dist/commands/read/search-cli.js +207 -0
  84. package/dist/commands/{search.js → read/search.js} +22 -27
  85. package/dist/commands/{show.js → read/show.js} +77 -44
  86. package/dist/commands/registry-cli.js +8 -8
  87. package/dist/commands/remember.js +8 -8
  88. package/dist/commands/sources/add-cli.js +293 -0
  89. package/dist/commands/{history.js → sources/history.js} +27 -25
  90. package/dist/commands/{info.js → sources/info.js} +6 -6
  91. package/dist/commands/{init.js → sources/init.js} +10 -5
  92. package/dist/commands/{installed-stashes.js → sources/installed-stashes.js} +12 -12
  93. package/dist/commands/{migration-help.js → sources/migration-help.js} +3 -2
  94. package/dist/commands/{schema-repair.js → sources/schema-repair.js} +8 -8
  95. package/dist/commands/{self-update.js → sources/self-update.js} +10 -9
  96. package/dist/commands/{source-add.js → sources/source-add.js} +10 -10
  97. package/dist/commands/{source-clone.js → sources/source-clone.js} +7 -7
  98. package/dist/commands/{source-manage.js → sources/source-manage.js} +4 -4
  99. package/dist/commands/sources/sources-cli.js +305 -0
  100. package/dist/commands/sources/stash-cli.js +219 -0
  101. package/dist/commands/sources/stash-skeleton.js +79 -0
  102. package/dist/commands/tasks/default-tasks.js +173 -0
  103. package/dist/commands/tasks/tasks-cli.js +210 -0
  104. package/dist/commands/{tasks.js → tasks/tasks.js} +14 -14
  105. package/dist/commands/wiki-cli.js +307 -0
  106. package/dist/commands/workflow-cli.js +329 -0
  107. package/dist/core/action-contributors.js +1 -1
  108. package/dist/core/assert.js +40 -0
  109. package/dist/core/asset/asset-create.js +54 -0
  110. package/dist/core/{asset-ref.js → asset/asset-ref.js} +21 -4
  111. package/dist/core/{asset-registry.js → asset/asset-registry.js} +3 -3
  112. package/dist/core/{asset-spec.js → asset/asset-spec.js} +17 -31
  113. package/dist/core/{markdown.js → asset/markdown.js} +1 -1
  114. package/dist/core/asset/stash-meta.js +110 -0
  115. package/dist/core/best-effort.js +64 -0
  116. package/dist/core/common.js +32 -18
  117. package/dist/core/{config-io.js → config/config-io.js} +29 -19
  118. package/dist/core/{config-migration.js → config/config-migration.js} +11 -9
  119. package/dist/core/{config-schema.js → config/config-schema.js} +45 -1
  120. package/dist/core/config/config-types.js +16 -0
  121. package/dist/core/{config-walker.js → config/config-walker.js} +2 -2
  122. package/dist/core/{config.js → config/config.js} +10 -8
  123. package/dist/core/env-secret-ref.js +90 -0
  124. package/dist/core/errors.js +13 -3
  125. package/dist/core/events.js +27 -4
  126. package/dist/core/file-lock.js +1 -1
  127. package/dist/core/improve-types.js +48 -0
  128. package/dist/core/lesson-lint.js +2 -2
  129. package/dist/core/paths.js +2 -2
  130. package/dist/{setup/ripgrep-install.js → core/ripgrep/install.js} +2 -2
  131. package/dist/{setup/ripgrep-resolve.js → core/ripgrep/resolve.js} +2 -2
  132. package/dist/core/state-db.js +88 -46
  133. package/dist/core/text-truncation.js +148 -0
  134. package/dist/core/time.js +1 -1
  135. package/dist/core/write-source.js +98 -85
  136. package/dist/indexer/{db-backup.js → db/db-backup.js} +9 -24
  137. package/dist/indexer/{db.js → db/db.js} +126 -116
  138. package/dist/indexer/{graph-db.js → db/graph-db.js} +9 -4
  139. package/dist/indexer/{llm-cache.js → db/llm-cache.js} +15 -12
  140. package/dist/indexer/ensure-index.js +4 -4
  141. package/dist/indexer/{graph-boost.js → graph/graph-boost.js} +1 -1
  142. package/dist/indexer/{graph-extraction.js → graph/graph-extraction.js} +55 -13
  143. package/dist/indexer/indexer.js +37 -30
  144. package/dist/indexer/init.js +54 -0
  145. package/dist/indexer/manifest.js +10 -10
  146. package/dist/indexer/{memory-inference.js → passes/memory-inference.js} +92 -23
  147. package/dist/indexer/{metadata-contributors.js → passes/metadata-contributors.js} +10 -8
  148. package/dist/indexer/{metadata.js → passes/metadata.js} +15 -19
  149. package/dist/indexer/{staleness-detect.js → passes/staleness-detect.js} +53 -12
  150. package/dist/indexer/{db-search.js → search/db-search.js} +28 -16
  151. package/dist/indexer/{ranking-contributors.js → search/ranking-contributors.js} +1 -1
  152. package/dist/indexer/{ranking.js → search/ranking.js} +2 -2
  153. package/dist/indexer/{search-hit-enrichers.js → search/search-hit-enrichers.js} +3 -3
  154. package/dist/indexer/{search-source.js → search/search-source.js} +8 -8
  155. package/dist/indexer/{semantic-status.js → search/semantic-status.js} +3 -3
  156. package/dist/indexer/usage/unmigrated-vaults-guard.js +94 -0
  157. package/dist/indexer/{usage-events.js → usage/usage-events.js} +32 -0
  158. package/dist/indexer/{file-context.js → walk/file-context.js} +10 -15
  159. package/dist/indexer/{matchers.js → walk/matchers.js} +13 -9
  160. package/dist/indexer/{path-resolver.js → walk/path-resolver.js} +6 -6
  161. package/dist/indexer/{project-context.js → walk/project-context.js} +1 -1
  162. package/dist/indexer/{walker.js → walk/walker.js} +4 -3
  163. package/dist/integrations/agent/builder-shared.js +39 -0
  164. package/dist/integrations/agent/builders.js +14 -81
  165. package/dist/integrations/agent/config.js +6 -4
  166. package/dist/integrations/agent/detect.js +1 -1
  167. package/dist/integrations/agent/index.js +23 -8
  168. package/dist/integrations/agent/prompts.js +2 -3
  169. package/dist/integrations/agent/runner.js +22 -3
  170. package/dist/integrations/agent/spawn.js +9 -10
  171. package/dist/integrations/harnesses/claude/agent-builder.js +48 -0
  172. package/dist/integrations/harnesses/claude/config-import.js +70 -0
  173. package/dist/integrations/harnesses/claude/index.js +64 -0
  174. package/dist/integrations/{session-logs/providers/claude-code.js → harnesses/claude/session-log.js} +16 -1
  175. package/dist/integrations/harnesses/index.js +144 -0
  176. package/dist/integrations/harnesses/opencode/agent-builder.js +43 -0
  177. package/dist/integrations/harnesses/opencode/config-import.js +82 -0
  178. package/dist/integrations/harnesses/opencode/index.js +59 -0
  179. package/dist/integrations/{session-logs/providers/opencode.js → harnesses/opencode/session-log.js} +1 -1
  180. package/dist/integrations/harnesses/opencode-sdk/index.js +49 -0
  181. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +234 -0
  182. package/dist/integrations/harnesses/types.js +43 -0
  183. package/dist/integrations/lockfile.js +7 -16
  184. package/dist/integrations/session-logs/index.js +82 -9
  185. package/dist/llm/call-ai.js +4 -4
  186. package/dist/llm/client.js +131 -6
  187. package/dist/llm/embedder.js +6 -6
  188. package/dist/llm/embedders/local.js +9 -22
  189. package/dist/llm/embedders/remote.js +2 -2
  190. package/dist/llm/embedders/types.js +1 -1
  191. package/dist/llm/graph-extract.js +31 -12
  192. package/dist/llm/index-passes.js +1 -1
  193. package/dist/llm/memory-infer.js +12 -5
  194. package/dist/llm/metadata-enhance.js +2 -2
  195. package/dist/output/context.js +6 -44
  196. package/dist/output/renderers.js +88 -58
  197. package/dist/output/shapes/curate.js +7 -3
  198. package/dist/output/shapes/distill.js +7 -3
  199. package/dist/output/shapes/env-list.js +18 -16
  200. package/dist/output/shapes/events.js +5 -4
  201. package/dist/output/shapes/helpers.js +2 -4
  202. package/dist/output/shapes/history.js +7 -3
  203. package/dist/output/shapes/passthrough.js +8 -11
  204. package/dist/output/shapes/{proposal-accept.js → proposal/accept.js} +7 -3
  205. package/dist/output/shapes/{proposal-diff.js → proposal/diff.js} +7 -3
  206. package/dist/output/shapes/{proposal-list.js → proposal/list.js} +7 -3
  207. package/dist/output/shapes/{proposal-producer.js → proposal/producer.js} +5 -4
  208. package/dist/output/shapes/{proposal-reject.js → proposal/reject.js} +7 -3
  209. package/dist/output/shapes/{proposal-show.js → proposal/show.js} +7 -3
  210. package/dist/output/shapes/registry-search.js +7 -3
  211. package/dist/output/shapes/registry.js +12 -0
  212. package/dist/output/shapes/search.js +7 -3
  213. package/dist/output/shapes/secret-list.js +18 -16
  214. package/dist/output/shapes/show.js +7 -3
  215. package/dist/output/shapes.js +55 -30
  216. package/dist/output/text/add.js +2 -3
  217. package/dist/output/text/clone.js +2 -3
  218. package/dist/output/text/config.js +2 -3
  219. package/dist/output/text/curate.js +4 -3
  220. package/dist/output/text/distill.js +2 -3
  221. package/dist/output/text/enable-disable.js +5 -4
  222. package/dist/output/text/env.js +13 -0
  223. package/dist/output/text/events.js +5 -4
  224. package/dist/output/text/feedback.js +4 -3
  225. package/dist/output/text/helpers.js +54 -39
  226. package/dist/output/text/history.js +2 -3
  227. package/dist/output/text/import.js +2 -3
  228. package/dist/output/text/index.js +2 -3
  229. package/dist/output/text/info.js +2 -3
  230. package/dist/output/text/init.js +2 -3
  231. package/dist/output/text/list.js +2 -3
  232. package/dist/output/text/proposal/producer.js +9 -0
  233. package/dist/output/text/proposal/proposal.js +13 -0
  234. package/dist/output/text/registry-commands.js +8 -7
  235. package/dist/output/text/registry.js +12 -0
  236. package/dist/output/text/remember.js +4 -3
  237. package/dist/output/text/remove.js +2 -3
  238. package/dist/output/text/save.js +2 -3
  239. package/dist/output/text/search.js +4 -3
  240. package/dist/output/text/show.js +4 -3
  241. package/dist/output/text/update.js +2 -3
  242. package/dist/output/text/upgrade.js +2 -3
  243. package/dist/output/text/wiki.js +12 -11
  244. package/dist/output/text/workflow.js +12 -10
  245. package/dist/output/text.js +66 -32
  246. package/dist/registry/build-index.js +11 -10
  247. package/dist/registry/factory.js +1 -1
  248. package/dist/registry/origin-resolve.js +1 -1
  249. package/dist/registry/providers/index.js +2 -2
  250. package/dist/registry/providers/skills-sh.js +91 -72
  251. package/dist/registry/providers/static-index.js +75 -52
  252. package/dist/registry/resolve.js +3 -3
  253. package/dist/runtime.js +242 -0
  254. package/dist/scripts/migrate-storage.js +1594 -673
  255. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +240 -166
  256. package/dist/setup/detect.js +338 -9
  257. package/dist/setup/harness-config-import.js +56 -0
  258. package/dist/setup/registry-stash-loader.js +99 -0
  259. package/dist/setup/setup.js +664 -96
  260. package/dist/sources/include.js +1 -1
  261. package/dist/sources/provider-factory.js +2 -2
  262. package/dist/sources/providers/filesystem.js +3 -3
  263. package/dist/sources/providers/git.js +9 -9
  264. package/dist/sources/providers/index.js +4 -4
  265. package/dist/sources/providers/npm.js +6 -6
  266. package/dist/sources/providers/provider-utils.js +13 -20
  267. package/dist/sources/providers/sync-from-ref.js +5 -5
  268. package/dist/sources/providers/tar-utils.js +2 -2
  269. package/dist/sources/providers/website.js +2 -2
  270. package/dist/sources/resolve.js +5 -5
  271. package/dist/sources/website-ingest.js +5 -5
  272. package/dist/storage/database.js +102 -0
  273. package/dist/storage/engines/sqlite-migrations.js +42 -0
  274. package/dist/storage/locations.js +25 -0
  275. package/dist/storage/repositories/index-db.js +43 -0
  276. package/dist/storage/repositories/workflow-runs-repository.js +141 -0
  277. package/dist/tasks/backends/cron.js +4 -4
  278. package/dist/tasks/backends/exec-utils.js +32 -0
  279. package/dist/tasks/backends/index.js +3 -3
  280. package/dist/tasks/backends/launchd.js +7 -14
  281. package/dist/tasks/backends/schtasks.js +7 -16
  282. package/dist/tasks/embedded.js +71 -0
  283. package/dist/tasks/parser.js +2 -2
  284. package/dist/tasks/resolveAkmBin.js +1 -1
  285. package/dist/tasks/runner.js +28 -15
  286. package/dist/tasks/schedule.js +1 -1
  287. package/dist/tasks/validator.js +7 -7
  288. package/dist/text-import-hook.mjs +51 -0
  289. package/dist/version.js +2 -1
  290. package/dist/wiki/wiki.js +7 -7
  291. package/dist/workflows/{authoring.js → authoring/authoring.js} +6 -6
  292. package/dist/workflows/{scope-key.js → authoring/scope-key.js} +1 -1
  293. package/dist/workflows/cli.js +1 -1
  294. package/dist/workflows/db.js +50 -32
  295. package/dist/workflows/parser.js +4 -4
  296. package/dist/workflows/renderer.js +5 -5
  297. package/dist/workflows/runtime/agent-identity.js +56 -0
  298. package/dist/workflows/runtime/checkin.js +57 -0
  299. package/dist/workflows/{runs.js → runtime/runs.js} +197 -101
  300. package/dist/workflows/validate-summary.js +82 -0
  301. package/docs/README.md +1 -1
  302. package/docs/data-and-telemetry.md +6 -6
  303. package/package.json +16 -8
  304. package/dist/commands/add-cli.js +0 -279
  305. package/dist/commands/env.js +0 -213
  306. package/dist/integrations/agent/sdk-runner.js +0 -126
  307. package/dist/output/shapes/vault-list.js +0 -19
  308. package/dist/output/text/proposal-producer.js +0 -8
  309. package/dist/output/text/proposal.js +0 -12
  310. package/dist/output/text/vault.js +0 -16
  311. /package/dist/core/{asset-serialize.js → asset/asset-serialize.js} +0 -0
  312. /package/dist/core/{frontmatter.js → asset/frontmatter.js} +0 -0
  313. /package/dist/core/{config-sources.js → config/config-sources.js} +0 -0
  314. /package/dist/indexer/{graph-dedup.js → graph/graph-dedup.js} +0 -0
  315. /package/dist/{core/config-types.js → indexer/passes/pass-context.js} +0 -0
  316. /package/dist/indexer/{search-fields.js → search/search-fields.js} +0 -0
  317. /package/dist/indexer/{index-context.js → walk/index-context.js} +0 -0
  318. /package/dist/workflows/{document-cache.js → runtime/document-cache.js} +0 -0
@@ -1,22 +1,34 @@
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
+ /**
5
+ * Database-backed (SQLite + FTS5/vector) source search implementation.
6
+ *
7
+ * Extracted from source-search.ts to break the circular import:
8
+ * source-search.ts → sources/providers/filesystem.ts → db-search.ts (no cycle)
9
+ *
10
+ * source-search.ts imports this module for the `searchLocal` export.
11
+ * sources/providers/filesystem.ts also imports `searchLocal` from here.
12
+ *
13
+ * Renamed from `local-search.ts` to signal that this is the DB-layer search
14
+ * implementation, not a "local vs. remote" distinction.
15
+ */
4
16
  import fs from "node:fs";
5
- import { buildActionFromContributors, defaultActionContributors } from "../core/action-contributors";
6
- import { makeAssetRef } from "../core/asset-ref";
7
- import { defaultRendererRegistry } from "../core/asset-registry";
8
- import { getDbPath } from "../core/paths";
9
- import { warn } from "../core/warn";
10
- import { getCurrentWorkflowScopeKey } from "../workflows/scope-key";
11
- import { closeDatabase, getAllEntries, getEntryById, getEntryCount, getMeta, getPositiveFeedbackCountsByIds, openExistingDatabase, sanitizeFtsQuery, searchFts, searchVec, } from "./db";
12
- import { ensureIndex } from "./ensure-index";
13
- import { collectGraphRelatedHit, computeGraphBoost, loadGraphBoostContext, } from "./graph-boost";
14
- import { isProposedQuality } from "./metadata";
15
- import { resolveProjectContext } from "./project-context";
16
- import { applyRankingRules, combineSearchScores, normalizeFtsScores } from "./ranking";
17
- import { enrichSearchHit } from "./search-hit-enrichers";
18
- import { buildEditHint, findSourceForPath, isEditable } from "./search-source";
19
- import { deriveSemanticProviderFingerprint, getEffectiveSemanticStatus, isSemanticRuntimeReady, readSemanticStatus, } from "./semantic-status";
17
+ import { buildActionFromContributors, defaultActionContributors } from "../../core/action-contributors.js";
18
+ import { makeAssetRef } from "../../core/asset/asset-ref.js";
19
+ import { defaultRendererRegistry } from "../../core/asset/asset-registry.js";
20
+ import { getDbPath } from "../../core/paths.js";
21
+ import { warn } from "../../core/warn.js";
22
+ import { getCurrentWorkflowScopeKey } from "../../workflows/authoring/scope-key.js";
23
+ import { closeDatabase, getAllEntries, getEntryById, getEntryCount, getMeta, getPositiveFeedbackCountsByIds, openExistingDatabase, sanitizeFtsQuery, searchFts, searchVec, } from "../db/db.js";
24
+ import { ensureIndex } from "../ensure-index.js";
25
+ import { collectGraphRelatedHit, computeGraphBoost, loadGraphBoostContext, } from "../graph/graph-boost.js";
26
+ import { isProposedQuality } from "../passes/metadata.js";
27
+ import { resolveProjectContext } from "../walk/project-context.js";
28
+ import { applyRankingRules, combineSearchScores, normalizeFtsScores } from "./ranking.js";
29
+ import { enrichSearchHit } from "./search-hit-enrichers.js";
30
+ import { buildEditHint, findSourceForPath, isEditable } from "./search-source.js";
31
+ import { deriveSemanticProviderFingerprint, getEffectiveSemanticStatus, isSemanticRuntimeReady, readSemanticStatus, } from "./semantic-status.js";
20
32
  export function buildLocalAction(type, ref, registry = defaultRendererRegistry) {
21
33
  return buildActionFromContributors({ type, ref }, defaultActionContributors(registry)) ?? `akm show ${ref}`;
22
34
  }
@@ -358,7 +370,7 @@ async function tryVecScores(db, query, k, config) {
358
370
  if (hasEmbeddings !== "1")
359
371
  return null;
360
372
  try {
361
- const { embed } = await import("../llm/embedder.js");
373
+ const { embed } = await import("../../llm/embedder.js");
362
374
  const queryEmbedding = await embed(query, config.embedding);
363
375
  const vecResults = searchVec(db, queryEmbedding, k);
364
376
  const scores = new Map();
@@ -1,7 +1,7 @@
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 { computeGraphBoost } from "./graph-boost";
4
+ import { computeGraphBoost } from "../graph/graph-boost.js";
5
5
  const TYPE_BOOST = {
6
6
  skill: 0.4,
7
7
  command: 0.35,
@@ -1,8 +1,8 @@
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 { getUtilityScoresByIds } from "./db";
5
- import { applyScoreContributors, applyUtilityContributors } from "./ranking-contributors";
4
+ import { getUtilityScoresByIds } from "../db/db.js";
5
+ import { applyScoreContributors, applyUtilityContributors } from "./ranking-contributors.js";
6
6
  export function normalizeFtsScores(results) {
7
7
  const ftsScoreMap = new Map();
8
8
  if (results.length === 0)
@@ -1,9 +1,9 @@
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 { makeAssetRef } from "../core/asset-ref";
5
- import { getDerivedForParent } from "./db";
6
- import { getRenderer } from "./file-context";
4
+ import { makeAssetRef } from "../../core/asset/asset-ref.js";
5
+ import { getDerivedForParent } from "../db/db.js";
6
+ import { getRenderer } from "../walk/file-context.js";
7
7
  const rendererSearchHitEnricher = {
8
8
  name: "renderer-search-hit-enricher",
9
9
  appliesTo(ctx) {
@@ -3,15 +3,15 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
- import { resolveStashDir } from "../core/common";
7
- import { getSources, loadConfig } from "../core/config";
8
- import { resolveSourceProviderFactory } from "../sources/provider-factory";
6
+ import { resolveStashDir } from "../../core/common.js";
7
+ import { getSources, loadConfig } from "../../core/config/config.js";
8
+ import { resolveSourceProviderFactory } from "../../sources/provider-factory.js";
9
9
  // Eager side-effect imports so all built-in source providers self-register
10
10
  // before resolveEntryContentDir() runs.
11
- import "../sources/providers/index";
12
- import { warn } from "../core/warn";
13
- import { ensureGitMirror, getCachePaths, parseGitRepoUrl } from "../sources/providers/git";
14
- import { ensureWebsiteMirror } from "../sources/website-ingest";
11
+ import "../../sources/providers/index.js";
12
+ import { warn } from "../../core/warn.js";
13
+ import { ensureGitMirror, getCachePaths, parseGitRepoUrl } from "../../sources/providers/git.js";
14
+ import { ensureWebsiteMirror } from "../../sources/website-ingest.js";
15
15
  // Legacy "context-hub" / "github" type aliases are normalized to "git" at
16
16
  // config-load time (see src/config.ts), so this set only contains the canonical
17
17
  // type.
@@ -108,7 +108,7 @@ export function resolveSourceEntries(overrideStashDir, existingConfig) {
108
108
  * so the caller can skip it.
109
109
  *
110
110
  * Single source of truth: each provider owns its own path. We instantiate the
111
- * registered {@link import("../sources/provider").SourceProvider} for the entry
111
+ * registered {@link import("../../sources/provider.js").SourceProvider} for the entry
112
112
  * and call `provider.path()`. This replaces the old per-kind switch ladder
113
113
  * (filesystem path / git cache / website cache) that lived here in 0.6.0 —
114
114
  * see spec §10 step 4 and §7 "Removed from 0.6.0".
@@ -2,9 +2,9 @@
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
4
  import fs from "node:fs";
5
- import { writeFileAtomic } from "../core/common";
6
- import { getCacheDir, getSemanticStatusPath } from "../core/paths";
7
- import { DEFAULT_LOCAL_MODEL } from "../llm/embedders/local";
5
+ import { writeFileAtomic } from "../../core/common.js";
6
+ import { getCacheDir, getSemanticStatusPath } from "../../core/paths.js";
7
+ import { DEFAULT_LOCAL_MODEL } from "../../llm/embedders/local.js";
8
8
  export function deriveSemanticProviderFingerprint(embedding) {
9
9
  if (embedding?.endpoint) {
10
10
  return `remote:${embedding.endpoint}|${embedding.model}|${embedding.dimension ?? "default"}`;
@@ -0,0 +1,94 @@
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
+ * One-time, read-only guard for un-migrated `vaults/` directories (0.9.0).
6
+ *
7
+ * Background: 0.8.0 introduced the `env` asset type and a `vaults/` → `env/`
8
+ * copy migration (run by `akm-migrate-storage`). 0.9.0 removed the `vault`
9
+ * asset type entirely, and the indexer now unconditionally SKIPS `vaults/`
10
+ * (see `shouldIndexStashFile` in `metadata.ts`). A user who upgrades straight
11
+ * to 0.9.0 without ever running the storage migration therefore has the `.env`
12
+ * data in their `vaults/` directory silently dropped from the index — it was
13
+ * never copied to `env/`, and `vaults/` is no longer scanned.
14
+ *
15
+ * This guard detects exactly that state on a stash and emits ONE clear warning
16
+ * pointing at `akm-migrate-storage`. It is:
17
+ * - Non-destructive: it never reads `.env` contents, never writes, never
18
+ * deletes, and never moves anything. It only stats directory entries.
19
+ * - Idempotent: the warning is emitted at most once per process per stash
20
+ * directory (deduped in-memory).
21
+ *
22
+ * It deliberately does NOT auto-run the copy: filesystem mutation + chmod of
23
+ * secret material stays in the dedicated `akm-migrate-storage` bin, behind the
24
+ * user's explicit invocation, never as a side effect of a normal `akm` command.
25
+ */
26
+ import fs from "node:fs";
27
+ import path from "node:path";
28
+ import { warn } from "../../core/warn.js";
29
+ /**
30
+ * Marker filename the `vaults/` → `env/` migration drops inside `vaults/` after
31
+ * a successful copy. Single source of truth shared with
32
+ * `scripts/migrate-storage.ts` (which writes it) and this guard (which reads
33
+ * it). Its presence means the data already lives under `env/` (or was a no-op
34
+ * fresh install).
35
+ */
36
+ export const MIGRATED_MARKER = ".migrated";
37
+ /** Stashes already warned about in this process — keyed by absolute stash dir. */
38
+ const warnedStashDirs = new Set();
39
+ /** True when `dir` contains at least one `*.env` / `.env` file (recursively). */
40
+ function hasEnvFilesRecursive(dir) {
41
+ let entries;
42
+ try {
43
+ entries = fs.readdirSync(dir, { withFileTypes: true });
44
+ }
45
+ catch {
46
+ return false;
47
+ }
48
+ for (const entry of entries) {
49
+ const full = path.join(dir, entry.name);
50
+ if (entry.isDirectory()) {
51
+ if (hasEnvFilesRecursive(full))
52
+ return true;
53
+ }
54
+ else if (entry.name === ".env" || entry.name.endsWith(".env")) {
55
+ return true;
56
+ }
57
+ }
58
+ return false;
59
+ }
60
+ /**
61
+ * Warn (once) when `<stashDir>/vaults/` holds `.env` data that was never
62
+ * migrated to `env/`. No-op when there is no `vaults/` dir, when the
63
+ * `vaults/.migrated` marker is present, or when `vaults/` has no `.env` files.
64
+ *
65
+ * @returns `true` when a warning was emitted, `false` otherwise. The return is
66
+ * primarily for tests; callers can ignore it.
67
+ */
68
+ export function warnOnUnmigratedVaults(stashDir) {
69
+ const resolved = path.resolve(stashDir);
70
+ if (warnedStashDirs.has(resolved))
71
+ return false;
72
+ const vaultsDir = path.join(resolved, "vaults");
73
+ if (!fs.existsSync(vaultsDir))
74
+ return false;
75
+ // The migration writes this marker after a successful copy. Its presence
76
+ // means the data already lives under env/ (or was a no-op fresh install).
77
+ if (fs.existsSync(path.join(vaultsDir, MIGRATED_MARKER)))
78
+ return false;
79
+ if (!hasEnvFilesRecursive(vaultsDir))
80
+ return false;
81
+ // Mark before emitting so a throw in `warn` can't cause a re-warn loop.
82
+ warnedStashDirs.add(resolved);
83
+ warn(`[akm] WARNING: found un-migrated secrets in ${vaultsDir}.\n` +
84
+ ` The 'vault' asset type was removed in 0.9.0 and 'vaults/' is no longer indexed,\n` +
85
+ ` so this data will NOT appear under 'env:' until you migrate it. Run:\n` +
86
+ ` akm-migrate-storage --yes\n` +
87
+ ` This copies 'vaults/' -> 'env/' (non-destructive — your 'vaults/' dir is left intact).\n` +
88
+ ` See docs/migration/v0.8-to-v0.9.md.`);
89
+ return true;
90
+ }
91
+ /** Test-only: clear the per-process dedup set. */
92
+ export function _resetUnmigratedVaultsGuardForTests() {
93
+ warnedStashDirs.clear();
94
+ }
@@ -54,12 +54,44 @@ export function getUsageEvents(db, filters) {
54
54
  conditions.push("source = ?");
55
55
  params.push(filters.source);
56
56
  }
57
+ if (filters?.since) {
58
+ conditions.push("created_at >= ?");
59
+ params.push(filters.since);
60
+ }
57
61
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
58
62
  const sql = `SELECT id, event_type, query, entry_id, entry_ref, signal, metadata, source, created_at
59
63
  FROM usage_events ${where}
60
64
  ORDER BY id ASC`;
61
65
  return db.prepare(sql).all(...params);
62
66
  }
67
+ /**
68
+ * Aggregate positive/negative feedback counts for a single entry.
69
+ *
70
+ * Lifted verbatim from `akm feedback` (feedback-cli.ts) where the same
71
+ * SUM(CASE …) query was hand-rolled inline. Returns plain numbers (NULL SUMs
72
+ * over an empty set are coalesced to 0) so the result fully materialises before
73
+ * any owning connection closes.
74
+ */
75
+ export function countFeedbackSignals(db, entryId) {
76
+ const counts = db
77
+ .prepare(`SELECT
78
+ SUM(CASE WHEN signal = 'positive' THEN 1 ELSE 0 END) AS pos,
79
+ SUM(CASE WHEN signal = 'negative' THEN 1 ELSE 0 END) AS neg
80
+ FROM usage_events
81
+ WHERE event_type = 'feedback' AND entry_id = ?`)
82
+ .get(entryId);
83
+ return { pos: counts?.pos ?? 0, neg: counts?.neg ?? 0 };
84
+ }
85
+ /**
86
+ * Count usage events of a given `event_type`.
87
+ *
88
+ * Lifted verbatim from `akm improve` (improve.ts) where the show-event count
89
+ * was hand-rolled inline to drive the zero-feedback fallback warning.
90
+ */
91
+ export function countUsageEventsByType(db, eventType) {
92
+ return db.prepare("SELECT COUNT(*) AS cnt FROM usage_events WHERE event_type = ?").get(eventType)
93
+ .cnt;
94
+ }
63
95
  /**
64
96
  * Delete usage events older than the given number of days.
65
97
  */
@@ -9,8 +9,8 @@
9
9
  */
10
10
  import fs from "node:fs";
11
11
  import path from "node:path";
12
- import { toPosix } from "../core/common";
13
- import { parseFrontmatter } from "../core/frontmatter";
12
+ import { parseFrontmatter } from "../../core/asset/frontmatter.js";
13
+ import { toPosix } from "../../core/common.js";
14
14
  /**
15
15
  * Build a FileContext from a stash root and an absolute file path.
16
16
  *
@@ -71,22 +71,17 @@ export function buildFileContext(stashRoot, absPath) {
71
71
  const matchers = [];
72
72
  /** Renderer lookup by name. */
73
73
  const renderers = new Map();
74
- let builtinsPromise;
75
74
  /**
76
- * Ensure that built-in matchers and renderers are registered.
77
- * Called lazily on first use of runMatchers/getRenderer.
78
- * Stores the in-progress promise so parallel callers don't double-register.
75
+ * Ensure that all built-in indexer contributors are registered.
76
+ *
77
+ * Delegates to the single `initIndexer()` composition root (see
78
+ * `src/indexer/init.ts`). Imported dynamically to keep this a lazy gate and to
79
+ * avoid a static import cycle (init -> renderers -> file-context). Called on
80
+ * first use of runMatchers/getRenderer/getAllRenderers; idempotent.
79
81
  */
80
82
  async function ensureBuiltinsRegistered() {
81
- if (!builtinsPromise) {
82
- builtinsPromise = (async () => {
83
- const { registerBuiltinMatchers } = await import("./matchers.js");
84
- const { registerBuiltinRenderers } = await import("../output/renderers.js");
85
- registerBuiltinMatchers();
86
- registerBuiltinRenderers();
87
- })();
88
- }
89
- return builtinsPromise;
83
+ const { initIndexer } = await import("../init.js");
84
+ await initIndexer();
90
85
  }
91
86
  /**
92
87
  * Register an AssetMatcher.
@@ -8,10 +8,10 @@
8
8
  * one heuristic. The public `*Matcher` exports compose those facts into the
9
9
  * `MatchResult` shape expected by the rest of the indexer.
10
10
  */
11
- import { defaultRendererRegistry } from "../core/asset-registry";
12
- import { SCRIPT_EXTENSIONS } from "../core/asset-spec";
13
- import { looksLikeWorkflow } from "../workflows/parser";
14
- import { registerMatcher } from "./file-context";
11
+ import { defaultRendererRegistry } from "../../core/asset/asset-registry.js";
12
+ import { SCRIPT_EXTENSIONS } from "../../core/asset/asset-spec.js";
13
+ import { looksLikeWorkflow } from "../../workflows/parser.js";
14
+ import { registerMatcher } from "./file-context.js";
15
15
  // ---------------------------------------------------------------------------
16
16
  // Private data
17
17
  // ---------------------------------------------------------------------------
@@ -56,11 +56,6 @@ const DIR_TYPE_MAP = [
56
56
  type: "env",
57
57
  test: (_, fileName) => fileName === ".env" || fileName.endsWith(".env"),
58
58
  },
59
- {
60
- dir: "vaults",
61
- type: "vault",
62
- test: (_, fileName) => fileName === ".env" || fileName.endsWith(".env"),
63
- },
64
59
  {
65
60
  dir: "secrets",
66
61
  type: "secret",
@@ -74,6 +69,15 @@ const DIR_TYPE_MAP = [
74
69
  type: "task",
75
70
  test: (ext) => ext === ".md",
76
71
  },
72
+ {
73
+ // #561 — agent session assets live under `sessions/<harness>/<id>.md`.
74
+ // classifyByDirectory walks every ancestor dir, so a nested file still
75
+ // matches the `sessions` rule. Without this entry the file falls through
76
+ // to classifyBySmartMd and is mistyped as `knowledge`.
77
+ dir: "sessions",
78
+ type: "session",
79
+ test: (ext) => ext === ".md",
80
+ },
77
81
  ];
78
82
  const COMMAND_PLACEHOLDER_RE = /\$ARGUMENTS|\$[123]\b/;
79
83
  // Files that should never be treated as the typed asset for the surrounding
@@ -3,12 +3,12 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
- import { parseAssetRef } from "../core/asset-ref";
7
- import { resolveAssetPathFromName, TYPE_DIRS } from "../core/asset-spec";
8
- import { isWithin } from "../core/common";
9
- import { resolveSourcesForOrigin } from "../registry/origin-resolve";
10
- import { lookup } from "./indexer";
11
- import { resolveSourceEntries } from "./search-source";
6
+ import { parseAssetRef } from "../../core/asset/asset-ref.js";
7
+ import { resolveAssetPathFromName, TYPE_DIRS } from "../../core/asset/asset-spec.js";
8
+ import { isWithin } from "../../core/common.js";
9
+ import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
10
+ import { lookup } from "../indexer.js";
11
+ import { resolveSourceEntries } from "../search/search-source.js";
12
12
  function normalizeRef(ref) {
13
13
  return typeof ref === "string" ? parseAssetRef(ref) : ref;
14
14
  }
@@ -20,7 +20,7 @@
20
20
  import fs from "node:fs";
21
21
  import os from "node:os";
22
22
  import path from "node:path";
23
- import { resolveWorkflowScopeAnchor } from "../workflows/scope-key.js";
23
+ import { resolveWorkflowScopeAnchor } from "../../workflows/authoring/scope-key.js";
24
24
  // Words that appear in almost every project name and carry no discriminating
25
25
  // signal for ranking. Filtered out after token splitting.
26
26
  const TOKEN_BLOCKLIST = new Set([
@@ -10,8 +10,9 @@
10
10
  */
11
11
  import fs from "node:fs";
12
12
  import path from "node:path";
13
- import { isRelevantAssetFile } from "../core/asset-spec";
14
- import { buildFileContext } from "./file-context";
13
+ import { isRelevantAssetFile } from "../../core/asset/asset-spec.js";
14
+ import { spawnSync } from "../../runtime.js";
15
+ import { buildFileContext } from "./file-context.js";
15
16
  const SKIP_DIRS = new Set([".git", "node_modules", "bin", ".cache"]);
16
17
  /**
17
18
  * Walk a type root directory and return files grouped by their parent directory.
@@ -80,7 +81,7 @@ function walkStashGit(stashRoot) {
80
81
  if (!isInsideGitRepo(stashRoot))
81
82
  return null;
82
83
  // Get tracked + untracked (non-ignored) files
83
- const result = Bun.spawnSync(["git", "ls-files", "--cached", "--others", "--exclude-standard", "-z", "--", "."], {
84
+ const result = spawnSync(["git", "ls-files", "--cached", "--others", "--exclude-standard", "-z", "--", "."], {
84
85
  cwd: stashRoot,
85
86
  });
86
87
  // result.success is false if the process exited non-zero OR git was not found
@@ -0,0 +1,39 @@
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
+ * Shared agent-command-builder types and helpers (#563).
6
+ *
7
+ * Extracted from `agent/builders.ts` so per-harness builders (e.g.
8
+ * `harnesses/claude/agent-builder.ts`) can depend on the common
9
+ * types/validation WITHOUT creating an import cycle back through
10
+ * `builders.ts` (which imports the per-harness builders into its registry).
11
+ * This module is a dependency-graph LEAF for the builder subsystem.
12
+ *
13
+ * Behaviour-preserving: the type shapes and helper bodies are unchanged from
14
+ * their previous home in `builders.ts`.
15
+ */
16
+ import { UsageError } from "../../core/errors.js";
17
+ /**
18
+ * Guard against values that start with `--`, which would be mis-interpreted as
19
+ * CLI flags by the spawned process when used as flag values (model, systemPrompt).
20
+ * Bun.spawn uses array argv so there is no shell injection, but a `--`-prefixed
21
+ * value passed as the argument to `--model` or `--system-prompt` can still
22
+ * confuse the CLI parser of the target process.
23
+ */
24
+ export function assertNotFlag(value, field) {
25
+ if (value?.trimStart().startsWith("--")) {
26
+ throw new UsageError(`${field} must not start with "--": ${JSON.stringify(value.slice(0, 60))}`, "INVALID_FLAG_VALUE");
27
+ }
28
+ }
29
+ /**
30
+ * Normalize a toolPolicy value to a comma-separated string suitable for a
31
+ * CLI flag. Structured policy objects are JSON-serialized.
32
+ */
33
+ export function normalizeTools(tools) {
34
+ if (typeof tools === "string")
35
+ return tools;
36
+ if (Array.isArray(tools))
37
+ return tools.join(",");
38
+ return JSON.stringify(tools);
39
+ }
@@ -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