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,181 @@
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
+ const GRAMMAR_HINT = "allowed forms: params.<name>, steps.<id>.output(.<ident>|[<int>])*";
5
+ /**
6
+ * Parse a bare reference string (a whole-value frontmatter field, already
7
+ * delimiter-free: `map.over`, `route.input`, or one entry of `inputs[]`).
8
+ */
9
+ export function parseReference(source) {
10
+ const text = source.trim();
11
+ if (text === "")
12
+ return { ok: false, message: `Empty reference; ${GRAMMAR_HINT}.` };
13
+ const root = readIdent(text, 0);
14
+ if (!root) {
15
+ return { ok: false, message: `Invalid reference "${text}" — must start with an identifier; ${GRAMMAR_HINT}.` };
16
+ }
17
+ switch (root.name) {
18
+ case "params": {
19
+ if (text[root.end] !== ".") {
20
+ return { ok: false, message: `"params" requires a name: params.<name> (got "${text}").` };
21
+ }
22
+ const name = readIdent(text, root.end + 1);
23
+ if (!name) {
24
+ return { ok: false, message: `Invalid param name after "params." in "${text}".` };
25
+ }
26
+ if (name.end !== text.length) {
27
+ return {
28
+ ok: false,
29
+ message: `"params.${name.name}" takes exactly one name — found trailing "${text.slice(name.end)}".`,
30
+ };
31
+ }
32
+ return { ok: true, expr: { kind: "param", name: name.name } };
33
+ }
34
+ case "steps": {
35
+ if (text[root.end] !== ".") {
36
+ return { ok: false, message: `"steps" requires a step id: steps.<id>.output (got "${text}").` };
37
+ }
38
+ const stepId = readIdent(text, root.end + 1);
39
+ if (!stepId) {
40
+ return { ok: false, message: `Invalid step id after "steps." in "${text}".` };
41
+ }
42
+ if (text[stepId.end] !== ".") {
43
+ return { ok: false, message: `"steps.${stepId.name}" must be followed by ".output" (got "${text}").` };
44
+ }
45
+ const output = readIdent(text, stepId.end + 1);
46
+ if (!output || output.name !== "output") {
47
+ return { ok: false, message: `Expected ".output" after "steps.${stepId.name}" in "${text}".` };
48
+ }
49
+ const path = parsePath(text, output.end);
50
+ if (!path.ok)
51
+ return { ok: false, message: path.message };
52
+ return { ok: true, expr: { kind: "stepOutput", stepId: stepId.name, path: path.path } };
53
+ }
54
+ default:
55
+ return { ok: false, message: `Unknown root "${root.name}" in "${text}"; ${GRAMMAR_HINT}.` };
56
+ }
57
+ }
58
+ /** `<ident>` is `[A-Za-z_][A-Za-z0-9_-]*`. Returns null when no ident starts at `start`. */
59
+ function readIdent(text, start) {
60
+ if (start >= text.length || !/[A-Za-z_]/.test(text[start]))
61
+ return null;
62
+ let end = start + 1;
63
+ while (end < text.length && /[A-Za-z0-9_-]/.test(text[end]))
64
+ end++;
65
+ return { name: text.slice(start, end), end };
66
+ }
67
+ /** Parse `( .<ident> | [<non-negative int>] )*` from `start` to end of text. */
68
+ function parsePath(text, start) {
69
+ const path = [];
70
+ let i = start;
71
+ while (i < text.length) {
72
+ const char = text[i];
73
+ if (char === ".") {
74
+ const ident = readIdent(text, i + 1);
75
+ if (!ident) {
76
+ return { ok: false, message: `Invalid path segment after "." at position ${i} in "${text}".` };
77
+ }
78
+ path.push(ident.name);
79
+ i = ident.end;
80
+ }
81
+ else if (char === "[") {
82
+ let j = i + 1;
83
+ while (j < text.length && /[0-9]/.test(text[j]))
84
+ j++;
85
+ if (j === i + 1 || text[j] !== "]") {
86
+ return {
87
+ ok: false,
88
+ message: `Invalid indexer at position ${i} in "${text}" — expected [<non-negative integer>].`,
89
+ };
90
+ }
91
+ path.push(Number.parseInt(text.slice(i + 1, j), 10));
92
+ i = j + 1;
93
+ }
94
+ else {
95
+ return { ok: false, message: `Unexpected character "${char}" at position ${i} in "${text}".` };
96
+ }
97
+ }
98
+ return { ok: true, path };
99
+ }
100
+ // ── Resolution ───────────────────────────────────────────────────────────────
101
+ /**
102
+ * Resolve a single reference to its RAW value for whole-value contexts
103
+ * (`map.over`, `route.input`, `inputs[]`): arrays stay arrays, objects stay
104
+ * objects. null/undefined values and missing paths are errors.
105
+ */
106
+ export function resolveReference(expr, scope) {
107
+ const reference = formatReference(expr);
108
+ const fail = (message) => ({ ok: false, error: { reference, message } });
109
+ switch (expr.kind) {
110
+ case "param": {
111
+ if (!Object.hasOwn(scope.params, expr.name)) {
112
+ return fail(`${reference} is not defined in the run's params.`);
113
+ }
114
+ return finish(scope.params[expr.name], reference, fail);
115
+ }
116
+ case "stepOutput": {
117
+ if (!Object.hasOwn(scope.stepOutputs, expr.stepId)) {
118
+ return fail(`steps.${expr.stepId}.output is not available — step "${expr.stepId}" has no recorded output.`);
119
+ }
120
+ let current = scope.stepOutputs[expr.stepId];
121
+ let walked = `steps.${expr.stepId}.output`;
122
+ for (const segment of expr.path) {
123
+ if (typeof segment === "number") {
124
+ if (!Array.isArray(current)) {
125
+ return fail(`${walked} is not an array — cannot resolve index [${segment}].`);
126
+ }
127
+ if (segment >= current.length) {
128
+ return fail(`${walked}[${segment}] is out of bounds (array length ${current.length}).`);
129
+ }
130
+ current = current[segment];
131
+ walked += `[${segment}]`;
132
+ }
133
+ else {
134
+ if (typeof current !== "object" || current === null || Array.isArray(current)) {
135
+ return fail(`${walked} is not an object — cannot resolve property "${segment}".`);
136
+ }
137
+ if (!Object.hasOwn(current, segment)) {
138
+ return fail(`${walked}.${segment} is missing (no such property, resolving ${reference}).`);
139
+ }
140
+ current = current[segment];
141
+ walked += `.${segment}`;
142
+ }
143
+ }
144
+ return finish(current, reference, fail);
145
+ }
146
+ }
147
+ }
148
+ /**
149
+ * Resolve a bare reference STRING directly (parse + resolve in one call) —
150
+ * the shape every whole-value frontmatter position (`map.over`, `route.input`,
151
+ * one entry of `inputs[]`) actually needs.
152
+ */
153
+ export function resolveReferenceString(text, scope) {
154
+ const parsed = parseReference(text);
155
+ if (!parsed.ok) {
156
+ return { ok: false, error: { reference: text, message: parsed.message } };
157
+ }
158
+ return resolveReference(parsed.expr, scope);
159
+ }
160
+ function finish(value, reference, fail) {
161
+ if (value === undefined)
162
+ return fail(`${reference} resolved to undefined.`);
163
+ if (value === null)
164
+ return fail(`${reference} resolved to null.`);
165
+ return { ok: true, value };
166
+ }
167
+ // ── Introspection helpers ────────────────────────────────────────────────────
168
+ /** Canonical source spelling of a reference, e.g. `steps.review.output.files[2].name`. */
169
+ export function formatReference(expr) {
170
+ switch (expr.kind) {
171
+ case "param":
172
+ return `params.${expr.name}`;
173
+ case "stepOutput": {
174
+ let text = `steps.${expr.stepId}.output`;
175
+ for (const segment of expr.path) {
176
+ text += typeof segment === "number" ? `[${segment}]` : `.${segment}`;
177
+ }
178
+ return text;
179
+ }
180
+ }
181
+ }
@@ -0,0 +1,51 @@
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
+ /** How a map step folds its per-item unit results into the step artifact. */
5
+ export const PROGRAM_REDUCERS = ["collect", "vote"];
6
+ /** Failure policy: fail the step on first unit failure, or record and go on. */
7
+ export const PROGRAM_ON_ERROR = ["fail", "continue"];
8
+ /** Filesystem isolation for file-mutating units. */
9
+ export const PROGRAM_ISOLATION_KINDS = ["none", "worktree"];
10
+ /**
11
+ * `retry.on` vocabulary — exactly the persisted `AgentFailureReason` taxonomy
12
+ * from `src/integrations/agent/spawn.ts`. The `satisfies` clause fails the
13
+ * typecheck if spawn.ts adds/renames a reason without this list (and the JSON
14
+ * Schema, via the drift test) being updated.
15
+ */
16
+ const RETRY_REASON_SET = {
17
+ timeout: true,
18
+ spawn_failed: true,
19
+ non_zero_exit: true,
20
+ parse_error: true,
21
+ cooldown: true,
22
+ llm_rate_limit: true,
23
+ llm_content_filter: true,
24
+ llm_invalid_json: true,
25
+ content_policy_reject: true,
26
+ unsupported_type: true,
27
+ no_change: true,
28
+ aborted: true,
29
+ };
30
+ export const PROGRAM_RETRY_REASONS = Object.keys(RETRY_REASON_SET);
31
+ /**
32
+ * Step ids: `[A-Za-z_][A-Za-z0-9_-]*` (also pinned in the JSON Schema) — the
33
+ * ONE id grammar for the unified format (workflow-format-unification, spec
34
+ * §2.2). This is EXACTLY the `<ident>` grammar `readIdent` accepts in
35
+ * `program/expressions.ts` for `steps.<id>.output` references: a
36
+ * letter/underscore first char, then letters/digits/underscores/dashes, and
37
+ * NO dots (the expression parser treats `.` as the `.output` path separator,
38
+ * so a dotted id could never be addressed). Keeping step ids inside the
39
+ * addressable grammar guarantees every step can be referenced from map
40
+ * inputs, routes, and `inputs:` without renaming.
41
+ *
42
+ * Forbidding dots additionally keeps the engine's internal gate-row node id
43
+ * `<stepId>.gate` collision-free: no user step id can contain a dot, so it can
44
+ * never equal another step's `<stepId>.gate` synthetic id.
45
+ */
46
+ export const PROGRAM_STEP_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*$/;
47
+ /**
48
+ * Param names must be `params.<ident>`-addressable, so they are plain
49
+ * identifiers (no dots/dashes).
50
+ */
51
+ export const PROGRAM_PARAM_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -2,18 +2,16 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  /**
5
- * Show + indexing renderer for workflow assets.
6
- *
7
- * Reads the markdown via `parseWorkflow` and projects the validated
8
- * `WorkflowDocument` down to the public `ShowResponse` shape (which still
9
- * uses the flat `WorkflowStepDefinition` type for backwards compatibility)
10
- * and into search hints for the indexer.
5
+ * Show + indexing renderer for the unified workflow asset (workflow-format-
6
+ * unification). One format now: reads the frontmatter+body document via
7
+ * `parseWorkflow` and projects the validated `WorkflowDocument` down to the
8
+ * public `ShowResponse` shape and into search hints for the indexer,
9
+ * including a compact per-step orchestration summary (engine/model,
10
+ * `map.over` reference, route table) when the step declares one.
11
11
  */
