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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -4,109 +4,78 @@
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
6
  import workflowTemplate from "../../assets/workflows/workflow-template.md" with { type: "text" };
7
- import { canonicalizeWorkflowName, WORKFLOW_EXTENSIONS } from "../../core/asset/asset-spec.js";
8
- import { isWithin, resolveStashDir } from "../../core/common.js";
7
+ import { ensureAkmMarkdownType } from "../../core/asset/akm-markdown.js";
8
+ import { makeBundleRef } from "../../core/asset/asset-ref.js";
9
+ import { isWithin, writeFileAtomic } from "../../core/common.js";
10
+ import { loadConfig } from "../../core/config/config.js";
9
11
  import { UsageError } from "../../core/errors.js";
12
+ import { defaultBundleForTarget } from "../../core/mutation-target.js";
13
+ import { canonicalizeWorkflowName, WORKFLOW_EXTENSIONS } from "../../core/recognition-util.js";
10
14
  import { warn } from "../../core/warn.js";
11
- import { compileWorkflowProgram } from "../ir/compile.js";
15
+ import { prepareWriteTargetForMutation, resolveWriteTarget, withWriteTargetMutation } from "../../core/write-source.js";
16
+ import { compileWorkflowPlan } from "../ir/compile.js";
12
17
  import { parseWorkflow } from "../parser.js";
13
- import { parseWorkflowProgram } from "../program/parser.js";
14
- import workflowProgramTemplate from "./workflow-program-template.yaml" with { type: "text" };
15
- const DEFAULT_WORKFLOW_TEMPLATE = renderWorkflowTemplate({
16
- title: "Example Workflow",
17
- firstStepTitle: "First Step",
18
- firstStepId: "first-step",
19
- });
18
+ const DEFAULT_WORKFLOW_TEMPLATE = renderWorkflowTemplate("New Workflow");
20
19
  export function getWorkflowTemplate() {
21
20
  return DEFAULT_WORKFLOW_TEMPLATE;
22
21
  }
23
- /**
24
- * Minimal valid YAML workflow *program* (redesign addendum, R1), printed by
25
- * `akm workflow template --yaml`. Kept as an external asset file per the repo
26
- * convention (see `workflow-program-template.yaml` next to this module);
27
- * `tests/workflows/program-assets.test.ts` pins that it parses AND compiles.
28
- */
29
- export function getWorkflowProgramTemplate() {
30
- return workflowProgramTemplate;
31
- }
32
22
  export function buildWorkflowTemplate(name) {
33
23
  if (!name)
34
24
  return DEFAULT_WORKFLOW_TEMPLATE;
35
- const title = humanizeWorkflowName(name);
36
- const stepId = slugifyWorkflowStepId(name);
37
- const customized = renderWorkflowTemplate({
38
- title,
39
- firstStepTitle: `${title} Setup`,
40
- firstStepId: `${stepId}-setup`,
41
- });
42
- const result = parseWorkflow(customized, { path: `<template:${name}>` });
43
- if (!result.ok) {
44
- throw new UsageError(formatWorkflowErrors(`<template:${name}>`, result.errors));
45
- }
25
+ // Only the H1 is customized. Step ids are STRUCTURAL under the unified format
26
+ // — each appears in `steps[].id`, as a body `## <id>` heading, and possibly in
27
+ // another step's `inputs:` — so rewriting them from a name would have to patch
28
+ // three places consistently to stay parseable. Generic `first-step`/
29
+ // `second-step` are the author's to rename.
30
+ const customized = renderWorkflowTemplate(humanizeWorkflowName(name));
31
+ validateWorkflowContent(customized, `<template:${name}>`);
46
32
  return customized;
47
33
  }
