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,4 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ export {};
@@ -0,0 +1,93 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ const ENV_OPTIONS_WITH_OPERAND = new Set(["--argv0", "--chdir", "--unset"]);
5
+ const ENV_OPTIONS_WITH_OPTIONAL_VALUE = new Set(["--block-signal", "--default-signal", "--ignore-signal"]);
6
+ const ENV_OPTIONS_WITHOUT_OPERAND = new Set(["--debug", "--ignore-environment", "--list-signal-handling"]);
7
+ /** Locate a command whose executable position clearly names AKM, including an explicit path. */
8
+ export function findAkmExecutableIndex(command) {
9
+ if (command.length === 0)
10
+ return undefined;
11
+ const executableIndex = isEnvExecutable(command[0]) ? findEnvCommandIndex(command) : 0;
12
+ if (executableIndex === undefined || !isAkmExecutable(command[executableIndex]))
13
+ return undefined;
14
+ return executableIndex;
15
+ }
16
+ /** Locate only PATH-selected AKM, which is safe to redirect to the current installation. */
17
+ export function findBareAkmExecutableIndex(command) {
18
+ const executableIndex = findAkmExecutableIndex(command);
19
+ if (executableIndex === undefined || !isBareAkm(command[executableIndex]))
20
+ return undefined;
21
+ return executableIndex;
22
+ }
23
+ function findEnvCommandIndex(command) {
24
+ let index = 1;
25
+ while (index < command.length) {
26
+ const part = command[index];
27
+ if (part === "--") {
28
+ index += 1;
29
+ break;
30
+ }
31
+ if (isEnvironmentAssignment(part))
32
+ break;
33
+ if (!part.startsWith("-"))
34
+ break;
35
+ const operandCount = envOptionOperandCount(part);
36
+ if (operandCount === undefined || index + operandCount >= command.length)
37
+ return undefined;
38
+ index += operandCount + 1;
39
+ }
40
+ while (index < command.length && isEnvironmentAssignment(command[index]))
41
+ index += 1;
42
+ return index < command.length ? index : undefined;
43
+ }
44
+ function envOptionOperandCount(option) {
45
+ if (option === "-")
46
+ return 0;
47
+ if (ENV_OPTIONS_WITHOUT_OPERAND.has(option) || ENV_OPTIONS_WITH_OPTIONAL_VALUE.has(option))
48
+ return 0;
49
+ if ([...ENV_OPTIONS_WITH_OPTIONAL_VALUE].some((prefix) => option.startsWith(`${prefix}=`)))
50
+ return 0;
51
+ if (ENV_OPTIONS_WITH_OPERAND.has(option))
52
+ return 1;
53
+ if (["--argv0=", "--chdir=", "--unset="].some((prefix) => option.startsWith(prefix)))
54
+ return 0;
55
+ if (!option.startsWith("-") || option.startsWith("--"))
56
+ return undefined;
57
+ const shortOptions = option.slice(1);
58
+ for (let index = 0; index < shortOptions.length; index += 1) {
59
+ const flag = shortOptions[index];
60
+ if (flag === "i" || flag === "v")
61
+ continue;
62
+ if (flag === "S")
63
+ return undefined;
64
+ if (flag === "u" || flag === "C" || flag === "P" || flag === "a") {
65
+ return index === shortOptions.length - 1 ? 1 : 0;
66
+ }
67
+ return undefined;
68
+ }
69
+ return shortOptions.length > 0 ? 0 : undefined;
70
+ }
71
+ function isEnvironmentAssignment(value) {
72
+ return /^[A-Za-z_][A-Za-z0-9_]*=/.test(value);
73
+ }
74
+ function isEnvExecutable(value) {
75
+ if (!value)
76
+ return false;
77
+ if (value === "env")
78
+ return true;
79
+ if (!isAbsolutePath(value))
80
+ return false;
81
+ return /^env(?:\.exe)?$/i.test(value.split(/[\\/]/).at(-1) ?? "");
82
+ }
83
+ function isAbsolutePath(value) {
84
+ return value.startsWith("/") || value.startsWith("\\\\") || /^[A-Za-z]:[\\/]/.test(value);
85
+ }
86
+ function isBareAkm(value) {
87
+ return value !== undefined && /^akm(?:\.exe)?$/i.test(value);
88
+ }
89
+ function isAkmExecutable(value) {
90
+ if (!value)
91
+ return false;
92
+ return /^akm(?:\.exe)?$/i.test(value.split(/[\\/]/).at(-1) ?? "");
93
+ }
@@ -2,14 +2,18 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  /**
5
- * Embedded core task templates.
5
+ * Embedded task templates.
6
6
  *
7
- * A curated set of read-only YAML task templates ships inside the akm binary
8
- * under `src/assets/tasks/core/`. They are resolved at runtime via
7
+ * Curated sets of read-only YAML task templates ship inside the akm binary
8
+ * under `src/assets/tasks/<category>/` — `core/` (general-purpose maintenance)
9
+ * and `improve/` (the maintainer-oriented multi-cadence improve schedule,
10
+ * folded in from the retired `registerDefaultTasks`/`akm tasks init` path in
11
+ * 0.9, S6). Every category subdirectory is enumerated the same way; adding a
12
+ * new one needs no code change here. Templates are resolved at runtime via
9
13
  * `import.meta.dir` (mirroring `SKELETON_DIR` in
10
14
  * src/commands/stash-skeleton.ts) and are NOT written to any stash at
11
- * install/init time — the `akm setup` wizard copies a template into the
12
- * primary stash only when the user opts in (copy-on-enable).
15
+ * install time — the `akm setup` wizard copies a template into the primary
16
+ * stash only when the user opts in (copy-on-enable).
13
17
  *
14
18
  * Each entry exposes the parsed `command`, `schedule`, and `description`
15
19
  * alongside the raw `yaml`, so the wizard can both render a choice and write
@@ -17,55 +21,69 @@
17
21
  */
