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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (598) hide show
  1. package/CHANGELOG.md +1283 -22
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
  26. package/dist/assets/stash-skeleton/README.md +38 -10
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  38. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  39. package/dist/assets/tasks/core/extract.yml +3 -2
  40. package/dist/assets/tasks/core/improve.yml +2 -1
  41. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  42. package/dist/assets/tasks/core/sync.yml +1 -0
  43. package/dist/assets/tasks/core/version-check.yml +2 -1
  44. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  45. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  46. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  48. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  49. package/dist/assets/templates/html/health.html +5 -4
  50. package/dist/assets/workflows/workflow-template.md +31 -15
  51. package/dist/cli/invocation.js +279 -0
  52. package/dist/cli/parse-args.js +5 -90
  53. package/dist/cli/retired-commands.js +78 -0
  54. package/dist/cli/shared.js +158 -48
  55. package/dist/cli-node.mjs +2 -1
  56. package/dist/cli.js +747 -293
  57. package/dist/commands/agent/agent-dispatch.js +19 -18
  58. package/dist/commands/agent/agent-support.js +0 -24
  59. package/dist/commands/agent/contribute-cli.js +43 -97
  60. package/dist/commands/completions.js +80 -23
  61. package/dist/commands/config-cli.js +44 -281
  62. package/dist/commands/env/env-binding.js +99 -0
  63. package/dist/commands/env/env-cli.js +84 -224
  64. package/dist/commands/env/env.js +12 -163
  65. package/dist/commands/env/marker-path.js +6 -0
  66. package/dist/commands/env/secret-cli.js +45 -61
  67. package/dist/commands/env/secret.js +32 -62
  68. package/dist/commands/feedback-cli.js +179 -85
  69. package/dist/commands/health/accept-rate.js +58 -0
  70. package/dist/commands/health/advisories.js +7 -8
  71. package/dist/commands/health/checks.js +279 -94
  72. package/dist/commands/health/html-report.js +197 -578
  73. package/dist/commands/health/improve-metrics.js +277 -246
  74. package/dist/commands/health/llm-usage.js +19 -19
  75. package/dist/commands/health/md-report.js +16 -7
  76. package/dist/commands/health/metrics.js +67 -32
  77. package/dist/commands/health/renderers.js +47 -0
  78. package/dist/commands/health/report-view-model.js +508 -0
  79. package/dist/commands/health/stash-exposure.js +1 -1
  80. package/dist/commands/health/surfaces.js +16 -56
  81. package/dist/commands/health/task-runs.js +3 -67
  82. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  83. package/dist/commands/health/types-improve.js +29 -0
  84. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  85. package/dist/commands/health/types-result.js +7 -0
  86. package/dist/commands/health/types-runs.js +4 -0
  87. package/dist/commands/health/types-session-log.js +4 -0
  88. package/dist/commands/health/types-windows.js +4 -0
  89. package/dist/commands/health/types.js +26 -21
  90. package/dist/commands/health/windows.js +2 -3
  91. package/dist/commands/health.js +296 -167
  92. package/dist/commands/improve/anti-collapse.js +5 -5
  93. package/dist/commands/improve/autonomy-gate.js +68 -0
  94. package/dist/commands/improve/collapse-detector.js +65 -52
  95. package/dist/commands/improve/consolidate/chunking.js +9 -7
  96. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  97. package/dist/commands/improve/consolidate/merge.js +4 -0
  98. package/dist/commands/improve/consolidate.js +454 -1354
  99. package/dist/commands/improve/content-hash.js +39 -0
  100. package/dist/commands/improve/distill/content-repair.js +4 -10
  101. package/dist/commands/improve/distill/promote-memory.js +89 -64
  102. package/dist/commands/improve/distill/quality-gate.js +118 -42
  103. package/dist/commands/improve/distill-guards.js +1 -1
  104. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  105. package/dist/commands/improve/distill.js +607 -363
  106. package/dist/commands/improve/eligibility.js +165 -79
  107. package/dist/commands/improve/extract-cli.js +35 -126
  108. package/dist/commands/improve/extract-prompt.js +6 -35
  109. package/dist/commands/improve/extract.js +640 -391
  110. package/dist/commands/improve/feedback-valence.js +2 -12
  111. package/dist/commands/improve/improve-cli.js +134 -135
  112. package/dist/commands/improve/improve-result-file.js +30 -50
  113. package/dist/commands/improve/improve-run-types.js +4 -0
  114. package/dist/commands/improve/improve-strategies.js +135 -0
  115. package/dist/commands/improve/improve.js +904 -701
  116. package/dist/commands/improve/locks.js +64 -111
  117. package/dist/commands/improve/loop-stages.js +1110 -923
  118. package/dist/commands/improve/memory/derived-ref.js +124 -0
  119. package/dist/commands/improve/memory/memory-belief.js +79 -7
  120. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  121. package/dist/commands/improve/memory/memory-improve.js +25 -37
  122. package/dist/commands/improve/outcome-loop.js +25 -88
  123. package/dist/commands/improve/preparation.js +1034 -813
  124. package/dist/commands/improve/proactive-maintenance.js +34 -9
  125. package/dist/commands/improve/proposal-envelope.js +31 -0
  126. package/dist/commands/improve/reflect.js +983 -794
  127. package/dist/commands/improve/run-context.js +119 -0
  128. package/dist/commands/improve/salience.js +24 -127
  129. package/dist/commands/improve/session-asset.js +7 -3
  130. package/dist/commands/improve/shared.js +14 -34
  131. package/dist/commands/improve/source-identity.js +28 -0
  132. package/dist/commands/improve/triage.js +20 -17
  133. package/dist/commands/lint/base-linter.js +340 -313
  134. package/dist/commands/lint/env-key-rules.js +31 -47
  135. package/dist/commands/lint/index.js +185 -30
  136. package/dist/commands/{events.js → log.js} +28 -38
  137. package/dist/commands/migrate-cli.js +54 -0
  138. package/dist/commands/migration-tool.js +55 -0
  139. package/dist/commands/observability-cli.js +70 -208
  140. package/dist/commands/proposal/diff-format.js +50 -0
  141. package/dist/commands/proposal/drain-policies.js +0 -6
  142. package/dist/commands/proposal/drain.js +91 -40
  143. package/dist/commands/proposal/proposal-cli.js +134 -132
  144. package/dist/commands/proposal/proposal-types.js +56 -0
  145. package/dist/commands/proposal/proposal.js +83 -65
  146. package/dist/commands/proposal/propose-cli.js +88 -0
  147. package/dist/commands/proposal/propose.js +105 -88
  148. package/dist/commands/proposal/repository.js +1303 -278
  149. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  150. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  151. package/dist/commands/proposal/validators/proposals.js +6 -8
  152. package/dist/commands/read/curate.js +78 -73
  153. package/dist/commands/read/knowledge.js +510 -13
  154. package/dist/commands/read/registry-search.js +2 -2
  155. package/dist/commands/read/remember-cli.js +84 -15
  156. package/dist/commands/read/search-cli.js +203 -96
  157. package/dist/commands/read/search.js +126 -94
  158. package/dist/commands/read/show.js +226 -250
  159. package/dist/commands/registry-cli.js +34 -60
  160. package/dist/commands/remember.js +18 -57
  161. package/dist/commands/sources/add-cli.js +104 -49
  162. package/dist/commands/sources/bundle-cli.js +166 -0
  163. package/dist/commands/sources/bundle-config-ops.js +63 -0
  164. package/dist/commands/sources/info.js +27 -15
  165. package/dist/commands/sources/init.js +30 -40
  166. package/dist/commands/sources/installed-stashes.js +469 -172
  167. package/dist/commands/sources/migration-help.js +7 -4
  168. package/dist/commands/sources/schema-repair.js +10 -9
  169. package/dist/commands/sources/self-update.js +182 -121
  170. package/dist/commands/sources/source-add.js +169 -178
  171. package/dist/commands/sources/source-clone.js +144 -41
  172. package/dist/commands/sources/source-manage.js +94 -59
  173. package/dist/commands/sources/sources-cli.js +64 -205
  174. package/dist/commands/sources/stash-cli.js +91 -54
  175. package/dist/commands/sources/stash-skeleton.js +1 -1
  176. package/dist/commands/tasks/tasks-cli.js +106 -104
  177. package/dist/commands/tasks/tasks.js +445 -262
  178. package/dist/commands/workflow-cli.js +232 -121
  179. package/dist/core/action-contributors.js +1 -1
  180. package/dist/core/activation-policy.js +49 -0
  181. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  182. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  183. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  184. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  185. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  186. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  187. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  188. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  189. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  190. package/dist/core/adapter/adapters/index.js +80 -0
  191. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  192. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  193. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  194. package/dist/core/adapter/adapters/shared.js +286 -0
  195. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  196. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  197. package/dist/core/adapter/bundle-adapter.js +4 -0
  198. package/dist/core/adapter/detect-adapter.js +17 -0
  199. package/dist/core/adapter/recognize-match.js +44 -0
  200. package/dist/core/adapter/registry.js +56 -0
  201. package/dist/core/adapter/types.js +4 -0
  202. package/dist/core/asset/akm-markdown.js +30 -0
  203. package/dist/core/asset/asset-placement.js +243 -0
  204. package/dist/core/asset/asset-ref.js +110 -79
  205. package/dist/core/asset/asset-serialize.js +20 -0
  206. package/dist/core/asset/frontmatter.js +28 -12
  207. package/dist/core/asset/markdown.js +40 -51
  208. package/dist/core/asset/resolve-ref.js +274 -0
  209. package/dist/core/asset/stash-meta.js +2 -2
  210. package/dist/core/bundle-id.js +51 -0
  211. package/dist/core/common.js +281 -86
  212. package/dist/core/config/config-io.js +42 -128
  213. package/dist/core/config/config-schema.js +233 -834
  214. package/dist/core/config/config-sources.js +162 -39
  215. package/dist/core/config/config-types.js +16 -11
  216. package/dist/core/config/config-version.js +29 -0
  217. package/dist/core/config/config-walker.js +126 -37
  218. package/dist/core/config/config.js +154 -331
  219. package/dist/core/config/deep-merge.js +41 -0
  220. package/dist/core/config/engine-semantics.js +28 -0
  221. package/dist/core/config/experimental.js +21 -0
  222. package/dist/core/config/schema/embedding.js +38 -0
  223. package/dist/core/config/schema/engines.js +116 -0
  224. package/dist/core/config/schema/experimental.js +47 -0
  225. package/dist/core/config/schema/feedback.js +31 -0
  226. package/dist/core/config/schema/improve-processes.js +389 -0
  227. package/dist/core/config/schema/improve.js +94 -0
  228. package/dist/core/config/schema/index-config.js +176 -0
  229. package/dist/core/config/schema/output.js +18 -0
  230. package/dist/core/config/schema/primitives.js +94 -0
  231. package/dist/core/config/schema/search.js +30 -0
  232. package/dist/core/config/schema/setup.js +18 -0
  233. package/dist/core/config/schema/sources-bundles.js +169 -0
  234. package/dist/core/config/schema/workflow.js +29 -0
  235. package/dist/core/env-secret-ref.js +155 -20
  236. package/dist/core/errors.js +17 -15
  237. package/dist/core/events-types.js +4 -0
  238. package/dist/core/events.js +46 -128
  239. package/dist/core/extra-params.js +62 -0
  240. package/dist/core/file-change.js +17 -0
  241. package/dist/core/file-lock.js +202 -57
  242. package/dist/core/fs-txn.js +392 -0
  243. package/dist/core/git-message.js +59 -0
  244. package/dist/core/improve-result.js +167 -0
  245. package/dist/core/json-schema.js +142 -0
  246. package/dist/core/lesson-lint.js +1 -17
  247. package/dist/core/logs-db.js +1 -1
  248. package/dist/core/maintenance-barrier.js +135 -0
  249. package/dist/core/migration-operation.js +44 -0
  250. package/dist/core/mutation-target.js +78 -0
  251. package/dist/core/paths.js +22 -25
  252. package/dist/core/platform.js +10 -0
  253. package/dist/core/recognition-util.js +128 -0
  254. package/dist/core/redaction.js +392 -0
  255. package/dist/core/standards/resolve-standards-context.js +36 -65
  256. package/dist/core/standards/resolve-stash-standards.js +2 -2
  257. package/dist/core/standards/resolve-type-conventions.js +5 -5
  258. package/dist/core/state/migrations.js +242 -11
  259. package/dist/core/state-db.js +98 -10
  260. package/dist/core/structured.js +1 -1
  261. package/dist/core/subprocess.js +303 -0
  262. package/dist/core/text-truncation.js +9 -5
  263. package/dist/core/time.js +20 -0
  264. package/dist/core/type-presentation.js +130 -0
  265. package/dist/core/warn.js +0 -3
  266. package/dist/core/write-source.js +834 -118
  267. package/dist/indexer/bundle-identity-guard.js +92 -0
  268. package/dist/indexer/db/graph-db.js +1 -25
  269. package/dist/indexer/db/llm-cache.js +1 -1
  270. package/dist/indexer/ensure-index.js +30 -9
  271. package/dist/indexer/graph/graph-boost.js +9 -30
  272. package/dist/indexer/graph/graph-extraction.js +41 -27
  273. package/dist/indexer/graph/graph-types.js +4 -0
  274. package/dist/indexer/index-writer-lock.js +93 -49
  275. package/dist/indexer/index-written-assets.js +100 -53
  276. package/dist/indexer/indexer.js +746 -329
  277. package/dist/indexer/init.js +18 -25
  278. package/dist/indexer/installations.js +142 -0
  279. package/dist/indexer/passes/dir-staleness.js +18 -10
  280. package/dist/indexer/passes/memory-inference.js +25 -15
  281. package/dist/indexer/passes/metadata.js +412 -243
  282. package/dist/indexer/scan/doc-to-entry.js +160 -0
  283. package/dist/indexer/scan/drain-dir.js +134 -0
  284. package/dist/indexer/search/db-search.js +292 -108
  285. package/dist/indexer/search/fts-query.js +64 -0
  286. package/dist/indexer/search/ranking-contributors.js +145 -25
  287. package/dist/indexer/search/ranking-types.js +4 -0
  288. package/dist/indexer/search/ranking.js +28 -71
  289. package/dist/indexer/search/search-attribution.js +67 -0
  290. package/dist/indexer/search/search-fields.js +18 -3
  291. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  292. package/dist/indexer/search/search-source.js +157 -111
  293. package/dist/indexer/search/semantic-status.js +4 -1
  294. package/dist/indexer/usage/usage-events.js +10 -30
  295. package/dist/indexer/walk/file-context.js +3 -45
  296. package/dist/indexer/walk/matchers.js +42 -34
  297. package/dist/indexer/walk/path-resolver.js +11 -5
  298. package/dist/indexer/walk/walker.js +42 -14
  299. package/dist/integrations/agent/builder-shared.js +7 -0
  300. package/dist/integrations/agent/builders.js +5 -56
  301. package/dist/integrations/agent/config.js +3 -143
  302. package/dist/integrations/agent/detect.js +17 -2
  303. package/dist/integrations/agent/engine-resolution.js +231 -0
  304. package/dist/integrations/agent/index.js +1 -2
  305. package/dist/integrations/agent/model-aliases.js +16 -2
  306. package/dist/integrations/agent/profiles.js +36 -62
  307. package/dist/integrations/agent/prompts.js +46 -18
  308. package/dist/integrations/agent/runner-dispatch.js +93 -4
  309. package/dist/integrations/agent/runner.js +76 -208
  310. package/dist/integrations/agent/spawn.js +88 -196
  311. package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
  312. package/dist/integrations/harnesses/aider/index.js +48 -0
  313. package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
  314. package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
  315. package/dist/integrations/harnesses/amazonq/index.js +45 -0
  316. package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
  317. package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
  318. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  319. package/dist/integrations/harnesses/claude/index.js +24 -35
  320. package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
  321. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  322. package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
  323. package/dist/integrations/harnesses/codex/index.js +52 -0
  324. package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
  325. package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
  326. package/dist/integrations/harnesses/copilot/index.js +48 -0
  327. package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
  328. package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
  329. package/dist/integrations/harnesses/gemini/index.js +48 -0
  330. package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
  331. package/dist/integrations/harnesses/ids.js +24 -0
  332. package/dist/integrations/harnesses/index.js +54 -34
  333. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  334. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  335. package/dist/integrations/harnesses/opencode/index.js +14 -32
  336. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  337. package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
  338. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
  339. package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
  340. package/dist/integrations/harnesses/openhands/index.js +48 -0
  341. package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
  342. package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
  343. package/dist/integrations/harnesses/pi/index.js +45 -0
  344. package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
  345. package/dist/integrations/harnesses/shared.js +17 -0
  346. package/dist/integrations/harnesses/types.js +43 -32
  347. package/dist/integrations/lockfile.js +211 -24
  348. package/dist/integrations/session-logs/index.js +36 -39
  349. package/dist/integrations/session-logs/provider-base.js +113 -0
  350. package/dist/llm/client.js +182 -110
  351. package/dist/llm/embedders/deterministic.js +2 -2
  352. package/dist/llm/embedders/remote.js +21 -9
  353. package/dist/llm/feature-gate.js +17 -57
  354. package/dist/llm/graph-extract.js +12 -13
  355. package/dist/llm/index-passes.js +8 -42
  356. package/dist/llm/memory-infer.js +144 -1
  357. package/dist/llm/metadata-enhance.js +45 -30
  358. package/dist/llm/structured-call.js +16 -8
  359. package/dist/llm/usage-persist.js +30 -5
  360. package/dist/llm/usage-telemetry.js +59 -6
  361. package/dist/output/cli-hints.js +1 -2
  362. package/dist/output/command-registry.js +27 -0
  363. package/dist/output/context.js +22 -7
  364. package/dist/output/format-exempt.js +80 -0
  365. package/dist/output/generic-render.js +251 -0
  366. package/dist/output/html-render.js +11 -16
  367. package/dist/output/render-registry.js +57 -0
  368. package/dist/output/renderers.js +14 -279
  369. package/dist/output/shapes/curate.js +10 -1
  370. package/dist/output/shapes/events.js +12 -7
  371. package/dist/output/shapes/helpers.js +58 -84
  372. package/dist/output/shapes/passthrough.js +11 -39
  373. package/dist/output/shapes/proposal/producer.js +15 -7
  374. package/dist/output/shapes/registry.js +12 -6
  375. package/dist/output/shapes.js +0 -9
  376. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  377. package/dist/output/text/bundle-show.js +7 -0
  378. package/dist/output/text/command-format.js +562 -0
  379. package/dist/output/text/env.js +1 -3
  380. package/dist/output/text/events.js +8 -7
  381. package/dist/output/text/helpers.js +15 -1164
  382. package/dist/output/text/proposal/producer.js +4 -2
  383. package/dist/output/text/proposal-format.js +202 -0
  384. package/dist/output/text/registry-commands.js +1 -2
  385. package/dist/output/text/registry.js +12 -6
  386. package/dist/output/text/show-directives.js +117 -0
  387. package/dist/output/text/show-format.js +103 -0
  388. package/dist/output/text/sync.js +5 -0
  389. package/dist/output/text/workflow-format.js +332 -0
  390. package/dist/output/text/workflow.js +3 -2
  391. package/dist/output/text.js +10 -19
  392. package/dist/registry/factory.js +4 -6
  393. package/dist/registry/origin-resolve.js +16 -27
  394. package/dist/registry/providers/skills-sh.js +3 -3
  395. package/dist/registry/providers/static-index.js +15 -25
  396. package/dist/registry/resolve.js +43 -94
  397. package/dist/registry/semver.js +43 -0
  398. package/dist/runtime.js +81 -12
  399. package/dist/scripts/akm-migrate.js +35529 -0
  400. package/dist/setup/detect.js +5 -7
  401. package/dist/setup/detected-engines.js +136 -0
  402. package/dist/setup/engine-config.js +100 -0
  403. package/dist/setup/registry-stash-loader.js +3 -3
  404. package/dist/setup/semantic-assets.js +12 -9
  405. package/dist/setup/setup.js +444 -208
  406. package/dist/setup/steps/connection-shared.js +120 -0
  407. package/dist/setup/steps/connection.js +108 -305
  408. package/dist/setup/steps/platforms.js +13 -12
  409. package/dist/setup/steps/semantic.js +15 -3
  410. package/dist/setup/steps/sources.js +21 -15
  411. package/dist/setup/steps/stashdir.js +6 -4
  412. package/dist/setup/steps/tasks.js +236 -119
  413. package/dist/setup/steps.js +3 -2
  414. package/dist/sources/freshness.js +39 -0
  415. package/dist/sources/provider-factory.js +11 -17
  416. package/dist/sources/providers/filesystem.js +2 -3
  417. package/dist/sources/providers/git-install.js +278 -34
  418. package/dist/sources/providers/git-provider.js +54 -56
  419. package/dist/sources/providers/git-stash.js +420 -91
  420. package/dist/sources/providers/git.js +2 -2
  421. package/dist/sources/providers/npm.js +16 -19
  422. package/dist/sources/providers/provider-utils.js +47 -22
  423. package/dist/sources/providers/sync-from-ref.js +3 -9
  424. package/dist/sources/providers/website.js +2 -2
  425. package/dist/sources/resolve.js +11 -10
  426. package/dist/sources/snapshot-fetchers/types.js +4 -0
  427. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  428. package/dist/storage/database.js +60 -4
  429. package/dist/storage/engines/sqlite-migrations.js +156 -5
  430. package/dist/storage/locations.js +1 -2
  431. package/dist/storage/repositories/canaries-repository.js +1 -1
  432. package/dist/storage/repositories/events-repository.js +51 -11
  433. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  434. package/dist/storage/repositories/index-connection.js +79 -0
  435. package/dist/storage/repositories/index-db.js +4 -3
  436. package/dist/storage/repositories/index-entries-repository.js +863 -0
  437. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  438. package/dist/storage/repositories/index-entry-types.js +4 -0
  439. package/dist/storage/repositories/index-fts-repository.js +167 -0
  440. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  441. package/dist/storage/repositories/index-meta-repository.js +49 -0
  442. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  443. package/dist/storage/repositories/index-sql.js +12 -0
  444. package/dist/storage/repositories/index-utility-repository.js +356 -0
  445. package/dist/storage/repositories/index-vec-repository.js +250 -0
  446. package/dist/storage/repositories/outcome-repository.js +119 -0
  447. package/dist/storage/repositories/proposals-repository.js +317 -75
  448. package/dist/storage/repositories/registry-cache.js +1 -1
  449. package/dist/storage/repositories/salience-repository.js +172 -0
  450. package/dist/storage/repositories/task-history-repository.js +110 -3
  451. package/dist/storage/repositories/workflow-runs-repository.js +240 -19
  452. package/dist/tasks/backends/cron.js +169 -46
  453. package/dist/tasks/backends/exec-utils.js +76 -3
  454. package/dist/tasks/backends/index.js +6 -9
  455. package/dist/tasks/backends/launchd.js +292 -55
  456. package/dist/tasks/backends/schtasks.js +557 -70
  457. package/dist/tasks/backends/types.js +4 -0
  458. package/dist/tasks/command-executable.js +93 -0
  459. package/dist/tasks/embedded.js +56 -38
  460. package/dist/tasks/parser.js +156 -64
  461. package/dist/tasks/resolve-akm-bin.js +144 -51
  462. package/dist/tasks/runner.js +377 -209
  463. package/dist/tasks/schedule.js +108 -19
  464. package/dist/tasks/scheduler-invocation.js +296 -0
  465. package/dist/tasks/schema.js +1 -1
  466. package/dist/tasks/task-id.js +35 -0
  467. package/dist/tasks/validator.js +30 -16
  468. package/dist/text-import-hook.mjs +1 -1
  469. package/dist/workflows/authoring/authoring.js +104 -43
  470. package/dist/workflows/authoring/scope-key.js +1 -1
  471. package/dist/workflows/cli.js +0 -16
  472. package/dist/workflows/concurrency-policy.js +15 -0
  473. package/dist/workflows/exec/brief.js +450 -0
  474. package/dist/workflows/exec/frozen-judge.js +47 -0
  475. package/dist/workflows/exec/native-executor.js +1038 -0
  476. package/dist/workflows/exec/param-secrets.js +115 -0
  477. package/dist/workflows/exec/report.js +1460 -0
  478. package/dist/workflows/exec/run-workflow.js +602 -0
  479. package/dist/workflows/exec/scheduler.js +71 -0
  480. package/dist/workflows/exec/step-work.js +1190 -0
  481. package/dist/workflows/exec/unit-writer.js +23 -0
  482. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  483. package/dist/workflows/exec/worktree.js +171 -0
  484. package/dist/workflows/ir/compile.js +246 -0
  485. package/dist/workflows/ir/freeze.js +233 -0
  486. package/dist/workflows/ir/params.js +54 -0
  487. package/dist/workflows/ir/plan-hash.js +68 -0
  488. package/dist/workflows/ir/schema.js +540 -0
  489. package/dist/workflows/parser.js +878 -304
  490. package/dist/workflows/program/expressions.js +181 -0
  491. package/dist/workflows/program/schema.js +51 -0
  492. package/dist/workflows/renderer.js +100 -45
  493. package/dist/workflows/resource-limits.js +22 -0
  494. package/dist/workflows/runtime/agent-identity.js +59 -14
  495. package/dist/workflows/runtime/checkin.js +1 -1
  496. package/dist/workflows/runtime/plan-classifier.js +131 -0
  497. package/dist/workflows/runtime/runs.js +376 -119
  498. package/dist/workflows/runtime/unit-checkin.js +45 -0
  499. package/dist/workflows/runtime/unit-phases.js +20 -0
  500. package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
  501. package/dist/workflows/schema.js +1 -11
  502. package/dist/workflows/validate-summary.js +2 -3
  503. package/dist/workflows/validator.js +52 -30
  504. package/docs/README.md +42 -78
  505. package/docs/migration/README.md +8 -0
  506. package/docs/migration/release-notes/0.6.0.md +1 -1
  507. package/docs/migration/release-notes/0.7.0.md +9 -8
  508. package/docs/migration/release-notes/0.9.0.md +158 -14
  509. package/docs/migration/v0.7-to-v0.8.md +46 -47
  510. package/docs/migration/v0.8-to-v0.9.md +844 -0
  511. package/docs/reference/README.md +12 -0
  512. package/docs/reference/data-and-telemetry.md +333 -0
  513. package/package.json +21 -17
  514. package/schemas/akm-asset-envelope.json +93 -0
  515. package/schemas/akm-config.json +4636 -0
  516. package/schemas/akm-task.json +87 -0
  517. package/schemas/akm-workflow.json +373 -0
  518. package/dist/akm-migrate-storage +0 -38
  519. package/dist/assets/help/help-accept.md +0 -12
  520. package/dist/assets/help/help-improve.md +0 -84
  521. package/dist/assets/help/help-proposals.md +0 -17
  522. package/dist/assets/help/help-propose.md +0 -17
  523. package/dist/assets/help/help-reject.md +0 -11
  524. package/dist/assets/profiles/frequent.json +0 -13
  525. package/dist/assets/profiles/recombine-only.json +0 -21
  526. package/dist/assets/profiles/reflect-distill.json +0 -30
  527. package/dist/assets/profiles/synthesize.json +0 -15
  528. package/dist/assets/prompts/procedural-system.md +0 -44
  529. package/dist/assets/prompts/recombine-system.md +0 -40
  530. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  531. package/dist/assets/tasks/core/backup.yml +0 -4
  532. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  533. package/dist/assets/templates/html/default.html +0 -78
  534. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  535. package/dist/assets/wiki/index-template.md +0 -12
  536. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  537. package/dist/assets/wiki/log-template.md +0 -8
  538. package/dist/assets/wiki/schema-template.md +0 -61
  539. package/dist/cli/config-migrate.js +0 -150
  540. package/dist/cli/config-validate.js +0 -39
  541. package/dist/commands/graph/graph-cli.js +0 -124
  542. package/dist/commands/graph/graph.js +0 -487
  543. package/dist/commands/improve/calibration.js +0 -161
  544. package/dist/commands/improve/dedup.js +0 -482
  545. package/dist/commands/improve/extract-watch.js +0 -140
  546. package/dist/commands/improve/hot-probation.js +0 -45
  547. package/dist/commands/improve/improve-auto-accept.js +0 -276
  548. package/dist/commands/improve/improve-profiles.js +0 -168
  549. package/dist/commands/improve/procedural.js +0 -398
  550. package/dist/commands/improve/recombine.js +0 -818
  551. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  552. package/dist/commands/lint/agent-linter.js +0 -44
  553. package/dist/commands/lint/command-linter.js +0 -44
  554. package/dist/commands/lint/default-linter.js +0 -16
  555. package/dist/commands/lint/fact-linter.js +0 -39
  556. package/dist/commands/lint/knowledge-linter.js +0 -16
  557. package/dist/commands/lint/memory-linter.js +0 -61
  558. package/dist/commands/lint/registry.js +0 -41
  559. package/dist/commands/lint/skill-linter.js +0 -45
  560. package/dist/commands/lint/task-linter.js +0 -50
  561. package/dist/commands/lint/workflow-linter.js +0 -81
  562. package/dist/commands/proposal/legacy-import.js +0 -115
  563. package/dist/commands/sources/history.js +0 -196
  564. package/dist/commands/tasks/default-tasks.js +0 -186
  565. package/dist/commands/wiki-cli.js +0 -292
  566. package/dist/core/asset/asset-registry.js +0 -76
  567. package/dist/core/asset/asset-spec.js +0 -259
  568. package/dist/core/config/config-migration.js +0 -602
  569. package/dist/core/deep-merge.js +0 -38
  570. package/dist/core/eval/rank-metrics.js +0 -113
  571. package/dist/core/ripgrep/install.js +0 -163
  572. package/dist/core/ripgrep/resolve.js +0 -81
  573. package/dist/indexer/db/db.js +0 -1413
  574. package/dist/indexer/manifest.js +0 -170
  575. package/dist/indexer/passes/metadata-contributors.js +0 -31
  576. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  577. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
  578. package/dist/llm/call-ai.js +0 -62
  579. package/dist/llm/memory-infer-impl.js +0 -138
  580. package/dist/output/shapes/distill.js +0 -14
  581. package/dist/output/shapes/history.js +0 -11
  582. package/dist/output/text/distill.js +0 -6
  583. package/dist/output/text/enable-disable.js +0 -8
  584. package/dist/output/text/history.js +0 -6
  585. package/dist/output/text/wiki.js +0 -16
  586. package/dist/registry/build-index.js +0 -386
  587. package/dist/scripts/migrate-storage.js +0 -19108
  588. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
  589. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  590. package/dist/setup/legacy-config.js +0 -106
  591. package/dist/storage/repositories/consolidation-repository.js +0 -38
  592. package/dist/storage/repositories/recombine-repository.js +0 -213
  593. package/dist/wiki/wiki-templates.js +0 -15
  594. package/dist/wiki/wiki.js +0 -1012
  595. package/dist/workflows/db.js +0 -215
  596. package/docs/data-and-telemetry.md +0 -226
  597. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  598. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -8,100 +8,49 @@
