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
@@ -3,100 +3,102 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
- import { resolveStashDir } from "../../core/common.js";
7
- import { getSources, loadConfig } from "../../core/config/config.js";
6
+ import { isSourceWriteActivated } from "../../core/activation-policy.js";
7
+ import { isWithin, resolveStashDir } from "../../core/common.js";
8
+ import { bundleComponentConfig, bundlesToSourceEntries, getSources, loadConfig } from "../../core/config/config.js";
9
+ import { resolveGitContentRoot, resolveWritable } from "../../core/write-source.js";
10
+ import { lockContentRootFor } from "../../integrations/lockfile.js";
8
11
  import { resolveSourceProviderFactory } from "../../sources/provider-factory.js";
9
12
  // Eager side-effect imports so all built-in source providers self-register
10
13
  // before resolveEntryContentDir() runs.
11
14
  import "../../sources/providers/index.js";
12
15
  import { warn } from "../../core/warn.js";
13
- // Legacy "context-hub" / "github" type aliases are normalized to "git" at
14
- // config-load time (see src/config.ts), so this set only contains the canonical
15
- // type.
16
- const GIT_STASH_TYPES = new Set(["git"]);
17
16
  // ── Resolution ──────────────────────────────────────────────────────────────
18
17
  /**
19
18
  * Build the ordered list of stash sources, walking every configured stash
20
19
  * once. Iteration order:
21
20
  *
22
- * 1. The primary stash directory (the entry marked `primary: true`, or the
23
- * legacy top-level `stashDir`). Always emitted, even when the directory
24
- * does not yet exist on disk, so callers can use it as the clone target.
25
- * 2. Each entry in `config.sources[]` (in declared order), excluding the
26
- * one already emitted as the primary.
27
- * 3. Each entry in `config.installed[]` (registry-managed stashes).
21
+ * 1. An explicit argument or `AKM_BUNDLE_DIR`, when present.
22
+ * 2. The configured `defaultBundle`, after component-root validation.
23
+ * 3. Remaining configured bundles in installation-priority order.
28
24
  *
29
25
  * Replaces the previous four-pass loop that walked `stashes[]` separately
30
- * for each provider kind. Disabled entries (`enabled: false`) and entries
31
- * whose disk path doesn't exist are filtered after deduplication.
26
+ * for each provider kind. Disabled entries (`enabled: false`) are filtered
27
+ * after deduplication. Missing configured roots remain in the result so the
28
+ * indexer can classify their scan as incomplete instead of mistaking them for
29
+ * removed sources.
32
30
  */
