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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -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
+ }
@@ -2,86 +2,57 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  /**
5
- * Dispatch resolver for the standards prompt seam — selects which of the two
6
- * standards features fires for a given write target, mutually exclusively:
5
+ * Dispatch resolver for the standards prompt seam.
7
6
  *
8
- * - **Feature A — wiki schema**: the target is a wiki page (a ref/path under
9
- * `wikis/<name>/`, NOT a `raw/` file and NOT a wiki infra file
10
- * `schema.md`/`index.md`/`log.md`). Returns that wiki's `schema.md` body.
11
- * - **Feature B — stash standards**: the target is any non-wiki asset.
12
- * Returns the concatenated `category: convention`/`meta` fact bodies.
13
- * - **Neither fires**: a wiki `raw/` file or a wiki infra file. Returns `""`.
14
- *
15
- * The two NEVER both fire. Both underlying readers degrade to `""` on
16
- * missing/malformed input and never throw, so this resolver never throws.
7
+ * The wiki `schema.md` injection (former "Feature A") was collapsed in chunk 4
8
+ * with the wiki asset-type death (plan §11 Chunk 4): LLM Wiki content is served
9
+ * by the `llm-wiki` adapter, which owns its own `schema.md` contract. What
10
+ * remains is **stash standards**: for any write target, return the concatenated
11
+ * `category: convention`/`meta` fact bodies plus the per-type SOFT conventions
12
+ * layer (#646), type-scoped to the write target. The underlying readers degrade
13
+ * to `""` on missing/malformed input and never throw, so this resolver never
14
+ * throws.
17
15
  */
18
- import { extractWikiNameFromRef, INDEX_MD, LOG_MD, loadWikiSchema, SCHEMA_MD } from "../../wiki/wiki.js";
16
+ import { typeNameFromConceptId } from "../asset/resolve-ref.js";
19
17
  import { resolveStashStandards } from "./resolve-stash-standards.js";
20
18
  import { resolveTypeConventions, typeConventionRef } from "./resolve-type-conventions.js";
21
- /** Wiki infra files that are not authored pages (relative to the wiki root). */
22
- const WIKI_INFRA_BASENAMES = new Set([SCHEMA_MD, INDEX_MD, LOG_MD]);
23
19
  /**
24
- * Extract the asset type from a canonical ref (`[origin//]type:name`) without
25
- * throwing. Returns `undefined` for refs that have no `type:` prefix. Kept local
26
- * and lenient — the per-type resolver validates the result against
27
- * `getAssetTypes()`, so a bogus prefix here simply yields no convention.
20
+ * Extract the asset type from a write-target ref without throwing. Returns
21
+ * `undefined` for refs that carry no recognizable type. Kept local and lenient —
22
+ * the per-type resolver validates the result against `placementTypes()`, so a
23
+ * bogus prefix here simply yields no convention.
28
24
  */
29
25
  function refType(ref) {
30
26
  if (!ref)
31
27
  return undefined;
32
28
  const body = ref.includes("//") ? ref.slice(ref.indexOf("//") + 2) : ref;
33
- const colon = body.indexOf(":");
34
- if (colon <= 0)
35
- return undefined;
36
- return body.slice(0, colon).trim() || undefined;
29
+ // 0.9.0 conceptId `<stash-subdir>/<name>`: delegate to the D-R2 reverse table
30
+ // so the leading stash subdir maps back to its asset type (the canonical path).
31
+ return typeNameFromConceptId(body)?.type;
37
32
  }
38
33
  /**
39
34
  * Resolve the standards context for a write target identified by its asset ref.
40
35
  *
41
- * @param ref Canonical asset ref of the write target (e.g. `skill:foo`,
42
- * `wiki:research/topics/x`). When undefined, the target is a
43
- * non-wiki authoring flow → stash standards.
36
+ * @param ref Canonical asset ref of the write target (e.g. `skills/foo`).
37
+ * When undefined, the target is a general authoring flow.
44
38
  * @param stashRoot Stash root directory.
45
39
  */