8
8
  *
9
9
  * show(ref) → indexer.lookup(ref) → readFile(entry.filePath)
10
10
  *
11
- * The richer presentation logic (matchers, renderers, wiki-root handling,
12
- * edit-hints, summary-detail truncation) lives below in this file. The flow:
11
+ * The richer presentation logic (matchers, renderers, edit-hints,
12
+ * summary-detail truncation) lives below in this file. The flow:
13
13
  *
14
- * 1. Special-case wiki-root refs (`wiki:<name>` with no page path).
15
- * 2. Auto-index when stale so the index is current.
16
- * 3. Ask `indexer.lookup(ref)` for the row in the FTS index.
17
- * 4. Render the file via the matcher/renderer pipeline.
14
+ * 1. Auto-index when stale so the index is current.
15
+ * 2. Ask `indexer.lookup(ref)` for the row in the FTS index.
16
+ * 3. Render the file via the matcher/renderer pipeline.
18
17
  */
19
18
  import fs from "node:fs";
20
19
  import path from "node:path";
21
- import { findCittyTopLevelCommandIndex } from "../../cli/parse-args.js";
22
- import { parseAssetRef } from "../../core/asset/asset-ref.js";
20
+ import { recognizeMatch } from "../../core/adapter/recognize-match.js";
21
+ import { makeBundleRef, parseBundleRef } from "../../core/asset/asset-ref.js";
23
22
  import { parseFrontmatter } from "../../core/asset/frontmatter.js";