12
- import { makeAssetRef } from "../core/asset/asset-ref.js";
12
+ import { displayRef } from "../core/asset/resolve-ref.js";
13
13
  import { UsageError } from "../core/errors.js";
14
- import { registerMetadataContributor } from "../indexer/passes/metadata-contributors.js";
15
14
  import { parseWorkflow } from "./parser.js";
16
- import { cacheWorkflowDocument } from "./runtime/document-cache.js";
17
15
  function shellQuote(value) {
18
16
  return `'${value.replace(/'/g, `'\\''`)}'`;
19
17
  }
@@ -34,53 +32,110 @@ function loadDocument(ctx) {
34
32
  const summary = result.errors.map((e) => `${ctx.relPath}:${e.line} — ${e.message}`).join("\n");
35
33
  throw new UsageError(`Workflow has errors:\n${summary}`);
36
34
  }
35
+ /**
36
+ * The instruction text a step contributes to the flat step projection. A
37
+ * route step has no body requirement, so a deterministic description of the
38
+ * routing table stands in when it declares no section (the spine still needs
39
+ * a non-empty instructions string).
40
+ */
41
+ function stepInstructions(step) {
42
+ if (step.instructions)
43
+ return step.instructions.text;
44
+ if (step.route) {
45
+ const branches = step.route.branches.map((b) => `"${b.match}" -> ${b.stepId}`);
46
+ if (step.route.defaultStepId !== undefined)
47
+ branches.push(`default -> ${step.route.defaultStepId}`);
48
+ return `Route on ${step.route.input}: ${branches.join(", ")}.`;
49
+ }
50
+ return "";
51
+ }
52
+ /** Project the `params` block into the flat `WorkflowParameter` list. */
53
+ function projectParameters(document) {
54
+ if (!document.params)
55
+ return undefined;
56
+ const parameters = Object.entries(document.params).map(([name, schema]) => {
57
+ const description = schema.description;
58
+ return { name, ...(typeof description === "string" && description !== "" ? { description } : {}) };
59
+ });
60
+ return parameters.length > 0 ? parameters : undefined;
61
+ }
62
+ /**
63
+ * Compact, show-facing orchestration summary for one step. Field mapping:
64
+ * `engine`/`model`/`timeoutMs` merge the run-level `defaults` exactly like the
65
+ * compiler does (per-unit override wins), `fanOut.over` carries the raw
66
+ * reference string, and `route` carries the explicit input + branch table.
67
+ * Returns undefined when the step declares nothing worth summarizing.
68
+ */
69
+ function summarizeStepOrchestration(step, defaults) {
70
+ const unit = step.unit ?? step.map?.unit;
71
+ const engine = unit?.engine ?? defaults?.engine;
72
+ const model = unit?.model ?? defaults?.model;
73
+ const timeoutMs = unit?.timeoutMs !== undefined ? unit.timeoutMs : defaults?.timeoutMs;
74
+ const summary = {
75
+ ...(engine !== undefined ? { engine } : {}),
76
+ ...(model !== undefined ? { model } : {}),
77
+ ...(timeoutMs !== undefined ? { timeoutMs } : {}),
78
+ ...(step.map
79
+ ? {
80
+ fanOut: {
81
+ over: step.map.over,
82
+ ...(step.map.concurrency !== undefined ? { concurrency: step.map.concurrency } : {}),
83
+ reducer: step.map.reducer ?? "collect",
84
+ },
85
+ }
86
+ : {}),
87
+ ...(unit?.output !== undefined || step.output !== undefined ? { hasSchema: true } : {}),
88
+ ...(unit?.env !== undefined ? { env: [...unit.env] } : {}),
89
+ ...(step.route
90
+ ? {
91
+ route: {
92
+ input: step.route.input,
93
+ branches: step.route.branches.map((b) => ({ match: b.match, stepId: b.stepId })),
94
+ ...(step.route.defaultStepId !== undefined ? { defaultStepId: step.route.defaultStepId } : {}),
95
+ },
96
+ }
97
+ : {}),
98
+ };
99
+ return Object.keys(summary).length > 0 ? summary : undefined;
100
+ }
101
+ function projectStepDefinitions(document) {
102
+ return document.steps.map((step) => {
103
+ const orchestration = summarizeStepOrchestration(step, document.defaults);
104
+ return {
105
+ id: step.id,
106
+ // No titles anywhere in the unified format — a step IS its id.
107
+ title: step.id,
108
+ instructions: stepInstructions(step),
109
+ ...(step.gateRubric?.text.trim() ? { completionCriteria: [step.gateRubric.text] } : {}),
110
+ sequenceIndex: step.sequenceIndex,
111
+ ...(orchestration ? { orchestration } : {}),
112
+ };
113
+ });
114
+ }
37
115
  export const workflowMdRenderer = {
38
116
  name: "workflow-md",
39
117
  buildShowResponse(ctx) {
40
118
  const name = deriveName(ctx);
41
119
  const doc = loadDocument(ctx);
42
- const ref = makeAssetRef("workflow", name, ctx.origin);
120
+ // WI-8.5b (display flip): the `akm workflow next <ref>` action is DISPLAY
121
+ // output — its spelling follows the D-R5 display rule (`displayRef`). A
122
+ // primary/default-bundle workflow renders the SHORT conceptId
123
+ // (`workflows/<name>`); a named source qualifies it as
124
+ // (`<bundle>//workflows/<name>`).
125
+ const ref = displayRef({ type: "workflow", name, bundleId: ctx.origin }, ctx.defaultBundle);
126
+ const parameters = projectParameters(doc);
43
127
  return {
44
128
  type: "workflow",
45
129
  name,
46
130
  path: ctx.absPath,
47
131
  action: buildWorkflowAction(ref),
132
+ ...(doc.preamble ? { content: doc.preamble } : {}),
48
133
  description: doc.description,
49
- workflowTitle: doc.title,
50
- parameters: doc.parameters?.map((p) => p.name),
51
- workflowParameters: doc.parameters?.map((p) => ({ name: p.name, description: p.description })),
52
- steps: doc.steps.map((s) => ({
53
- id: s.id,
54
- title: s.title,
55
- instructions: s.instructions.text,
56
- ...(s.completionCriteria ? { completionCriteria: s.completionCriteria.map((c) => c.text) } : {}),
57
- sequenceIndex: s.sequenceIndex,
58
- })),
134
+ // No authored title in the unified format — the asset's human name is
135
+ // its `description`/H1 like any other asset; this is its canonical name.
136
+ workflowTitle: name,
137
+ ...(parameters ? { parameters: parameters.map((p) => p.name), workflowParameters: parameters } : {}),
138
+ steps: projectStepDefinitions(doc),
59
139
  };
60
140
  },
