akm-cli 0.9.0-rc.0 → 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 (598) hide show
  1. package/CHANGELOG.md +1283 -22
  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/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -0,0 +1,23 @@
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
+ * Serialized writer queue for `workflow_run_units` (orchestration plan,
6
+ * *Persistence changes*).
7
+ *
8
+ * `withWorkflowRunsRepo` opens a fresh SQLite connection per call, so N
9
+ * parallel units completing at once would contend on SQLite's single writer
10
+ * and burn the 30 s busy_timeout. Bun is single-threaded, so a promise-chained
11
+ * in-process queue is sufficient: every unit write is appended to one chain
12
+ * and executes strictly in enqueue order. Reads and gate evaluation stay OFF
13
+ * this queue — only writes serialize.
14
+ *
15
+ * A failed write rejects its own caller but never wedges the chain.
16
+ */
17
+ let tail = Promise.resolve();
18
+ export function enqueueUnitWrite(fn) {
19
+ const run = tail.then(() => fn());
20
+ // Keep the chain alive regardless of individual outcomes.
21
+ tail = run.then(() => undefined, () => undefined);
22
+ return run;
23
+ }
@@ -0,0 +1,67 @@
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
+ * The `akm workflow` engine gate (`experimental.workflowEngine`, Q-05).
6
+ *
7
+ * Mirrors the shape of `src/commands/improve/autonomy-gate.ts` (D8) for a
8
+ * different failure mode. `akm improve`'s gated lanes have a safe downgrade —
9
+ * skip the lane, keep the rest of the run going — but a workflow step either
10
+ * executes or it does not: there is no partial-execution fallback to degrade
11
+ * into. So this gate REFUSES outright rather than silently skipping: an
12
+ * ungated call throws a classified `ConfigError` naming the exact config key,
13
+ * which the CLI's JSON error envelope (`emitJsonError`, `src/cli/shared.ts`)
14
+ * always routes to stderr with a non-zero exit — in every `--format`, not
15
+ * just `json` — so the refusal is visible and never a silent no-op. (A
16
+ * second, plain-text `warn()` call alongside the throw was deliberately
17
+ * rejected: it would interleave non-JSON text with the JSON error envelope on
18
+ * the SAME stream, corrupting stderr for any `--json` caller — a real defect,
19
+ * not just a test inconvenience.)
20
+ *
21
+ * Gated surfaces:
22
+ * - `akm workflow run` — the native step-execution engine
23
+ * - `akm workflow brief` — the harness-neutral driver protocol (read half)
24
+ * - `akm workflow report` — the harness-neutral driver protocol (write half)
25
+ *
26
+ * Deliberately NOT gated: authoring/linting the unified markdown format and
27
+ * the manual workflow CLI contract (`start`, `next`, `complete`, `status`,
28
+ * `list`, `create`, `resume`, `abandon`) remain stable per STABILITY.md.
29
+ */
30
+ import { ConfigError } from "../../core/errors.js";
31
+ /**
32
+ * The config key an operator sets to enable the workflow engine.
33
+ *
34
+ * Named rather than inlined because it is user-facing text: it goes into the
35
+ * thrown error's message and `akm task doctor`, and those must name the same
36
+ * key as the schema.
37
+ */
38
+ export const WORKFLOW_ENGINE_CONFIG_KEY = "experimental.workflowEngine";
39
+ /**
40
+ * True only when the user has explicitly opted into the workflow engine.
41
+ * Absent, an absent `experimental` section, and an explicit `false` all read
42
+ * as off — the engine is never enabled by inference.
43
+ */
44
+ export function isWorkflowEngineEnabled(config) {
45
+ return config?.experimental?.workflowEngine === true;
46
+ }
47
+ /** The message shown to the user AND matched by tests naming the config key. */
48
+ export function workflowEngineGateMessage(surface) {
49
+ return (`\`akm workflow ${surface}\` is EXPERIMENTAL and refuses to run until ` +
50
+ `\`${WORKFLOW_ENGINE_CONFIG_KEY}\` is set. Run \`akm config set ${WORKFLOW_ENGINE_CONFIG_KEY} true\` to enable it.`);
51
+ }
52
+ /**
53
+ * Refuse a gated workflow-engine surface unless the opt-in is set.
54
+ *
55
+ * `surface` is the human name of the subcommand/action being refused (e.g.
56
+ * `"run"`, `"brief"`, `"create <name>.yaml"`) — it is folded into the thrown
57
+ * error's message so the refusal names both the surface and the exact config
58
+ * key that would enable it. The throw alone is the whole mechanism: every
59
+ * command defined with `defineJsonCommand` routes an uncaught throw through
60
+ * `runWithJsonErrors`/`emitJsonError`, which prints the error to stderr and
61
+ * exits non-zero regardless of `--format` — so this is never a silent no-op.
62
+ */
63
+ export function requireWorkflowEngineEnabled(config, surface) {
64
+ if (isWorkflowEngineEnabled(config))
65
+ return;
66
+ throw new ConfigError(workflowEngineGateMessage(surface), "WORKFLOW_ENGINE_NOT_ENABLED");
67
+ }
@@ -0,0 +1,171 @@
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
+ * Git worktree lifecycle for `isolation: worktree` units (redesign addendum,
6
+ * R2). Parallel file-mutating units on the agent/sdk runners each get a
7
+ * fresh DETACHED worktree of the run's base repository under a run-scoped
8
+ * tmp directory, so concurrent units can never trample each other's working
9
+ * tree. Lifecycle (driven by the native executor per journaled attempt):
10
+ *
11
+ * 1. {@link assertGitWorkTree} — preflight, once per step: a non-git base
12
+ * directory fails the step cleanly before anything dispatches.
13
+ * 2. {@link createUnitWorktree} — `git worktree add --detach` into
14
+ * `<tmp>/akm-worktrees/<runId>/<attemptId>`; the path is journaled on
15
+ * the unit row (`workflow_run_units.worktree_path`, migration 004) and
16
+ * passed to dispatch as the unit's cwd.
17
+ * 3. {@link cleanupUnitWorktree} — after the unit finishes:
18
+ * `git status --porcelain` CLEAN → the worktree is removed;
19
+ * DIRTY → it is RETAINED (the caller logs the path) so uncollected work
20
+ * is never destroyed.
21
+ *
22
+ * What "uncollected work" means (the honest contract): the clean probe is
23
+ * `git status --porcelain` WITHOUT `--ignored`, so it counts tracked-file
24
+ * modifications and untracked *unignored* files, but NOT files the base repo's
25
+ * own `.gitignore` matches (build outputs, caches, logs, dependency dirs such
26
+ * as `node_modules`/`dist`). Those ignored files are DISPOSABLE BY DEFINITION
27
+ * — the repository already declares them regenerable — so a worktree whose only
28
+ * residue is ignored files probes clean and IS removed. This is deliberate:
29
+ * adding `--ignored` would retain a worktree after essentially every unit that
30
+ * ran a package install or a build (the ignored `node_modules`/`dist` tree),
31
+ * blowing up disk under the run-scoped tmp root. Work a unit needs preserved
32
+ * must therefore be tracked or untracked-unignored; anything the workflow
33
+ * repo has chosen to `.gitignore` is treated as throwaway.
34
+ *
35
+ * All git invocations are `spawnSync` (the repo-wide pattern for git
36
+ * shell-outs) with explicit timeouts; this module never throws — every
37
+ * operation returns a result object so the executor maps failures onto its
38
+ * own step/unit failure vocabulary.
39
+ */
40
+ import { spawnSync } from "node:child_process";
41
+ import fs from "node:fs";
42
+ import os from "node:os";
43
+ import path from "node:path";
44
+ const GIT_TIMEOUT_MS = 30_000;
45
+ /** Run one git command; `ok` = exit 0. Never throws (spawn errors → ok: false). */
46
+ function git(cwd, args) {
47
+ const result = spawnSync("git", ["-C", cwd, ...args], { encoding: "utf8", timeout: GIT_TIMEOUT_MS });
48
+ if (result.error) {
49
+ return { ok: false, stdout: "", error: `git ${args[0]} failed to spawn: ${result.error.message}` };
50
+ }
51
+ if (result.status !== 0) {
52
+ const detail = (result.stderr || result.stdout || "").trim();
53
+ return {
54
+ ok: false,
55
+ stdout: result.stdout ?? "",
56
+ error: `git ${args.join(" ")} exited ${result.status}${detail ? `: ${detail}` : ""}`,
57
+ };
58
+ }
59
+ return { ok: true, stdout: result.stdout ?? "" };
60
+ }
61
+ /** True when a usable `git` binary is on PATH (tests skip gracefully without one). */
62
+ export function isGitAvailable() {
63
+ const result = spawnSync("git", ["--version"], { encoding: "utf8", timeout: 5_000 });
64
+ return !result.error && result.status === 0;
65
+ }
66
+ /**
67
+ * Preflight for worktree isolation: `dir` must be inside a git work tree.
68
+ * Returns an error message (for a clean step failure) or undefined when ok.
69
+ * A missing git binary reports as the same clean failure — a workflow that
70
+ * declares isolation cannot run without git.
71
+ */
72
+ export function assertGitWorkTree(dir) {
73
+ const result = git(dir, ["rev-parse", "--is-inside-work-tree"]);
74
+ if (!result.ok) {
75
+ return `"${dir}" is not a git repository (isolation: worktree requires one): ${result.error}`;
76
+ }
77
+ if (result.stdout.trim() !== "true") {
78
+ return `"${dir}" is not inside a git work tree (isolation: worktree requires one).`;
79
+ }
80
+ return undefined;
81
+ }
82
+ /** Journal-safe directory name for a unit attempt id (ids carry `:` / `~`). */
83
+ function sanitizeAttemptId(attemptId) {
84
+ return attemptId.replace(/[^A-Za-z0-9._-]/g, "-");
85
+ }
86
+ /** Run-scoped parent directory for all of one run's unit worktrees. */
87
+ export function runWorktreeRoot(runId) {
88
+ return path.join(os.tmpdir(), "akm-worktrees", runId);
89
+ }
90
+ /**
91
+ * Move a leftover attempt directory aside to `<dest>.retained-<ts>[-n]`
92
+ * (never overwriting an earlier retained copy). Throws on fs errors — the
93
+ * caller maps them onto its result object.
94
+ */
95
+ function moveLeftoverAside(dest) {
96
+ const base = `${dest}.retained-${Date.now()}`;
97
+ let aside = base;
98
+ for (let n = 1; fs.existsSync(aside); n++)
99
+ aside = `${base}-${n}`;
100
+ fs.renameSync(dest, aside);
101
+ return aside;
102
+ }
103
+ /**
104
+ * Create a fresh DETACHED worktree of `baseDir`'s repository at
105
+ * `<tmp>/akm-worktrees/<runId>/<attemptId>` (detached HEAD — no branch is
106
+ * minted, so parallel units cannot collide on branch names).
107
+ *
108
+ * A leftover directory at the attempt path (a RETAINED dirty worktree from a
109
+ * prior invocation, or a crashed attempt's partial state) is handled with the
110
+ * same never-destroy-unverified-work rule as {@link cleanupUnitWorktree}:
111
+ * `git status --porcelain` CLEAN → removed; DIRTY or unverifiable (the probe
112
+ * fails — e.g. a half-created directory that is no longer a valid worktree)
113
+ * → moved aside to `<dest>.retained-<ts>` and reported via
114
+ * `preservedLeftover` so the caller can log where the work went. Either way
115
+ * `git worktree prune` clears the stale registration before re-creating.
116
+ */
117
+ export function createUnitWorktree(baseDir, runId, attemptId) {
118
+ const dest = path.join(runWorktreeRoot(runId), sanitizeAttemptId(attemptId));
119
+ let preservedLeftover;
120
+ try {
121
+ if (fs.existsSync(dest)) {
122
+ const status = git(dest, ["status", "--porcelain"]);
123
+ if (status.ok && status.stdout.trim() === "") {
124
+ fs.rmSync(dest, { recursive: true, force: true });
125
+ }
126
+ else {
127
+ preservedLeftover = moveLeftoverAside(dest);
128
+ }
129
+ git(baseDir, ["worktree", "prune"]);
130
+ }
131
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
132
+ }
133
+ catch (err) {
134
+ return { ok: false, error: `could not prepare worktree directory ${dest}: ${message(err)}` };
135
+ }
136
+ const added = git(baseDir, ["worktree", "add", "--detach", dest]);
137
+ if (!added.ok) {
138
+ return { ok: false, error: `could not create isolation worktree at ${dest}: ${added.error}` };
139
+ }
140
+ return { ok: true, path: dest, ...(preservedLeftover !== undefined ? { preservedLeftover } : {}) };
141
+ }
142
+ /**
143
+ * Post-unit cleanup: remove the worktree when `git status --porcelain` shows
144
+ * it clean; retain it (dirty: true) when the unit left uncommitted work —
145
+ * the caller logs the retained path. Any git failure retains the worktree
146
+ * too (never destroy a tree whose state could not be verified).
147
+ *
148
+ * The probe deliberately omits `--ignored`: a worktree whose only residue is
149
+ * files matched by the base repo's `.gitignore` (build artifacts, caches,
150
+ * logs, `node_modules`) probes clean and IS removed. Those files are disposable
151
+ * by the repo's own declaration; retaining a worktree per build/install would
152
+ * blow up disk. "Uncollected work" the caller preserves is therefore
153
+ * tracked-or-untracked-unignored changes only (module doc).
154
+ */
155
+ export function cleanupUnitWorktree(baseDir, worktreePath) {
156
+ const status = git(worktreePath, ["status", "--porcelain"]);
157
+ if (!status.ok) {
158
+ return { removed: false, dirty: false, error: status.error };
159
+ }
160
+ if (status.stdout.trim() !== "") {
161
+ return { removed: false, dirty: true };
162
+ }
163
+ const removed = git(baseDir, ["worktree", "remove", worktreePath]);
164
+ if (!removed.ok) {
165
+ return { removed: false, dirty: false, error: removed.error };
166
+ }
167
+ return { removed: true, dirty: false };
168
+ }
169
+ function message(err) {
170
+ return err instanceof Error ? err.message : String(err);
171
+ }
@@ -0,0 +1,246 @@
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
+ * Frontend -> unresolved workflow plan compiler (workflow-format-unification).
6
+ *
7
+ * ONE frontend now: {@link compileWorkflowPlan} lowers a parsed unified
8
+ * `WorkflowDocument` (`../parser.ts`) into the same `WorkflowPlanDraft` shape
9
+ * IR v3 has always consumed — the pre-unification split between a linear
10
+ * markdown compiler and a YAML-program compiler is gone. This pass owns the
11
+ * semantic rules the parser deliberately does not check:
12
+ *
13
+ * - every reference string (`map.over` / `route.input` / `inputs[]`) parses
14
+ * against the CLOSED two-root grammar (`program/expressions.ts`);
15
+ * - `steps.<id>` references name an EARLIER step (a producer that has
16
+ * already run when the reference resolves);
17
+ * - `inputs:` entries must reference a STEP OUTPUT, never `params.*` — params
18
+ * are already attached to every unit unconditionally, so naming one as a
19
+ * declared input would be redundant.
20
+ *
21
+ * Node-id convention (stable, unique within a plan):
22
+ * step root → `<stepId>` (unit) or `<stepId>.map` (map)
23
+ * map unit → `<stepId>.unit` (template instantiated per item)
24
+ * gate → `<stepId>.gate`
25
+ *
26
+ * Returns accumulated `WorkflowError`s rather than throwing. Pure and
27
+ * deterministic: the same document always compiles to the same plan.
28
+ */
29
+ import { formatReference, parseReference } from "../program/expressions.js";
30
+ /**
31
+ * Compile a parsed unified workflow document into a frozen-plan-ready graph.
32
+ * `title` is the run-level display title (the asset's canonical name — the
33
+ * format carries no authored title). Assumes the document came out of
34
+ * `parseWorkflow` ok (structure already valid).
35
+ */
36
+ export function compileWorkflowPlan(document, title) {
37
+ const errors = [];
38
+ const allStepIds = new Set(document.steps.map((s) => s.id));
39
+ const earlierStepIds = new Set();
40
+ const steps = [];
41
+ document.steps.forEach((step) => {
42
+ const check = { allStepIds, earlierStepIds, errors };
43
+ if (step.map) {
44
+ checkReferenceField(step.map.over, { ...check, line: step.source.start, label: `Step "${step.id}" map.over` });
45
+ }
46
+ if (step.route) {
47
+ checkReferenceField(step.route.input, {
48
+ ...check,
49
+ line: step.source.start,
50
+ label: `Step "${step.id}" route.input`,
51
+ });
52
+ }
53
+ for (const [index, reference] of (step.inputs ?? []).entries()) {
54
+ checkInputReference(reference, index, {
55
+ ...check,
56
+ line: step.source.start,
57
+ label: `Step "${step.id}" inputs`,
58
+ });
59
+ }
60
+ steps.push(compileStep(step, defaultsOf(document)));
61
+ earlierStepIds.add(step.id);
62
+ });
63
+ if (errors.length > 0)
64
+ return { ok: false, errors };
65
+ const paramNames = document.params ? Object.keys(document.params) : [];
66
+ return {
67
+ ok: true,
68
+ warnings: collectWorkflowWarnings(document),
69
+ plan: {
70
+ title,
71
+ ...(paramNames.length > 0 ? { params: paramNames } : {}),
72
+ ...(document.params && paramNames.length > 0 ? { paramSchemas: document.params } : {}),
73
+ ...(document.budget
74
+ ? {
75
+ budget: {
76
+ ...(document.budget.maxTokens !== undefined ? { maxTokens: document.budget.maxTokens } : {}),
77
+ ...(document.budget.maxUnits !== undefined ? { maxUnits: document.budget.maxUnits } : {}),
78
+ },
79
+ }
80
+ : {}),
81
+ steps,
82
+ },
83
+ };
84
+ }
85
+ function defaultsOf(document) {
86
+ return document.defaults;
87
+ }
88
+ function compileStep(step, defaults) {
89
+ const gate = {
90
+ kind: "gate",
91
+ id: `${step.id}.gate`,
92
+ stepId: step.id,
93
+ // The body `### gate` rubric is carried through as the ONE criterion string
94
+ // — the judge receives the whole section byte-exact (spec §2.4). A step
95
+ // with no rubric has no gate at all (fail-open, criteria: []).
96
+ criteria: step.gateRubric?.text.trim() ? [step.gateRubric.text] : [],
97
+ ...(step.gate?.maxLoops !== undefined ? { maxLoops: step.gate.maxLoops } : {}),
98
+ };
99
+ let root;
100
+ if (step.route === undefined) {
101
+ const instructionsText = step.instructions?.text ?? "";
102
+ if (step.map) {
103
+ root = {
104
+ kind: "map",
105
+ id: `${step.id}.map`,
106
+ over: step.map.over,
107
+ template: compileUnit(step.map.unit, `${step.id}.unit`, instructionsText, defaults, step.inputs, step.source),
108
+ ...(step.map.concurrency !== undefined ? { concurrency: step.map.concurrency } : {}),
109
+ reducer: step.map.reducer ?? "collect",
110
+ source: step.source,
111
+ };
112
+ }
113
+ else {
114
+ root = compileUnit(step.unit, step.id, instructionsText, defaults, step.inputs, step.instructions?.source);
115
+ }
116
+ }
117
+ return {
118
+ stepId: step.id,
119
+ title: step.id,
120
+ sequenceIndex: step.sequenceIndex,
121
+ ...(root ? { root } : {}),
122
+ ...(step.route
123
+ ? {
124
+ route: {
125
+ input: step.route.input,
126
+ when: Object.fromEntries(step.route.branches.map((b) => [b.match, b.stepId])),
127
+ ...(step.route.defaultStepId !== undefined ? { defaultStepId: step.route.defaultStepId } : {}),
128
+ },
129
+ }
130
+ : {}),
131
+ ...(step.output !== undefined ? { outputSchema: step.output } : {}),
132
+ gate,
133
+ };
134
+ }
135
+ /**
136
+ * Lower one source unit into the unresolved structural plan. Instructions are
137
+ * ALWAYS the step's body prose, byte-exact — never templated, never scanned
138
+ * for reference syntax. Engine/model/timeout settings remain on the parsed
139
+ * override bag until the single freeze boundary.
140
+ */
141
+ function compileUnit(unit, id, instructions, defaults, inputs, source) {
142
+ return {
143
+ kind: "unit",
144
+ id,
145
+ instructions,
146
+ templating: "verbatim",
147
+ ...(inputs && inputs.length > 0 ? { inputs: [...inputs] } : {}),
148
+ ...(unit?.output !== undefined ? { schema: unit.output } : {}),
149
+ ...(unit?.retry ? { retry: { max: unit.retry.max, on: [...unit.retry.on] } } : {}),
150
+ onError: unit?.onError ?? defaults?.onError ?? "fail",
151
+ ...(unit?.env ? { env: [...unit.env] } : {}),
152
+ ...(unit?.isolation !== undefined ? { isolation: unit.isolation } : {}),
153
+ ...(source ? { source } : {}),
154
+ };
155
+ }
156
+ /** Validate a whole-value reference field (`map.over`, `route.input`). */
157
+ function checkReferenceField(text, check) {
158
+ const parsed = parseReference(text);
159
+ if (!parsed.ok) {
160
+ check.errors.push({ line: check.line, message: `${check.label}: ${parsed.message}` });
161
+ return;
162
+ }
163
+ if (parsed.expr.kind === "stepOutput" && !check.earlierStepIds.has(parsed.expr.stepId)) {
164
+ const why = check.allStepIds.has(parsed.expr.stepId)
165
+ ? `step "${parsed.expr.stepId}" does not come before this step — references must name an earlier step (a producer that has already run)`
166
+ : `"${parsed.expr.stepId}" is not a step in this workflow`;
167
+ check.errors.push({
168
+ line: check.line,
169
+ message: `${check.label}: "${formatReference(parsed.expr)}" cannot be resolved — ${why}.`,
170
+ });
171
+ }
172
+ }
173
+ /** Validate one `inputs[]` entry: must be a step-output reference to an earlier step. */
174
+ function checkInputReference(text, index, check) {
175
+ const parsed = parseReference(text);
176
+ if (!parsed.ok) {
177
+ check.errors.push({ line: check.line, message: `${check.label}[${index}]: ${parsed.message}` });
178
+ return;
179
+ }
180
+ if (parsed.expr.kind === "param") {
181
+ check.errors.push({
182
+ line: check.line,
183
+ message: `${check.label}[${index}]: "${formatReference(parsed.expr)}" names a param, not a step output — ` +
184
+ `params are already attached to every unit, so declaring one as an input is redundant. "inputs:" only ` +
185
+ `names step outputs (steps.<id>.output...).`,
186
+ });
187
+ return;
188
+ }
189
+ if (!check.earlierStepIds.has(parsed.expr.stepId)) {
190
+ const why = check.allStepIds.has(parsed.expr.stepId)
191
+ ? `step "${parsed.expr.stepId}" does not come before this step — references must name an earlier step (a producer that has already run)`
192
+ : `"${parsed.expr.stepId}" is not a step in this workflow`;
193
+ check.errors.push({
194
+ line: check.line,
195
+ message: `${check.label}[${index}]: "${formatReference(parsed.expr)}" cannot be resolved — ${why}.`,
196
+ });
197
+ }
198
+ }
199
+ // ── Non-fatal warnings ───────────────────────────────────────────────────────
200
+ /**
201
+ * Collect the document's non-fatal WARNINGS — advisories that never fail
202
+ * compilation, never change the frozen plan or its hash, and are surfaced by
203
+ * `workflow validate` (human + JSON) and as `warn()` lines at `workflow start`.
204
+ *
205
+ * A. A unit/map step with NO step-level `output:` schema carries its units'
206
+ * raw results as an untyped artifact — permitted, but worth flagging.
207
+ * B. A `params.<name>` reference (in `map.over`/`route.input`) to an
208
+ * UNDECLARED param, but ONLY when the document declares a `params:`
209
+ * block — a likely typo. Prose can no longer carry param references at
210
+ * all (it is never scanned), so this warning's surface shrinks to the
211
+ * two whole-value fields that can legally contain one.
212
+ */
213
+ export function collectWorkflowWarnings(document) {
214
+ const warnings = [];
215
+ const declaredParams = document.params ? new Set(Object.keys(document.params)) : undefined;
216
+ for (const step of document.steps) {
217
+ if ((step.map || step.route === undefined) && step.output === undefined) {
218
+ warnings.push({
219
+ line: step.source.start,
220
+ message: `Step "${step.id}" declares no \`output:\` schema — its unit results are carried as an untyped ` +
221
+ `artifact (permitted). Add an \`output:\` JSON Schema to type and validate the step artifact.`,
222
+ });
223
+ }
224
+ if (declaredParams) {
225
+ const declaredList = [...declaredParams].join(", ");
226
+ const scan = (text, label) => {
227
+ if (!text)
228
+ return;
229
+ const parsed = parseReference(text);
230
+ if (!parsed.ok || parsed.expr.kind !== "param" || declaredParams.has(parsed.expr.name))
231
+ return;
232
+ warnings.push({
233
+ line: step.source.start,
234
+ message: `${label}: "${formatReference(parsed.expr)}" references a param not declared in \`params:\` ` +
235
+ `(declared: ${declaredList || "none"}) — likely a typo. An undeclared param supplied at start still ` +
236
+ `resolves at run time.`,
237
+ });
238
+ };
239
+ if (step.map)
240
+ scan(step.map.over, `Step "${step.id}" map.over`);
241
+ if (step.route)
242
+ scan(step.route.input, `Step "${step.id}" route.input`);
243
+ }
244
+ }
245
+ return warnings;
246
+ }