akm-cli 0.9.0-rc.8 → 0.9.0

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 (450) hide show
  1. package/CHANGELOG.md +1063 -44
  2. package/README.md +51 -25
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +497 -0
  5. package/dist/akm +148 -35
  6. package/dist/{akm-migrate-storage → akm-migrate} +6 -9
  7. package/dist/assets/hints/cli-hints-full.md +223 -95
  8. package/dist/assets/hints/cli-hints-short.md +85 -22
  9. package/dist/assets/improve-strategies/default.json +1 -1
  10. package/dist/assets/improve-strategies/reflect-distill.json +1 -1
  11. package/dist/assets/prompts/memory-infer-user.md +2 -3
  12. package/dist/assets/stash-skeleton/README.md +6 -5
  13. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
  14. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
  15. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
  17. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
  18. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
  19. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
  20. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
  21. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
  22. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
  23. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
  24. package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
  25. package/dist/assets/tasks/core/extract.yml +1 -1
  26. package/dist/assets/tasks/core/version-check.yml +1 -1
  27. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  28. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  29. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  30. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  31. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  32. package/dist/assets/templates/html/health.html +1 -3
  33. package/dist/assets/workflows/workflow-template.md +32 -15
  34. package/dist/cli/invocation.js +40 -15
  35. package/dist/cli/parse-args.js +0 -22
  36. package/dist/cli/retired-commands.js +121 -0
  37. package/dist/cli/shared.js +154 -22
  38. package/dist/cli/unknown-flags.js +236 -0
  39. package/dist/cli-node.mjs +2 -1
  40. package/dist/cli.js +696 -258
  41. package/dist/commands/agent/agent-dispatch.js +14 -3
  42. package/dist/commands/agent/contribute-cli.js +73 -88
  43. package/dist/commands/completions.js +79 -22
  44. package/dist/commands/config-cli.js +17 -150
  45. package/dist/commands/env/env-cli.js +59 -143
  46. package/dist/commands/env/env.js +12 -163
  47. package/dist/commands/env/marker-path.js +6 -0
  48. package/dist/commands/env/secret-cli.js +36 -66
  49. package/dist/commands/env/secret.js +24 -57
  50. package/dist/commands/feedback-cli.js +141 -87
  51. package/dist/commands/health/accept-rate.js +58 -0
  52. package/dist/commands/health/advisories.js +3 -4
  53. package/dist/commands/health/checks.js +85 -23
  54. package/dist/commands/health/html-report.js +7 -10
  55. package/dist/commands/health/improve-metrics.js +25 -83
  56. package/dist/commands/health/md-report.js +5 -9
  57. package/dist/commands/health/metrics.js +62 -20
  58. package/dist/commands/health/renderers.js +47 -0
  59. package/dist/commands/health/report-view-model.js +4 -5
  60. package/dist/commands/health/stash-exposure.js +1 -1
  61. package/dist/commands/health/surfaces.js +3 -48
  62. package/dist/commands/health/task-runs.js +3 -67
  63. package/dist/commands/health/types-improve.js +7 -0
  64. package/dist/commands/health.js +99 -28
  65. package/dist/commands/improve/anti-collapse.js +2 -2
  66. package/dist/commands/improve/autonomy-gate.js +68 -0
  67. package/dist/commands/improve/collapse-detector.js +41 -40
  68. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  69. package/dist/commands/improve/consolidate/merge.js +4 -0
  70. package/dist/commands/improve/consolidate.js +140 -1000
  71. package/dist/commands/improve/distill/promote-memory.js +12 -12
  72. package/dist/commands/improve/distill/quality-gate.js +6 -6
  73. package/dist/commands/improve/distill.js +58 -69
  74. package/dist/commands/improve/eligibility.js +105 -57
  75. package/dist/commands/improve/extract-cli.js +14 -133
  76. package/dist/commands/improve/improve-cli.js +98 -114
  77. package/dist/commands/improve/improve-result-file.js +1 -28
  78. package/dist/commands/improve/improve-strategies.js +8 -5
  79. package/dist/commands/improve/improve.js +128 -91
  80. package/dist/commands/improve/loop-stages.js +182 -20
  81. package/dist/commands/improve/memory/derived-ref.js +45 -43
  82. package/dist/commands/improve/memory/memory-belief.js +1 -1
  83. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  84. package/dist/commands/improve/memory/memory-improve.js +6 -5
  85. package/dist/commands/improve/outcome-loop.js +22 -65
  86. package/dist/commands/improve/preparation.js +114 -123
  87. package/dist/commands/improve/proactive-maintenance.js +2 -5
  88. package/dist/commands/improve/reflect.js +56 -160
  89. package/dist/commands/improve/salience.js +11 -122
  90. package/dist/commands/improve/source-identity.js +10 -38
  91. package/dist/commands/lint/base-linter.js +20 -124
  92. package/dist/commands/lint/env-key-rules.js +31 -47
  93. package/dist/commands/lint/index.js +249 -43
  94. package/dist/commands/{events.js → log.js} +33 -38
  95. package/dist/commands/migrate-cli.js +92 -12
  96. package/dist/commands/migration-tool.js +46 -0
  97. package/dist/commands/observability-cli.js +70 -209
  98. package/dist/commands/proposal/drain.js +101 -29
  99. package/dist/commands/proposal/proposal-cli.js +76 -48
  100. package/dist/commands/proposal/proposal.js +54 -18
  101. package/dist/commands/proposal/propose-cli.js +88 -0
  102. package/dist/commands/proposal/propose.js +23 -15
  103. package/dist/commands/proposal/repository.js +701 -278
  104. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  105. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  106. package/dist/commands/proposal/validators/proposals.js +4 -7
  107. package/dist/commands/read/curate.js +34 -53
  108. package/dist/commands/read/knowledge.js +150 -95
  109. package/dist/commands/read/registry-search.js +2 -2
  110. package/dist/commands/read/remember-cli.js +42 -15
  111. package/dist/commands/read/search-cli.js +180 -78
  112. package/dist/commands/read/search.js +58 -43
  113. package/dist/commands/read/show.js +197 -141
  114. package/dist/commands/registry-cli.js +12 -51
  115. package/dist/commands/remember.js +14 -57
  116. package/dist/commands/sources/add-cli.js +100 -31
  117. package/dist/commands/sources/bundle-cli.js +166 -0
  118. package/dist/commands/sources/bundle-config-ops.js +7 -2
  119. package/dist/commands/sources/info.js +18 -5
  120. package/dist/commands/sources/init.js +12 -12
  121. package/dist/commands/sources/installed-stashes.js +382 -98
  122. package/dist/commands/sources/schema-repair.js +3 -2
  123. package/dist/commands/sources/self-update.js +131 -38
  124. package/dist/commands/sources/source-add.js +72 -17
  125. package/dist/commands/sources/source-clone.js +129 -45
  126. package/dist/commands/sources/source-manage.js +43 -23
  127. package/dist/commands/sources/sources-cli.js +57 -208
  128. package/dist/commands/sources/stash-cli.js +46 -53
  129. package/dist/commands/tasks/tasks-cli.js +91 -97
  130. package/dist/commands/tasks/tasks.js +276 -421
  131. package/dist/commands/workflow-cli.js +175 -450
  132. package/dist/core/adapter/adapters/akm-adapter.js +47 -28
  133. package/dist/core/adapter/adapters/akm-lint.js +42 -27
  134. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  135. package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
  136. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  137. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  138. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  139. package/dist/core/adapter/adapters/index.js +6 -6
  140. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  141. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  142. package/dist/core/adapter/adapters/shared.js +3 -19
  143. package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
  144. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  145. package/dist/core/adapter/detect-adapter.js +17 -0
  146. package/dist/core/adapter/recognize-match.js +6 -4
  147. package/dist/core/adapter/validate-context.js +214 -0
  148. package/dist/core/asset/akm-markdown.js +63 -0
  149. package/dist/core/asset/asset-placement.js +20 -6
  150. package/dist/core/asset/asset-ref.js +11 -9
  151. package/dist/core/asset/frontmatter-lint.js +30 -0
  152. package/dist/core/asset/frontmatter.js +37 -9
  153. package/dist/core/asset/markdown.js +40 -51
  154. package/dist/core/asset/resolve-ref.js +89 -18
  155. package/dist/core/asset/stash-meta.js +1 -1
  156. package/dist/core/bundle-id.js +51 -0
  157. package/dist/core/common.js +152 -38
  158. package/dist/core/config/config-io.js +12 -1
  159. package/dist/core/config/config-schema.js +35 -8
  160. package/dist/core/config/config-sources.js +55 -11
  161. package/dist/core/config/config-walker.js +25 -9
  162. package/dist/core/config/config.js +9 -48
  163. package/dist/core/config/experimental.js +21 -0
  164. package/dist/core/config/schema/embedding.js +5 -1
  165. package/dist/core/config/schema/experimental.js +30 -0
  166. package/dist/core/config/schema/improve-processes.js +0 -6
  167. package/dist/core/config/schema/improve.js +21 -3
  168. package/dist/core/config/schema/index-config.js +8 -15
  169. package/dist/core/config/schema/output.js +4 -1
  170. package/dist/core/config/schema/setup.js +9 -18
  171. package/dist/core/config/schema/sources-bundles.js +49 -33
  172. package/dist/core/config/schema/workflow.js +3 -3
  173. package/dist/core/env-secret-ref.js +76 -46
  174. package/dist/core/errors.js +18 -12
  175. package/dist/core/events.js +46 -128
  176. package/dist/core/file-change.js +6 -5
  177. package/dist/core/fs-txn.js +83 -7
  178. package/dist/core/git-message.js +2 -2
  179. package/dist/core/improve-result.js +1 -100
  180. package/dist/core/lesson-lint.js +1 -17
  181. package/dist/core/logs-db.js +2 -1
  182. package/dist/core/migration-operation.js +16 -0
  183. package/dist/core/mutation-target.js +78 -0
  184. package/dist/core/parse.js +4 -1
  185. package/dist/core/paths.js +17 -20
  186. package/dist/core/recognition-util.js +12 -14
  187. package/dist/core/redaction.js +34 -0
  188. package/dist/core/standards/resolve-standards-context.js +2 -14
  189. package/dist/core/standards/resolve-stash-standards.js +2 -2
  190. package/dist/core/standards/resolve-type-conventions.js +2 -2
  191. package/dist/core/state/migrations.js +41 -18
  192. package/dist/core/state-db.js +5 -14
  193. package/dist/core/structured.js +1 -1
  194. package/dist/core/subprocess.js +6 -4
  195. package/dist/core/text-truncation.js +9 -5
  196. package/dist/core/type-presentation.js +3 -3
  197. package/dist/core/warn.js +0 -3
  198. package/dist/core/write-source.js +771 -95
  199. package/dist/indexer/bundle-identity-guard.js +3 -2
  200. package/dist/indexer/db/graph-db.js +0 -24
  201. package/dist/indexer/ensure-index.js +1 -0
  202. package/dist/indexer/graph/graph-boost.js +9 -34
  203. package/dist/indexer/graph/graph-extraction.js +8 -5
  204. package/dist/indexer/index-writer-lock.js +53 -17
  205. package/dist/indexer/index-written-assets.js +16 -22
  206. package/dist/indexer/indexer.js +497 -239
  207. package/dist/indexer/installations.js +14 -96
  208. package/dist/indexer/passes/dir-staleness.js +16 -9
  209. package/dist/indexer/passes/memory-inference.js +11 -9
  210. package/dist/indexer/passes/metadata.js +113 -47
  211. package/dist/indexer/scan/doc-to-entry.js +38 -1
  212. package/dist/indexer/scan/drain-dir.js +13 -23
  213. package/dist/indexer/search/db-search.js +99 -54
  214. package/dist/indexer/search/fts-query.js +47 -24
  215. package/dist/indexer/search/ranking-contributors.js +42 -20
  216. package/dist/indexer/search/ranking.js +18 -99
  217. package/dist/indexer/search/search-fields.js +7 -2
  218. package/dist/indexer/search/search-source.js +82 -93
  219. package/dist/indexer/usage/usage-events.js +0 -89
  220. package/dist/indexer/walk/file-context.js +2 -1
  221. package/dist/indexer/walk/matchers.js +30 -43
  222. package/dist/indexer/walk/path-resolver.js +7 -2
  223. package/dist/indexer/walk/walker.js +38 -12
  224. package/dist/integrations/agent/builders.js +0 -6
  225. package/dist/integrations/agent/config.js +2 -2
  226. package/dist/integrations/agent/detect.js +49 -19
  227. package/dist/integrations/agent/engine-fallback.js +76 -0
  228. package/dist/integrations/agent/profiles.js +14 -0
  229. package/dist/integrations/agent/prompts.js +12 -8
  230. package/dist/integrations/agent/runner-dispatch.js +4 -2
  231. package/dist/integrations/agent/runner.js +0 -1
  232. package/dist/integrations/agent/spawn.js +5 -6
  233. package/dist/integrations/github.js +1 -1
  234. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  235. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  236. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  237. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  238. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  239. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  240. package/dist/integrations/harnesses/index.js +3 -7
  241. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  242. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  243. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  244. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  245. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  246. package/dist/integrations/lockfile.js +101 -6
  247. package/dist/integrations/session-logs/index.js +3 -28
  248. package/dist/llm/client.js +136 -100
  249. package/dist/llm/embedders/remote.js +13 -5
  250. package/dist/llm/feature-gate.js +4 -12
  251. package/dist/llm/graph-extract.js +5 -11
  252. package/dist/llm/memory-infer.js +144 -1
  253. package/dist/llm/metadata-enhance.js +5 -7
  254. package/dist/llm/structured-call.js +1 -1
  255. package/dist/llm/usage-persist.js +26 -5
  256. package/dist/llm/usage-telemetry.js +25 -2
  257. package/dist/output/cli-hints.js +1 -2
  258. package/dist/output/context.js +22 -7
  259. package/dist/output/format-exempt.js +80 -0
  260. package/dist/output/generic-render.js +259 -0
  261. package/dist/output/render-registry.js +57 -0
  262. package/dist/output/renderers.js +14 -36
  263. package/dist/output/shapes/curate.js +10 -1
  264. package/dist/output/shapes/events.js +12 -7
  265. package/dist/output/shapes/helpers.js +56 -83
  266. package/dist/output/shapes/migrate.js +8 -0
  267. package/dist/output/shapes/passthrough.js +7 -41
  268. package/dist/output/shapes/proposal/producer.js +15 -7
  269. package/dist/output/shapes.js +2 -9
  270. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  271. package/dist/output/text/bundle-show.js +7 -0
  272. package/dist/output/text/command-format.js +164 -96
  273. package/dist/output/text/env.js +1 -3
  274. package/dist/output/text/events.js +8 -7
  275. package/dist/output/text/health-format.js +103 -0
  276. package/dist/output/text/health.js +7 -0
  277. package/dist/output/text/helpers.js +10 -8
  278. package/dist/output/text/lint-format.js +43 -0
  279. package/dist/output/text/{save.js → lint.js} +2 -2
  280. package/dist/output/text/migrate.js +88 -0
  281. package/dist/output/text/proposal/producer.js +4 -2
  282. package/dist/output/text/proposal-format.js +44 -72
  283. package/dist/output/text/registry-commands.js +1 -2
  284. package/dist/output/text/show-directives.js +15 -7
  285. package/dist/output/text/status-list.js +32 -0
  286. package/dist/output/text/sync.js +5 -0
  287. package/dist/output/text/workflow-format.js +24 -203
  288. package/dist/output/text/workflow.js +1 -7
  289. package/dist/output/text.js +16 -17
  290. package/dist/registry/factory.js +4 -6
  291. package/dist/registry/origin-resolve.js +16 -27
  292. package/dist/registry/providers/skills-sh.js +3 -3
  293. package/dist/registry/providers/static-index.js +13 -23
  294. package/dist/registry/resolve.js +42 -7
  295. package/dist/registry/semver.js +34 -84
  296. package/dist/runtime.js +2 -23
  297. package/dist/scripts/akm-migrate-node.js +60290 -0
  298. package/dist/scripts/akm-migrate.js +59628 -0
  299. package/dist/setup/detect.js +42 -15
  300. package/dist/setup/registry-stash-loader.js +2 -2
  301. package/dist/setup/setup.js +236 -136
  302. package/dist/setup/steps/connection.js +7 -9
  303. package/dist/setup/steps/platforms.js +9 -9
  304. package/dist/setup/steps/semantic.js +15 -3
  305. package/dist/setup/steps/sources.js +12 -13
  306. package/dist/setup/steps/stashdir.js +2 -3
  307. package/dist/setup/steps/tasks.js +237 -120
  308. package/dist/sources/freshness.js +1 -1
  309. package/dist/sources/provider-factory.js +11 -17
  310. package/dist/sources/providers/filesystem.js +2 -3
  311. package/dist/sources/providers/git-install.js +278 -34
  312. package/dist/sources/providers/git-provider.js +25 -23
  313. package/dist/sources/providers/git-stash.js +395 -106
  314. package/dist/sources/providers/git.js +2 -2
  315. package/dist/sources/providers/npm.js +16 -19
  316. package/dist/sources/providers/provider-utils.js +7 -4
  317. package/dist/sources/providers/sync-from-ref.js +3 -9
  318. package/dist/sources/providers/website.js +6 -1
  319. package/dist/sources/resolve.js +6 -5
  320. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  321. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  322. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  323. package/dist/sources/snapshot-fetchers/github.js +100 -0
  324. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  325. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  326. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  327. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  328. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  329. package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
  330. package/dist/sources/snapshot-fetchers/x.js +910 -0
  331. package/dist/storage/database.js +7 -0
  332. package/dist/storage/engines/sqlite-migrations.js +23 -111
  333. package/dist/storage/managed-db.js +2 -2
  334. package/dist/storage/repositories/canaries-repository.js +1 -1
  335. package/dist/storage/repositories/events-repository.js +27 -11
  336. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  337. package/dist/storage/repositories/index-connection.js +17 -6
  338. package/dist/storage/repositories/index-entries-repository.js +151 -240
  339. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  340. package/dist/storage/repositories/index-fts-repository.js +5 -2
  341. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  342. package/dist/storage/repositories/index-meta-repository.js +2 -3
  343. package/dist/storage/repositories/index-schema.js +10 -25
  344. package/dist/storage/repositories/index-utility-repository.js +15 -28
  345. package/dist/storage/repositories/index-vec-repository.js +6 -1
  346. package/dist/storage/repositories/outcome-repository.js +119 -0
  347. package/dist/storage/repositories/proposals-repository.js +296 -59
  348. package/dist/storage/repositories/registry-cache.js +19 -0
  349. package/dist/storage/repositories/salience-repository.js +172 -0
  350. package/dist/storage/repositories/task-history-repository.js +15 -13
  351. package/dist/storage/repositories/workflow-runs-repository.js +52 -40
  352. package/dist/tasks/backends/cron.js +105 -15
  353. package/dist/tasks/backends/index.js +1 -1
  354. package/dist/tasks/backends/launchd.js +85 -38
  355. package/dist/tasks/backends/schtasks.js +135 -15
  356. package/dist/tasks/embedded.js +56 -40
  357. package/dist/tasks/parser.js +7 -157
  358. package/dist/tasks/resolve-akm-bin.js +137 -59
  359. package/dist/tasks/runner.js +79 -42
  360. package/dist/tasks/scheduler-invocation.js +220 -10
  361. package/dist/tasks/schema.js +24 -1
  362. package/dist/tasks/task-id.js +1 -3
  363. package/dist/tasks/validator.js +20 -6
  364. package/dist/workflows/authoring/authoring.js +94 -143
  365. package/dist/workflows/authoring/scope-key.js +1 -1
  366. package/dist/workflows/exec/frozen-judge.js +28 -2
  367. package/dist/workflows/exec/native-executor.js +77 -57
  368. package/dist/workflows/exec/param-secrets.js +9 -9
  369. package/dist/workflows/exec/run-workflow.js +133 -79
  370. package/dist/workflows/exec/step-work.js +219 -346
  371. package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
  372. package/dist/workflows/ir/compile.js +141 -270
  373. package/dist/workflows/ir/freeze.js +40 -30
  374. package/dist/workflows/ir/params.js +135 -11
  375. package/dist/workflows/ir/plan-hash.js +1 -1
  376. package/dist/workflows/ir/schema.js +25 -26
  377. package/dist/workflows/parser.js +872 -307
  378. package/dist/workflows/program/expressions.js +20 -208
  379. package/dist/workflows/program/schema.js +7 -10
  380. package/dist/workflows/renderer.js +95 -68
  381. package/dist/workflows/resource-limits.js +2 -0
  382. package/dist/workflows/runtime/checkin.js +3 -3
  383. package/dist/workflows/runtime/plan-classifier.js +16 -75
  384. package/dist/workflows/runtime/runs.js +186 -127
  385. package/dist/workflows/runtime/unit-checkin.js +1 -1
  386. package/dist/workflows/runtime/unit-phases.js +2 -2
  387. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  388. package/dist/workflows/schema.js +1 -11
  389. package/dist/workflows/validate-summary.js +30 -36
  390. package/dist/workflows/validator.js +21 -62
  391. package/docs/README.md +68 -0
  392. package/docs/migration/README.md +8 -0
  393. package/docs/migration/release-notes/0.7.0.md +11 -11
  394. package/docs/migration/release-notes/0.9.0.md +208 -27
  395. package/docs/migration/v0.7-to-v0.8.md +46 -47
  396. package/docs/migration/v0.8-to-v0.9.md +564 -208
  397. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  398. package/docs/reference/README.md +12 -0
  399. package/docs/reference/cli.md +2253 -0
  400. package/docs/reference/configuration.md +358 -0
  401. package/docs/reference/data-and-telemetry.md +105 -42
  402. package/docs/reference/workflows.md +647 -0
  403. package/package.json +22 -11
  404. package/schemas/akm-asset-envelope.json +93 -0
  405. package/schemas/akm-config.json +81 -128
  406. package/schemas/akm-workflow.json +74 -73
  407. package/dist/assets/tasks/core/backup.yml +0 -5
  408. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  409. package/dist/cli/config-migrate.js +0 -1806
  410. package/dist/cli/config-validate.js +0 -41
  411. package/dist/commands/backup-cli.js +0 -56
  412. package/dist/commands/bundle/bundle-cli.js +0 -68
  413. package/dist/commands/bundle/bundle.js +0 -219
  414. package/dist/commands/graph/graph-cli.js +0 -124
  415. package/dist/commands/graph/graph.js +0 -489
  416. package/dist/commands/improve/extract-watch.js +0 -140
  417. package/dist/commands/mv-cli.js +0 -1221
  418. package/dist/commands/sources/history.js +0 -201
  419. package/dist/commands/tasks/default-tasks.js +0 -186
  420. package/dist/core/migration-backup.js +0 -1234
  421. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  422. package/dist/llm/memory-infer-impl.js +0 -138
  423. package/dist/migrate/legacy/config-source-migration.js +0 -223
  424. package/dist/migrate/legacy/content-migration.js +0 -305
  425. package/dist/migrate/legacy/legacy-layout.js +0 -779
  426. package/dist/migrate/legacy/legacy-paths.js +0 -25
  427. package/dist/migrate/legacy/legacy-stash-json.js +0 -72
  428. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  429. package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
  430. package/dist/migrate/legacy/three-db-cutover.js +0 -841
  431. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  432. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  433. package/dist/migrate/legacy-ref-grammar.js +0 -214
  434. package/dist/output/shapes/distill.js +0 -14
  435. package/dist/output/shapes/history.js +0 -11
  436. package/dist/output/text/distill.js +0 -6
  437. package/dist/output/text/enable-disable.js +0 -8
  438. package/dist/output/text/history.js +0 -6
  439. package/dist/registry/build-index.js +0 -382
  440. package/dist/schemas/akm-config.json +0 -4704
  441. package/dist/schemas/akm-task.json +0 -87
  442. package/dist/schemas/akm-workflow.json +0 -372
  443. package/dist/scripts/migrate-storage.js +0 -3816
  444. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  445. package/dist/workflows/cli.js +0 -53
  446. package/dist/workflows/exec/brief.js +0 -481
  447. package/dist/workflows/exec/report.js +0 -1460
  448. package/dist/workflows/exec/watch.js +0 -116
  449. package/dist/workflows/program/parser.js +0 -813
  450. package/dist/workflows/program/project.js +0 -104