33
31
  export function resolveSourceEntries(overrideStashDir, existingConfig) {
34
- const stashDir = overrideStashDir ?? resolveStashDir();
35
32
  const config = existingConfig ?? loadConfig();
36
- // Primary stash is always writable.
37
- const sources = [{ path: stashDir, writable: true }];
38
- const seen = new Set([path.resolve(stashDir)]);
39
- const addSource = (dir, registryId, wikiName, writable) => {
33
+ const configuredEntries = bundlesToSourceEntries(config) ?? [];
34
+ const envOverride = process.env.AKM_BUNDLE_DIR?.trim();
35
+ const implicitStashDir = overrideStashDir !== undefined
36
+ ? path.resolve(overrideStashDir)
37
+ : envOverride
38
+ ? resolveStashDir()
39
+ : config.defaultBundle
40
+ ? undefined
41
+ : resolveStashDir();
42
+ // Explicit and environment overrides stay first. Without either override,
43
+ // the configured default enters through the validated loop below.
44
+ const sources = implicitStashDir ? [{ path: implicitStashDir, writable: true }] : [];
45
+ const seen = new Set(implicitStashDir ? [implicitStashDir] : []);
46
+ const addSource = (dir, registryId, writable, type, adapterId, unresolved = false) => {
40
47
  const resolved = path.resolve(dir);
41
48
  if (seen.has(resolved)) {
42
49
  // Already in the source list — typically the primary stash injected at
43
50
  // sources[0] before this loop. Enrich that entry with whatever metadata
44
- // the matching config source carries so `--source <config-name>` can
51
+ // the matching config source carries so `--from <config-name>` can
45
52
  // find it via registryId. Without this, the primary stash entry stays
46
53
  // identity-less and a user-named primary source ("name": "my-stash")
47
54
  // would validate but match zero entries when filtering.
48
55
  const existing = sources.find((s) => s.path === resolved);
49
- if (existing) {
50
- if (registryId && !existing.registryId)
56
+ if (existing && existing.type === undefined) {
57
+ if (registryId)
51
58
  existing.registryId = registryId;
52
- if (wikiName && !existing.wikiName)
53
- existing.wikiName = wikiName;
54
- if (writable && !existing.writable)
55
- existing.writable = true;
59
+ existing.type = type;
60
+ existing.writable = writable;
61
+ existing.adapterId = adapterId;
56
62
  }
63
+ if (existing && unresolved)
64
+ existing.unresolved = true;
57
65
  return;
58
66
  }
59
67
  seen.add(resolved);
60
68
  if (isSuspiciousStashRoot(dir)) {
61
69
  warn(`Warning: stash root "${dir}" appears to be a system directory. This may be unintentional.`);
62
70
  }
63
- if (isValidDirectory(dir)) {
64
- sources.push({
65
- path: resolved,
66
- ...(registryId ? { registryId } : {}),
67
- ...(wikiName ? { wikiName } : {}),
68
- ...(writable ? { writable: true } : {}),
69
- });
70
- }
71
- };
72
- // (1) + (2) Single pass over declared stashes — primary first if present,
73
- // then the rest in declared order. The primary's directory is already
74
- // injected as `sources[0]` above, so we only need to dedupe the source set.
75
- const stashes = getSources(config);
76
- const primaryIdx = stashes.findIndex((entry) => entry.primary === true);
77
- const ordered = [];
78
- if (primaryIdx >= 0) {
79
- ordered.push(stashes[primaryIdx]);
80
- stashes.forEach((entry, i) => {
81
- if (i !== primaryIdx)
82
- ordered.push(entry);
71
+ sources.push({
72
+ path: resolved,
73
+ ...(registryId ? { registryId } : {}),
74
+ writable,
75
+ type,
76
+ ...(adapterId ? { adapterId } : {}),
77
+ ...(unresolved ? { unresolved: true } : {}),
83
78
  });
84
- }
85
- else {
86
- ordered.push(...stashes);
87
- }
88
- for (const entry of ordered) {
79
+ };
80
+ // 0.9.0 shape (spec §10.1 / D-R5): resolve from `bundles` + `defaultBundle`.
81
+ // `bundlesToSourceEntries` returns the configured default first, then map
82
+ // insertion order. Each entry is validated before insertion so a component
83
+ // root can never escape its provider's materialized content root.
84
+ for (const entry of configuredEntries) {
89
85
  if (entry.enabled === false)
90
86
  continue;
91
- const dir = resolveEntryContentDir(entry);
92
- if (dir == null)
87
+ const component = bundleComponentConfig(config.bundles?.[entry.name ?? ""]);
88
+ const contentRoot = resolveEntryContentDir(entry);
89
+ if (contentRoot == null) {
90
+ const unresolvedPath = path.join(implicitStashDir ?? process.cwd(), ".akm", "unresolved-sources", entry.name ?? entry.type);
91
+ addSource(unresolvedPath, entry.name, component?.writable ?? resolveWritable(entry), entry.type, component?.adapter, true);
93
92
  continue;
94
- addSource(dir, entry.name, entry.wikiName, entry.writable === true);
95
- }
96
- // (3) Installed stashes (registry-managed). Always last.
97
- // Only installed entries explicitly marked writable: true are considered writable.
98
- for (const entry of config.installed ?? []) {
99
- addSource(entry.stashRoot, entry.id, entry.wikiName, entry.writable === true);
93
+ }
94
+ const dir = path.resolve(contentRoot, component?.root ?? ".");
95
+ if (!isWithin(dir, contentRoot)) {
96
+ warn(`Warning: component root "${component?.root}" escapes bundle "${entry.name}"; skipping source.`);
97
+ const unresolvedPath = path.join(contentRoot, ".akm", "unresolved-sources", entry.name ?? entry.type);
98
+ addSource(unresolvedPath, entry.name, component?.writable ?? resolveWritable(entry), entry.type, component?.adapter, true);
99
+ continue;
100
+ }
101
+ addSource(dir, entry.name, component?.writable ?? resolveWritable(entry), entry.type, component?.adapter);
100
102
  }
101
103
  return sources;
102
104
  }
@@ -116,7 +118,19 @@ export function resolveSourceEntries(overrideStashDir, existingConfig) {
116
118
  * That convention is part of the akm content layout, not a provider concern,
117
119
  * so it stays here.
118
120
  */
119
- function resolveEntryContentDir(entry) {
121
+ export function resolveEntryContentDir(entry) {
122
+ // §10.2 (WI-8.5) desired/resolved split: a git/npm bundle's desired config
123
+ // carries only the source LOCATOR, not the materialized cache root — the
124
+ // resolved root lives in the lock (`localRoot`). Resolve from there first via
125
+ // the SHARED lock-first resolver (the same one write-source consults, so reads
126
+ // and writes agree on where content is); the localRoot is the already-walkable
127
+ // content root (installed sources are extracted to their content dir), so no
128
+ // content/-subdir step is applied. Fall back to the provider path logic when no
129
+ // lock entry exists (e.g. a git bundle migrated from a `sources[]` url, whose
130
+ // provider re-derives the mirror path).
131
+ const localRoot = lockContentRootFor(entry.name, entry.type);
132
+ if (localRoot != null)
133
+ return localRoot;
120
134
  const factory = resolveSourceProviderFactory(entry.type);
121
135
  if (!factory)
122
136
  return undefined;
@@ -140,9 +154,8 @@ function resolveEntryContentDir(entry) {
140
154
  // layout puts indexable files under `<repo>/content/`, so the walker needs
141
155
  // that subdirectory. This is a content-layout convention, not a provider
142
156
  // capability — keep it here.
143
- if (GIT_STASH_TYPES.has(entry.type)) {
144
- const contentDir = path.join(dir, "content");
145
- return isValidDirectory(contentDir) ? contentDir : dir;
157
+ if (entry.type === "git") {
158
+ return resolveGitContentRoot(dir);
146
159
  }
147
160
  return dir;
148
161
  }
@@ -154,15 +167,10 @@ export function resolveAllStashDirs(overrideStashDir) {
154
167
  }
155
168
  /**
156
169
  * Return the resolved absolute paths of all writable stash sources.
157
- *
158
- * The primary stash is always writable. Filesystem/git sources that have
159
- * `writable: true` in config are also included. Registry-cached sources
160
- * (installed without `writable: true`) are excluded because they are
161
- * overwritten on `akm update` and must never be mutated.
162
170
  */
163
171
  export function getWritableStashDirs(overrideStashDir, existingConfig) {
164
172
  return resolveSourceEntries(overrideStashDir, existingConfig)
165
- .filter((s) => s.writable === true)
173
+ .filter((s) => isSourceWriteActivated(s))
166
174
  .map((s) => s.path);
167
175
  }
168
176
  /**
@@ -197,45 +205,22 @@ export function getPrimarySource(sources) {
197
205
  }
198
206
  // ── Editability ─────────────────────────────────────────────────────────────
199
207
  /**
200
- * Determine whether a file is safe to edit in place.
201
- *
202
- * The only files that are NOT editable are those inside a cache directory
203
- * managed by the package manager (`installed[].cacheDir`). These
204
- * will be overwritten by `akm update` without warning.
205
- *
206
- * Everything else — working stash, additional stashes, local project dirs — is
207
- * the user's domain to manage.
208
+ * Determine whether AKM policy allows modifying this exact file in place.
209
+ * Ownership is resolved by longest source-root match and unknown ownership
210
+ * fails closed. Resolved sources already carry canonical `resolveWritable()`
211
+ * semantics; editability is never persisted in the index.
208
212
  */
209
- export function isEditable(filePath, config) {
210
- const cfg = config ?? loadConfig();
211
- const resolved = path.resolve(filePath);
212
- const cacheManaged = cfg.installed ?? [];
213
- const isWin = process.platform === "win32";
214
- for (const entry of cacheManaged) {
215
- // Local sources reference original paths — always editable
216
- if (entry.source === "local")
217
- continue;
218
- const cacheRoot = path.resolve(entry.cacheDir);
219
- if (isWin) {
220
- // Windows paths are case-insensitive — normalize both sides
221
- if (resolved.toLowerCase().startsWith(cacheRoot.toLowerCase() + path.sep))
222
- return false;
223
- }
224
- else {
225
- if (resolved.startsWith(cacheRoot + path.sep))
226
- return false;
227
- }
228
- }
229
- return true;
213
+ export function isEditable(filePath, config, sources) {
214
+ const resolvedSources = sources ?? resolveSourceEntries(undefined, config ?? loadConfig());
215
+ return findSourceForPath(filePath, resolvedSources)?.writable === true;
230
216
  }
231
217
  /**
232
218
  * Build an actionable hint for the agent when a file is not editable.
233
219
  * Callers must check `isEditable()` before calling — this function
234
220
  * unconditionally returns the hint string.
235
221
  */
236
- export function buildEditHint(_filePath, assetType, assetName, origin) {
237
- const ref = origin ? `${origin}//${assetType}:${assetName}` : `${assetType}:${assetName}`;
238
- return `This asset is managed by akm and may be overwritten on update. To edit, run: akm clone ${ref}`;
222
+ export function buildEditHint(ref) {
223
+ return `This asset is read-only under current AKM source policy. To make an editable copy, run: akm clone ${ref}`;
239
224
  }
240
225
  // ── Validation ──────────────────────────────────────────────────────────────
241
226
  const SUSPICIOUS_ROOTS = new Set(["/", "/etc", "/bin", "/sbin", "/usr", "/var", "/tmp", "/dev", "/proc", "/sys"]);
@@ -252,33 +237,53 @@ function isSuspiciousStashRoot(dir) {
252
237
  }
253
238
  return false;
254
239
  }
255
- // ── Helpers ─────────────────────────────────────────────────────────────────
256
- function isValidDirectory(dir) {
257
- try {
258
- return fs.statSync(dir).isDirectory();
259
- }
260
- catch {
261
- return false;
262
- }
263
- }
264
240
  // ── Stash cache integration ─────────────────────────────────────────────────
265
241
  /**
266
242
  * Ensure all cache-backed stash providers are refreshed so their cache
267
243
  * directories exist on disk. Must be called (async) before
268
244
  * `resolveSourceEntries()` so the content directories pass the
269
245
  * `isValidDirectory()` check.
246
+ *
247
+ * `materialize` (default `true`) is the query-time safety valve (spec §14.3 /
248
+ * D11): the sanctioned materialization callers (`akm index`, source
249
+ * add/update/sync, improve's blocking preflight) pass it truthy and clone/pull/
250
+ * fetch as needed. A READ command's inline auto-index passes `materialize:
251
+ * false` — network is FORBIDDEN at query time, so instead of `sync()` we only
252
+ * check whether each cache-backed source is already materialized: a present
253
+ * cache is served as-is (last-known-good; no TTL pull either), while an absent
254
+ * or partially-staged cache makes that source UNAVAILABLE for the read and is
255
+ * skipped with one warning naming the remedy. The rest of the command still
256
+ * resolves.
270
257
  */
271
258
  export async function ensureSourceCaches(config, options) {
272
259
  const cfg = config ?? loadConfig();
273
260
  const force = options?.force === true;
261
+ const materialize = options?.materialize !== false;
274
262
  // Polymorphic refresh: walk every enabled source through its registered
275
263
  // provider and call `sync()`. Every cache-backed kind (git, website, npm)
276
264
  // refreshes the same way — a bad source warns and is skipped without
277
265
  // aborting the others. The git content/-subdir layout convention stays in
278
- // resolveEntryContentDir.
266
+ // resolveEntryContentDir. NEW shape reads `bundles`; old shape reads sources[].
267
+ //
268
+ // DISTINCTION (deliberately NOT lock-first): refresh derives the PROVIDER's
269
+ // own cache path to git-pull/re-materialize INTO — that derived path is where
270
+ // content ENDS UP; the lock's `localRoot` merely records the result. So this
271
+ // path correctly uses the provider, not the shared `lockContentRootFor`
272
+ // resolver that reads/writes use to agree on where content already IS.
279
273
  for (const entry of getSources(cfg)) {
280
274
  if (entry.enabled === false)
281
275
  continue;
276
+ const lockedRoot = lockContentRootFor(entry.name, entry.type);
277
+ if (lockedRoot) {
278
+ if (!isMaterializedDir(lockedRoot)) {
279
+ warn(`Warning: managed source "${entry.name}" is missing its locked materialization at ${lockedRoot}; ` +
280
+ `run \`akm bundle update ${entry.name}\` to restore it.`);
281
+ }
282
+ // Managed installs are refreshed only by add/update. Hydrating the URL-
283
+ // derived provider cache here would create a second checkout while reads
284
+ // and writes continue using the lock root.
285
+ continue;
286
+ }
282
287
  const factory = resolveSourceProviderFactory(entry.type);
283
288
  if (!factory)
284
289
  continue;
@@ -292,6 +297,12 @@ export async function ensureSourceCaches(config, options) {
292
297
  }
293
298
  if (!provider.sync)
294
299
  continue;
300
+ if (!materialize) {
301
+ // READ path: never clone/pull/fetch. Serve an already-materialized cache
302
+ // as last-known-good; skip an absent/partial one with a single warning.
303
+ warnIfSourceUnavailableForRead(entry, provider.name);
304
+ continue;
305
+ }
295
306
  try {
296
307
  await provider.sync({ force });
297
308
  }
@@ -300,3 +311,38 @@ export async function ensureSourceCaches(config, options) {
300
311
  }
301
312
  }
302
313
  }
314
+ /**
315
+ * True when `dir` holds already-materialized content: it exists, is a
316
+ * directory, and is non-empty. A non-existent path or an empty leftover /
317
+ * partial staging dir reads as NOT materialized so the read skips it rather
318
+ * than walking a hollow cache.
319
+ */
320
+ function isMaterializedDir(dir) {
321
+ try {
322
+ if (!fs.statSync(dir).isDirectory())
323
+ return false;
324
+ return fs.readdirSync(dir).length > 0;
325
+ }
326
+ catch {
327
+ return false;
328
+ }
329
+ }
330
+ /**
331
+ * On a read-path auto-index, warn (once per source) that a cache-backed source
332
+ * is not materialized locally and is being skipped — naming the remedy. Uses
333
+ * the SAME lock-first content-root resolution the walker uses, so an installed
334
+ * source whose content lives at its lock `localRoot` counts as materialized.
335
+ */
336
+ function warnIfSourceUnavailableForRead(entry, providerName) {
337
+ let dir;
338
+ try {
339
+ dir = resolveEntryContentDir(entry);
340
+ }
341
+ catch {
342
+ dir = undefined;
343
+ }
344
+ if (dir && isMaterializedDir(dir))
345
+ return;
346
+ warn(`Warning: source "${providerName}" is not materialized locally; skipping it for this read. ` +
347
+ "Run `akm index` (or `akm bundle update`) to fetch it.");
348
+ }
@@ -11,7 +11,10 @@ export function deriveSemanticProviderFingerprint(embedding) {
11
11
  return `deterministic:${DETERMINISTIC_EMBED_MODEL_ID}`;
12
12
  }
13
13
  if (embedding?.endpoint) {
14
- return `remote:${embedding.endpoint}|${embedding.model}|${embedding.dimension ?? "default"}`;
14
+ // Fingerprint keys on vector identity only (model + dimension). The endpoint
15
+ // is transport/routing and has no bearing on vector compatibility, so moving
16
+ // the same model+dimension to a different host must not force a full re-embed.
17
+ return `remote:${embedding.model}|${embedding.dimension ?? "default"}`;
15
18
  }
16
19
  return `local:${embedding?.localModel ?? DEFAULT_LOCAL_MODEL}`;
17
20
  }
@@ -1,6 +1,14 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
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
+ const USAGE_EVENT_SOURCES = new Set(["user", "improve", "task", "audit", "unknown"]);
5
+ /** Resolve subprocess provenance without treating an invalid value as user demand. */
6
+ export function resolveUsageEventSource(env = process.env) {
7
+ const raw = env.AKM_EVENT_SOURCE;
8
+ if (raw === undefined || raw === "")
9
+ return "user";
10
+ return USAGE_EVENT_SOURCES.has(raw) ? raw : "unknown";
11
+ }
4
12
  // ── Schema ──────────────────────────────────────────────────────────────────
5
13
  export function ensureUsageEventsSchema(db) {
6
14
  db.exec(`
@@ -29,41 +37,13 @@ export function ensureUsageEventsSchema(db) {
29
37
  export function insertUsageEvent(db, event) {
30
38
  try {
31
39
  db.prepare(`INSERT INTO usage_events (event_type, query, entry_id, entry_ref, signal, metadata, source)
32
- VALUES (?, ?, ?, ?, ?, ?, ?)`).run(event.event_type, event.query ?? null, event.entry_id ?? null, event.entry_ref ?? null, event.signal ?? null, event.metadata ?? null, event.source ?? "user");
40
+ VALUES (?, ?, ?, ?, ?, ?, ?)`).run(event.event_type, event.query ?? null, event.entry_id ?? null, event.entry_ref ?? null, event.signal ?? null, event.metadata ?? null, event.source ?? "unknown");
33
41
  }
34
42
  catch {
35
43
  /* fire-and-forget: silently ignore errors */
36
44
  }
37
45
  }
38
46
  // ── Query ────────────────────────────────────────────────────────────────────
39
- /**
40
- * Retrieve usage events, optionally filtered by event_type and/or entry_ref.
41
- */
42
- export function getUsageEvents(db, filters) {
43
- const conditions = [];
44
- const params = [];
45
- if (filters?.event_type) {
46
- conditions.push("event_type = ?");
47
- params.push(filters.event_type);
48
- }
49
- if (filters?.entry_ref) {
50
- conditions.push("entry_ref = ?");
51
- params.push(filters.entry_ref);
52
- }
53
- if (filters?.source) {
54
- conditions.push("source = ?");
55
- params.push(filters.source);
56
- }
57
- if (filters?.since) {
58
- conditions.push("created_at >= ?");
59
- params.push(filters.since);
60
- }
61
- const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
62
- const sql = `SELECT id, event_type, query, entry_id, entry_ref, signal, metadata, source, created_at
63
- FROM usage_events ${where}
64
- ORDER BY id ASC`;
65
- return db.prepare(sql).all(...params);
66
- }
67
47
  /**
68
48
  * Aggregate positive/negative feedback counts for a single entry.
69
49
  *
@@ -78,7 +58,7 @@ export function countFeedbackSignals(db, entryId) {
78
58
  SUM(CASE WHEN signal = 'positive' THEN 1 ELSE 0 END) AS pos,
79
59
  SUM(CASE WHEN signal = 'negative' THEN 1 ELSE 0 END) AS neg
80
60
  FROM usage_events
81
- WHERE event_type = 'feedback' AND entry_id = ?`)
61
+ WHERE event_type = 'feedback' AND entry_id = ? AND source = 'user'`)
82
62
  .get(entryId);
83
63
  return { pos: counts?.pos ?? 0, neg: counts?.neg ?? 0 };
84
64
  }
@@ -67,8 +67,6 @@ export function buildFileContext(stashRoot, absPath) {
67
67
  };
68
68
  }
69
69
  // ── Registry ─────────────────────────────────────────────────────────────────
70
- /** Ordered list of registered matchers. Later registrations win ties. */
71
- const matchers = [];
72
70
  /** Renderer lookup by name. */
73
71
  const renderers = new Map();
74
72
  /**
@@ -77,21 +75,12 @@ const renderers = new Map();
77
75
  * Delegates to the single `initIndexer()` composition root (see
78
76
  * `src/indexer/init.ts`). Imported dynamically to keep this a lazy gate and to
79
77
  * avoid a static import cycle (init -> renderers -> file-context). Called on
80
- * first use of runMatchers/getRenderer/getAllRenderers; idempotent.
78
+ * first use of getRenderer/getAllRenderers; idempotent.
81
79
  */
82
80
  async function ensureBuiltinsRegistered() {
83
81
  const { initIndexer } = await import("../init.js");
84
82
  await initIndexer();
85
83
  }
86
- /**
87
- * Register an AssetMatcher.
88
- *
89
- * Matchers are evaluated in registration order. When two matchers produce
90
- * the same specificity score, the one registered later wins.
91
- */
92
- export function registerMatcher(matcher) {
93
- matchers.push(matcher);
94
- }
95
84
  /**
96
85
  * Register an AssetRenderer.
97
86
  *
@@ -114,47 +103,16 @@ export async function getAllRenderers() {
114
103
  await ensureBuiltinsRegistered();
115
104
  return Array.from(renderers.values());
116
105
  }
117
- /**
118
- * Run every registered matcher against a FileContext and return the
119
- * highest-specificity result.
120
- *
121
- * Resolution rules:
122
- * 1. Every matcher is invoked; null returns are discarded.
123
- * 2. Results are ranked by specificity (descending).
124
- * 3. Ties are broken by registration order: the matcher registered later wins
125
- * (this lets user-registered matchers override built-in ones).
126
- * 4. Returns null when no matcher claims the file.
127
- */
128
- export async function runMatchers(ctx) {
129
- await ensureBuiltinsRegistered();
130
- // Collect (result, registrationIndex) pairs from all matchers.
131
- const hits = [];
132
- for (let i = 0; i < matchers.length; i++) {
133
- const result = matchers[i](ctx);
134
- if (result !== null) {
135
- hits.push({ result, index: i });
136
- }
137
- }
138
- if (hits.length === 0)
139
- return null;
140
- // Sort by specificity descending, then by registration index descending (later wins ties).
141
- hits.sort((a, b) => {
142
- const specDiff = b.result.specificity - a.result.specificity;
143
- if (specDiff !== 0)
144
- return specDiff;
145
- return b.index - a.index;
146
- });
147
- return hits[0].result;
148
- }
149
106
  /**
150
107
  * Build a RenderContext by merging a FileContext with its winning MatchResult
151
108
  * and the list of stash search paths.
152
109
  */
153
- export function buildRenderContext(ctx, match, stashDirs, origin) {
110
+ export function buildRenderContext(ctx, match, stashDirs, origin, defaultBundle) {
154
111
  return {
155
112
  ...ctx,
156
113
  matchResult: match,
157
114
  stashDirs,
158
115
  origin,
116
+ defaultBundle,
159
117
  };
160
118
  }