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,45 @@
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 { GATE_EVALUATION_PHASE } from "./unit-phases.js";
5
+ /**
6
+ * Default staleness window. A unit claimed `running` whose last heartbeat (or,
7
+ * absent any heartbeat, its first claim) is older than this is surfaced as
8
+ * stale. Matches the run-level {@link ../runtime/checkin.CHECKIN_STALL_MS}.
9
+ */
10
+ export const UNIT_STALE_MS = 90_000;
11
+ function parseIso(value) {
12
+ if (!value)
13
+ return null;
14
+ const ms = Date.parse(value);
15
+ return Number.isNaN(ms) ? null : ms;
16
+ }
17
+ /**
18
+ * Pure stale-unit evaluator. Returns every `running` DISPATCH unit whose last
19
+ * heartbeat (`last_checkin_at`, else the first-claim `started_at`) is older than
20
+ * `staleMs`. Gate-evaluation rows (`phase = "gate"`) are excluded — they are
21
+ * synchronous engine judge calls, never driver-claimed work. A running row with
22
+ * no usable timestamp at all is treated as stale (a claim we can no longer age).
23
+ * Deterministic in `now` — free of timer flakiness.
24
+ */
25
+ export function evaluateStaleUnits(rows, now = Date.now(), staleMs = UNIT_STALE_MS) {
26
+ const stale = [];
27
+ for (const row of rows) {
28
+ if (row.status !== "running")
29
+ continue;
30
+ if (row.phase === GATE_EVALUATION_PHASE)
31
+ continue;
32
+ const lastSeenAt = row.last_checkin_at ?? row.started_at;
33
+ const lastSeen = parseIso(lastSeenAt);
34
+ const idleMs = lastSeen === null ? Number.POSITIVE_INFINITY : now - lastSeen;
35
+ if (idleMs < staleMs)
36
+ continue;
37
+ stale.push({
38
+ unitId: row.unit_id,
39
+ stepId: row.step_id,
40
+ idleMs,
41
+ lastSeenAt: lastSeenAt ?? null,
42
+ });
43
+ }
44
+ return stale;
45
+ }
@@ -0,0 +1,20 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Unit-row phase markers — a leaf module (imports nothing) so both the exec
6
+ * drivers (step-work, brief, run-workflow) and the runtime (unit-checkin) can
7
+ * key on the phase discriminator without an exec ↔ runtime import cycle.
8
+ * Extracting {@link GATE_EVALUATION_PHASE} here broke the last workflows-
9
+ * runtime knot (step-work → runs → unit-checkin → step-work; chunk-8 WI-8.6,
10
+ * DoD 11).
11
+ */
12
+ /**
13
+ * `phase` marker stamped on gate-evaluation unit rows. Step ids cannot contain
14
+ * dots (`PROGRAM_STEP_ID_PATTERN`), so a step can never be NAMED `x.gate` and
15
+ * the synthetic `<stepId>.gate` node id is collision-free against user step
16
+ * ids. The phase column is nonetheless the discriminator we key on — an
17
+ * explicit marker, not a `node_id` suffix match, so recovery stays robust even
18
+ * if the id scheme evolves. Dispatch rows always journal `phase: null`.
19
+ */
20
+ export const GATE_EVALUATION_PHASE = "gate";
@@ -2,62 +2,242 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
5
+ import path from "node:path";
6
+ import { detectAdapterId } from "../../core/adapter/detect-adapter.js";
7
+ import { adapterForId } from "../../core/adapter/registry.js";
8
+ import { makeBundleRef, parseBundleRef } from "../../core/asset/asset-ref.js";
9
+ import { isWithin } from "../../core/common.js";
6
10
  import { loadConfig } from "../../core/config/config.js";
7
11
  import { NotFoundError, UsageError } from "../../core/errors.js";
8
12
  import { getDbPath } from "../../core/paths.js";