@@ -0,0 +1,2253 @@
1
+ # CLI Reference
2
+
3
+ The CLI is called `akm` (Agent Knowledge Manager). Commands default to structured
4
+ JSON at `--detail brief`. Use `--format json|jsonl|yaml|text|md|html`,
5
+ `--detail brief|normal|full`, and `--shape human|agent|summary` when you want a
6
+ different presentation. Errors include `error` and `hint` fields.
7
+
8
+ This page is authoritative for the current CLI. For per-release behavior
9
+ changes, see [`CHANGELOG.md`](../../CHANGELOG.md) and
10
+ [`docs/migration/`](../migration/).
11
+
12
+ ## Global Flags
13
+
14
+ These flags are accepted by all commands:
15
+
16
+ | Flag | Values | Default | Description |
17
+ | --- | --- | --- | --- |
18
+ | `--format` | `json`, `jsonl`, `yaml`, `text`, `md`, `html` | `json` | Output format |
19
+ | `--output` | path | _(none)_ | Write rendered output to a file instead of stdout (all formats except `jsonl`) |
20
+ | `--detail` | `brief`, `normal`, `full` | `brief` | Output **verbosity** level |
21
+ | `--shape` | `human`, `agent`, `summary` | `human` | Output **projection** |
22
+ | `--quiet` / `-q` | boolean | `false` | Suppress stderr warnings |
23
+ | `--verbose` | boolean | `false` | Enable verbose diagnostics gated behind `isVerbose()`. Parsed globally before any subcommand runs. The `AKM_VERBOSE` env var honours the same setting and wins when both are present (see `src/core/warn.ts`). |
24
+
25
+ `--detail` controls **how much** is returned (`brief|normal|full`); `--shape`
26
+ controls the **projection** (`human` for people, `agent` for a token-lean
27
+ action view, `summary` for capability discovery).
28
+
29
+ ### `--format jsonl`
30
+
31
+ Outputs one JSON object per line. For `search` (including `--from registry`),
32
+ each hit is a separate line. For other commands, the entire result is a single line.
33
+ Useful for streaming consumption by scripts or agents.
34
+
35
+ ### `--format md` and `--format html`
36
+
37
+ `json`, `jsonl`, and `yaml` serialize the result envelope; `text`, `md`, and
38
+ `html` render it. Every result-envelope command supports all six.
39
+
40
+ A command may register a renderer for a document format when it has something
41
+ better to say than the generic one: `akm health --group-by run --format md`
42
+ emits its per-run table, and `akm health --report --format html` renders the
43
+ full report with KPI cards, charts, and advisories. The renderers are
44
+ data-driven — they fire when the result carries the report dataset, never on
45
+ the format alone, so the same dataset is available as JSON too. Every other command falls back to a
46
+ generic rendering derived from its own envelope — headings for the top-level
47
+ keys, a table for an array of uniform objects, lists otherwise. HTML output is a
48
+ self-contained document with no external references, so it can be redirected to
49
+ a file and opened directly.
50
+
51
+ A small set of commands is **format-exempt** because their output is not a
52
+ result envelope at all — `completions`, child-process passthrough (`env run`
53
+ and `secret run`), document payloads (`help`,
54
+ `help migrate`), and `env path` (a bare filesystem path is the payload, the
55
+ documented shell-substitution primitive — wrapping it in an envelope would
56
+ break `$(akm env path <ref>)` substitutions). Passing `--format` to one of
57
+ those **warns on stderr** and is otherwise ignored; the exempt set is declared
58
+ in `src/output/format-exempt.ts`. `migrate status`/`apply` also spawn a
59
+ standalone tool (the migration tool) but are NOT exempt: the CLI parses that
60
+ child's final JSON result line and renders it through the normal `--format`
61
+ pipeline, so `text`/`md`/`html`/`yaml` genuinely reformat it; any progress
62
+ lines the child printed along the way still print verbatim, ahead of the
63
+ formatted result.
64
+
65
+ Scripted `setup` modes emit a normal format-aware result. Interactive `setup`
66
+ is a terminal UI and emits no result document. `agent` leaves inherited child
67
+ streams raw, then formats its final `agent-result` envelope normally.
68
+
69
+ ### `--shape=agent`
70
+
71
+ Strips output to only action-relevant fields:
72
+
73
+ - **search**: keeps `name`, canonical `ref`, absolute `path`, `editable`, `type`, `description`, `action`, `score`, and optional `estimatedTokens`/`keys`
74
+ - **show**: adds absolute `path`, `editable`, and the existing type-specific action/content fields on top of the canonical `ref` that every `show` shape returns (`ref` is not agent-exclusive — see `--shape summary` below)
75
+ - **curate**: local items keep canonical `ref`, absolute `path`, `editable`, and their follow-up fields
76
+
77
+ For local materialized assets, `editHint` is added only when `editable` is
78
+ `false`. It is supplemental guidance and does not replace the normal show, run,
79
+ or use `action` (or curate `followUp`). Registry-only results have no local
80
+ `path`, `editable`, or `editHint`.
81
+
82
+ ### `--shape summary`
83
+
84
+ Valid **only on `akm show`**. Every other command rejects `--shape summary`
85
+ with an `INVALID_SHAPE_VALUE` usage error (exit 2) — an honest rejection rather
86
+ than a silent fallback. It returns a compact view suitable for capability
87
+ discovery:
88
+
89
+ - **show**: `type`, `name`, canonical `ref`, `description`, `tags`, `parameters`, `workflowTitle`, `action`, `run`, `origin`, `keys`, `related`
90
+
91
+ ## Exit Codes and Error Envelope
92
+
93
+ Every command exits with one of the following codes:
94
+
95
+ | Exit code | Meaning | Error class |
96
+ | --- | --- | --- |
97
+ | 0 | Success | — |
98
+ | 1 | Not found or command-reported failure | `NotFoundError`, command result |
99
+ | 2 | Usage / bad input | `UsageError` |
100
+ | 4 | Health warning (`akm health` only) | — |
101
+ | 70 | Internal / unclassified error | unexpected throw |
102
+ | 78 | Configuration error | `ConfigError` |
103
+
104
+ Failures classified by akm emit a JSON error envelope on **stderr** before
105
+ exiting; stdout is normally left empty:
106
+
107
+ ```json
108
+ {"ok": false, "error": "<message>", "hint": "<optional hint>"}
109
+ ```
110
+
111
+ The `hint` field is present only when actionable remediation is available
112
+ (e.g. a suggested flag or alternate command). Agents should check
113
+ `ok === false` on the parsed stderr envelope or a non-zero exit code to
114
+ detect failure. Scripts can rely on the exit code alone.
115
+
116
+ `env run`, `secret run`, and `migrate` preserve the spawned process's exact
117
+ status and raw streams instead of replacing them with an akm failure envelope.
118
+ `task run` maps completed, active, and disabled status to 0; blocked and failed
119
+ status to 1; and configuration errors to 78. It retains a command child's exact
120
+ status in `result.detail.exitCode`. `agent` maps a failed dispatch to 1 while
121
+ retaining the child status in its formatted result envelope.
122
+
123
+ ## Commands
124
+
125
+ ### bundle create
126
+
127
+ > **Note:** `akm setup` is the recommended entry point — it runs the same directory initialization plus guides you through AI connection configuration. `akm bundle create` remains available as a low-level building block.
128
+
129
+ Create the bundle directory structure and persist the working bundle path in
130
+ config.
131
+
132
+ ```sh
133
+ akm setup # Interactive setup wizard (creates bundle + configures connections)
134
+ akm setup --dir ~/custom-bundle # Initialize at a custom location
135
+ akm setup --yes # Non-interactive, accepts all defaults
136
+ ```
137
+
138
+ Creates one subdirectory per asset type under the bundle path — currently
139
+ `scripts/`, `skills/`, `commands/`, `agents/`, `knowledge/`, `workflows/`,
140
+ `instructions/`, `memories/`, `env/`, `secrets/`, `lessons/`, `tasks/`,
141
+ `sessions/`, and `facts/`. See
142
+ [technical/filesystem.md](https://github.com/itlackey/akm/blob/main/docs/architecture/internals/storage-locations.md) for config file locations.
143
+
144
+ ```sh
145
+ akm bundle create # Initialize the default bundle (~/akm) and set it as default
146
+ akm bundle create --dir ~/scratch-bundle # Scaffold a secondary bundle WITHOUT changing your default
147
+ akm bundle create --dir ~/scratch-bundle --set-default # Scaffold AND make it the default bundle
148
+ ```
149
+
150
+ **`--dir <path>`** scaffolds (and backfills) the target directory. By design it
151
+ does **not** change your configured default bundle unless you ask: `bundle
152
+ create` updates the primary `bundles` entry and `defaultBundle` in
153
+ `config.json` only when (a) no `--dir` is given, (b) no default is configured
154
+ yet (first-time bootstrap), or (c) you pass **`--set-default`**. When a `--dir`
155
+ is given and a default already exists without `--set-default`, your default
156
+ bundle pointer is left untouched and `bundle create` prints a note telling you
157
+ so. This prevents `akm bundle create --dir /tmp/throwaway` from silently
158
+ hijacking your real default bundle.
159
+
160
+ ### setup
161
+
162
+ Run the interactive first-run wizard.
163
+
164
+ ```sh
165
+ akm setup
166
+ ```
167
+
168
+ The setup wizard configures AKM in two steps:
169
+
170
+ **Step 1 — Small model connection** (for background processing)
171
+ Configures the OpenAI-compatible endpoint and model used for `akm index`
172
+ metadata enhancement, `akm remember --enrich`, and `akm curate --rerank`. Supports Ollama,
173
+ OpenAI, LM Studio, or any custom endpoint. Skipping disables enrichment features.
174
+
175
+ **Step 2 — Agent connection** (for agentic commands)
176
+ Configures how `akm improve`, `akm proposal new`, and `akm task run` dispatch AI sessions.
177
+ Options:
178
+ - **Same connection** — reuse the Step 1 endpoint with a (optionally different) model
179
+ - **New connection** — separate endpoint, model, and API key
180
+ - **Installed CLI agent** — use an installed agent binary (opencode, claude, codex, etc.)
181
+ - **None** — agentic commands disabled with a clear warning
182
+
183
+ A feature capability summary is shown at the end of setup.
184
+
185
+ The wizard also lets you choose a bundle directory, review registries, and add bundle
186
+ sources. When you save, akm writes the config file, initializes the bundle directory,
187
+ and builds the search index.
188
+
189
+ ### index
190
+
191
+ Build or refresh the search index.
192
+
193
+ ```sh
194
+ akm index # Incremental (only changed directories)
195
+ akm index --full # Full rebuild
196
+ akm index --verbose # Print phase progress to stderr
197
+ akm index --clean # Normal index + remove stale entries from the DB
198
+ akm index --clean --dry-run # Report stale entries without deleting
199
+ ```
200
+
201
+ Returns stats: `totalEntries`, `generatedMetadata`, `directoriesScanned`,
202
+ `directoriesSkipped`, `verification`, optional `warnings`, and `timing`
203
+ breakdown in milliseconds. Use `--verbose` to print the indexing mode,
204
+ semantic-search settings, and phase-by-phase progress to stderr while the
205
+ index is being built. Malformed workflow assets are skipped with file-path
206
+ warnings instead of aborting the full run.
207
+
208
+ **`--clean` flag:** After indexing completes, verifies every indexed entry's source
209
+ file still exists on disk. Removes any entries whose file is missing (for local
210
+ bundle sources only; remote entries are skipped). Returns a `clean` block in the
211
+ JSON result with `checked`, `removed`, `removedRefs` arrays, and `dryRun` flag.
212
+ Use `--clean` to resolve the edge case where a deleted file in an unchanged
213
+ directory lingers in the index across incremental runs. With `--dry-run`, reports
214
+ which entries would be removed without modifying the database.
215
+
216
+ `akm index` always rebuilds the search index and keeps metadata in the index.
217
+ When a selected named LLM engine (`defaults.llmEngine` or an indexing-pass
218
+ override) is configured and the per-pass gate allows it, metadata
219
+ enhancement runs during indexing. In text mode, the default CLI UI shows a
220
+ spinner with processed-versus-total source counts; structured output modes
221
+ (`json`, `yaml`, `jsonl`) stay clean and machine-readable.
222
+
223
+ ### info
224
+
225
+ Show system capabilities, configuration, and index state.
226
+
227
+ ```sh
228
+ akm info
229
+ ```
230
+
231
+ Returns a JSON object with:
232
+
233
+ | Field | Description |
234
+ | --- | --- |
235
+ | `version` | Current akm version |
236
+ | `bundleDir` | Primary bundle directory — same resolution `akm bundle list` uses |
237
+ | `defaultBundle` | Name of the primary bundle from config, or `null` when none is configured |
238
+ | `assetTypes` | List of recognized asset types |
239
+ | `searchModes` | Active search modes (`fts`, optionally `semantic` and `hybrid`) |
240
+ | `semanticSearch` | Semantic search status: `mode`, `status`, and optional `reason`/`message` |
241
+ | `registries` | Configured registries |
242
+ | `sourceProviders` | Configured sources (filesystem, git, website, npm) |
243
+ | `indexStats` | Index stats: `entryCount`, `byType` (per-asset-type breakdown), `lastBuiltAt`, `hasEmbeddings`, `vecAvailable` |
244
+
245
+ `semanticSearch.status` values:
246
+ - `"ready-vec"` — native sqlite-vec extension active (fastest)
247
+ - `"ready-js"` — pure JS fallback active (correct but slower at scale)
248
+ - `"pending"` — not yet initialized (run `akm index` to set up)
249
+ - `"blocked"` — setup failed (see `reason` and `message` fields)
250
+ - `"disabled"` — semantic search is turned off in config
251
+
252
+ Use `akm info` to verify that semantic search is working after setup.
253
+
254
+ ### health
255
+
256
+ Check akm runtime health, durable state, and recent improve-loop telemetry.
257
+
258
+ ```sh
259
+ akm health
260
+ akm health --since 24h
261
+ akm health --since 7d --format text
262
+ akm health --since 2026-05-01T00:00:00Z
263
+ akm health --report --format html # full report: per-run rows, trends, proposal queue
264
+ akm health --report --format json # the same dataset as data
265
+ akm health --report --window-compare 7d --format html
266
+ ```
267
+
268
+ | Flag | Description |
269
+ | --- | --- |
270
+ | `--since` | Rolling window start for task-history, improve, and advisory metrics. Accepts ISO 8601, `YYYY-MM-DD`, epoch milliseconds, or shorthand like `24h` / `7d`. Default: last 24 hours. |
271
+ | `--report` | Fetch the full report dataset: per-run rows, trend deltas vs the prior window (default: the `--since` window, so deltas are like-for-like), and the pending proposal queue. A **data** flag — the same dataset comes back in every `--format`; `md`/`html` render it as the rich report. |
272
+ | `--window-compare` | Compare the current window against the prior window of the same duration (e.g. `24h`, `7d`). With `--report`, overrides the default trend window. |
273
+ | `--group-by` | Group rows by `run` (one row per `improve_runs` entry). Omit for the default summary. |
274
+ | `--windows` | Explicit comparison window(s) as `name=...,since=ISO,until=ISO` (repeatable, up to 4). Mutually exclusive with `--window-compare`. |
275
+
276
+ The command reads `state.db`, verifies that the required tables exist, performs a
277
+ write-read probe against the events stream, inspects `task_history`, checks the
278
+ default agent engine, and summarizes recent `improve_*` events.
279
+
280
+ Primary result fields:
281
+
282
+ | Field | Description |
283
+ | --- | --- |
284
+ | `status` | Overall health verdict: `pass`, `warn`, or `fail` |
285
+ | `hardChecks` | Deterministic checks such as `state-db-schema`, `state-db-round-trip`, `task-log-backing`, `active-runs`, and `default-engine` |
286
+ | `advisories` | Non-fatal warnings including `semantic-search-runtime`, `session-extraction` (akmExtract pipeline health), and `session-log-failures` (informational keyword matches, never triggers warn) |
287
+ | `metrics` | Aggregate task/runtime metrics: `taskFailRate`, `agentFailureRate`, `stuckActiveRuns`, `logBackingRate`, `probeRoundTripMs` |
288
+ | `improve` | Recent improve-loop counts derived from `improve_invoked`, `improve_skipped`, and `improve_completed` events |
289
+ | `sessionLogAdvisories` | Raw keyword-matched session-log topics (pre-LLM, informational only) |
290
+
291
+ The `improve` section includes counts for planned refs, reflect/distill actions,
292
+ memory-prune actions, memory-inference writes, graph-extraction refreshes,
293
+ session-extraction outcomes (`sessionsScanned`, `sessionsExtracted`, `proposalsCreated`),
294
+ dead-URL detections, and skip reasons observed in the selected time window.
295
+
296
+ The `session-extraction` advisory reflects the health of the `akmExtract` pipeline
297
+ (Phase 0.4 of `akm improve`). It warns on harness errors or when no proposals are
298
+ generated across five or more scanned sessions. The `session-log-failures` advisory
299
+ is informational only and never triggers `warn` — it reports raw keyword matches,
300
+ not LLM-validated extraction outcomes.
301
+
302
+ The indexed entity graph (entities/relations extracted from bundle assets) has
303
+ no dedicated inspection command; its summary counts surface as an info-level
304
+ metric in `akm health`. Graph data is automatically re-extracted on the first
305
+ `akm improve` cycle after a `DB_VERSION` upgrade, and search ranking can
306
+ optionally use graph-derived confidence-weighted boosts — tune
307
+ `search.graphBoost.confidenceMode` and `search.graphBoost.confidenceWeight` in
308
+ [`docs/reference/configuration.md#search-tuning`](configuration.md#search-tuning).
309
+
310
+ ### search
311
+
312
+ Search bundle assets, registries, or both.
313
+
314
+ ```sh
315
+ akm search "deploy"
316
+ akm search "deploy" --type script --limit 10
317
+ akm search "lint" --from registry
318
+ akm search "docker" --from all --detail full
319
+
320
+ # Multi-tenant scope filtering:
321
+ akm search "deploy" --filter user=alice
322
+ akm search "deploy" --filter user=alice --filter agent=claude
323
+
324
+ # Include proposal-queue entries:
325
+ akm search "deploy" --include-proposed
326
+
327
+ # ConceptId-prefix enumeration — list a subtree instead of keyword-matching:
328
+ akm search "memories/projectA/"
329
+ akm search "knowledge/"
330
+ akm search "team-catalog//"
331
+ akm search "team-catalog//skills/"
332
+ ```
333
+
334
+ A query ending in `/` is a **conceptId prefix**, not a keyword search. It
335
+ enumerates the entries whose conceptId starts with that prefix: `akm search
336
+ "memories/projectA/"` lists exactly the `projectA/` subtree of memories
337
+ (recursive, `/`-boundary exact — a sibling `projectAlpha/` scope does not
338
+ leak), and `akm search "sessions/"` lists every session (a prefix is explicit
339
+ intent, so the default `session` exclusion — an untyped-path policy — does not
340
+ apply). A `<bundle>//` prefix scopes enumeration to one bundle, optionally
341
+ narrowed further (`team-catalog//skills/`); `<bundle>//` alone lists the whole
342
+ bundle, which is what replaced `akm bundle items`.
343
+
344
+ Because the prefix matches the **conceptId** — the same spelling every emitted
345
+ `ref` carries — a ref copied out of search output can be truncated to a prefix
346
+ and pasted straight back in. Hits carry the fixed browse score `1` in
347
+ deterministic listing order, matching the empty-query enumeration contract, and
348
+ compose with `--limit`, `--belief`, `--filter`, and named `--from` narrowing.
349
+ A full ref without the trailing slash (`memories/projectA/auth-tip`) stays an
350
+ ordinary keyword search — use `akm show` to resolve a single ref. An explicit
351
+ `--type` flag wins over the prefix.
352
+
353
+ The pre-0.9.0 `<type>:` / `<type>:<prefix>/` spelling was removed. A query in
354
+ that shape is now an ordinary keyword search, and when it returns nothing the
355
+ tip names the conceptId spelling that replaces it.
356
+
357
+ | Flag | Values | Default | Description |
358
+ | --- | --- | --- | --- |
359
+ | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter by asset type. Free-form and unvalidated — an unknown type returns no hits. Also accepts any adapter-defined type (e.g. `website`). |
360
+ | `--limit` | number | `20` | Maximum results |
361
+ | `--from` | `local`, `registry`, `all` | `local` | Where to search |
362
+ | `--assets` | flag | `false` | Include asset-level registry results (only meaningful with `--from registry\|all`; folds in the retired `akm registry search --assets`) |
363
+ | `--filter` | `<key>=<value>` | _(none)_ | Scope filter — repeatable. Valid keys: `user`, `agent`, `run`, `channel`. Example: `--filter user=alice --filter channel=ops`. Narrows the result set; ranking is unchanged. |
364
+ | `--include-proposed` | flag | `false` | Include entries with `quality: "proposed"` in the result set. Default search excludes them; `generated` and `curated` quality entries are always included. Unknown quality values warn once and remain searchable. |
365
+ | `--belief` | `all`, `current`, `historical` | `all` | Memory belief filter. `current` keeps active memory beliefs; `historical` keeps contradicted/superseded/archived ones. |
366
+ | `--no-project-context` | flag | `false` | Disable the automatic project-context ranking boost for this search only |
367
+ | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage-event and ranking updates for this successful read |
368
+ | `--include-sessions` | flag | `false` | Include session assets, which are excluded from default results via `config.search.defaultExcludeTypes` |
369
+ | `--format` | `json`, `jsonl`, `yaml`, `text`, `md`, `html` | `json` | Output format |
370
+ | `--detail` | `brief`, `normal`, `full` | `brief` | Output verbosity level |
371
+ | `--shape` | `human`, `agent`, `summary` | `human` | Output projection. `--shape summary` is valid **only on `akm show`**; passing it here is an `INVALID_SHAPE_VALUE` usage error (exit 2), like on every other command. |
372
+
373
+ `--filter` flags AND-join: every supplied key must match the entry's
374
+ `scope` for the entry to appear in the result set. Entries without any scope
375
+ are excluded as soon as a filter is supplied. With no `--filter` (the
376
+ default), unfiltered queries continue to surface all entries — including
377
+ legacy memories that pre-date the scope contract.
378
+
379
+ Local refs come from the index's canonical fully qualified `item_ref`; output
380
+ keeps the short form for the default bundle and qualifies non-default bundles.
381
+ Local paths are absolute materialized `file_path` values. Key fields by
382
+ availability:
383
+
384
+ - **`ref`** -- The asset handle to pass to `akm show` (for example
385
+ `team//scripts/deploy.sh`); present at `brief`, `full`, and `agent` for local
386
+ hits
387
+ - **`name`** -- The asset's filename or identifier; present at all levels
388
+ - **`origin`** -- The source bundle (e.g. `npm:@scope/pkg`), present only for
389
+ managed source assets; surfaced at `full` only
390
+ - **`id`** -- Registry-level identifier (registry hits only)
391
+
392
+ The default brief shape is intentionally small. The exact field set per
393
+ detail level (and per `--shape`) is authoritative in
394
+ `src/output/shapes/helpers.ts` (`shapeSearchHit` / `shapeSearchHitForAgent`),
395
+ assembled into the shape registry by the `src/output/shapes.ts` barrel:
396
+
397
+ | Level | Local bundle hits | Registry hits |
398
+ | --- | --- | --- |
399
+ | `brief` (default) | `type`, `name`, `ref`, `action`, `estimatedTokens` | `name`, `installRef`, `score` |
400
+ | `normal` | `type`, `name`, `description`, `action`, `score`, `estimatedTokens`, optional `warnings`/`quality`/`keys` | `name`, `description`, `action`, `installRef`, `score`, optional `warnings` |
401
+ | `full` | full hit object (includes `ref`, `origin`, `tags`, `whyMatched`, optional `warnings`, optional `quality`, timings, bundle metadata) | full hit object |
402
+ | `--shape agent` | `name`, `ref`, `type`, `path`, `editable`, conditional `editHint`, `description`, `action`, `score`, optional `estimatedTokens`/`keys` | no local access fields |
403
+
404
+ `--shape summary` is **not valid on `search`** — see
405
+ [`--shape summary`](#--shape-summary) above; it is a usage error (exit 2)
406
+ everywhere except `akm show`.
407
+
408
+ There is no registry `curated` boolean. Renderers surface an optional
409
+ `warnings: string[]` field on hits when a provider has non-fatal issues to
410
+ report; the field is omitted otherwise. Populating `warnings` does not affect
411
+ ranking.
412
+
413
+ > **Score ranges differ between local and registry hits.** Local
414
+ > `SearchHit.score` is a fixed contract value in `[0, 1]`, higher = better.
415
+ > Registry `RegistrySearchHit.score`
416
+ > is registry-native: provider-defined and may exceed `1` (the bundled
417
+ > `static-index` provider can emit values up to ~1.85 from `scoreStash()`).
418
+ > Use registry scores only for ranking within a single registry — do **not**
419
+ > compare them numerically against local `SearchHit.score` values or across
420
+ > registries with different scoring formulas. See
421
+ > `docs/architecture/architecture.md` for the current type-level distinction.
422
+
423
+ ### curate
424
+
425
+ Pick the assets worth loading for a task. Unlike `akm search`, curate reranks by
426
+ intent, attaches a preview and run details per hit, adds related support refs,
427
+ and summarizes the set — the usual starting point for an agent.
428
+
429
+ ```sh
430
+ akm curate "plan a release"
431
+ akm curate "deploy a Bun app" --limit 3
432
+ akm curate "review an architecture proposal" --type skill
433
+ akm curate "learn the release workflow" --from all --format text
434
+ ```
435
+
436
+ | Flag | Values | Default | Description |
437
+ | --- | --- | --- | --- |
438
+ | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter curated results by asset type |
439
+ | `--limit` | number | `4` | Maximum curated results |
440
+ | `--from` | `local`, `registry`, `all` | `local` | Where to search before curating |
441
+ | `--track-usage`, `--no-track-usage` | flag | `true` | Record or suppress local usage-event and ranking updates for this successful read |
442
+
443
+ `akm curate` selects a small relevance-first shortlist. It preserves the
444
+ strongest search hits first, uses only small type-aware nudges for close-score
445
+ ties, can collapse obvious root/reference families into one top-level result,
446
+ and falls back to token searches when the phrase result set is weak. Curate
447
+ includes direct follow-up commands such as `akm show <ref>` or `akm bundle add <ref>`
448
+ so you can immediately inspect or install what it found.
449
+ `--detail` and `--shape agent` both work on curate output; `--shape summary`
450
+ does not.
451
+ Agent-shaped local items include `ref`, `path`, and `editable`, plus `editHint`
452
+ only for read-only items. Their `followUp` remains `akm show <ref>` rather than
453
+ being replaced by clone guidance.
454
+ Use `--type workflow` when you want curated step-by-step procedures instead of
455
+ individual scripts, skills, or docs.
456
+ Use `--no-track-usage` when this inspection must not update local usage or
457
+ ranking signals.
458
+
459
+ ### show
460
+
461
+ Display an asset by ref. On a markdown document `#fragment` selects one
462
+ section by heading slug (falling back to case-insensitive heading text); an
463
+ unmatched fragment lists the available slugs.
464
+
465
+ Successful reads record local usage and ranking signals by default; pass
466
+ `--no-track-usage` to suppress those updates.
467
+
468
+ ```sh
469
+ akm show scripts/deploy.sh
470
+ akm show skills/code-review
471
+ akm show agents/architect
472
+ akm show commands/release
473
+ akm show workflows/ship-release
474
+ akm show knowledge/guide # the whole document
475
+ akm show knowledge/guide#authentication # just that section
476
+ akm show knowledge/guide#nope # lists the available fragment slugs
477
+
478
+ # Bundle .meta/ orientation docs — direct-read, not indexed:
479
+ akm show meta # working bundle's .meta/index.md
480
+ akm show meta:about # working bundle's .meta/about.md
481
+ akm show akm//meta # the primary bundle explicitly
482
+ akm show github:owner/repo//meta # an installed bundle's .meta/index.md
483
+
484
+ # Multi-tenant scope filtering:
485
+ akm show memories/retro --filter user=alice
486
+ akm show memories/retro --filter user=alice --filter agent=claude
487
+ ```
488
+
489
+ `meta` is not an asset type — `[<origin>//]meta[:<name>]` direct-reads a
490
+ human-authored orientation doc from a bundle's optional `.meta/` directory
491
+ (`<name>` defaults to `index`; `.meta/<name>.md` is tried before an
492
+ extensionless `.meta/<name>`). These files are never indexed, so they do not
493
+ appear in `akm search`. See [concepts.md](https://github.com/itlackey/akm/blob/main/docs/guides/concepts.md#bundle-orientation-the-meta-convention)
494
+ for the full convention.
495
+
496
+ `--filter` accepts the same `<key>=<value>` shape as `akm search --filter` — one
497
+ spelling for the scope-narrowing axis on both commands (`--scope` was removed
498
+ in 0.9.0)
499
+ (repeatable; valid keys: `user`, `agent`, `run`, `channel`). When supplied,
500
+ the resolved asset's frontmatter `scope_*` keys must match every supplied
501
+ filter. A mismatch (or absent scope) returns `NotFoundError` so the caller
502
+ cannot accidentally read out-of-scope content.
503
+
504
+ The default `show` JSON includes the asset body when applicable. Canonical
505
+ `ref` is always present, in every `--shape` (`human`, `agent`, and `summary`
506
+ alike) and at every `--detail` level. Absolute `path` and `editable` are
507
+ always present too, at every `--detail` level, in the `human` (default) and
508
+ `agent` shapes — `--shape summary` omits both, since it is a compact
509
+ capability-discovery view, not an edit-target view. None of `ref`/`path`/
510
+ `editable` are gated behind `--detail full`. Use `--detail brief` for a
511
+ reduced metadata-first view without `content`/`template`/`prompt`;
512
+ `--detail full` adds verbose extras such as `schemaVersion` and, when
513
+ `editable` is `false`, `editHint`; `--shape agent` strips non-action metadata
514
+ (e.g. `origin`, `tags`) down to the action-relevant field set while still
515
+ including `ref`/`path`/`editable`; `--shape summary`
516
+ returns a compact view with only `type`, `name`, `ref`, `description`, `tags`,
517
+ `parameters`, `workflowTitle`, `action`, `run`, `origin`, and `keys`.
518
+
519
+ Returns type-specific payloads:
520
+
521
+ | Type | Key fields |
522
+ | --- | --- |
523
+ | script | `run`, `setup`, `cwd` |
524
+ | skill | `content` (full SKILL.md) |
525
+ | command | `template`, `description` |
526
+ | agent | `prompt`, `description`, `modelHint` |
527
+ | knowledge | `content` — the whole document, or one section via `#fragment` |
528
+ | workflow | `workflowTitle`, `workflowParameters`, `steps` |
529
+ | memory | `content` |
530
+ | env | `keys` (key names only — values and comment text never returned) |
531
+ | lesson | `content` plus `when_to_use` surfaced from frontmatter |
532
+
533
+ `editable` means current AKM source policy authorizes direct in-place
534
+ modification of that exact path. It is computed from current source ownership
535
+ and effective `writable` policy, not persisted in the index; unknown paths fail
536
+ closed. `editHint` is present only when `editable` is `false`. `akm show` uses
537
+ the local index and materialized disk path, with no remote-provider fallback. If
538
+ the ref points to a package origin that is not installed, it returns guidance
539
+ to run `akm bundle add <origin>` first.
540
+
541
+ ### workflow
542
+
543
+ Author, inspect, and execute structured workflow assets.
544
+
545
+ ```sh
546
+ akm workflow create ship-release --print
547
+ akm workflow create ship-release
548
+ akm workflow create ship-release --from ./ship-release.md
549
+ akm workflow run workflows/ship-release --version 1.2.3
550
+ akm workflow run <run-id> # continue an active partial run
551
+ akm workflow status <run-id>
552
+ akm workflow status workflows/ship-release
553
+ akm workflow resume <run-id>
554
+ akm workflow abandon <run-id>
555
+ akm workflow list --active
556
+ ```
557
+
558
+ Bare `akm workflow` (no subcommand) is a usage error (exit 2), the canonical
559
+ bare-group behavior — name a subcommand.
560
+
561
+ Subcommands:
562
+
563
+ | Subcommand | Description |
564
+ | --- | --- |
565
+ | `create <name>` | Validate and write a unified markdown workflow under `workflows/`. `--path <dir>` places it in a subdirectory; `--from <file>` imports content; `--force` (requires `--from` or `--reset`) overwrites; `--print` prints the template that would be written instead of writing it |
566
+ | `run <run-id\|ref>` | Stable canonical start/resume/execute command. A ref starts a run or continues the active run in the current scope; a run id continues that exact active run. Executes until completion, failure, verification rejection, interruption, or an explicit limit |
567
+ | `status <run-id\|ref>` | Show the full run state, including all step statuses. `--units` also lists per-unit rows from the run journal (diagnostics only) |
568
+ | `list` | List workflow runs (optionally filtered by `--ref`; `--active` shows only `status=active` runs, excluding `blocked`/`failed`/`completed`) |
569
+ | `resume <run-id>` | Flip a `blocked` or `failed` run back to `active`. Completed runs cannot be resumed |
570
+ | `abandon <run-id>` | Mark a run failed so it stops counting as active (`resume` can reopen it) |
571
+
572
+ The public `workflow start`, `next`, and `complete` lifecycle was removed in
573
+ 0.9, along with the experimental `brief`/`report` external-driver protocol.
574
+ Use `workflow run` for execution and `workflow status` for inspection. The
575
+ removed commands fail with an `UNKNOWN_COMMAND` envelope and a migration hint;
576
+ there are no compatibility aliases.
577
+
578
+ There is also no `akm workflow template`, `validate`, or `watch`.
579
+ `workflow create --print` prints a starter, `akm lint --type workflows`
580
+ validates it, and `akm log --run <id> --since '@offset:<id>'` provides durable
581
+ event polling.
582
+
583
+ #### workflow run
584
+
585
+ ```sh
586
+ akm workflow run workflows/ship-release --version 1.2.3
587
+ akm workflow run workflows/review --files a.ts --files b.ts
588
+ akm workflow run <run-id> --max-steps 3
589
+ akm workflow run <run-id> --max-retries 2 --timeout 10m
590
+ ```
591
+
592
+ Parameter flags must follow the target and exactly match keys declared in the
593
+ workflow's `params` frontmatter. AKM coerces each value from the declared JSON
594
+ Schema before persisting the run:
595
+
596
+ - strings retain their exact spelling;
597
+ - numbers, integers, booleans, and `null` use their schema types;
598
+ - object values are JSON;
599
+ - array flags may be repeated (`--files a.ts --files b.ts`) or supplied once as
600
+ a JSON array.
601
+
602
+ A bare boolean flag means `true`. Hyphen/underscore aliases are not inferred:
603
+ declared `include_processes` requires `--include_processes`, not
604
+ `--include-processes`. Parameters can be supplied only when a new run is
605
+ created; a later invocation against an active run rejects parameter flags.
606
+ The old `--params <json>` bag is removed.
607
+
608
+ | Flag | Description |
609
+ | --- | --- |
610
+ | `--max-steps <n>` | Stop after executing at most this many steps, leaving a partial run active. Must be at least 1. |
611
+ | `--max-retries <n>` | When a step fails, reopen the same run and retry the failed step up to this many additional times. Range: 0 through 100; default 0. Gate rejection and interruption are not retried. |
612
+ | `--timeout <duration>` | Abort the whole invocation after `N`, `Nms`, `Ns`, or `Nm`; bare `N` is milliseconds. The active step remains resumable. |
613
+
614
+ The result includes the current `run`, an `executed` step report list, and
615
+ optional `done`, `gateRejection`, `aborted`, or `timedOut` markers. A failed
616
+ run, rejected verification gate, timeout, or interrupt exits nonzero. `SIGINT`
617
+ and `SIGTERM` map to 130 and 143; a timeout maps to exit 1. Reaching
618
+ `--max-steps` with an active resumable run is successful.
619
+
620
+ `run` is Stable and does not consult `experimental.workflowEngine`. Every
621
+ non-empty `### gate` requires `workflow.judgeEngine` to name a configured LLM
622
+ or agent engine before a new run can be frozen. Gate evaluation is fail-closed.
623
+
624
+ Workflow runs are scoped to the current working context, not globally across all
625
+ repos or directories. akm resolves that context from the nearest `.akm/config.json`
626
+ ancestor when present, otherwise the nearest git root, otherwise the bundle root
627
+ when the cwd is inside it, otherwise the cwd itself. In practice this means:
628
+
629
+ - `workflow run workflows/<name>` continues the active run for the current project/worktree/directory, or starts one when none is active.
630
+ - `workflow status workflows/<name>` resolves the most-recently-updated run in the current scope only.
631
+ - `workflow list` shows runs for the current scope only.
632
+ - Direct run-id commands like `workflow status <run-id>` still work even if the run was started from another directory.
633
+
634
+ #### workflow create
635
+
636
+ ```sh
637
+ akm workflow create ship-release
638
+ akm workflow create ship-release --from ./ship-release.md
639
+ akm workflow create ship-release --from ./ship-release.md --force
640
+ akm workflow create ship-release --force --reset
641
+ akm workflow create ship --path release # writes workflows/release/ship.md
642
+ ```
643
+
644
+ | Flag | Description |
645
+ | --- | --- |
646
+ | `--path <dir>` | Relative subdirectory under `workflows/` to place the workflow in. The filename comes from `<name>`. |
647
+ | `--from <file>` | Import and validate a unified markdown workflow from an existing file |
648
+ | `--force` | Overwrite an existing workflow. Requires `--from` or `--reset`. |
649
+ | `--reset` | Explicitly replace an existing workflow with a fresh template (use with `--force`) |
650
+ | `--print` | Print the unified markdown template without creating anything |
651
+
652
+ `--force` requires either `--from <file>` (replace from a source file) or
653
+ `--reset` (explicitly acknowledge you are overwriting in place). Without one of
654
+ these, `--force` is rejected to prevent silent template overwrites.
655
+
656
+ `<name>` itself must be **flat** — `^[a-z0-9][a-z0-9._/-]*$` after combining
657
+ with `--path`, but the bare `--name` positional is rejected if it contains a
658
+ `/`. Hierarchical placement (`release/ship`) goes through `--path release
659
+ --name ship`, the same convention every other `create` command
660
+ (`knowledge`, `env`, `secret`, …) uses — `akm workflow create release/ship`
661
+ directly is a usage error (exit 2).
662
+
663
+ **Snapshot isolation:** `workflow run` compiles and freezes the workflow plan
664
+ when it creates a run. Edits to the source workflow after that point do not
665
+ affect the in-flight run.
666
+
667
+ #### workflow status
668
+
669
+ ```sh
670
+ akm workflow status <run-id>
671
+ akm workflow status workflows/ship-release
672
+ akm workflow status <run-id> --units # also list per-unit rows from the run journal
673
+ ```
674
+
675
+ Accepts either a run-id or a workflow ref. When given a workflow ref, resolves
676
+ to the most-recently-updated run for that ref in the current working scope.
677
+ `--units` adds per-unit rows (unit id, status, failure reason, and any
678
+ result/error diagnostic text) from the run journal — diagnostics only; step
679
+ evidence stays deterministic and is unaffected.
680
+
681
+ #### workflow resume
682
+
683
+ ```sh
684
+ akm workflow resume <run-id>
685
+ ```
686
+
687
+ Flips a `blocked` or `failed` run back to `active`. Completed runs cannot be
688
+ resumed. Use `workflow list` to find runs by status.
689
+
690
+ Workflow markdown contract:
691
+
692
+ - Frontmatter carries the asset envelope and orchestration graph (`params`,
693
+ `steps`, `defaults`, and `budget`).
694
+ - Every `## <step-id>` heading must name a declared step exactly. Unit and map
695
+ steps require a section; route-only steps may omit one.
696
+ - An optional `### gate` inside a step section carries its gate rubric. Omitted
697
+ or empty rubric text skips validation.
698
+
699
+ See [Workflows](workflows.md) for the complete authoring contract.
700
+
701
+ ### How `bundle add` works
702
+
703
+ `akm bundle add` infers what to do from the input:
704
+
705
+ | Input | What happens |
706
+ | --- | --- |
707
+ | `akm bundle add ~/.claude/skills` | Registers a local directory as a `filesystem` source |
708
+ | `akm bundle add github:owner/repo` | Clones the repo into akm's cache as a `git` source |
709
+ | `akm bundle add @scope/pkg` | Installs the npm package as an `npm` source |
710
+ | `akm bundle add https://docs.example.com` | Crawls and caches a website as a `website` source |
711
+ | `akm registry add <url>` | Adds a discovery registry (separate concept) |
712
+
713
+ HTTP(S) URLs on known Git hosts, and URLs ending in `.git`, are treated as git
714
+ sources. Other HTTP(S) URLs are crawled as website sources.
715
+
716
+ ### bundle add
717
+
718
+ Add a source — a local directory, npm package, GitHub repo, git URL, or website.
719
+
720
+ ```sh
721
+ akm bundle add ~/.claude/skills # Local directory
722
+ akm bundle add @scope/pkg # npm package
723
+ akm bundle add npm:@scope/pkg@latest # npm with version
724
+ akm bundle add github:owner/repo#v1.2.3 # GitHub with tag
725
+ akm bundle add https://github.com/owner/repo
726
+ akm bundle add git+https://gitlab.com/org/bundle
727
+ akm bundle add ./path/to/local/bundle
728
+ akm bundle add github:andrewyng/context-hub --name context-hub # context-hub as a git bundle
729
+ akm bundle add https://docs.example.com --name docs
730
+ akm bundle add https://docs.example.com --max-pages 100 --max-depth 5
731
+ ```
732
+
733
+ | Flag | Description |
734
+ | --- | --- |
735
+ | `--name` | Human-friendly name for the source |
736
+ | `--provider` | Explicit provider for declarative source configuration; normally inferred from the input |
737
+ | `--writable` | Mark a git source as writable so `akm sync` also pushes (default: false) |
738
+ | `--options` | Provider options as JSON (e.g. `'{"ref":"main"}'`) |
739
+ | `--allow-insecure` | Bypass plain-HTTP source rejection **and** dangerous env key blocking. Accepts two risks: (1) plain-HTTP download without TLS, (2) env keys that can hijack process execution. Use only after reviewing the bundle manually |
740
+ | `--max-pages` | Maximum pages to crawl for website sources (default: 50) |
741
+ | `--max-depth` | Maximum crawl depth for website sources (default: 3) |
742
+
743
+ #### Dangerous env key audit
744
+
745
+ When `akm bundle add` installs a bundle that contains env files, it recursively scans
746
+ every `.env`-suffixed file under `env/` (the same "real env file" test used
747
+ everywhere else — a bare `.env` or any name ending `.env`, at any depth) for
748
+ environment variable names that can be used for process-execution hijacking. A
749
+ non-`.env` file under `env/` (e.g. `env/notes.txt`) is never scanned — such a
750
+ file is never sourced as environment variables by any akm codepath, so a
751
+ dangerous key sitting in its contents cannot hijack anything. The flagged key
752
+ set is 41 literal names plus 2 regex pattern families (`src/commands/lint/env-key-rules.ts`):
753
+ `LD_PRELOAD`, `LD_LIBRARY_PATH`, `LD_AUDIT`, `LD_DEBUG`, `LD_BIND_NOW`,
754
+ `LD_PROFILE`, `LD_ASSUME_KERNEL`, `LD_TRACE_LOADED_OBJECTS`,
755
+ `DYLD_INSERT_LIBRARIES`, `DYLD_LIBRARY_PATH`, `DYLD_FRAMEWORK_PATH`, `PATH`,
756
+ `BASH_ENV`, `ENV`, `PROMPT_COMMAND`, `PS1`, `PS2`, `IFS`, `ZDOTDIR`,
757
+ `NODE_OPTIONS`, `NODE_PATH`, `NODE_TLS_REJECT_UNAUTHORIZED`, `PYTHONSTARTUP`,
758
+ `PYTHONPATH`, `PYTHONINSPECT`, `PYTHONHOME`, `PYTHONNOUSERSITE`, `RUBYLIB`,
759
+ `RUBYOPT`, `PERL5LIB`, `PERL5OPT`, `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS`,
760
+ `_JAVA_OPTIONS`, `GIT_SSH_COMMAND`, `GIT_EXTERNAL_DIFF`, `GIT_PAGER`,
761
+ `GIT_EDITOR`, `EDITOR`, `VISUAL`, and `PAGER` (41 literals), plus any key
762
+ matching `^BASH_FUNC_` (Shellshock-class injection) or `^GIT_CONFIG_` (git
763
+ config override injection).
764
+
765
+ When dangerous keys are found, `akm bundle add` pauses and prompts for
766
+ confirmation (default: No). In non-interactive mode (CI, scripts) the
767
+ install fails with **exit 1** unless `--allow-insecure` is passed, and the
768
+ freshly-installed bundle is rolled back before the process exits.
769
+
770
+ ```sh
771
+ # Interactive: prompts before continuing
772
+ akm bundle add github:owner/repo-with-sensitive-env
773
+
774
+ # Non-interactive: fails unless bypassed
775
+ akm bundle add github:owner/repo-with-sensitive-env --allow-insecure
776
+ ```
777
+
778
+ Bundle publishers: see the [Stash Maker's Guide](https://github.com/itlackey/akm/blob/main/docs/guides/stash-makers.md#env-security)
779
+ for guidance on env files that legitimately need these keys.
780
+
781
+ #### Website sources
782
+
783
+ An HTTP(S) URL outside known Git hosts is treated as a website source. akm
784
+ crawls the site breadth-first from the given URL, converts each page to markdown,
785
+ and stores the results as knowledge assets with the URL path hierarchy preserved.
786
+
787
+ ```sh
788
+ akm bundle add https://www.agentic-patterns.com/ --name agent-patterns
789
+ akm bundle add https://docs.example.com/guide --name guide --max-pages 200
790
+ ```
791
+
792
+ Pages are cached locally and refreshed every 12 hours. The crawl stays within
793
+ the same origin (hostname) and skips static assets (images, CSS, JS, etc.).
794
+
795
+ Use `--max-pages` and `--max-depth` to control how many pages are fetched and
796
+ how many link levels deep the crawler goes. These values are persisted in your
797
+ config so subsequent re-indexes use the same limits.
798
+
799
+ See [registry.md](https://github.com/itlackey/akm/blob/main/docs/reference/registry.md) for the full install flow for managed sources.
800
+
801
+ > **Note:** there is no `akm bundle add context-hub` convenience alias or `akm
802
+ > enable`/`disable context-hub` command — add it explicitly as a git bundle:
803
+ > `akm bundle add github:andrewyng/context-hub --name context-hub`. A bundle *type*
804
+ > string of `"context-hub"` in an existing config still normalizes to
805
+ > `"git"` at load time, so you don't need to edit your config files.
806
+
807
+ ### bundle list
808
+
809
+ Show all sources — local directories, managed packages, and remote providers.
810
+
811
+ ```sh
812
+ akm bundle list # All sources
813
+ akm bundle list --kind filesystem # Only plain filesystem/local directory sources
814
+ akm bundle list --kind git # Only git sources
815
+ akm bundle list --kind npm # Only npm-managed sources
816
+ akm bundle list --kind website # Only crawled website sources
817
+ akm bundle list --kind filesystem,git # Multiple kinds (comma-separated)
818
+ ```
819
+
820
+ | Flag | Description |
821
+ | --- | --- |
822
+ | `--kind` | Filter by source provider: `filesystem`, `git`, `npm`, `website` (comma-separated). Any other value is a usage error (exit 2) — there is no `local`/`managed`/`remote` grouping. |
823
+
824
+ ### bundle remove
825
+
826
+ Remove a source by id, ref, path, URL, or name and reindex.
827
+
828
+ ```sh
829
+ akm bundle remove npm:@scope/pkg # Managed source by id
830
+ akm bundle remove owner/repo # Managed source by ref
831
+ akm bundle remove ~/.claude/skills # Local source by path
832
+ akm bundle remove my-provider # Any source by name
833
+ akm bundle remove my-provider --yes # Skip the confirmation prompt
834
+ ```
835
+
836
+ | Flag | Description |
837
+ | --- | --- |
838
+ | `-y`, `--yes` | Skip the confirmation prompt |
839
+
840
+ ### bundle update
841
+
842
+ Update one or all managed sources to the latest available version. Local and
843
+ remote sources are not updatable — akm explains why if you target one.
844
+
845
+ ```sh
846
+ akm bundle update npm:@scope/pkg
847
+ akm bundle update --all
848
+ akm bundle update --all --force # Force fresh download even if version is unchanged
849
+ akm bundle update --all --yes # Skip confirmation when an update needs to delete a moved install dir
850
+ ```
851
+
852
+ | Flag | Description |
853
+ | --- | --- |
854
+ | `--all` | Update all managed sources |
855
+ | `--force` | Delete cached extraction before re-downloading |
856
+ | `-y`, `--yes` | Skip the confirmation prompt for the rare branch where the resolved content location moved and the previous install directory must be deleted. No effect on a normal refresh, which deletes nothing. |
857
+
858
+ Reports per-entry change flags: `changed.version`, `changed.revision`,
859
+ `changed.any`.
860
+
861
+ ### upgrade
862
+
863
+ Upgrade `akm` itself to the latest release. Standalone binaries are downloaded,
864
+ checksummed, and staged before replacement; npm, Bun, and pnpm global installs
865
+ use their package manager.
866
+
867
+ For contract-capable releases, upgrade treats migration and indexing as
868
+ separate steps. It runs migration preflight before installation, migration apply
869
+ after installation, and rebuilds the derived index only after migration
870
+ succeeds. Standalone upgrades retain the previous binary until migration apply
871
+ completes. If apply fails, the new binary stays installed and the previous binary
872
+ remains beside it for operator recovery; the executable is never rolled back
873
+ independently of durable state.
874
+
875
+ A binary that predates the `migrate` command and `--migration-config` cannot
876
+ enforce guards implemented in a release that is not installed yet, so
877
+ self-update cannot safely cross that boundary; install or stage the new
878
+ binary manually instead and run its `akm migrate apply` command. See
879
+ [docs/migration/](../migration/) for version-specific upgrade guides.
880
+
881
+ For contract-capable upgrades, the old/current binary's preflight inspects only its
882
+ current artifact state and never parses the future prepared config. The prepared
883
+ config is then checked by the staged standalone binary's `migrate status` before
884
+ replacement and passed to the newly installed binary's apply command. A failed
885
+ staged preflight removes the stage and leaves the old executable untouched.
886
+
887
+ Standalone downloads are streamed directly to the staged file while SHA-256 is
888
+ computed, with a 256 MiB binary limit. Release/checksum metadata is capped at
889
+ 1 MiB; an oversized response is cancelled and the staged file is removed.
890
+
891
+ ```sh
892
+ akm upgrade # Download and replace the running binary
893
+ akm upgrade --check # Check for updates without installing
894
+ akm upgrade --force # Force upgrade even if already on latest
895
+ akm upgrade --migration-config ./prepared-config.json # Contract-capable releases only
896
+ ```
897
+
898
+ | Flag | Description |
899
+ | --- | --- |
900
+ | `--check` | Check for updates without installing |
901
+ | `--force` | Force upgrade even if on latest version |
902
+ | `--skip-post-upgrade` | Skip only the post-migration index rebuild; migration preflight and apply still run |
903
+ | `--migration-config` | On contract-capable upgrades, operator-prepared config passed only to the new binary's migration apply; not a path for crossing from a pre-`migrate` binary |
904
+
905
+ Checksum verification is not optional and has no flag. If a release's
906
+ `checksums.txt` is genuinely unreachable, the recovery hatch is the
907
+ `AKM_UPGRADE_SKIP_CHECKSUM=1` environment variable (Internal — deliberately
908
+ not a discoverable, tab-completable flag). See STABILITY.md.
909
+
910
+ ### clone
911
+
912
+ Copy an asset from any source into a managed writable bundle or an unmanaged
913
+ custom destination for editing.
914
+
915
+ ```sh
916
+ akm clone scripts/deploy.sh
917
+ akm clone "npm:@scope/pkg//scripts/deploy.sh"
918
+ akm clone scripts/deploy.sh --name my-deploy.sh
919
+ akm clone scripts/deploy.sh --force
920
+ akm clone scripts/deploy.sh --bundle team-bundle
921
+ akm clone scripts/deploy.sh --dest ./project/.claude
922
+ akm clone "npm:@scope/pkg//scripts/deploy.sh" --dest /tmp/preview
923
+ ```
924
+
925
+ | Flag | Description |
926
+ | --- | --- |
927
+ | `--name` | New name for the cloned asset |
928
+ | `--force` | Overwrite if the asset already exists at the destination |
929
+ | `--bundle <name>` | Managed destination bundle. When omitted, clone falls back to `defaultWriteTarget`, then the working bundle |
930
+ | `--dest <path>` | Unmanaged destination directory. Bypasses managed target resolution and cannot be combined with `--bundle`; the type subdirectory is appended automatically |
931
+
932
+ Skills (directories) are copied recursively. Other types copy a single file.
933
+
934
+ **Remote clone:** When the origin in the ref points to a package that is not
935
+ installed locally (e.g. an npm package or local path not in your bundle
936
+ sources), akm fetches it to the cache automatically and extracts the
937
+ requested asset. The package is **not** registered as a managed source --
938
+ use `akm bundle add` for that.
939
+
940
+ ```sh
941
+ # Clone a single script from a remote package without installing the full bundle
942
+ akm clone "npm:@scope/pkg//scripts/deploy.sh"
943
+
944
+ # Clone from a local directory that isn't configured as a search path
945
+ akm clone "/path/to/bundle//skills/code-review" --dest ./project/.claude
946
+ ```
947
+
948
+ Without `--dest`, clone uses normal write-target resolution: explicit
949
+ `--bundle` -> `defaultWriteTarget` -> working bundle. Managed clones use the
950
+ destination bundle's canonical ref and are indexed immediately. When `--dest`
951
+ is provided, no managed write target is required, which keeps clone usable in
952
+ CI or fresh environments without running `akm setup` first.
953
+
954
+ ### sync
955
+
956
+ Stage and commit local changes in a git-backed bundle. If the bundle has a
957
+ remote configured and is marked `writable: true`, the commit is also pushed.
958
+
959
+ > **Note:** there is no `akm save` command — use `akm sync`.
960
+
961
+ ```sh
962
+ akm sync # Sync primary bundle (auto timestamp message)
963
+ akm sync -m "Add deploy skill" # Sync with custom message
964
+ akm sync --no-push # Commit only; never push even when writable
965
+ akm sync --format json # Explicit format (both --format json and --format=json work)
966
+ akm sync my-skills # Sync a named writable git bundle
967
+ akm sync team/core -m "Update" # Slash-containing source names are valid selectors
968
+ akm sync my-skills -m "Update" # Sync named bundle with message
969
+ ```
970
+
971
+ | Argument / Flag | Description |
972
+ | --- | --- |
973
+ | `[name]` | Optional git-backed bundle selector. Matches the configured source name exactly and also accepts canonical GitHub aliases such as `owner/repo`, `github:owner/repo`, and branch-ref forms like `github:owner/repo#branch`. Forward slashes are allowed. Defaults to the primary bundle |
974
+ | `-m`, `--message` | Commit message. Defaults to `akm save <timestamp>` |
975
+ | `--no-push` | Commit only; never push even when the bundle is writable with a remote configured |
976
+ | `--format` | Output format (any of the six global values). Both `--format json` and `--format=json` are accepted |
977
+
978
+ If no positional selector is provided, `akm sync --format json` still targets
979
+ the primary bundle. If a positional selector is provided, it wins even when the
980
+ value also looks like a format token.
981
+
982
+ **Behaviour by repo state:**
983
+
984
+ | State | Result |
985
+ | --- | --- |
986
+ | Not a git repo | Exit 0, `skipped: true` in JSON output — no error |
987
+ | Git repo, no remote | Stage and commit only |
988
+ | Git repo, has remote, not writable | Stage and commit only |
989
+ | Git repo, has remote, `writable: true` | Stage, commit, and push |
990
+ | Any writable repo with `--no-push` | Stage and commit only (push suppressed) |
991
+
992
+ **Primary bundle writable config:**
993
+
994
+ To make the primary bundle push on sync, set `writable: true` on its `bundles`
995
+ entry in your config file (`~/.config/akm/config.json` or the path shown by
996
+ `akm config path`):
997
+
998
+ ```json
999
+ {
1000
+ "bundles": { "primary": { "path": "~/akm", "writable": true } },
1001
+ "defaultBundle": "primary"
1002
+ }
1003
+ ```
1004
+
1005
+ When `writable: true` is set and the primary bundle has a git remote configured,
1006
+ `akm sync` will stage, commit, and push.
1007
+
1008
+ When `akm setup` successfully initializes the default bundle as a local git repo
1009
+ (requires `git` to be installed), `akm sync` will commit there safely without
1010
+ pushing. If git is unavailable, the bundle will not be a git repo and sync will
1011
+ return a skipped result.
1012
+
1013
+ To make a named remote git bundle writable, pass `--writable` when adding it:
1014
+
1015
+ ```sh
1016
+ akm bundle add git@github.com:org/skills.git --provider git --name my-skills --writable
1017
+ ```
1018
+
1019
+ ### remember
1020
+
1021
+ Record a memory. This writes a markdown file into `memories/` in the configured
1022
+ write target and returns the resulting ref.
1023
+
1024
+ **Write target resolution:** the destination is the working bundle
1025
+ (`defaultBundle`) unless `defaultWriteTarget` is set in config, which
1026
+ overrides it to a named source. An explicit `--bundle <name>` flag overrides
1027
+ both. The full order is `--bundle` → `defaultWriteTarget` → working bundle →
1028
+ `ConfigError`. See [Configuration](configuration.md#bundles-and-write-target) for
1029
+ details.
1030
+
1031
+ A bundle-qualified mutation ref implies that bundle. In particular, a
1032
+ qualified `--supersedes team//memories/old` routes the correction and demotion
1033
+ to `team`; a different explicit `--bundle` is a usage error. Qualified `--xref`
1034
+ values only identify the cited copy and do not select the write target.
1035
+
1036
+ ```sh
1037
+ akm remember "Deployment needs VPN access"
1038
+ akm remember --name release-retro < notes.md
1039
+ akm remember "Pair with ops before rotating prod secrets" --name ops/prod-secrets
1040
+
1041
+ # With structured frontmatter:
1042
+ akm remember "VPN required for staging deploys" \
1043
+ --tag ops --tag networking \
1044
+ --expires 90d \
1045
+ --source "skills/deploy"
1046
+
1047
+ # Opt-in heuristic tagging — derives `code`, `source`, `observed_at`, `subjective`:
1048
+ akm remember "Found this snippet: \`curl -fsSL ... | bash\`" --tag ops --auto
1049
+
1050
+ # Opt-in LLM enrichment (requires configured LLM endpoint; fails soft):
1051
+ akm remember "Long meeting notes..." --enrich
1052
+
1053
+ # Multi-tenant / multi-agent scope:
1054
+ akm remember "Use staging cluster for blue-green" \
1055
+ --user alice --agent claude --run run-42 --channel "#ops"
1056
+
1057
+ # Cite provenance / related assets in frontmatter `xrefs:` (validated at write time):
1058
+ akm remember "The token rotation quirk applies to staging too" \
1059
+ --xref knowledge/auth/vendor-x-token-api \
1060
+ --xref memories/projectA/token-quirk
1061
+
1062
+ # Correct an existing memory: write the fix AND demote the stale incumbent
1063
+ # (beliefState: superseded + supersededBy on the old asset, in one step):
1064
+ akm remember "Staging now uses the new gateway endpoint" \
1065
+ --name new-endpoint --supersedes memories/projectA/old-endpoint
1066
+
1067
+ # Route the write to a specific writable bundle:
1068
+ akm remember "Deployment needs VPN access" --bundle team-bundle
1069
+ ```
1070
+
1071
+ | Flag | Description |
1072
+ | --- | --- |
1073
+ | `--name` | Optional memory name. Defaults to a slug derived from the content |
1074
+ | `--force` | Overwrite an existing memory with the same name |
1075
+ | `--description <text>` | Short description written to frontmatter (persisted as the memory's `description` field). Honoured by both the zero-flag form and the tagged form. |
1076
+ | `--tag <v>` | Tag to attach to the memory. Repeatable: `--tag foo --tag bar` |
1077
+ | `--expires <dur>` | Expiry shorthand (`30d`, `12h`, `6m`). Resolved to an ISO date |
1078
+ | `--source <s>` | Free-form source reference — URL, asset ref, file path, or any string |
1079
+ | `--xref <ref>` | Cross-reference ref recorded in the memory's `xrefs:` frontmatter list. Repeatable: `--xref knowledge/auth-flow --xref memories/vpn-note`. Each ref must resolve in the write target or a configured source (read-only sources count); an unresolvable ref fails with exit 2 before anything is written. More than 5 refs warns (soft cap) but still writes. Does not trigger the tags-required check. |
1080
+ | `--supersedes <ref>` | Ref of an existing asset this memory corrects. Repeatable. Writes the correction with the old ref folded into its `xrefs:` (correction provenance) AND demotes the old asset — `beliefState: superseded` + `supersededBy: [<new ref>]`, a metadata-only frontmatter edit that preserves every other key and the body — then reindexes it so ranking prefers the correction and `--belief current` hides the stale version immediately. An unresolvable ref fails with exit 2 before anything is written or demoted; so does a ref naming the asset being written itself (a correction cannot supersede itself, e.g. `--force` overwriting the same name). A ref that resolves only outside the write target and the working bundle still writes the correction but skips the demotion: stderr warns and the JSON output reports `superseded: [{ref, applied: false, reason}]` — the reason names the `--bundle` remedy when the old asset lives in a configured writable source. An old asset whose existing frontmatter is not parseable YAML is skipped the same way (`applied: false`) instead of being rewritten lossily. Re-running the same correction is idempotent. On a git write target the correction and the demoted old asset land in the same single boundary commit. |
1081
+ | `--auto` | Apply heuristic tagging from the body (opt-in, zero-latency, pure TS) |
1082
+ | `--enrich` | Call the configured LLM for tag/description proposals (opt-in, 10s timeout, fails soft) |
1083
+ | `--user <id>` | Scope this memory to a user id. Persisted as the canonical `scope_user` frontmatter key. |
1084
+ | `--agent <id>` | Scope this memory to an agent id. Persisted as `scope_agent`. |
1085
+ | `--run <id>` | Scope this memory to a run id. Persisted as `scope_run`. |
1086
+ | `--channel <name>` | Scope this memory to a channel name. Persisted as `scope_channel`. |
1087
+ | `--bundle <name>` | Override the write destination. Accepts a source name from your config; falls back to `defaultWriteTarget` then the working bundle. |
1088
+
1089
+ Pass the content as a quoted positional argument for short notes, or pipe
1090
+ markdown into stdin for longer memories.
1091
+
1092
+ **Zero-flag form** (`akm remember "body"`) writes a bare memory with no
1093
+ frontmatter — existing agent scripts keep working unchanged. `--tag` /
1094
+ `--expires` / `--source` still trigger the required-field check: if `tags`
1095
+ cannot be derived, the command rejects *before* writing the file, so you
1096
+ never end up with an orphan. `--auto` and `--enrich` are fail-soft metadata
1097
+ helpers: if they derive nothing, the memory still writes successfully.
1098
+
1099
+ **Scope flags** (`--user`, `--agent`, `--run`, `--channel`) are independent
1100
+ of the tag-required check. They write the four canonical top-level
1101
+ frontmatter keys (`scope_user`, `scope_agent`, `scope_run`, `scope_channel`)
1102
+ and a memory with only scope flags is valid (no tags required). Scope is the
1103
+ multi-tenant / multi-agent contract; the same shape is read back by
1104
+ `akm search --filter` and `akm show --filter`.
1105
+
1106
+ **Cross-references** (`--xref`) implement the bundle back-linking conventions'
1107
+ provenance channel: the refs land in the memory's `xrefs:` frontmatter list,
1108
+ which the indexer folds into the asset's search hints, so the new memory is
1109
+ findable from searches for its source. Refs are validated before anything is
1110
+ written — against the write target plus every configured source, including
1111
+ read-only cross-bundle sources — so a typo'd ref fails fast (exit 2) instead
1112
+ of becoming permanent silent noise. When a write lands at the type root (no
1113
+ `--path`, flat name) in a bundle that carries convention facts, the JSON output
1114
+ includes an additive `hint` key pointing at the bundle's placement conventions.
1115
+
1116
+ **Corrections** (`--supersedes`) implement the conventions' two-write
1117
+ corrections pattern in one command: the new asset is written with an xref to
1118
+ what it corrects, and the old asset gets a metadata-only demotion
1119
+ (`beliefState: superseded` + `supersededBy: [<new ref>]`) that the write path
1120
+ reindexes immediately. A qualified superseded ref selects that bundle as the
1121
+ write target. Same-bundle frontmatter edges remain short; cross-bundle edges stay
1122
+ qualified. The old asset is demoted only when it lives in the
1123
+ write target or the working bundle — a match in any other configured source
1124
+ (read-only, or writable but not this write's target) is reported as
1125
+ `applied: false` (with a stderr warning) while the correction still writes;
1126
+ so is an old asset whose existing frontmatter is not parseable YAML, which a
1127
+ demotion rewrite would corrupt. Validation happens before any write, so a
1128
+ typo'd ref, or a ref naming the asset being written itself (exit 2), leaves
1129
+ both assets untouched — no partial correction.
1130
+
1131
+ ### import
1132
+
1133
+ Import a knowledge document. This writes a markdown file into `knowledge/` in
1134
+ the configured write target and returns the resulting ref. The source may be a
1135
+ file path, a single HTTP/HTTPS URL, or `-` for stdin.
1136
+
1137
+ **Write target resolution:** the destination is the working bundle
1138
+ (`defaultBundle`) unless `defaultWriteTarget` is set in config, which
1139
+ overrides it to a named source. An explicit `--target <name>` flag overrides
1140
+ both. The full order is `--target` → `defaultWriteTarget` → working bundle →
1141
+ `ConfigError`. See [Configuration](configuration.md#bundles-and-write-target) for
1142
+ details.
1143
+
1144
+ ```sh
1145
+ akm import ./docs/auth-flow.md
1146
+ akm import ./notes/release.txt --name release-checklist
1147
+ akm import - --name scratch-notes < notes.md
1148
+ akm import https://example.com/docs/auth
1149
+
1150
+ # Cite provenance in the document's frontmatter `xrefs:` (validated at write time):
1151
+ akm import ./notes/oauth-quirks.md --xref knowledge/auth/vendor-x-token-api
1152
+
1153
+ # Import a corrected doc AND demote the one it replaces (in one step):
1154
+ akm import ./notes/modern-guide.md --supersedes knowledge/legacy-guide
1155
+
1156
+ # Route the write to a specific writable bundle:
1157
+ akm import ./docs/auth-flow.md --target team-bundle
1158
+ ```
1159
+
1160
+ | Flag | Description |
1161
+ | --- | --- |
1162
+ | `--name` | Optional knowledge name. Defaults to the source filename, URL path, or a slug from stdin content |
1163
+ | `--force` | Overwrite an existing knowledge document with the same name |
1164
+ | `--target <name>` | Override the write destination. Accepts a source name from your config; falls back to `defaultWriteTarget` then the working bundle. |
1165
+ | `--xref <ref>` | Cross-reference ref merged into the document's `xrefs:` frontmatter list. Repeatable. A document without frontmatter gains a block; a document with valid frontmatter keeps every existing key and value and gets the refs dedupe-appended (never a nested second block). Each ref must resolve in the write target or a configured source; an unresolvable ref fails with exit 2 before anything is written. If the document's existing frontmatter is not a parseable YAML mapping, the import fails (exit 2) rather than rewriting the block lossily — fix the frontmatter or import without `--xref`, which preserves the file verbatim. |
1166
+ | `--supersedes <ref>` | Ref of an existing asset this document corrects. Repeatable. Imports the correction with the old ref merged into its `xrefs:` AND demotes the old asset (`beliefState: superseded` + `supersededBy: [<new ref>]`, a metadata-only frontmatter edit), then reindexes it. Same validation (including the self-supersede rejection), skipped-demotion (`applied: false`), idempotence, and git-boundary-commit behaviour as on `remember` (see above). |
1167
+
1168
+ URL imports fetch only the exact page you pass, convert it to markdown, and do
1169
+ not register a persistent website source. The default knowledge name comes from
1170
+ the URL path (for example, `/docs/auth` -> `knowledge/docs/auth.md`).
1171
+
1172
+ The source must be a readable file path, a reachable HTTP/HTTPS URL, or `-` to
1173
+ read the document from stdin.
1174
+
1175
+ `--xref` behaves as on `remember` (validated refs, soft ~5 cap, additive
1176
+ `hint` output key on type-root writes), with one import-specific rule: because
1177
+ imported documents may already carry frontmatter, the refs are **merged** —
1178
+ existing keys are preserved and the `xrefs:` list is dedupe-appended, so the
1179
+ result always has exactly one frontmatter block. The merge requires the
1180
+ existing block to parse as a YAML mapping; a malformed block aborts the import
1181
+ (exit 2, nothing written) instead of silently flattening the values the parser
1182
+ could not read. Importing the same document *without* `--xref` always
1183
+ preserves it byte-for-byte.
1184
+
1185
+ ### feedback
1186
+
1187
+ Record positive or negative feedback for any indexed bundle asset. Feedback
1188
+ influences utility scores during the next index run, causing highly-rated
1189
+ assets to rank higher in search results over time.
1190
+
1191
+ ```sh
1192
+ akm feedback scripts/deploy.sh --positive
1193
+ akm feedback agents/reviewer --negative
1194
+ akm feedback memories/deployment-notes --positive
1195
+ akm feedback env/prod --positive
1196
+ akm feedback skills/code-review --positive --reason "Worked perfectly for PR reviews"
1197
+ akm feedback skills/code-review --negative --failure-mode outdated --reason "references a removed flag"
1198
+ akm feedback skills/code-review --negative --reason "flaky" --tag slice:train --tag team:platform
1199
+ ```
1200
+
1201
+ | Flag | Description |
1202
+ | --- | --- |
1203
+ | `--positive` | Record positive feedback (use when an asset was helpful) |
1204
+ | `--negative` | Record negative feedback (use when an asset was not useful) |
1205
+ | `--reason` | Optional text reason to attach to the feedback event (required for negative feedback by default) |
1206
+ | `--failure-mode` | Structured failure-mode taxonomy for negative feedback: `incorrect`, `outdated`, `dangerous`, `incomplete`, `redundant`. Stored alongside `--reason` in event metadata for the distill pipeline. |
1207
+ | `--tag` | Tag to attach to the feedback (repeatable, e.g. `--tag slice:train --tag team:platform`) |
1208
+ | `--applied-to <ref>` | Credit a `lessons/<name>` lesson that helped resolve this task. When combined with `--positive`, appends this feedback ref to the target lesson's `lessonStrength[]` frontmatter array (dedup, idempotent). A non-lesson target, or a missing `--positive`, produces a warning rather than silently doing nothing. |
1209
+
1210
+ Specify exactly one of `--positive` or `--negative`. The ref must already be
1211
+ present in the current local index.
1212
+
1213
+ The `--applied-to` flag drives the lesson-strength ranking signal: lessons that
1214
+ have demonstrably helped resolve tasks receive a small additive ranking boost
1215
+ (capped at +0.3) so they float to the top of search.
1216
+
1217
+ ### log
1218
+
1219
+ Append-only realtime events stream (#204). Every mutating CLI verb appends an
1220
+ event row to `<dataDir>/state.db`; `akm log` reads it.
1221
+
1222
+ > **Note:** there is no `akm events` command, and no `akm history` command —
1223
+ > use `akm log`. There is no `akm log tail` either (0.9.0: dropped — a
1224
+ > foreground polling daemon in a one-shot CLI); poll `--since
1225
+ > '@offset:<id>'` from a cooperating process instead.
1226
+
1227
+ ```sh
1228
+ akm log # All events, oldest first
1229
+ akm log --type feedback # Filter by event type
1230
+ akm log --ref skills/deploy # Filter by asset ref
1231
+ akm log --since 2026-04-01T00:00:00Z # ISO timestamp
1232
+ akm log --since '@offset:12345' # Resume from a row-id cursor
1233
+ akm log --limit 20 # Only the 20 most recent events (unlimited by default)
1234
+ akm log --run <run-id> # Only events for one workflow run
1235
+ ```
1236
+
1237
+ | Flag | Description |
1238
+ | --- | --- |
1239
+ | `--since` | Lower bound. Accepts ISO 8601, epoch ms, or `@offset:<id>` for a durable row-id cursor that survives across processes. |
1240
+ | `--type` | Filter by event type. Common values include `add`, `remove`, `update`, `remember`, `import`, `sync`, `feedback`, `promoted`, `rejected`, `propose_invoked`, `reflect_invoked`, `distill_invoked`, `select`, and `improve_skipped`. `sync` and the legacy `save` are synonyms on read, so `--type save` still returns rows written before the 0.9.0 rename as well as new ones. |
1241
+ | `--ref` | Filter by asset ref (`[bundle//]conceptId`). |
1242
+ | `--run` | Filter to one workflow run's events (`metadata.runId`) — the replacement for the dropped `akm workflow watch <run-id>`. Poll with `--since '@offset:<id>'` for a live tail; there is no daemon. |
1243
+ | `--limit` | Return only the most recent N events matching every other filter. Default: unlimited. |
1244
+ | `--include-tags` | Only include events with ALL these tags (repeatable). |
1245
+ | `--exclude-tags` | Exclude events matching these tags (repeatable). |
1246
+
1247
+ The envelope echoes a `nextOffset` row-id cursor — persist it and pass it
1248
+ back as `--since '@offset:<nextOffset>'` to resume from exactly where you
1249
+ stopped, with no duplicates and no losses, even across process boundaries
1250
+ (poll on an interval from a cooperating process if you need to follow the
1251
+ stream live).
1252
+
1253
+ #### Environment isolation
1254
+
1255
+ The events stream lives in `<dataDir>/state.db`, where `<dataDir>` is derived
1256
+ from `XDG_DATA_HOME` (or `AKM_DATA_DIR`) at the time of each call. Two
1257
+ processes with different inherited data-dir env values write to different
1258
+ databases; if the events stream is being used as a shared bus between
1259
+ cooperating processes, set those env vars consistently across them.
1260
+
1261
+ ### registry
1262
+
1263
+ Manage bundle registries. The `registry` command has three subcommands: `list`,
1264
+ `add`, and `remove`. Searching registries is `akm search --from registry`
1265
+ (0.9.0: `registry search` was dropped in favor of it — see [search](#search)).
1266
+
1267
+ Building a registry index is maintainer tooling, not a CLI command — see
1268
+ `bun scripts/build-registry-index.ts` in the akm repository.
1269
+
1270
+ #### registry list
1271
+
1272
+ List all configured registries and their status.
1273
+
1274
+ ```sh
1275
+ akm registry list
1276
+ ```
1277
+
1278
+ #### registry add
1279
+
1280
+ Add a third-party registry by URL.
1281
+
1282
+ ```sh
1283
+ akm registry add https://example.com/registry/index.json
1284
+ akm registry add https://example.com/registry/index.json --name my-team
1285
+ akm registry add https://skills.sh --name skills.sh --provider skills-sh
1286
+ ```
1287
+
1288
+ | Flag | Description |
1289
+ | --- | --- |
1290
+ | `--name` | Human-friendly label for the registry |
1291
+ | `--provider` | Provider type (e.g. `static-index`, `skills-sh`). Default: `static-index` |
1292
+ | `--options` | Provider-specific options as JSON (e.g. `'{"apiKey":"key"}'`) |
1293
+ | `--allow-insecure` | Allow a plain HTTP registry URL (rejected by default) |
1294
+
1295
+ Duplicate URLs are rejected.
1296
+
1297
+ #### registry remove
1298
+
1299
+ Remove a registry by URL or name.
1300
+
1301
+ ```sh
1302
+ akm registry remove https://example.com/registry/index.json
1303
+ akm registry remove my-team
1304
+ akm registry remove my-team --yes # Skip the confirmation prompt
1305
+ ```
1306
+
1307
+ | Flag | Description |
1308
+ | --- | --- |
1309
+ | `-y`, `--yes` | Skip confirmation prompt |
1310
+
1311
+ ### migrate
1312
+
1313
+ Inspect or apply config and durable database (`state.db`) migration as one
1314
+ installation lifecycle. Status and dry-run are read-only and exit nonzero when
1315
+ newer, inconsistent, corrupt, or unresolved config state blocks apply.
1316
+
1317
+ ```sh
1318
+ akm migrate status
1319
+ akm migrate status --config ./prepared-config.json
1320
+ akm migrate apply --config ./prepared-config.json --dry-run
1321
+ akm migrate apply --config ./prepared-config.json
1322
+ ```
1323
+
1324
+ `--config` is required when the active config is legacy or absent. When the
1325
+ active config is current, apply safely uses it as the target. Apply is
1326
+ idempotent and creates a semantically verified recovery run before changing any
1327
+ artifact. One phase-free incomplete sentinel makes a killed apply replayable;
1328
+ while apply or restore is incomplete, ordinary canonical config/database access
1329
+ fails closed. Apply refuses before backup when managed handles, maintenance
1330
+ activities, mutation locks, or workflow claims are live.
1331
+
1332
+ ### config
1333
+
1334
+ Read and write configuration. Bare `akm config` (no subcommand) is a usage
1335
+ error (exit 2), the canonical bare-group behavior — name a subcommand.
1336
+
1337
+ ```sh
1338
+ akm config list # List current config
1339
+ akm config get output.format # Read one key
1340
+ akm config set output.detail full # Set one key
1341
+ akm config set output.detail full --silent # Set without the post-write config dump on stdout
1342
+ akm config unset llm # Remove an optional key
1343
+ akm config path # Print path to config file
1344
+ akm config path --all # Print all config-related paths
1345
+ ```
1346
+
1347
+ Subcommands:
1348
+
1349
+ | Subcommand | Description |
1350
+ | --- | --- |
1351
+ | `get <key>` | Read one config key |
1352
+ | `list` | List current configuration |
1353
+ | `set <key> <value>` | Set one config key |
1354
+ | `unset <key>` | Unset an optional key, or a whole `embedding`/engine section |
1355
+ | `path` | Show paths to config, bundle, cache, and index. `--all` prints every path; without it, just the config path. Load-bearing: `config path` is the one subcommand the CLI still allows to run when the on-disk config itself fails to load, so you always have a way to locate a broken config. |
1356
+
1357
+ `set` and `unset` accept `--silent` to suppress the post-write config dump on
1358
+ stdout (the write still happens and errors still print) — use it from hooks
1359
+ and CI scripts.
1360
+
1361
+ > **Removed in 0.9.0:** `akm config enable`/`akm config disable`. Use
1362
+ > `akm registry add|remove` to toggle a registry, the general mechanism.
1363
+ > `akm config show` (an alias of `list`) and `akm config validate` (load-time
1364
+ > schema checks already reject an invalid config) were also removed.
1365
+
1366
+ See [configuration.md](configuration.md) for details.
1367
+
1368
+ ### help
1369
+
1370
+ Print the sectioned command overview, detailed help for any command, agent
1371
+ usage instructions, or a release's migration guidance.
1372
+
1373
+ ```sh
1374
+ akm help # Sectioned command overview (same as `akm --help`)
1375
+ akm help bundle # Detailed options and subcommands for `bundle`
1376
+ akm help env # Detailed options and subcommands for `env`
1377
+ akm help agents # Agent-facing usage instructions
1378
+ akm help migrate 0.6.0 # Notes for a specific release
1379
+ akm help migrate v0.6.0 # v-prefix accepted
1380
+ akm help migrate v0.6.0-rc1 # Prereleases normalize to the stable note
1381
+ akm help migrate latest # Resolve against the most recent CHANGELOG entry
1382
+ ```
1383
+
1384
+ `akm help <command>` is equivalent to `akm <command> --help`. Bare `akm help`
1385
+ prints the same sectioned overview as `akm --help` and exits
1386
+ `0` — this is the one group where a bare invocation is a complete request,
1387
+ not the canonical bare-group usage error.
1388
+
1389
+ Migration notes live as one markdown file per release in
1390
+ [`docs/migration/release-notes/`](../migration/release-notes/). Adding notes for a
1391
+ future version is a one-file drop — no code edit required. Requesting an
1392
+ unknown version prints the list of bundled notes so you can pick one that
1393
+ exists. See [`CONTRIBUTING.md`](https://github.com/itlackey/akm/blob/main/.github/CONTRIBUTING.md#shipping-a-release--migration-notes)
1394
+ for the per-release workflow.
1395
+
1396
+ ### help agents
1397
+
1398
+ Print agent-facing instructions for using `akm`. Add this output to your
1399
+ `AGENTS.md`, `CLAUDE.md`, or system prompt so your agent knows how to use
1400
+ the CLI. Prints the short guide by default; pass `--full` for the complete
1401
+ one.
1402
+
1403
+ ```sh
1404
+ akm help agents
1405
+ ```
1406
+
1407
+ ### hints
1408
+
1409
+ Print the agent-facing CLI guide directly. The complete guide is the default;
1410
+ use `--detail brief` for the compact version. `akm help agents` remains the
1411
+ short-first form and accepts `--full`.
1412
+
1413
+ ```sh
1414
+ akm hints
1415
+ akm hints --detail brief
1416
+ ```
1417
+
1418
+ ### env vs secret — which do I use?
1419
+
1420
+ Both protect their values identically (values never reach akm's stdout, the
1421
+ index, or `akm show`). They differ in **purpose**, not in how well they hide
1422
+ data:
1423
+
1424
+ | | `env` | `secret` |
1425
+ | --- | --- | --- |
1426
+ | **Purpose** | **configuration** — a group of related settings for an app/service | **authentication** — one sensitive value used on its own |
1427
+ | **Holds** | a `.env` file of **many** `KEY=value` pairs (URLs, flags, and any credentials it needs) | **one** value per file (an API token, PEM key, cert, service-account JSON) |
1428
+ | **Sensitivity** | values may or may not be sensitive — **all are protected anyway** | the value is always a credential |
1429
+ | **Injects** | many env vars at once (`env run`) | one env var (`secret run <ref> <VAR>`) |
1430
+ | **Discoverable** | key *names* (not values) | name only (the whole file is the value) |
1431
+
1432
+ **`env` is primarily for configuration — a group of related values you load
1433
+ together, protected whether or not any are sensitive. `secret` is primarily for
1434
+ a single sensitive value used for authentication.** Reach for `env` to load a
1435
+ service's config; reach for `secret` when one value *is* an auth credential.
1436
+
1437
+ > **Note:** there is no `akm vault` command — use `env` or `secret`.
1438
+
1439
+ ### env
1440
+
1441
+ Manage `.env`-backed **environment files** — a group of related **configuration**
1442
+ for an app or service (URLs, feature flags, and any credentials it needs),
1443
+ loaded together. Each `env` asset is an entire `.env` file stored under `env/`
1444
+ in your bundle (mode 0600). Values may or may not be sensitive; **akm protects
1445
+ them all the same** — key *names* are discoverable; values and comment text
1446
+ never appear in structured output (comments routinely contain commented-out
1447
+ credentials, so they are treated like values). akm does **not** manage
1448
+ individual entries — you edit the `.env` with your own editor (or ingest one
1449
+ with `--from-file`) and akm loads it wholesale. `list` and `show` surface key
1450
+ names only; `run` and `export` are the supported value-use paths.
1451
+
1452
+ ```sh
1453
+ akm env list
1454
+ akm env create prod # creates env/prod.env (mode 0600)
1455
+ akm env create prod --from-file ./.env # ingest an existing .env
1456
+ akm env create prod --path staging # creates env/staging/prod.env
1457
+ $EDITOR "$(akm env path env/prod --quiet)" # edit the file directly
1458
+ akm env run env/prod -- npm test # run a command with the whole file injected
1459
+ akm env run env/prod -- $SHELL # interactive shell with the env loaded
1460
+ akm env run env/prod --only DATABASE_URL -- ./migrate # inject just one var
1461
+ akm env remove env/prod --yes # remove the whole env file
1462
+ ```
1463
+
1464
+ akm does not manage individual keys — edit the `.env` file directly (`$EDITOR
1465
+ "$(akm env path <ref>)"`). `env remove <ref>` removes the whole file.
1466
+
1467
+ Env mutations (`create`, `remove`) pick their write destination the same way
1468
+ every other write command does: an explicit `--target <source>` wins, else
1469
+ `defaultWriteTarget`, else the working bundle. The chosen source must be
1470
+ writable — a non-writable `--target`/`defaultWriteTarget` fails with a
1471
+ `ConfigError` before anything is written — and on a git-backed writable target
1472
+ the mutation lands in a single boundary commit (filesystem targets are
1473
+ committed by `akm sync`; `env/` stays out of git when your bundle `.gitignore`
1474
+ excludes it). Reads (`list`, `path`, `run`, `export`) still span all configured
1475
+ sources and are unchanged.
1476
+
1477
+ Subcommands:
1478
+
1479
+ | Subcommand | Description |
1480
+ | --- | --- |
1481
+ | `list` | List all env files across all bundles with key names only |
1482
+ | `run <ref> -- <command>` | Run a command with the env injected. `--only` / `--except` filter which keys are injected; `--clean` starts from a minimal inherited environment |
1483
+ | `create <name>` | Create an env file. Empty by default; seed with `--from-file <path>` or `--from-stdin` |
1484
+ | `path <ref>` | Print the absolute env file path (Docker `_FILE` / `--env-file` / direct editing). `--quiet` suppresses the warning |
1485
+ | `export <ref> --out <file>` | Write a safe sourceable `export` script to a file (never to stdout) |
1486
+ | `remove <ref>` | Delete an env file (and its `.sensitive` marker) |
1487
+
1488
+ > **Removed in 0.9.0:** `akm env set`/`akm env unset`. akm does not manage
1489
+ > individual keys — edit the `.env` file directly.
1490
+
1491
+ #### env run — the primary value path
1492
+
1493
+ ```sh
1494
+ akm env run env/prod -- <command>
1495
+ akm env run env/prod -- $SHELL # interactive: a shell with the env loaded
1496
+ akm env run env/prod --only A,B -- cmd # inject only A and B
1497
+ akm env run env/prod --except DEBUG -- cmd
1498
+ akm env run env/prod --clean -- cmd
1499
+ akm env run env/prod --clean --inherit SSH_AUTH_SOCK -- cmd
1500
+ ```
1501
+
1502
+ Runs the command with the env file's values injected **directly into the child
1503
+ process** — never through a shell, and never into akm's own structured output.
1504
+ However, the child process controls its own stdout/stderr: if it prints its
1505
+ environment, those values will appear in your terminal or agent transcript.
1506
+ `--only` / `--except` (comma-separated key names, mutually exclusive) restrict
1507
+ which env-file keys are injected. `--clean` starts from a minimal inherited
1508
+ environment (PATH/HOME/locale/terminal basics) instead of inheriting the full
1509
+ parent environment; use `--inherit KEY1,KEY2` to pass specific parent vars
1510
+ through in clean mode. Before spawning, the injected key names are scanned for
1511
+ known process-hijacking variables (`LD_PRELOAD`, `PATH`, `GIT_CONFIG_*`, ...):
1512
+ a first-party bundle warns and proceeds; a third-party-sourced bundle is refused.
1513
+
1514
+ > The single-key `run <ref>/KEY` form was removed. To inject one value, store it
1515
+ > as a [secret](#secret) and use `akm secret run secrets/<name> <VAR> -- …`, or
1516
+ > use `akm env run <ref> --only <KEY> -- …`.
1517
+
1518
+ > Values injected via `env run` live in the child process environment for its
1519
+ > entire lifetime and are visible to all subprocesses it spawns. Avoid
1520
+ > `env run` for long-lived daemon or server processes, and do not use commands
1521
+ > like `env`, `printenv`, shell tracing, or verbose diagnostics in agent
1522
+ > contexts unless you explicitly intend to expose the child environment.
1523
+
1524
+ #### env create
1525
+
1526
+ ```sh
1527
+ akm env create prod # empty
1528
+ akm env create prod --from-file ./.env # seed from an existing .env (byte-for-byte)
1529
+ printf 'A=1\nB=2\n' | akm env create prod --from-stdin
1530
+ akm env create prod --path staging # creates env/staging/prod.env
1531
+ akm env create prod --sensitive # hidden from `env list` and the search index
1532
+ akm env create prod --target team # write to the `team` source
1533
+ ```
1534
+
1535
+ | Flag | Description |
1536
+ | --- | --- |
1537
+ | `--path <dir>` | Relative subdirectory under `env/` to place the file in. The filename comes from `<name>`. |
1538
+ | `--from-file <path>` | Seed the env file from an existing `.env` at this path |
1539
+ | `--from-stdin` | Seed the env file from stdin |
1540
+ | `--sensitive` | Exclude this env file from `env list` output and the search index |
1541
+ | `--target <source>` | Override the write destination (falls back to `defaultWriteTarget` then the working bundle) |
1542
+
1543
+ Creates `env/prod.env` with mode 0600. Empty `create` is a no-op if the file
1544
+ exists; `--from-file`/`--from-stdin` **refuse to clobber** an existing env (remove
1545
+ it first). `--sensitive` hides the file from `env list` and the search index.
1546
+
1547
+ #### env list
1548
+
1549
+ ```sh
1550
+ akm env list
1551
+ ```
1552
+
1553
+ One entry per env file across all configured bundles. The structured shape is
1554
+ `envs: [{ ref, keys }]` — values are never included and the absolute `path` is
1555
+ omitted from JSON output. Text output uses Markdown sections:
1556
+
1557
+ ```md
1558
+ ## env/prod
1559
+
1560
+ - DATABASE_URL
1561
+ - API_KEY
1562
+ ```
1563
+
1564
+ #### env path
1565
+
1566
+ ```sh
1567
+ akm env path env/prod # warns: don't source the raw file
1568
+ akm env path env/prod --quiet # for `_FILE` / `--env-file` use
1569
+ ```
1570
+
1571
+ Prints the absolute path to the env file — for the Docker `_FILE` convention
1572
+ (`MY_VAR_FILE=$(akm env path env/prod --quiet)`), `docker run --env-file`, or
1573
+ editing the file directly. By default a stderr warning steers you away from
1574
+ `source`-ing the raw file (its shell substitutions would execute); `--quiet`
1575
+ suppresses it for the legitimate file-path uses. Format-exempt
1576
+ (`src/output/format-exempt.ts`) — this command's stdout is always the bare
1577
+ path, never a result envelope; passing `--format` warns rather than doing
1578
+ anything.
1579
+
1580
+ #### env export
1581
+
1582
+ ```sh
1583
+ akm env export env/prod --out /tmp/prod.sh && source /tmp/prod.sh && rm -f /tmp/prod.sh
1584
+ ```
1585
+
1586
+ Writes a safe, sourceable `export KEY='value'` script to `--out <file>` (mode
1587
+ 0600). Values are re-serialised single-quoted, so a raw `.env` containing shell
1588
+ substitutions (e.g. `X=$(rm -rf ~)`) becomes a **literal string** — sourcing the
1589
+ generated file can never execute it. `export` **never prints values to stdout**
1590
+ (that would leak them into a captured/agent context) and so requires `--out`.
1591
+
1592
+ > For most uses prefer `akm env run` (no file, no cleanup). `export` exists for
1593
+ > the case where a tool must `source` a file or you need a generated env script.
1594
+
1595
+ ### secret
1596
+
1597
+ Manage **secrets** — a single sensitive value used on its own for
1598
+ **authentication**: an API token, a PEM private key, a TLS cert, a
1599
+ service-account JSON. Where an [env](#env) file holds a *group* of related
1600
+ configuration and exposes key *names*, a secret is *one* value and its **entire
1601
+ file is the value**, so only the secret's *name* is ever surfaced. Each secret
1602
+ is a mode-0600 file under `secrets/` in your bundle.
1603
+
1604
+ This mirrors Docker's secret model (one value per file, mounted at
1605
+ `/run/secrets/<name>`, read at runtime, never baked into the image or env at
1606
+ build time). The key security property: **secret values never appear in
1607
+ structured output** — not in the index, `akm search`, `akm curate`, or
1608
+ `akm show`. The supported value-use path is `secret run` (inject into a child
1609
+ env var).
1610
+
1611
+ ```sh
1612
+ akm secret list
1613
+ printf '%s' "$TOKEN" | akm secret set secrets/deploy-token
1614
+ akm secret set secrets/deploy-key --from-file ~/.ssh/id_ed25519 # byte-exact
1615
+ AKM_VALUE="$TOKEN" akm secret set secrets/api --from-env AKM_VALUE
1616
+ akm secret run secrets/deploy-token GITHUB_TOKEN -- gh release create v1.0.0
1617
+ ```
1618
+
1619
+ Subcommands:
1620
+
1621
+ | Subcommand | Description |
1622
+ | --- | --- |
1623
+ | `list` | List all secrets across all bundles by name (contents never shown) |
1624
+ | `set <ref>` | Create/overwrite a secret — value from stdin (default), `--from-file`, or `--from-env` |
1625
+ | `run <ref> <VAR> -- <command>` | Run a command with the secret value injected into `$VAR` in the child only |
1626
+
1627
+ > **Removed in 0.9.0: `secret path` and `secret remove`.** The two resolved a
1628
+ > ref through *different* bundle-selection logic — `path` through the read-side,
1629
+ > all-sources resolver and `remove` through the write-target resolver — so for a
1630
+ > ref present in more than one bundle they could silently name different files:
1631
+ > you could inspect one secret and delete another. Both now exit 2 with
1632
+ > `Unknown command`. A ref's file lives at `<bundle>/secrets/<name>` (run
1633
+ > `akm bundle list` for bundle roots); locate or delete it there directly, or
1634
+ > use `akm secret run` to consume the value without touching disk.
1635
+
1636
+ #### secret set
1637
+
1638
+ ```sh
1639
+ # Default: read the value from stdin (never crosses argv)
1640
+ printf '%s' "$TOKEN" | akm secret set secrets/deploy-token
1641
+
1642
+ # Import an existing file byte-exact (multi-line PEM keys, certs, binary)
1643
+ akm secret set secrets/deploy-key --from-file ~/.ssh/id_ed25519
1644
+
1645
+ # From an environment variable
1646
+ AKM_VALUE="$TOKEN" akm secret set secrets/api --from-env AKM_VALUE
1647
+ ```
1648
+
1649
+ The value is **never accepted via positional arguments**. With stdin, a single
1650
+ trailing newline is stripped (so `echo "$TOKEN" | akm secret set …` stores the
1651
+ token without the shell-added newline); use `--from-file` for byte-exact storage
1652
+ of multi-line material. Writes are atomic (mode 0600) under an exclusive
1653
+ `<secret>.lock`. Maximum size is 5 MB.
1654
+
1655
+ `secret set` selects its write destination like every other write command: an
1656
+ explicit `--target <source>` wins, else `defaultWriteTarget`, else the working
1657
+ bundle. The chosen source must be writable (a non-writable target fails with a
1658
+ `ConfigError`), and on a git-backed writable target the mutation lands in a
1659
+ single boundary commit. Reads (`list`, `run`) still span all configured sources.
1660
+
1661
+ #### secret run
1662
+
1663
+ ```sh
1664
+ akm secret run secrets/deploy-token GITHUB_TOKEN -- gh release create v1.0.0
1665
+ akm secret run secrets/deploy-token GITHUB_TOKEN --clean -- gh auth status
1666
+ ```
1667
+
1668
+ Runs one subprocess with the secret's value set as `$VAR` in the child's
1669
+ environment. **The value never appears in akm's structured output** — it is
1670
+ passed directly to the child process. The target variable name is validated and
1671
+ known process-hijacking names (`LD_PRELOAD`, `PATH`, etc.) are rejected.
1672
+ `--clean` starts from a minimal inherited environment instead of inheriting the
1673
+ full parent environment; use `--inherit KEY1,KEY2` to pass specific parent vars
1674
+ through in clean mode.
1675
+
1676
+ > Secrets injected via `secret run` live in the child process environment for
1677
+ > its entire lifetime and are visible to all subprocesses it spawns. For
1678
+ > long-lived daemons, point the process at the secret file directly
1679
+ > (`<bundle>/secrets/<name>`) so the value never sits in an environment
1680
+ > variable. Avoid commands that print the environment in agent contexts unless
1681
+ > you explicitly intend to expose the child environment.
1682
+
1683
+ #### Sensitive marker
1684
+
1685
+ A sibling `<name>.sensitive` marker file excludes a secret from `secret list`
1686
+ **and** from indexing entirely (parallel to env files). The secret remains usable
1687
+ via `secret run`.
1688
+
1689
+ ### Wikis (no dedicated command)
1690
+
1691
+ An LLM wiki (the Karpathy pattern — `schema.md` rulebook, agent-authored
1692
+ `pages/`, immutable `raw/` sources) is a **bundle format**, not a command
1693
+ family. There is no `akm wiki` verb; a bundle whose root holds `schema.md`
1694
+ plus `pages/` is recognized automatically at install time, and its pages are
1695
+ indexed and addressed like any other asset:
1696
+
1697
+ ```sh
1698
+ akm bundle add github:team/research-wiki # install a wiki bundle (or a local dir)
1699
+ akm search "attention" # pages rank alongside all other assets
1700
+ akm show research-wiki//pages/attention # read a page by bundle//conceptId ref
1701
+ ```
1702
+
1703
+ Writing pages, ingesting raw sources, and maintaining `index.md`/`log.md` are
1704
+ the agent's job, using its native `Read`/`Write`/`Edit` tools guided by
1705
+ `schema.md` — akm's job is recognition, indexing, and search. See
1706
+ [wikis.md](https://github.com/itlackey/akm/blob/main/docs/guides/wikis.md) for the full format.
1707
+
1708
+ ### completions
1709
+
1710
+ Generate or install a bash completion script for `akm`. The script is built
1711
+ dynamically from the command tree, so it always reflects the current set of
1712
+ subcommands and flags.
1713
+
1714
+ ```sh
1715
+ akm completions # Print bash completion script to stdout
1716
+ akm completions --install # Install to the appropriate directory
1717
+ ```
1718
+
1719
+ | Flag | Description |
1720
+ | --- | --- |
1721
+ | `--install` | Write the script to the XDG-compliant completions directory |
1722
+ | `--shell` | Shell type (currently only `bash` is supported) |
1723
+
1724
+ **Manual activation:** pipe the output into your shell or source it from
1725
+ your profile:
1726
+
1727
+ ```sh
1728
+ source <(akm completions)
1729
+ ```
1730
+
1731
+ **Install locations** (checked in order):
1732
+
1733
+ 1. `$XDG_DATA_HOME/bash-completion/completions/akm`
1734
+ 2. `~/.local/share/bash-completion/completions/akm`
1735
+ 3. `~/.bash_completion.d/akm`
1736
+
1737
+ ---
1738
+
1739
+ ## Improvement Flow
1740
+
1741
+ These commands define the self-improvement and agent-dispatch surface.
1742
+
1743
+ ### agent
1744
+
1745
+ Dispatch a configured agent engine, optionally embodying a bundle agent asset.
1746
+
1747
+ ```sh
1748
+ akm agent [<agent-ref>] [--engine <name>] [--prompt <text>] [--model <model>] [--command <ref>] [--workflow <ref>] [--timeout-ms <ms>] [--cwd <path>]
1749
+ ```
1750
+
1751
+ | Argument / Flag | Description |
1752
+ | --- | --- |
1753
+ | `<agent-ref>` | Optional agent asset ref (e.g. `agents/code-reviewer`). Loads system prompt, model, and tool policy from the bundle asset. |
1754
+ | `--engine <name>` | Agent engine to use; defaults to `defaults.engine` |
1755
+ | `--prompt <text>` | Task prompt to pass to the agent |
1756
+ | `--model <model>` | Model override. Accepts aliases (`opus`, `sonnet`, `haiku`) or exact platform model IDs. Overrides the model in the agent asset. Resolved per platform: `opencode/claude-opus-4-7` for opencode, `claude-opus-4-7` for claude. |
1757
+ | `--command <ref>` | Load prompt from a `commands/<name>` asset |
1758
+ | `--workflow <ref>` | Load prompt from a `workflows/<name>` asset |
1759
+ | `--timeout-ms <ms>` | Override the agent CLI timeout in milliseconds |
1760
+ | `--cwd <path>` | Working directory for the spawned agent (defaults to the current directory) |
1761
+
1762
+ When `<agent-ref>` is provided, akm loads the bundle agent asset and extracts
1763
+ its system prompt, `modelHint`, and `toolPolicy`. The `--model` flag wins
1764
+ over any model specified in the asset.
1765
+
1766
+ **Platform-specific dispatch:** akm uses a platform builder to construct the
1767
+ CLI argv for each engine's harness platform. `platform: "opencode"` engines emit:
1768
+ `opencode run [--system-prompt "..."] [--model opencode/claude-opus-4-7] "<prompt>"`.
1769
+ `platform: "claude"` engines emit:
1770
+ `claude [--system-prompt "..."] [--model claude-opus-4-7] [--allowedTools ...] --print "<prompt>"`.
1771
+ Agent engines may set `bin`, `args`, `workspace`, `model`, `timeoutMs`, and
1772
+ `modelAliases` in config.
1773
+
1774
+ Without any `--prompt`, `<agent-ref>`, or `--model`, the agent is launched
1775
+ interactively (no injected prompt, no platform-specific flags beyond the
1776
+ engine's base args).
1777
+
1778
+ Configure agent engines under `engines.<name>` with `kind: "agent"` and a
1779
+ registered harness `platform` (see [Configuration](configuration.md)). AKM
1780
+ lowers the selected engine to the spawn or embedded SDK runner with captured or
1781
+ interactive stdio, hard timeout, and structured failure reasons.
1782
+
1783
+ ```sh
1784
+ # Interactive launch:
1785
+ akm agent --engine opencode
1786
+
1787
+ # Dispatch with a prompt only:
1788
+ akm agent --engine claude --prompt "summarize recent changes"
1789
+
1790
+ # Embody a bundle agent asset:
1791
+ akm agent agents/code-reviewer --engine opencode --prompt "review src/"
1792
+
1793
+ # Model override with alias:
1794
+ akm agent agents/planner --engine claude --model sonnet --prompt "plan the sprint"
1795
+
1796
+ # Exact model ID override:
1797
+ akm agent --engine opencode --model opencode/claude-opus-4-7 --prompt "audit the API"
1798
+ ```
1799
+
1800
+ Returns `{ ok, exitCode, stdout?, stderr?, durationMs, reason? }`. On
1801
+ failure, `reason` is one of `timeout | spawn_failed | non_zero_exit |
1802
+ parse_error`. Captured dispatches render this final envelope using the selected
1803
+ akm format. Interactive child stdout/stderr remain inherited and raw. A failed
1804
+ dispatch exits 1; `exitCode` in the envelope retains the child's exact status
1805
+ when one exists.
1806
+
1807
+ ### lint
1808
+
1809
+ Scan bundle markdown files for structural issues: unquoted colons, missing
1810
+ `updated` field, orphaned stubs, placeholder stubs, missing `name`/`type`,
1811
+ stale paths, and broken refs — in body text and in
1812
+ `refs`/`xrefs`/`supersededBy`/`contradictedBy` frontmatter. Also reports
1813
+ `dangerous-env-key` findings for env files (the same key set `akm bundle add`
1814
+ enforces — see [Dangerous env key audit](#dangerous-env-key-audit) — but
1815
+ non-blocking here; `lint` only warns). `--type workflows` structurally parses
1816
+ and compiles unified markdown workflows; errors surface as
1817
+ `invalid-workflow-structure` findings (0.9.0: this is the only
1818
+ structural-validation surface now that `akm workflow validate` is gone).
1819
+
1820
+ ```sh
1821
+ akm lint # Report findings; exits 0 regardless
1822
+ akm lint --fix # Auto-fix Tier-1 issues in place
1823
+ akm lint --type workflows # Only lint one asset type
1824
+ akm lint --dir ~/other-bundle # Override the bundle root (default: from config)
1825
+ akm lint --fail-on-flagged # CI-friendly: exit non-zero when summary.flagged > 0
1826
+ ```
1827
+
1828
+ | Flag | Description |
1829
+ | --- | --- |
1830
+ | `--fix` (alias `--auto-fix`) | Apply auto-fixes in place |
1831
+ | `--dir` | Override the bundle root directory (default: from config) |
1832
+ | `--type` | Only lint assets of this type (e.g. `workflows`, `tasks`, `memories`) |
1833
+ | `--fail-on-flagged` | Exit non-zero when `summary.flagged > 0`. Default: exit 0 regardless of findings. |
1834
+
1835
+ Returns `fixed[]` and `flagged[]` arrays plus a `summary: { fixed, flagged }`
1836
+ count. Each entry carries `file`, `issue`, `detail`, and whether it was
1837
+ `fixed`.
1838
+
1839
+ ### improve
1840
+
1841
+ Improve existing assets and write the results to the proposal queue.
1842
+
1843
+ ```sh
1844
+ akm improve
1845
+ akm improve memory
1846
+ akm improve skills/code-review
1847
+ akm improve workflows/release-checklist --task "reduce duplication"
1848
+ akm improve --skip-if-locked # for high-frequency scheduled runs: skip (exit 0) if a run is already in progress
1849
+ akm improve --no-sync # skip the end-of-run git commit entirely (default: on for git-backed bundles)
1850
+ akm improve --sync --no-push # commit only, skip the push after it
1851
+ ```
1852
+
1853
+ | Flag | Description |
1854
+ | --- | --- |
1855
+ | `--task` | Optional extra guidance for this improvement pass |
1856
+ | `--dry-run` | Show the schema-v2 result on stdout without creating config, data, state, cache, bundle, log, or result artifacts. Dry-run results are never persisted, including on errors or signals. |
1857
+ | `--bundle` | Select the proposal/write target; when the ref scope is bundle-qualified, it must name the same bundle |
1858
+ | `--limit <n>` | Maximum number of assets to process (highest utility first) |
1859
+ | `--timeout-ms <ms>` | Wall-clock budget for the run (default: `7200000` = 2 hours) |
1860
+ | `--require-feedback-signal` | Only process assets with recent feedback signals |
1861
+ | `--strategy <name>` | Override the active improve strategy (a built-in or entry under `improve.strategies`) |
1862
+ | `--json-to-stdout` | Also emit the full persisted JSON result on stdout for a live run. Without this flag, stdout stays empty. Dry-runs always emit their result and are never persisted. |
1863
+ | `--skip-if-locked` | If another improve run already holds the lock, skip gracefully (exit 0) instead of failing with "already running" (exit 78). Use for high-frequency scheduled runs so they don't pile up failures while a longer run is in progress. |
1864
+ | `--sync` / `--no-sync` | Commit (and optionally push) the git-backed primary bundle when the run finishes. Default: on for git-backed bundles (per profile config). |
1865
+ | `--push` / `--no-push` | Push after the end-of-run sync commit when writable with a remote configured. `--no-push` commits only, skipping the push. Default: per profile config (`true`). `sync.push` stays outside the autonomy gate — this is a per-run opt-out, not a default change. |
1866
+
1867
+ `akm improve` is the public entrypoint for whole-bundle, type-scoped, and
1868
+ ref-scoped improvement. It owns the memory-cleanup and lesson-distillation
1869
+ flow. A qualified scope such as `team//skills/code-review` selects that bundle;
1870
+ a different explicit `--bundle` is a usage error. Inspecting or re-minting the
1871
+ collapse-detector canary set is maintainer tooling, not a CLI verb — run
1872
+ `bun scripts/refresh-canary-set.ts` (add `--refresh` to mint a new set and
1873
+ deactivate the old one; old rows and their cycle history are retained).
1874
+
1875
+ Built-in `default` and `frequent` leave the improve-stage extract process off,
1876
+ and `default` plus `reflect-distill` leave proactive maintenance off. Use the
1877
+ explicit `proactive-maintenance` strategy or set the selected strategy's
1878
+ process `enabled: true` to opt in. The stage toggle does not disable a direct
1879
+ `akm proposal extract --type <harness>` or `akm proposal extract --auto`
1880
+ invocation.
1881
+
1882
+ The maintenance pass run by `improve` also expires stale proposals: any pending
1883
+ proposal older than the top-level `archiveRetentionDays` config key (default
1884
+ **90**, not `improve.archiveRetentionDays`) is moved to the archive with the
1885
+ reason `expired: no action within retention window` and a `proposal_expired`
1886
+ event is emitted. Set `archiveRetentionDays` to `0` to disable expiration
1887
+ entirely. The total expired count surfaces in the improve result as
1888
+ `proposalsExpired`.
1889
+
1890
+ `improve` never promotes proposals on its own — there is no confidence gate.
1891
+ Every generated proposal lands in the queue with a `pending` status
1892
+ and is adjudicated later with `akm proposal accept` / `akm proposal reject` or
1893
+ the drain engine. Reflect still emits a `confidence` score (0..1) in its JSON
1894
+ response schema; it is recorded on the proposal for triage and ranking, but no
1895
+ threshold auto-accepts anything.
1896
+
1897
+ Selection behavior defaults to recent feedback signals first, with a
1898
+ zero-feedback retrieval fallback for high-traffic refs. Use
1899
+ `--require-feedback-signal` to disable retrieval fallback for the run.
1900
+
1901
+ When reinforced facts need promotion, `knowledge` is the higher-authority
1902
+ destination than `memory`. The deterministic search ranking also prefers
1903
+ `knowledge` over `memory` hits, including inferred `.derived` memories, when
1904
+ the evidence is otherwise comparable.
1905
+
1906
+ ### proposal
1907
+
1908
+ Manage the proposal queue. The canonical grammar is `akm proposal <verb>`:
1909
+ `extract`, `new`, `list`, `show`, `diff`, `accept`, `reject`, `revert`,
1910
+ `drain`. Bare `akm proposal` is a usage error (exit 2) as of 0.9.0 — it used
1911
+ to behave as `akm proposal list`; name the verb. There are no flat-verb
1912
+ spellings (`akm proposals`, `akm extract`, `akm propose`, `akm accept`, `akm
1913
+ reject`, `akm diff`, `akm revert`) — use the `akm proposal <verb>` form.
1914
+
1915
+ `list`, `show`, `diff`, `accept`, `reject`, and `revert` (and bulk accept/
1916
+ reject) support `--queue <source>`. It selects the proposal queue stored for
1917
+ that configured writable source root; without it, commands use the primary
1918
+ queue. Queue selection is not a destination override. `drain` does **not**
1919
+ take `--queue` — it operates on the standing backlog via a policy, not a
1920
+ single queue.
1921
+
1922
+ New qualified proposals record their destination source name and materialized
1923
+ root. `proposal diff`, `accept`, and `revert` use that recorded target by
1924
+ default; an explicit `--target` must resolve to the same source and root or the
1925
+ command fails with exit 2. An unbound proposal in a selected non-primary queue
1926
+ uses that authenticated queue root. A short historical unbound proposal
1927
+ mutation requires either an explicit `--target` or a selected `--queue` that
1928
+ authenticates its root; it never falls back to an ambient write target.
1929
+
1930
+ #### proposal extract
1931
+
1932
+ Extract durable insights from native coding-agent session files (claude-code,
1933
+ opencode) and queue them as proposals. This is the standalone entrypoint for
1934
+ session extraction — it replaces the legacy session-checkpoint hook and runs
1935
+ independently of the improve-stage extract toggle (see `improve` above).
1936
+
1937
+ ```sh
1938
+ akm proposal extract --type claude-code --session-id <id>
1939
+ akm proposal extract --type claude-code --since 24h
1940
+ akm proposal extract --type opencode --since 7d --dry-run
1941
+ akm proposal extract --auto # iterate every available harness
1942
+ akm proposal extract --type claude-code --location /custom/path --session-id <id>
1943
+ ```
1944
+
1945
+ | Flag | Description |
1946
+ | --- | --- |
1947
+ | `--type <harness>` | Harness name (`claude-code`, `opencode`). Required unless `--auto`. |
1948
+ | `--session-id <id>` | Process only this session ID. When absent, discover sessions via `--since`. |
1949
+ | `--location <path>` | Override the harness's default session-discovery location. |
1950
+ | `--since <cutoff>` | Discovery cutoff. ISO timestamp or duration (`24h`, `7d`, `30m`). Default `24h`. |
1951
+ | `--auto` | Iterate every available harness with the default `--since`. Mutually exclusive with `--type`. |
1952
+ | `--dry-run` | Show candidates without queuing proposals. |
1953
+ | `--force` | Re-process sessions even if they were already extracted and have no new events. Default: skip already-seen sessions. |
1954
+ | `--timeout-ms <ms>` | Per-session LLM timeout in ms (default `600000`). |
1955
+ | `--engine <name>` | Named LLM engine for this invocation. Mutually exclusive with `--strategy`. |
1956
+ | `--strategy <name>` | Improve strategy supplying extract behavior and engine. Mutually exclusive with `--engine`. |
1957
+
1958
+ `--type` and `--auto` are mutually exclusive; one of them is required.
1959
+ `--auto` iterates `getAvailableHarnesses()` — every harness with a detectable
1960
+ session-log location on the current machine — and returns an aggregated
1961
+ `extract-auto-result` envelope (`harnessesProcessed`, `totalProposals`,
1962
+ per-harness `results`); the run exits non-zero only when every harness
1963
+ failed.
1964
+
1965
+ There is no `akm proposal extract --watch`/`--debounce-ms` either (0.9.0:
1966
+ dropped — a foreground polling daemon in a one-shot CLI); the shipped
1967
+ `core/extract.yml` cron template (`akm proposal extract --auto` on a
1968
+ schedule) is the answer.
1969
+
1970
+ Requires an LLM engine: pass `--engine`, select a `--strategy` whose
1971
+ `processes.extract.engine` is set, or configure `defaults.llmEngine`.
1972
+
1973
+ #### proposal new
1974
+
1975
+ Generate a brand-new asset proposal from a description. Output is always a
1976
+ proposal — never a direct write.
1977
+
1978
+ ```sh
1979
+ akm proposal new <type> <name> --task "..."
1980
+ akm proposal new <type> <name> --file ./prompt.md
1981
+ akm proposal new skill code-review --task "PR-style review skill"
1982
+ akm proposal new lesson docker-cleanup --file ./prompts/docker-cleanup.md
1983
+ akm proposal new skill code-review --path team --task "PR-style review skill" # writes under skills/team/
1984
+ ```
1985
+
1986
+ | Flag | Description |
1987
+ | --- | --- |
1988
+ | `--path` | Relative subdirectory under the type dir to place the proposed asset in (e.g. `release`). The filename comes from `<name>`. |
1989
+ | `--task` | Inline task text |
1990
+ | `--file` | Read task text from a UTF-8 file |
1991
+ | `--engine` | Override the default execution engine |
1992
+ | `--timeout-ms` | Override the selected engine timeout for this call |
1993
+
1994
+ Exactly one of `--task` or `--file` is required. Emits `propose_invoked`.
1995
+
1996
+ **Prompt-task `timeoutMs`:** a version-2 prompt task may set `timeoutMs` to
1997
+ override its selected engine timeout. Set it to `null` to disable the timer, or
1998
+ to a positive integer (milliseconds) to apply a task-specific limit.
1999
+
2000
+ #### proposal list
2001
+
2002
+ List proposal queue entries.
2003
+
2004
+ ```sh
2005
+ akm proposal list
2006
+ akm proposal list --queue team-bundle
2007
+ akm proposal list --status pending|accepted|rejected|reverted
2008
+ akm proposal list --ref skills/deploy
2009
+ ```
2010
+
2011
+ | Flag | Description |
2012
+ | --- | --- |
2013
+ | `--queue <source>` | Select the proposal queue by configured writable source name |
2014
+ | `--status` | Filter by `pending`, `accepted`, `rejected`, or `reverted` |
2015
+ | `--ref` | Filter by asset ref. A qualified ref preserves bundle identity; a short ref matches that concept in the selected queue |
2016
+ | `--type` | Reserved type filter |
2017
+
2018
+ Each proposal record carries an optional `confidence` field (0..1) emitted by
2019
+ reflect/propose runs. It is recorded for triage and ranking only — there is no
2020
+ confidence gate or auto-promotion; proposals are
2021
+ adjudicated with `akm proposal accept` / `reject`. Once accepted, a proposal
2022
+ that overwrote an existing asset also carries a `backup` field pointing to the
2023
+ captured prior content, which `akm proposal revert` uses.
2024
+
2025
+ #### proposal show
2026
+
2027
+ Inspect a queued proposal and its validation findings.
2028
+
2029
+ ```sh
2030
+ akm proposal show <id>
2031
+ akm proposal show <id> --queue team-bundle
2032
+ ```
2033
+
2034
+ #### proposal accept
2035
+
2036
+ Accept a proposal and promote it into its recorded destination. Accepts a full
2037
+ UUID, an 8-character UUID prefix, or an asset ref.
2038
+
2039
+ ```sh
2040
+ akm proposal accept <id>
2041
+ akm proposal accept 7c115132 # 8-char UUID prefix
2042
+ akm proposal accept skills/akm-dream # Asset ref
2043
+ akm proposal accept <id> --queue team-bundle
2044
+ akm proposal accept <id> --target team-bundle # Must match a recorded target
2045
+ akm proposal accept --generator reflect -y # Bulk-accept by generator (requires -y)
2046
+ akm proposal accept --generator reflect --max-diff-lines 50 -y # ...only if <= 50 lines
2047
+ akm proposal accept --generator reflect --older-than 7 --dry-run # Preview a bulk accept
2048
+ ```
2049
+
2050
+ | Flag | Description |
2051
+ | --- | --- |
2052
+ | `--queue <source>` | Select the proposal queue by configured writable source name |
2053
+ | `--target <name>` | Write destination; must match the proposal's recorded target |
2054
+ | `--generator <name>` | Bulk-accept all pending proposals from this generator (e.g. `reflect`, `distill`). Requires no positional id. |
2055
+ | `--max-diff-lines` | When bulk-accepting, only accept proposals whose content is `<=` this many lines. Larger proposals are skipped. |
2056
+ | `--older-than` | When bulk-accepting, only accept proposals created more than this many days ago |
2057
+ | `--dry-run` | List proposals that would be bulk-accepted without accepting them |
2058
+ | `-y`, `--yes` | Skip confirmation (required in non-interactive mode for bulk accept) |
2059
+
2060
+ Bulk-accept all pending proposals from one generator with `--generator <name>`
2061
+ (e.g. `reflect`, `distill`) and no positional id. Bulk accept requires
2062
+ `-y`/`--yes` in non-interactive shells.
2063
+
2064
+ #### proposal reject
2065
+
2066
+ Reject a proposal and archive the reason. Accepts a full UUID, an 8-character
2067
+ UUID prefix, or an asset ref.
2068
+
2069
+ ```sh
2070
+ akm proposal reject <id> --reason "duplicates existing workflow"
2071
+ akm proposal reject <id> --queue team-bundle --reason "duplicates existing workflow"
2072
+ akm proposal reject 7c115132 --reason "not ready" # 8-char UUID prefix
2073
+ akm proposal reject skills/my-skill --reason "not ready" # Asset ref
2074
+ akm proposal reject --generator reflect --reason "noisy" -y # Bulk-reject by generator
2075
+ akm proposal reject --generator reflect --reason "noisy" --max-diff-lines 50 -y
2076
+ ```
2077
+
2078
+ | Flag | Description |
2079
+ | --- | --- |
2080
+ | `--reason` | Reason for rejection (required) |
2081
+ | `--queue <source>` | Select the proposal queue by configured writable source name |
2082
+ | `--generator <name>` | Bulk-reject all pending proposals from this generator (e.g. `reflect`, `distill`). Requires no positional id. |
2083
+ | `--max-diff-lines` | When bulk-rejecting, only reject proposals whose content is `<=` this many lines. Larger proposals are skipped. |
2084
+ | `--older-than` | When bulk-rejecting, only reject proposals created more than this many days ago |
2085
+ | `--dry-run` | List proposals that would be bulk-rejected without rejecting them |
2086
+ | `-y`, `--yes` | Skip confirmation (required in non-interactive mode for bulk reject) |
2087
+
2088
+ Bulk-reject all pending proposals from one generator with `--generator <name>`
2089
+ and no positional id. Bulk reject requires `-y`/`--yes` in non-interactive shells.
2090
+
2091
+ #### proposal revert
2092
+
2093
+ Revert an accepted proposal by restoring the prior asset content from the
2094
+ backup captured at promotion time. Only works on proposals that overwrote an
2095
+ existing asset; new-asset proposals leave no backup. Sets the proposal's status
2096
+ to `reverted` and appends a `proposal_reverted` event to the audit log.
2097
+
2098
+ ```sh
2099
+ akm proposal revert <id>
2100
+ akm proposal revert skills/akm-dream # Asset ref
2101
+ akm proposal revert <id> --queue team-bundle
2102
+ akm proposal revert <id> --target team-bundle # Must match a recorded target
2103
+ ```
2104
+
2105
+ | Flag | Description |
2106
+ | --- | --- |
2107
+ | `--queue <source>` | Select the proposal queue by configured writable source name |
2108
+ | `--target <name>` | Select the destination for an unbound proposal, or confirm a recorded destination; a conflict with a recorded target is rejected |
2109
+
2110
+ Accepts the full proposal UUID or the asset ref. UUID prefixes are **not**
2111
+ supported for reverting (archived proposals require the full identifier). Errors
2112
+ with exit code 2 if the proposal is not in `accepted` status, has no captured
2113
+ backup, or cannot be found.
2114
+
2115
+ #### proposal diff
2116
+
2117
+ Preview the proposed change against the live asset. Accepts a full UUID, an
2118
+ 8-character UUID prefix, or an asset ref directly.
2119
+
2120
+ ```sh
2121
+ akm proposal diff <id>
2122
+ akm proposal diff skills/akm-dream # Asset ref form
2123
+ akm proposal diff 7c115132 # 8-char UUID prefix
2124
+ akm proposal diff <id> --queue team-bundle
2125
+ akm proposal diff <id> --target team-bundle # Must match a recorded target
2126
+ ```
2127
+
2128
+ | Flag | Description |
2129
+ | --- | --- |
2130
+ | `--queue <source>` | Select the proposal queue by configured writable source name |
2131
+ | `--target <name>` | Select an unbound destination or confirm a recorded one for `proposal accept`, `diff`, or `revert`; a conflict with a recorded target is rejected |
2132
+
2133
+ `proposal accept` runs full validation before promoting. `proposal reject`
2134
+ requires `--reason`.
2135
+
2136
+ #### proposal drain
2137
+
2138
+ Drain the standing pending-proposal backlog using a deterministic triage
2139
+ policy, instead of adjudicating proposals one at a time. Default mode stages
2140
+ decisions (queue mode); pass `--promote` to actually accept matching
2141
+ proposals.
2142
+
2143
+ ```sh
2144
+ akm proposal drain --dry-run # Preview without writing
2145
+ akm proposal drain --policy personal-stash --promote -y
2146
+ akm proposal drain --policy conservative --max-accepts 10 --promote -y
2147
+ akm proposal drain --max-diff-lines 50 --older-than 7 --promote -y
2148
+ akm proposal drain --strategy default --promote -y # Read the triage block from an improve strategy
2149
+ ```
2150
+
2151
+ | Flag | Description |
2152
+ | --- | --- |
2153
+ | `--policy` | Built-in preset (`personal-stash`, `conservative`, `manual`) or a path to a policy file |
2154
+ | `--strategy` | Read the triage block (policy, apply mode, ceilings, judgment) from this improve strategy instead |
2155
+ | `--promote` | Promote (accept) matching proposals. Default is queue mode — stage only, no writes to assets. |
2156
+ | `--dry-run` | List what would be accepted/rejected/deferred, without writing |
2157
+ | `--max-accepts` | Hard per-run accept ceiling; accepts beyond this are reported as `skippedByCap` |
2158
+ | `--max-diff-lines` | Defer (never promote) accepts whose proposed content exceeds this many lines |
2159
+ | `--older-than` | Only consider proposals created more than this many days ago |
2160
+ | `--judgment` | Opt into the judgment tier (`llm` by default; `agent`/`sdk` per config) for deferred items. No-op with a logged `triage_deferred` summary when no runner is configured. |
2161
+ | `-y`, `--yes` | Skip the confirmation prompt (required in non-interactive mode for promotion) |
2162
+
2163
+ ### feedback (`--reason`)
2164
+
2165
+ `akm feedback` accepts an optional `--reason <text>` flag whose value is
2166
+ forwarded into feedback metadata and consumed by improve/distill proposal
2167
+ prompts. Negative feedback requires a reason by default.
2168
+
2169
+ ### task
2170
+
2171
+ `akm task` is the scheduling surface for workflows, agent prompts, and
2172
+ shell commands. It manages on-disk task definitions under
2173
+ `<bundle>/tasks/<id>.yml` and reconciles them with the OS-native scheduler
2174
+ (cron / launchd / schtasks). Only version-2 task YAML is discovered. The
2175
+ group is `add | run | sync | doctor | history` — there is no `list` or
2176
+ `remove`; use `akm search --type task` / `akm show tasks/<id>` to inspect,
2177
+ and edit the file + `akm task sync` to change or remove a schedule.
2178
+
2179
+ ```sh
2180
+ akm search --type task # List tasks (cross-bundle)
2181
+ akm show tasks/<id> # Inspect one task
2182
+ akm task add <id> --schedule "@daily" \ # Register a new task and install it
2183
+ --command "akm improve --strategy default"
2184
+ akm task add review --schedule "@daily" --prompt "Review recent changes" --engine reviewer
2185
+ akm task add nightly --schedule "@daily" --command "akm improve" --disabled # register but leave off
2186
+ akm task add nightly --schedule "@daily" --command "akm improve" --force # overwrite an existing task id
2187
+ akm task run <id> # Execute now (what the scheduler calls)
2188
+ akm task history [--id <id>] [--limit <n>] # Recent runs from state.db
2189
+ akm task sync # Reconcile on-disk YAML with scheduler
2190
+ akm task sync --rebind # Also capture the current installed runtime
2191
+ akm task doctor # Report scheduler backend + paths
2192
+ ```
2193
+
2194
+ `task add` also accepts `--disabled` (register but leave off in the OS
2195
+ scheduler), `--force` (overwrite an existing task with the same id), and
2196
+ `--rebind` (explicitly permit scheduler creation from a local invocation that
2197
+ would otherwise be considered ineligible).
2198
+
2199
+ `akm task run` is what cron / launchd / schtasks invoke at the scheduled
2200
+ time. Each run is recorded as a row in the durable `task_history` table
2201
+ (`state.db`), surfaced by `akm task history` — **not** by `akm log`; there is
2202
+ no `task_invoked`/`task_completed` event type on the `akm log` stream.
2203
+
2204
+ To disable a scheduled task, set `enabled: false` in its file and run
2205
+ `akm task sync`. To remove one, delete its file (`<bundle>/tasks/<id>.yml`)
2206
+ and run `akm task sync` — sync uninstalls the orphaned scheduler entry.
2207
+
2208
+ Scheduler activation captures the installed akm runtime. Ordinary `task sync`
2209
+ reconciles definitions, schedules, and enabled state while preserving that
2210
+ runtime binding. Use `task sync --rebind` only after intentionally moving or
2211
+ replacing the installation, or to repair a stale runtime path, then verify the
2212
+ result with `akm task doctor`. Interactive `akm setup` reviews every embedded
2213
+ task template (both the core set and the improve-schedule set) and asks once
2214
+ before changing task files or scheduler state; non-interactive setup changes
2215
+ neither.
2216
+
2217
+ Setup reconfiguration preserves existing scheduler runtime bindings. Changing
2218
+ the AKM storage path or installed runtime path therefore requires an explicit
2219
+ `akm task sync --rebind`; setup does not silently migrate those entries.
2220
+
2221
+ **Bundle targeting (`--bundle <bundle>`).** By default every subcommand
2222
+ operates on the primary/default bundle. `add`, `history`, `sync`, and `run`
2223
+ all accept `--bundle <bundle>` to schedule and reconcile tasks that live in
2224
+ another configured bundle (`doctor` reports scheduler-wide state and takes no
2225
+ `--bundle`):
2226
+
2227
+ ```sh
2228
+ akm task add nightly --schedule "@daily" --command "akm improve" --bundle team-bundle
2229
+ akm task sync --bundle team-bundle # reconcile only that bundle
2230
+ ```
2231
+
2232
+ A non-default bundle is recorded in the installed scheduler entry as a
2233
+ `--bundle <bundle>` token, so the scheduled `akm task run` resolves the task
2234
+ (and its relative asset refs) from that bundle. `sync` reconciles one bundle at a
2235
+ time and only touches entries attributed to it, so a plain (primary) sync never
2236
+ disturbs another bundle's scheduled tasks. Scheduler ids are the bare task id and
2237
+ are never namespaced: registering a task whose id is already scheduled from a
2238
+ different bundle is a hard error.
2239
+
2240
+ Each task targets exactly one of `--workflow <ref>`, `--prompt <text-or-ref>`,
2241
+ or `--command <shell>`. Task YAML is strict and begins with `version: 2`.
2242
+ Prompt targets dispatch through `--engine` or `defaults.engine` and may set
2243
+ `model`, `timeoutMs`, and LLM request overrides; command tasks may set only
2244
+ `timeoutMs`; workflow tasks may set only `params`. `task add` accepts
2245
+ `--engine`, `--model`, `--timeout-ms`, `--params`, `--name`, `--when-to-use`,
2246
+ `--description`, and `--tags`. A v1 task is diagnosed by sync and doctor
2247
+ but is never rewritten or executed.
2248
+
2249
+ A workflow-target task executes the same native orchestration as `akm workflow
2250
+ run`; it does not stop after creating a run. Completion maps to task
2251
+ `completed`, while workflow failure or verifier rejection maps to task
2252
+ `failed`. The task schema's `params` mapping remains the non-CLI way a scheduled
2253
+ definition supplies its new-run parameter snapshot.