23
+ import { extractSection, markdownFragmentSlugs } from "../../core/asset/markdown.js";
24
+ import { displayRef, typeNameFromConceptId } from "../../core/asset/resolve-ref.js";
24
25
  import { META_DIR, parseMetaRef, resolveMetaFilePath } from "../../core/asset/stash-meta.js";
25
26
  import { asNonEmptyString } from "../../core/common.js";
26
27
  import { getIndexPassConfig, loadConfig } from "../../core/config/config.js";
27
28
  import { NotFoundError, rethrowIfTestIsolationError, UsageError } from "../../core/errors.js";
28
29
  import { appendEvent, readEvents } from "../../core/events.js";
29
- import { closeDatabase, computeBodyHash, findEntryIdByRef, openExistingDatabase } from "../../indexer/db/db.js";
30
+ import { withStateDbTelemetry } from "../../core/state-db.js";
31
+ import { presentationFor } from "../../core/type-presentation.js";
30
32
  import { hasGraphData } from "../../indexer/db/graph-db.js";
31
33
  import { listRelatedPathsForFile } from "../../indexer/graph/graph-boost.js";
32
34
  import { extractGraphForSingleFile } from "../../indexer/graph/graph-extraction.js";
33
- import { lookup } from "../../indexer/indexer.js";
35
+ import { lookupBundleRef } from "../../indexer/indexer.js";
34
36
  import { ensurePrimaryIndexForRead, resolveReadSources } from "../../indexer/read-preflight.js";