13
+ import { canonicalizeWorkflowName, WORKFLOW_EXTENSIONS } from "../../core/recognition-util.js";
14
+ import { deriveInstallations } from "../../indexer/installations.js";
9
15
  import { resolveSourceEntries } from "../../indexer/search/search-source.js";
10
- import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
16
+ import { buildFileContext } from "../../indexer/walk/file-context.js";
11
17
  import { resolveAssetPath } from "../../sources/resolve.js";
12
18
  import { withIndexDb } from "../../storage/repositories/index-db.js";
13
19
  import { formatWorkflowErrors } from "../authoring/authoring.js";
14
20
  import { parseWorkflow } from "../parser.js";
21
+ import { WORKFLOW_SCHEMA_VERSION } from "../schema.js";
15
22
  /**
16
- * Resolve a `workflow:<name>` ref to a fully-projected {@link WorkflowAsset}.
17
- *
18
- * Prefers the parsed document cached in `index.db` (fast path) and falls back to
19
- * reading + parsing the source file from disk. Pure loading/parsing concern —
20
- * extracted from the run repository so run orchestration no longer owns asset
21
- * resolution.
23
+ * Build the canonical `workflow_runs.workflow_ref` for an AKM workflow asset.
22
24
  */
23
- export async function loadWorkflowAsset(ref) {
24
- const parsed = parseAssetRef(ref);
25
- if (parsed.type !== "workflow") {
26
- throw new UsageError(`Expected a workflow ref (workflow:<name>), got "${ref}".`);
25
+ export function canonicalWorkflowRunRef(bundle, canonicalName) {
26
+ return makeBundleRef(bundle, `workflows/${canonicalName}`);
27
+ }
28
+ /** Parse a workflow ref using the canonical `[bundle//]conceptId` grammar. */
29
+ export function parseWorkflowRefInput(ref) {
30
+ const parsed = parseBundleRef(ref.trim());
31
+ if (parsed.fragment !== undefined) {
32
+ throw new UsageError(`Export fragment "#${parsed.fragment}" is not accepted in a workflow ref.`, "INVALID_FLAG_VALUE");
33
+ }
34
+ if (parsed.conceptId.startsWith("workflow:")) {
35
+ throw new UsageError(`Invalid workflow ref "${ref.trim()}". Use [bundle//]conceptId, such as workflows/release.`, "INVALID_FLAG_VALUE");
27
36
  }
37
+ return parsed;
38
+ }
39
+ /** Resolve input sugar to the workflow's canonical run identity. */
40
+ export async function canonicalizeWorkflowRefInput(ref) {
41
+ return (await loadWorkflowAsset(ref)).ref;
42
+ }
43
+ /**
44
+ * Resolve a workflow ref to a fully-projected {@link WorkflowAsset}. Prefers the
45
+ * parsed document cached in `index.db` (fast path) and falls back to reading +
46
+ * parsing the source file from disk.
47
+ */
48
+ export async function loadWorkflowAsset(ref) {
49
+ const bundleRef = parseWorkflowRefInput(ref);
28
50
  const config = loadConfig();
29
51
  const allSources = resolveSourceEntries(undefined, config);
30
- const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
52
+ const installations = deriveInstallations(allSources);
53
+ const searchSources = allSources.flatMap((source, index) => {
54
+ const bundleId = installations[index]?.id;
55
+ if (!bundleId || (bundleRef.bundle !== undefined && bundleRef.bundle !== bundleId))
56
+ return [];
57
+ return [{ source, bundleId }];
58
+ });
59
+ if (bundleRef.bundle && searchSources.length === 0) {
60
+ throw new UsageError(`Bundle "${bundleRef.bundle}" was not found among configured sources.`, "INVALID_FLAG_VALUE");
61
+ }
31
62
  let assetPath;
32
63
  let sourcePath;
33
- for (const source of searchSources) {
64
+ let sourceBundleId;
65
+ let workflowName;
66
+ let workflowAdapterId;
67
+ let rejectedSource;
68
+ for (const candidateSource of searchSources) {
69
+ const { source, bundleId } = candidateSource;
34
70
  try {
35
- assetPath = await resolveAssetPath(source.path, "workflow", parsed.name);
71
+ const adapterId = source.adapterId ?? detectAdapterId(source.path);
72
+ const candidateName = adapterId === "akm-workflow" ? bundleRef.conceptId : workflowNameFromConceptId(bundleRef.conceptId);
73
+ const ownedSource = source.adapterId ? source : { ...source, adapterId };
74
+ if (!candidateName) {
75
+ if (adapterOwnsConcept(source.path, adapterId, bundleRef.conceptId)) {
76
+ rejectedSource ??= { source: ownedSource, bundleId };
77
+ break;
78
+ }
79
+ continue;
80
+ }
81
+ const candidate = await resolveNativeWorkflowPath(source.path, adapterId, candidateName);
82
+ if (!ownsNativeWorkflowRuntime(ownedSource)) {
83
+ rejectedSource ??= { source: ownedSource, bundleId };
84
+ break;
85
+ }
86
+ assetPath = candidate;
36
87
  sourcePath = source.path;
88
+ sourceBundleId = bundleId;
89
+ workflowName = candidateName;
90
+ workflowAdapterId = adapterId;
37
91
  break;
38
92
  }
39
- catch {
40
- /* continue */
93
+ catch (error) {
94
+ if (error instanceof NotFoundError)
95
+ continue;
96
+ throw error;
41
97
  }
42
98
  }
43
99
  if (!assetPath) {
44
- throw new NotFoundError(`Workflow not found for ref: workflow:${parsed.name}`);
100
+ if (rejectedSource) {
101
+ const sourceName = rejectedSource.bundleId;
102
+ const adapterId = rejectedSource.source.adapterId ?? "unassigned";
103
+ throw new UsageError(`Bundle "${sourceName}" uses adapter "${adapterId}", which does not support native workflow execution.`, "INVALID_FLAG_VALUE");
104
+ }
105
+ throw new NotFoundError(`Workflow not found for ref: ${ref}`);
45
106
  }
46
- const resolvedSourcePath = sourcePath ?? config.stashDir ?? assetPath;
47
- const fullRef = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${parsed.name}`;
48
- const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef);
107
+ const resolvedSourcePath = sourcePath;
108
+ // Canonicalize the stored ref: `workflows/foo.md` and `workflows/foo` resolve
109
+ // to the same file, so they MUST share one run identity.
110
+ const canonicalName = canonicalizeWorkflowName(workflowName);
111
+ const fullRef = workflowAdapterId === "akm-workflow"
112
+ ? makeBundleRef(sourceBundleId, canonicalName)
113
+ : canonicalWorkflowRunRef(sourceBundleId, canonicalName);
114
+ const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef, workflowAdapterId);
49
115
  const document = cached ?? loadWorkflowDocumentFromDisk(assetPath);
50
- return projectAsset(document, fullRef, assetPath, resolvedSourcePath);
116
+ return projectAsset(document, fullRef, assetPath, resolvedSourcePath, workflowAdapterId, canonicalName);
117
+ }
118
+ function ownsNativeWorkflowRuntime(source) {
119
+ return source.adapterId === "akm" || source.adapterId === "akm-workflow";
120
+ }
121
+ function workflowNameFromConceptId(conceptId) {
122
+ const prefix = "workflows/";
123
+ return conceptId.startsWith(prefix) && conceptId.length > prefix.length ? conceptId.slice(prefix.length) : undefined;
124
+ }
125
+ function adapterOwnsConcept(sourcePath, adapterId, conceptId) {
126
+ const adapter = adapterForId(adapterId);
127
+ if (!adapter)
128
+ return false;
129
+ const normalized = conceptId.replaceAll("\\", "/");
130
+ if (!normalized ||
131
+ path.posix.isAbsolute(normalized) ||
132
+ normalized === ".." ||
133
+ normalized.startsWith("../") ||
134
+ path.posix.normalize(normalized) !== normalized) {
135
+ return false;
136
+ }
137
+ const extensions = [...adapter.extensions].sort((left, right) => right.length - left.length);
138
+ const extension = extensions.find((candidate) => normalized.toLowerCase().endsWith(candidate.toLowerCase()));
139
+ const extensionless = extension ? normalized.slice(0, -extension.length) : normalized;
140
+ const parent = path.join(sourcePath, path.posix.dirname(extensionless));
141
+ let realRoot;
142
+ let realParent;
143
+ try {
144
+ realRoot = fs.realpathSync(sourcePath);
145
+ realParent = fs.realpathSync(parent);
146
+ }
147
+ catch {
148
+ return false;
149
+ }
150
+ if (!isWithin(realParent, realRoot))
151
+ return false;
152
+ const basename = path.posix.basename(extensionless);
153
+ let entries;
154
+ try {
155
+ entries = fs.readdirSync(realParent, { withFileTypes: true });
156
+ }
157
+ catch {
158
+ return false;
159
+ }
160
+ for (const entry of entries) {
161
+ if (!entry.isFile())
162
+ continue;
163
+ const recognizedExtension = extensions.find((candidate) => entry.name.toLowerCase().endsWith(candidate.toLowerCase()) &&
164
+ entry.name.slice(0, -candidate.length) === basename);
165
+ if (!recognizedExtension)
166
+ continue;
167
+ const candidatePath = path.join(realParent, entry.name);
168
+ try {
169
+ const document = adapter.recognize({ id: adapterId, adapter: adapterId, root: realRoot, writable: false }, buildFileContext(realRoot, candidatePath));
170
+ if (document)
171
+ return true;
172
+ }
173
+ catch {
174
+ // A malformed matching file still belongs to the earlier adapter and cannot be bypassed for execution.
175
+ return true;
176
+ }
177
+ }
178
+ return false;
179
+ }
180
+ async function resolveNativeWorkflowPath(sourcePath, adapterId, name) {
181
+ if (adapterId !== "akm-workflow")
182
+ return resolveAssetPath(sourcePath, "workflow", name);
183
+ const canonicalName = canonicalizeWorkflowName(name);
184
+ let realRoot;
185
+ try {
186
+ realRoot = fs.realpathSync(sourcePath);
187
+ }
188
+ catch {
189
+ throw new NotFoundError(`Workflow bundle root not found: ${sourcePath}`);
190
+ }
191
+ const parent = path.join(sourcePath, path.dirname(canonicalName));
192
+ if (!isWithin(parent, realRoot)) {
193
+ throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
194
+ }
195
+ let entries;
196
+ try {
197
+ entries = fs.readdirSync(parent, { withFileTypes: true });
198
+ }
199
+ catch {
200
+ throw new NotFoundError(`Workflow not found: ${name}`);
201
+ }
202
+ const basename = path.basename(canonicalName);
203
+ for (const extension of WORKFLOW_EXTENSIONS) {
204
+ const matches = entries.filter((entry) => {
205
+ if (!entry.isFile() && !entry.isSymbolicLink())
206
+ return false;
207
+ const entryExtension = path.extname(entry.name);
208
+ return entryExtension.toLowerCase() === extension && entry.name.slice(0, -entryExtension.length) === basename;
209
+ });
210
+ if (matches.length > 1) {
211
+ throw new UsageError(`Workflow "${canonicalName}" has multiple ${extension} files that differ only by extension case.`, "RESOURCE_ALREADY_EXISTS");
212
+ }
213
+ const match = matches[0];
214
+ if (!match)
215
+ continue;
216
+ const candidate = path.join(parent, match.name);
217
+ let realTarget;
218
+ try {
219
+ if (!fs.statSync(candidate).isFile())
220
+ continue;
221
+ realTarget = fs.realpathSync(candidate);
222
+ }
223
+ catch {
224
+ continue;
225
+ }
226
+ if (!isWithin(realTarget, realRoot)) {
227
+ throw new UsageError("Workflow ref resolves outside the bundle root.", "PATH_ESCAPE_VIOLATION");
228
+ }
229
+ return realTarget;
230
+ }
231
+ throw new NotFoundError(`Workflow not found: ${name}`);
51
232
  }
52
233
  /**
53
234
  * Resolve the `entries.id` for an indexed workflow, or null when the index
54
235
  * database does not yet exist or has no matching entry.
55
236
  */
56
- export function resolveWorkflowEntryId(sourcePath, ref) {
237
+ export function resolveWorkflowEntryId(sourcePath, ref, adapterId) {
57
238
  if (!fs.existsSync(getDbPath()))
58
239
  return null;
59
- const parsed = parseAssetRef(ref);
60
- const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
240
+ const entryKey = workflowEntryKey(sourcePath, ref, adapterId);
61
241
  return withIndexDb((db) => {
62
242
  const row = db
63
243
  .prepare(`SELECT id
@@ -77,20 +257,19 @@ function loadWorkflowDocumentFromDisk(assetPath) {
77
257
  }
78
258
  return result.document;
79
259
  }
80
- function readWorkflowDocumentFromIndex(sourcePath, ref) {
260
+ function readWorkflowDocumentFromIndex(sourcePath, ref, adapterId) {
81
261
  if (!fs.existsSync(getDbPath()))
82
262
  return null;
83
- const parsed = parseAssetRef(ref);
84
- const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
263
+ const entryKey = workflowEntryKey(sourcePath, ref, adapterId);
85
264
  return withIndexDb((db) => {
86
265
  const row = db
87
- .prepare(`SELECT wd.document_json AS document_json
266
+ .prepare(`SELECT wd.document_json AS document_json, wd.schema_version AS schema_version
88
267
  FROM workflow_documents wd
89
268
  JOIN entries e ON e.id = wd.entry_id
90
269
  WHERE e.entry_type = 'workflow' AND e.entry_key = ?
91
270
  LIMIT 1`)
92
271
  .get(entryKey);
93
- if (!row)
272
+ if (!row || row.schema_version !== WORKFLOW_SCHEMA_VERSION)
94
273
  return null;
95
274
  try {
96
275
  return JSON.parse(row.document_json);
@@ -100,26 +279,48 @@ function readWorkflowDocumentFromIndex(sourcePath, ref) {
100
279
  }
101
280
  });
102
281
  }
103
- function projectAsset(doc, ref, assetPath, sourcePath) {
282
+ function workflowEntryKey(sourcePath, ref, adapterId) {
283
+ const bundleRef = parseBundleRef(ref);
284
+ if ((adapterId ?? detectAdapterId(sourcePath)) === "akm-workflow") {
285
+ return `${sourcePath}:concept:${bundleRef.conceptId}`;
286
+ }
287
+ const name = workflowNameFromConceptId(bundleRef.conceptId);
288
+ if (!name)
289
+ throw new UsageError(`Expected a workflow ref, got "${ref}".`);
290
+ return `${sourcePath}:workflow:${name}`;
291
+ }
292
+ function projectAsset(doc, ref, assetPath, sourcePath, adapterId, canonicalName) {
293
+ const title = canonicalName.split("/").pop() || canonicalName;
104
294
  return {
105
295
  ref,
106
296
  path: assetPath,
107
297
  sourcePath,
108
- title: doc.title,
109
- ...(doc.parameters
298
+ adapterId,
299
+ title,
300
+ ...(doc.params
110
301
  ? {
111
- parameters: doc.parameters.map((p) => ({
112
- name: p.name,
113
- ...(p.description ? { description: p.description } : {}),
114
- })),
302
+ parameters: Object.entries(doc.params).map(([name, schema]) => {
303
+ const description = schema.description;
304
+ return { name, ...(typeof description === "string" && description ? { description } : {}) };
305
+ }),
115
306
  }
116
307
  : {}),
117
308
  steps: doc.steps.map((s) => ({
118
309
  id: s.id,
119
- title: s.title,
120
- instructions: s.instructions.text,
121
- ...(s.completionCriteria ? { completionCriteria: s.completionCriteria.map((c) => c.text) } : {}),
310
+ title: s.id,
311
+ instructions: s.instructions?.text ?? stepFallbackInstructions(s),
312
+ ...(s.gateRubric?.text.trim() ? { completionCriteria: [s.gateRubric.text] } : {}),
122
313
  sequenceIndex: s.sequenceIndex,
123
314
  })),
315
+ document: doc,
124
316
  };
125
317
  }
318
+ /** A route-only step with no body section still needs a non-empty spine instructions string. */
319
+ function stepFallbackInstructions(step) {
320
+ if (!step.route)
321
+ return "";
322
+ const branches = step.route.branches.map((b) => `"${b.match}" -> ${b.stepId}`);
323
+ if (step.route.defaultStepId !== undefined)
324
+ branches.push(`default -> ${step.route.defaultStepId}`);
325
+ return `Route on ${step.route.input}: ${branches.join(", ")}.`;
326
+ }
@@ -1,14 +1,4 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- /**
5
- * Validated JSON shape for a workflow asset.
6
- *
7
- * `parseWorkflow` (parser.ts) converts a workflow markdown file into a
8
- * `WorkflowDocument` plus a list of `WorkflowError`s. The document is the
9
- * single source of truth consumed by the renderer, the indexer (cached
10
- * into `workflow_documents` in `index.db`), and the run engine. Source
11
- * markdown is referenced by `SourceRef` line spans so editors and agents
12
- * can rewrite content in place without a full re-parse.
13
- */
14
- export const WORKFLOW_SCHEMA_VERSION = 1;
4
+ export const WORKFLOW_SCHEMA_VERSION = 2;
@@ -11,8 +11,8 @@
11
11
  *
12
12
  * The LLM call is injected (`judge`) so the gate is unit-testable without a
13
13
  * live endpoint, and the whole gate is fail-open: when no criteria exist or no
14
- * judge is available the step completes as before. See
15
- * docs/technical/workflow-agent-checkin-adr.md.
14
+ * judge is available the step completes as before (per the workflow-agent
15
+ * check-in ADR).
16
16
  *
17
17
  * @module workflows/validate-summary
18
18
  */
@@ -56,7 +56,6 @@ export async function validateStepSummary(input, judge) {
56
56
  raw = await judge({ system: JUDGE_SYSTEM, user: buildUserPrompt({ ...input, completionCriteria: criteria }) });
57
57
  }
58
58
  catch {
59
- // LLM unreachable / errored — fail open so offline use keeps working.
60
59
  return { complete: true, missing: [], skipped: true };
61
60
  }
62
61
  const parsed = parseJsonResponse(raw);
@@ -1,44 +1,66 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- const STEP_ID_REGEX = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
5
- const ALLOWED_FRONTMATTER_KEYS = new Set(["description", "tags", "params", "name", "updated", "when_to_use"]);
4
+ /**
5
+ * Cross-cutting semantic checks over an assembled `WorkflowDocument` draft
6
+ * that need the whole document (not just one frontmatter key) at once.
7
+ *
8
+ * Per-key structural checks (unknown keys, id/param-name patterns, timeout
9
+ * format, retry taxonomy, route target ordering, duplicate ids, gate/body
10
+ * binding) all live in `parser.ts`, where line-anchored errors are cheapest to
11
+ * produce. The workflow-only closed frontmatter allowlist that used to live
12
+ * here (`ALLOWED_FRONTMATTER_KEYS`/`checkFrontmatterKeys`) is GONE —
13
+ * `schemas/akm-workflow.json` (`additionalProperties: false` over the shared
14
+ * asset envelope ∪ the workflow keys) is the closed-key authority now; this
15
+ * module only runs checks the schema cannot express (canonical xref shape,
16
+ * resource limits).
17
+ */
18
+ import { bundleRefToString, parseBundleRef } from "../core/asset/asset-ref.js";
19
+ import { utf8Bytes, WORKFLOW_MAX_INSTRUCTION_BYTES, WORKFLOW_MAX_PARAMS, WORKFLOW_MAX_STEPS } from "./resource-limits.js";
6
20
  export function runSemanticChecks(draft, frontmatterData, frontmatterEndLine, errors) {
7
- checkFrontmatterKeys(frontmatterData, frontmatterEndLine, errors);
8
- checkStepIdFormat(draft, errors);
9
- checkDuplicateStepIds(draft, errors);
21
+ checkXrefs(frontmatterData.xrefs, frontmatterEndLine, errors);
22
+ checkResourceLimits(draft, errors);
10
23
  }
11
- function checkFrontmatterKeys(data, fmEndLine, errors) {
12
- for (const key of Object.keys(data)) {
13
- if (ALLOWED_FRONTMATTER_KEYS.has(key))
14
- continue;
15
- errors.push({
16
- line: fmEndLine,
17
- message: `Workflow frontmatter "${key}" is not supported. Use only: description, tags, params, when_to_use.`,
18
- });
24
+ function checkXrefs(value, line, errors) {
25
+ if (value === undefined)
26
+ return;
27
+ if (!Array.isArray(value))
28
+ return; // shape already flagged by parser.ts's checkXrefs
29
+ for (const ref of value) {
30
+ try {
31
+ if (typeof ref !== "string")
32
+ throw new Error("non-canonical ref");
33
+ const parsed = parseBundleRef(ref);
34
+ if (parsed.conceptId.includes(":") || ref !== bundleRefToString(parsed))
35
+ throw new Error("non-canonical ref");
36
+ }
37
+ catch {
38
+ errors.push({
39
+ line,
40
+ message: `Workflow frontmatter "xrefs" contains an invalid or non-canonical ref: ${String(ref)}.`,
41
+ });
42
+ }
19
43
  }
20
44
  }
21
- function checkStepIdFormat(draft, errors) {
22
- for (const step of draft.steps) {
23
- if (STEP_ID_REGEX.test(step.id))
24
- continue;
25
- errors.push({
26
- line: step.source.start,
27
- message: `Step ID "${step.id}" is invalid. Use letters, numbers, ".", "_" or "-" (e.g. "deploy-job").`,
28
- });
45
+ function checkResourceLimits(draft, errors) {
46
+ if (draft.steps.length > WORKFLOW_MAX_STEPS) {
47
+ errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_STEPS} steps.` });
48
+ }
49
+ if (Object.keys(draft.params ?? {}).length > WORKFLOW_MAX_PARAMS) {
50
+ errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_PARAMS} parameters.` });
29
51
  }
30
- }
31
- function checkDuplicateStepIds(draft, errors) {
32
- const firstSeenLine = new Map();
33
52
  for (const step of draft.steps) {
34
- const previous = firstSeenLine.get(step.id);
35
- if (previous !== undefined) {
53
+ if (step.instructions && utf8Bytes(step.instructions.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
54
+ errors.push({
55
+ line: step.instructions.source.start,
56
+ message: `Step "${step.id}" instructions exceed the 256 KiB resource limit.`,
57
+ });
58
+ }
59
+ if (step.gateRubric && utf8Bytes(step.gateRubric.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
36
60
  errors.push({
37
- line: step.source.start,
38
- message: `Step ID "${step.id}" is already used on line ${previous}. Step IDs must be unique within a workflow.`,
61
+ line: step.gateRubric.source.start,
62
+ message: `Step "${step.id}" gate rubric exceeds the 256 KiB resource limit.`,
39
63
  });
40
- continue;
41
64
  }
42
- firstSeenLine.set(step.id, step.source.start);
43
65
  }
44
66
  }