61
141
  };
62
- registerMetadataContributor({
63
- name: "workflow-document-metadata",
64
- appliesTo: ({ rendererName }) => rendererName === "workflow-md",
65
- contribute(entry, { renderContext }) {
66
- const doc = loadDocument(renderContext);
67
- const hints = new Set(entry.searchHints ?? []);
68
- hints.add(doc.title);
69
- for (const step of doc.steps) {
70
- hints.add(step.title);
71
- hints.add(step.id);
72
- hints.add(step.instructions.text);
73
- for (const criterion of step.completionCriteria ?? []) {
74
- hints.add(criterion.text);
75
- }
76
- }
77
- entry.searchHints = Array.from(hints).filter(Boolean);
78
- if (doc.parameters?.length) {
79
- entry.parameters = doc.parameters.map((p) => ({
80
- name: p.name,
81
- ...(p.description ? { description: p.description } : {}),
82
- }));
83
- }
84
- cacheWorkflowDocument(entry, doc);
85
- },
86
- });
@@ -0,0 +1,22 @@
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
+ export const WORKFLOW_MAX_PLAN_BYTES = 2 * 1024 * 1024;
5
+ export const WORKFLOW_MAX_SOURCE_BYTES = 1024 * 1024;
6
+ export const WORKFLOW_MAX_STEPS = 256;
7
+ export const WORKFLOW_MAX_ENGINES = 64;
8
+ export const WORKFLOW_MAX_PARAMS = 128;
9
+ export const WORKFLOW_MAX_ROUTE_BRANCHES = 256;
10
+ export const WORKFLOW_MAX_INSTRUCTION_BYTES = 256 * 1024;
11
+ export const WORKFLOW_MAX_SCHEMA_BYTES = 256 * 1024;
12
+ export const WORKFLOW_MAX_EXTRA_PARAMS_BYTES = 64 * 1024;
13
+ export const WORKFLOW_MAX_JSON_DEPTH = 64;
14
+ export const WORKFLOW_MAX_MAP_EXPANSION = 10_000;
15
+ /** Max declared `inputs:` reference strings on one unit/map step. */
16
+ export const WORKFLOW_MAX_INPUTS = 64;
17
+ export function utf8Bytes(value) {
18
+ return Buffer.byteLength(value, "utf8");
19
+ }
20
+ export function jsonBytes(value) {
21
+ return utf8Bytes(JSON.stringify(value));
22
+ }
@@ -11,14 +11,42 @@
11
11
  * already exposes via the environment.