37
+ import { usageEventAttributionMetadata } from "../../indexer/search/search-attribution.js";
35
38
  import { buildEditHint, findSourceForPath, isEditable, resolveSourceEntries } from "../../indexer/search/search-source.js";
36
39
  import { insertUsageEvent } from "../../indexer/usage/usage-events.js";
37
- import { buildFileContext, buildRenderContext, getRenderer, runMatchers } from "../../indexer/walk/file-context.js";
40
+ import { buildFileContext, buildRenderContext, getRenderer, } from "../../indexer/walk/file-context.js";
38
41
  import { resolveAssetPath } from "../../indexer/walk/path-resolver.js";
39
42
  import { resolveIndexPassLLM } from "../../llm/index-passes.js";
40
43
  import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
41
44
  import { resolveStorageLocations } from "../../storage/locations.js";
45
+ import { closeDatabase, openExistingDatabase } from "../../storage/repositories/index-connection.js";
42
46
  import { TELEMETRY_BUSY_TIMEOUT_MS, withIndexDb } from "../../storage/repositories/index-db.js";
47
+ import { findEntryIdByRef, getEntryById, getEntryIdByFilePath, getItemRefById, } from "../../storage/repositories/index-entries-repository.js";
48
+ import { computeBodyHash } from "../../storage/repositories/index-llm-cache-repository.js";
43
49
  // Eagerly import source providers to trigger self-registration.
