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
@@ -10,8 +10,8 @@
10
10
  */
11
11
  import os from "node:os";
12
12
  import path from "node:path";
13
- import { IS_WINDOWS } from "./common.js";
14
13
  import { ConfigError } from "./errors.js";
14
+ import { IS_WINDOWS } from "./platform.js";
15
15
  /**
16
16
  * Returns true when the current process appears to be running under
17
17
  * `bun test` (either via the BUN_TEST sentinel Bun sets on the test
@@ -30,10 +30,10 @@ function isUnderBunTest(env) {
30
30
  * Returns true when the given path is in a directory family the OS may
31
31
  * reap (or that the user has clearly designated as a sandbox by virtue
32
32
  * of placing it under `/tmp` or a macOS per-user temp dir). Used to
33
- * decide whether `AKM_STASH_DIR=$tmpdir` should also isolate config +
33
+ * decide whether `AKM_BUNDLE_DIR=$tmpdir` should also isolate config +
34
34
  * cache writes (so a test harness's `akm setup --yes --dir .` cannot
35
35
  * silently clobber the user's `~/.config/akm/config.json`). See
36
- * `docs/technical/incidents/2026-05-23-setup-clobbers-user-config.md`
36
+ * the 2026-05-23 setup-clobbers-user-config incident
37
37
  * for the incident that motivated this.
38
38
  *
39
39
  * Both `/var/folders/*` and `/private/var/folders/*` are matched because
@@ -67,7 +67,7 @@ export function getConfigDir(env = process.env, platform = process.platform) {
67
67
  return override;
68
68
  // Explicit XDG override wins next — tests and operators that pre-arrange
69
69
  // an isolated config dir via XDG_CONFIG_HOME (or %APPDATA% on Windows)
70
- // must be honored as set, so the AKM_STASH_DIR transient-isolation rule
70
+ // must be honored as set, so the AKM_BUNDLE_DIR transient-isolation rule
71
71
  // below does not silently move config away from where they pointed it.
72
72
  if (platform === "win32") {
73
73
  const appData = env.APPDATA?.trim();
@@ -79,16 +79,16 @@ export function getConfigDir(env = process.env, platform = process.platform) {
79
79
  if (xdgConfigHome)
80
80
  return path.join(xdgConfigHome, "akm");
81
81
  }
82
- // Isolation safety: when AKM_STASH_DIR points at a transient/sandbox path
82
+ // Isolation safety: when AKM_BUNDLE_DIR points at a transient/sandbox path
83
83
  // (/tmp, /var/tmp, /private/var/folders) AND no explicit config dir
84
- // override is set, route config writes into `${AKM_STASH_DIR}/.akm`
84
+ // override is set, route config writes into `${AKM_BUNDLE_DIR}/.akm`
85
85
  // instead of the user's host ~/.config/akm. This prevents the documented
86
86
  // isolation pattern
87
- // AKM_DATA_DIR=/tmp/x AKM_STASH_DIR=/tmp/x akm setup --yes --dir .
87
+ // AKM_DATA_DIR=/tmp/x AKM_BUNDLE_DIR=/tmp/x akm setup --yes --dir .
88
88
  // from silently clobbering the host config. See
89
- // docs/technical/incidents/2026-05-23-setup-clobbers-user-config.md for the incident.
90
- // Daily users with a persistent AKM_STASH_DIR=~/my-stash are unaffected.
91
- const stashOverride = env.AKM_STASH_DIR?.trim();
89
+ // the 2026-05-23 setup-clobbers-user-config incident.
90
+ // Daily users with a persistent AKM_BUNDLE_DIR=~/my-stash are unaffected.
91
+ const stashOverride = env.AKM_BUNDLE_DIR?.trim();
92
92
  if (stashOverride && isTransientStashPath(stashOverride)) {
93
93
  return path.join(stashOverride, ".akm");
94
94
  }
@@ -122,7 +122,7 @@ export function getCacheDir(env = process.env) {
122
122
  // Explicit XDG/platform overrides win before the transient-stash isolation
123
123
  // rule below — tests and operators that pre-arrange XDG_CACHE_HOME (or
124
124
  // %LOCALAPPDATA% / %USERPROFILE% / %APPDATA% on Windows) must be honored
125
- // as set, so the AKM_STASH_DIR transient rule does not silently move cache
125
+ // as set, so the AKM_BUNDLE_DIR transient rule does not silently move cache
126
126
  // writes away from where they pointed them.
127
127
  if (IS_WINDOWS) {
128
128
  const localAppData = env.LOCALAPPDATA?.trim();
@@ -145,12 +145,12 @@ export function getCacheDir(env = process.env) {
145
145
  if (xdgCacheHome)
146
146
  return path.join(xdgCacheHome, "akm");
147
147
  }
148
- // Isolation safety (mirrors getConfigDir): when AKM_STASH_DIR points at a
148
+ // Isolation safety (mirrors getConfigDir): when AKM_BUNDLE_DIR points at a
149
149
  // transient path AND no explicit cache override is set, route cache writes
150
- // into `${AKM_STASH_DIR}/.akm/cache` so that config backups, registry-index
150
+ // into `${AKM_BUNDLE_DIR}/.akm/cache` so that config backups, registry-index
151
151
  // cache, and other regenerable artifacts do not pollute the user's host
152
152
  // ~/.cache/akm directory.
153
- const stashOverride = env.AKM_STASH_DIR?.trim();
153
+ const stashOverride = env.AKM_BUNDLE_DIR?.trim();
154
154
  if (stashOverride && isTransientStashPath(stashOverride)) {
155
155
  return path.join(stashOverride, ".akm", "cache");
156
156
  }
@@ -184,7 +184,7 @@ export function getDataDir(env = process.env, platform = process.platform) {
184
184
  // user's real $XDG_DATA_HOME / ~/.local/share/akm under any condition.
185
185
  // Any test that needs a data dir must point it at a mktemp-d directory
186
186
  // via XDG_DATA_HOME (or AKM_DATA_DIR). The previous carve-out that only
187
- // fired when AKM_STASH_DIR was set was a loophole: tests calling
187
+ // fired when AKM_BUNDLE_DIR was set was a loophole: tests calling
188
188
  // openDatabase() or getDbPath() without overriding any env var silently
189
189
  // wrote into ~/.local/share/akm/index.db (observed: 4,183-row
190
190
  // registry-cache pollution). Item 5 of the 0.8.x critical-review plan.
@@ -218,16 +218,16 @@ export function getDbPath(env = process.env) {
218
218
  export function getIndexWriterLockPath() {
219
219
  return path.join(getDataDir(), "index.db.write.lock");
220
220
  }
221
- export function getWorkflowDbPath() {
222
- return path.join(getDataDir(), "workflow.db");
221
+ export function getMaintenanceBarrierPath() {
222
+ return path.join(getDataDir(), "maintenance.barrier.lock");
223
223
  }
224
224
  /** Path to the state.db file in $DATA. */