18
22
  import fs from "node:fs";
19
23
  import path from "node:path";
20
- import { parse as yamlParse } from "yaml";
21
24
  import { getDirname } from "../runtime.js";
22
- /** Directory holding the bundled core task templates. */
23
- const CORE_TASKS_DIR = path.join(getDirname(import.meta.url), "../assets/tasks/core");
25
+ import { parseTaskDocument } from "./parser.js";
26
+ /** Directory holding the bundled task template categories. */
27
+ const TASKS_ASSETS_DIR = path.join(getDirname(import.meta.url), "../assets/tasks");
24
28
  /**
25
- * Enumerate the embedded core task templates from the bundled assets
26
- * directory. Sorted by id for deterministic ordering. Returns an empty array
27
- * if the directory is missing (defensive — a build without assets should not
28
- * crash the wizard).
29
+ * Enumerate the embedded task templates from every category subdirectory of
30
+ * the bundled assets directory. Sorted by category then id for deterministic
31
+ * ordering. Returns an empty array if the directory is missing (defensive —
32
+ * a build without assets should not crash the wizard).
29
33
  */
30
34
  export function listEmbeddedTasks() {
31
- let entries;
35
+ let categories;
32
36
  try {
33
- entries = fs.readdirSync(CORE_TASKS_DIR);
37
+ categories = fs
38
+ .readdirSync(TASKS_ASSETS_DIR, { withFileTypes: true })
39
+ .filter((entry) => entry.isDirectory())
40
+ .map((entry) => entry.name)
41
+ .sort();
34
42
  }
35
43
  catch {
36
44
  return [];
37
45
  }
38
46
  const tasks = [];
39
- for (const entry of entries.sort()) {
40
- if (!entry.endsWith(".yml"))
41
- continue;
42
- const id = entry.slice(0, -4);
43
- const filePath = path.join(CORE_TASKS_DIR, entry);
44
- let yaml;
47
+ for (const category of categories) {
48
+ const categoryDir = path.join(TASKS_ASSETS_DIR, category);
49
+ let entries;
45
50
  try {
46
- yaml = fs.readFileSync(filePath, "utf8");
51
+ entries = fs.readdirSync(categoryDir);
47
52
  }
48
53
  catch {
49
54
  continue;
50
55
  }
51
- let doc;
52
- try {
53
- doc = yamlParse(yaml) ?? {};
54
- }
55
- catch {
56
- continue;
56
+ for (const entry of entries.sort()) {
57
+ if (!entry.endsWith(".yml"))
58
+ continue;
59
+ const id = entry.slice(0, -4);
60
+ const filePath = path.join(categoryDir, entry);
61
+ let yaml;
62
+ try {
63
+ yaml = fs.readFileSync(filePath, "utf8");
64
+ }
65
+ catch {
66
+ continue;
67
+ }
68
+ let task;
69
+ try {
70
+ task = parseTaskDocument({ yaml, filePath, id });
71
+ }
72
+ catch {
73
+ continue;
74
+ }
75
+ if (task.target.kind !== "command")
76
+ continue;
77
+ tasks.push({
78
+ id,
79
+ label: `${category}/${id}`,
80
+ command: task.target.cmd.join(" "),
81
+ schedule: task.schedule,
82
+ description: task.description ?? "",
83
+ enabled: task.enabled,
84
+ yaml,
85
+ });
57
86
  }
58
- const command = typeof doc.command === "string" ? doc.command : "";
59
- const schedule = typeof doc.schedule === "string" ? doc.schedule : "";
60
- const description = typeof doc.description === "string" ? doc.description : "";
61
- tasks.push({
62
- id,
63
- label: `core/${id}`,
64
- command,
65
- schedule,
66
- description,
67
- yaml,
68
- });
69
87
  }
70
88
  return tasks;
71
89
  }
@@ -9,11 +9,11 @@
9
9
  * ```yaml
10
10
  * schedule: "0 9 * * *"
11
11
  * # one of:
12
- * workflow: workflow:daily-backup
12
+ * workflow: workflows/daily-backup
13
13
  * params:
14
14
  * region: us-east-1
15
15
  * # ...or:
16
- * prompt: agent:my-agent # asset ref
16
+ * prompt: agents/my-agent # asset ref
17
17
  * # ...or:
18
18
  * prompt: ./prompts/my-prompt.md # relative file path
19
19
  * # ...or:
@@ -21,7 +21,7 @@
21
21
  * Do the thing.
22
22
  * And the other thing.
23
23
  * # ...or:
24
- * command: akm improve --auto-accept=90 --limit 25
24
+ * command: akm improve --strategy quick --limit 25
25
25
  * enabled: true # default true
26
26
  * name: Daily backup
27
27
  * description: …
@@ -29,16 +29,20 @@
29
29
  * tags: [scheduled, backup]
30
30
  * ```
31
31
  *
32
- * Validation lives in {@link validateTaskDocument}. The parser only enforces
33
- * shape; cron syntax, target reachability, and profile availability are
32
+ * Validation lives in {@link validateTaskDocument}. The parser enforces the
33
+ * strict source shape; cron syntax and target reachability are
34
34
  * checked separately so callers can choose how strictly to surface errors.
35
35
  */
36
36
  import path from "node:path";
37
37
  import { parse as parseYaml } from "yaml";
38
+ import { isFullRefInput } from "../core/asset/resolve-ref.js";
38
39
  import { UsageError } from "../core/errors.js";
40
+ import { formatExtraParamsIssue, validateExtraParams } from "../core/extra-params.js";
39
41
  import { TASK_SCHEMA_VERSION } from "./schema.js";
42
+ import { validateTaskId } from "./task-id.js";
40
43
  export function parseTaskDocument(input) {
41
- const { yaml, filePath, id } = input;
44
+ const { yaml, filePath } = input;
45
+ const id = validateTaskId(input.id);
42
46
  let data;
43
47
  try {
44
48
  const parsed = parseYaml(yaml);
@@ -52,15 +56,17 @@ export function parseTaskDocument(input) {
52
56
  throw err;
53
57
  throw new UsageError(`Task "${id}" has invalid YAML: ${err instanceof Error ? err.message : String(err)}. File: ${filePath}`, "INVALID_FLAG_VALUE");
54
58
  }
55
- const schedule = readString(data.schedule, "schedule", filePath);
59
+ requireVersion(data, id, filePath);
60
+ rejectUnknownKeys(data, id, filePath);
61
+ const schedule = requireString(data.schedule, "schedule", filePath);
56
62
  if (!schedule) {
57
63
  throw new UsageError(`Task "${id}" is missing a schedule (YAML key "schedule"). File: ${filePath}`, "MISSING_REQUIRED_ARGUMENT");
58
64
  }
59
- const enabled = data.enabled === undefined ? true : data.enabled === true;
60
- const name = readString(data.name, "name", filePath);
61
- const description = readString(data.description, "description", filePath);
62
- const when_to_use = readString(data.when_to_use, "when_to_use", filePath);
63
- const tags = readStringArray(data.tags);
65
+ const enabled = readEnabled(data.enabled, filePath);
66
+ const name = optionalString(data.name, "name", filePath);
67
+ const description = optionalString(data.description, "description", filePath);
68
+ const when_to_use = optionalString(data.when_to_use, "when_to_use", filePath);
69
+ const tags = readTags(data.tags, filePath);
64
70
  const hasWorkflow = "workflow" in data && data.workflow !== "" && data.workflow != null;
65
71
  const hasPrompt = "prompt" in data && data.prompt !== "" && data.prompt != null;
66
72
  const hasCommand = "command" in data && data.command !== "" && data.command != null;
@@ -73,7 +79,8 @@ export function parseTaskDocument(input) {
73
79
  }
74
80
  let target;
75
81
  if (hasWorkflow) {
76
- const ref = readString(data.workflow, "workflow", filePath);
82
+ rejectTargetFields(data, ["params"], id, filePath);
83
+ const ref = requireString(data.workflow, "workflow", filePath);
77
84
  if (!ref) {
78
85
  throw new UsageError(`Task "${id}" has empty \`workflow\`. File: ${filePath}`, "INVALID_FLAG_VALUE");
79
86
  }
@@ -84,98 +91,146 @@ export function parseTaskDocument(input) {
84
91
  };
85
92
  }
86
93
  else if (hasCommand) {
87
- const cmd = readCommand(data.command, filePath, id);
88
- target = { kind: "command", cmd };
94
+ rejectTargetFields(data, ["timeoutMs"], id, filePath);
95
+ target = { kind: "command", cmd: readCommand(data.command, filePath, id) };
89
96
  }
90
97
  else {
91
- const promptRaw = readString(data.prompt, "prompt", filePath);
98
+ rejectTargetFields(data, ["engine", "model", "timeoutMs", "llm"], id, filePath);
99
+ const promptRaw = requireString(data.prompt, "prompt", filePath);
92
100
  if (!promptRaw) {
93
101
  throw new UsageError(`Task "${id}" has empty \`prompt\`. File: ${filePath}`, "INVALID_FLAG_VALUE");
94
102
  }
95
- const profile = readString(data.profile, "profile", filePath);
103
+ const engine = optionalString(data.engine, "engine", filePath);
104
+ const model = optionalString(data.model, "model", filePath);
105
+ const timeoutMs = readTimeout(data.timeoutMs, filePath);
106
+ const llm = readLlmOverrides(data.llm, filePath);
96
107
  target = {
97
108
  kind: "prompt",
98
109
  source: resolvePromptSource(promptRaw, filePath, id),
99
- profile: profile && profile.length > 0 ? profile : undefined,
110
+ ...(engine ? { engine } : {}),
111
+ ...(model ? { model } : {}),
112
+ ...(timeoutMs !== undefined ? { timeoutMs } : {}),
113
+ ...(llm ? { llm } : {}),
100
114
  };
101
115
  }
102
- // null / 0 / negative → disabled (no timeout). Positive number → override.
103
- // Omitted → undefined (inherits config.agent.timeoutMs).
104
- let timeoutMs;
105
- if ("timeoutMs" in data) {
106
- const raw = data.timeoutMs;
107
- if (raw === null || raw === "null" || raw === 0 || (typeof raw === "number" && raw < 0)) {
108
- timeoutMs = null;
109
- }
110
- else if (typeof raw === "number" && raw > 0) {
111
- timeoutMs = raw;
112
- }
113
- // non-numeric / unrecognised → leave as undefined (inherit)
114
- }
116
+ const timeoutMs = hasCommand ? readTimeout(data.timeoutMs, filePath) : undefined;
115
117
  return {
118
+ version: TASK_SCHEMA_VERSION,
116
119
  schemaVersion: TASK_SCHEMA_VERSION,
117
120
  id,
118
121
  schedule,
119
122
  enabled,
120
123
  target,
121
- name: name && name.length > 0 ? name : undefined,
122
- description: description && description.length > 0 ? description : undefined,
123
- when_to_use: when_to_use && when_to_use.length > 0 ? when_to_use : undefined,
124
- tags: tags && tags.length > 0 ? tags : undefined,
124
+ ...(name ? { name } : {}),
125
+ ...(description ? { description } : {}),
126
+ ...(when_to_use ? { when_to_use } : {}),
127
+ ...(tags ? { tags } : {}),
125
128
  source: { path: filePath },
126
129
  timeoutMs,
127
130
  };
128
131
  }
132
+ const TASK_KEYS = new Set([
133
+ "version",
134
+ "name",
135
+ "description",
136
+ "when_to_use",
137
+ "tags",
138
+ "schedule",
139
+ "enabled",
140
+ "workflow",
141
+ "prompt",
142
+ "command",
143
+ "params",
144
+ "engine",
145
+ "model",
146
+ "timeoutMs",
147
+ "llm",
148
+ ]);
149
+ const SHARED_KEYS = new Set(["version", "name", "description", "when_to_use", "tags", "schedule", "enabled"]);
150
+ function requireVersion(data, id, filePath) {
151
+ if (data.version === TASK_SCHEMA_VERSION)
152
+ return;
153
+ const actual = data.version === undefined ? "missing" : JSON.stringify(data.version);
154
+ throw new UsageError(`TASK_SCHEMA_VERSION_UNSUPPORTED: Task "${id}" uses task schema version ${actual}; version: 2 is required. File: ${filePath}`, "TASK_SCHEMA_VERSION_UNSUPPORTED", "Use task schema version: 2.");
155
+ }
156
+ function rejectUnknownKeys(data, id, filePath) {
157
+ const unknown = Object.keys(data).filter((key) => !TASK_KEYS.has(key));
158
+ if (unknown.length > 0) {
159
+ throw new UsageError(`Task "${id}" has unknown key(s): ${unknown.join(", ")}. File: ${filePath}`, "INVALID_FLAG_VALUE");
160
+ }
161
+ }
162
+ function rejectTargetFields(data, allowed, id, filePath) {
163
+ const forbidden = Object.keys(data).filter((key) => !SHARED_KEYS.has(key) && !allowed.includes(key) && !["workflow", "prompt", "command"].includes(key));
164
+ if (forbidden.length > 0) {
165
+ throw new UsageError(`Task "${id}" has field(s) not valid for this target: ${forbidden.join(", ")}. File: ${filePath}`, "INVALID_FLAG_VALUE");
166
+ }
167
+ }
129
168
  /**
130
169
  * Resolve a `prompt:` value into a {@link TaskPromptSource} variant.
131
170
  *
132
- * • "<type>:<name>" (asset ref) → asset
171
+ * • "[bundle//]<subdir>/<name>" (asset ref) → asset
133
172
  * • "./foo.md", "../foo.md", "/abs" → file
134
173
  * • "C:\\abs" (Windows absolute) → file
135
- * • anything else (incl. block scalars) → inline text
174
+ * • anything else (including colon text and block scalars) → inline text
136
175
  */
137
176
  function resolvePromptSource(raw, filePath, id) {
138
177
  const trimmed = raw.trim();
178
+ if (!trimmed) {
179
+ throw new UsageError(`Task "${id}" has empty \`prompt\`. File: ${filePath}`, "MISSING_REQUIRED_ARGUMENT");
180
+ }
139
181
  if (trimmed.startsWith("./") || trimmed.startsWith("../") || path.isAbsolute(trimmed)) {
140
182
  return { kind: "file", path: trimmed };
141
183
  }
142
184
  if (/^[A-Za-z]:[\\/]/.test(trimmed)) {
143
185
  return { kind: "file", path: trimmed };
144
186
  }
145
- if (/^[a-z][a-z0-9_-]*:[^\s]/i.test(trimmed)) {
187
+ // Canonical 0.9.0 asset ref: `[bundle//]<stash-subdir>/<name>`. Detection is
188
+ // delegated to the canonical parser (never a hand-rolled regex) — only a
189
+ // conceptId whose leading segment is a real stash subdir counts as a ref; a
190
+ // bare `word/word` inline prompt (no known subdir) stays inline text (D-R3).
191
+ if (isFullRefInput(trimmed)) {
146
192
  return { kind: "asset", ref: trimmed };
147
193
  }
148
- if (!trimmed) {
149
- throw new UsageError(`Task "${id}" has empty \`prompt\`. File: ${filePath}`, "MISSING_REQUIRED_ARGUMENT");
150
- }
151
194
  return { kind: "inline", text: trimmed };
152
195
  }
153
- function readString(value, key, filePath) {
196
+ function optionalString(value, key, filePath) {
154
197
  if (value === undefined || value === null)
155
198
  return undefined;
156
199
  if (typeof value === "string")
157
- return value.trim();
158
- if (typeof value === "number" || typeof value === "boolean")
159
- return String(value);
200
+ return value;
160
201
  throw new UsageError(`Key "${key}" must be a string. File: ${filePath}`, "INVALID_FLAG_VALUE");
161
202
  }
162
- function readStringArray(value) {
203
+ function requireString(value, key, filePath) {
204
+ const result = optionalString(value, key, filePath);
205
+ if (result === undefined || result.length === 0) {
206
+ throw new UsageError(`Key "${key}" must be a non-empty string. File: ${filePath}`, "INVALID_FLAG_VALUE");
207
+ }
208
+ return result;
209
+ }
210
+ function readEnabled(value, filePath) {
211
+ if (value === undefined)
212
+ return true;
213
+ if (typeof value !== "boolean")
214
+ throw new UsageError(`Key "enabled" must be a boolean. File: ${filePath}`, "INVALID_FLAG_VALUE");
215
+ return value;
216
+ }
217
+ function readTags(value, filePath) {
163
218
  if (value === undefined || value === null)
164
219
  return undefined;
165
- if (typeof value === "string") {
166
- return value
167
- .split(/[\s,]+/)
168
- .map((s) => s.trim())
169
- .filter(Boolean);
170
- }
171
220
  if (Array.isArray(value)) {
172
- return value.filter((v) => typeof v === "string" && v.trim().length > 0);
221
+ if (!value.every((entry) => typeof entry === "string" && entry.length > 0)) {
222
+ throw new UsageError(`Key "tags" must be an array of non-empty strings. File: ${filePath}`, "INVALID_FLAG_VALUE");
223
+ }
224
+ return value;
173
225
  }
174
- return undefined;
226
+ throw new UsageError(`Key "tags" must be an array of strings. File: ${filePath}`, "INVALID_FLAG_VALUE");
175
227
  }
176
228
  function readCommand(value, filePath, id) {
177
229
  if (Array.isArray(value)) {
178
- const parts = value.filter((v) => typeof v === "string" && v.trim().length > 0);
230
+ if (!value.every((entry) => typeof entry === "string" && entry.length > 0)) {
231
+ throw new UsageError(`Task "${id}" command array must contain non-empty strings. File: ${filePath}`, "INVALID_FLAG_VALUE");
232
+ }
233
+ const parts = value;
179
234
  if (parts.length === 0) {
180
235
  throw new UsageError(`Task "${id}" has empty \`command\` array. File: ${filePath}`, "INVALID_FLAG_VALUE");
181
236
  }
@@ -196,16 +251,53 @@ function readParams(value, filePath) {
196
251
  if (typeof value === "object" && !Array.isArray(value)) {
197
252
  return value;
198
253
  }
199
- if (typeof value === "string" && value.trim()) {
200
- try {
201
- const parsed = JSON.parse(value);
202
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
203
- return parsed;
204
- }
254
+ throw new UsageError(`Key "params" must be a mapping. File: ${filePath}`, "INVALID_FLAG_VALUE");
255
+ }
256
+ function readTimeout(value, filePath) {
257
+ if (value === undefined)
258
+ return undefined;
259
+ if (value === null)
260
+ return null;
261
+ if (typeof value === "number" && Number.isInteger(value) && value > 0)
262
+ return value;
263
+ throw new UsageError(`Key "timeoutMs" must be a positive integer or null. File: ${filePath}`, "INVALID_FLAG_VALUE");
264
+ }
265
+ function readLlmOverrides(value, filePath) {
266
+ if (value === undefined)
267
+ return undefined;
268
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
269
+ throw new UsageError(`Key "llm" must be a mapping. File: ${filePath}`, "INVALID_FLAG_VALUE");
270
+ }
271
+ const data = value;
272
+ const allowed = new Set([
273
+ "temperature",
274
+ "maxTokens",
275
+ "supportsJsonSchema",
276
+ "extraParams",
277
+ "contextLength",
278
+ "enableThinking",
279
+ ]);
280
+ const unknown = Object.keys(data).filter((key) => !allowed.has(key));
281
+ if (unknown.length)
282
+ throw new UsageError(`Key "llm" has unknown field(s): ${unknown.join(", ")}. File: ${filePath}`, "INVALID_FLAG_VALUE");
283
+ if (data.temperature !== undefined && (typeof data.temperature !== "number" || !Number.isFinite(data.temperature))) {
284
+ throw new UsageError(`Key "llm.temperature" must be a finite number. File: ${filePath}`, "INVALID_FLAG_VALUE");
285
+ }
286
+ for (const key of ["maxTokens", "contextLength"]) {
287
+ if (data[key] !== undefined && (!Number.isInteger(data[key]) || data[key] <= 0)) {
288
+ throw new UsageError(`Key "llm.${key}" must be a positive integer. File: ${filePath}`, "INVALID_FLAG_VALUE");
289
+ }
290
+ }
291
+ for (const key of ["supportsJsonSchema", "enableThinking"]) {
292
+ if (data[key] !== undefined && typeof data[key] !== "boolean") {
293
+ throw new UsageError(`Key "llm.${key}" must be a boolean. File: ${filePath}`, "INVALID_FLAG_VALUE");
205
294
  }
206
- catch {
207
- // fall through
295
+ }
296
+ if (data.extraParams !== undefined) {
297
+ const issue = validateExtraParams(data.extraParams)[0];
298
+ if (issue) {
299
+ throw new UsageError(`${formatExtraParamsIssue('Key "llm.extraParams"', issue)}. File: ${filePath}`, "INVALID_FLAG_VALUE");
208
300
  }
209
301
  }
210
- throw new UsageError(`Key "params" must be a mapping or a JSON object. File: ${filePath}`, "INVALID_FLAG_VALUE");
302
+ return data;
211
303
  }