12
12
  *
13
13
  * Resolution is best-effort and environment-driven:
14
- * - harness: AKM_AGENT_HARNESS, else inferred from a known harness env var.
14
+ * - harness: AKM_AGENT_HARNESS, else inferred from a harness session-id
15
+ * env var (`identityEnv`), else from a harness presence flag
16
+ * (`presenceEnv`).
15
17
  * - sessionId: AKM_SESSION_ID, else the harness-native session env var.
18
+ * Presence flags NEVER contribute a session id — their values
19
+ * (`CODEX_SANDBOX=seatbelt`, `GEMINI_CLI=1`) are modes/flags,
20
+ * not sessions, and must not be persisted as agent_session_id.
16
21
  *
17
22
  * Explicit values passed to `startWorkflowRun` always win over the environment.
18
23
  *
24
+ * The harness-native markers are DERIVED from `HARNESS_REGISTRY` (plan §"Kill
25
+ * registry drift", P2): each harness declares its session-id env vars via
26
+ * `identityEnv` and its presence-only flags via `presenceEnv`, so adding a
27
+ * harness never touches this module. Only the `AKM_*` explicit-override vars
28
+ * are non-registry (they are akm's own, not any harness's) and stay hardcoded
29
+ * here.
30
+ *
19
31
  * @module workflows/agent-identity
20
32
  */
21
- import { denormalizeRuntimeIdentity } from "../../integrations/harnesses/index.js";
33
+ import { denormalizeRuntimeIdentity, HARNESS_REGISTRY } from "../../integrations/harnesses/index.js";
34
+ /**
35
+ * Derive a marker table from one registry env-var field, ordered by canonical
36
+ * id. The sort keeps the pre-derivation precedence byte-identical ('claude'
37
+ * before 'opencode' — the old if/else chain's order) and independent of
38
+ * `HARNESS_REGISTRY` declaration order, which is pinned for JSON-schema enum
39
+ * stability, not detection precedence.
40
+ */
41
+ function deriveMarkers(pick) {
42
+ return HARNESS_REGISTRY.filter((h) => (pick(h)?.length ?? 0) > 0)
43
+ .map((h) => ({ harnessId: h.id, envKeys: pick(h) ?? [] }))
44
+ .sort((a, b) => a.harnessId.localeCompare(b.harnessId));
45
+ }
46
+ /** Session-id-bearing markers — usable for BOTH harness inference and sessionId. */
47
+ const SESSION_MARKERS = deriveMarkers((h) => h.identityEnv);
48
+ /** Presence-only flags — harness inference ONLY; their values are never a session id. */
49
+ const PRESENCE_MARKERS = deriveMarkers((h) => h.presenceEnv);
22
50
  function firstNonEmpty(env, keys) {
23
51
  for (const key of keys) {
24
52
  const value = env[key];
@@ -37,20 +65,37 @@ export function resolveAgentIdentity(env = process.env) {
37
65
  // Explicit override always wins.
38
66
  let harness = firstNonEmpty(env, ["AKM_AGENT_HARNESS"]);
39
67
  if (!harness) {
40
- // Infer the harness from a harness-specific *session* env var. We only
41
- // infer when a concrete session id is present: the bare "this process is
42
- // Claude Code" flag does not mean a given run is owned by an agent session,
43
- // so it must not silently stamp identity onto manual CLI invocations.
44
- if (firstNonEmpty(env, ["CLAUDE_SESSION_ID"])) {
45
- // Runtime identity for Claude Code is "claude-code" (vs the canonical
46
- // config id "claude"). Derived from the unified registry's bridge (#562)
47
- // so the persisted runtime string can't drift — still emits "claude-code".
48
- harness = denormalizeRuntimeIdentity("claude");
68
+ // Infer the harness from a harness-specific *session* env var first
69
+ // (registry `identityEnv` markers). A concrete session id is the
70
+ // strongest evidence of the immediate driver, so it outranks any
71
+ // presence flag — e.g. opencode launched inside a codex sandbox
72
+ // (OPENCODE_SESSION_ID + CODEX_SANDBOX) attributes to opencode.
73
+ for (const marker of SESSION_MARKERS) {
74
+ if (firstNonEmpty(env, marker.envKeys)) {
75
+ // Report the harness's RUNTIME identity (e.g. canonical 'claude' →
76
+ // 'claude-code') via the registry's #562 bridge so the persisted
77
+ // runtime string can't drift.
78
+ harness = denormalizeRuntimeIdentity(marker.harnessId);
79
+ break;
80
+ }
49
81
  }
50
- else if (firstNonEmpty(env, ["OPENCODE_SESSION_ID"])) {
51
- harness = denormalizeRuntimeIdentity("opencode");
82
+ }
83
+ if (!harness) {
84
+ // Fall back to presence-only flags (registry `presenceEnv`). These are
85
+ // stamped by the harness on its OWN child processes (CODEX_SANDBOX,
86
+ // GEMINI_CLI=1), so they cannot mis-attribute manual CLI invocations —
87
+ // but they carry no session id, so sessionId stays null below.
88
+ for (const marker of PRESENCE_MARKERS) {
89
+ if (firstNonEmpty(env, marker.envKeys)) {
90
+ harness = denormalizeRuntimeIdentity(marker.harnessId);
91
+ break;
92
+ }
52
93
  }
53
94
  }
54
- const sessionId = firstNonEmpty(env, ["AKM_SESSION_ID", "CLAUDE_SESSION_ID", "OPENCODE_SESSION_ID"]);
95
+ // Session id: the explicit AKM override first, then the session-id-bearing
96
+ // registry markers in the same precedence order as harness inference (so
97
+ // harness and session id agree when multiple harness env vars are present).
98
+ // Presence flags are deliberately excluded — their values are not sessions.
99
+ const sessionId = firstNonEmpty(env, ["AKM_SESSION_ID", ...SESSION_MARKERS.flatMap((m) => [...m.envKeys])]);
55
100
  return { harness, sessionId };
56
101
  }
@@ -5,7 +5,7 @@
5
5
  * Agent check-in: a no-background-thread "continue" nudge for stalled workflow
6
6
  * runs (#506).
7
7
  *
8
- * The design decision (see docs/technical/workflow-agent-checkin-adr.md)
8
+ * The design decision (the workflow-agent check-in ADR)
9
9
  * reconciles #506 (file/command-loop signal) with #501 (background thread) in
10
10
  * favour of the former. There is intentionally NO timer or resident process
11
11
  * here. Arming a check-in writes a timestamp (`checkin_armed_at`) on the run
@@ -0,0 +1,131 @@
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
+ import { UsageError } from "../../core/errors.js";
5
+ import { decodeCanonicalPlan } from "../ir/plan-hash.js";
6
+ import { WORKFLOW_IR_VERSION } from "../ir/schema.js";
7
+ /** Validate that a live run carries exactly the current frozen-plan format. */
8
+ export function classifyWorkflowRunPlan(row) {
9
+ const runId = row.id ?? "(unknown)";
10
+ if (!row.plan_json) {
11
+ return {
12
+ support: "missing-plan",
13
+ irVersion: row.plan_ir_version ?? null,
14
+ error: `Workflow run ${runId} has no frozen workflow plan.`,
15
+ };
16
+ }
17
+ if (row.plan_ir_version !== null &&
18
+ row.plan_ir_version !== undefined &&
19
+ row.plan_ir_version !== WORKFLOW_IR_VERSION) {
20
+ return {
21
+ support: "unsupported-version",
22
+ irVersion: row.plan_ir_version,
23
+ error: `Workflow run ${runId} uses unsupported workflow IR version ${row.plan_ir_version}; this runtime requires version ${WORKFLOW_IR_VERSION}.`,
24
+ };
25
+ }
26
+ if (row.plan_ir_version !== WORKFLOW_IR_VERSION) {
27
+ return {
28
+ support: "corrupt-plan",
29
+ irVersion: null,
30
+ error: `Workflow run ${runId} does not declare workflow IR version ${WORKFLOW_IR_VERSION}.`,
31
+ };
32
+ }
33
+ try {
34
+ return {
35
+ support: "supported",
36
+ irVersion: WORKFLOW_IR_VERSION,
37
+ plan: decodeCanonicalPlan(runId, row.plan_json, row.plan_hash),
38
+ };
39
+ }
40
+ catch (cause) {
41
+ return {
42
+ support: "corrupt-plan",
43
+ irVersion: WORKFLOW_IR_VERSION,
44
+ error: cause instanceof Error ? cause.message : String(cause),
45
+ };
46
+ }
47
+ }
48
+ /** Reject any operation that requires a valid current frozen plan. */
49
+ export function requireExecutableWorkflowPlan(row) {
50
+ const classified = classifyWorkflowRunPlan(row);
51
+ if (classified.support === "supported")
52
+ return classified.plan;
53
+ throw new UsageError(classified.error, "INVALID_JSON_ARGUMENT");
54
+ }
55
+ /** Project persisted spine rows from the decoded plan, never from the mutable source asset. */
56
+ export function frozenStepRows(plan) {
57
+ return plan.steps.map((step) => ({
58
+ stepId: step.stepId,
59
+ stepTitle: step.title,
60
+ instructions: step.root
61
+ ? step.root.kind === "map"
62
+ ? step.root.template.instructions
63
+ : step.root.instructions
64
+ : routeInstructions(step.route),
65
+ completionJson: step.gate.criteria.length > 0 ? JSON.stringify(step.gate.criteria) : null,
66
+ sequenceIndex: step.sequenceIndex,
67
+ }));
68
+ }
69
+ /** Verify the durable spine still agrees with the decoded/hash-verified plan before any mutation. */
70
+ export function assertWorkflowSpineMatchesPlan(plan, run, rows) {
71
+ const expected = frozenStepRows(plan);
72
+ if (rows.length !== expected.length)
73
+ corruptSpine(run.id, "step count differs from the frozen plan");
74
+ for (let index = 0; index < expected.length; index++) {
75
+ const actual = rows[index];
76
+ const planned = expected[index];
77
+ // The length check above (corruptSpine returns `never`) guarantees both are
78
+ // present; the guard narrows them and preserves the "missing row" message.
79
+ if (!actual || !planned) {
80
+ corruptSpine(run.id, `step row ${index} differs from the frozen plan (missing row)`);
81
+ }
82
+ if (actual.step_id !== planned.stepId ||
83
+ actual.step_title !== planned.stepTitle ||
84
+ actual.instructions !== planned.instructions ||
85
+ actual.completion_json !== planned.completionJson ||
86
+ actual.sequence_index !== planned.sequenceIndex) {
87
+ const fields = [
88
+ actual.step_id !== planned.stepId ? "step_id" : "",
89
+ actual.step_title !== planned.stepTitle ? "step_title" : "",
90
+ actual.instructions !== planned.instructions ? "instructions" : "",
91
+ actual.completion_json !== planned.completionJson ? "completion_json" : "",
92
+ actual.sequence_index !== planned.sequenceIndex ? "sequence_index" : "",
93
+ ].filter(Boolean);
94
+ corruptSpine(run.id, `step row ${index} differs from the frozen plan (${fields.join(", ")})`);
95
+ }
96
+ }
97
+ if (run.current_step_id !== null && !expected.some((step) => step.stepId === run.current_step_id))
98
+ corruptSpine(run.id, `current step ${run.current_step_id} is not in the frozen plan`);
99
+ const current = run.current_step_id ? rows.find((row) => row.step_id === run.current_step_id) : undefined;
100
+ if (run.status === "active") {
101
+ const firstPending = rows.find((row) => row.status === "pending");
102
+ if (!current || current.status !== "pending" || firstPending?.step_id !== current.step_id)
103
+ corruptSpine(run.id, "active status/current step does not match the first pending plan step");
104
+ }
105
+ else if (run.status === "blocked") {
106
+ if (!current || current.status !== "blocked")
107
+ corruptSpine(run.id, `${run.status} status does not match the current plan step`);
108
+ }
109
+ else if (run.status === "failed") {
110
+ // `workflow abandon` marks the run failed while intentionally leaving its
111
+ // current step pending so `resume` can reopen the same work.
112
+ if (!current || (current.status !== "failed" && current.status !== "pending"))
113
+ corruptSpine(run.id, `${run.status} status does not match the current plan step`);
114
+ }
115
+ else if (run.status === "completed") {
116
+ if (run.current_step_id !== null ||
117
+ rows.some((row) => row.status === "pending" || row.status === "blocked" || row.status === "failed"))
118
+ corruptSpine(run.id, "completed status disagrees with the plan spine");
119
+ }
120
+ }
121
+ function routeInstructions(route) {
122
+ const branches = Object.entries(route.when)
123
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
124
+ .map(([match, stepId]) => `"${match}" -> ${stepId}`);
125
+ if (route.defaultStepId !== undefined)
126
+ branches.push(`default -> ${route.defaultStepId}`);
127
+ return `Route on ${route.input}: ${branches.join(", ")}.`;
128
+ }
129
+ function corruptSpine(runId, detail) {
130
+ throw new UsageError(`Workflow run ${runId} has a corrupt durable step spine: ${detail}. Refusing to mutate state that disagrees with its frozen plan.`, "INVALID_JSON_ARGUMENT");
131
+ }