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
@@ -8,232 +8,69 @@
8
8
  * new config field is one line of Zod schema in `core/config-schema.ts` and
9
9
  * zero lines here — the walker handles get/set/unset/coercion uniformly.
10
10
  *
11
- * Legacy behaviour preserved:
12
- * - `akm config set llm.<x>` writes to `profiles.llm.<defaults.llm>` (or
13
- * auto-creates a "default" profile), mirroring the pre-rewrite shim.
14
- * - `akm config set embedding.ollamaOptions.numCtx` is sugar for
15
- * `embedding.ollamaOptions.num_ctx` (camelCase ↔ snake_case bridge).
16
- * - `parseConfigValue` returns a Partial<AkmConfig> so it can be merged with
17
- * the runtime config object via `mergeConfigValue`.
11
+ * `configVersion` is controlled by the config lifecycle. All execution
12
+ * settings use their canonical engine/strategy paths; retired aliases are not
13
+ * rewritten at this boundary.
18
14
  */
19
15
  import { defineGroupCommand, defineJsonCommand, output } from "../cli/shared.js";
20
16
  import { resolveStashDir } from "../core/common.js";
21
- import { DEFAULT_CONFIG, getSources, loadConfig, loadUserConfig, saveConfig, } from "../core/config/config.js";
17
+ import { DEFAULT_CONFIG, loadConfig, mutateConfig } from "../core/config/config.js";
22
18
  import { configGet, configSet, configUnset, unknownKeyHint } from "../core/config/config-walker.js";
23
- import { UsageError } from "../core/errors.js";
24
19
  import { getCacheDir, getConfigPath, getDbPath, getDefaultStashDir } from "../core/paths.js";
25
- // ── Legacy `llm.*` → `profiles.llm.<default>.*` aliasing ────────────────────
26
- /**
27
- * Map a legacy top-level `llm.<sub>` path onto the actual schema path. The
28
- * default profile name is "default" when `defaults.llm` is unset.
29
- */
30
- function rewriteLegacyLlmPath(config, key) {
31
- if (key !== "llm" && !key.startsWith("llm."))
32
- return key;
33
- const sub = key === "llm" ? "" : key.slice("llm.".length);
34
- const profileName = config.defaults?.llm ?? "default";
35
- return sub ? `profiles.llm.${profileName}.${sub}` : `profiles.llm.${profileName}`;
36
- }
37
- /**
38
- * Translate the legacy `embedding.ollamaOptions.numCtx` to the actual schema
39
- * key `embedding.ollamaOptions.num_ctx`.
40
- */
41
- function rewriteEmbeddingPath(key) {
42
- if (key === "embedding.ollamaOptions.numCtx")
43
- return "embedding.ollamaOptions.num_ctx";
44
- return key;
45
- }
46
- /**
47
- * Translate the deprecated `stashes` alias for `sources` (one-way: both read
48
- * and write go through `sources`).
49
- */
50
- function rewriteSourcesAlias(key) {
51
- if (key === "stashes")
52
- return "sources";
53
- if (key.startsWith("stashes."))
54
- return `sources.${key.slice("stashes.".length)}`;
55
- return key;
56
- }
57
- function rewriteKey(config, key) {
58
- let k = rewriteLegacyLlmPath(config, key);
59
- k = rewriteEmbeddingPath(k);
60
- k = rewriteSourcesAlias(k);
61
- return k;
62
- }
63
20
  // ── Public API ──────────────────────────────────────────────────────────────
64
21
  export function getConfigValue(config, key) {
65
- const k = rewriteKey(config, key);
66
- const value = configGet(config, k);
67
- if (k.split(".").at(-1) === "apiKey")
68
- return null;
69
- return omitApiKeysForOutput(value);
22
+ return redactConfigValue(configGet(config, key));
70
23
  }
