akm-cli 0.9.0-rc.4 → 0.9.0-rc.6

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 (438) hide show
  1. package/CHANGELOG.md +122 -26
  2. package/README.md +7 -7
  3. package/SECURITY.md +11 -10
  4. package/dist/akm +2 -2
  5. package/dist/akm-migrate-storage +2 -2
  6. package/dist/assets/hints/cli-hints-full.md +60 -73
  7. package/dist/assets/hints/cli-hints-short.md +8 -12
  8. package/dist/assets/improve-strategies/default.json +5 -7
  9. package/dist/assets/improve-strategies/frequent.json +2 -2
  10. package/dist/assets/improve-strategies/proactive-maintenance.json +2 -2
  11. package/dist/assets/improve-strategies/quick.json +1 -1
  12. package/dist/assets/improve-strategies/reflect-distill.json +3 -3
  13. package/dist/assets/improve-strategies/thorough.json +1 -1
  14. package/dist/assets/prompts/consolidate-system.md +5 -5
  15. package/dist/assets/prompts/extract-session.md +2 -6
  16. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  17. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  18. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  19. package/dist/assets/stash-skeleton/README.md +10 -11
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +1 -1
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +1 -1
  22. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +1 -1
  23. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -2
  24. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -2
  25. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +1 -1
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -2
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +1 -1
  28. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +18 -18
  29. package/dist/assets/stash-skeleton/facts/conventions/domains.md +8 -9
  30. package/dist/assets/stash-skeleton/facts/conventions/organization.md +13 -15
  31. package/dist/assets/tasks/core/extract.yml +2 -2
  32. package/dist/assets/tasks/core/improve.yml +1 -1
  33. package/dist/assets/templates/html/health.html +2 -3
  34. package/dist/cli/config-migrate.js +1328 -101
  35. package/dist/cli/invocation.js +255 -0
  36. package/dist/cli/parse-args.js +20 -83
  37. package/dist/cli/shared.js +15 -37
  38. package/dist/cli.js +18 -49
  39. package/dist/commands/agent/agent-dispatch.js +2 -2
  40. package/dist/commands/agent/contribute-cli.js +5 -4
  41. package/dist/commands/bundle/bundle-cli.js +68 -0
  42. package/dist/commands/bundle/bundle.js +219 -0
  43. package/dist/commands/completions.js +2 -2
  44. package/dist/commands/config-cli.js +6 -3
  45. package/dist/commands/env/env-binding.js +13 -9
  46. package/dist/commands/env/env-cli.js +49 -48
  47. package/dist/commands/env/secret-cli.js +24 -10
  48. package/dist/commands/events.js +2 -2
  49. package/dist/commands/feedback-cli.js +59 -33
  50. package/dist/commands/graph/graph.js +6 -4
  51. package/dist/commands/health/advisories.js +4 -4
  52. package/dist/commands/health/html-report.js +190 -593
  53. package/dist/commands/health/improve-metrics.js +240 -188
  54. package/dist/commands/health/metrics.js +9 -17
  55. package/dist/commands/health/report-view-model.js +509 -0
  56. package/dist/commands/health/surfaces.js +6 -3
  57. package/dist/commands/health/types-checks.js +4 -0
  58. package/dist/commands/health/types-improve.js +22 -0
  59. package/dist/commands/health/types-metrics.js +4 -0
  60. package/dist/commands/health/types-result.js +7 -0
  61. package/dist/commands/health/types-runs.js +4 -0
  62. package/dist/commands/health/types-session-log.js +4 -0
  63. package/dist/commands/health/types-windows.js +4 -0
  64. package/dist/commands/health/types.js +26 -21
  65. package/dist/commands/health/windows.js +1 -2
  66. package/dist/commands/health.js +219 -161
  67. package/dist/commands/improve/collapse-detector.js +25 -14
  68. package/dist/commands/improve/consolidate/chunking.js +7 -5
  69. package/dist/commands/improve/consolidate.js +640 -740
  70. package/dist/commands/improve/content-hash.js +39 -0
  71. package/dist/commands/improve/distill/content-repair.js +4 -10
  72. package/dist/commands/improve/distill/promote-memory.js +79 -49
  73. package/dist/commands/improve/distill/quality-gate.js +113 -35
  74. package/dist/commands/improve/distill-promotion-policy.js +24 -885
  75. package/dist/commands/improve/distill.js +565 -337
  76. package/dist/commands/improve/eligibility.js +75 -36
  77. package/dist/commands/improve/extract-cli.js +6 -6
  78. package/dist/commands/improve/extract-prompt.js +5 -34
  79. package/dist/commands/improve/extract.js +526 -357
  80. package/dist/commands/improve/feedback-valence.js +2 -12
  81. package/dist/commands/improve/improve-cli.js +11 -20
  82. package/dist/commands/improve/improve-result-file.js +7 -6
  83. package/dist/commands/improve/improve-run-types.js +4 -0
  84. package/dist/commands/improve/improve-strategies.js +3 -9
  85. package/dist/commands/improve/improve.js +822 -727
  86. package/dist/commands/improve/locks.js +27 -95
  87. package/dist/commands/improve/loop-stages.js +941 -963
  88. package/dist/commands/improve/memory/derived-ref.js +122 -0
  89. package/dist/commands/improve/memory/memory-contradiction-detect.js +35 -38
  90. package/dist/commands/improve/memory/memory-improve.js +24 -37
  91. package/dist/commands/improve/outcome-loop.js +13 -33
  92. package/dist/commands/improve/preparation.js +889 -691
  93. package/dist/commands/improve/proactive-maintenance.js +37 -9
  94. package/dist/commands/improve/proposal-envelope.js +31 -0
  95. package/dist/commands/improve/reflect.js +974 -588
  96. package/dist/commands/improve/run-context.js +119 -0
  97. package/dist/commands/improve/salience.js +8 -4
  98. package/dist/commands/improve/session-asset.js +7 -3
  99. package/dist/commands/improve/shared.js +14 -40
  100. package/dist/commands/improve/source-identity.js +39 -26
  101. package/dist/commands/improve/triage.js +20 -17
  102. package/dist/commands/lint/base-linter.js +288 -295
  103. package/dist/commands/lint/index.js +132 -19
  104. package/dist/commands/mv-cli.js +257 -234
  105. package/dist/commands/observability-cli.js +2 -1
  106. package/dist/commands/proposal/diff-format.js +50 -0
  107. package/dist/commands/proposal/drain-policies.js +0 -6
  108. package/dist/commands/proposal/drain.js +17 -16
  109. package/dist/commands/proposal/proposal-cli.js +40 -77
  110. package/dist/commands/proposal/proposal-types.js +56 -0
  111. package/dist/commands/proposal/proposal.js +39 -1
  112. package/dist/commands/proposal/propose.js +41 -19
  113. package/dist/commands/proposal/repository.js +566 -486
  114. package/dist/commands/proposal/validators/proposal-quality-validators.js +22 -6
  115. package/dist/commands/proposal/validators/proposal-validators.js +6 -5
  116. package/dist/commands/proposal/validators/proposals.js +5 -4
  117. package/dist/commands/read/curate.js +50 -28
  118. package/dist/commands/read/knowledge.js +25 -16
  119. package/dist/commands/read/remember-cli.js +12 -4
  120. package/dist/commands/read/search-cli.js +33 -33
  121. package/dist/commands/read/search.js +68 -55
  122. package/dist/commands/read/show.js +54 -135
  123. package/dist/commands/remember.js +7 -5
  124. package/dist/commands/sources/add-cli.js +10 -24
  125. package/dist/commands/sources/bundle-config-ops.js +58 -0
  126. package/dist/commands/sources/history.js +13 -8
  127. package/dist/commands/sources/info.js +10 -11
  128. package/dist/commands/sources/init.js +12 -21
  129. package/dist/commands/sources/installed-stashes.js +151 -138
  130. package/dist/commands/sources/schema-repair.js +5 -3
  131. package/dist/commands/sources/self-update.js +9 -7
  132. package/dist/commands/sources/source-add.js +116 -154
  133. package/dist/commands/sources/source-clone.js +33 -14
  134. package/dist/commands/sources/source-manage.js +43 -32
  135. package/dist/commands/sources/sources-cli.js +12 -7
  136. package/dist/commands/sources/stash-cli.js +12 -5
  137. package/dist/commands/sources/stash-skeleton.js +1 -1
  138. package/dist/commands/tasks/default-tasks.js +13 -13
  139. package/dist/commands/tasks/tasks-cli.js +3 -3
  140. package/dist/commands/tasks/tasks.js +71 -31
  141. package/dist/commands/workflow-cli.js +22 -26
  142. package/dist/core/action-contributors.js +1 -1
  143. package/dist/core/activation-policy.js +49 -0
  144. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  145. package/dist/core/adapter/adapters/akm-adapter.js +509 -0
  146. package/dist/core/adapter/adapters/akm-lint.js +381 -0
  147. package/dist/core/adapter/adapters/akm-metadata.js +416 -0
  148. package/dist/core/adapter/adapters/akm-task-adapter.js +150 -0
  149. package/dist/core/adapter/adapters/akm-workflow-adapter.js +196 -0
  150. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  151. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  152. package/dist/core/adapter/adapters/generic-files-adapter.js +117 -0
  153. package/dist/core/adapter/adapters/index.js +80 -0
  154. package/dist/core/adapter/adapters/llm-wiki-adapter.js +413 -0
  155. package/dist/core/adapter/adapters/okf-adapter.js +223 -0
  156. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  157. package/dist/core/adapter/adapters/shared.js +286 -0
  158. package/dist/core/adapter/adapters/tool-dir-shared.js +212 -0
  159. package/dist/core/adapter/adapters/website-snapshot-adapter.js +154 -0
  160. package/dist/core/adapter/bundle-adapter.js +4 -0
  161. package/dist/core/adapter/recognize-match.js +42 -0
  162. package/dist/core/adapter/registry.js +56 -0
  163. package/dist/core/adapter/types.js +4 -0
  164. package/dist/core/asset/asset-placement.js +229 -0
  165. package/dist/core/asset/asset-ref.js +107 -78
  166. package/dist/core/asset/asset-serialize.js +20 -0
  167. package/dist/core/asset/frontmatter.js +1 -1
  168. package/dist/core/asset/resolve-ref.js +223 -0
  169. package/dist/core/asset/stash-meta.js +1 -1
  170. package/dist/core/common.js +141 -49
  171. package/dist/core/config/config-io.js +0 -108
  172. package/dist/core/config/config-schema.js +94 -1039
  173. package/dist/core/config/config-sources.js +115 -36
  174. package/dist/core/config/config-types.js +16 -11
  175. package/dist/core/config/config-walker.js +4 -2
  176. package/dist/core/config/config.js +21 -26
  177. package/dist/core/config/engine-semantics.js +0 -4
  178. package/dist/core/config/schema/embedding.js +38 -0
  179. package/dist/core/config/schema/engines.js +116 -0
  180. package/dist/core/config/schema/feedback.js +31 -0
  181. package/dist/core/config/schema/improve-processes.js +395 -0
  182. package/dist/core/config/schema/improve.js +76 -0
  183. package/dist/core/config/schema/index-config.js +183 -0
  184. package/dist/core/config/schema/output.js +15 -0
  185. package/dist/core/config/schema/primitives.js +94 -0
  186. package/dist/core/config/schema/search.js +30 -0
  187. package/dist/core/config/schema/setup.js +27 -0
  188. package/dist/core/config/schema/sources-bundles.js +164 -0
  189. package/dist/core/config/schema/workflow.js +29 -0
  190. package/dist/core/env-secret-ref.js +113 -8
  191. package/dist/core/errors.js +1 -1
  192. package/dist/core/events-types.js +4 -0
  193. package/dist/core/extra-params.js +1 -0
  194. package/dist/core/file-change.js +16 -0
  195. package/dist/core/fs-txn.js +316 -0
  196. package/dist/core/git-message.js +59 -0
  197. package/dist/core/improve-result.js +9 -1
  198. package/dist/core/logs-db.js +1 -1
  199. package/dist/core/maintenance-barrier.js +16 -0
  200. package/dist/core/migration-backup.js +332 -160
  201. package/dist/core/paths.js +3 -6
  202. package/dist/core/platform.js +10 -0
  203. package/dist/core/recognition-util.js +130 -0
  204. package/dist/core/redaction.js +2 -2
  205. package/dist/core/standards/resolve-standards-context.js +47 -64
  206. package/dist/core/standards/resolve-type-conventions.js +3 -3
  207. package/dist/core/state/migrations.js +201 -8
  208. package/dist/core/state-db.js +38 -2
  209. package/dist/core/subprocess.js +303 -0
  210. package/dist/core/time.js +20 -0
  211. package/dist/core/type-presentation.js +130 -0
  212. package/dist/core/write-source.js +39 -67
  213. package/dist/indexer/bundle-identity-guard.js +91 -0
  214. package/dist/indexer/db/graph-db.js +1 -1
  215. package/dist/indexer/db/llm-cache.js +1 -1
  216. package/dist/indexer/ensure-index.js +29 -9
  217. package/dist/indexer/graph/graph-boost.js +28 -24
  218. package/dist/indexer/graph/graph-extraction.js +5 -6
  219. package/dist/indexer/graph/graph-types.js +4 -0
  220. package/dist/indexer/index-written-assets.js +44 -17
  221. package/dist/indexer/indexer.js +289 -153
  222. package/dist/indexer/init.js +18 -25
  223. package/dist/indexer/installations.js +224 -0
  224. package/dist/indexer/passes/dir-staleness.js +2 -1
  225. package/dist/indexer/passes/memory-inference.js +8 -4
  226. package/dist/indexer/passes/metadata.js +96 -243
  227. package/dist/indexer/scan/doc-to-entry.js +123 -0
  228. package/dist/indexer/scan/drain-dir.js +144 -0
  229. package/dist/indexer/search/db-search.js +171 -99
  230. package/dist/indexer/search/fts-query.js +1 -1
  231. package/dist/indexer/search/ranking-contributors.js +57 -7
  232. package/dist/indexer/search/ranking-types.js +4 -0
  233. package/dist/indexer/search/ranking.js +31 -6
  234. package/dist/indexer/search/search-attribution.js +67 -0
  235. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  236. package/dist/indexer/search/search-source.js +109 -52
  237. package/dist/indexer/search/semantic-status.js +4 -1
  238. package/dist/indexer/usage/unmigrated-vaults-guard.js +2 -1
  239. package/dist/indexer/usage/usage-events.js +72 -9
  240. package/dist/indexer/walk/file-context.js +1 -44
  241. package/dist/indexer/walk/matchers.js +16 -32
  242. package/dist/indexer/walk/path-resolver.js +6 -5
  243. package/dist/indexer/walk/walker.js +4 -2
  244. package/dist/integrations/agent/engine-resolution.js +22 -0
  245. package/dist/integrations/agent/model-aliases.js +1 -1
  246. package/dist/integrations/agent/prompts.js +35 -11
  247. package/dist/integrations/agent/spawn.js +41 -270
  248. package/dist/integrations/harnesses/aider/agent-builder.js +2 -2
  249. package/dist/integrations/harnesses/aider/index.js +2 -11
  250. package/dist/integrations/harnesses/amazonq/agent-builder.js +1 -9
  251. package/dist/integrations/harnesses/amazonq/index.js +3 -16
  252. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  253. package/dist/integrations/harnesses/claude/index.js +1 -12
  254. package/dist/integrations/harnesses/claude/session-log.js +27 -65
  255. package/dist/integrations/harnesses/codex/agent-builder.js +1 -2
  256. package/dist/integrations/harnesses/codex/index.js +2 -12
  257. package/dist/integrations/harnesses/copilot/agent-builder.js +2 -3
  258. package/dist/integrations/harnesses/copilot/index.js +1 -12
  259. package/dist/integrations/harnesses/gemini/agent-builder.js +1 -3
  260. package/dist/integrations/harnesses/gemini/index.js +1 -12
  261. package/dist/integrations/harnesses/ids.js +24 -0
  262. package/dist/integrations/harnesses/index.js +27 -2
  263. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  264. package/dist/integrations/harnesses/opencode/index.js +1 -12
  265. package/dist/integrations/harnesses/opencode/session-log.js +67 -110
  266. package/dist/integrations/harnesses/opencode-sdk/harness.js +2 -11
  267. package/dist/integrations/harnesses/openhands/agent-builder.js +3 -3
  268. package/dist/integrations/harnesses/openhands/index.js +2 -11
  269. package/dist/integrations/harnesses/pi/agent-builder.js +3 -11
  270. package/dist/integrations/harnesses/pi/index.js +3 -15
  271. package/dist/integrations/harnesses/shared.js +17 -0
  272. package/dist/integrations/harnesses/types.js +37 -2
  273. package/dist/integrations/lockfile.js +36 -0
  274. package/dist/integrations/session-logs/index.js +21 -12
  275. package/dist/integrations/session-logs/provider-base.js +113 -0
  276. package/dist/llm/client.js +7 -5
  277. package/dist/llm/embedders/deterministic.js +2 -2
  278. package/dist/llm/embedders/remote.js +8 -4
  279. package/dist/llm/graph-extract.js +7 -2
  280. package/dist/llm/metadata-enhance.js +43 -26
  281. package/dist/llm/structured-call.js +15 -7
  282. package/dist/migrate/legacy/config-source-migration.js +223 -0
  283. package/dist/migrate/legacy/content-migration.js +305 -0
  284. package/dist/migrate/legacy/legacy-layout.js +779 -0
  285. package/dist/migrate/legacy/legacy-paths.js +25 -0
  286. package/dist/migrate/legacy/legacy-stash-json.js +72 -0
  287. package/dist/migrate/legacy/proposal-fs-import.js +168 -0
  288. package/dist/migrate/legacy/task-target-ref-migration.js +272 -0
  289. package/dist/migrate/legacy/three-db-cutover.js +840 -0
  290. package/dist/migrate/legacy/workflow-migrations-bodies.js +52 -0
  291. package/dist/migrate/legacy/workflow-migrations-frozen.js +21 -0
  292. package/dist/migrate/legacy-ref-grammar.js +209 -0
  293. package/dist/output/command-registry.js +27 -0
  294. package/dist/output/html-render.js +11 -16
  295. package/dist/output/renderers.js +32 -276
  296. package/dist/output/shapes/passthrough.js +3 -9
  297. package/dist/output/shapes/registry.js +12 -6
  298. package/dist/output/text/command-format.js +547 -0
  299. package/dist/output/text/helpers.js +15 -1377
  300. package/dist/output/text/proposal-format.js +230 -0
  301. package/dist/output/text/registry.js +12 -6
  302. package/dist/output/text/show-directives.js +107 -0
  303. package/dist/output/text/show-format.js +103 -0
  304. package/dist/output/text/workflow-format.js +345 -0
  305. package/dist/output/text.js +1 -3
  306. package/dist/registry/build-index.js +13 -17
  307. package/dist/registry/providers/static-index.js +2 -2
  308. package/dist/registry/resolve.js +4 -90
  309. package/dist/registry/semver.js +93 -0
  310. package/dist/runtime.js +90 -0
  311. package/dist/schemas/akm-config.json +2956 -14890
  312. package/dist/schemas/akm-task.json +2 -2
  313. package/dist/schemas/akm-workflow.json +2 -2
  314. package/dist/scripts/migrate-storage.js +2312 -19642
  315. package/dist/setup/detect.js +5 -7
  316. package/dist/setup/engine-config.js +2 -1
  317. package/dist/setup/registry-stash-loader.js +1 -1
  318. package/dist/setup/semantic-assets.js +12 -9
  319. package/dist/setup/setup.js +109 -39
  320. package/dist/setup/steps/connection-shared.js +120 -0
  321. package/dist/setup/steps/connection.js +50 -274
  322. package/dist/setup/steps/platforms.js +1 -0
  323. package/dist/setup/steps/sources.js +13 -6
  324. package/dist/setup/steps/stashdir.js +5 -2
  325. package/dist/sources/freshness.js +39 -0
  326. package/dist/sources/providers/git-provider.js +29 -33
  327. package/dist/sources/providers/git-stash.js +10 -5
  328. package/dist/sources/providers/provider-utils.js +40 -18
  329. package/dist/sources/providers/website.js +1 -1
  330. package/dist/sources/resolve.js +5 -5
  331. package/dist/sources/snapshot-fetchers/types.js +4 -0
  332. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +105 -39
  333. package/dist/storage/database.js +47 -3
  334. package/dist/storage/engines/sqlite-migrations.js +34 -16
  335. package/dist/storage/locations.js +1 -2
  336. package/dist/storage/repositories/improve-runs-repository.js +0 -20
  337. package/dist/storage/repositories/index-connection.js +80 -0
  338. package/dist/storage/repositories/index-db.js +4 -3
  339. package/dist/storage/repositories/index-entries-repository.js +952 -0
  340. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +15 -2
  341. package/dist/storage/repositories/index-entry-types.js +4 -0
  342. package/dist/storage/repositories/index-fts-repository.js +164 -0
  343. package/dist/storage/repositories/index-llm-cache-repository.js +109 -0
  344. package/dist/storage/repositories/index-meta-repository.js +50 -0
  345. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +241 -100
  346. package/dist/storage/repositories/index-sql.js +12 -0
  347. package/dist/storage/repositories/index-utility-repository.js +369 -0
  348. package/dist/storage/repositories/index-vec-repository.js +245 -0
  349. package/dist/storage/repositories/proposals-repository.js +41 -50
  350. package/dist/storage/repositories/registry-cache.js +1 -1
  351. package/dist/storage/repositories/workflow-runs-repository.js +17 -11
  352. package/dist/tasks/backends/cron.js +5 -5
  353. package/dist/tasks/backends/exec-utils.js +21 -0
  354. package/dist/tasks/backends/index.js +6 -9
  355. package/dist/tasks/backends/launchd.js +16 -17
  356. package/dist/tasks/backends/schtasks.js +33 -41
  357. package/dist/tasks/backends/types.js +4 -0
  358. package/dist/tasks/parser.js +25 -5
  359. package/dist/tasks/runner.js +33 -39
  360. package/dist/tasks/validator.js +5 -6
  361. package/dist/workflows/authoring/authoring.js +8 -11
  362. package/dist/workflows/exec/brief.js +10 -7
  363. package/dist/workflows/exec/report.js +261 -156
  364. package/dist/workflows/exec/run-workflow.js +2 -1
  365. package/dist/workflows/exec/step-work.js +3 -9
  366. package/dist/workflows/program/parser.js +4 -60
  367. package/dist/workflows/renderer.js +11 -60
  368. package/dist/workflows/runtime/checkin.js +1 -1
  369. package/dist/workflows/runtime/plan-classifier.js +7 -4
  370. package/dist/workflows/runtime/runs.js +11 -10
  371. package/dist/workflows/runtime/unit-checkin.js +1 -1
  372. package/dist/workflows/runtime/unit-phases.js +20 -0
  373. package/dist/workflows/runtime/workflow-asset-loader.js +27 -16
  374. package/dist/workflows/validate-summary.js +2 -2
  375. package/dist/workflows/validator.js +18 -2
  376. package/docs/migration/release-notes/0.9.0.md +45 -3
  377. package/docs/migration/v0.8-to-v0.9.md +466 -262
  378. package/docs/{data-and-telemetry.md → reference/data-and-telemetry.md} +61 -17
  379. package/package.json +10 -9
  380. package/schemas/akm-config.json +2956 -14890
  381. package/schemas/akm-task.json +2 -2
  382. package/schemas/akm-workflow.json +2 -2
  383. package/dist/assets/help/help-accept.md +0 -12
  384. package/dist/assets/help/help-improve.md +0 -84
  385. package/dist/assets/help/help-proposals.md +0 -17
  386. package/dist/assets/help/help-propose.md +0 -17
  387. package/dist/assets/help/help-reject.md +0 -11
  388. package/dist/assets/improve-strategies/recombine-only.json +0 -23
  389. package/dist/assets/improve-strategies/synthesize.json +0 -17
  390. package/dist/assets/prompts/procedural-system.md +0 -44
  391. package/dist/assets/prompts/recombine-system.md +0 -40
  392. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  393. package/dist/assets/templates/html/default.html +0 -78
  394. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  395. package/dist/assets/wiki/index-template.md +0 -12
  396. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  397. package/dist/assets/wiki/log-template.md +0 -8
  398. package/dist/assets/wiki/schema-template.md +0 -61
  399. package/dist/commands/improve/calibration.js +0 -161
  400. package/dist/commands/improve/dedup.js +0 -482
  401. package/dist/commands/improve/hot-probation.js +0 -45
  402. package/dist/commands/improve/improve-auto-accept.js +0 -262
  403. package/dist/commands/improve/procedural.js +0 -403
  404. package/dist/commands/improve/recombine.js +0 -843
  405. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  406. package/dist/commands/lint/agent-linter.js +0 -44
  407. package/dist/commands/lint/command-linter.js +0 -44
  408. package/dist/commands/lint/default-linter.js +0 -16
  409. package/dist/commands/lint/fact-linter.js +0 -39
  410. package/dist/commands/lint/knowledge-linter.js +0 -16
  411. package/dist/commands/lint/memory-linter.js +0 -61
  412. package/dist/commands/lint/registry.js +0 -41
  413. package/dist/commands/lint/skill-linter.js +0 -45
  414. package/dist/commands/lint/task-linter.js +0 -50
  415. package/dist/commands/lint/workflow-linter.js +0 -81
  416. package/dist/commands/proposal/legacy-import.js +0 -115
  417. package/dist/commands/wiki-cli.js +0 -291
  418. package/dist/core/asset/asset-registry.js +0 -76
  419. package/dist/core/asset/asset-spec.js +0 -316
  420. package/dist/core/eval/rank-metrics.js +0 -113
  421. package/dist/core/ripgrep/install.js +0 -163
  422. package/dist/core/ripgrep/resolve.js +0 -81
  423. package/dist/indexer/db/db.js +0 -1585
  424. package/dist/indexer/manifest.js +0 -170
  425. package/dist/indexer/passes/metadata-contributors.js +0 -31
  426. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  427. package/dist/output/text/wiki.js +0 -16
  428. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -18228
  429. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  430. package/dist/storage/repositories/consolidation-repository.js +0 -38
  431. package/dist/storage/repositories/recombine-repository.js +0 -213
  432. package/dist/wiki/wiki-templates.js +0 -15
  433. package/dist/wiki/wiki.js +0 -1013
  434. package/dist/workflows/db.js +0 -413
  435. package/docs/README.md +0 -103
  436. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  437. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  438. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -59,7 +59,23 @@
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; a
69
+ * legacy `type:name` falls back to the post-colon segment.
70
+ */
71
+ function refNameTail(inputRef) {
72
+ try {
73
+ return parseRefInput(inputRef).name.toLowerCase();
74
+ }
75
+ catch {
76
+ return (inputRef.split(":").pop() ?? "").toLowerCase();
77
+ }
78
+ }
63
79
  import { detectTruncatedDescription, TRUNCATION_TRAILING_WORDS } from "../../../core/text-truncation.js";