44
50
  import "../../sources/providers/index.js";
45
51
  import { getCurrentWorkflowScopeKey } from "../../workflows/authoring/scope-key.js";
52
+ import { buildWorkflowAction } from "../../workflows/renderer.js";
46
53
  import { getActiveWorkflowRun } from "../../workflows/runtime/runs.js";
47
- /**
48
- * Show a wiki root (no page path) — returns the same payload as
49
- * `akm wiki show <name>`.
50
- */
51
- async function showWikiRoot(stashDir, wikiName) {
52
- const { showWiki } = await import("../../wiki/wiki.js");
53
- const result = showWiki(stashDir, wikiName);
54
- return {
55
- type: "wiki",
56
- name: result.ref,
57
- path: result.path,
58
- ...(result.description ? { description: result.description } : {}),
59
- origin: null,
60
- editable: false,
61
- pages: result.pages,
62
- raws: result.raws,
63
- ...(result.lastModified ? { lastModified: result.lastModified } : {}),
64
- recentLog: result.recentLog,
65
- };
66
- }
67
- async function showWikiRootForSource(stashDir, source, wikiName) {
68
- const { showWikiAtPath } = await import("../../wiki/wiki.js");
69
- if (source.wikiName === wikiName) {
70
- const result = showWikiAtPath(wikiName, source.path);
71
- return {
72
- type: "wiki",
73
- name: result.ref,
74
- path: result.path,
75
- ...(result.description ? { description: result.description } : {}),
76
- origin: null,
77
- editable: false,
78
- pages: result.pages,
79
- raws: result.raws,
80
- ...(result.lastModified ? { lastModified: result.lastModified } : {}),
81
- recentLog: result.recentLog,
82
- };
83
- }
84
- return showWikiRoot(stashDir, wikiName);
85
- }
86
- function resolveRegisteredWikiAssetPath(wikiRoot, wikiName, assetName) {
87
- const pageName = assetName === wikiName ? "" : assetName.slice(wikiName.length + 1);
88
- if (!pageName) {
89
- throw new NotFoundError(`Wiki page not found: wiki:${assetName}`);
90
- }
91
- const candidate = path.resolve(wikiRoot, `${pageName}.md`);
92
- const resolvedRoot = fs.realpathSync(wikiRoot);
93
- if (!candidate.startsWith(resolvedRoot + path.sep)) {
94
- throw new UsageError("Ref resolves outside the stash root.", "PATH_ESCAPE_VIOLATION");
95
- }
96
- if (!fs.existsSync(candidate) || !fs.statSync(candidate).isFile()) {
97
- throw new NotFoundError(`Stash asset not found for ref: wiki:${assetName}`);
98
- }
99
- const realTarget = fs.realpathSync(candidate);
100
- if (!realTarget.startsWith(resolvedRoot + path.sep)) {
101
- throw new UsageError("Ref resolves outside the stash root.", "PATH_ESCAPE_VIOLATION");
102
- }
103
- return realTarget;
104
- }
105
54
  /**
106
55
  * Unified show: queries the local FTS5 index, then falls back to on-disk
107
56
  * type-dir resolution if the index has no row. Spec §6.2; no remote provider
@@ -115,55 +64,33 @@ export async function akmShowUnified(input) {
115
64
  // 0a. Stash `.meta/` convention: `[origin//]meta[:name]` direct-reads a
116
65
  // human-authored orientation doc from the stash's `.meta/` directory.
117
66
  // These files are not indexed (the walker skips dot-dirs), so they are
118
- // resolved here before the index lookup and the `type:name` parser,
119
- // which would otherwise reject the non-asset-type `meta`.
67
+ // resolved here before the index lookup; meta docs are not asset refs.
120
68
  {
121
69
  const metaRef = parseMetaRef(ref);
122
70
  if (metaRef)
123
71
  return showStashMeta(metaRef);
124
72
  }
125
- // 0. Wiki-root shortcut: `wiki:<name>` with no page path routes to the
126
- // wiki summary (same payload as `akm wiki show <name>`). Honour
127
- // `parsed.origin` by resolving against the matching stash source(s),
128
- // falling back to the primary stash when no origin is given.
129
- {
130
- const parsed = parseAssetRef(ref);
131
- if (parsed.type === "wiki" && !parsed.name.includes("/")) {
132
- const allSources = resolveSourceEntries();
133
- const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
134
- let lastError;
135
- for (const source of searchSources) {
136
- try {
137
- return await showWikiRootForSource(allSources[0]?.path ?? source.path, source, parsed.name);
138
- }
139
- catch (err) {
140
- if (!(err instanceof NotFoundError))
141
- throw err;
142
- lastError = err;
143
- }
144
- }
145
- throw (lastError ??
146
- new NotFoundError(`Wiki not found: ${parsed.name}. Run \`akm wiki create ${parsed.name}\` to create it.`));
147
- }
148
- }
149
73
  // Auto-index when stale so the index is current before lookup.
150
74
  const { primarySource } = resolveReadSources();
151
75
  await ensurePrimaryIndexForRead(primarySource);
152
76
  // Try local filesystem (FTS5 index lookup)
153
77
  const result = await showLocal(input);
154
- // Scope filter narrows resolution: if --scope was supplied, the asset's
155
- // frontmatter scope must satisfy every supplied key. We re-read the file
156
- // (cheap — already on the show hot path) so we don't have to thread scope
157
- // through the renderer chain just for one verification step.
78
+ // Scope filter narrows resolution: if a scope filter was supplied, the
79
+ // asset's frontmatter scope must satisfy every supplied key. We re-read the
80
+ // file (cheap — already on the show hot path) so we don't have to thread
81
+ // scope through the renderer chain just for one verification step.
158
82
  if (input.scope && hasAnyScopeKey(input.scope) && result.path) {
159
83
  enforceScopeOrThrow(result.path, ref, input.scope);
160
84
  }
161
85
  // Count prior shows of this ref before logging the current one.
162
- const priorShowCount = recentShowCount(ref);
163
- logShowEvent(ref, input.eventSource);
164
- if (priorShowCount >= 2) {
165
- // Agent has shown this same asset 3+ times — inject a loop-break hint.
166
- result.showLoopWarning = priorShowCount + 1;
86
+ if (!input.skipLogging) {
87
+ const consumedRef = result.ref ?? makeBundleRef(undefined, parseBundleRef(ref).conceptId);
88
+ const priorShowCount = recentShowCount(consumedRef);
89
+ logShowEvent(consumedRef, result.type, result.name, input.eventSource, result.path);
90
+ if (priorShowCount >= 2) {
91
+ // Agent has shown this same asset 3+ times — inject a loop-break hint.
92
+ result.showLoopWarning = priorShowCount + 1;
93
+ }
167
94
  }
168
95
  return result;
169
96
  }
@@ -180,7 +107,7 @@ async function showStashMeta(metaRef) {
180
107
  const sources = resolveSourcesForOrigin(metaRef.origin, allSources);
181
108
  if (metaRef.origin && sources.length === 0) {
182
109
  throw new NotFoundError(`Stash "${metaRef.origin}" is not installed, so its ${META_DIR}/ docs are unavailable. ` +
183
- `Run: akm add ${metaRef.origin}`);
110
+ `Run: akm bundle add ${metaRef.origin}`);
184
111
  }
185
112
  const config = loadConfig();
186
113
  for (const source of sources) {
@@ -188,12 +115,13 @@ async function showStashMeta(metaRef) {
188
115
  if (!filePath)
189
116
  continue;
190
117
  const content = fs.readFileSync(filePath, "utf8");
191
- const editable = isEditable(filePath, config);
118
+ const editable = isEditable(filePath, config, allSources);
192
119
  appendEvent({ eventType: "show", ref: `meta:${metaRef.name}`, metadata: { type: "meta", name: metaRef.name } });
193
120
  return {
194
121
  type: "meta",
195
122
  name: metaRef.name,
196
123
  path: filePath,
124
+ ref: `meta:${metaRef.name}`,
197
125
  content,
198
126
  origin: source.registryId ?? null,
199
127
  editable,
@@ -257,11 +185,11 @@ function recentShowCount(ref) {
257
185
  return 0;
258
186
  }
259
187
  }
260
- function logShowEvent(ref, eventSource = "user") {
188
+ function logShowEvent(ref, type, name, eventSource = "user", filePath) {
261
189
  // Emit a structured event to events.jsonl so workflow-trace consumers
262
190
  // detect akm show invocations without relying on stdout scraping.
263
- const parsed = parseAssetRef(ref);
264
- appendEvent({ eventType: "show", ref, metadata: { type: parsed.type, name: parsed.name } });
191
+ const eventRef = makeBundleRef(parseBundleRef(ref).bundle, parseBundleRef(ref).conceptId);
192
+ appendEvent({ eventType: "show", ref: eventRef, metadata: { type, name } });
265
193
  // Detect if this show is a selection from a recent search result.
266
194
  try {
267
195
  // D7: bound the query to the last 60 s so we never scan unbounded history
@@ -293,12 +221,25 @@ function logShowEvent(ref, eventSource = "user") {
293
221
  }
294
222
  try {
295
223
  withIndexDb((db) => {
296
- insertUsageEvent(db, {
297
- event_type: "show",
298
- entry_ref: ref,
299
- entry_id: findEntryIdByRef(db, ref),
300
- source: eventSource,
301
- });
224
+ const entryId = filePath ? getEntryIdByFilePath(db, filePath) : findEntryIdByRef(db, eventRef);
225
+ if (entryId === undefined)
226
+ return;
227
+ // Usage events carry only the resolved row's fully-qualified item_ref.
228
+ // A disk-only show has no durable indexed identity yet, so it does not
229
+ // create a per-entry usage row.
230
+ const entryRef = getItemRefById(db, entryId);
231
+ if (!entryRef)
232
+ return;
233
+ const entry = getEntryById(db, entryId);
234
+ withStateDbTelemetry((stateDb) => {
235
+ insertUsageEvent(stateDb, {
236
+ event_type: "show",
237
+ entry_ref: entryRef,
238
+ entry_id: entryId,
239
+ metadata: usageEventAttributionMetadata(entry?.entry.derivedFrom ? { memoryInference: { exposure: "direct" } } : undefined, entryRef),
240
+ source: eventSource,
241
+ });
242
+ }, TELEMETRY_BUSY_TIMEOUT_MS);
302
243
  }, { busyTimeoutMs: TELEMETRY_BUSY_TIMEOUT_MS });
303
244
  }
304
245
  catch (err) {
@@ -308,61 +249,102 @@ function logShowEvent(ref, eventSource = "user") {
308
249
  }
309
250
  /** @internal Use akmShowUnified() for all external callers. */