48
- /**
49
- * Customize the shipped YAML program template ({@link getWorkflowProgramTemplate})
50
- * for a named workflow: swap the placeholder `name:` for the workflow's slug so
51
- * a freshly created `.yaml`/`.yml` asset round-trips through the program parser
52
- * (its `title` becomes the slug). Parses AND compiles the result — mirroring
53
- * {@link buildWorkflowTemplate} — so a create never writes an asset that
54
- * `show`/`start`/`validate` would then reject.
55
- */
56
- export function buildWorkflowProgramTemplate(name) {
57
- if (!name)
58
- return workflowProgramTemplate;
59
- const programName = slugifyWorkflowStepId(name);
60
- const customized = workflowProgramTemplate.replace(/^name:.*$/m, `name: ${programName}`);
61
- const parsed = parseWorkflowProgram(customized, { path: `<template:${name}>` });
62
- if (!parsed.ok) {
63
- throw new UsageError(formatWorkflowErrors(`<template:${name}>`, parsed.errors));
34
+ /** Parse AND compile `content`, so a create never writes an asset that `show`/`start`/`validate` would then reject. */
35
+ function validateWorkflowContent(content, sourcePath) {
36
+ const result = parseWorkflow(content, { path: sourcePath });
37
+ if (!result.ok) {
38
+ throw new UsageError(formatWorkflowErrors(sourcePath, result.errors));
64
39
  }
65
- const compiled = compileWorkflowProgram(parsed.program);
40
+ const compiled = compileWorkflowPlan(result.document, slugifyWorkflowStepId(sourcePath));
66
41
  if (!compiled.ok) {
67
- throw new UsageError(formatWorkflowErrors(`<template:${name}>`, compiled.errors));
42
+ throw new UsageError(formatWorkflowErrors(sourcePath, compiled.errors));
68
43
  }
69
- return customized;
70
44
  }
71
- /** Recognized YAML workflow-program suffixes (see {@link WORKFLOW_EXTENSIONS}). */
72
- const WORKFLOW_PROGRAM_SUFFIX_RE = /\.ya?ml$/i;
45
+ /** Recognized workflow-program suffixes — creating one is a lint-time usage error (workflow-format-unification). */
46
+ const YAML_SUFFIX_RE = /\.ya?ml$/i;
47
+ export function assertWorkflowMarkdownName(name) {
48
+ if (!YAML_SUFFIX_RE.test(name.trim()))
49
+ return;
50
+ throw new UsageError(`Workflows are markdown-only now (workflow-format-unification) — "${name}" cannot be created. ` +
51
+ `Use a plain name (no ".yaml"/".yml" suffix); the orchestration graph lives in the ".md" file's frontmatter.`);
52
+ }
73
53
  export function createWorkflowAsset(input) {
74
- const stashDir = resolveStashDir();
75
- const typeRoot = path.join(stashDir, "workflows");
76
- fs.mkdirSync(typeRoot, { recursive: true });
77
- // A `.yaml`/`.yml` name selects the YAML *program* format (redesign
78
- // addendum, R1); capture the exact suffix the user typed so the written file
79
- // keeps it, then strip every workflow extension to get the canonical name.
80
- const suffixMatch = input.name.trim().replace(/\\/g, "/").match(WORKFLOW_PROGRAM_SUFFIX_RE);
81
- const programSuffix = suffixMatch ? suffixMatch[0].toLowerCase() : undefined;
82
- const isProgram = programSuffix !== undefined;
54
+ assertWorkflowMarkdownName(input.name);
55
+ const config = loadConfig();
56
+ const resolvedTarget = resolveWriteTarget(config);
57
+ const target = prepareWriteTargetForMutation(resolvedTarget, { allowedAdapters: ["akm", "akm-workflow"] });
58
+ const stashDir = target.source.path;
59
+ const standaloneWorkflowBundle = target.source.adapterId === "akm-workflow";
60
+ const typeRoot = standaloneWorkflowBundle ? stashDir : path.join(stashDir, "workflows");
83
61
  const normalizedName = normalizeWorkflowName(input.name);
84
- // The write target is DEFINITIVE — the canonical name plus the chosen format's
85
- // extension (`.yaml`/`.yml` for a program, `.md` for markdown). We deliberately
86
- // do NOT go through `resolveAssetPathFromName`, which PROBES existing files and
87
- // would redirect a markdown create onto an existing `foo.yaml` (writing
88
- // markdown into a `.yaml`). Computing the target directly makes a markdown
89
- // create always write `.md`, so the finding-C cross-extension check below sees
90
- // the real collision instead of a self-match.
91
- const targetSuffix = isProgram ? programSuffix : ".md";
92
- const assetPath = path.join(typeRoot, `${normalizedName}${targetSuffix}`);
93
- if (!isWithin(assetPath, typeRoot)) {
94
- throw new UsageError(`Resolved workflow path escapes the stash: "${normalizedName}"`, "PATH_ESCAPE_VIOLATION");
95
- }
96
- // Codex round-3 finding C: a `workflow:<name>` ref is canonical across every
97
- // recognized extension (`.md`/`.yaml`/`.yml`) and resolves `.md` BEFORE
98
- // `.yaml`. So creating `foo.yaml` while `foo.md` exists would return the ref
99
- // `workflow:foo` that still starts the OLD markdown workflow — a silently
100
- // shadowed asset. Reject creation when ANY recognized extension already holds
101
- // the same canonical name, naming the existing file. A same-extension collision
102
- // (the target path itself exists) keeps the classic `--force` overwrite escape;
103
- // a DIFFERENT-extension collision cannot be force-overwritten (writing a new
104
- // file would leave the old one shadowing it) — remove the existing file first.
105
- const existingPaths = WORKFLOW_EXTENSIONS.map((ext) => path.join(typeRoot, `${normalizedName}${ext}`)).filter((candidate) => fs.existsSync(candidate));
106
- const conflicting = existingPaths.find((p) => p !== assetPath);
107
- if (conflicting !== undefined) {
108
- throw new UsageError(`Workflow "${normalizedName}" already exists as ${path.relative(stashDir, conflicting)} — the ` +
109
- `\`workflow:${normalizedName}\` ref resolves to that file, so creating this one would shadow it. ` +
62
+ const conceptId = standaloneWorkflowBundle ? normalizedName : `workflows/${normalizedName}`;
63
+ const assetPath = path.join(typeRoot, `${normalizedName}.md`);
64
+ const relativeAssetPath = path.relative(path.resolve(typeRoot), path.resolve(assetPath));
65
+ if (relativeAssetPath === ".." ||
66
+ relativeAssetPath.startsWith(`..${path.sep}`) ||
67
+ path.isAbsolute(relativeAssetPath)) {
68
+ throw new UsageError(`Resolved workflow path escapes the bundle: "${normalizedName}"`, "PATH_ESCAPE_VIOLATION");
69
+ }
70
+ // A file whose canonical name matches but whose PATH differs can only be a
71
+ // case variant now (`upper.MD` vs `upper.md`) — the cross-EXTENSION case this
72
+ // guard also covered is gone with the unified `.md`-only format. It still
73
+ // matters: on a case-insensitive filesystem the two spellings are one file,
74
+ // so writing the target would silently clobber or shadow the existing asset.
75
+ const shadowing = findExistingWorkflowPaths(typeRoot, normalizedName).find((p) => p !== assetPath);
76
+ if (shadowing !== undefined) {
77
+ throw new UsageError(`Workflow "${normalizedName}" already exists as ${path.relative(stashDir, shadowing)} — the ` +
78
+ `\`${conceptId}\` ref resolves to that file, so creating this one would shadow it. ` +
110
79
  `Remove or rename the existing file first, or create the workflow under a different name.`, "RESOURCE_ALREADY_EXISTS");
111
80
  }
112
81
  if (fs.existsSync(assetPath) && !input.force) {
@@ -114,33 +83,19 @@ export function createWorkflowAsset(input) {
114
83
  }
115
84
  const content = input.from
116
85
  ? readWorkflowSource(input.from, stashDir)
117
- : (input.content ??
118
- (isProgram ? buildWorkflowProgramTemplate(normalizedName) : buildWorkflowTemplate(normalizedName)));
119
- const sourcePath = input.from ?? `workflows/${normalizedName}${isProgram ? programSuffix : ".md"}`;
120
- // Validate against the format the destination extension selects — a YAML
121
- // program parses+compiles as a program, markdown as a document — so the
122
- // created asset is guaranteed usable by show/start/validate, which pick
123
- // their parser by the same extension.
124
- if (isProgram) {
125
- const parsed = parseWorkflowProgram(content, { path: sourcePath });
126
- if (!parsed.ok) {
127
- throw new UsageError(formatWorkflowErrors(sourcePath, parsed.errors));
128
- }
129
- const compiled = compileWorkflowProgram(parsed.program);
130
- if (!compiled.ok) {
131
- throw new UsageError(formatWorkflowErrors(sourcePath, compiled.errors));
132
- }
133
- }
134
- else {
135
- const result = parseWorkflow(content, { path: sourcePath });
136
- if (!result.ok) {
137
- throw new UsageError(formatWorkflowErrors(sourcePath, result.errors));
138
- }
139
- }
140
- fs.mkdirSync(path.dirname(assetPath), { recursive: true });
141
- fs.writeFileSync(assetPath, content.endsWith("\n") ? content : `${content}\n`, "utf8");
86
+ : (input.content ?? buildWorkflowTemplate(normalizedName));
87
+ const sourcePath = input.from ?? `workflows/${normalizedName}.md`;
88
+ validateWorkflowContent(content, sourcePath);
89
+ const authoredContent = ensureAkmMarkdownType(content, "workflow");
90
+ const mode = fs.existsSync(assetPath) ? fs.lstatSync(assetPath).mode & 0o777 : 0o644;
91
+ const defaultBundle = defaultBundleForTarget(config);
92
+ const ref = makeBundleRef(target.source.name === defaultBundle ? undefined : target.source.name, conceptId);
93
+ withWriteTargetMutation(target, [assetPath], { ignored: "reject", purpose: "workflow-authoring", message: `Create ${ref}` }, () => {
94
+ fs.mkdirSync(path.dirname(assetPath), { recursive: true });
95
+ writeFileAtomic(assetPath, authoredContent.endsWith("\n") ? authoredContent : `${authoredContent}\n`, mode);
96
+ });
142
97
  return {
143
- ref: `workflow:${normalizedName}`,
98
+ ref,
144
99
  path: assetPath,
145
100
  stashDir,
146
101
  };
@@ -167,10 +122,9 @@ function readWorkflowSource(source, stashDir) {
167
122
  return fs.readFileSync(resolved, "utf8");
168
123
  }
169
124
  function normalizeWorkflowName(name) {
170
- // Strip any recognized workflow extension (.md/.yaml/.yml) so the canonical
171
- // name — and thus the `workflow:<name>` ref — is extension-free regardless of
172
- // how the user spelled it. The chosen format is recovered from the raw suffix
173
- // by the caller (createWorkflowAsset).
125
+ // Strip a recognized workflow extension (.md) so the canonical name — and
126
+ // thus the `workflows/<name>` ref — is extension-free regardless of how the
127
+ // user spelled it.
174
128
  const normalized = canonicalizeWorkflowName(name
175
129
  .trim()
176
130
  .replace(/\\/g, "/")
@@ -190,7 +144,7 @@ function humanizeWorkflowName(name) {
190
144
  .pop()
191
145
  ?.replace(/[-_]+/g, " ")
192
146
  .replace(/\b\w/g, (match) => match.toUpperCase())
193
- .trim() || "Example Workflow");
147
+ .trim() || "New Workflow");
194
148
  }
195
149
  function slugifyWorkflowStepId(name) {
196
150
  return (name
@@ -206,7 +160,7 @@ export function formatWorkflowErrors(path, errors) {
206
160
  return [heading, ...lines].join("\n");
207
161
  }
208
162
  /**
209
- * Validate a workflow by ref (`workflow:<name>`) or filesystem path.
163
+ * Validate a workflow filesystem path.
210
164
  *
211
165
  * Returns the parse result plus the source-relative path used. Throws
212
166
  * `UsageError` only when the target cannot be located on disk; parse
@@ -214,9 +168,6 @@ export function formatWorkflowErrors(path, errors) {
214
168
  * format them however they like.
215
169
  */
216
170
  export function validateWorkflowSource(target) {
217
- if (target.startsWith("workflow:")) {
218
- throw new UsageError(`validateWorkflowSource expects a filesystem path; resolve refs to paths in the caller before invoking.`);
219
- }
220
171
  const resolved = path.resolve(target);
221
172
  if (!fs.existsSync(resolved)) {
222
173
  throw new UsageError(`Workflow file not found: "${target}".`);
@@ -225,34 +176,31 @@ export function validateWorkflowSource(target) {
225
176
  return { path: target, parse: parseWorkflow(content, { path: target }) };
226
177
  }
227
178
  /**
228
- * Validate a YAML workflow *program* by filesystem path: parse via
229
- * `parseWorkflowProgram`, then — only when the parse is clean — compile via
230
- * `compileWorkflowProgram` so expression/reference errors surface too. Both
231
- * error lists carry line numbers and are returned in the same
232
- * `WorkflowError[]` shape, ready for `formatWorkflowErrors`. Throws
233
- * `UsageError` only when the target cannot be located on disk.
179
+ * Every file under `typeRoot` whose canonical workflow name equals
180
+ * `normalizedName`. Extension matching is case-INSENSITIVE, so `foo.MD` and
181
+ * `foo.md` both match — the case-variant collision the create path must refuse
182
+ * rather than silently clobber on a case-insensitive filesystem.
234
183
  */
235
- export function validateWorkflowProgramSource(target) {
236
- const resolved = path.resolve(target);
237
- if (!fs.existsSync(resolved)) {
238
- throw new UsageError(`Workflow file not found: "${target}".`);
239
- }
240
- const content = fs.readFileSync(resolved, "utf8");
241
- const parse = parseWorkflowProgram(content, { path: target });
242
- if (!parse.ok) {
243
- return { path: target, result: { ok: false, errors: parse.errors } };
244
- }
245
- const compiled = compileWorkflowProgram(parse.program);
246
- if (!compiled.ok) {
247
- return { path: target, result: { ok: false, errors: compiled.errors } };
184
+ function findExistingWorkflowPaths(typeRoot, normalizedName) {
185
+ const parent = path.join(typeRoot, path.dirname(normalizedName));
186
+ let entries;
187
+ try {
188
+ entries = fs.readdirSync(parent, { withFileTypes: true });
248
189
  }
249
- // Non-fatal advisories ride along on a successful validation (additive) so
250
- // `workflow validate` can surface them without changing the ok verdict.
251
- return { path: target, result: { ok: true, program: parse.program, warnings: compiled.warnings } };
190
+ catch {
191
+ return [];
192
+ }
193
+ const basename = path.basename(normalizedName);
194
+ return WORKFLOW_EXTENSIONS.flatMap((extension) => entries
195
+ .filter((entry) => {
196
+ if (!entry.isFile() && !entry.isSymbolicLink())
197
+ return false;
198
+ const entryExtension = path.extname(entry.name);
199
+ return entryExtension.toLowerCase() === extension && entry.name.slice(0, -entryExtension.length) === basename;
200
+ })
201
+ .sort((a, b) => a.name.localeCompare(b.name))
202
+ .map((entry) => path.join(parent, entry.name)));
252
203
  }
253
- function renderWorkflowTemplate(input) {
254
- return workflowTemplate
255
- .replace("{{TITLE}}", input.title)
256
- .replace("{{FIRST_STEP_TITLE}}", input.firstStepTitle)
257
- .replace("{{FIRST_STEP_ID}}", input.firstStepId);
204
+ function renderWorkflowTemplate(title) {
205
+ return workflowTemplate.replace("{{TITLE}}", title);
258
206
  }
@@ -21,7 +21,7 @@ export function resolveWorkflowScopeAnchor(startDir) {
21
21
  if (gitRoot)
22
22
  return gitRoot;
23
23
  try {
24
- const stashDir = safeRealpath(resolveStashDir({ readOnly: true }));
24
+ const stashDir = safeRealpath(resolveStashDir());
25
25
  if (isWithin(cwd, stashDir))
26
26
  return stashDir;
27
27
  }
@@ -8,22 +8,6 @@ export const WORKFLOW_STEP_STATES = [
8
8
  "failed",
9
9
  "skipped",
10
10
  ];
11
- export const WORKFLOW_SUBCOMMANDS = new Set([
12
- "start",
13
- "next",
14
- "complete",
15
- "status",
16
- "list",
17
- "create",
18
- "template",
19
- "resume",
20
- "abandon",
21
- "validate",
22
- "run",
23
- "brief",
24
- "report",
25
- "watch",
26
- ]);
27
11
  export function parseWorkflowJsonObject(raw, flagName) {
28
12
  if (!raw)
29
13
  return {};
@@ -47,7 +31,3 @@ export function parseWorkflowStepState(value) {
47
31
  }
48
32
  throw new UsageError(`Invalid workflow step state "${value}". Expected one of: ${WORKFLOW_STEP_STATES.join(", ")}`);
49
33
  }
50
- export function hasWorkflowSubcommand(args) {
51
- const command = Array.isArray(args._) ? args._[0] : undefined;
52
- return typeof command === "string" && WORKFLOW_SUBCOMMANDS.has(command);
53
- }
@@ -0,0 +1,15 @@
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 os from "node:os";
5
+ export const WORKFLOW_MAX_CONCURRENCY_CEILING = 64;
6
+ export function cpuDerivedUnitConcurrency(cpuCount = os.cpus()?.length ?? 4) {
7
+ return Math.min(16, Math.max(1, cpuCount - 2));
8
+ }
9
+ export function clampMaxConcurrency(value) {
10
+ return Math.min(WORKFLOW_MAX_CONCURRENCY_CEILING, Math.max(1, Math.floor(value)));
11
+ }
12
+ /** Resolve and freeze the engine-wide cap once when a workflow run starts. */
13
+ export function workflowMaxConcurrency(configured, cpuCount = os.cpus()?.length ?? 4) {
14
+ return configured === undefined ? cpuDerivedUnitConcurrency(cpuCount) : clampMaxConcurrency(configured);
15
+ }
@@ -29,16 +29,14 @@
29
29
  * driven run of the same frozen plan produce byte-identical unit graphs — the
30
30
  * invariant R4 asserts.
31
31
  */
32
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
33
- import { canonicalizeWorkflowName } from "../../core/asset/asset-spec.js";
34
- import { NotFoundError, UsageError } from "../../core/errors.js";
35
- import { withWorkflowRunsRepo } from "../../storage/repositories/workflow-runs-repository.js";
36
- import { getCurrentWorkflowScopeKey } from "../authoring/scope-key.js";
32
+ import { UsageError } from "../../core/errors.js";
37
33
  import { assertRunParamsSatisfyPlan } from "../ir/params.js";
38
- import { snapshotRunForDriver } from "../runtime/runs.js";
34
+ import { frozenStepRows, requireExecutableWorkflowPlan } from "../runtime/plan-classifier.js";
35
+ import { resolveExistingWorkflowRunId, snapshotRunForDriver } from "../runtime/runs.js";
39
36
  import { evaluateStaleUnits } from "../runtime/unit-checkin.js";
37
+ import { GATE_EVALUATION_PHASE } from "../runtime/unit-phases.js";
40
38
  import { detectSecretShapedParams } from "./param-secrets.js";
41
- import { activeGateLoop, assertJournaledRouteSelectionsValid, computeStepWorkList, evaluateRoute, GATE_EVALUATION_PHASE, isWorkListFullyTerminal, parseFrozenPlan, recoverGateFeedback, selectUnitAttemptRow, stepOutputsFromEvidence, } from "./step-work.js";
39
+ import { activeGateLoop, assertJournaledRouteSelectionsValid, computeStepWorkList, evaluateRoute, isWorkListFullyTerminal, recoverGateFeedback, selectUnitAttemptRow, stepOutputsFromEvidence, } from "./step-work.js";
42
40
  const EMPTY_WORK_LIST = { isFanOut: false, reducer: null, itemCount: 0, units: [] };
43
41
  // ── Entry point ──────────────────────────────────────────────────────────────
44
42
  /**
@@ -54,8 +52,6 @@ export async function buildWorkflowBrief(target) {
54
52
  // the active step between the spine read and the unit-journal read. A bare run
55
53
  // id never auto-starts (we resolved to a concrete id above).
56
54
  const { next, run: runRow, units } = await snapshotRunForDriver(runId);
57
- const planJson = runRow.plan_json;
58
- const planHash = runRow.plan_hash;
59
55
  const leaseHolder = runRow.engine_lease_holder;
60
56
  const leaseUntil = runRow.engine_lease_until;
61
57
  const run = {
@@ -141,10 +137,8 @@ export async function buildWorkflowBrief(target) {
141
137
  message: "Workflow run is active but has no current step.",
142
138
  };
143
139
  }
144
- // Load the FROZEN plan the engine executes (migration 006). A legacy run
145
- // (NULL plan_json) has no plan for brief to read — point at engine-driven
146
- // mode, which still handles pre-006 runs by compiling from the asset.
147
- const plan = loadFrozenPlanForBrief(run.id, planJson, planHash);
140
+ // Load the same frozen plan the engine executes.
141
+ const plan = requireExecutableWorkflowPlan(runRow);
148
142
  // Reviewer #12: the journaled params row must still satisfy the frozen param
149
143
  // schemas — a violation is post-start corruption, loud on the brief surface
150
144
  // too (mirrors the frozen-plan hash check and the tampered-params divergence).
@@ -171,19 +165,21 @@ export async function buildWorkflowBrief(target) {
171
165
  const gateFeedback = recoverGateFeedback(units, stepState.id, gateLoop);
172
166
  const isRouteOnly = !!stepPlan.route && !stepPlan.root;
173
167
  const kind = isRouteOnly ? "route" : stepPlan.route ? "execute-and-route" : "execute";
174
- const criteria = stepState.completionCriteria ?? [];
168
+ const criteria = stepPlan.gate.criteria;
169
+ const instructions = frozenStepRows(plan).find((step) => step.stepId === stepState.id)?.instructions;
170
+ if (instructions === undefined)
171
+ throw new UsageError(`Step "${stepState.id}" has no frozen instructions.`);
175
172
  const step = {
176
173
  stepId: stepState.id,
177
- title: stepState.title,
178
- sequenceIndex: stepState.sequenceIndex ?? 0,
174
+ title: stepPlan.title,
175
+ sequenceIndex: stepPlan.sequenceIndex,
179
176
  kind,
180
- instructions: stepState.instructions,
177
+ instructions,
181
178
  gate: {
182
179
  criteria,
183
180
  maxLoops: Math.max(1, stepPlan.gate.maxLoops ?? 1),
184
181
  currentLoop: gateLoop,
185
182
  judgesArtifact: !isRouteOnly && criteria.length > 0,
186
- required: stepPlan.gate.required === true,
187
183
  },
188
184
  ...(stepPlan.outputSchema ? { outputSchema: stepPlan.outputSchema } : {}),
189
185
  };
@@ -209,6 +205,7 @@ export async function buildWorkflowBrief(target) {
209
205
  runId: run.id,
210
206
  params: run.params,
211
207
  stepOutputs,
208
+ engines: plan.execution.engines,
212
209
  gateLoop,
213
210
  ...(gateFeedback ? { gateFeedback } : {}),
214
211
  });
@@ -315,15 +312,19 @@ function makeSpineToken(runId, stepId, gateLoop, watermark) {
315
312
  }
316
313
  // ── Helpers ──────────────────────────────────────────────────────────────────
317
314
  function toBriefUnit(runId, unit, stepId, journaled, ctx) {
315
+ if (!unit.engine || !unit.invocation) {
316
+ throw new UsageError(`Unit "${unit.unitId}" has no complete frozen engine attribution.`);
317
+ }
318
318
  const action = deriveUnitAction(unit, journaled, ctx);
319
319
  const report = reportCommandForAction(runId, unit, stepId, action, journaled?.claim_holder ?? null);
320
320
  return {
321
321
  unitId: unit.unitId,
322
322
  nodeId: unit.nodeId,
323
323
  index: unit.index,
324
- runner: unit.runner,
325
- ...(unit.profile ? { profile: unit.profile } : {}),
326
- ...(unit.model ? { model: unit.model } : {}),
324
+ engine: unit.invocation.engine,
325
+ runtimeKind: unit.runner,
326
+ platform: unit.engine.kind === "agent" ? unit.engine.platform : null,
327
+ model: unit.invocation.model,
327
328
  timeoutMs: unit.timeoutMs,
328
329
  ...(unit.schema ? { outputSchema: unit.schema } : {}),
329
330
  // Env asset REF names only — brief never resolves bindings, so no secret
@@ -428,33 +429,16 @@ function buildMessage(step, workList, route, gateLoop, settleState) {
428
429
  if (settleState === "finalize") {
429
430
  // Fully-terminal work-list on a still-active step: everything ran, nothing
430
431
  // remains to execute — the step only needs finalization (the run was
431
- // gate-blocked then resumed, or a crash interrupted completion). A required
432
- // gate with no judge available will re-block, which is correct behavior.
433
- const gateNote = step.gate.required && step.gate.criteria.length > 0
434
- ? " If this step's REQUIRED gate has no judge available it will re-block, pending a configured judge or a manual `akm workflow complete`."
435
- : "";
432
+ // gate-rejected then resumed, or a crash interrupted completion).
436
433
  return (`Active step "${step.stepId}" has run all ${n} unit(s) to a terminal state${loopNote} — nothing remains to ` +
437
434
  `execute or report. Finalize it with \`akm workflow report --settle\` (see settleCommand): the gate is judged ` +
438
- `and the step advances.${gateNote}`);
435
+ "and the step advances.");
439
436
  }
440
437
  if (settleState === "non-dispatching") {
441
438
  return `Active step "${step.stepId}" dispatches no reportable units${loopNote}.${settleNote}`;
442
439
  }
443
440
  return `Active step "${step.stepId}" expects ${n} unit(s)${loopNote}. Execute them, then report each result.`;
444
441
  }
445
- /**
446
- * brief-specific frozen-plan loader: unlike the engine's loader, a NULL
447
- * plan_json is a hard, actionable error rather than a warn-and-compile — brief
448
- * describes the frozen plan the engine executes, and a legacy run has none.
449
- */
450
- function loadFrozenPlanForBrief(runId, planJson, planHash) {
451
- if (!planJson) {
452
- throw new UsageError(`Workflow run ${runId} predates frozen plans (no plan_json on the run row) and cannot be described by ` +
453
- `\`akm workflow brief\`. Drive it with engine-driven mode instead: \`akm workflow run ${runId}\` ` +
454
- `(which compiles a legacy run's plan from the live asset).`);
455
- }
456
- return parseFrozenPlan(runId, planJson, planHash);
457
- }
458
442
  /**
459
443
  * Resolve `target` to a concrete run id WITHOUT starting anything. A run id
460
444
  * resolves directly; a workflow ref resolves to its active run in the current
@@ -462,23 +446,5 @@ function loadFrozenPlanForBrief(runId, planJson, planHash) {
462
446
  * would mutate).
463
447
  */
464
448
  export async function resolveRunId(target) {
465
- return withWorkflowRunsRepo((repo) => {
466
- const byId = repo.getRunById(target);
467
- if (byId)
468
- return byId.id;
469
- if (!target.includes(":")) {
470
- throw new NotFoundError(`Workflow run "${target}" not found.`, "WORKFLOW_NOT_FOUND");
471
- }
472
- const parsed = parseAssetRef(target);
473
- if (parsed.type !== "workflow") {
474
- throw new UsageError(`Expected a workflow run id or workflow ref (workflow:<name>), got "${target}".`);
475
- }
476
- const ref = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${canonicalizeWorkflowName(parsed.name)}`;
477
- const active = repo.getActiveRunRowForScope(ref, getCurrentWorkflowScopeKey());
478
- if (!active) {
479
- throw new NotFoundError(`No active workflow run for ${ref} in this scope. \`akm workflow brief\` describes an existing run and never ` +
480
- `starts one — run \`akm workflow start ${ref}\` (or \`akm workflow run ${ref}\`) first.`, "WORKFLOW_NOT_FOUND");
481
- }
482
- return active.id;
483
- });
449
+ return resolveExistingWorkflowRunId(target);
484
450
  }
@@ -0,0 +1,47 @@
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 { deepMergeConfig } from "../../core/config/deep-merge.js";
5
+ import { ConfigError } from "../../core/errors.js";
6
+ /** Build a gate judge from a v3 catalog entry without consulting live config. */
7
+ export function frozenSummaryJudge(plan, invocation) {
8
+ if (!invocation)
9
+ return null;
10
+ const engine = plan.execution?.engines[invocation.engine];
11
+ if (!engine || engine.kind !== "llm")
12
+ throw new ConfigError(`Frozen gate engine "${invocation.engine}" is unavailable.`, "INVALID_CONFIG_FILE");
13
+ return async ({ system, user }) => {
14
+ const { chatCompletion } = await import("../../llm/client.js");
15
+ return chatCompletion(materialize(engine, invocation), [
16
+ { role: "system", content: system },
17
+ { role: "user", content: user },
18
+ ], {
19
+ timeoutMs: invocation.timeoutMs,
20
+ });
21
+ };
22
+ }
23
+ function materialize(engine, invocation) {
24
+ let apiKey;
25
+ for (const name of engine.credential?.names ?? []) {
26
+ const value = process.env[name]?.trim();
27
+ if (value) {
28
+ apiKey = value;
29
+ break;
30
+ }
31
+ }
32
+ if (engine.credential?.required && !apiKey)
33
+ throw new ConfigError(`Required engine credential ${engine.credential.names[0]} is not set.`, "INVALID_CONFIG_FILE");
34
+ const base = {
35
+ provider: engine.provider,
36
+ endpoint: engine.endpoint,
37
+ model: invocation.model ?? engine.model,
38
+ ...(engine.temperature !== undefined ? { temperature: engine.temperature } : {}),
39
+ ...(engine.maxTokens !== undefined ? { maxTokens: engine.maxTokens } : {}),
40
+ ...(engine.supportsJsonSchema !== undefined ? { supportsJsonSchema: engine.supportsJsonSchema } : {}),
41
+ ...(engine.extraParams ? { extraParams: engine.extraParams } : {}),
42
+ ...(engine.contextLength !== undefined ? { contextLength: engine.contextLength } : {}),
43
+ ...(engine.enableThinking !== undefined ? { enableThinking: engine.enableThinking } : {}),
44
+ ...(apiKey ? { apiKey } : {}),
45
+ };
46
+ return (invocation.llm ? deepMergeConfig(base, invocation.llm) : base);
47
+ }