46
40
  export function resolveStandardsContext(ref, stashRoot) {
47
- const wikiName = ref ? extractWikiNameFromRef(ref) : undefined;
48
- if (!wikiName) {
49
- // Non-wiki asset target → Feature B (general stash standards) plus the
50
- // per-type SOFT conventions layer (#646), type-scoped to the write target.
51
- const general = resolveStashStandards(stashRoot);
52
- const type = refType(ref);
53
- // A non-empty body here guarantees `type` is a `getAssetTypes()`-validated
54
- // string (the resolver returns "" otherwise).
55
- const typeConventions = type ? resolveTypeConventions(stashRoot, type) : "";
56
- if (!typeConventions || !type)
57
- return general;
58
- // Soft, type-scoped guidance — clearly labeled and kept separate from the
59
- // HARD (validator-enforced) rules that `authoringRulesForType` injects
60
- // downstream. These facts are advice only; they never weaken the gate.
61
- const softSection = [
62
- `# ${typeConventionRef(type)} (soft per-type conventions — guidance, not enforced)`,
63
- typeConventions,
64
- ].join("\n");
65
- return general ? `${general}\n\n${softSection}` : softSection;
66
- }
67
- // Wiki target. Extract the page path after `wiki:<name>/`.
68
- const prefix = `wiki:${wikiName}/`;
69
- const pagePath = ref?.startsWith(prefix) ? ref.slice(prefix.length) : "";
70
- // `wiki:<name>` with no page, a `raw/` file, or a wiki infra file → neither
71
- // feature fires.
72
- if (!pagePath)
73
- return "";
74
- if (pagePath === "raw" || pagePath.startsWith("raw/"))
75
- return "";
76
- // Infra files (`schema`/`index`/`log`) are only special at the WIKI ROOT.
77
- // A nested page like `wiki:research/analysis/schema` is a genuine page and
78
- // must NOT be suppressed, so only check when the page is at root depth.
79
- if (!pagePath.includes("/")) {
80
- // Refs drop the `.md` extension; compare against both forms defensively.
81
- if (WIKI_INFRA_BASENAMES.has(pagePath) || WIKI_INFRA_BASENAMES.has(`${pagePath}.md`)) {
82
- return "";
83
- }
84
- }
85
- // A genuine wiki page → Feature A (that wiki's schema body).
86
- return loadWikiSchema(stashRoot, wikiName).body;
41
+ // General stash standards plus the per-type SOFT conventions layer (#646),
42
+ // type-scoped to the write target.
43
+ const general = resolveStashStandards(stashRoot);
44
+ const type = refType(ref);
45
+ // A non-empty body here guarantees `type` is a `placementTypes()`-validated
46
+ // string (the resolver returns "" otherwise).
47
+ const typeConventions = type ? resolveTypeConventions(stashRoot, type) : "";
48
+ if (!typeConventions || !type)
49
+ return general;
50
+ // Soft, type-scoped guidance — clearly labeled and kept separate from the
51
+ // HARD (validator-enforced) rules that `authoringRulesForType` injects
52
+ // downstream. These facts are advice only; they never weaken the gate.
53
+ const softSection = [
54
+ `# ${typeConventionRef(type)} (soft per-type conventions — guidance, not enforced)`,
55
+ typeConventions,
56
+ ].join("\n");
57
+ return general ? `${general}\n\n${softSection}` : softSection;
87
58
  }
@@ -53,14 +53,14 @@ function collectMarkdownFiles(dir) {
53
53
  return results;
54
54
  }
55
55
  /**
56
- * Derive a fact ref (`fact:conventions/naming`) from an absolute markdown path
56
+ * Derive a fact ref (`facts/conventions/naming`) from an absolute markdown path
57
57
  * relative to the facts root. Mirrors the canonical-name derivation in
58
58
  * `asset-spec.ts` (POSIX separators, `.md` stripped).
59
59
  */
60
60
  function toFactRef(factsRoot, absPath) {
61
61
  const rel = path.relative(factsRoot, absPath).split(path.sep).join("/");
62
62
  const name = rel.endsWith(".md") ? rel.slice(0, -3) : rel;
63
- return `fact:${name}`;
63
+ return `${FACTS_SUBDIR}/${name}`;
64
64
  }
65
65
  export function resolveStashStandards(stashRoot) {
66
66
  const factsRoot = path.join(stashRoot, FACTS_SUBDIR);