225
225
  export function getStateDbPathInDataDir() {
226
226
  return path.join(getDataDir(), "state.db");
227
227
  }
228
- /** Path for the task history directory in $DATA. */
229
- export function getTaskHistoryStateDir() {
230
- return path.join(getDataDir(), "tasks", "history");
228
+ /** Content-addressed scheduler runtime descriptors. */
229
+ export function getTaskContextDir(env = process.env) {
230
+ return path.join(getDataDir(env), "tasks", "context");
231
231
  }
232
232
  /** Path to the akm.lock file in $DATA. */
233
233
  export function getLockfilePath() {
@@ -246,9 +246,6 @@ export function getRegistryCacheDir() {
246
246
  export function getRegistryIndexCacheDir() {
247
247
  return path.join(getCacheDir(), "registry-index");
248
248
  }
249
- export function getBinDir() {
250
- return path.join(getCacheDir(), "bin");
251
- }
252
249
  // ── Scheduled-task runtime directories (logs + history) ──────────────────────
253
250
  export function getTaskLogDir() {
254
251
  return path.join(getCacheDir(), "tasks", "logs");
@@ -258,7 +255,7 @@ export function getTaskHistoryDir() {
258
255
  }
259
256
  // ── Default stash directory ──────────────────────────────────────────────────
260
257
  export function getDefaultStashDir(env = process.env) {
261
- const override = env.AKM_STASH_DIR?.trim();
258
+ const override = env.AKM_BUNDLE_DIR?.trim();
262
259
  if (override)
263
260
  return override;
264
261
  if (IS_WINDOWS) {
@@ -269,7 +266,7 @@ export function getDefaultStashDir(env = process.env) {
269
266
  }
270
267
  const home = env.HOME?.trim();
271
268
  if (!home) {
272
- throw new ConfigError("Unable to determine default stash directory. Set HOME.", "STASH_DIR_NOT_FOUND");
269
+ throw new ConfigError("Unable to determine default bundle directory. Set HOME.", "STASH_DIR_NOT_FOUND");
273
270
  }
274
271
  return path.join(home, "akm");
275
272
  }
@@ -0,0 +1,10 @@
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
+ * Platform detection leaf (chunk-8 WI-8.6, DoD 11). Imports NOTHING so both
6
+ * `common.ts` and `paths.ts` can depend on it — extracting IS_WINDOWS here
7
+ * broke the `common.ts ↔ paths.ts` import cycle (paths needed only this
8
+ * constant from common).
9
+ */
10
+ export const IS_WINDOWS = process.platform === "win32";
@@ -0,0 +1,128 @@
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
+ * The util home for recognition/grammar constants shared across the asset,
6
+ * indexer, and workflow layers (chunk 1, D1-4).
7
+ *
8
+ * INVARIANT (D1-5, cycle-safety): this module MUST import NOTHING from
9
+ * `src/` (no relative `./`/`../` imports into the tree). All four symbols
10
+ * below are self-contained literals/pure functions today, so this file is a
11
+ * pure sink — everything imports FROM it, it imports from nothing internal.
12
+ * The import-cycle ratchet (`scripts/lint-import-cycles.ts`) is shrink-only:
13
+ * a 29th cycle participant is a hard failure, so this file must never gain
14
+ * an internal import that could pull it into an existing knot. Enforced
15
+ * mechanically by `tests/core/recognition-util.test.ts`.
16
+ */
17
+ /** All recognized script extensions for the script asset type. */
18
+ export const SCRIPT_EXTENSIONS = new Set([
19
+ ".sh",
20
+ ".ts",
21
+ ".js",
22
+ ".ps1",
23
+ ".cmd",
24
+ ".bat",
25
+ ".py",
26
+ ".rb",
27
+ ".go",
28
+ ".pl",
29
+ ".php",
30
+ ".lua",
31
+ ".r",
32
+ ".swift",
33
+ ".kt",
34
+ ".kts",
35
+ ]);
36
+ /**
37
+ * Recognized workflow asset extensions. One format now (workflow-format-
38
+ * unification): orchestration graph in frontmatter, prose in the body.
39
+ * `workflows/<name>` refs resolve against this list.
40
+ */
41
+ export const WORKFLOW_EXTENSIONS = [".md"];
42
+ /**
43
+ * Strip the recognized workflow extension (`.md`) from a workflow asset
44
+ * *name* so `foo` and `foo.md` collapse to one canonical identity — the same
45
+ * collapse `workflowSpec.toCanonicalName` performs on a resolved file path.
46
+ * Callers that turn a `workflows/<name>` ref into run identity (the
47
+ * active-run guard, list/status filters) MUST route the name through this so
48
+ * an aliased spelling (`workflows/foo.md`) and the canonical `workflows/foo`
49
+ * cannot start or hide parallel runs of the same workflow. Names without the
50
+ * extension pass through unchanged.
51
+ */
52
+ export function canonicalizeWorkflowName(name) {
53
+ const lower = name.toLowerCase();
54
+ for (const ext of WORKFLOW_EXTENSIONS) {
55
+ if (lower.endsWith(ext))
56
+ return name.slice(0, -ext.length);
57
+ }
58
+ return name;
59
+ }
60
+ /** Structural marker suffix for a derived (inferred) memory's canonical name. */
61
+ export const DERIVED_SUFFIX = ".derived";
62
+ // ── Known-type taxonomy (chunk 1.5, D1.5-4) ─────────────────────────────────
63
+ //
64
+ // `KNOWN_TYPES` replaces the deleted `common.ts` closed asset-type union.
65
+ // It is a HINT/exhaustiveness tuple, NOT a validation gate: unknown/foreign
66
+ // `type` strings are still valid `IndexDocument`/`IndexDocument`/`AssetRef` DATA
67
+ // (plan §2.3/§15.4) — this tuple only anchors compile-time completeness for
68
+ // AKM's OWN presentation/ranking tables (`Record<KnownType, X>` fails to
69
+ // compile if a key is missing). A plain `as const` literal tuple adds no
70
+ // import, so it lives here without breaking the D1-5 import-free invariant.
71
+ /**
72
+ * The AKM-owned built-in asset type keys — the deleted `common.ts` `ASSET_TYPES`
73
+ * set (same order) minus the retired `wiki` type (chunk 4); `instruction`
74
+ * (CLAUDE.md / AGENTS.md project-instruction files) is the newest, added for the
75
+ * format-family adapters (spec §6/§7 instruction row, maintainer resolution
76
+ * 2026-07). An instruction file is a read-like-knowledge markdown document, so
77
+ * it reuses knowledge's presentation shape (label "Instruction", `knowledge-md`
78
+ * renderer, a "read the project instructions" action) rather than the generic
79
+ * fallback. `wiki` was removed here in chunk 4 ("the wiki ASSET-TYPE dies", plan
80
+ * §11 Chunk 4 / §7.4): the LLM Wiki structure now lives in the first-class
81
+ * `llm-wiki` adapter whose page kinds are open (foreign) types, not AKM-owned.
82
+ */
83
+ export const KNOWN_TYPES = [
84
+ "skill",
85
+ "command",
86
+ "agent",
87
+ "knowledge",
88
+ "workflow",
89
+ "script",
90
+ "memory",
91
+ "env",
92
+ "secret",
93
+ "lesson",
94
+ "task",
95
+ "session",
96
+ "fact",
97
+ "instruction",
98
+ ];
99
+ /**
100
+ * Returns true when `type` is one of AKM's own known type keys
101
+ * ({@link KNOWN_TYPES}). Unlike the deleted `isAssetType`, this is NOT a
102
+ * validation gate — a `false` result does not mean `type` is invalid data,
103
+ * only that it is not AKM-owned (a foreign/adapter type is still a valid
104
+ * ref/entry). Used to index `Record<KnownType, X>` tables safely from an
105
+ * open `string` and, later, for cross-surface known-type spelling checks.
106
+ */
107
+ export function isKnownType(type) {
108
+ return KNOWN_TYPES.includes(type);
109
+ }
110
+ /**
111
+ * Type keys deliberately REMOVED from AKM (chunk 1.5, D1.5-6 — the key
112
+ * correctness call in the open-token change). The open type token accepts
113
+ * any non-empty string as valid ref/entry DATA except this set: silently
114
+ * re-admitting a retired type as an ordinary "foreign" type would defeat the
115
+ * guard that removed it in the first place.
116
+ *
117
+ * - `vault` — removed in 0.9.0 in favor of `env`/`secret`; carries its own
118
+ * migration-hint `UsageError` in `asset-ref.ts` (checked before this
119
+ * set) and interacts with the dangerous-env-key lint
120
+ * (`commands/lint/env-key-rules.ts`) — vaults must never be silently
121
+ * re-admitted as an ordinary indexed/ref-able type.
122
+ * - `tool` — retired outright, no replacement.
123
+ *
124
+ * Consulted by the ref parser and `metadata.ts`'s
125
+ * `validateStashEntry` gate (and the `akm` adapter's `recognize`) so the
126
+ * rejection lives in one place instead of three closed-union-shaped copies.
127
+ */
128
+ export const DEPRECATED_REJECTED_TYPES = new Set(["tool", "vault"]);
@@ -0,0 +1,392 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ const ENV_PASSTHROUGH_REDACTION_POLICY = {
5
+ HOME: "path",
6
+ PATH: "path",
7
+ USER: "identifier",
8
+ LANG: "identifier",
9
+ LC_ALL: "identifier",
10
+ TERM: "identifier",
11
+ TMPDIR: "path",
12
+ SYSTEMROOT: "path",
13
+ COMSPEC: "path",
14
+ PATHEXT: "path",
15
+ WINDIR: "path",
16
+ TEMP: "path",
17
+ TMP: "path",
18
+ AKM_EVENT_SOURCE: "identifier",
19
+ OPENCODE_CONFIG: "path",
20
+ CLAUDE_CONFIG: "path",
21
+ CODEX_CONFIG: "path",
22
+ AWS_PROFILE: "identifier",
23
+ AWS_REGION: "identifier",
24
+ LLM_MODEL: "identifier",
25
+ LLM_BASE_URL: "url",
26
+ };
27
+ /** Environment names whose ordinary values identify runtime configuration rather than credentials. */
28
+ export const ENV_PASSTHROUGH_REDACTION_ALLOWLIST = new Set(Object.keys(ENV_PASSTHROUGH_REDACTION_POLICY));
29
+ const SIGNED_QUERY_KEYS = new Set([
30
+ "accesskey",
31
+ "accesskeyid",
32
+ "accesstoken",
33
+ "actortoken",
34
+ "apikey",
35
+ "assertion",
36
+ "authorization",
37
+ "authorizationcode",
38
+ "authreqid",
39
+ "clientassertion",
40
+ "clientsecret",
41
+ "code",
42
+ "codeverifier",
43
+ "credential",
44
+ "devicecode",
45
+ "googleaccessid",
46
+ "idtoken",
47
+ "idtokenhint",
48
+ "initialaccesstoken",
49
+ "key",
50
+ "loginhinttoken",
51
+ "logouthint",
52
+ "logouttoken",
53
+ "nonce",
54
+ "oauthcode",
55
+ "oauthtoken",
56
+ "oauthverifier",
57
+ "password",
58
+ "refreshtoken",
59
+ "registrationaccesstoken",
60
+ "requesturi",
61
+ "response",
62
+ "secret",
63
+ "sessiontoken",
64
+ "sharedaccesssignature",
65
+ "sig",
66
+ "signature",
67
+ "softwarestatement",
68
+ "state",
69
+ "subjecttoken",
70
+ "token",
71
+ "usercode",
72
+ "verifier",
73
+ "xamzcredential",
74
+ "xamzsecuritytoken",
75
+ "xamzsignature",
76
+ "xgoogcredential",
77
+ "xgoogsignature",
78
+ ]);
79
+ function normalizedQueryKey(key) {
80
+ return key.toLowerCase().replaceAll(/[^a-z0-9]/g, "");
81
+ }
82
+ function collectCredentialParameters(params, values) {
83
+ let found = false;
84
+ for (const [key, value] of params) {
85
+ if (!SIGNED_QUERY_KEYS.has(normalizedQueryKey(key)))
86
+ continue;
87
+ found = true;
88
+ if (value)
89
+ values?.add(value);
90
+ }
91
+ return found;
92
+ }
93
+ function addEncodedCredentialVariants(rawValue, values) {
94
+ if (!rawValue || !values)
95
+ return;
96
+ values.add(rawValue);
97
+ let decoded;
98
+ try {
99
+ decoded = decodeURIComponent(rawValue.replaceAll("+", " "));
100
+ }
101
+ catch {
102
+ return;
103
+ }
104
+ if (!decoded)
105
+ return;
106
+ values.add(decoded);
107
+ const encoded = encodeURIComponent(decoded);
108
+ values.add(encoded);
109
+ values.add(encoded.replaceAll("%20", "+"));
110
+ values.add(encoded.replace(/%[0-9A-F]{2}/g, (sequence) => sequence.toLowerCase()));
111
+ }
112
+ function collectEncodedCredentialParameters(raw, values) {
113
+ let found = false;
114
+ for (const part of raw.split("&")) {
115
+ const separator = part.indexOf("=");
116
+ if (separator < 0)
117
+ continue;
118
+ const rawKey = part.slice(0, separator);
119
+ const rawValue = part.slice(separator + 1);
120
+ let key = rawKey;
121
+ try {
122
+ key = decodeURIComponent(rawKey.replaceAll("+", " "));
123
+ }
124
+ catch {
125
+ // Keep the raw key so malformed credential-shaped input still fails closed.
126
+ }
127
+ if (!SIGNED_QUERY_KEYS.has(normalizedQueryKey(key)))
128
+ continue;
129
+ found = true;
130
+ addEncodedCredentialVariants(rawValue, values);
131
+ }
132
+ return found;
133
+ }
134
+ function collectCredentialFragment(fragment, values) {
135
+ const directDecoded = fragment.includes("=") && collectCredentialParameters(new URLSearchParams(fragment), values);
136
+ const directEncoded = fragment.includes("=") && collectEncodedCredentialParameters(fragment, values);
137
+ let found = directDecoded || directEncoded;
138
+ const nestedQuery = fragment.indexOf("?");
139
+ if (nestedQuery >= 0) {
140
+ const query = fragment.slice(nestedQuery + 1);
141
+ const decoded = collectCredentialParameters(new URLSearchParams(query), values);
142
+ const encoded = collectEncodedCredentialParameters(query, values);
143
+ found = decoded || encoded || found;
144
+ }
145
+ return found;
146
+ }
147
+ function inspectCredentialBearingUrl(value, values) {
148
+ const trimmed = value.trim();
149
+ if (!trimmed)
150
+ return false;
151
+ try {
152
+ const url = new URL(trimmed);
153
+ let found = false;
154
+ for (const userInfo of [url.username, url.password]) {
155
+ if (!userInfo)
156
+ continue;
157
+ found = true;
158
+ values?.add(userInfo);
159
+ try {
160
+ values?.add(decodeURIComponent(userInfo));
161
+ }
162
+ catch {
163
+ values?.add(userInfo);
164
+ }
165
+ }
166
+ const decodedQuery = collectCredentialParameters(url.searchParams, values);
167
+ const encodedQuery = collectEncodedCredentialParameters(url.search.slice(1), values);
168
+ found = decodedQuery || encodedQuery || found;
169
+ return collectCredentialFragment(url.hash.slice(1), values) || found;
170
+ }
171
+ catch {
172
+ // Fail closed for malformed URL-like values carrying the same credential shapes.
173
+ let found = /^[a-z][a-z0-9+.-]*:\/\/[^/\s?#]*@/i.test(trimmed);
174
+ const query = trimmed.indexOf("?");
175
+ const fragment = trimmed.indexOf("#");
176
+ if (query >= 0) {
177
+ const queryText = trimmed.slice(query + 1, fragment >= 0 ? fragment : undefined);
178
+ const decodedQuery = collectCredentialParameters(new URLSearchParams(queryText), values);
179
+ const encodedQuery = collectEncodedCredentialParameters(queryText, values);
180
+ found = decodedQuery || encodedQuery || found;
181
+ }
182
+ if (fragment >= 0) {
183
+ const fragmentText = trimmed.slice(fragment + 1);
184
+ found = collectCredentialFragment(fragmentText, values) || found;
185
+ }
186
+ return found;
187
+ }
188
+ }
189
+ /** Collect exact secrets plus decoded values embedded in credential-bearing URLs. */
190
+ export function collectSensitiveValues(rawValues) {
191
+ const values = new Set();
192
+ for (const value of rawValues) {
193
+ if (value === undefined || value.length === 0)
194
+ continue;
195
+ values.add(value);
196
+ const trimmed = value.trim();
197
+ if (inspectCredentialBearingUrl(value, values) && trimmed)
198
+ values.add(trimmed);
199
+ }
200
+ return [...values];
201
+ }
202
+ /**
203
+ * Decide whether an allowlisted passthrough value may cross an output boundary.
204
+ * The name allowlist never overrides value inspection: URL userinfo and signed
205
+ * query credentials remain secret even under ordinarily non-secret names.
206
+ */
207
+ export function isEnvPassthroughValueSafeToExpose(name, value) {
208
+ if (value === undefined)
209
+ return true;
210
+ const policy = ENV_PASSTHROUGH_REDACTION_POLICY[name];
211
+ if (!policy)
212
+ return false;
213
+ const classifiedPolicy = policy;
214
+ switch (classifiedPolicy) {
215
+ case "identifier":
216
+ case "path":
217
+ case "url":
218
+ return !inspectCredentialBearingUrl(value);
219
+ default: {
220
+ const exhaustive = classifiedPolicy;
221
+ return exhaustive;
222
+ }
223
+ }
224
+ }
225
+ function utf8SequenceLength(firstByte) {
226
+ if (firstByte <= 0x7f)
227
+ return 1;
228
+ if (firstByte >= 0xc2 && firstByte <= 0xdf)
229
+ return 2;
230
+ if (firstByte >= 0xe0 && firstByte <= 0xef)
231
+ return 3;
232
+ if (firstByte >= 0xf0 && firstByte <= 0xf4)
233
+ return 4;
234
+ return 0;
235
+ }
236
+ function normalizeEncodedText(value, plusAsSpace) {
237
+ let text = "";
238
+ const starts = new Int32Array(value.length);
239
+ let mappingLength = 0;
240
+ const append = (decoded, start) => {
241
+ text += decoded;
242
+ for (let index = 0; index < decoded.length; index++) {
243
+ starts[mappingLength] = start;
244
+ mappingLength++;
245
+ }
246
+ };
247
+ for (let index = 0; index < value.length;) {
248
+ if (value[index] === "%" && /^[0-9a-f]{2}$/i.test(value.slice(index + 1, index + 3))) {
249
+ const start = index;
250
+ const firstByte = Number.parseInt(value.slice(index + 1, index + 3), 16);
251
+ const sequenceLength = utf8SequenceLength(firstByte);
252
+ if (sequenceLength > 0) {
253
+ const bytes = [firstByte];
254
+ let cursor = index + 3;
255
+ while (bytes.length < sequenceLength &&
256
+ value[cursor] === "%" &&
257
+ /^[0-9a-f]{2}$/i.test(value.slice(cursor + 1, cursor + 3))) {
258
+ bytes.push(Number.parseInt(value.slice(cursor + 1, cursor + 3), 16));
259
+ cursor += 3;
260
+ }
261
+ if (bytes.length === sequenceLength) {
262
+ try {
263
+ const decoded = new TextDecoder("utf-8", { fatal: true }).decode(Uint8Array.from(bytes));
264
+ index = cursor;
265
+ append(decoded, start);
266
+ continue;
267
+ }
268
+ catch {
269
+ // Treat invalid UTF-8 percent sequences as literal text.
270
+ }
271
+ }
272
+ }
273
+ }
274
+ const start = index;
275
+ const codePoint = value.codePointAt(index);
276
+ if (codePoint === undefined)
277
+ break;
278
+ const character = String.fromCodePoint(codePoint);
279
+ index += character.length;
280
+ append(plusAsSpace && character === "+" ? " " : character, start);
281
+ }
282
+ return { text, starts, sourceLength: value.length };
283
+ }
284
+ function addMappedMatches(coverageDelta, haystack, needle) {
285
+ if (!needle)
286
+ return;
287
+ let offset = 0;
288
+ while (offset <= haystack.text.length - needle.length) {
289
+ const match = haystack.text.indexOf(needle, offset);
290
+ if (match < 0)
291
+ break;
292
+ const start = haystack.starts[match];
293
+ const normalizedEnd = match + needle.length;
294
+ const end = normalizedEnd < haystack.text.length ? haystack.starts[normalizedEnd] : haystack.sourceLength;
295
+ coverageDelta[start] = coverageDelta[start] + 1;
296
+ coverageDelta[end] = coverageDelta[end] - 1;
297
+ offset = match + Math.max(needle.length, 1);
298
+ }
299
+ }
300
+ /**
301
+ * Redact credential-shaped substrings from arbitrary text by pattern alone —
302
+ * unlike {@link redactSensitiveText}, which requires the exact secret value
303
+ * up front, this catches credentials no caller ever knew to list. No
304
+ * truncation is applied; callers that need a length cap (e.g.
305
+ * {@link redactErrorBody} in src/llm/client.ts) apply it themselves.
306
+ *
307
+ * Targets:
308
+ * - `Bearer <token>` headers echoed back by a provider
309
+ * - `sk-…` / `sk_…` style API keys (OpenAI / Anthropic-shaped)
310
+ * - `key-…` / `key_…` shorthand keys
311
+ * - `"api_key": "…"` / `"apiKey": "…"` JSON fields
312
+ * - Discord webhook URLs (`discord.com/api/webhooks/<id>/<token>`) — the id
313
+ * is kept, only the token segment is redacted
314
+ * - Slack incoming-webhook URLs (`hooks.slack.com/services/<team>/<channel>/<token>`)
315
+ * — the team/channel ids are kept, only the trailing token is redacted
316
+ */
317
+ export function redactCredentialPatterns(input) {
318
+ if (!input)
319
+ return "";
320
+ return (input
321
+ // Bearer tokens (case-insensitive)
322
+ .replace(/\bBearer\s+[A-Za-z0-9._\-+/=]+/gi, "Bearer [REDACTED]")
323
+ // sk-/sk_ style keys
324
+ .replace(/\bsk[-_][A-Za-z0-9._-]{6,}/g, "[REDACTED]")
325
+ // key-/key_ shorthand keys
326
+ .replace(/\bkey[-_][A-Za-z0-9._-]{6,}/g, "[REDACTED]")
327
+ // JSON-style "api_key": "...", "apiKey": "...", "api-key": "..."
328
+ .replace(/("(?:api[_-]?key|apiKey|authorization|token)"\s*:\s*")([^"]*)(")/gi, "$1[REDACTED]$3")
329
+ // Discord webhook URLs: keep the webhook id, redact the token segment.
330
+ .replace(/(discord(?:app)?\.com\/api\/webhooks\/\d+\/)[A-Za-z0-9_-]+/gi, "$1[REDACTED]")
331
+ // Slack incoming-webhook URLs: keep the team/channel ids, redact the token.
332
+ .replace(/(hooks\.slack\.com\/services\/[A-Za-z0-9]+\/[A-Za-z0-9]+\/)[A-Za-z0-9]+/gi, "$1[REDACTED]"));
333
+ }
334
+ /**
335
+ * Replace exact sensitive values in text. Longer values are replaced first so
336
+ * an overlapping prefix cannot expose the suffix of a longer credential.
337
+ */
338
+ export function redactSensitiveText(text, sensitiveValues) {
339
+ const values = [...new Set(sensitiveValues)]
340
+ .filter((value) => value.length > 0)
341
+ .sort((a, b) => b.length - a.length || a.localeCompare(b));
342
+ if (values.length === 0)
343
+ return text;
344
+ if (!text.includes("%") && !text.includes("+")) {
345
+ let redacted = text;
346
+ for (const value of values)
347
+ redacted = redacted.replaceAll(value, "[REDACTED]");
348
+ return redacted;
349
+ }
350
+ const coverageDelta = new Int32Array(text.length + 1);
351
+ const addMatchesForMode = (plusAsSpace) => {
352
+ const haystack = normalizeEncodedText(text, plusAsSpace);
353
+ for (const value of values) {
354
+ addMappedMatches(coverageDelta, haystack, normalizeEncodedText(value, plusAsSpace).text);
355
+ }
356
+ };
357
+ addMatchesForMode(false);
358
+ if (text.includes("+"))
359
+ addMatchesForMode(true);
360
+ let redacted = "";
361
+ let coverage = 0;
362
+ let offset = 0;
363
+ let found = false;
364
+ for (let index = 0; index <= text.length; index++) {
365
+ const wasCovered = coverage > 0;
366
+ coverage += coverageDelta[index];
367
+ const isCovered = coverage > 0;
368
+ if (!wasCovered && isCovered) {
369
+ redacted += `${text.slice(offset, index)}[REDACTED]`;
370
+ found = true;
371
+ }
372
+ else if (wasCovered && !isCovered) {
373
+ offset = index;
374
+ }
375
+ }
376
+ return found ? redacted + text.slice(offset) : text;
377
+ }
378
+ /** Recursively redact string leaves before a structured value crosses a durable/output boundary. */
379
+ export function redactSensitiveValue(value, sensitiveValues) {
380
+ const values = [...sensitiveValues];
381
+ const redact = (entry) => {
382
+ if (typeof entry === "string")
383
+ return redactSensitiveText(entry, values);
384
+ if (Array.isArray(entry))
385
+ return entry.map(redact);
386
+ if (entry && typeof entry === "object") {
387
+ return Object.fromEntries(Object.entries(entry).map(([key, child]) => [redactSensitiveText(key, values), redact(child)]));
388
+ }
389
+ return entry;
390
+ };
391
+ return redact(value);
392
+ }