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
@@ -59,7 +59,17 @@
59
59
  */
60
60
  // ── Reflect-size guard ───────────────────────────────────────────────────────
61
61
  import { parseFrontmatter } from "../../../core/asset/frontmatter.js";
62
+ import { parseRefInput } from "../../../core/asset/resolve-ref.js";
62
63
  import { DESCRIPTION_MAX_CHARS, DESCRIPTION_MIN_CHARS, WHEN_TO_USE_MAX_CHARS, WHEN_TO_USE_MIN_CHARS, } from "../../../core/authoring-rules.js";
64
+ import { proposalContent } from "../../../core/file-change.js";
65
+ /**
66
+ * The canonical asset NAME an inputRef names, lower-cased — the tail the
67
+ * "just restates the ref" heuristics compare against. WI-8.5c: the ref is the
68
+ * conceptId (`<subdir>/<name>`), so the name is parsed off the conceptId.
69
+ */
70
+ function refNameTail(inputRef) {
71
+ return parseRefInput(inputRef).name.toLowerCase();
72
+ }
63
73
  import { detectTruncatedDescription, TRUNCATION_TRAILING_WORDS } from "../../../core/text-truncation.js";
64
74
  // ── Description / when_to_use shape ─────────────────────────────────────────
65
75
  export const HEADING_FRAGMENT_PATTERNS = [
@@ -122,7 +132,7 @@ export function isValidDescription(value, inputRef, options = {}) {
122
132
  severity: "warn",
123
133
  };
124
134
  if (!options.skipRefTailCheck) {
125
- const refTail = inputRef.split(":").pop()?.toLowerCase() ?? "";
135
+ const refTail = refNameTail(inputRef);
126
136
  if (refTail.length >= 6 && v.toLowerCase().includes(refTail) && v.length < refTail.length + 40)
127
137
  return { ok: false, reason: "description appears to just name the input ref" };
128
138
  }
@@ -140,7 +150,7 @@ export function isValidWhenToUse(value, inputRef) {
140
150
  return { ok: false, reason: `when_to_use is too long (${v.length} chars; max ${WHEN_TO_USE_MAX_CHARS})` };
141
151
  if (/^when working with\b/i.test(v))
142
152
  return { ok: false, reason: "when_to_use is the circular 'When working with ...' fallback" };
143
- const refTail = inputRef.split(":").pop()?.toLowerCase() ?? "";
153
+ const refTail = refNameTail(inputRef);
144
154
  if (refTail.length >= 6 && v.toLowerCase().includes(refTail) && v.length < refTail.length + 25)
145
155
  return { ok: false, reason: "when_to_use appears to just name the input ref" };
146
156
  return { ok: true };
@@ -267,7 +277,7 @@ const descriptionQualityValidator = {
267
277
  return [];
268
278
  let fm;
269
279
  try {
270
- fm = parseFrontmatter(proposal.payload.content).data;
280
+ fm = parseFrontmatter(proposalContent(proposal)).data;
271
281
  }
272
282
  catch {
273
283
  return [];
@@ -293,7 +303,7 @@ const lessonContentQualityValidator = {
293
303
  return [];
294
304
  let fm;
295
305
  try {
296
- fm = parseFrontmatter(proposal.payload.content).data;
306
+ fm = parseFrontmatter(proposalContent(proposal)).data;
297
307
  }
298
308
  catch {
299
309
  return [];
@@ -322,7 +332,7 @@ const lessonContentQualityValidator = {
322
332
  message: `Lesson proposal ${proposal.id} (${proposal.ref}) has identical description and when_to_use.`,
323
333
  });
324
334
  }
325
- const dfm = detectDoubleFrontmatter(proposal.payload.content);
335
+ const dfm = detectDoubleFrontmatter(proposalContent(proposal));
326
336
  if (dfm)
327
337
  findings.push({ kind: dfm.kind, message: `Lesson proposal ${proposal.id} (${proposal.ref}): ${dfm.message}` });
328
338
  return findings;
@@ -356,7 +366,7 @@ const reflectSizeGuardValidator = {
356
366
  },
357
367
  validate(proposal, ctx) {
358
368
  const sourceBody = stripFrontmatterBody(ctx.source?.content ?? "");
359
- const proposedBody = typeof proposal.payload?.content === "string" ? stripFrontmatterBody(proposal.payload.content) : "";
369
+ const proposedBody = typeof proposal.payload?.content === "string" ? stripFrontmatterBody(proposalContent(proposal)) : "";
360
370
  const outcome = checkReflectSize(sourceBody, proposedBody);
361
371
  if (outcome.ok)
362
372
  return [];
@@ -1,9 +1,12 @@
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
- import { parseAssetRef } from "../../../core/asset/asset-ref.js";
5
4
  import { parseFrontmatter } from "../../../core/asset/frontmatter.js";
5
+ import { parseRefInput } from "../../../core/asset/resolve-ref.js";
6
+ import { proposalContent } from "../../../core/file-change.js";
6
7
  import { lintLessonContent } from "../../../core/lesson-lint.js";
8
+ import { parseTaskDocument } from "../../../tasks/parser.js";
9
+ import { parseWorkflow } from "../../../workflows/parser.js";
7
10
  import { defaultProposalQualityValidators } from "./proposal-quality-validators.js";
8
11
  const genericProposalValidator = {
9
12
  name: "generic-proposal-validator",
@@ -14,7 +17,7 @@ const genericProposalValidator = {
14
17
  findings.push({ kind: "empty-content", message: `Proposal ${proposal.id} has empty content.` });
15
18
  }
16
19
  try {
17
- ctx.parsedRef = parseAssetRef(proposal.ref);
20
+ ctx.parsedRef = parseRefInput(proposal.ref);
18
21
  }
19
22
  catch (err) {
20
23
  findings.push({
@@ -24,9 +27,9 @@ const genericProposalValidator = {
24
27
  ctx.stop = true;
25
28
  return findings;
26
29
  }
27
- if (proposal.payload.content.startsWith("---")) {
30
+ if (proposalContent(proposal).startsWith("---")) {
28
31
  try {
29
- parseFrontmatter(proposal.payload.content);
32
+ parseFrontmatter(proposalContent(proposal));
30
33
  }
31
34
  catch (err) {
32
35
  findings.push({
@@ -38,21 +41,67 @@ const genericProposalValidator = {
38
41
  return findings;
39
42
  },
40
43
  };
41
- const lessonProposalValidator = {
42
- name: "lesson-proposal-validator",
43
- appliesTo(_proposal, ctx) {
44
- return ctx.parsedRef?.type === "lesson";
45
- },
46
- validate(proposal) {
47
- return lintLessonContent(proposal.payload.content, `proposal:${proposal.id}`).findings.map((finding) => ({
44
+ const canonicalProposalValidators = {
45
+ lesson(proposal) {
46
+ return lintLessonContent(proposalContent(proposal), `proposal:${proposal.id}`).findings.map((finding) => ({
48
47
  kind: finding.kind,
49
48
  message: finding.message,
50
49
  }));
51
50
  },
51
+ task(proposal, ctx) {
52
+ const name = ctx.parsedRef?.name;
53
+ if (!name)
54
+ return [];
55
+ parseTaskDocument({
56
+ yaml: proposalContent(proposal),
57
+ filePath: proposal.changes[0]?.path || proposal.ref,
58
+ id: name,
59
+ });
60
+ return [];
61
+ },
62
+ workflow(proposal) {
63
+ const content = proposalContent(proposal);
64
+ if (!content.trim())
65
+ return [];
66
+ const changePath = proposal.changes[0]?.path ?? "";
67
+ const result = parseWorkflow(content, { path: changePath || proposal.ref });
68
+ if (result.ok)
69
+ return [];
70
+ return result.errors.map((error) => ({
71
+ kind: "invalid-workflow-structure",
72
+ message: `Workflow proposal ${proposal.id} (${proposal.ref}) is invalid at line ${error.line}: ${error.message}`,
73
+ }));
74
+ },
75
+ };
76
+ export function hasCanonicalProposalValidator(type) {
77
+ return Object.hasOwn(canonicalProposalValidators, type);
78
+ }
79
+ const canonicalProposalValidator = {
80
+ name: "canonical-asset-proposal-validator",
81
+ appliesTo(_proposal, ctx) {
82
+ return ctx.parsedRef !== undefined && hasCanonicalProposalValidator(ctx.parsedRef.type);
83
+ },
84
+ validate(proposal, ctx) {
85
+ const type = ctx.parsedRef?.type;
86
+ const validator = type ? canonicalProposalValidators[type] : undefined;
87
+ if (!validator)
88
+ return [];
89
+ try {
90
+ return validator(proposal, ctx);
91
+ }
92
+ catch (error) {
93
+ return [
94
+ {
95
+ kind: `invalid-${type}-structure`,
96
+ message: `${type} proposal ${proposal.id} (${proposal.ref}) is invalid: ${error instanceof Error ? error.message : String(error)}`,
97
+ },
98
+ ];
99
+ }
100
+ },
52
101
  };
53
102
  export const defaultProposalValidators = [
54
103
  genericProposalValidator,
55
- lessonProposalValidator,
104
+ canonicalProposalValidator,
56
105
  ...defaultProposalQualityValidators,
57
106
  ];
58
107
  export function runProposalValidators(proposal, validators = defaultProposalValidators, initialContext = {}) {
@@ -4,19 +4,17 @@
4
4
  /**
5
5
  * Proposal validation and content repair.
6
6
  *
7
- * The proposal repository, domain service, and legacy filesystem import moved
8
- * to `../repository.ts` and `../legacy-import.ts` (#578 storage consolidation).
9
- * This module keeps only the two proposal *validators* — {@link validateProposal}
10
- * and {@link repairProposalContent}.
7
+ * The proposal repository and domain service moved to `../repository.ts` (#578
8
+ * storage consolidation). This module keeps only the two proposal *validators* — {@link validateProposal} and
9
+ * {@link repairProposalContent}.
11
10
  */
12
11
  import { repairTruncatedDescription } from "../../../core/text-truncation.js";
13
12
  import { runProposalValidators } from "./proposal-validators.js";
14
13
  /**
15
14
  * Validate a proposal payload before promotion. Generic by default — any
16
- * proposal must parse cleanly and carry a non-empty body. Lessons get the
17
- * extra per-type lint from {@link lintLessonContent} so the contract documented
18
- * in v1 spec §13 is enforced at promotion time. Other asset types can hook
19
- * here in the future without changing call sites.
15
+ * proposal must parse cleanly and carry a non-empty body. Asset types in the
16
+ * fail-closed canonical registry run their existing parser or validator; types
17
+ * without one remain on generic validation.
20
18
  */
21
19
  export function validateProposal(proposal) {
22
20
  return runProposalValidators(proposal);
@@ -14,17 +14,20 @@
14
14
  * `mergeCurateSearchResponses`) by importing them directly.
15
15
  */
16
16
  import fs from "node:fs";
17
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
18
17
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
18
+ import { parseRefInput } from "../../core/asset/resolve-ref.js";
19
19
  import { getIndexPassConfig, loadConfig } from "../../core/config/config.js";
20
20
  import { rethrowIfTestIsolationError, UsageError } from "../../core/errors.js";
21
21
  import { appendEvent } from "../../core/events.js";
22
- import { computeBodyHash } from "../../indexer/db/db.js";
22
+ import { withStateDbTelemetry } from "../../core/state-db.js";
23
23
  import { enqueueGraphExtraction, hasGraphData } from "../../indexer/db/graph-db.js";
24
+ import { copySearchHitAttribution, getSearchHitAttribution, usageEventAttributionMetadata, } from "../../indexer/search/search-attribution.js";
24
25
  import { findSourceForPath, resolveSourceEntries } from "../../indexer/search/search-source.js";
25
26
  import { insertUsageEvent } from "../../indexer/usage/usage-events.js";
26
- import { truncateDescription } from "../../output/shapes.js";
27
+ import { truncateDescription } from "../../output/shapes/helpers.js";
27
28
  import { TELEMETRY_BUSY_TIMEOUT_MS, withIndexDb } from "../../storage/repositories/index-db.js";
29
+ import { findEntryIdByRef, getItemRefById } from "../../storage/repositories/index-entries-repository.js";
30
+ import { computeBodyHash } from "../../storage/repositories/index-llm-cache-repository.js";
28
31
  import { akmSearch, parseSearchSource } from "./search.js";
29
32
  import { akmShowUnified } from "./show.js";
30
33
  const CURATE_FALLBACK_FILTER_WORDS = new Set([
@@ -58,7 +61,7 @@ const CURATE_REFERENCE_QUERY_RE = /\b(?:reference|docs?|guide|how|explain|learn|
58
61
  * Fire-and-forget: log a curate event to the usage_events table and events.jsonl.
59
62
  * Never blocks the caller; errors are silently ignored.
60
63
  */
61
- function logCurateEvent(query, result, eventSource = "user") {
64
+ function logCurateEvent(query, result, eventSource = "user", attributionProjection = "full") {
62
65
  const itemRefs = result.items.map((item) => ("ref" in item ? item.ref : `registry:${item.id}`));
63
66
  appendEvent({
64
67
  eventType: "curate",
@@ -66,25 +69,39 @@ function logCurateEvent(query, result, eventSource = "user") {
66
69
  });
67
70
  try {
68
71
  withIndexDb((db) => {
69
- insertUsageEvent(db, {
70
- event_type: "curate",
71
- query,
72
- metadata: JSON.stringify({
73
- itemCount: result.items.length,
74
- itemRefs,
75
- }),
76
- source: eventSource,
72
+ // Resolve each curated item's DURABLE fully-qualified `item_ref` (D-R3)
73
+ // + entry_id from index.db (`db`); the usage_events writes land in
74
+ // state.db (Chunk-8 WI-8.3).
75
+ const perItem = result.items
76
+ .filter((item) => "ref" in item && typeof item.ref === "string")
77
+ .flatMap((item) => {
78
+ const entryId = findEntryIdByRef(db, item.ref);
79
+ if (entryId === undefined)
80
+ return [];
81
+ const itemRef = getItemRefById(db, entryId);
82
+ return itemRef ? [{ entryRef: itemRef, entryId, item }] : [];
77
83
  });
78
- for (const item of result.items) {
79
- if (!("ref" in item) || typeof item.ref !== "string")
80
- continue;
81
- insertUsageEvent(db, {
84
+ withStateDbTelemetry((stateDb) => {
85
+ insertUsageEvent(stateDb, {
82
86
  event_type: "curate",
83
87
  query,
84
- entry_ref: item.ref,
88
+ metadata: JSON.stringify({
89
+ itemCount: result.items.length,
90
+ itemRefs,
91
+ }),
85
92
  source: eventSource,
86
93
  });
87
- }
94
+ for (const { entryRef, entryId, item } of perItem) {
95
+ insertUsageEvent(stateDb, {
96
+ event_type: "curate",
97
+ query,
98
+ entry_ref: entryRef,
99
+ entry_id: entryId,
100
+ metadata: usageEventAttributionMetadata(getSearchHitAttribution(item), entryRef, attributionProjection),
101
+ source: eventSource,
102
+ });
103
+ }
104
+ }, TELEMETRY_BUSY_TIMEOUT_MS);
88
105
  }, { busyTimeoutMs: TELEMETRY_BUSY_TIMEOUT_MS });
89
106
  }
90
107
  catch (err) {
@@ -97,7 +114,7 @@ export async function akmCurate(options) {
97
114
  throw new UsageError('A curation query is required. Usage: akm curate "<task or prompt>" [--type <type>] [--limit <n>]', "MISSING_REQUIRED_ARGUMENT");
98
115
  }
99
116
  const limit = options.limit && options.limit > 0 ? options.limit : DEFAULT_CURATE_LIMIT;
100
- const source = options.source ?? parseSearchSource("stash");
117
+ const source = options.source ?? parseSearchSource("local");
101
118
  const searchResponse = options.searchResponse ??
102
119
  (await searchForCuration({
103
120
  query: options.query,
@@ -105,30 +122,36 @@ export async function akmCurate(options) {
105
122
  limit: Math.max(limit * CURATE_SEARCH_LIMIT_MULTIPLIER, MIN_CURATE_SEARCH_LIMIT),
106
123
  source,
107
124
  }));
108
- const result = await curateSearchResults(options.query, searchResponse, limit, options.type);
109
- logCurateEvent(options.query, result, options.eventSource);
125
+ const result = await curateSearchResults(options.query, searchResponse, limit, options.type, options.eventSource);
126
+ if (!options.skipLogging) {
127
+ logCurateEvent(options.query, result, options.eventSource, options.attributionProjection);
128
+ }
110
129
  return result;
111
130
  }
112
- export async function curateSearchResults(query, result, limit, selectedType) {
113
- const stashHits = result.hits.filter((hit) => hit.type !== "registry");
131
+ export async function curateSearchResults(query, result, limit, selectedType, eventSource) {
132
+ const allStashHits = result.hits.filter((hit) => hit.type !== "registry");
114
133
  const registryHits = result.registryHits ?? [];
115
- let selectedStashHits;
116
- let supportRefsByRef = new Map();
117
- if (selectedType && selectedType !== "any") {
118
- selectedStashHits = stashHits.slice(0, limit);
119
- }
120
- else {
121
- const selected = selectCuratedStashHits(query, stashHits, limit);
122
- const preferred = preferBroadRootRepresentative(query, selected.selected, stashHits, selected.supportRefsByRef);
123
- selectedStashHits = preferred.selected;
124
- supportRefsByRef = preferred.supportRefsByRef;
125
- }
126
- const selectedRegistryHits = selectedStashHits.length >= limit ? [] : registryHits.slice(0, Math.min(2, limit - selectedStashHits.length));
134
+ // F3/R-018: `--type` must NARROW the candidate pool, not bypass curation.
135
+ // Previously a set `selectedType` skipped `selectCuratedStashHits` (ranking,
136
+ // intent nudges, score floor) entirely, taking the raw top-N of whatever
137
+ // order the hits arrived in. Filtering the pool down to the requested type up front and
138
+ // then running the SAME pipeline over it gives `--type` its intended
139
+ // "narrow, don't disable" semantics — and matters even when the caller's
140
+ // search already applied a type filter at the DB layer, because
141
+ // `curateSearchResults` is also driven directly (tests, `searchResponse`
142
+ // fixtures) with a `SearchResponse` that was never type-filtered.
143
+ const stashHits = selectedType && selectedType !== "any" ? allStashHits.filter((hit) => hit.type === selectedType) : allStashHits;
144
+ const selected = selectCuratedStashHits(query, stashHits, limit);
145
+ const selectedStashHits = selected.selected;
146
+ const supportRefsByRef = selected.supportRefsByRef;
147
+ // F4/R-019: respect `--limit` for registry fill instead of hard-capping it
148
+ // at a bare literal 2 — the remaining slots after stash hits ARE the cap.
149
+ const selectedRegistryHits = selectedStashHits.length >= limit ? [] : registryHits.slice(0, limit - selectedStashHits.length);
127
150
  const selectedRefs = new Set(selectedStashHits.map((hit) => hit.ref));
128
151
  const items = [
129
152
  ...(await Promise.all(selectedStashHits
130
153
  .slice(0, limit)
131
- .map((hit) => enrichCuratedStashHit(query, hit, supportRefsByRef.get(hit.ref) ?? [], selectedRefs)))),
154
+ .map((hit) => enrichCuratedStashHit(query, hit, supportRefsByRef.get(hit.ref) ?? [], selectedRefs, eventSource)))),
132
155
  ...selectedRegistryHits.map((hit) => buildCuratedRegistryItem(query, hit)),
133
156
  ].slice(0, limit);
134
157
  return {
@@ -139,10 +162,10 @@ export async function curateSearchResults(query, result, limit, selectedType) {
139
162
  ...(result.tip ? { tip: result.tip } : {}),
140
163
  };
141
164
  }
142
- async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
165
+ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs, eventSource) {
143
166
  let shown;
144
167
  try {
145
- shown = await akmShowUnified({ ref: hit.ref });
168
+ shown = await akmShowUnified({ ref: hit.ref, eventSource, skipLogging: true });
146
169
  }
147
170
  catch {
148
171
  shown = undefined;
@@ -155,11 +178,16 @@ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
155
178
  const description = shown?.description ?? hit.description;
156
179
  const preview = buildCuratedPreview(shown, hit);
157
180
  const mergedSupportRefs = mergeCurateSupportRefs(supportRefs, shown?.related?.hits, selectedRefs, hit.ref);
158
- return {
159
- source: "stash",
181
+ const item = {
182
+ source: "local",
160
183
  type: shown?.type ?? hit.type,
161
184
  name: shown?.name ?? hit.name,
162
185
  ref: hit.ref,
186
+ path: shown?.path ?? hit.path,
187
+ editable: shown?.editable ?? hit.editable ?? false,
188
+ ...((shown?.editable ?? hit.editable ?? false) === false
189
+ ? { editHint: shown?.editHint ?? hit.editHint ?? `This asset is read-only. Inspect it with: akm show ${hit.ref}` }
190
+ : {}),
163
191
  ...(description ? { description } : {}),
164
192
  ...(preview ? { preview } : {}),
165
193
  ...(shown?.keys?.length ? { keys: shown.keys } : {}),
@@ -170,6 +198,8 @@ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
170
198
  reason: buildCuratedReason(query, shown?.type ?? hit.type),
171
199
  ...(hit.score !== undefined ? { score: hit.score } : {}),
172
200
  };
201
+ copySearchHitAttribution(hit, item, item.description);
202
+ return item;
173
203
  }
174
204
  /**
175
205
  * #624-P3 — enqueue an ungraphed asset for lazy graph extraction when the
@@ -216,7 +246,7 @@ function buildCuratedRegistryItem(query, hit) {
216
246
  name: hit.name,
217
247
  id: hit.id,
218
248
  ...(hit.description ? { description: hit.description } : {}),
219
- followUp: hit.action ?? `akm add ${hit.id}`,
249
+ followUp: hit.action ?? `akm bundle add ${hit.id}`,
220
250
  reason: `Useful external source to explore for ${query}.`,
221
251
  ...(hit.score !== undefined ? { score: hit.score } : {}),
222
252
  };
@@ -254,7 +284,9 @@ function buildCurateSummary(query, items) {
254
284
  if (items.length === 0) {
255
285
  return `No curated assets were selected for "${query}".`;
256
286
  }
257
- const labels = items.map((item) => `${item.type}:${item.name}`);
287
+ // F4b: emit the flipped conceptId ref for stash items (registry items have no
288
+ // ref — keep their `registry:<name>` label).
289
+ const labels = items.map((item) => ("ref" in item ? item.ref : `${item.type}:${item.name}`));
258
290
  return `Selected ${items.length} curated result${items.length === 1 ? "" : "s"}: ${labels.join(", ")}.`;
259
291
  }
260
292
  export function deriveCurateFallbackQueries(query) {
@@ -423,7 +455,10 @@ function computeCurateTypeNudge(type, intent) {
423
455
  }
424
456
  function getCurateFamily(ref) {
425
457
  try {
426
- const parsed = parseAssetRef(ref);
458
+ // F4b: `ref` is a search-hit ref in the 0.9.0 conceptId grammar — parse via
459
+ // the new-grammar `parseRefInput` so skill/reference family grouping still
460
+ // recognizes it.
461
+ const parsed = parseRefInput(ref);
427
462
  if (parsed.type === "skill") {
428
463
  return { key: parsed.name, role: "root" };
429
464
  }
@@ -556,36 +591,6 @@ function collapseCurateFamilies(query, hits) {
556
591
  supportRefsByRef,
557
592
  };
558
593
  }
559
- function preferBroadRootRepresentative(query, selected, allHits, supportRefsByRef) {
560
- const first = selected[0];
561
- if (!first)
562
- return { selected, supportRefsByRef };
563
- const match = /^knowledge:skills\/(.+?)\/references\/(.+)$/.exec(first.ref);
564
- if (!match)
565
- return { selected, supportRefsByRef };
566
- const lower = query.toLowerCase();
567
- const topicTokens = match[2].split(/[^a-z0-9]+/i).filter(Boolean);
568
- const wantsReference = CURATE_REFERENCE_QUERY_RE.test(lower) ||
569
- topicTokens.some((token) => token.length >= 3 && lower.includes(token.toLowerCase()));
570
- if (wantsReference)
571
- return { selected, supportRefsByRef };
572
- const rootRef = `skill:${match[1]}`;
573
- const rootHit = allHits.find((hit) => hit.ref === rootRef);
574
- if (!rootHit)
575
- return { selected, supportRefsByRef };
576
- const next = [rootHit, ...selected.filter((hit) => hit.ref !== first.ref && hit.ref !== rootRef)];
577
- const merged = new Map(supportRefsByRef);
578
- const priorSupport = merged.get(first.ref) ?? [];
579
- for (const entry of priorSupport)
580
- appendCurateSupportRef(merged, rootRef, entry);
581
- appendCurateSupportRef(merged, rootRef, {
582
- ref: first.ref,
583
- type: first.type,
584
- reason: "Related family asset to inspect next.",
585
- });
586
- merged.delete(first.ref);
587
- return { selected: next, supportRefsByRef: merged };
588
- }
589
594
  function mergeCurateSupportRefs(seeded, relatedHits, selectedRefs, ownerRef) {
590
595
  const merged = [];
591
596
  for (const entry of seeded) {