310
251
  export async function showLocal(input) {
311
- const parsed = parseAssetRef(input.ref);
312
- const displayType = parsed.type;
252
+ const parsed = parseBundleRef(input.ref);
253
+ const assetParts = typeNameFromConceptId(parsed.conceptId);
313
254
  const config = loadConfig();
314
255
  const allSources = resolveSourceEntries(input.stashDir);
315
- const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
256
+ const searchSources = resolveSourcesForOrigin(parsed.bundle, allSources);
316
257
  const allSourceDirs = searchSources.map((s) => s.path);
317
- let assetPath;
318
- const matchedSource = parsed.type === "wiki" ? searchSources.find((source) => parsed.name.startsWith(`${source.wikiName}/`)) : undefined;
319
- let lastError;
320
- if (parsed.type === "wiki" && matchedSource?.wikiName) {
321
- try {
322
- assetPath = resolveRegisteredWikiAssetPath(matchedSource.path, matchedSource.wikiName, parsed.name);
323
- }
324
- catch (err) {
325
- lastError = err instanceof Error ? err : new Error(String(err));
326
- }
327
- }
328
- if (!assetPath) {
329
- const resolvedAssetPath = await resolveAssetPath(parsed, {
330
- stashDir: input.stashDir,
331
- mode: "index-first",
332
- });
333
- assetPath = resolvedAssetPath ?? undefined;
258
+ let indexedEntry = null;
259
+ try {
260
+ indexedEntry = await lookupBundleRef(parsed);
334
261
  }
335
- if (!assetPath && parsed.origin && searchSources.length === 0) {
336
- const installCmd = `akm add ${parsed.origin}`;
337
- throw new NotFoundError(`Stash asset not found for ref: ${displayType}:${parsed.name}. ` +
338
- `Stash "${parsed.origin}" is not installed. Run: ${installCmd}`);
262
+ catch (err) {
263
+ rethrowIfTestIsolationError(err);
264
+ indexedEntry = null;
265
+ }
266
+ const resolvedAssetPath = indexedEntry?.filePath ??
267
+ (assetParts
268
+ ? await resolveAssetPath({ type: assetParts.type, name: assetParts.name, origin: parsed.bundle }, {
269
+ stashDir: input.stashDir,
270
+ mode: "disk-only",
271
+ })
272
+ : null);
273
+ const assetPath = resolvedAssetPath ?? undefined;
274
+ const displayType = indexedEntry?.type ?? assetParts?.type ?? "asset";
275
+ const displayName = indexedEntry?.name ?? assetParts?.name ?? parsed.conceptId;
276
+ if (!assetPath && parsed.bundle && searchSources.length === 0) {
277
+ const installCmd = `akm bundle add ${parsed.bundle}`;
278
+ throw new NotFoundError(`Stash asset not found for ref: ${makeBundleRef(parsed.bundle, parsed.conceptId)}. ` +
279
+ `Stash "${parsed.bundle}" is not installed. Run: ${installCmd}`);
339
280
  }
340
281
  if (!assetPath) {
341
- throw (lastError ??
342
- new NotFoundError(`Stash asset not found for ref: ${displayType}:${parsed.name}. ` +
343
- "Check the name with `akm search` or verify the asset exists in your stash."));
282
+ throw new NotFoundError(`Stash asset not found for ref: ${makeBundleRef(parsed.bundle, parsed.conceptId)}. ` +
283
+ "Check the name with `akm search` or verify the asset exists in your stash.");
344
284
  }
345
- const source = matchedSource ?? findSourceForPath(assetPath, allSources);
285
+ if (indexedEntry) {
286
+ try {
287
+ fs.accessSync(assetPath, fs.constants.R_OK);
288
+ }
289
+ catch (error) {
290
+ throwIndexedPathNotFound(error, input.ref);
291
+ }
292
+ }
293
+ const source = findSourceForPath(assetPath, allSources);
346
294
  const sourceStashDir = source?.path ?? allSourceDirs[0];
347
295
  if (!sourceStashDir) {
348
- throw new UsageError(`Could not determine stash root for asset: ${displayType}:${parsed.name}. ` +
349
- "Run `akm init` to create the stash directory, or check `akm stash list` for configured paths.");
296
+ throw new UsageError(`Could not determine stash root for asset: ${makeBundleRef(parsed.bundle, parsed.conceptId)}. ` +
297
+ "Run `akm bundle create` to create the stash directory, or check `akm bundle list` for configured paths.");
350
298
  }
351
299
  const fileCtx = buildFileContext(sourceStashDir, assetPath);
352
- const forcedWikiMatch = parsed.type === "wiki" && source?.wikiName && parsed.name.startsWith(`${source.wikiName}/`)
353
- ? { type: "wiki", specificity: 20, renderer: "wiki-md", meta: {} }
354
- : undefined;
355
- const match = forcedWikiMatch ?? (await runMatchers(fileCtx));
356
- if (!match) {
357
- throw new UsageError(`Could not display asset "${displayType}:${parsed.name}" — unsupported file type or unrecognized layout`);
358
- }
359
- match.meta = { ...match.meta, name: parsed.name, view: input.view };
360
- const renderer = await getRenderer(match.renderer);
361
- if (!renderer) {
362
- throw new UsageError(`Renderer "${match.renderer}" not found for asset: ${displayType}:${parsed.name}`);
363
- }
364
- const renderCtx = buildRenderContext(fileCtx, match, allSourceDirs, source?.registryId);
365
- const response = renderer.buildShowResponse(renderCtx);
300
+ const indexedRenderer = indexedEntry ? rendererForIndexedEntry(indexedEntry, fileCtx) : undefined;
301
+ let response;
302
+ try {
303
+ if (indexedEntry && indexedRenderer === null) {
304
+ response = buildIndexedProjectionResponse(indexedEntry, assetPath, parsed.fragment);
305
+ }
306
+ else {
307
+ const match = indexedEntry && typeof indexedRenderer === "string"
308
+ ? indexedMatch(indexedEntry, indexedRenderer)
309
+ : recognizeMatch(fileCtx);
310
+ if (!match) {
311
+ throw new UsageError(`Could not display asset "${makeBundleRef(parsed.bundle, parsed.conceptId)}" — unsupported file type or unrecognized layout`);
312
+ }
313
+ match.meta = { ...match.meta, name: displayName };
314
+ const renderer = await getRenderer(match.renderer);
315
+ if (!renderer) {
316
+ throw new UsageError(`Renderer "${match.renderer}" not found for asset: ${makeBundleRef(parsed.bundle, parsed.conceptId)}`);
317
+ }
318
+ const renderBundle = indexedEntry ? indexedEntry.bundleId : source?.registryId;
319
+ const renderDefaultBundle = config.defaultBundle ?? (source?.path === allSources[0]?.path ? renderBundle : undefined);
320
+ const renderCtx = buildRenderContext(fileCtx, match, allSourceDirs, renderBundle, renderDefaultBundle);
321
+ response = renderer.buildShowResponse(renderCtx);
322
+ if (parsed.fragment !== undefined) {
323
+ if (!match.renderer.endsWith("-md")) {
324
+ throw new UsageError(`Fragments are not supported for ${makeBundleRef(parsed.bundle, parsed.conceptId)}. Only Markdown documents support heading fragments.`, "INVALID_FLAG_VALUE");
325
+ }
326
+ applyMarkdownFragment(response, fileCtx.content(), parsed.fragment, displayName);
327
+ }
328
+ }
329
+ }
330
+ catch (error) {
331
+ if (indexedEntry)
332
+ throwIndexedPathNotFound(error, input.ref);
333
+ throw error;
334
+ }
335
+ if (indexedEntry) {
336
+ response.type = indexedEntry.type;
337
+ response.name = indexedEntry.name;
338
+ }
339
+ const isPrimaryStash = source !== undefined && source.path === allSources[0]?.path;
340
+ const canonicalRef = displayRef({
341
+ type: displayType,
342
+ name: displayName,
343
+ conceptId: indexedEntry?.conceptId,
344
+ bundleId: indexedEntry ? indexedEntry.bundleId : source?.registryId,
345
+ }, config.defaultBundle ?? (isPrimaryStash ? indexedEntry?.bundleId : undefined));
346
+ if (response.type === "workflow")
347
+ response.action = buildWorkflowAction(canonicalRef);
366
348
  // 07 P1-D: provenance-aware toolPolicy CEILING. An agent's self-declared
367
349
  // `tools` frontmatter is honoured ONLY for the operator's own PRIMARY stash —
368
350
  // the assets they authored. Every other source is content pulled from
@@ -374,16 +356,16 @@ export async function showLocal(input) {
374
356
  // `allSources[0]` is always the primary (search-source.ts) — not a
375
357
  // name-derived registryId or the orthogonal `writable` bit. `source` undefined
376
358
  // (unresolved path) also fails closed.
377
- const isPrimaryStash = source !== undefined && source.path === allSources[0]?.path;
378
359
  if (response.toolPolicy !== undefined && !isPrimaryStash) {
379
360
  delete response.toolPolicy;
380
361
  }
381
- const editable = isEditable(assetPath, config);
362
+ const editable = isEditable(assetPath, config, allSources);
382
363
  const fullResponse = {
383
364
  ...response,
365
+ ref: canonicalRef,
384
366
  origin: source?.registryId ?? null,
385
367
  editable,
386
- ...(!editable ? { editHint: buildEditHint(assetPath, parsed.type, parsed.name, source?.registryId) } : {}),
368
+ ...(!editable ? { editHint: buildEditHint(canonicalRef) } : {}),
387
369
  related: (() => {
388
370
  try {
389
371
  return withIndexDb((db) => {
@@ -476,14 +458,87 @@ async function maybeExtractGraphInline(config, sourceStashDir, assetPath) {
476
458
  * renderer graph. Spec §6.2's literal flow.
477
459
  */
478
460
  export async function showByRef(ref) {
479
- const parsed = parseAssetRef(ref);
480
- const entry = await lookup(parsed);
461
+ const parsed = parseBundleRef(ref);
462
+ if (parsed.fragment !== undefined) {
463
+ throw new UsageError(`Fragments are not accepted by raw show: ${ref}`, "INVALID_FLAG_VALUE");
464
+ }
465
+ const entry = await lookupBundleRef(parsed);
481
466
  if (!entry) {
482
- throw new NotFoundError(`Asset not found for ref: ${parsed.type}:${parsed.name}`);
467
+ throw new NotFoundError(`Asset not found for ref: ${makeBundleRef(parsed.bundle, parsed.conceptId)}`);
468
+ }
469
+ let body;
470
+ try {
471
+ body = await fs.promises.readFile(entry.filePath, "utf8");
472
+ }
473
+ catch (error) {
474
+ throwIndexedPathNotFound(error, ref);
483
475
  }
484
- const body = await fs.promises.readFile(entry.filePath, "utf8");
485
476
  return { filePath: entry.filePath, body };
486
477
  }
478
+ function throwIndexedPathNotFound(error, ref) {
479
+ const code = error?.code;
480
+ if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM") {
481
+ throw new NotFoundError(`The indexed file for ${ref} is missing or unreadable. The search index may be stale.`, "ASSET_NOT_FOUND", "Run `akm index` to reconcile indexed paths, then retry `akm show`.");
482
+ }
483
+ throw error;
484
+ }
485
+ /** `null` selects adapter-owned projection; a string selects a core renderer. */
486
+ function rendererForIndexedEntry(entry, _file) {
487
+ if (entry.document?.ownsPresentation === true)
488
+ return null;
489
+ switch (entry.adapterId) {
490
+ case null:
491
+ case undefined:
492
+ case "akm":
493
+ return undefined;
494
+ case "akm-workflow":
495
+ return "workflow-md";
496
+ default:
497
+ return presentationFor(entry.type).renderer;
498
+ }
499
+ }
500
+ function indexedMatch(entry, renderer) {
501
+ return { type: entry.type, specificity: Number.MAX_SAFE_INTEGER, renderer, meta: { name: entry.name } };
502
+ }
503
+ function buildIndexedProjectionResponse(entry, assetPath, fragment) {
504
+ if (fragment !== undefined && path.extname(assetPath).toLowerCase() !== ".md") {
505
+ throw new UsageError(`Fragments are not supported for ${entry.conceptId}. Only Markdown documents support heading fragments.`, "INVALID_FLAG_VALUE");
506
+ }
507
+ const raw = fs.readFileSync(assetPath, "utf8");
508
+ const parsed = parseFrontmatter(raw);
509
+ const content = fragment ? requireMarkdownSection(parsed.content, fragment, entry.name).content : parsed.content;
510
+ const description = entry.document?.description ?? asNonEmptyString(parsed.data.description);
511
+ const tags = entry.document?.tags ??
512
+ (Array.isArray(parsed.data.tags)
513
+ ? parsed.data.tags.filter((tag) => typeof tag === "string" && tag.trim().length > 0)
514
+ : undefined);
515
+ return {
516
+ type: entry.type,
517
+ name: entry.name,
518
+ path: assetPath,
519
+ action: "Read the content below.",
520
+ content,
521
+ ...(description ? { description } : {}),
522
+ ...(tags && tags.length > 0 ? { tags } : {}),
523
+ };
524
+ }
525
+ function applyMarkdownFragment(response, raw, fragment, name) {
526
+ const section = requireMarkdownSection(parseFrontmatter(raw).content, fragment, name).content;
527
+ if (response.template !== undefined)
528
+ response.template = section;
529
+ else if (response.prompt !== undefined)
530
+ response.prompt = section;
531
+ else
532
+ response.content = section;
533
+ }
534
+ function requireMarkdownSection(content, fragment, name) {
535
+ const section = extractSection(content, fragment);
536
+ if (section)
537
+ return section;
538
+ const available = markdownFragmentSlugs(content);
539
+ throw new NotFoundError(`Fragment "#${fragment}" not found in ${name}.` +
540
+ (available.length > 0 ? ` Available fragments: ${available.map((slug) => `#${slug}`).join(", ")}.` : ""));
541
+ }
487
542
  /**
488
543
  * Build a reduced brief response from a full ShowResponse.
489
544
  *
@@ -495,11 +550,13 @@ function buildBriefResponse(full, assetPath) {
495
550
  type: summary.type,
496
551
  name: summary.name,
497
552
  path: summary.path,
553
+ ...(summary.ref ? { ref: summary.ref } : {}),
498
554
  ...(summary.description ? { description: summary.description } : {}),
499
555
  ...(summary.action ? { action: summary.action } : {}),
500
556
  ...(summary.run ? { run: summary.run } : {}),
501
557
  ...(summary.origin !== undefined ? { origin: summary.origin } : {}),
502
558
  ...(full.editable !== undefined ? { editable: full.editable } : {}),
559
+ ...(full.editHint ? { editHint: full.editHint } : {}),
503
560
  };
504
561
  }
505
562
  /**
@@ -525,6 +582,7 @@ function buildSummaryResponse(full, assetPath) {
525
582
  type: full.type,
526
583
  name: full.name,
527
584
  path: full.path,
585
+ ...(full.ref ? { ref: full.ref } : {}),
528
586
  ...(description ? { description } : {}),
529
587
  ...(tags && tags.length > 0 ? { tags } : {}),
530
588
  ...(full.parameters ? { parameters: full.parameters } : {}),
@@ -532,90 +590,8 @@ function buildSummaryResponse(full, assetPath) {
532
590
  ...(full.action ? { action: full.action } : {}),
533
591
  ...(full.run ? { run: full.run } : {}),
534
592
  ...(full.origin !== undefined ? { origin: full.origin } : {}),
593
+ ...(full.editable !== undefined ? { editable: full.editable } : {}),
594
+ ...(full.editHint ? { editHint: full.editHint } : {}),
535
595
  };
536
596
  return summary;
537
597
  }
538
- // ── argv normalisation ───────────────────────────────────────────────────────
539
- const SHOW_VIEW_MODES = new Set(["toc", "frontmatter", "full", "section", "lines"]);
540
- const SHOW_ARGV_TOP_LEVEL_ARGS = {
541
- format: { type: "string" },
542
- output: { type: "string" },
543
- detail: { type: "string" },
544
- shape: { type: "string" },
545
- quiet: { type: "boolean", alias: "q" },
546
- verbose: { type: "boolean" },
547
- };
548
- /**
549
- * Normalize argv so positional view-mode arguments after the asset ref
550
- * are rewritten into internal flags that citty can parse.
551
- *
552
- * Converts:
553
- * akm show knowledge:guide.md toc → akm show knowledge:guide.md --akmView toc
554
- * akm show knowledge:guide.md section Auth → akm show knowledge:guide.md --akmView section --akmHeading Auth
555
- * akm show knowledge:guide.md lines 1 50 → akm show knowledge:guide.md --akmView lines --akmStart 1 --akmEnd 50
556
- *
557
- * Legacy `--view` is intentionally unsupported.
558
- * Returns a new array; the input is never modified.
559
- */
560
- export function normalizeShowArgv(argv) {
561
- const rawArgs = argv.slice(2);
562
- const commandIndex = findCittyTopLevelCommandIndex(rawArgs, SHOW_ARGV_TOP_LEVEL_ARGS);
563
- if (commandIndex < 0 || rawArgs[commandIndex] !== "show")
564
- return argv;
565
- const commandArgs = rawArgs.slice(commandIndex + 1);
566
- if (commandArgs.includes("--view") ||
567
- commandArgs.includes("--heading") ||
568
- commandArgs.includes("--start") ||
569
- commandArgs.includes("--end")) {
570
- throw new UsageError('Legacy show flags are no longer supported. Use positional syntax like `akm show knowledge:guide toc` or `akm show knowledge:guide section "Auth"`.');
571
- }
572
- // Separate global flags from positional/show-specific args
573
- const prefix = [...argv.slice(0, 2), ...rawArgs.slice(0, commandIndex + 1)];
574
- const rest = commandArgs;
575
- const globalFlags = [];
576
- const showArgs = [];
577
- for (let i = 0; i < rest.length; i++) {
578
- const arg = rest[i];
579
- if (arg === "--quiet" || arg === "-q" || arg === "--verbose") {
580
- globalFlags.push(arg);
581
- continue;
582
- }
583
- if (arg.startsWith("--format=") || arg.startsWith("--detail=") || arg.startsWith("--shape=")) {
584
- globalFlags.push(arg);
585
- continue;
586
- }
587
- if (arg === "--format" || arg === "--detail" || arg === "--shape") {
588
- globalFlags.push(arg);
589
- if (rest[i + 1] !== undefined) {
590
- globalFlags.push(rest[i + 1]);
591
- i++;
592
- }
593
- continue;
594
- }
595
- showArgs.push(arg);
596
- }
597
- // showArgs[0] = ref, showArgs[1] = potential view mode, showArgs[2..] = view params
598
- const ref = showArgs[0];
599
- const viewMode = showArgs[1];
600
- if (!ref || !viewMode || !SHOW_VIEW_MODES.has(viewMode)) {
601
- return argv;
602
- }
603
- const result = [...prefix, ref, "--akmView", viewMode];
604
- if (viewMode === "section") {
605
- // Next arg is the heading name; pass empty string when missing so the
606
- // show handler can produce a clear "section not found" error.
607
- const heading = showArgs[2] ?? "";
608
- result.push("--akmHeading", heading);
609
- }
610
- else if (viewMode === "lines") {
611
- // Next two args are start and end
612
- const start = showArgs[2];
613
- const end = showArgs[3];
614
- if (start)
615
- result.push("--akmStart", start);
616
- if (end)
617
- result.push("--akmEnd", end);
618
- }
619
- result.push(...globalFlags);
620
- return result;
621
- }