71
24
  export function setConfigValue(config, key, rawValue) {
72
- // #454: reject the legacy aliases up front so the error message names the
73
- // env var the user typed (AKM_LLM_API_KEY) rather than the rewritten profile
74
- // env var (AKM_PROFILE_DEFAULT_API_KEY) — both work at runtime, but the
75
- // shorter name matches the user's mental model.
76
- if (key === "llm.apiKey") {
77
- throw new UsageError("apiKey cannot be persisted in config; export AKM_LLM_API_KEY instead. (key: llm.apiKey)", "INVALID_FLAG_VALUE", "Storing API keys in config.json leaks them through backups, logs, and version control. " +
78
- "Use the corresponding environment variable. AKM reads it at request time.");
79
- }
80
- if (key === "embedding.apiKey") {
81
- throw new UsageError("apiKey cannot be persisted in config; export AKM_EMBED_API_KEY instead. (key: embedding.apiKey)", "INVALID_FLAG_VALUE", "Storing API keys in config.json leaks them through backups, logs, and version control. " +
82
- "Use the corresponding environment variable. AKM reads it at request time.");
83
- }
84
- const k = rewriteKey(config, key);
85
- // Legacy ergonomic: `akm config set semanticSearchMode true|false`
86
- let coerced = rawValue;
87
- if (k === "semanticSearchMode") {
88
- if (rawValue === "true")
89
- coerced = "auto";
90
- else if (rawValue === "false")
91
- coerced = "off";
92
- }
93
- let next = configSet(config, k, coerced);
94
- // Legacy ergonomic shim: when the user sets `llm.<field>` and no
95
- // `defaults.llm` is set, point it at the freshly-created profile so the
96
- // value actually takes effect at runtime.
97
- if (key === "llm" || key.startsWith("llm.")) {
98
- if (!next.defaults?.llm) {
99
- next = {
100
- ...next,
101
- defaults: { ...(next.defaults ?? {}), llm: "default" },
102
- };
103
- }
104
- }
105
- return next;
25
+ return configSet(config, key, rawValue);
106
26
  }
107
27
  export function unsetConfigValue(config, key) {
108
- const k = rewriteKey(config, key);
109
- return configUnset(config, k);
110
- }
111
- /**
112
- * Compatibility shim: returns a `Partial<AkmConfig>` containing just the
113
- * change. Older code merged this onto the live config — new code should call
114
- * `setConfigValue` directly (which returns the full merged config).
115
- */
116
- export function parseConfigValue(key, value) {
117
- // Use a "marker" base so we can detect which top-level fields actually got
118
- // touched by the set call. Anything still equal to the marker is untouched.
119
- const SENTINEL = Symbol("untouched");
120
- const base = { semanticSearchMode: SENTINEL };
121
- const next = setConfigValue(base, key, value);
122
- const patch = {};
123
- for (const k of Object.keys(next)) {
124
- if (next[k] !== SENTINEL) {
125
- patch[k] = next[k];
126
- }
127
- }
128
- return patch;
28
+ return configUnset(config, key);
129
29
  }
130
30
  export function listConfig(config) {
131
- const result = {
132
- semanticSearchMode: config.semanticSearchMode,
133
- registries: config.registries ?? DEFAULT_CONFIG.registries ?? [],
134
- output: { ...(DEFAULT_CONFIG.output ?? {}), ...(config.output ?? {}) },
135
- stashDir: config.stashDir ?? null,
136
- installed: config.installed ?? [],
137
- sources: getSources(config),
138
- };
139
- if (config.defaultWriteTarget)
140
- result.defaultWriteTarget = config.defaultWriteTarget;
141
- if (config.embedding)
142
- result.embedding = config.embedding;
143
- if (config.profiles)
144
- result.profiles = config.profiles;
145
- if (config.defaults)
146
- result.defaults = config.defaults;
147
- if (config.search)
148
- result.search = config.search;
149
- if (config.index)
150
- result.index = config.index;
151
- if (config.feedback)
152
- result.feedback = config.feedback;
153
- if (config.improve)
154
- result.improve = config.improve;
155
- if (config.archiveRetentionDays !== undefined)
156
- result.archiveRetentionDays = config.archiveRetentionDays;
157
- if (config.configVersion !== undefined)
158
- result.configVersion = config.configVersion;
159
- return omitApiKeysForOutput(result);
31
+ // 0.9.0 (spec §10.1): sources live in `bundles` (spread from config); the
32
+ // retired top-level `sources[]` array is no longer surfaced.
33
+ return redactConfigValue({ ...DEFAULT_CONFIG, ...config });
160
34
  }