64
80
  // ── Description / when_to_use shape ─────────────────────────────────────────
65
81
  export const HEADING_FRAGMENT_PATTERNS = [
@@ -122,7 +138,7 @@ export function isValidDescription(value, inputRef, options = {}) {
122
138
  severity: "warn",
123
139
  };
124
140
  if (!options.skipRefTailCheck) {
125
- const refTail = inputRef.split(":").pop()?.toLowerCase() ?? "";
141
+ const refTail = refNameTail(inputRef);
126
142
  if (refTail.length >= 6 && v.toLowerCase().includes(refTail) && v.length < refTail.length + 40)
127
143
  return { ok: false, reason: "description appears to just name the input ref" };
128
144
  }
@@ -140,7 +156,7 @@ export function isValidWhenToUse(value, inputRef) {
140
156
  return { ok: false, reason: `when_to_use is too long (${v.length} chars; max ${WHEN_TO_USE_MAX_CHARS})` };
141
157
  if (/^when working with\b/i.test(v))
142
158
  return { ok: false, reason: "when_to_use is the circular 'When working with ...' fallback" };
143
- const refTail = inputRef.split(":").pop()?.toLowerCase() ?? "";
159
+ const refTail = refNameTail(inputRef);
144
160
  if (refTail.length >= 6 && v.toLowerCase().includes(refTail) && v.length < refTail.length + 25)
145
161
  return { ok: false, reason: "when_to_use appears to just name the input ref" };
146
162
  return { ok: true };
@@ -267,7 +283,7 @@ const descriptionQualityValidator = {
267
283
  return [];
268
284
  let fm;
269
285
  try {
270
- fm = parseFrontmatter(proposal.payload.content).data;
286
+ fm = parseFrontmatter(proposalContent(proposal)).data;
271
287
  }
272
288
  catch {
273
289
  return [];
@@ -293,7 +309,7 @@ const lessonContentQualityValidator = {
293
309
  return [];
294
310
  let fm;
295
311
  try {
296
- fm = parseFrontmatter(proposal.payload.content).data;
312
+ fm = parseFrontmatter(proposalContent(proposal)).data;
297
313
  }
298
314
  catch {
299
315
  return [];
@@ -322,7 +338,7 @@ const lessonContentQualityValidator = {
322
338
  message: `Lesson proposal ${proposal.id} (${proposal.ref}) has identical description and when_to_use.`,
323
339
  });
324
340
  }
325
- const dfm = detectDoubleFrontmatter(proposal.payload.content);
341
+ const dfm = detectDoubleFrontmatter(proposalContent(proposal));
326
342
  if (dfm)
327
343
  findings.push({ kind: dfm.kind, message: `Lesson proposal ${proposal.id} (${proposal.ref}): ${dfm.message}` });
328
344
  return findings;
@@ -356,7 +372,7 @@ const reflectSizeGuardValidator = {
356
372
  },
357
373
  validate(proposal, ctx) {
358
374
  const sourceBody = stripFrontmatterBody(ctx.source?.content ?? "");
359
- const proposedBody = typeof proposal.payload?.content === "string" ? stripFrontmatterBody(proposal.payload.content) : "";
375
+ const proposedBody = typeof proposal.payload?.content === "string" ? stripFrontmatterBody(proposalContent(proposal)) : "";
360
376
  const outcome = checkReflectSize(sourceBody, proposedBody);
361
377
  if (outcome.ok)
362
378
  return [];
@@ -1,8 +1,9 @@
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";
7
8
  import { defaultProposalQualityValidators } from "./proposal-quality-validators.js";
8
9
  const genericProposalValidator = {
@@ -14,7 +15,7 @@ const genericProposalValidator = {
14
15
  findings.push({ kind: "empty-content", message: `Proposal ${proposal.id} has empty content.` });
15
16
  }
16
17
  try {
17
- ctx.parsedRef = parseAssetRef(proposal.ref);
18
+ ctx.parsedRef = parseRefInput(proposal.ref);
18
19
  }
19
20
  catch (err) {
20
21
  findings.push({
@@ -24,9 +25,9 @@ const genericProposalValidator = {
24
25
  ctx.stop = true;
25
26
  return findings;
26
27
  }
27
- if (proposal.payload.content.startsWith("---")) {
28
+ if (proposalContent(proposal).startsWith("---")) {
28
29
  try {
29
- parseFrontmatter(proposal.payload.content);
30
+ parseFrontmatter(proposalContent(proposal));
30
31
  }
31
32
  catch (err) {
32
33
  findings.push({
@@ -44,7 +45,7 @@ const lessonProposalValidator = {
44
45
  return ctx.parsedRef?.type === "lesson";
45
46
  },
46
47
  validate(proposal) {
47
- return lintLessonContent(proposal.payload.content, `proposal:${proposal.id}`).findings.map((finding) => ({
48
+ return lintLessonContent(proposalContent(proposal), `proposal:${proposal.id}`).findings.map((finding) => ({
48
49
  kind: finding.kind,
49
50
  message: finding.message,
50
51
  }));
@@ -4,10 +4,11 @@
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); the legacy filesystem import now lives in the migrator
9
+ * (`../../../migrate/legacy/proposal-fs-import.ts`). This module keeps only the
10
+ * two proposal *validators* — {@link validateProposal} and
11
+ * {@link repairProposalContent}.
11
12
  */
12
13
  import { repairTruncatedDescription } from "../../../core/text-truncation.js";
13
14
  import { runProposalValidators } from "./proposal-validators.js";
@@ -14,17 +14,20 @@
14
14
  * `mergeCurateSearchResponses`) by importing them directly.
15
15
  */
16
16
  import fs from "node:fs";
17
- import { parseAssetRef, refToString } 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
27
  import { truncateDescription } from "../../output/shapes.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,27 +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
+ .map((item) => {
78
+ const entryId = findEntryIdByRef(db, item.ref);
79
+ const itemRef = entryId !== undefined ? getItemRefById(db, entryId) : null;
80
+ // Post-flip the resolved row carries `item_ref`; fall back to the
81
+ // item's own (new-grammar) ref for an unresolved straggler.
82
+ return { entryRef: itemRef ?? item.ref, entryId, item };
77
83
  });
78
- for (const item of result.items) {
79
- if (!("ref" in item) || typeof item.ref !== "string")
80
- continue;
81
- const parsed = parseAssetRef(item.ref);
82
- const itemOrigin = "origin" in item && typeof item.origin === "string" ? item.origin : undefined;
83
- insertUsageEvent(db, {
84
+ withStateDbTelemetry((stateDb) => {
85
+ insertUsageEvent(stateDb, {
84
86
  event_type: "curate",
85
87
  query,
86
- entry_ref: refToString({ ...parsed, ...(parsed.origin || !itemOrigin ? {} : { origin: itemOrigin }) }),
88
+ metadata: JSON.stringify({
89
+ itemCount: result.items.length,
90
+ itemRefs,
91
+ }),
87
92
  source: eventSource,
88
93
  });
89
- }
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);
90
105
  }, { busyTimeoutMs: TELEMETRY_BUSY_TIMEOUT_MS });
91
106
  }
92
107
  catch (err) {
@@ -107,11 +122,11 @@ export async function akmCurate(options) {
107
122
  limit: Math.max(limit * CURATE_SEARCH_LIMIT_MULTIPLIER, MIN_CURATE_SEARCH_LIMIT),
108
123
  source,
109
124
  }));
110
- const result = await curateSearchResults(options.query, searchResponse, limit, options.type);
111
- logCurateEvent(options.query, result, options.eventSource);
125
+ const result = await curateSearchResults(options.query, searchResponse, limit, options.type, options.eventSource);
126
+ logCurateEvent(options.query, result, options.eventSource, options.attributionProjection);
112
127
  return result;
113
128
  }
114
- export async function curateSearchResults(query, result, limit, selectedType) {
129
+ export async function curateSearchResults(query, result, limit, selectedType, eventSource) {
115
130
  const stashHits = result.hits.filter((hit) => hit.type !== "registry");
116
131
  const registryHits = result.registryHits ?? [];
117
132
  let selectedStashHits;
@@ -130,7 +145,7 @@ export async function curateSearchResults(query, result, limit, selectedType) {
130
145
  const items = [
131
146
  ...(await Promise.all(selectedStashHits
132
147
  .slice(0, limit)
133
- .map((hit) => enrichCuratedStashHit(query, hit, supportRefsByRef.get(hit.ref) ?? [], selectedRefs)))),
148
+ .map((hit) => enrichCuratedStashHit(query, hit, supportRefsByRef.get(hit.ref) ?? [], selectedRefs, eventSource)))),
134
149
  ...selectedRegistryHits.map((hit) => buildCuratedRegistryItem(query, hit)),
135
150
  ].slice(0, limit);
136
151
  return {
@@ -141,10 +156,10 @@ export async function curateSearchResults(query, result, limit, selectedType) {
141
156
  ...(result.tip ? { tip: result.tip } : {}),
142
157
  };
143
158
  }
144
- async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
159
+ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs, eventSource) {
145
160
  let shown;
146
161
  try {
147
- shown = await akmShowUnified({ ref: hit.ref });
162
+ shown = await akmShowUnified({ ref: hit.ref, eventSource, skipLogging: true });
148
163
  }
149
164
  catch {
150
165
  shown = undefined;
@@ -157,7 +172,7 @@ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
157
172
  const description = shown?.description ?? hit.description;
158
173
  const preview = buildCuratedPreview(shown, hit);
159
174
  const mergedSupportRefs = mergeCurateSupportRefs(supportRefs, shown?.related?.hits, selectedRefs, hit.ref);
160
- return {
175
+ const item = {
161
176
  source: "stash",
162
177
  type: shown?.type ?? hit.type,
163
178
  name: shown?.name ?? hit.name,
@@ -172,6 +187,8 @@ async function enrichCuratedStashHit(query, hit, supportRefs, selectedRefs) {
172
187
  reason: buildCuratedReason(query, shown?.type ?? hit.type),
173
188
  ...(hit.score !== undefined ? { score: hit.score } : {}),
174
189
  };
190
+ copySearchHitAttribution(hit, item, item.description);
191
+ return item;
175
192
  }
176
193
  /**
177
194
  * #624-P3 — enqueue an ungraphed asset for lazy graph extraction when the
@@ -256,7 +273,9 @@ function buildCurateSummary(query, items) {
256
273
  if (items.length === 0) {
257
274
  return `No curated assets were selected for "${query}".`;
258
275
  }
259
- const labels = items.map((item) => `${item.type}:${item.name}`);
276
+ // F4b: emit the flipped conceptId ref for stash items (registry items have no
277
+ // ref — keep their `registry:<name>` label).
278
+ const labels = items.map((item) => ("ref" in item ? item.ref : `${item.type}:${item.name}`));
260
279
  return `Selected ${items.length} curated result${items.length === 1 ? "" : "s"}: ${labels.join(", ")}.`;
261
280
  }
262
281
  export function deriveCurateFallbackQueries(query) {
@@ -425,7 +444,10 @@ function computeCurateTypeNudge(type, intent) {
425
444
  }
426
445
  function getCurateFamily(ref) {
427
446
  try {
428
- const parsed = parseAssetRef(ref);
447
+ // F4b: `ref` is a search-hit ref in the 0.9.0 conceptId grammar — parse via
448
+ // the new-grammar `parseRefInput` so skill/reference family grouping still
449
+ // recognizes it.
450
+ const parsed = parseRefInput(ref);
429
451
  if (parsed.type === "skill") {
430
452
  return { key: parsed.name, role: "root" };
431
453
  }
@@ -12,10 +12,10 @@ import fs from "node:fs";
12
12
  import path from "node:path";
13
13
  import { parse as yamlParse } from "yaml";
14
14
  import { assertFlatAssetName, combineCreatePath, normalizeCreateSubPath } from "../../core/asset/asset-create.js";
15
- import { makeAssetRef, parseAssetRef } from "../../core/asset/asset-ref.js";
15
+ import { assetPathForName, stashDirFor } from "../../core/asset/asset-placement.js";
16
16
  import { assembleAsset } from "../../core/asset/asset-serialize.js";
17
- import { resolveAssetPathFromName, TYPE_DIRS } from "../../core/asset/asset-spec.js";
18
17
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
18
+ import { conceptIdFromTypeName, parseRefInput } from "../../core/asset/resolve-ref.js";
19
19
  import { isHttpUrl, isWithin, resolveStashDir, tryReadStdinText } from "../../core/common.js";
20
20
  import { loadConfig } from "../../core/config/config.js";
21
21
  import { UsageError } from "../../core/errors.js";
@@ -24,7 +24,7 @@ import { warn } from "../../core/warn.js";
24
24
  import { commitWriteTargetBoundary, formatRefForMessage, recordWriteTargetPath, resolveWriteTarget, writeAssetToSource, } from "../../core/write-source.js";
25
25
  import { indexWrittenAssets } from "../../indexer/index-written-assets.js";
26
26
  import { resolveSourceEntries } from "../../indexer/search/search-source.js";
27
- import { fetchWebsiteMarkdownSnapshot, shouldAllowPrivateWebsiteUrlForTests } from "../../sources/website-ingest.js";
27
+ import { fetchWebsiteMarkdownSnapshot, shouldAllowPrivateWebsiteUrlForTests, } from "../../sources/snapshot-fetchers/website-ingest.js";
28
28
  import { writeSupersededEdge } from "../improve/memory/memory-belief.js";
29
29
  import { refToRelPath, resolveRefPathInStash } from "../lint/base-linter.js";
30
30
  const MAX_CAPTURED_ASSET_SLUG_LENGTH = 64;
@@ -121,9 +121,11 @@ export async function readKnowledgeInput(source, options) {
121
121
  return { content: snapshot.content, preferredName: snapshot.preferredName };
122
122
  }
123
123
  /**
124
- * Parse a `--xref` / `--supersedes` value through the canonical ref parser
125
- * (`parseAssetRef`) so malformed and origin-prefixed spellings get a
126
- * structured error instead of a misleading "did not resolve". A `local//`
124
+ * Parse a `--xref` / `--supersedes` value through the new-grammar input parser
125
+ * (`parseRefInput`, the 0.9.0 `[bundle//]conceptId` grammar) so malformed and
126
+ * origin-prefixed spellings get a structured error instead of a misleading "did
127
+ * not resolve". Chunk-8 WI-8.5c: the legacy `[origin//]type:name` content-surface
128
+ * arm is retired — `--xref`/`--supersedes` take the conceptId form. A `local//`
127
129
  * origin is accepted (it names the same local resolution this validator
128
130
  * performs, mirroring lint's `local//` strip); any other origin is rejected —
129
131
  * write-time validation only resolves local stash roots.
@@ -131,18 +133,21 @@ export async function readKnowledgeInput(source, options) {
131
133
  function parseWriteRef(raw, flag) {
132
134
  let parsed;
133
135
  try {
134
- parsed = parseAssetRef(raw);
136
+ parsed = parseRefInput(raw);
135
137
  }
136
138
  catch (error) {
137
139
  const message = error instanceof Error ? error.message : String(error);
138
- throw new UsageError(`${flag} "${raw}" is not a valid asset ref: ${message}`, "INVALID_FLAG_VALUE", `Refs use the form type:name, e.g. ${flag} knowledge:auth-flow.`);
140
+ throw new UsageError(`${flag} "${raw}" is not a valid asset ref: ${message}`, "INVALID_FLAG_VALUE", `Refs use the conceptId form, e.g. ${flag} knowledge/auth-flow.`);
139
141
  }
140
142
  if (parsed.origin && parsed.origin !== "local") {
141
- throw new UsageError(`${flag} "${raw}" carries the origin prefix "${parsed.origin}//" — ${flag} only resolves refs in the write target, the working stash, and configured sources.`, "INVALID_FLAG_VALUE", `Pass the plain type:name form, e.g. ${flag} ${parsed.type}:${parsed.name}.`);
143
+ throw new UsageError(`${flag} "${raw}" carries the origin prefix "${parsed.origin}//" — ${flag} only resolves refs in the write target, the working stash, and configured sources.`, "INVALID_FLAG_VALUE", `Pass the plain conceptId form, e.g. ${flag} ${conceptIdFromTypeName(parsed.type, parsed.name)}.`);
142
144
  }
143
- // Canonical bare form: type alias resolved, name normalized, `local//`
144
- // dropped (it names the same local resolution this validator performs).
145
- return { ref: makeAssetRef(parsed.type, parsed.name), type: parsed.type, name: parsed.name };
145
+ // Canonical bare conceptId: type alias resolved, name normalized, `local//`
146
+ // dropped (it names the same local resolution this validator performs). The
147
+ // bare `<stash-subdir>/<name>` short ref (WI-8.5a) is what lands in the
148
+ // containing bundle's frontmatter (§11.1 short-ref rule); the name is already
149
+ // normalized by the parser.
150
+ return { ref: conceptIdFromTypeName(parsed.type, parsed.name), type: parsed.type, name: parsed.name };
146
151
  }
147
152
  /**
148
153
  * Trim, parse, and dedupe `--xref` / `--supersedes` flag values, in argv
@@ -213,8 +218,8 @@ function isFailOpenRefType(type, name) {
213
218
  */
214
219
  function locateWriteRefInRoot(type, name, root) {
215
220
  if (type === "workflow") {
216
- const typeRoot = path.join(root, TYPE_DIRS.workflow ?? "workflows");
217
- const candidate = resolveAssetPathFromName("workflow", typeRoot, name);
221
+ const typeRoot = path.join(root, stashDirFor("workflow") ?? "workflows");
222
+ const candidate = assetPathForName("workflow", typeRoot, name);
218
223
  if (fs.existsSync(candidate))
219
224
  return candidate;
220
225
  }
@@ -226,7 +231,7 @@ function locateWriteRefInRoot(type, name, root) {
226
231
  /** Build the shared exit-2 error for refs that resolved in no root. */
227
232
  function unresolvedRefsError(flag, unresolved) {
228
233
  const first = unresolved[0];
229
- return new UsageError(`${flag} ref${unresolved.length > 1 ? "s" : ""} did not resolve in the write target or any configured source: ${unresolved.map((u) => u.ref).join(", ")}`, "INVALID_FLAG_VALUE", `Find the intended asset with \`akm search "${first.name}" --type ${first.type}\`. Refs use the form type:name.`);
234
+ return new UsageError(`${flag} ref${unresolved.length > 1 ? "s" : ""} did not resolve in the write target or any configured source: ${unresolved.map((u) => u.ref).join(", ")}`, "INVALID_FLAG_VALUE", `Find the intended asset with \`akm search "${first.name}" --type ${first.type}\`. Refs use the form [bundle//]conceptId (e.g. knowledge/guide.md).`);
230
235
  }
231
236
  // ── Cross-references (--xref) ────────────────────────────────────────────────
232
237
  /**
@@ -466,7 +471,7 @@ export async function writeMarkdownAsset(options) {
466
471
  // Pre-flight: existence + force semantics. The helper itself overwrites
467
472
  // unconditionally; the CLI surfaces a friendlier UsageError before any
468
473
  // disk activity when --force is absent.
469
- const assetPath = resolveAssetPathFromName(options.type, typeRoot, normalizedName);
474
+ const assetPath = assetPathForName(options.type, typeRoot, normalizedName);
470
475
  if (!isWithin(assetPath, typeRoot)) {
471
476
  throw new UsageError(`Resolved ${options.type} path escapes the stash: "${normalizedName}"`);
472
477
  }
@@ -527,6 +532,10 @@ export async function writeMarkdownAsset(options) {
527
532
  // on a git target, uncommitted (and a re-run hits RESOURCE_ALREADY_EXISTS).
528
533
  // Degrade to the same applied:false report the non-writable path uses.
529
534
  try {
535
+ // supersededBy points at the correction's canonical write ref (F4b-flipped
536
+ // display spelling), keeping it in lockstep with the reported `result.ref`.
537
+ // The --xref/--supersedes input path (resolveXrefsForWrite/parseWriteRef)
538
+ // is now the new-grammar conceptId surface too (WI-8.5c).
530
539
  writeSupersededEdge(item.filePath, result.ref);
531
540
  if (path.resolve(item.stashRoot) === path.resolve(source.path)) {
532
541
  recordWriteTargetPath(source, item.filePath);
@@ -5,6 +5,7 @@ import { getStringArg } from "../../cli/parse-args.js";
5
5
  import { defineJsonCommand, output, parseAllFlagValues } from "../../cli/shared.js";
6
6
  import { UsageError } from "../../core/errors.js";
7
7
  import { appendEvent } from "../../core/events.js";
8
+ import { resolveUsageEventSource } from "../../indexer/usage/usage-events.js";
8
9
  import { buildMemoryFrontmatter, parseDuration, readMemoryContent, resolveRememberContentArg, runAutoHeuristics, runLlmEnrich, } from "../remember.js";
9
10
  import { assertFlatAssetName, inferAssetName, resolveSupersedesForWrite, resolveXrefsForWrite, writeMarkdownAsset, } from "./knowledge.js";
10
11
  import { akmSearch } from "./search.js";
@@ -13,9 +14,15 @@ import { akmSearch } from "./search.js";
13
14
  * Best-effort top-3 similar memory search for `--show-similar`.
14
15
  * Scoped to memory: type; excludes the just-written ref.
15
16
  */
16
- async function fetchSimilarMemories(query, excludeRef) {
17
+ async function fetchSimilarMemories(query, excludeRef, eventSource) {
17
18
  try {
18
- const result = await akmSearch({ query, type: "memory", limit: 4 });
19
+ const result = await akmSearch({
20
+ query,
21
+ type: "memory",
22
+ limit: 4,
23
+ eventSource,
24
+ attributionProjection: "brief",
25
+ });
19
26
  return (result.hits ?? [])
20
27
  .filter((h) => "ref" in h && h.ref !== excludeRef)
21
28
  .slice(0, 3)
@@ -111,6 +118,7 @@ export const rememberCommand = defineJsonCommand({
111
118
  },
112
119
  async run({ args }) {
113
120
  const body = readMemoryContent(resolveRememberContentArg(args.content));
121
+ const eventSource = resolveUsageEventSource();
114
122
  // `--name` is a flat name; subdirectory placement is `--path`'s job.
115
123
  assertFlatAssetName(args.name);
116
124
  // Determine if the user has requested any structured metadata mode.
@@ -178,7 +186,7 @@ export const rememberCommand = defineJsonCommand({
178
186
  metadata: { path: result.path, force: args.force === true },
179
187
  });
180
188
  if (args.showSimilar) {
181
- const similar = await fetchSimilarMemories(body.slice(0, 500), result.ref);
189
+ const similar = await fetchSimilarMemories(body.slice(0, 500), result.ref, eventSource);
182
190
  output("remember", { ok: true, ...result, similar });
183
191
  }
184
192
  else {
@@ -287,7 +295,7 @@ export const rememberCommand = defineJsonCommand({
287
295
  },
288
296
  });
289
297
  if (args.showSimilar) {
290
- const similar = await fetchSimilarMemories((body ?? args.content ?? "").slice(0, 500), result.ref);
298
+ const similar = await fetchSimilarMemories((body ?? args.content ?? "").slice(0, 500), result.ref, eventSource);
291
299
  output("remember", { ok: true, ...result, similar });
292
300
  }
293
301
  else {
@@ -6,34 +6,23 @@
6
6
  * from src/cli.ts (WS6) so the God Module shrinks; the `main.subCommands.search`,
7
7
  * `.curate`, and `.show` keys and every command's args/output shape are
8
8
  * byte-identical. The three commands form a clean cluster: they share the
9
- * private `resolveEventSource()` helper and the `parseScopeFilterFlags`
9
+ * usage-event provenance and the `parseScopeFilterFlags`
10
10
  * search-source parsers. Handlers whose body is a plain
11
11
  * `runWithJsonErrors(async () => { … })` are migrated to `defineJsonCommand`,
12
12
  * which emits the same JSON envelope (stdout/stderr/exit-code) as the inline
13
13
  * form.
14
14
  */
15
+ import { getParsedInvocation } from "../../cli/invocation.js";
15
16
  import { parsePositiveIntFlag } from "../../cli/parse-args.js";
16
17
  import { defineJsonCommand, output, parseAllFlagValues } from "../../cli/shared.js";
17
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
18
+ import { parseRefInput } from "../../core/asset/resolve-ref.js";
18
19
  import { parseMetaRef } from "../../core/asset/stash-meta.js";
19
20
  import { UsageError } from "../../core/errors.js";
20
- import { getHyphenatedBoolean, getOutputMode, parseFlagValue } from "../../output/context.js";
21
+ import { resolveUsageEventSource } from "../../indexer/usage/usage-events.js";
22
+ import { getHyphenatedBoolean, getOutputMode } from "../../output/context.js";
21
23
  import { akmCurate } from "./curate.js";
22
24
  import { akmSearch, parseBeliefFilterMode, parseScopeFilterFlags, parseSearchSource } from "./search.js";
23
25
  import { akmShowUnified } from "./show.js";
24
- // AKM_EVENT_SOURCE attributes a query to a `user` invocation, the internal
25
- // `improve` loop, or the `task` runner so the event log can distinguish
26
- // genuine demand from machine traffic; any other value is treated as unset.
27
- function resolveEventSource() {
28
- const raw = process.env.AKM_EVENT_SOURCE;
29
- if (raw === "improve")
30
- return "improve";
31
- if (raw === "task")
32
- return "task";
33
- if (raw === "user")
34
- return "user";
35
- return undefined;
36
- }
37
26
  export const searchCommand = defineJsonCommand({
38
27
  meta: { name: "search", description: "Search the stash" },
39
28
  args: {
@@ -45,7 +34,7 @@ export const searchCommand = defineJsonCommand({
45
34
  },
46
35
  type: {
47
36
  type: "string",
48
- description: "Asset type filter (skill, command, agent, knowledge, workflow, script, memory, env, secret, wiki, lesson, or any). Use workflow to find step-by-step task assets.",
37
+ description: "Asset type filter (skill, command, agent, knowledge, workflow, script, memory, env, secret, lesson, or any). Use workflow to find step-by-step task assets.",
49
38
  },
50
39
  limit: { type: "string", description: "Maximum number of results" },
51
40
  source: { type: "string", description: "Search source (stash|registry|both)", default: "stash" },
@@ -92,6 +81,7 @@ export const searchCommand = defineJsonCommand({
92
81
  const belief = parseBeliefFilterMode(typeof args.belief === "string" ? args.belief : undefined);
93
82
  const noProjectContext = getHyphenatedBoolean(args, "no-project-context");
94
83
  const includeSessions = args["include-sessions"];
84
+ const outputMode = getOutputMode();
95
85
  const result = await akmSearch({
96
86
  query,
97
87
  type,
@@ -103,7 +93,8 @@ export const searchCommand = defineJsonCommand({
103
93
  includeSessions,
104
94
  disableProjectContext: noProjectContext,
105
95
  disableScopedUtility: noProjectContext,
106
- eventSource: resolveEventSource(),
96
+ eventSource: resolveUsageEventSource(),
97
+ attributionProjection: outputMode.shape === "agent" ? "agent" : outputMode.detail,
107
98
  });
108
99
  output("search", result);
109
100
  },
@@ -117,7 +108,7 @@ export const curateCommand = defineJsonCommand({
117
108
  query: { type: "positional", description: "Task or prompt to curate assets for", required: false },
118
109
  type: {
119
110
  type: "string",
120
- description: "Asset type filter (skill, command, agent, knowledge, workflow, script, memory, env, secret, wiki, lesson, or any). Use workflow to curate step-by-step task assets.",
111
+ description: "Asset type filter (skill, command, agent, knowledge, workflow, script, memory, env, secret, lesson, or any). Use workflow to curate step-by-step task assets.",
121
112
  },
122
113
  limit: { type: "string", description: "Maximum number of curated results", default: "4" },
123
114
  source: { type: "string", description: "Search source (stash|registry|both)", default: "stash" },
@@ -136,19 +127,27 @@ export const curateCommand = defineJsonCommand({
136
127
  const limitParsed = parsePositiveIntFlag(args.limit ?? undefined);
137
128
  const limit = limitParsed && limitParsed > 0 ? limitParsed : 4;
138
129
  const source = parseSearchSource(args.source ?? "stash");
139
- const curated = await akmCurate({ query: args.query, type, limit, source, eventSource: resolveEventSource() });
130
+ const outputMode = getOutputMode();
131
+ const curated = await akmCurate({
132
+ query: args.query,
133
+ type,
134
+ limit,
135
+ source,
136
+ eventSource: resolveUsageEventSource(),
137
+ attributionProjection: outputMode.shape === "agent" ? "agent" : outputMode.detail,
138
+ });
140
139
  output("curate", curated);
141
140
  },
142
141
  });
143
142
  export const showCommand = defineJsonCommand({
144
143
  meta: {
145
144
  name: "show",
146
- description: "Show a stash asset by ref (e.g. akm show knowledge:guide.md toc, akm show knowledge:guide.md section 'Auth')",
145
+ description: "Show a stash asset by ref (e.g. akm show knowledge/guide.md toc, akm show knowledge/guide.md section 'Auth')",
147
146
  },
148
147
  args: {
149
148
  ref: {
150
149
  type: "positional",
151
- description: 'Asset ref ([origin//]type:name) optionally followed by a view mode. View modes: `toc` (table of contents), `section "Heading"` (extract one section), `lines <start> <end>` (line range), `frontmatter` (YAML metadata only), `full` (raw file). Example: `akm show knowledge:guide.md section "Auth"`.',
150
+ description: 'Asset ref ([bundle//]conceptId) optionally followed by a view mode. View modes: `toc` (table of contents), `section "Heading"` (extract one section), `lines <start> <end>` (line range), `frontmatter` (YAML metadata only), `full` (raw file). Example: `akm show knowledge/guide.md section "Auth"`.',
152
151
  required: true,
153
152
  },
154
153
  format: { type: "string", description: "Output format (json|jsonl|text|yaml)" },
@@ -162,18 +161,19 @@ export const showCommand = defineJsonCommand({
162
161
  async run({ args }) {
163
162
  // `[origin//]meta[:name]` targets the stash `.meta/` convention, which is
164
163
  // not a typed asset ref — skip ref validation and let akmShowUnified
165
- // direct-read it. (`parseAssetRef` would reject the non-type `meta`.)
164
+ // direct-read it. (the ref parser would reject the non-type `meta`.)
166
165
  if (!parseMetaRef(args.ref))
167
- parseAssetRef(args.ref);
168
- // The knowledge-view positional syntax (`akm show knowledge:foo section "Auth"`)
166
+ parseRefInput(args.ref);
167
+ // The knowledge-view positional syntax (`akm show knowledge/foo section "Auth"`)
169
168
  // is rewritten to `--akmView` / `--akmHeading` / `--akmStart` / `--akmEnd`
170
169
  // by `normalizeShowArgv` before citty parses argv. We read those values
171
- // directly via `parseFlagValue` so the flags don't surface as user-facing
172
- // options in `akm show --help`.
173
- const akmView = parseFlagValue(process.argv, "--akmView");
174
- const akmHeading = parseFlagValue(process.argv, "--akmHeading");
175
- const akmStart = parseFlagValue(process.argv, "--akmStart");
176
- const akmEnd = parseFlagValue(process.argv, "--akmEnd");
170
+ // directly via `getParsedInvocation()` so the flags don't surface as
171
+ // user-facing options in `akm show --help`.
172
+ const invocation = getParsedInvocation();
173
+ const akmView = invocation.getFlagValue("--akmView");
174
+ const akmHeading = invocation.getFlagValue("--akmHeading");
175
+ const akmStart = invocation.getFlagValue("--akmStart");
176
+ const akmEnd = invocation.getFlagValue("--akmEnd");
177
177
  let view;
178
178
  if (akmView) {
179
179
  switch (akmView) {
@@ -197,7 +197,7 @@ export const showCommand = defineJsonCommand({
197
197
  }
198
198
  }
199
199
  const cliShape = getOutputMode().shape;
200
- const explicitDetail = parseFlagValue(process.argv, "--detail");
200
+ const explicitDetail = invocation.getFlagValue("--detail");
201
201
  // `--shape summary` selects the compact metadata projection for show
202
202
  // (the legacy `--detail summary` spelling still maps here via the
203
203
  // back-compat path in resolveOutputMode). `--detail brief` forces the
@@ -212,7 +212,7 @@ export const showCommand = defineJsonCommand({
212
212
  view,
213
213
  detail: showDetail,
214
214
  scope,
215
- eventSource: resolveEventSource(),
215
+ eventSource: resolveUsageEventSource(),
216
216
  });
217
217
  output("show", result);
218
218
  },