akm-cli 0.9.0-rc.1 → 0.9.0-rc.13

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 (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -18,35 +18,9 @@ import fs from "node:fs";
18
18
  import os from "node:os";
19
19
  import path from "node:path";
20
20
  import { parseEmbeddedJsonResponse } from "../../core/parse.js";
21
- import { spawn as runtimeSpawn } from "../../runtime.js";
21
+ import { runManagedSubprocess, } from "../../core/subprocess.js";
22
22
  import { getCommandBuilder } from "./builders.js";
23
23
  import { DEFAULT_AGENT_TIMEOUT_MS } from "./config.js";
24
- /**
25
- * Kill the process group of `proc` with `signal`, falling back to
26
- * `proc.kill(signal)` when `proc.pid` is unavailable (e.g. test fakes).
27
- *
28
- * Passing a negative PID to `process.kill` targets the entire process
29
- * group, so opencode's child processes (the .opencode binary, etc.) are
30
- * reaped alongside the node wrapper. The fallback keeps test fakes working
31
- * without modification.
32
- */
33
- function killGroup(proc, signal) {
34
- if (typeof proc.pid === "number") {
35
- try {
36
- process.kill(-proc.pid, signal);
37
- return;
38
- }
39
- catch {
40
- // Process may have already exited; fall through to direct kill.
41
- }
42
- }
43
- try {
44
- proc.kill(signal);
45
- }
46
- catch {
47
- /* ignore */
48
- }
49
- }
50
24
  const DEFAULT_TIMEOUT_MS = DEFAULT_AGENT_TIMEOUT_MS;
51
25
  /**
52
26
  * Supplement `existingPath` with well-known user binary directories when
@@ -102,14 +76,6 @@ function pathCandidatesForCurrentPlatform(home) {
102
76
  "/usr/local/bin",
103
77
  ];
104
78
  }
105
- function resolveSpawnFn(options) {
106
- if (options.spawn)
107
- return options.spawn;
108
- // Default to the runtime-boundary spawn, which delegates to the native
109
- // subprocess API on each runtime. Tests inject `options.spawn` to avoid
110
- // poking real binaries.
111
- return runtimeSpawn;
112
- }
113
79
  /**
114
80
  * Build the child env. Starts empty and copies through:
115
81
  * • Every name in `profile.envPassthrough`.
@@ -143,80 +109,6 @@ function buildChildEnv(profile, options) {
143
109
  }
144
110
  return env;
145
111
  }
146
- const STREAM_READ_TIMEOUT = Symbol("stream-read-timeout");
147
- async function readStream(stream, opts) {
148
- if (!stream)
149
- return { text: "", timedOut: false };
150
- const reader = stream.getReader();
151
- const decoder = new TextDecoder();
152
- let text = "";
153
- if (!opts?.timeoutMs) {
154
- try {
155
- while (true) {
156
- const chunk = await reader.read();
157
- if (chunk.done)
158
- break;
159
- text += decoder.decode(chunk.value, { stream: true });
160
- }
161
- text += decoder.decode();
162
- return { text, timedOut: false };
163
- }
164
- catch (error) {
165
- return { text, timedOut: false, error };
166
- }
167
- finally {
168
- try {
169
- reader.releaseLock();
170
- }
171
- catch {
172
- /* ignore */
173
- }
174
- }
175
- }
176
- // Race the stream read against a timeout so a process that is killed via
177
- // SIGTERM/SIGKILL but whose pipe endpoints stay open (e.g. background
178
- // threads still holding the fd) cannot block the caller indefinitely.
179
- // On timeout we return whatever was decoded before the pipe stopped draining.
180
- const setTimeoutImpl = opts.setTimeoutFn ?? setTimeout;
181
- const clearTimeoutImpl = opts.clearTimeoutFn ?? clearTimeout;
182
- let timer;
183
- const timeoutPromise = new Promise((resolve) => {
184
- timer = setTimeoutImpl(() => {
185
- timer = undefined;
186
- resolve(STREAM_READ_TIMEOUT);
187
- }, opts.timeoutMs);
188
- if (typeof timer !== "number")
189
- timer.unref?.();
190
- });
191
- try {
192
- while (true) {
193
- const chunk = await Promise.race([reader.read(), timeoutPromise]);
194
- if (chunk === STREAM_READ_TIMEOUT) {
195
- void reader.cancel().catch(() => { });
196
- return { text, timedOut: true };
197
- }
198
- if (chunk.done)
199
- break;
200
- text += decoder.decode(chunk.value, { stream: true });
201
- }
202
- text += decoder.decode();
203
- return { text, timedOut: false };
204
- }
205
- catch (error) {
206
- return { text, timedOut: false, error };
207
- }
208
- finally {
209
- if (timer !== undefined) {
210
- clearTimeoutImpl(timer);
211
- }
212
- try {
213
- reader.releaseLock();
214
- }
215
- catch {
216
- /* ignore */
217
- }
218
- }
219
- }
220
112
  function streamFailureMessage(profileName, stdout, stderr) {
221
113
  const failures = [];
222
114
  if (stdout.error)
@@ -251,8 +143,8 @@ function streamFailureMessage(profileName, stdout, stderr) {
251
143
  */
252
144
  export async function runAgent(profile, prompt, options = {}) {
253
145
  const stdioMode = options.stdio ?? profile.stdio;
254
- // null = explicitly disabled (no kill timer). undefined = inherit from profile/default.
255
- const timeoutMs = options.timeoutMs !== undefined ? options.timeoutMs : (profile.timeoutMs ?? DEFAULT_TIMEOUT_MS);
146
+ // null = explicitly disabled (no kill timer). undefined = runtime default.
147
+ const timeoutMs = options.timeoutMs !== undefined ? options.timeoutMs : DEFAULT_TIMEOUT_MS;
256
148
  const parseOutput = options.parseOutput ?? profile.parseOutput;
257
149
  const setTimeoutImpl = options.setTimeoutFn ?? setTimeout;
258
150
  const clearTimeoutImpl = options.clearTimeoutFn ?? clearTimeout;
@@ -268,20 +160,20 @@ export async function runAgent(profile, prompt, options = {}) {
268
160
  }
269
161
  };
270
162
  // Build argv via the platform-specific builder when dispatch params are
271
- // provided; fall back to the legacy positional-prompt form otherwise.
163
+ // provided; otherwise use the direct positional-prompt form.
272
164
  let builtArgv;
273
165
  let builtEnv;
274
166
  if (options.dispatch !== undefined) {
275
- const builder = getCommandBuilder(profile.commandBuilder ?? profile.name, options.builderRegistry);
167
+ const builder = getCommandBuilder(profile.platform ?? profile.name, options.builderRegistry);
276
168
  const built = builder.build(profile, options.dispatch);
277
169
  builtArgv = built.argv;
278
170
  builtEnv = built.env;
279
171
  }
280
172
  else {
281
- const legacyArgs = [...profile.args, ...(options.args ?? [])];
173
+ const positionalArgs = [...profile.args, ...(options.args ?? [])];
282
174
  if (prompt !== undefined)
283
- legacyArgs.push(prompt);
284
- builtArgv = [profile.bin, ...legacyArgs];
175
+ positionalArgs.push(prompt);
176
+ builtArgv = [profile.bin, ...positionalArgs];
285
177
  }
286
178
  // Extra args (e.g. forwarded CLI positionals) are appended after the builder output.
287
179
  const finalArgv = [...builtArgv, ...(options.dispatch ? (options.args ?? []) : [])];
@@ -300,161 +192,43 @@ export async function runAgent(profile, prompt, options = {}) {
300
192
  error: `agent CLI "${profile.name}" not started: caller signal already aborted`,
301
193
  };
302
194
  }
303
- let proc;
304
- try {
305
- const spawnFn = resolveSpawnFn(options);
306
- proc = spawnFn(finalArgv, {
307
- stdin: stdioMode === "captured" ? (options.stdin !== undefined ? "pipe" : "ignore") : "inherit",
308
- stdout: stdioMode === "captured" ? "pipe" : "inherit",
309
- stderr: stdioMode === "captured" ? "pipe" : "inherit",
310
- env,
311
- // options.cwd wins; dispatch.cwd is the request-level fallback (it was
312
- // declared on AgentDispatchRequest but consumed by nothing — P0.5 fix).
313
- ...((options.cwd ?? options.dispatch?.cwd) ? { cwd: options.cwd ?? options.dispatch?.cwd } : {}),
314
- // Spawn in its own process group so killGroup(-pid, signal) reaches all
315
- // descendants (e.g. the .opencode binary that opencode's node wrapper forks).
316
- // Only applied in captured mode — interactive mode inherits the parent
317
- // terminal's process group intentionally.
318
- ...(stdioMode === "captured" ? { detached: true } : {}),
319
- });
320
- }
321
- catch (err) {
322
- const durationMs = Date.now() - start;
323
- return {
324
- ok: false,
325
- exitCode: null,
326
- stdout: "",
327
- stderr: "",
328
- durationMs,
329
- reason: "spawn_failed",
330
- error: err instanceof Error ? err.message : String(err),
331
- };
332
- }
333
- emitSpawnEvent("spawn_start", {
334
- profile: profile.name,
335
- ...(typeof proc.pid === "number" ? { pid: proc.pid } : {}),
336
- });
337
- // Hard timeout. We prefer SIGTERM, then SIGKILL if SIGTERM is ignored,
338
- // but the subprocess only exposes a single .kill() — one signal is enough
339
- // for the structured-failure contract.
195
+ // Spawn/timeout/abort/capture are owned by the managed-subprocess primitive
196
+ // (src/core/subprocess.ts): process-GROUP spawn (detached in captured mode),
197
+ // the SIGTERM→SIGKILL kill ladder on timeout/abort, bounded output capture,
198
+ // and the optional stdin payload. runAgent keeps its agent-specific surface —
199
+ // the onEvent observability seam, the failure taxonomy, and JSON parsing.
340
200
  //
341
- // BUG-M3: only flag `timedOut` when the child has not already exited. A
342
- // timer firing in the same microtask as `proc.exited` resolving could
343
- // otherwise label a clean exit as a timeout.
344
- //
345
- // When timeoutMs is null the kill timer is skipped entirely — the task runs
346
- // until the process exits naturally. Intended for long-running local-model
347
- // tasks where wall-clock time is unpredictable.
348
- let timedOut = false;
349
- let timer;
350
- if (timeoutMs !== null) {
351
- timer = setTimeoutImpl(() => {
352
- if (!proc || proc.exitCode !== null)
353
- return;
354
- timedOut = true;
355
- killGroup(proc, "SIGTERM");
356
- // Follow up with SIGKILL after 5 s in case the process ignores SIGTERM.
357
- const sigkillTimer = setTimeoutImpl(() => {
358
- if (!proc || proc.exitCode !== null)
359
- return;
360
- killGroup(proc, "SIGKILL");
361
- }, 5000);
362
- if (typeof sigkillTimer !== "number")
363
- sigkillTimer.unref?.();
364
- }, timeoutMs);
365
- }
366
- // Cooperative cancel: same SIGTERM→SIGKILL discipline as the timeout, but
367
- // flagged separately so the result carries `reason: "aborted"`.
368
- let aborted = false;
369
- const abortSignal = options.signal;
370
- const onAbort = () => {
371
- if (!proc || proc.exitCode !== null)
372
- return;
373
- aborted = true;
374
- killGroup(proc, "SIGTERM");
375
- const sigkillTimer = setTimeoutImpl(() => {
376
- if (!proc || proc.exitCode !== null)
377
- return;
378
- killGroup(proc, "SIGKILL");
379
- }, 5000);
380
- if (typeof sigkillTimer !== "number")
381
- sigkillTimer.unref?.();
382
- };
383
- if (abortSignal) {
384
- // A signal that aborted between the pre-spawn check and here is handled
385
- // by calling the listener directly.
386
- if (abortSignal.aborted)
387
- onAbort();
388
- else
389
- abortSignal.addEventListener("abort", onAbort, { once: true });
390
- }
391
- // Stream-drain timeout: the overall wall-clock budget plus a 2 s grace
392
- // period. When a process is killed via SIGTERM/SIGKILL (from our timeout
393
- // handler or from outside) some runtimes keep the pipe write-end open in
394
- // background threads, which would cause `Response.text()` to block forever.
395
- // Capping stream draining ensures the caller never hangs past the wall
396
- // budget regardless of subprocess pipe behaviour.
397
- // When there is no kill timer, allow up to 30 s for streams to drain.
398
- const streamDrainTimeoutMs = timeoutMs !== null ? timeoutMs + 2_000 : 30_000;
399
- const stdoutPromise = stdioMode === "captured"
400
- ? readStream(proc.stdout ?? null, {
401
- timeoutMs: streamDrainTimeoutMs,
402
- setTimeoutFn: setTimeoutImpl,
403
- clearTimeoutFn: clearTimeoutImpl,
404
- })
405
- : Promise.resolve({ text: "", timedOut: false });
406
- const stderrPromise = stdioMode === "captured"
407
- ? readStream(proc.stderr ?? null, {
408
- timeoutMs: streamDrainTimeoutMs,
409
- setTimeoutFn: setTimeoutImpl,
410
- clearTimeoutFn: clearTimeoutImpl,
411
- })
412
- : Promise.resolve({ text: "", timedOut: false });
413
- // Optional stdin payload (captured mode only).
414
- //
415
- // BUG-H1: race the stdin write/close against `proc.exited` and the
416
- // timeout timer. If the child never drains stdin, an unraced
417
- // `await writer.write()` would block forever and prevent `runAgent`
418
- // from ever returning.
419
- if (options.stdin !== undefined && stdioMode === "captured" && proc.stdin) {
420
- const stdinPayload = options.stdin;
421
- const stdinStream = proc.stdin;
422
- const stdinDone = (async () => {
423
- try {
424
- const writer = stdinStream.getWriter();
425
- const bytes = new TextEncoder().encode(stdinPayload);
426
- await writer.write(bytes);
427
- await writer.close();
428
- }
429
- catch {
430
- // Best-effort: ignore stdin write failures, the child will get EOF.
431
- }
432
- })();
433
- // Resolve as soon as either the write completes or the child exits.
434
- // We don't await the result — only that one of the two has settled —
435
- // so a stuck writer cannot keep us pinned past the timeout.
436
- await Promise.race([stdinDone, proc.exited.catch(() => undefined)]);
437
- }
438
- let exitCode = null;
439
- try {
440
- exitCode = await proc.exited;
441
- }
442
- catch (err) {
443
- if (timer !== undefined)
444
- clearTimeoutImpl(timer);
445
- abortSignal?.removeEventListener("abort", onAbort);
446
- // BUG-H2: drain stream readers before the early return so they don't
447
- // surface as unhandled rejections after the function resolves.
448
- // The streams already carry a built-in drain timeout so this allSettled
449
- // will not block indefinitely.
450
- await Promise.allSettled([stdoutPromise, stderrPromise]);
451
- const durationMs = Date.now() - start;
452
- emitSpawnEvent("spawn_exit", {
453
- profile: profile.name,
454
- ...(typeof proc.pid === "number" ? { pid: proc.pid } : {}),
455
- exitCode: null,
456
- status: "spawn_failed",
457
- });
201
+ // `onSpawn` fires spawn_start once the child is live (never for a pre-spawn
202
+ // abort or a synchronous spawn failure), and captures the proc so spawn_exit
203
+ // can carry the same pid.
204
+ let spawnedProc;
205
+ const result = await runManagedSubprocess(finalArgv, {
206
+ capture: stdioMode === "captured",
207
+ env,
208
+ ...(options.cwd ? { cwd: options.cwd } : {}),
209
+ ...(options.stdin !== undefined ? { stdin: options.stdin } : {}),
210
+ timeoutMs,
211
+ ...(options.signal ? { signal: options.signal } : {}),
212
+ ...(options.spawn ? { spawnFn: options.spawn } : {}),
213
+ setTimeoutFn: setTimeoutImpl,
214
+ clearTimeoutFn: clearTimeoutImpl,
215
+ onSpawn: (proc) => {
216
+ spawnedProc = proc;
217
+ emitSpawnEvent("spawn_start", {
218
+ profile: profile.name,
219
+ ...(typeof proc.pid === "number" ? { pid: proc.pid } : {}),
220
+ });
221
+ },
222
+ });
223
+ const pidField = spawnedProc && typeof spawnedProc.pid === "number" ? { pid: spawnedProc.pid } : {};
224
+ const durationMs = Date.now() - start;
225
+ // Spawn/exit failure. A synchronous spawn throw never reached a live child
226
+ // (no spawn_start fired, so no spawn_exit either); a rejected proc.exited did
227
+ // (spawn_start already fired, so it emits a spawn_exit with status spawn_failed).
228
+ if (result.spawnError) {
229
+ if (spawnedProc) {
230
+ emitSpawnEvent("spawn_exit", { profile: profile.name, ...pidField, exitCode: null, status: "spawn_failed" });
231
+ }
458
232
  return {
459
233
  ok: false,
460
234
  exitCode: null,
@@ -462,21 +236,16 @@ export async function runAgent(profile, prompt, options = {}) {
462
236
  stderr: "",
463
237
  durationMs,
464
238
  reason: "spawn_failed",
465
- error: err instanceof Error ? err.message : String(err),
239
+ error: result.spawnError.message,
466
240
  };
467
241
  }
468
- clearTimeoutImpl(timer);
469
- abortSignal?.removeEventListener("abort", onAbort);
242
+ const { exitCode, timedOut, aborted, stdout, stderr } = result;
470
243
  emitSpawnEvent("spawn_exit", {
471
244
  profile: profile.name,
472
- ...(typeof proc.pid === "number" ? { pid: proc.pid } : {}),
245
+ ...pidField,
473
246
  exitCode,
474
247
  status: aborted ? "aborted" : timedOut ? "timeout" : exitCode !== 0 ? "non_zero_exit" : "ok",
475
248
  });
476
- const [stdoutRead, stderrRead] = await Promise.all([stdoutPromise, stderrPromise]);
477
- const stdout = stdoutRead.text;
478
- const stderr = stderrRead.text;
479
- const durationMs = Date.now() - start;
480
249
  if (aborted) {
481
250
  return {
482
251
  ok: false,
@@ -499,7 +268,7 @@ export async function runAgent(profile, prompt, options = {}) {
499
268
  error: `agent CLI "${profile.name}" timed out after ${timeoutMs ?? 0}ms`,
500
269
  };
501
270
  }
502
- const captureFailure = streamFailureMessage(profile.name, stdoutRead, stderrRead);
271
+ const captureFailure = streamFailureMessage(profile.name, result.stdoutRead, result.stderrRead);
503
272
  if (captureFailure) {
504
273
  return {
505
274
  ok: false,
@@ -52,7 +52,7 @@
52
52
  * therefore dropped rather than approximated — never silently widened.
53
53
  * - **resume/session** — NOT expressible: Aider persists context in
54
54
  * chat-history files (`.aider.chat.history.md`), not session ids, so there
55
- * is no flag-shaped `HarnessResumeSupport` to export and the extractor
55
+ * is no flag-shaped resume to describe and the extractor
56
56
  * never yields a `sessionId`. akm's `workflow_run_units` remains the
57
57
  * durable source of truth; resume works even against a harness with no
58
58
  * session model (plan §"Session, MCP, and identity across harnesses" —
@@ -60,13 +60,14 @@
60
60
  * - **effort** — stays unconsumed (reserved; the shared request contract's
61
61
  * "no builder consumes it yet" note stays true).
62
62
  *
63
- * NOT registered anywhere: `builders.ts` / `harnesses/index.ts` wiring is a
64
- * follow-up integration task (as is the registry entry declaring
65
- * `structuredOutput: "none"` and no `resume`). Exported standalone so that
66
- * task only adds a registry entry.
63
+ * Registered: `aiderBuilder` is `AiderHarness.agentBuilder` (`./index.ts`),
64
+ * one of the ten harnesses `HARNESS_REGISTRY` constructs
65
+ * (`harnesses/index.ts`); `agent/builders.ts` derives `BUILTIN_BUILDERS` from
66
+ * that registry, so this builder is reachable under the `"aider"` platform
67
+ * name without any further wiring. The registry entry also declares
68
+ * `structuredOutput: "none"` alongside it (`./index.ts`).
67
69
  */
68
- import { assertNotFlag } from "../../agent/builder-shared.js";
69
- import { resolveModel } from "../../agent/model-aliases.js";
70
+ import { assertNotFlag, resolveDispatchModel, } from "../../agent/builder-shared.js";
70
71
  /** Canonical harness/platform id used for model-alias resolution. */
71
72
  export const AIDER_PLATFORM = "aider";
72
73
  /**
@@ -98,7 +99,7 @@ export const aiderBuilder = {
98
99
  assertNotFlag(req.model, "model");
99
100
  const args = [...profile.args];
100
101
  if (req.model) {
101
- const resolved = resolveModel(req.model, AIDER_PLATFORM, profile.modelAliases, profile.globalModelAliases);
102
+ const resolved = resolveDispatchModel(req, profile, AIDER_PLATFORM);
102
103
  args.push("--model", resolved);
103
104
  }
104
105
  // Headless essentials (matrix shape): auto-confirm everything, and keep
@@ -12,22 +12,12 @@
12
12
  * `HARNESS_REGISTRY` registers. Dispatch-only: no native session-log reader or
13
13
  * config importer yet.
14
14
  */
15
+ import { caps } from "../shared.js";
15
16
  import { BaseHarness } from "../types.js";
16
17
  import { aiderBuilder } from "./agent-builder.js";
17
18
  import { aiderResultExtractor } from "./result-extractor.js";
18
19
  export { AIDER_PLATFORM, aiderBuilder } from "./agent-builder.js";
19
20
  export { aiderResultExtractor } from "./result-extractor.js";
20
- function caps(c) {
21
- return {
22
- sessionLogs: false,
23
- agentDispatch: false,
24
- detection: false,
25
- configImport: false,
26
- runtimeIdentity: false,
27
- v1Migration: false,
28
- ...c,
29
- };
30
- }
31
21
  /**
32
22
  * Aider.
33
23
  *
@@ -45,7 +35,7 @@ export class AiderHarness extends BaseHarness {
45
35
  // No structured-output mode at all (the matrix's "none — parse output"):
46
36
  // akm injects the schema into the prompt and extracts embedded JSON.
47
37
  structuredOutput = "none";
48
- // No `resume`: Aider persists context in chat-history files
38
+ // No flag-shaped resume: Aider persists context in chat-history files
49
39
  // (`.aider.chat.history.md`), not session ids — the plan's named example of
50
40
  // a harness with no session model. akm's `workflow_run_units` remains the
51
41
  // durable resume source of truth.
@@ -11,8 +11,7 @@
11
11
  *
12
12
  * q chat --no-interactive --trust-all-tools "<prompt>"
13
13
  *
14
- * with `--model <m>` for model selection and `--resume` for resume. Resume is
15
- * registry-side (`AkmHarness.resume`, {@link AMAZONQ_RESUME_FLAG}) — and NOTE:
14
+ * with `--model <m>` for model selection and `--resume` for resume — NOTE:
16
15
  * unlike every other harness's resume, Q's `--resume` is a bare flag that
17
16
  * replays the previous conversation *of the working directory*; it takes no
18
17
  * session id. There is nothing to thread from `workflow_run_units` — akm's own
@@ -55,22 +54,17 @@
55
54
  * - **effort** — stays unconsumed (reserved; the shared request contract's
56
55
  * "no builder consumes it yet" note stays true).
57
56
  *
58
- * NOT registered anywhere: `builders.ts` / `harnesses/index.ts` wiring is a
59
- * follow-up integration task (as is the registry-side capability entry —
60
- * pattern `local-runner`, structuredOutput `none`). Exported standalone so
61
- * that task only adds a registry entry.
57
+ * Registered: `amazonqBuilder` is `AmazonqHarness.agentBuilder`
58
+ * (`./index.ts`), one of the ten harnesses `HARNESS_REGISTRY` constructs
59
+ * (`harnesses/index.ts`); `agent/builders.ts` derives `BUILTIN_BUILDERS` from
60
+ * that registry, so this builder is reachable under the `"amazonq"` platform
61
+ * name without any further wiring. The registry-side capability entry —
62
+ * pattern `local-runner`, structuredOutput `none` — is declared alongside it
63
+ * (`./index.ts`).
62
64
  */
63
- import { assertNotFlag } from "../../agent/builder-shared.js";
64
- import { resolveModel } from "../../agent/model-aliases.js";
65
+ import { assertNotFlag, resolveDispatchModel, } from "../../agent/builder-shared.js";
65
66
  /** Canonical harness/platform id used for model-alias resolution. */
66
67
  export const AMAZONQ_PLATFORM = "amazonq";
67
- /**
68
- * Resume flag per the capability matrix (`--resume`). Exported for the
69
- * integration task's `AkmHarness.resume` registry entry. Bare flag: Q resumes
70
- * the previous conversation of the current working directory and takes NO
71
- * session id value — do not append one after it.
72
- */
73
- export const AMAZONQ_RESUME_FLAG = "--resume";
74
68
  /**
75
69
  * Split a tool policy into individual tool names for `--trust-tools`.
76
70
  * Strings are comma-separated lists; arrays are taken as-is. Structured
@@ -141,7 +135,7 @@ export const amazonqBuilder = {
141
135
  args.push("--trust-all-tools");
142
136
  }
143
137
  if (req.model) {
144
- const resolved = resolveModel(req.model, AMAZONQ_PLATFORM, profile.modelAliases, profile.globalModelAliases);
138
+ const resolved = resolveDispatchModel(req, profile, AMAZONQ_PLATFORM);
145
139
  args.push("--model", resolved);
146
140
  }
147
141
  // No system-prompt / schema flags exist on `q chat` — both travel in the
@@ -13,22 +13,12 @@
13
13
  * that `HARNESS_REGISTRY` registers. Dispatch-only: no native session-log
14
14
  * reader or config importer yet.
15
15
  */
16
+ import { caps } from "../shared.js";
16
17
  import { BaseHarness } from "../types.js";
17
- import { AMAZONQ_RESUME_FLAG, amazonqBuilder } from "./agent-builder.js";
18
+ import { amazonqBuilder } from "./agent-builder.js";
18
19
  import { amazonqResultExtractor } from "./result-extractor.js";
19
- export { AMAZONQ_PLATFORM, AMAZONQ_RESUME_FLAG, amazonqBuilder } from "./agent-builder.js";
20
+ export { AMAZONQ_PLATFORM, amazonqBuilder } from "./agent-builder.js";
20
21
  export { amazonqResultExtractor, stripTerminalFraming } from "./result-extractor.js";
21
- function caps(c) {
22
- return {
23
- sessionLogs: false,
24
- agentDispatch: false,
25
- detection: false,
26
- configImport: false,
27
- runtimeIdentity: false,
28
- v1Migration: false,
29
- ...c,
30
- };
31
- }
32
22
  /**
33
23
  * Amazon Q Developer CLI (`q`).
34
24
  *
@@ -46,10 +36,6 @@ export class AmazonqHarness extends BaseHarness {
46
36
  // No documented structured output: akm injects the schema into the prompt
47
37
  // and extracts embedded JSON from plain-text stdout.
48
38
  structuredOutput = "none";
49
- // Q's `--resume` is a BARE flag (takesSessionId: false): it replays the
50
- // previous conversation of the working directory and takes no session id
51
- // (see AMAZONQ_RESUME_FLAG in ./agent-builder.ts).
52
- resume = { flag: AMAZONQ_RESUME_FLAG, takesSessionId: false };
53
39
  // No `identityEnv`: the matrix lists Q's identity markers as uncertain, and
54
40
  // Q stamps no session var onto child processes.
55
41
  capabilities = caps({
@@ -34,8 +34,7 @@
34
34
  *
35
35
  * The builder's `platform` stays `'claude'` (the canonical harness id).
36
36
  */
37
- import { assertNotFlag, normalizeTools, } from "../../agent/builder-shared.js";
38
- import { resolveModel } from "../../agent/model-aliases.js";
37
+ import { assertNotFlag, normalizeTools, resolveDispatchModel, } from "../../agent/builder-shared.js";
39
38
  /**
40
39
  * Assemble the positional prompt: the task prompt and — when a schema is
41
40
  * requested — the same schema directive the workflow engine's prompt assembly
@@ -67,7 +66,7 @@ export const claudeBuilder = {
67
66
  args.push("--system-prompt", req.systemPrompt);
68
67
  }
69
68
  if (req.model) {
70
- const resolved = resolveModel(req.model, "claude", profile.modelAliases, profile.globalModelAliases);
69
+ const resolved = resolveDispatchModel(req, profile, "claude");
71
70
  args.push("--model", resolved);
72
71
  }
73
72
  if (req.tools) {
@@ -15,9 +15,7 @@
15
15
  */
16
16
  import fs from "node:fs";
17
17
  import path from "node:path";
18
- function homeDir() {
19
- return process.env.HOME ?? process.env.USERPROFILE ?? "";
20
- }
18
+ import { homeDir } from "../shared.js";
21
19
  /**
22
20
  * Imports LLM config from a Claude Code installation.
23
21
  *
@@ -1,6 +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 { caps } from "../shared.js";
4
5
  import { BaseHarness } from "../types.js";
5
6
  import { claudeBuilder } from "./agent-builder.js";
6
7
  import { claudeResultExtractor } from "./result-extractor.js";
@@ -9,17 +10,6 @@ export { claudeBuilder } from "./agent-builder.js";
9
10
  export { claudeCodeImporter } from "./config-import.js";
10
11
  export { claudeResultExtractor } from "./result-extractor.js";
11
12
  export { ClaudeCodeProvider } from "./session-log.js";
12
- function caps(c) {
13
- return {
14
- sessionLogs: false,
15
- agentDispatch: false,
16
- detection: false,
17
- configImport: false,
18
- runtimeIdentity: false,
19
- v1Migration: false,
20
- ...c,
21
- };
22
- }
23
13
  /**
24
14
  * Claude Code.
25
15
  *
@@ -51,8 +41,6 @@ export class ClaudeHarness extends BaseHarness {
51
41
  // but that is a different surface than the dispatch builder — the descriptor
52
42
  // is aligned to what the builder honestly does.)
53
43
  structuredOutput = "native-json";
54
- // `claude --resume <sessionId>` replays a previous session in headless mode.
55
- resume = { flag: "--resume", takesSessionId: true };
56
44
  // Session-id env marker: presence of a concrete session id (not the bare
57
45
  // "running under Claude Code" flag) attributes a run to this harness.
58
46
  identityEnv = ["CLAUDE_SESSION_ID"];
@@ -63,6 +51,5 @@ export class ClaudeHarness extends BaseHarness {
63
51
  detection: true,
64
52
  configImport: true,
65
53
  runtimeIdentity: true,
66
- v1Migration: true,
67
54
  });
68
55
  }