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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -13,9 +13,9 @@
13
13
  */
14
14
  import { resolveStashDir } from "../../core/common.js";
15
15
  import { loadConfig } from "../../core/config/config.js";
16
- import { UsageError } from "../../core/errors.js";
17
- import { appendEvent } from "../../core/events.js";
18
- import { archiveProposal, createProposal, diffProposal, getProposal, isProposalSkipped, listProposals, promoteProposal, resolveProposalId, revertProposal, } from "./repository.js";
16
+ import { resolveWriteTarget } from "../../core/write-source.js";
17
+ import { withAssetMutationLease } from "../../indexer/index-writer-lock.js";
18
+ import { createProposal, diffProposal, isProposalSkipped, listProposals, promoteProposal, proposalContent, recoverProposalTransactionsForStash, rejectProposalDurably, resolveProposalId, resolveProposalIdForReject, revertProposal, } from "./repository.js";
19
19
  import { validateProposal } from "./validators/proposals.js";
20
20
  // ── Shared helpers ──────────────────────────────────────────────────────────
21
21
  function resolveStash(stashDir) {
@@ -23,6 +23,14 @@ function resolveStash(stashDir) {
23
23
  return stashDir;
24
24
  return resolveStashDir();
25
25
  }
26
+ function resolveProposalQueue(stashDir, queue, config) {
27
+ if (stashDir)
28
+ return { stashDir };
29
+ if (!queue)
30
+ return { stashDir: resolveStash() };
31
+ const target = resolveWriteTarget(config ?? loadConfig(), queue);
32
+ return { stashDir: target.source.path, target };
33
+ }
26
34
  /**
27
35
  * Thin in-process read of the pending proposal queue, used by the health HTML
28
36
  * report builder (#582) so it never shells out to `akm proposal list`.
@@ -35,7 +43,7 @@ export function listPendingProposals(stashDir) {
35
43
  return listProposals(resolveStash(stashDir), { status: "pending" });
36
44
  }
37
45
  export function akmProposalList(options = {}) {
38
- const stash = resolveStash(options.stashDir);
46
+ const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, options.config);
39
47
  // `--status accepted|rejected|reverted` implies archive-inclusion since the
40
48
  // live queue only ever contains pending entries.
41
49
  const includeArchive = options.includeArchive === true ||
@@ -51,8 +59,8 @@ export function akmProposalList(options = {}) {
51
59
  return { schemaVersion: 1, totalCount: proposals.length, proposals };
52
60
  }
53
61
  export function akmProposalShow(options) {
54
- const stash = resolveStash(options.stashDir);
55
- const proposal = getProposal(stash, options.id);
62
+ const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, options.config);
63
+ const proposal = resolveProposalId(stash, options.id);
56
64
  return {
57
65
  schemaVersion: 1,
58
66
  proposal,
@@ -60,29 +68,11 @@ export function akmProposalShow(options) {
60
68
  };
61
69
  }
62
70
  export async function akmProposalAccept(options) {
63
- const stash = resolveStash(options.stashDir);
64
71
  const config = options.config ?? loadConfig();
72
+ const queue = resolveProposalQueue(options.stashDir, options.queue, config);
73
+ const stash = queue.stashDir;
65
74
  const resolvedId = resolveProposalId(stash, options.id).id;
66
- const result = await promoteProposal(stash, config, resolvedId, { target: options.target }, options.ctx);
67
- // Emit `promoted` to the events stream so observers (audit, dashboards,
68
- // sync) see the accept happen. Only emit on the happy path — promotion
69
- // throws on validation failure, so reaching this point means the asset
70
- // is committed.
71
- appendEvent({
72
- eventType: "promoted",
73
- ref: result.ref,
74
- metadata: {
75
- proposalId: result.proposal.id,
76
- source: result.proposal.source,
77
- ...(result.proposal.sourceRun !== undefined ? { sourceRun: result.proposal.sourceRun } : {}),
78
- assetPath: result.assetPath,
79
- // Attribution tagging: carry the eligibility lane from the proposal record
80
- // onto the promoted event so accept outcomes can be sliced by lane.
81
- ...(result.proposal.eligibilitySource !== undefined
82
- ? { eligibilitySource: result.proposal.eligibilitySource }
83
- : {}),
84
- },
85
- });
75
+ const result = await promoteProposal(stash, config, resolvedId, { target: options.target, queueTarget: queue.target, gateDecision: options.gateDecision }, options.ctx);
86
76
  return {
87
77
  schemaVersion: 1,
88
78
  ok: true,
@@ -92,37 +82,32 @@ export async function akmProposalAccept(options) {
92
82
  proposal: result.proposal,
93
83
  };
94
84
  }
95
- export function akmProposalReject(options) {
96
- const stash = resolveStash(options.stashDir);
97
- const existing = resolveProposalId(stash, options.id);
98
- if (existing.status !== "pending") {
99
- throw new UsageError(`Proposal ${existing.id} is not pending (current status: ${existing.status}). Only pending proposals can be rejected.`, "INVALID_FLAG_VALUE");
100
- }
101
- const updated = archiveProposal(stash, existing.id, "rejected", options.reason, options.ctx);
102
- appendEvent({
103
- eventType: "rejected",
104
- ref: updated.ref,
105
- metadata: {
106
- proposalId: updated.id,
107
- source: updated.source,
108
- ...(updated.sourceRun !== undefined ? { sourceRun: updated.sourceRun } : {}),
85
+ export async function akmProposalReject(options) {
86
+ return withAssetMutationLease("proposal-reject", async () => {
87
+ const config = options.config ?? loadConfig();
88
+ const { stashDir: stash } = resolveProposalQueue(options.stashDir, options.queue, config);
89
+ // resolveProposalIdForReject tolerates a legacy row whose metadata fails
90
+ // strict decoding — resolveProposalId's exact-UUID match would otherwise
91
+ // throw here, before the terminal-status machinery even runs.
92
+ const proposalId = resolveProposalIdForReject(stash, options.id, options.ctx);
93
+ await recoverProposalTransactionsForStash(stash, config, options.ctx, proposalId);
94
+ const updated = rejectProposalDurably(stash, proposalId, options.reason, options.ctx, options.gateDecision);
95
+ return {
96
+ schemaVersion: 1,
97
+ ok: true,
98
+ id: updated.id,
99
+ ref: updated.ref,
109
100
  ...(options.reason !== undefined ? { reason: options.reason } : {}),
110
- },
101
+ proposal: updated,
102
+ };
111
103
  });
112
- return {
113
- schemaVersion: 1,
114
- ok: true,
115
- id: updated.id,
116
- ref: updated.ref,
117
- ...(options.reason !== undefined ? { reason: options.reason } : {}),
118
- proposal: updated,
119
- };
120
104
  }
121
105
  export function akmProposalDiff(options) {
122
- const stash = resolveStash(options.stashDir);
123
106
  const config = options.config ?? loadConfig();
107
+ const queue = resolveProposalQueue(options.stashDir, options.queue, config);
108
+ const stash = queue.stashDir;
124
109
  const proposal = resolveProposalId(stash, options.id);
125
- const diff = diffProposal(stash, config, proposal.id, { target: options.target });
110
+ const diff = diffProposal(stash, config, proposal.id, { target: options.target, queueTarget: queue.target });
126
111
  return {
127
112
  schemaVersion: 1,
128
113
  id: proposal.id,
@@ -133,12 +118,15 @@ export function akmProposalDiff(options) {
133
118
  };
134
119
  }
135
120
  export function akmProposalCreate(options) {
136
- const stash = resolveStash(options.stashDir);
121
+ const queue = resolveProposalQueue(options.stashDir, options.queue, options.config);
122
+ const stash = queue.stashDir;
123
+ const target = options.target ?? (queue.target ? { source: queue.target.source.name, root: queue.target.source.path } : undefined);
137
124
  // Manual proposal creation (via `akm proposal create`) always bypasses
138
125
  // dedup/cooldown guards — the operator is explicitly requesting a proposal.
139
126
  const result = createProposal(stash, {
140
127
  ref: options.ref,
141
128
  source: options.source,
129
+ ...(target !== undefined ? { target } : {}),
142
130
  ...(options.sourceRun !== undefined ? { sourceRun: options.sourceRun } : {}),
143
131
  payload: options.payload,
144
132
  force: true,
@@ -166,20 +154,11 @@ export function akmProposalCreate(options) {
166
154
  * `rejected`.
167
155
  */
168
156
  export async function akmProposalRevert(options) {
169
- const stash = resolveStash(options.stashDir);
170
157
  const config = options.config ?? loadConfig();
158
+ const queue = resolveProposalQueue(options.stashDir, options.queue, config);
159
+ const stash = queue.stashDir;
171
160
  const resolvedId = resolveProposalId(stash, options.id).id;
172
- const result = await revertProposal(stash, config, resolvedId, { target: options.target }, options.ctx);
173
- appendEvent({
174
- eventType: "proposal_reverted",
175
- ref: result.ref,
176
- metadata: {
177
- proposalId: result.proposal.id,
178
- source: result.proposal.source,
179
- ...(result.proposal.sourceRun !== undefined ? { sourceRun: result.proposal.sourceRun } : {}),
180
- assetPath: result.assetPath,
181
- },
182
- });
161
+ const result = await revertProposal(stash, config, resolvedId, { target: options.target, queueTarget: queue.target }, options.ctx);
183
162
  return {
184
163
  schemaVersion: 1,
185
164
  ok: true,
@@ -189,3 +168,42 @@ export async function akmProposalRevert(options) {
189
168
  proposal: result.proposal,
190
169
  };
191
170
  }
171
+ /**
172
+ * Bulk accept/reject every pending proposal from one generator, applying the
173
+ * shared `--max-diff-lines` / `--older-than` filters. Consolidates the two
174
+ * near-identical loops that lived in `proposal-cli.ts` (Chunk 6 WI-6.6);
175
+ * behavior is verbatim — same filter order, same per-item envelopes, same
176
+ * dry-run record shape. The destructive-confirmation prompt stays CLI-side.
177
+ */
178
+ export async function bulkAdjudicateProposals(options) {
179
+ const config = options.config ?? loadConfig();
180
+ const { stashDir } = resolveProposalQueue(options.stashDir, options.queue, config);
181
+ const pending = listProposals(stashDir, { status: "pending" }).filter((p) => {
182
+ if (p.source !== options.generator)
183
+ return false;
184
+ if (options.maxDiffLines !== undefined) {
185
+ const lines = proposalContent(p).split("\n").length;
186
+ if (lines > options.maxDiffLines)
187
+ return false;
188
+ }
189
+ if (options.olderThanMs !== undefined) {
190
+ const age = Date.now() - new Date(p.createdAt).getTime();
191
+ if (age < options.olderThanMs)
192
+ return false;
193
+ }
194
+ return true;
195
+ });
196
+ const results = [];
197
+ for (const proposal of pending) {
198
+ if (options.dryRun) {
199
+ results.push({ id: proposal.id, ref: proposal.ref, source: proposal.source, dryRun: true });
200
+ }
201
+ else if (options.action === "accept") {
202
+ results.push(await akmProposalAccept({ stashDir, id: proposal.id, queue: options.queue, target: options.target, config }));
203
+ }
204
+ else {
205
+ results.push(await akmProposalReject({ stashDir, id: proposal.id, queue: options.queue, reason: options.reason, config }));
206
+ }
207
+ }
208
+ return { count: results.length, results };
209
+ }
@@ -0,0 +1,88 @@
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
+ * `akm proposal new` — the asset-authoring entry point (formerly the
6
+ * top-level `akm propose`, moved under the `proposal` group per the 0.9 CLI
7
+ * overhaul, S8). Shares no private helper with the proposal MANAGEMENT
8
+ * family (list/show/accept/reject/…, `./proposal-cli.ts`) — its path/name
9
+ * helpers come from the shared src/core/asset/asset-create.ts module.
10
+ *
11
+ * Keeps the inline `runWithJsonErrors` form (branches on the result and sets
12
+ * `process.exitCode` conditionally on a failed proposal) rather than
13
+ * migrating to `defineJsonCommand`, matching the original contribute-cli.ts
14
+ * rationale: `process.exitCode` (not `process.exit()`) so the process still
15
+ * exits via natural event-loop drain rather than skipping pending cleanup.
16
+ */
17
+ import fs from "node:fs";
18
+ import path from "node:path";
19
+ import { defineCommand } from "citty";
20
+ import { getStringArg, parsePositiveIntFlag } from "../../cli/parse-args.js";
21
+ import { EXIT_CODES, GLOBAL_OUTPUT_ARGS, output, runWithJsonErrors } from "../../cli/shared.js";
22
+ import { assertFlatAssetName, combineCreatePath, normalizeCreateSubPath } from "../../core/asset/asset-create.js";
23
+ import { UsageError } from "../../core/errors.js";
24
+ import { akmPropose } from "./propose.js";
25
+ const EXIT_GENERAL = EXIT_CODES.GENERAL;
26
+ export const proposeCommand = defineCommand({
27
+ meta: {
28
+ name: "new",
29
+ description: "Ask the configured agent CLI to author a brand-new asset and queue it as a proposal",
30
+ },
31
+ // Raw defineCommand: declare the global output flags so their space-separated
32
+ // values are consumed rather than shifting the `type` / `name` positionals.
33
+ args: {
34
+ ...GLOBAL_OUTPUT_ARGS,
35
+ // Optional in citty so run() is invoked when omitted; we re-validate
36
+ // below to surface a structured UsageError (exit 2) instead of citty's
37
+ // default help-banner exit-0.
38
+ type: { type: "positional", description: "Asset type (skill, command, knowledge, lesson, ...)", required: false },
39
+ name: {
40
+ type: "positional",
41
+ description: "Asset name (flat, no '/'; use --path for a subdirectory)",
42
+ required: false,
43
+ },
44
+ path: {
45
+ type: "string",
46
+ description: "Relative subdirectory under the type dir to place the proposed asset in (e.g. 'release'). The filename comes from the name.",
47
+ },
48
+ task: { type: "string", description: "Task description for the agent (what should the asset do?)" },
49
+ file: { type: "string", description: "Read the task or prompt text from a UTF-8 file" },
50
+ engine: { type: "string", description: "Engine to use (defaults to defaults.engine)" },
51
+ "timeout-ms": { type: "string", description: "Override the agent CLI timeout in milliseconds" },
52
+ },
53
+ async run({ args }) {
54
+ await runWithJsonErrors(async () => {
55
+ // citty silently shows help and exits 0 when required positionals are
56
+ // omitted. Re-validate explicitly so the exit code is 2 (USAGE) and a
57
+ // structured JSON error reaches scripted callers.
58
+ const taskFromFlag = typeof args.task === "string" ? args.task : undefined;
59
+ const fileFromFlag = typeof args.file === "string" ? args.file : undefined;
60
+ if (!args.type || !args.name || (!taskFromFlag && !fileFromFlag)) {
61
+ throw new UsageError("Usage: akm proposal new <type> <name> (--task '<task>' | --file <path>).", "MISSING_REQUIRED_ARGUMENT", "Provide the asset type, name, and exactly one of --task or --file.");
62
+ }
63
+ if (taskFromFlag && fileFromFlag) {
64
+ throw new UsageError("Pass exactly one of --task or --file.", "INVALID_FLAG_VALUE");
65
+ }
66
+ // `name` is flat; subdirectory placement is `--path`'s job.
67
+ assertFlatAssetName(String(args.name));
68
+ const proposedName = combineCreatePath(normalizeCreateSubPath(getStringArg(args, "path")), String(args.name));
69
+ const taskText = fileFromFlag ? fs.readFileSync(path.resolve(fileFromFlag), "utf8") : (taskFromFlag ?? "");
70
+ const timeoutMs = parsePositiveIntFlag(args["timeout-ms"], "--timeout-ms");
71
+ const result = await akmPropose({
72
+ type: String(args.type),
73
+ name: proposedName,
74
+ task: taskText,
75
+ engine: getStringArg(args, "engine"),
76
+ ...(timeoutMs !== undefined ? { timeoutMs } : {}),
77
+ });
78
+ output("proposal-new", result);
79
+ if (result.ok === false) {
80
+ // Same reasoning as agentCommand in contribute-cli.ts: output() already
81
+ // ran, this is the last statement in the handler, so process.exitCode +
82
+ // return is equivalent without skipping any pending cleanup.
83
+ process.exitCode = EXIT_GENERAL;
84
+ return;
85
+ }
86
+ });
87
+ },
88
+ });
@@ -13,25 +13,57 @@
13
13
  * `akm reflect`. `propose_invoked` is emitted at command entry.
14
14
  */
15
15
  import fs from "node:fs";
16
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
17
- import { TYPE_DIRS } from "../../core/asset/asset-spec.js";
16
+ import { placementTypes, stashDirFor } from "../../core/asset/asset-placement.js";
17
+ import { parseRefInput } from "../../core/asset/resolve-ref.js";
18
18
  import { resolveStashDir } from "../../core/common.js";
19
19
  import { ConfigError, UsageError } from "../../core/errors.js";
20
20
  import { appendEvent } from "../../core/events.js";
21
+ import { redactSensitiveText } from "../../core/redaction.js";
21
22
  import { resolveStandardsContext } from "../../core/standards/resolve-standards-context.js";
22
- import { runAgent, } from "../../integrations/agent/index.js";
23
- import { resolveProcessAgentProfile } from "../../integrations/agent/config.js";
23
+ import { deriveEntryProvenance } from "../../indexer/installations.js";
24
+ import { resolveEngine } from "../../integrations/agent/engine-resolution.js";
24
25
  import { buildProposePrompt, parseAgentProposalPayload } from "../../integrations/agent/prompts.js";
25
- import { runOpencodeSdk } from "../../integrations/harnesses/opencode-sdk/index.js";
26
- import { baseFailureFields, enoentHintMessage, isEnoentFailure, loadAgentConfigFromDisk, resolveAgentProfile, } from "../agent/agent-support.js";
27
- import { createProposal, isProposalSkipped, } from "./repository.js";
28
- function failureEnvelope(result, type, name, fallbackReason = "non_zero_exit") {
26
+ import { collectDispatchSensitiveValues, executeRunner } from "../../integrations/agent/runner-dispatch.js";
27
+ import { baseFailureFields, enoentHintMessage, isEnoentFailure } from "../agent/agent-support.js";
28
+ import { createProposal, isProposalSkipped, resolveProposalQueueTarget, } from "./repository.js";
29
+ function failureEnvelope(result, type, name, engine, fallbackReason = "non_zero_exit") {
29
30
  return {
30
31
  ...baseFailureFields(result, fallbackReason),
32
+ schemaVersion: 2,
31
33
  type,
32
34
  name,
35
+ engine,
33
36
  };
34
37
  }
38
+ /**
39
+ * WI-8.5a — the fully-qualified `bundle//conceptId` item_ref for a proposal
40
+ * target in `stashDir`. The conceptId is BUILT from the D-R2 static table
41
+ * (`deriveEntryProvenance`), never looked up, so a propose target that does not
42
+ * yet exist on disk still keys onto its final spelling; the bundle is the
43
+ * write-target stash's installation id (same derivation the index write path
44
+ * uses). Matches `createProposal`'s durable `proposals.ref` mint, so the entry
45
+ * event, the fallback ref, and the stored proposal all carry one spelling.
46
+ */
47
+ function proposeItemRef(bundleId, type, name) {
48
+ return deriveEntryProvenance({ bundleId, componentId: bundleId, adapterId: "akm" }, type, name).itemRef;
49
+ }
50
+ /**
51
+ * The command-entry `propose_invoked` event. WI-8.5b: the ref carries the same
52
+ * fully-qualified item_ref the durable proposal is minted under
53
+ * (`proposeItemRef`), so the entry event and the stored proposal agree.
54
+ */
55
+ function emitProposeInvoked(bundleId, options) {
56
+ appendEvent({
57
+ eventType: "propose_invoked",
58
+ ref: proposeItemRef(bundleId, options.type, options.name),
59
+ metadata: {
60
+ type: options.type,
61
+ name: options.name,
62
+ task: options.task,
63
+ ...(options.engine ? { engine: options.engine } : {}),
64
+ },
65
+ });
66
+ }
35
67
  export async function akmPropose(options) {
36
68
  if (!options.type?.trim()) {
37
69
  throw new UsageError("propose: <type> is required.", "MISSING_REQUIRED_ARGUMENT");
@@ -42,53 +74,20 @@ export async function akmPropose(options) {
42
74
  if (!options.task?.trim()) {
43
75
  throw new UsageError("propose: --task is required.", "MISSING_REQUIRED_ARGUMENT");
44
76
  }
45
- if (!TYPE_DIRS[options.type]) {
46
- throw new UsageError(`propose: unknown asset type "${options.type}". Known types: ${Object.keys(TYPE_DIRS).sort().join(", ")}.`, "INVALID_FLAG_VALUE");
77
+ if (!stashDirFor(options.type)) {
78
+ throw new UsageError(`propose: unknown asset type "${options.type}". Known types: ${[...placementTypes()].sort().join(", ")}.`, "INVALID_FLAG_VALUE");
47
79
  }
48
80
  const stash = options.stashDir ?? resolveStashDir();
49
- // 1. Always emit `propose_invoked` at entry so observers see the attempt.
50
- appendEvent({
51
- eventType: "propose_invoked",
52
- ref: `${options.type}:${options.name}`,
53
- metadata: {
54
- type: options.type,
55
- name: options.name,
56
- task: options.task,
57
- ...(options.profile ? { profile: options.profile } : {}),
58
- },
59
- });
60
- // 2. Resolve profile.
61
- // When an explicit --profile flag is given, honour it directly (existing
62
- // behaviour). Otherwise use resolveProcessAgentProfile so that per-process
63
- // agent config (agent.processes["propose"]) is picked up automatically.
64
- let profile;
65
- let resolvedTimeoutMs = options.timeoutMs;
66
- try {
67
- if (options.agentProfile) {
68
- // Test seam: injected profile bypasses all config.
69
- profile = options.agentProfile;
70
- }
71
- else if (options.profile) {
72
- // Explicit --profile flag wins over process config.
73
- profile = resolveAgentProfile(options);
74
- }
75
- else {
76
- // Use per-process config resolution (falls back to agent.default).
77
- const agent = options.agentConfig ?? loadAgentConfigFromDisk();
78
- const processName = options.agentProcess ?? "propose";
79
- const resolved = resolveProcessAgentProfile(processName, agent);
80
- profile = resolved.profile;
81
- // Only apply process-resolved timeoutMs when caller didn't supply one.
82
- if (resolvedTimeoutMs === undefined) {
83
- resolvedTimeoutMs = resolved.timeoutMs;
84
- }
85
- }
86
- }
87
- catch (err) {
88
- if (err instanceof ConfigError || err instanceof UsageError)
89
- throw err;
90
- throw err;
91
- }
81
+ // 1. Resolve the selected engine and write target exactly once.
82
+ // the LLM arm uses the caller-specific plain-chat handler below.
83
+ const config = options.agentConfig ?? (await import("../../core/config/config.js")).loadConfig();
84
+ const target = resolveProposalQueueTarget(stash, config);
85
+ emitProposeInvoked(target.source, options);
86
+ const engineName = options.engine ?? config.defaults?.engine;
87
+ if (!engineName)
88
+ throw new ConfigError("propose requires --engine or defaults.engine.", "INVALID_CONFIG_FILE");
89
+ const runner = resolveEngine(engineName, config);
90
+ const profile = runner.kind === "llm" ? undefined : runner.profile;
92
91
  // 3. Build prompt.
93
92
  // Synthesize a temp draft path so opencode can write the asset content
94
93
  // directly using its file tools rather than returning JSON via stdout.
@@ -104,39 +103,51 @@ export async function akmPropose(options) {
104
103
  ...(standardsContext.trim() ? { standardsContext } : {}),
105
104
  draftFilePath: resolvedDraftPath,
106
105
  });
107
- // 4. Spawn the agent.
106
+ // 4. Dispatch the selected engine.
108
107
  // Real agent runs use interactive mode so file tools can write the draft.
109
108
  // Injected/custom spawns still need captured stdout for JSON payload tests.
110
- // Use callAi for the unified AI dispatch path (agent CLI preferred, LLM HTTP fallback).
109
+ // All kinds cross the unified RunnerSpec dispatch boundary.
111
110
  const useCustomSpawn = Boolean(options.runAgentOptions?.spawn);
112
111
  let result;
113
- if (useCustomSpawn) {
114
- // Test seam: use raw runAgent with injected spawn so tests remain deterministic.
115
- const runOptions = {
116
- stdio: "captured",
117
- parseOutput: "text",
118
- ...(resolvedTimeoutMs !== undefined ? { timeoutMs: resolvedTimeoutMs } : {}),
119
- ...(options.runAgentOptions ?? {}),
120
- };
121
- result = await runAgent(profile, prompt, runOptions);
122
- }
123
- else {
124
- // Production path: dispatch directly to the appropriate runner.
125
- const runOptions = {
126
- stdio: resolvedDraftPath ? "interactive" : "captured",
127
- parseOutput: "text",
128
- ...(resolvedTimeoutMs !== undefined ? { timeoutMs: resolvedTimeoutMs } : {}),
129
- };
130
- result = profile.sdkMode
131
- ? await runOpencodeSdk(profile, prompt ?? "", runOptions)
132
- : await runAgent(profile, prompt, runOptions);
133
- }
112
+ const runOptions = {
113
+ stdio: useCustomSpawn ? "captured" : "interactive",
114
+ parseOutput: "text",
115
+ ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
116
+ ...(options.runAgentOptions ?? {}),
117
+ };
118
+ const sensitiveValues = collectDispatchSensitiveValues(runner, runOptions);
119
+ result = await executeRunner(runner, prompt, runOptions, {
120
+ llm: async (spec, llmPrompt, opts) => {
121
+ const { chatCompletion } = await import("../../llm/client.js");
122
+ const started = Date.now();
123
+ try {
124
+ const stdout = await chatCompletion(spec.connection, [{ role: "user", content: llmPrompt }], {
125
+ ...(Object.hasOwn(opts, "timeoutMs") ? { timeoutMs: opts.timeoutMs } : {}),
126
+ });
127
+ return { ok: true, exitCode: 0, stdout, stderr: "", durationMs: Date.now() - started };
128
+ }
129
+ catch (error) {
130
+ return {
131
+ ok: false,
132
+ exitCode: null,
133
+ stdout: "",
134
+ stderr: "",
135
+ durationMs: Date.now() - started,
136
+ error: String(error),
137
+ reason: "spawn_failed",
138
+ };
139
+ }
140
+ },
141
+ });
134
142
  if (!result.ok) {
135
143
  // B3: ENOENT / not-found gives an actionable hint.
136
144
  if (isEnoentFailure(result)) {
137
- return { ...failureEnvelope(result, options.type, options.name), error: enoentHintMessage(profile.bin) };
145
+ return {
146
+ ...failureEnvelope(result, options.type, options.name, engineName),
147
+ error: enoentHintMessage(profile?.bin ?? engineName),
148
+ };
138
149
  }
139
- return failureEnvelope(result, options.type, options.name);
150
+ return failureEnvelope(result, options.type, options.name, engineName);
140
151
  }
141
152
  // 5. Resolve the proposal content.
142
153
  // Path A: opencode wrote the draft file — read it directly (no stdout parse).
@@ -146,7 +157,7 @@ export async function akmPropose(options) {
146
157
  const draftContent = fs.readFileSync(resolvedDraftPath, "utf8");
147
158
  fs.unlinkSync(resolvedDraftPath);
148
159
  payload = {
149
- ref: `${options.type}:${options.name}`,
160
+ ref: proposeItemRef(target.source, options.type, options.name),
150
161
  content: draftContent,
151
162
  };
152
163
  }
@@ -156,12 +167,13 @@ export async function akmPropose(options) {
156
167
  const stdioWasInteractive = !useCustomSpawn;
157
168
  if (stdioWasInteractive && (result.stdout ?? "") === "") {
158
169
  return {
159
- schemaVersion: 1,
170
+ schemaVersion: 2,
160
171
  ok: false,
161
172
  reason: "parse_error",
162
173
  error: "Agent did not write draft file and stdout was not captured (interactive mode). Check that the agent CLI understood the file-write instruction, or configure a headless profile with stdio: 'captured'.",
163
174
  type: options.type,
164
175
  name: options.name,
176
+ engine: engineName,
165
177
  exitCode: result.exitCode,
166
178
  ...(result.stderr ? { stderr: result.stderr } : {}),
167
179
  };
@@ -171,36 +183,39 @@ export async function akmPropose(options) {
171
183
  }
172
184
  catch (err) {
173
185
  return {
174
- schemaVersion: 1,
186
+ schemaVersion: 2,
175
187
  ok: false,
176
188
  reason: "parse_error",
177
189
  error: err instanceof Error ? err.message : String(err),
178
190
  type: options.type,
179
191
  name: options.name,
192
+ engine: engineName,
180
193
  exitCode: result.exitCode,
181
194
  stdout: result.stdout,
182
195
  ...(result.stderr ? { stderr: result.stderr } : {}),
183
196
  };
184
197
  }
185
198
  }
199
+ payload = { ...payload, content: redactSensitiveText(payload.content, sensitiveValues) };
186
200
  // 6. Insert the proposal. Note: we allow the agent's `ref` to normalise the
187
201
  // asset name (e.g. path-cleanup), but only after validating that the ref is
188
202
  // well-formed and the type still matches the requested type.
189
- const expectedRef = `${options.type}:${options.name}`;
203
+ const expectedRef = proposeItemRef(target.source, options.type, options.name);
190
204
  let ref = expectedRef;
191
205
  if (payload.ref) {
192
206
  let parsedRef;
193
207
  try {
194
- parsedRef = parseAssetRef(payload.ref);
208
+ parsedRef = parseRefInput(payload.ref);
195
209
  }
196
210
  catch (err) {
197
211
  return {
198
- schemaVersion: 1,
212
+ schemaVersion: 2,
199
213
  ok: false,
200
214
  reason: "parse_error",
201
215
  error: err instanceof Error ? err.message : String(err),
202
216
  type: options.type,
203
217
  name: options.name,
218
+ engine: engineName,
204
219
  exitCode: result.exitCode,
205
220
  stdout: result.stdout,
206
221
  ...(result.stderr ? { stderr: result.stderr } : {}),
@@ -208,23 +223,25 @@ export async function akmPropose(options) {
208
223
  }
209
224
  if (parsedRef.type !== options.type) {
210
225
  return {
211
- schemaVersion: 1,
226
+ schemaVersion: 2,
212
227
  ok: false,
213
228
  reason: "parse_error",
214
229
  error: `Agent returned ref type ${parsedRef.type} but expected ${options.type}`,
215
230
  type: options.type,
216
231
  name: options.name,
232
+ engine: engineName,
217
233
  exitCode: result.exitCode,
218
234
  stdout: result.stdout,
219
235
  ...(result.stderr ? { stderr: result.stderr } : {}),
220
236
  };
221
237
  }
222
- ref = `${parsedRef.type}:${parsedRef.name}`;
238
+ ref = proposeItemRef(target.source, parsedRef.type, parsedRef.name);
223
239
  }
224
240
  const createInput = {
225
241
  ref,
226
242
  source: "propose",
227
243
  sourceRun: `propose-${Date.now()}`,
244
+ target,
228
245
  // User-initiated proposals always bypass dedup/cooldown guards — the
229
246
  // operator is explicitly asking for a new proposal.
230
247
  force: true,
@@ -241,11 +258,11 @@ export async function akmPropose(options) {
241
258
  }
242
259
  const proposal = proposalResult;
243
260
  return {
244
- schemaVersion: 1,
261
+ schemaVersion: 2,
245
262
  ok: true,
246
263
  proposal,
247
264
  ref: proposal.ref,
248
- agentProfile: profile.name,
265
+ engine: engineName,
249
266
  durationMs: result.durationMs,
250
267
  };
251
268
  }