161
- function omitApiKeysForOutput(value) {
35
+ function redactConfigValue(value) {
162
36
  if (Array.isArray(value))
163
- return value.map(omitApiKeysForOutput);
37
+ return value.map(redactConfigValue);
164
38
  if (!value || typeof value !== "object")
165
39
  return value;
166
- const out = {};
40
+ const result = {};
167
41
  for (const [key, child] of Object.entries(value)) {
168
- if (key === "apiKey")
169
- continue;
170
- out[key] = omitApiKeysForOutput(child);
42
+ if (key !== "apiKey" ||
43
+ (typeof child === "string" && /^\$(?:[A-Za-z_][A-Za-z0-9_]*|\{[A-Za-z_][A-Za-z0-9_]*\})$/.test(child))) {
44
+ result[key] = redactConfigValue(child);
45
+ }
171
46
  }
172
- return out;
47
+ return result;
173
48
  }
174
49
  export { unknownKeyHint };
175
50
  // ── `akm config` command surface ────────────────────────────────────────────
176
51
  // Extracted verbatim from src/cli.ts (WS6). The `main.subCommands.config` key
177
- // and every config subcommand's args/output shape are byte-identical. The
178
- // `skills.sh` toggle helpers and the `CONFIG_SUBCOMMAND_SET` routing constant
179
- // are used ONLY by this command, so they move with the cluster. Leaf handlers
180
- // whose body is a plain `runWithJsonErrors(() => { … })` are migrated to
181
- // `defineJsonCommand`, which emits the same JSON envelope (stdout/stderr/
182
- // exit-code) as the inline form.
183
- const SKILLS_SH_NAME = "skills.sh";
184
- const SKILLS_SH_URL = "https://skills.sh";
185
- const SKILLS_SH_PROVIDER = "skills-sh";
186
- function normalizeToggleTarget(target) {
187
- const normalized = target.trim().toLowerCase();
188
- if (normalized === "skills.sh" || normalized === "skills-sh")
189
- return "skills.sh";
190
- throw new UsageError(`Unsupported target "${target}". Supported targets: skills.sh`);
191
- }
192
- function toggleSkillsShRegistry(enabled) {
193
- const config = loadUserConfig();
194
- const registries = (config.registries ?? DEFAULT_CONFIG.registries ?? []).map((registry) => ({ ...registry }));
195
- const idx = registries.findIndex((registry) => registry.provider === SKILLS_SH_PROVIDER || registry.name === SKILLS_SH_NAME || registry.url === SKILLS_SH_URL);
196
- if (idx >= 0) {
197
- const existing = registries[idx];
198
- const wasEnabled = existing.enabled !== false;
199
- existing.enabled = enabled;
200
- saveConfig({ ...config, registries });
201
- return { changed: wasEnabled !== enabled, component: SKILLS_SH_NAME, enabled };
202
- }
203
- if (!enabled) {
204
- // Materialize the skills.sh registry explicitly if absent.
205
- registries.push({ url: SKILLS_SH_URL, name: SKILLS_SH_NAME, provider: SKILLS_SH_PROVIDER, enabled: false });
206
- saveConfig({ ...config, registries });
207
- return { changed: true, component: SKILLS_SH_NAME, enabled: false };
208
- }
209
- registries.push({ url: SKILLS_SH_URL, name: SKILLS_SH_NAME, provider: SKILLS_SH_PROVIDER, enabled: true });
210
- saveConfig({ ...config, registries });
211
- return { changed: true, component: SKILLS_SH_NAME, enabled: true };
212
- }
213
- function toggleComponent(targetRaw, enabled) {
214
- const target = normalizeToggleTarget(targetRaw);
215
- if (target === "skills.sh")
216
- return toggleSkillsShRegistry(enabled);
217
- // normalizeToggleTarget throws for any unsupported target; this is unreachable.
218
- throw new UsageError(`Unsupported target "${targetRaw}". Supported targets: skills.sh`);
219
- }
52
+ // and every config subcommand's args/output shape are byte-identical. Leaf
53
+ // handlers whose body is a plain `runWithJsonErrors(() => { … })` are
54
+ // migrated to `defineJsonCommand`, which emits the same JSON envelope
55
+ // (stdout/stderr/exit-code) as the inline form.
56
+ //
57
+ // `akm config enable|disable` (a hardcoded alias for toggling the skills.sh
58
+ // registry) was removed in 0.9.0 (C4). Use `akm registry add|remove`, the
59
+ // general mechanism, instead.
220
60
  export const configCommand = defineGroupCommand({
221
61
  meta: { name: "config", description: "Show and manage configuration" },
222
- args: {
223
- list: { type: "boolean", description: "List current configuration", default: false },
224
- },
225
62
  subCommands: {
226
63
  path: defineJsonCommand({
227
- meta: { name: "path", description: "Show paths to config, stash, cache, and index" },
64
+ meta: { name: "path", description: "Show paths to config, bundle, cache, and index" },
228
65
  args: {
229
- all: { type: "boolean", description: "Show all paths (config, stash, cache, index)", default: false },
66
+ all: { type: "boolean", description: "Show all paths (config, bundle, cache, index)", default: false },
230
67
  },
231
68
  run({ args }) {
232
69
  const configPath = getConfigPath();
233
70
  if (args.all) {
234
71
  let stashDir;
235
72
  try {
236
- stashDir = resolveStashDir({ readOnly: true });
73
+ stashDir = resolveStashDir();
237
74
  }
238
75
  catch {
239
76
  stashDir = `${getDefaultStashDir()} (not initialized)`;
@@ -241,7 +78,7 @@ export const configCommand = defineGroupCommand({
241
78
  const cacheDir = getCacheDir();
242
79
  const result = {
243
80
  config: configPath,
244
- stash: stashDir,
81
+ bundle: stashDir,
245
82
  cache: cacheDir,
246
83
  index: getDbPath(),
247
84
  };
@@ -258,16 +95,10 @@ export const configCommand = defineGroupCommand({
258
95
  output("config", listConfig(loadConfig()));
259
96
  },
260
97
  }),
261
- show: defineJsonCommand({
262
- meta: { name: "show", description: "Alias for `akm config list` — list current configuration" },
263
- run() {
264
- output("config", listConfig(loadConfig()));
265
- },
266
- }),
267
98
  get: defineJsonCommand({
268
99
  meta: { name: "get", description: "Get a configuration value by key" },
269
100
  args: {
270
- key: { type: "positional", required: true, description: "Config key (for example: embedding, stashDir)" },
101
+ key: { type: "positional", required: true, description: "Config key (for example: embedding, defaultBundle)" },
271
102
  },
272
103
  run({ args }) {
273
104
  output("config", getConfigValue(loadConfig(), args.key));
@@ -276,7 +107,11 @@ export const configCommand = defineGroupCommand({
276
107
  set: defineJsonCommand({
277
108
  meta: { name: "set", description: "Set a configuration value by key" },
278
109
  args: {
279
- key: { type: "positional", required: true, description: "Config key (for example: embedding, llm)" },
110
+ key: {
111
+ type: "positional",
112
+ required: true,
113
+ description: "Config key (for example: embedding, engines.default)",
114
+ },
280
115
  value: { type: "positional", required: true, description: "Config value" },
281
116
  // #463: stable machine-friendly entry point for plugins / hooks.
282
117
  // `--silent` suppresses the config dump on stdout so hook-driven
@@ -286,31 +121,16 @@ export const configCommand = defineGroupCommand({
286
121
  description: "Suppress the post-write config dump on stdout. Use from hooks and CI scripts; the write still happens and errors still print.",
287
122
  default: false,
288
123
  },
289
- // #463: explicit layer flag for forward-compat. User layer is the only
290
- // settable layer today; the flag exists so plugin authors can encode
291
- // intent and the surface stays stable if project-layer writes return.
292
- layer: {
293
- type: "string",
294
- description: "Config layer to write to. Currently only `user` is supported.",
295
- default: "user",
296
- },
297
124
  },
298
125
  run({ args }) {
299
- if (args.layer && args.layer !== "user") {
300
- throw new UsageError(`Unsupported --layer "${args.layer}". Only "user" is settable in 0.8.0.`, "INVALID_FLAG_VALUE");
301
- }
302
- // Use loadConfig (not loadUserConfig) so the project-config
303
- // deprecation warning fires consistently with `akm config get`
304
- // (#457). Effective merged shape is identical post-0.8.0.
305
- const updated = setConfigValue(loadConfig(), args.key, args.value);
306
- saveConfig(updated);
126
+ const updated = mutateConfig((current) => setConfigValue(current, args.key, args.value)).config;
307
127
  if (!args.silent) {
308
128
  output("config", listConfig(updated));
309
129
  }
310
130
  },
311
131
  }),
312
132
  unset: defineJsonCommand({
313
- meta: { name: "unset", description: "Unset an optional configuration key or whole embedding/llm section" },
133
+ meta: { name: "unset", description: "Unset an optional configuration key or whole embedding/engine section" },
314
134
  args: {
315
135
  key: { type: "positional", required: true, description: "Config key to unset" },
316
136
  silent: {
@@ -318,78 +138,21 @@ export const configCommand = defineGroupCommand({
318
138
  description: "Suppress the post-write config dump on stdout.",
319
139
  default: false,
320
140
  },
321
- layer: {
322
- type: "string",
323
- description: "Config layer to write to. Currently only `user` is supported.",
324
- default: "user",
325
- },
326
141
  },
327
142
  run({ args }) {
328
- if (args.layer && args.layer !== "user") {
329
- throw new UsageError(`Unsupported --layer "${args.layer}". Only "user" is settable in 0.8.0.`, "INVALID_FLAG_VALUE");
330
- }
331
- const updated = unsetConfigValue(loadConfig(), args.key);
332
- saveConfig(updated);
143
+ const result = mutateConfig((current) => unsetConfigValue(current, args.key), { absentNoop: true });
144
+ const updated = result.config;
333
145
  if (!args.silent) {
334
146
  output("config", listConfig(updated));
335
147
  }
336
148
  },
337
149
  }),
338
- validate: defineJsonCommand({
339
- meta: {
340
- name: "validate",
341
- description: "Validate the on-disk config file against the schema. Exits non-zero on errors.",
342
- },
343
- async run() {
344
- const { runConfigValidate } = await import("../cli/config-validate.js");
345
- await runConfigValidate();
346
- },
347
- }),
348
- migrate: defineJsonCommand({
349
- meta: {
350
- name: "migrate",
351
- description: "Migrate the config file to the current schema version. Use --dry-run to preview without writing.",
352
- },
353
- args: {
354
- "dry-run": { type: "boolean", description: "Preview the migration result without writing.", default: false },
355
- "print-diff": {
356
- type: "boolean",
357
- description: "Print a unified diff of old vs new config alongside the migration output.",
358
- default: false,
359
- },
360
- },
361
- async run({ args }) {
362
- const { runConfigMigrate } = await import("../cli/config-migrate.js");
363
- await runConfigMigrate({ dryRun: Boolean(args["dry-run"]), printDiff: Boolean(args["print-diff"]) });
364
- },
365
- }),
366
- enable: defineJsonCommand({
367
- meta: { name: "enable", description: "Enable an optional component (skills.sh)" },
368
- args: {
369
- target: { type: "positional", description: "Component to enable (skills.sh)", required: true },
370
- },
371
- run({ args }) {
372
- const result = toggleComponent(args.target, true);
373
- output("enable", result);
374
- },
375
- }),
376
- disable: defineJsonCommand({
377
- meta: { name: "disable", description: "Disable an optional component (skills.sh)" },
378
- args: {
379
- target: { type: "positional", description: "Component to disable (skills.sh)", required: true },
380
- },
381
- run({ args }) {
382
- const result = toggleComponent(args.target, false);
383
- output("disable", result);
384
- },
385
- }),
386
150
  },
387
151
  // The bare `akm config` invocation (and `akm config --list`) dumps the
388
152
  // current config. defineGroupCommand short-circuits this body when a
389
153
  // registered subcommand ran, so the routing set stays derived from the
390
- // subCommands map and can never desync (previously validate/migrate were
391
- // missing from a hand-maintained set, causing a spurious second dump).
392
- defaultRun() {
393
- output("config", listConfig(loadConfig()));
394
- },
154
+ // subCommands map and can never desync.
155
+ // No `defaultRun`: bare `akm config` is a usage error (exit 2), the canonical
156
+ // bare-group behavior — owner ruling 12. Run `akm config list` for what the
157
+ // bare form used to print.
395
158
  });
@@ -0,0 +1,99 @@
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
+ * Env-ref → resolved values, shared between `akm env run` and the workflow
6
+ * engine's per-unit env bindings (orchestration plan, *Dispatch context*).
7
+ *
8
+ * Extracted from `env-cli.ts`'s `runEnvInjected` so the native executor
9
+ * REUSES the exact same machinery instead of forking it. Every safety
10
+ * invariant carries over unchanged:
11
+ *
12
+ * - `${secret:NAME}` tokens resolve against the env's own stash; a missing
13
+ * secret is a hard error and NOTHING is injected (no partial injection).
14
+ * - Known process-hijacking keys (LD_PRELOAD, PATH, …) are blocked for
15
+ * third-party-sourced stashes and warned about for first-party ones.
16
+ * - An `env_access` audit event records key NAMES only, never values.
17
+ * - Resolved values must never be written to stdout or logs by callers.
18
+ */
19
+ import fs from "node:fs";
20
+ import path from "node:path";
21
+ import { decideDangerousEnvInjection } from "../../core/activation-policy.js";
22
+ import { assetPathForName } from "../../core/asset/asset-placement.js";
23
+ import { isWithin } from "../../core/common.js";
24
+ import { makeEnvRef, makeSecretRef, resolveEnvPath } from "../../core/env-secret-ref.js";
25
+ import { NotFoundError, UsageError } from "../../core/errors.js";
26
+ import { appendEvent } from "../../core/events.js";
27
+ import { isDangerousEnvKey } from "../lint/env-key-rules.js";
28
+ import { loadEnv, resolveSecretTokens } from "./env.js";
29
+ import { readValue } from "./secret.js";
30
+ /**
31
+ * Resolve an env ref to its injectable values: load the file, apply key
32
+ * filtering, substitute `${secret:NAME}` tokens from the sibling secrets
33
+ * directory, enforce the dangerous-key policy, and append the keys-only
34
+ * `env_access` audit event.
35
+ */
36
+ export function resolveEnvBinding(target, options = {}) {
37
+ const warn = options.warn ?? ((message) => process.stderr.write(`warning: ${message}\n`));
38
+ const { name, absPath, source } = resolveEnvPath(target);
39
+ const envRef = makeEnvRef(name, source);
40
+ if (!fs.existsSync(absPath)) {
41
+ throw new NotFoundError(`Env not found: ${envRef}`);
42
+ }
43
+ const allValues = loadEnv(absPath);
44
+ // Value-safe key filtering (--only / --except operate on key NAMES only).
45
+ let envValues = allValues;
46
+ if (options.only && options.except) {
47
+ throw new UsageError("Pass only one of --only or --except.", "INVALID_FLAG_VALUE");
48
+ }
49
+ if (options.only) {
50
+ const wanted = new Set(options.only);
51
+ const missing = options.only.filter((k) => !(k in allValues));
52
+ if (missing.length > 0) {
53
+ warn(`--only key(s) not present in ${envRef}: ${missing.join(", ")}`);
54
+ }
55
+ envValues = Object.fromEntries(Object.entries(allValues).filter(([k]) => wanted.has(k)));
56
+ }
57
+ else if (options.except) {
58
+ const excluded = new Set(options.except);
59
+ envValues = Object.fromEntries(Object.entries(allValues).filter(([k]) => !excluded.has(k)));
60
+ }
61
+ // Substitute `${secret:NAME}` tokens with the sibling secret asset in the
62
+ // SAME stash. A missing secret is a hard error — inject NOTHING.
63
+ const secretsRoot = path.join(source.path, "secrets");
64
+ const resolveSecret = (secretName) => {
65
+ const secretPath = assetPathForName("secret", secretsRoot, secretName);
66
+ // Defense-in-depth: ensure the resolved path stays inside the secrets dir.
67
+ if (!isWithin(secretPath, secretsRoot)) {
68
+ throw new UsageError(`Secret name "${secretName}" escapes the secrets directory.`);
69
+ }
70
+ if (!fs.existsSync(secretPath))
71
+ return undefined;
72
+ // Match `secret run`: read utf8, do not trim (stay consistent with that path).
73
+ return readValue(secretPath).toString("utf8");
74
+ };
75
+ const { values: substituted, missing } = resolveSecretTokens(envValues, resolveSecret);
76
+ if (missing.length > 0) {
77
+ throw new NotFoundError(`Env "${envRef}" references secret(s) not found in its stash: ${missing.map((n) => makeSecretRef(n)).join(", ")}. Nothing was injected.`, "FILE_NOT_FOUND", `Create the missing secret, e.g. \`akm secret set ${makeSecretRef(missing[0])}\`.`);
78
+ }
79
+ envValues = substituted;
80
+ const keys = Object.keys(envValues);
81
+ // Scan injected keys for known process-hijacking variables. The workspace
82
+ // activation policy decides block (third-party, registryId set) vs. warn
83
+ // (first-party stash, where the operator owns the file).
84
+ const dangerous = keys.filter(isDangerousEnvKey);
85
+ if (dangerous.length > 0) {
86
+ const detail = `Env "${envRef}" injects process-hijacking variable(s): ${dangerous.join(", ")}.`;
87
+ const decision = decideDangerousEnvInjection({ dangerousKeys: dangerous, thirdParty: Boolean(source.registryId) });
88
+ if (decision === "block") {
89
+ throw new UsageError(`Refusing to inject env from a third-party stash. ${detail}\n` +
90
+ ` Review the file, then copy the values into a first-party env if you trust them.`, "INVALID_FLAG_VALUE");
91
+ }
92
+ if (decision === "warn") {
93
+ warn(`${detail} Injecting anyway (first-party stash).`);
94
+ }
95
+ }
96
+ // Audit trail: keys only, never values.
97
+ appendEvent({ eventType: "env_access", ref: envRef, metadata: { keys } });
98
+ return { ref: envRef, values: envValues, keys };
99
+ }