akm-cli 0.9.0-rc.9 → 0.9.1-beta.1

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 (477) hide show
  1. package/CHANGELOG.md +1770 -44
  2. package/README.md +38 -47
  3. package/SECURITY.md +14 -1
  4. package/STABILITY.md +499 -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 +74 -89
  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 +148 -88
  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/llm-usage.js +2 -1
  57. package/dist/commands/health/md-report.js +5 -9
  58. package/dist/commands/health/metrics.js +62 -20
  59. package/dist/commands/health/renderers.js +47 -0
  60. package/dist/commands/health/report-view-model.js +4 -5
  61. package/dist/commands/health/stash-exposure.js +1 -1
  62. package/dist/commands/health/surfaces.js +4 -122
  63. package/dist/commands/health/task-runs.js +3 -67
  64. package/dist/commands/health/types-improve.js +7 -0
  65. package/dist/commands/health.js +160 -35
  66. package/dist/commands/improve/anti-collapse.js +2 -2
  67. package/dist/commands/improve/autonomy-gate.js +68 -0
  68. package/dist/commands/improve/collapse-detector.js +41 -40
  69. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  70. package/dist/commands/improve/consolidate/merge.js +4 -0
  71. package/dist/commands/improve/consolidate.js +140 -1000
  72. package/dist/commands/improve/distill/promote-memory.js +12 -12
  73. package/dist/commands/improve/distill/quality-gate.js +11 -6
  74. package/dist/commands/improve/distill.js +58 -69
  75. package/dist/commands/improve/eligibility.js +101 -55
  76. package/dist/commands/improve/extract-cli.js +14 -133
  77. package/dist/commands/improve/improve-cli.js +98 -114
  78. package/dist/commands/improve/improve-result-file.js +1 -28
  79. package/dist/commands/improve/improve-strategies.js +8 -5
  80. package/dist/commands/improve/improve.js +254 -101
  81. package/dist/commands/improve/locks.js +7 -0
  82. package/dist/commands/improve/loop-stages.js +182 -20
  83. package/dist/commands/improve/memory/derived-ref.js +45 -43
  84. package/dist/commands/improve/memory/memory-belief.js +1 -1
  85. package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
  86. package/dist/commands/improve/memory/memory-improve.js +14 -5
  87. package/dist/commands/improve/outcome-loop.js +22 -65
  88. package/dist/commands/improve/preparation.js +114 -123
  89. package/dist/commands/improve/proactive-maintenance.js +2 -5
  90. package/dist/commands/improve/reflect.js +56 -160
  91. package/dist/commands/improve/run-context.js +5 -0
  92. package/dist/commands/improve/salience.js +11 -122
  93. package/dist/commands/improve/session-asset.js +4 -0
  94. package/dist/commands/improve/source-identity.js +10 -38
  95. package/dist/commands/lint/base-linter.js +51 -131
  96. package/dist/commands/lint/env-key-rules.js +31 -47
  97. package/dist/commands/lint/index.js +444 -88
  98. package/dist/commands/lint/types.js +22 -1
  99. package/dist/commands/{events.js → log.js} +33 -38
  100. package/dist/commands/migrate-cli.js +92 -12
  101. package/dist/commands/migration-tool.js +46 -0
  102. package/dist/commands/observability-cli.js +70 -209
  103. package/dist/commands/proposal/drain.js +101 -29
  104. package/dist/commands/proposal/proposal-cli.js +76 -48
  105. package/dist/commands/proposal/proposal.js +54 -18
  106. package/dist/commands/proposal/propose-cli.js +88 -0
  107. package/dist/commands/proposal/propose.js +23 -15
  108. package/dist/commands/proposal/repository.js +718 -279
  109. package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
  110. package/dist/commands/proposal/validators/proposal-validators.js +55 -7
  111. package/dist/commands/proposal/validators/proposals.js +4 -7
  112. package/dist/commands/read/curate.js +34 -53
  113. package/dist/commands/read/knowledge.js +150 -95
  114. package/dist/commands/read/registry-search.js +2 -2
  115. package/dist/commands/read/remember-cli.js +42 -15
  116. package/dist/commands/read/search-cli.js +180 -78
  117. package/dist/commands/read/search.js +58 -43
  118. package/dist/commands/read/show.js +197 -141
  119. package/dist/commands/registry-cli.js +12 -51
  120. package/dist/commands/remember.js +14 -57
  121. package/dist/commands/sources/add-cli.js +100 -31
  122. package/dist/commands/sources/bundle-cli.js +166 -0
  123. package/dist/commands/sources/bundle-config-ops.js +7 -2
  124. package/dist/commands/sources/info.js +30 -7
  125. package/dist/commands/sources/init.js +12 -12
  126. package/dist/commands/sources/installed-stashes.js +387 -98
  127. package/dist/commands/sources/schema-repair.js +3 -2
  128. package/dist/commands/sources/self-update.js +131 -38
  129. package/dist/commands/sources/source-add.js +72 -17
  130. package/dist/commands/sources/source-clone.js +129 -45
  131. package/dist/commands/sources/source-manage.js +43 -23
  132. package/dist/commands/sources/sources-cli.js +57 -208
  133. package/dist/commands/sources/stash-cli.js +46 -53
  134. package/dist/commands/tasks/tasks-cli.js +91 -97
  135. package/dist/commands/tasks/tasks.js +284 -423
  136. package/dist/commands/workflow-cli.js +181 -450
  137. package/dist/core/abort-deadline.js +28 -0
  138. package/dist/core/adapter/adapters/agent-skills-adapter.js +67 -5
  139. package/dist/core/adapter/adapters/akm-adapter.js +60 -38
  140. package/dist/core/adapter/adapters/akm-lint.js +109 -42
  141. package/dist/core/adapter/adapters/akm-metadata.js +15 -44
  142. package/dist/core/adapter/adapters/akm-task-adapter.js +54 -31
  143. package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
  144. package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
  145. package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
  146. package/dist/core/adapter/adapters/index.js +6 -6
  147. package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
  148. package/dist/core/adapter/adapters/okf-adapter.js +187 -19
  149. package/dist/core/adapter/adapters/shared.js +3 -19
  150. package/dist/core/adapter/adapters/tool-dir-shared.js +13 -6
  151. package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
  152. package/dist/core/adapter/detect-adapter.js +17 -0
  153. package/dist/core/adapter/recognize-match.js +6 -4
  154. package/dist/core/adapter/validate-context.js +214 -0
  155. package/dist/core/asset/akm-markdown.js +63 -0
  156. package/dist/core/asset/asset-placement.js +20 -6
  157. package/dist/core/asset/asset-ref.js +11 -9
  158. package/dist/core/asset/frontmatter-lint.js +30 -0
  159. package/dist/core/asset/frontmatter.js +29 -9
  160. package/dist/core/asset/markdown.js +40 -51
  161. package/dist/core/asset/resolve-ref.js +89 -18
  162. package/dist/core/asset/stash-meta.js +1 -1
  163. package/dist/core/bundle-id.js +51 -0
  164. package/dist/core/common.js +218 -44
  165. package/dist/core/concurrent.js +32 -0
  166. package/dist/core/config/config-io.js +12 -1
  167. package/dist/core/config/config-schema.js +35 -8
  168. package/dist/core/config/config-sources.js +55 -11
  169. package/dist/core/config/config-walker.js +25 -9
  170. package/dist/core/config/config.js +9 -48
  171. package/dist/core/config/experimental.js +21 -0
  172. package/dist/core/config/schema/embedding.js +5 -1
  173. package/dist/core/config/schema/experimental.js +30 -0
  174. package/dist/core/config/schema/improve-processes.js +0 -6
  175. package/dist/core/config/schema/improve.js +21 -3
  176. package/dist/core/config/schema/index-config.js +8 -15
  177. package/dist/core/config/schema/output.js +4 -1
  178. package/dist/core/config/schema/setup.js +9 -18
  179. package/dist/core/config/schema/sources-bundles.js +49 -33
  180. package/dist/core/config/schema/workflow.js +14 -3
  181. package/dist/core/env-secret-ref.js +76 -46
  182. package/dist/core/errors.js +43 -12
  183. package/dist/core/events.js +76 -152
  184. package/dist/core/file-change.js +6 -5
  185. package/dist/core/file-lock.js +7 -1
  186. package/dist/core/fs-txn.js +83 -7
  187. package/dist/core/git-message.js +2 -2
  188. package/dist/core/improve-result.js +6 -100
  189. package/dist/core/json-schema.js +327 -9
  190. package/dist/core/lesson-lint.js +1 -17
  191. package/dist/core/logs-db.js +2 -1
  192. package/dist/core/loopback.js +89 -0
  193. package/dist/core/migration-operation.js +33 -2
  194. package/dist/core/mutation-target.js +78 -0
  195. package/dist/core/parse.js +4 -1
  196. package/dist/core/path-access.js +107 -0
  197. package/dist/core/paths.js +17 -20
  198. package/dist/core/recognition-util.js +12 -14
  199. package/dist/core/redaction.js +98 -17
  200. package/dist/core/spawn-env.js +234 -0
  201. package/dist/core/standards/resolve-standards-context.js +2 -14
  202. package/dist/core/standards/resolve-stash-standards.js +2 -2
  203. package/dist/core/standards/resolve-type-conventions.js +2 -2
  204. package/dist/core/state/migrations.js +41 -18
  205. package/dist/core/state-db-scope.js +134 -0
  206. package/dist/core/state-db.js +5 -14
  207. package/dist/core/structured.js +1 -1
  208. package/dist/core/subprocess.js +182 -36
  209. package/dist/core/text-truncation.js +9 -5
  210. package/dist/core/type-presentation.js +3 -3
  211. package/dist/core/warn.js +0 -3
  212. package/dist/core/write-provenance.js +85 -0
  213. package/dist/core/write-source.js +778 -95
  214. package/dist/indexer/bundle-identity-guard.js +3 -2
  215. package/dist/indexer/db/graph-db.js +17 -30
  216. package/dist/indexer/ensure-index.js +11 -3
  217. package/dist/indexer/graph/graph-boost.js +9 -34
  218. package/dist/indexer/graph/graph-extraction.js +8 -5
  219. package/dist/indexer/index-writer-lock.js +53 -17
  220. package/dist/indexer/index-written-assets.js +33 -24
  221. package/dist/indexer/indexer.js +551 -253
  222. package/dist/indexer/installations.js +14 -96
  223. package/dist/indexer/passes/dir-staleness.js +16 -9
  224. package/dist/indexer/passes/memory-inference.js +15 -9
  225. package/dist/indexer/passes/metadata.js +113 -47
  226. package/dist/indexer/scan/doc-to-entry.js +38 -1
  227. package/dist/indexer/scan/drain-dir.js +13 -23
  228. package/dist/indexer/search/db-search.js +107 -69
  229. package/dist/indexer/search/fts-query.js +47 -24
  230. package/dist/indexer/search/ranking-contributors.js +42 -20
  231. package/dist/indexer/search/ranking.js +18 -99
  232. package/dist/indexer/search/search-fields.js +7 -2
  233. package/dist/indexer/search/search-source.js +82 -93
  234. package/dist/indexer/usage/usage-events.js +0 -89
  235. package/dist/indexer/walk/file-context.js +2 -1
  236. package/dist/indexer/walk/matchers.js +30 -43
  237. package/dist/indexer/walk/path-resolver.js +7 -2
  238. package/dist/indexer/walk/walker.js +38 -12
  239. package/dist/integrations/agent/builders.js +0 -6
  240. package/dist/integrations/agent/config.js +2 -2
  241. package/dist/integrations/agent/detect.js +49 -19
  242. package/dist/integrations/agent/engine-fallback.js +76 -0
  243. package/dist/integrations/agent/engine-resolution.js +24 -11
  244. package/dist/integrations/agent/model-aliases.js +1 -1
  245. package/dist/integrations/agent/profiles.js +23 -1
  246. package/dist/integrations/agent/prompts.js +12 -8
  247. package/dist/integrations/agent/runner-dispatch.js +4 -2
  248. package/dist/integrations/agent/runner.js +0 -1
  249. package/dist/integrations/agent/spawn.js +20 -93
  250. package/dist/integrations/github.js +1 -1
  251. package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
  252. package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
  253. package/dist/integrations/harnesses/claude/session-log.js +0 -10
  254. package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
  255. package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
  256. package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
  257. package/dist/integrations/harnesses/index.js +3 -7
  258. package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
  259. package/dist/integrations/harnesses/opencode/session-log.js +0 -15
  260. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
  261. package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
  262. package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
  263. package/dist/integrations/lockfile.js +132 -8
  264. package/dist/integrations/session-logs/index.js +3 -28
  265. package/dist/llm/client.js +136 -100
  266. package/dist/llm/embedders/remote.js +13 -5
  267. package/dist/llm/feature-gate.js +4 -12
  268. package/dist/llm/graph-extract.js +5 -11
  269. package/dist/llm/memory-infer.js +144 -1
  270. package/dist/llm/metadata-enhance.js +5 -7
  271. package/dist/llm/structured-call.js +1 -1
  272. package/dist/llm/usage-persist.js +26 -5
  273. package/dist/llm/usage-telemetry.js +25 -2
  274. package/dist/output/cli-hints.js +1 -2
  275. package/dist/output/context.js +22 -7
  276. package/dist/output/format-exempt.js +80 -0
  277. package/dist/output/generic-render.js +259 -0
  278. package/dist/output/render-registry.js +57 -0
  279. package/dist/output/renderers.js +14 -36
  280. package/dist/output/shapes/curate.js +10 -1
  281. package/dist/output/shapes/events.js +12 -7
  282. package/dist/output/shapes/helpers.js +56 -83
  283. package/dist/output/shapes/migrate.js +8 -0
  284. package/dist/output/shapes/passthrough.js +7 -41
  285. package/dist/output/shapes/proposal/producer.js +15 -7
  286. package/dist/output/shapes.js +2 -9
  287. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  288. package/dist/output/text/bundle-show.js +7 -0
  289. package/dist/output/text/command-format.js +164 -96
  290. package/dist/output/text/env.js +1 -3
  291. package/dist/output/text/events.js +8 -7
  292. package/dist/output/text/health-format.js +103 -0
  293. package/dist/output/text/health.js +7 -0
  294. package/dist/output/text/helpers.js +10 -8
  295. package/dist/output/text/lint-format.js +56 -0
  296. package/dist/{migrate-storage-node.mjs → output/text/lint.js} +2 -5
  297. package/dist/output/text/migrate.js +88 -0
  298. package/dist/output/text/proposal/producer.js +4 -2
  299. package/dist/output/text/proposal-format.js +44 -72
  300. package/dist/output/text/registry-commands.js +1 -2
  301. package/dist/output/text/show-directives.js +15 -7
  302. package/dist/output/text/status-list.js +32 -0
  303. package/dist/output/text/{save.js → sync.js} +2 -2
  304. package/dist/output/text/workflow-format.js +24 -203
  305. package/dist/output/text/workflow.js +1 -7
  306. package/dist/output/text.js +16 -17
  307. package/dist/registry/factory.js +4 -6
  308. package/dist/registry/origin-resolve.js +16 -27
  309. package/dist/registry/providers/skills-sh.js +3 -3
  310. package/dist/registry/providers/static-index.js +13 -23
  311. package/dist/registry/resolve.js +42 -7
  312. package/dist/registry/semver.js +34 -84
  313. package/dist/runtime.js +2 -23
  314. package/dist/scripts/akm-migrate-node.js +60972 -0
  315. package/dist/scripts/akm-migrate.js +60310 -0
  316. package/dist/setup/detect.js +42 -15
  317. package/dist/setup/registry-stash-loader.js +2 -2
  318. package/dist/setup/setup.js +236 -136
  319. package/dist/setup/steps/connection.js +7 -9
  320. package/dist/setup/steps/platforms.js +9 -9
  321. package/dist/setup/steps/semantic.js +15 -3
  322. package/dist/setup/steps/sources.js +12 -13
  323. package/dist/setup/steps/stashdir.js +2 -3
  324. package/dist/setup/steps/tasks.js +237 -120
  325. package/dist/sources/freshness.js +1 -1
  326. package/dist/sources/provider-factory.js +11 -17
  327. package/dist/sources/providers/filesystem.js +2 -3
  328. package/dist/sources/providers/git-install.js +278 -34
  329. package/dist/sources/providers/git-provider.js +25 -23
  330. package/dist/sources/providers/git-stash.js +414 -106
  331. package/dist/sources/providers/git.js +2 -2
  332. package/dist/sources/providers/npm.js +16 -19
  333. package/dist/sources/providers/provider-utils.js +7 -4
  334. package/dist/sources/providers/sync-from-ref.js +3 -9
  335. package/dist/sources/providers/website.js +6 -1
  336. package/dist/sources/resolve.js +6 -5
  337. package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
  338. package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
  339. package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
  340. package/dist/sources/snapshot-fetchers/github.js +100 -0
  341. package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
  342. package/dist/sources/snapshot-fetchers/registry.js +17 -1
  343. package/dist/sources/snapshot-fetchers/robots.js +348 -0
  344. package/dist/sources/snapshot-fetchers/rss.js +282 -0
  345. package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
  346. package/dist/sources/snapshot-fetchers/website-ingest.js +686 -282
  347. package/dist/sources/snapshot-fetchers/x.js +910 -0
  348. package/dist/storage/database.js +13 -1
  349. package/dist/storage/engines/sqlite-migrations.js +23 -111
  350. package/dist/storage/managed-db.js +21 -2
  351. package/dist/storage/repositories/canaries-repository.js +1 -1
  352. package/dist/storage/repositories/events-repository.js +27 -11
  353. package/dist/storage/repositories/improve-runs-repository.js +6 -12
  354. package/dist/storage/repositories/index-connection.js +44 -8
  355. package/dist/storage/repositories/index-entries-repository.js +157 -241
  356. package/dist/storage/repositories/index-entry-mapper.js +15 -11
  357. package/dist/storage/repositories/index-fts-repository.js +5 -2
  358. package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
  359. package/dist/storage/repositories/index-meta-repository.js +2 -3
  360. package/dist/storage/repositories/index-schema.js +10 -25
  361. package/dist/storage/repositories/index-utility-repository.js +15 -28
  362. package/dist/storage/repositories/index-vec-repository.js +6 -1
  363. package/dist/storage/repositories/outcome-repository.js +119 -0
  364. package/dist/storage/repositories/proposals-repository.js +296 -59
  365. package/dist/storage/repositories/registry-cache.js +19 -0
  366. package/dist/storage/repositories/salience-repository.js +172 -0
  367. package/dist/storage/repositories/task-history-repository.js +15 -13
  368. package/dist/storage/repositories/workflow-runs-repository.js +118 -53
  369. package/dist/tasks/backends/cron.js +105 -15
  370. package/dist/tasks/backends/index.js +1 -1
  371. package/dist/tasks/backends/launchd.js +85 -38
  372. package/dist/tasks/backends/schtasks.js +135 -15
  373. package/dist/tasks/embedded.js +56 -40
  374. package/dist/tasks/log-redaction.js +156 -0
  375. package/dist/tasks/parser.js +87 -160
  376. package/dist/tasks/resolve-akm-bin.js +137 -59
  377. package/dist/tasks/runner.js +209 -44
  378. package/dist/tasks/scheduler-invocation.js +220 -10
  379. package/dist/tasks/schema.js +89 -1
  380. package/dist/tasks/task-id.js +1 -3
  381. package/dist/tasks/validator.js +20 -6
  382. package/dist/workflows/authoring/authoring.js +94 -143
  383. package/dist/workflows/authoring/scope-key.js +1 -1
  384. package/dist/workflows/concurrency-policy.js +95 -1
  385. package/dist/workflows/exec/dispatch-redaction.js +114 -0
  386. package/dist/workflows/exec/exec-unit.js +542 -0
  387. package/dist/workflows/exec/frozen-judge.js +130 -32
  388. package/dist/workflows/exec/native-executor.js +513 -274
  389. package/dist/workflows/exec/param-secrets.js +12 -11
  390. package/dist/workflows/exec/run-workflow.js +496 -237
  391. package/dist/workflows/exec/step-work.js +616 -412
  392. package/dist/workflows/exec/unit-dispatch.js +34 -0
  393. package/dist/workflows/exec/unit-writer.js +53 -13
  394. package/dist/workflows/exec/worktree.js +454 -41
  395. package/dist/workflows/ir/compile.js +166 -271
  396. package/dist/workflows/ir/freeze.js +119 -42
  397. package/dist/workflows/ir/params.js +135 -11
  398. package/dist/workflows/ir/plan-hash.js +1 -1
  399. package/dist/workflows/ir/schema.js +129 -45
  400. package/dist/workflows/parser.js +1070 -307
  401. package/dist/workflows/program/expressions.js +20 -208
  402. package/dist/workflows/program/schema.js +31 -10
  403. package/dist/workflows/renderer.js +123 -68
  404. package/dist/workflows/resource-limits.js +184 -0
  405. package/dist/workflows/runtime/checkin.js +3 -3
  406. package/dist/workflows/runtime/plan-classifier.js +16 -75
  407. package/dist/workflows/runtime/runs.js +331 -132
  408. package/dist/workflows/runtime/unit-checkin.js +1 -1
  409. package/dist/workflows/runtime/unit-phases.js +2 -2
  410. package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
  411. package/dist/workflows/schema.js +1 -11
  412. package/dist/workflows/validate-summary.js +47 -38
  413. package/dist/workflows/validator.js +21 -62
  414. package/docs/README.md +110 -0
  415. package/docs/migration/README.md +8 -0
  416. package/docs/migration/release-notes/0.7.0.md +11 -11
  417. package/docs/migration/release-notes/0.9.0.md +209 -27
  418. package/docs/migration/v0.7-to-v0.8.md +48 -48
  419. package/docs/migration/v0.8-to-v0.9.md +567 -209
  420. package/docs/migration/v0.9.0-troubleshooting.md +561 -0
  421. package/docs/reference/README.md +19 -0
  422. package/docs/reference/bundle-types.md +19 -0
  423. package/docs/reference/cli.md +2342 -0
  424. package/docs/reference/configuration.md +371 -0
  425. package/docs/reference/data-and-telemetry.md +129 -46
  426. package/docs/reference/supported-formats.md +50 -0
  427. package/docs/reference/workflow-schema.md +1014 -0
  428. package/docs/reference/workflows.md +51 -0
  429. package/package.json +31 -13
  430. package/schemas/akm-asset-envelope.json +93 -0
  431. package/schemas/akm-config.json +89 -128
  432. package/schemas/akm-task.json +27 -5
  433. package/schemas/akm-workflow.json +157 -81
  434. package/dist/assets/tasks/core/backup.yml +0 -5
  435. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  436. package/dist/cli/config-migrate.js +0 -1878
  437. package/dist/cli/config-validate.js +0 -41
  438. package/dist/commands/backup-cli.js +0 -56
  439. package/dist/commands/bundle/bundle-cli.js +0 -68
  440. package/dist/commands/bundle/bundle.js +0 -219
  441. package/dist/commands/graph/graph-cli.js +0 -124
  442. package/dist/commands/graph/graph.js +0 -489
  443. package/dist/commands/improve/extract-watch.js +0 -140
  444. package/dist/commands/mv-cli.js +0 -1221
  445. package/dist/commands/sources/history.js +0 -201
  446. package/dist/commands/tasks/default-tasks.js +0 -186
  447. package/dist/core/migration-backup.js +0 -1231
  448. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
  449. package/dist/llm/memory-infer-impl.js +0 -138
  450. package/dist/migrate/legacy/config-source-migration.js +0 -257
  451. package/dist/migrate/legacy/content-migration.js +0 -350
  452. package/dist/migrate/legacy/legacy-layout.js +0 -779
  453. package/dist/migrate/legacy/legacy-paths.js +0 -25
  454. package/dist/migrate/legacy/legacy-stash-json.js +0 -80
  455. package/dist/migrate/legacy/proposal-fs-import.js +0 -168
  456. package/dist/migrate/legacy/task-target-ref-migration.js +0 -278
  457. package/dist/migrate/legacy/three-db-cutover.js +0 -845
  458. package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
  459. package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
  460. package/dist/migrate/legacy-ref-grammar.js +0 -214
  461. package/dist/output/shapes/distill.js +0 -14
  462. package/dist/output/shapes/history.js +0 -11
  463. package/dist/output/text/distill.js +0 -6
  464. package/dist/output/text/enable-disable.js +0 -8
  465. package/dist/output/text/history.js +0 -6
  466. package/dist/registry/build-index.js +0 -382
  467. package/dist/schemas/akm-config.json +0 -4704
  468. package/dist/schemas/akm-task.json +0 -87
  469. package/dist/schemas/akm-workflow.json +0 -372
  470. package/dist/scripts/migrate-storage.js +0 -3816
  471. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  472. package/dist/workflows/cli.js +0 -53
  473. package/dist/workflows/exec/brief.js +0 -481
  474. package/dist/workflows/exec/report.js +0 -1460
  475. package/dist/workflows/exec/watch.js +0 -116
  476. package/dist/workflows/program/parser.js +0 -813
  477. package/dist/workflows/program/project.js +0 -104
@@ -7,7 +7,7 @@
7
7
  * Given a single asset body (typically a `memory:` or `knowledge:` file),
8
8
  * asks the configured LLM to surface the entities mentioned in it and the
9
9
  * relations between them. The pass itself
10
- * (`src/indexer/graph-extraction.ts`) is responsible for deciding which
10
+ * (`src/indexer/graph/graph-extraction.ts`) is responsible for deciding which
11
11
  * files to extract, persisting the resulting nodes/edges to the index DB,
12
12
  * and feeding the graph data into the FTS5+boosts
13
13
  * search pipeline as a single boost component.
@@ -15,16 +15,15 @@
15
15
  * This module is intentionally tiny and stateless so tests can stub it via
16
16
  * `mock.module("../src/llm/graph-extract", ...)` without hitting a network.
17
17
  *
18
- * Locked v1 contract (#208): the LLM connection always comes from the
19
- * selected named LLM engine. Callers obtain
20
- * the connection via `resolveIndexPassLLM("graph", config)` and pass it
21
- * straight through.
18
+ * The LLM connection comes from the selected named engine. Callers obtain it
19
+ * via `resolveIndexPassLLM("graph", config)` and pass it straight through.
22
20
  */
23
21
  import systemPromptTemplate from "../assets/prompts/graph-extract-system.md" with { type: "text" };
24
22
  import userPromptTemplate from "../assets/prompts/graph-extract-user-prompt.md" with { type: "text" };
25
23
  import { toErrorMessage } from "../core/common.js";
24
+ import { parseEmbeddedJsonResponse } from "../core/parse.js";
26
25
  import { warn, warnVerbose } from "../core/warn.js";
27
- import { chatCompletion, isContextSizeError, parseEmbeddedJsonResponse } from "./client.js";
26
+ import { chatCompletion, isContextSizeError } from "./client.js";
28
27
  import { tryLlmFeature } from "./feature-gate.js";
29
28
  import { callStructured } from "./structured-call.js";
30
29
  /**
@@ -47,11 +46,6 @@ const SYSTEM_PROMPT = systemPromptTemplate;
47
46
  const USER_PROMPT_PREFIX = userPromptTemplate
48
47
  .replace("{{MAX_ENTITIES}}", String(MAX_ENTITIES_PER_ASSET))
49
48
  .replace("{{MAX_RELATIONS}}", String(MAX_RELATIONS_PER_ASSET));
50
- // `isContextSizeError` is defined in `./client` and re-exported here so the
51
- // graph extractor and the retry classifier (`isRetryable`) share one
52
- // definition (#496). Re-exported (not just imported) to preserve existing
53
- // importers of this module — including its unit test.
54
- export { isContextSizeError } from "./client.js";
55
49
  const GENERIC_ENTITIES = new Set([
56
50
  "agent",
57
51
  "application",
@@ -1,4 +1,147 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- export { compressMemoryToDerivedMemory, } from "./memory-infer-impl.js";
4
+ /**
5
+ * LLM helper for the `akm index` memory-inference pass (#201).
6
+ *
7
+ * Compresses a single memory body into one higher-signal derived memory. The
8
+ * pass itself (in `src/indexer/passes/memory-inference.ts`) is responsible for
9
+ * deciding which memories are pending, persisting the derived memory with the
10
+ * correct frontmatter (`inferred: true`, `source: <parent-ref>`), and marking
11
+ * the parent as processed for idempotency.
12
+ *
13
+ * This module is intentionally tiny and stateless so tests can stub it via
14
+ * `mock.module("../src/llm/memory-infer", ...)` without hitting a network.
15
+ *
16
+ * The LLM connection comes from the selected named engine. Callers obtain it
17
+ * via `resolveIndexPassLLM("memory", config)` and pass it straight through.
18
+ */
19
+ import memoryInferSystemPrompt from "../assets/prompts/memory-infer-system.md" with { type: "text" };
20
+ import memoryInferUserPrompt from "../assets/prompts/memory-infer-user.md" with { type: "text" };
21
+ import { toErrorMessage } from "../core/common.js";
22
+ import { parseEmbeddedJsonResponse } from "../core/parse.js";
23
+ import { warn } from "../core/warn.js";
24
+ import { callStructured } from "./structured-call.js";
25
+ /** Hard cap on body chars sent to the model — pragmatic and matches `runLlmEnrich`. */
26
+ const MAX_BODY_CHARS = 4000;
27
+ const SYSTEM_PROMPT = memoryInferSystemPrompt;
28
+ const USER_PROMPT_PREFIX = memoryInferUserPrompt;
29
+ const PROMPT_PLACEHOLDERS = new Set([
30
+ "short title string",
31
+ "one sentence summary string",
32
+ "tag1",
33
+ "tag2",
34
+ "search phrase 1",
35
+ "search phrase 2",
36
+ "2-3 sentence compressed body preserving key facts verbatim",
37
+ ]);
38
+ /**
39
+ * Strict JSON Schema for the derived-memory payload. Sent to providers that
40
+ * opt in via `ChatCompletionConfig.supportsJsonSchema = true`; the client
41
+ * silently drops the schema for providers that don't.
42
+ *
43
+ * Extends the responseSchema lift (PR 1, asset-writers-investigation §5) to
44
+ * the memory-inference path. Mirrors the validation gate below
45
+ * (title/description/content + non-empty tags/searchHints) so a
46
+ * schema-compliant response is guaranteed to pass the downstream check
47
+ * — no more "incomplete derived memory payload from LLM; skipping memory"
48
+ * for shape-only failures.
49
+ */
50
+ const DERIVED_MEMORY_JSON_SCHEMA = {
51
+ type: "object",
52
+ properties: {
53
+ title: { type: "string", minLength: 1 },
54
+ description: { type: "string", minLength: 1 },
55
+ content: { type: "string", minLength: 1 },
56
+ tags: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 8 },
57
+ searchHints: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 6 },
58
+ },
59
+ required: ["title", "description", "content", "tags", "searchHints"],
60
+ additionalProperties: false,
61
+ };
62
+ /**
63
+ * Compress a single memory body into one derived memory via the configured LLM.
64
+ *
65
+ * Returns `undefined` on any failure (timeout, invalid JSON, empty response).
66
+ * Errors are logged via `warn()` but never thrown — a failed split for one memory
67
+ * must not abort the rest of the index pass.
68
+ *
69
+ * Routes through `callStructured({ feature: "memory_inference", ... })` so the
70
+ * feature gate, error classification, and onFallback hook are honoured uniformly
71
+ * (Fix C5).
72
+ */
73
+ export async function compressMemoryToDerivedMemory(llmConfig, body, signal, akmConfig, onFallback, telemetry, onRetryAttempt) {
74
+ const trimmedBody = body.trim();
75
+ if (!trimmedBody)
76
+ return undefined;
77
+ const userPrompt = `${USER_PROMPT_PREFIX}${trimmedBody.slice(0, MAX_BODY_CHARS)}`;
78
+ // Memory inference is always gated: no config closes the gate instead of
79
+ // taking callStructured's ungated path for direct callers.
80
+ if (!akmConfig) {
81
+ onFallback?.({ feature: "memory_inference", reason: "disabled" });
82
+ return undefined;
83
+ }
84
+ return callStructured({
85
+ feature: "memory_inference",
86
+ akmConfig,
87
+ config: llmConfig,
88
+ messages: [
89
+ { role: "system", content: SYSTEM_PROMPT },
90
+ { role: "user", content: userPrompt },
91
+ ],
92
+ request: {
93
+ temperature: 0.1,
94
+ timeoutMs: llmConfig.timeoutMs,
95
+ signal,
96
+ responseSchema: DERIVED_MEMORY_JSON_SCHEMA,
97
+ onRetryAttempt,
98
+ },
99
+ parse: (raw) => {
100
+ if (!raw)
101
+ return undefined;
102
+ const parsed = parseEmbeddedJsonResponse(raw);
103
+ if (!parsed) {
104
+ warn("memory inference: invalid JSON response from LLM; skipping memory.");
105
+ return undefined;
106
+ }
107
+ const title = typeof parsed.title === "string" ? parsed.title.trim() : "";
108
+ const description = typeof parsed.description === "string" ? parsed.description.trim() : "";
109
+ const content = typeof parsed.content === "string" ? parsed.content.trim() : "";
110
+ const tags = Array.isArray(parsed.tags)
111
+ ? parsed.tags
112
+ .filter((t) => typeof t === "string")
113
+ .map((t) => t.trim())
114
+ .filter(Boolean)
115
+ .slice(0, 8)
116
+ : [];
117
+ const searchHints = Array.isArray(parsed.searchHints)
118
+ ? parsed.searchHints
119
+ .filter((h) => typeof h === "string")
120
+ .map((h) => h.trim())
121
+ .filter(Boolean)
122
+ .slice(0, 6)
123
+ : [];
124
+ if (!title || !description || !content || tags.length === 0 || searchHints.length === 0) {
125
+ warn("memory inference: incomplete derived memory payload from LLM; skipping memory.");
126
+ return undefined;
127
+ }
128
+ if ([title, description, content, ...tags, ...searchHints].some((value) => PROMPT_PLACEHOLDERS.has(value.toLowerCase()))) {
129
+ warn("memory inference: prompt placeholder response from LLM; skipping memory.");
130
+ return undefined;
131
+ }
132
+ return { title, description, tags, searchHints, content };
133
+ },
134
+ onError: (cls, err) => {
135
+ if (cls === "html") {
136
+ if (telemetry)
137
+ telemetry.htmlErrorCount = (telemetry.htmlErrorCount ?? 0) + 1;
138
+ warn(`memory inference: provider returned HTML instead of JSON; skipping memory: ${toErrorMessage(err)}`);
139
+ return undefined;
140
+ }
141
+ warn(`memory inference failed: ${toErrorMessage(err)}`);
142
+ return undefined;
143
+ },
144
+ fallback: undefined,
145
+ onFallback,
146
+ });
147
+ }
@@ -4,12 +4,11 @@
4
4
  /**
5
5
  * LLM-driven metadata enhancement for stash entries.
6
6
  *
7
- * Split out of `llm.ts` so the higher-level workflow (prompting the LLM to
8
- * improve descriptions/tags/searchHints) lives separately from the low-level
9
- * transport client in `client.ts`.
7
+ * Keeps the higher-level workflow for improving descriptions, tags, and search
8
+ * hints separate from the low-level transport client.
10
9
  */
11
10
  import metadataEnhanceSystemPrompt from "../assets/prompts/metadata-enhance-system.md" with { type: "text" };
12
- import { parseJsonResponse } from "./client.js";
11
+ import { parseJsonResponse } from "../core/parse.js";
13
12
  import { callStructured } from "./structured-call.js";
14
13
  const SYSTEM_PROMPT = metadataEnhanceSystemPrompt;
15
14
  /**
@@ -20,9 +19,8 @@ const SYSTEM_PROMPT = metadataEnhanceSystemPrompt;
20
19
  * `tryLlmFeature("metadata_enhance", ...)` so the feature gate is honoured: a
21
20
  * closed gate yields `{ status: "skipped" }` and a thrown/timed-out call yields
22
21
  * `{ status: "failed" }` — neither is reported as an enrichment. When
23
- * `akmConfig` is `undefined` the gate is bypassed entirely — the LLM call runs
24
- * unconditionally and errors propagate to the caller (pre-gate behaviour, used
25
- * by direct callers such as tests).
22
+ * `akmConfig` is `undefined` the gate is bypassed entirely: the LLM call runs
23
+ * unconditionally and errors propagate to direct callers such as tests.
26
24
  */
27
25
  export async function enhanceMetadata(config, entry, fileContent, signal, akmConfig) {
28
26
  const contextParts = [`Name: ${entry.name}`, `Type: ${entry.type}`];
@@ -1,7 +1,7 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { chatCompletion, isContextSizeError, LlmCallError } from "./client.js";
4
+ import { chatCompletion, isContextSizeError, LlmCallError, } from "./client.js";
5
5
  import { tryLlmFeature } from "./feature-gate.js";
6
6
  /**
7
7
  * Classify a thrown LLM error into one of the three buckets. This is the single
@@ -23,12 +23,18 @@ import { appendEvent } from "../core/events.js";
23
23
  import { clearLlmUsageSink, hasLlmUsageSink, setLlmUsageSink } from "./usage-telemetry.js";
24
24
  /** Event type for persisted per-call LLM usage telemetry. */
25
25
  export const LLM_USAGE_EVENT = "llm_usage";
26
+ /** Event type for the owning sink's terminal-record count marker. */
27
+ export const LLM_USAGE_SUMMARY_EVENT = "llm_usage_summary";
26
28
  /**
27
29
  * Project a usage record into event metadata, dropping `undefined` token
28
30
  * fields so an absent-usage call records only `{stage, model, durationMs}`.
29
31
  */
30
32
  function toEventMetadata(record) {
31
- const metadata = { durationMs: record.durationMs };
33
+ const metadata = {
34
+ durationMs: record.durationMs,
35
+ outcome: record.outcome,
36
+ modelSource: record.modelSource,
37
+ };
32
38
  if (record.stage !== undefined)
33
39
  metadata.stage = record.stage;
34
40
  if (record.engine !== undefined)
@@ -47,6 +53,8 @@ function toEventMetadata(record) {
47
53
  metadata.totalTokens = record.totalTokens;
48
54
  if (record.reasoningTokens !== undefined)
49
55
  metadata.reasoningTokens = record.reasoningTokens;
56
+ if (record.errorCode !== undefined)
57
+ metadata.errorCode = record.errorCode;
50
58
  return metadata;
51
59
  }
52
60
  /**
@@ -56,20 +64,33 @@ function toEventMetadata(record) {
56
64
  * test-isolation harness sees a clean sink between tests).
57
65
  *
58
66
  * `ctx` should carry the same long-lived `state.db` handle the caller already
59
- * opened for its other events; when omitted, `appendEvent` falls back to its
60
- * default open-insert-close path.
67
+ * opened for its other events. A getter is resolved for every append so a
68
+ * caller can replace its context binding without replacing this owning sink.
69
+ * When omitted, `appendEvent` falls back to its default open-insert-close path.
61
70
  */
62
71
  export function installLlmUsagePersistence(ctx) {
72
+ let expectedTerminalRecords = 0;
73
+ let disposed = false;
63
74
  setLlmUsageSink((record) => {
64
- appendEvent({ eventType: LLM_USAGE_EVENT, metadata: toEventMetadata(record) }, ctx);
75
+ expectedTerminalRecords += 1;
76
+ appendEvent({ eventType: LLM_USAGE_EVENT, metadata: toEventMetadata(record) }, typeof ctx === "function" ? ctx() : ctx);
65
77
  });
66
78
  return () => {
79
+ if (disposed)
80
+ return;
81
+ disposed = true;
67
82
  clearLlmUsageSink();
83
+ try {
84
+ appendEvent({ eventType: LLM_USAGE_SUMMARY_EVENT, metadata: { expectedTerminalRecords } }, typeof ctx === "function" ? ctx() : ctx);
85
+ }
86
+ catch {
87
+ // Persistence remains best-effort even during run teardown.
88
+ }
68
89
  };
69
90
  }
70
91
  /**
71
92
  * Like {@link installLlmUsagePersistence}, but a no-op when a sink is already
72
- * installed — used by standalone entry points (`akm consolidate`, `akm drain`)
93
+ * installed — used by standalone entry points (`akm proposal drain`)
73
94
  * that may also run as a sub-step of `akm improve`. When invoked inside an
74
95
  * enclosing run the existing per-run sink keeps ownership; the returned
75
96
  * disposer then does nothing, so the enclosing run's `finally` still clears it.
@@ -5,7 +5,8 @@
5
5
  * Per-call LLM usage telemetry (#576).
6
6
  *
7
7
  * `chatCompletion` captures usage + model + finish_reason + wall-time for
8
- * EVERY OpenAI-compatible call and emits one {@link LlmUsageRecord} through a
8
+ * EVERY OpenAI-compatible HTTP attempt and emits one terminal
9
+ * {@link LlmUsageRecord} through a
9
10
  * module-level sink. The sink indirection keeps `client.ts` free of any
10
11
  * dependency on the events/db layer: the application wires the sink to
11
12
  * persistence at startup / per improve run, and tests can inspect records in
@@ -87,6 +88,20 @@ function asFiniteNonNegative(value) {
87
88
  function asNonEmptyString(value) {
88
89
  return typeof value === "string" && value.length > 0 ? value : undefined;
89
90
  }
91
+ function asLlmUsageErrorCode(value) {
92
+ switch (value) {
93
+ case "rate_limited":
94
+ case "provider_error":
95
+ case "provider_html_error":
96
+ case "network_error":
97
+ case "parse_error":
98
+ case "timeout":
99
+ case "unknown_error":
100
+ return value;
101
+ default:
102
+ return undefined;
103
+ }
104
+ }
90
105
  /** Decode durable event metadata with the same validation used by health aggregation. */
91
106
  export function decodeLlmUsageRecord(value) {
92
107
  if (!value || typeof value !== "object")
@@ -95,7 +110,12 @@ export function decodeLlmUsageRecord(value) {
95
110
  const durationMs = asFiniteNonNegative(raw.durationMs);
96
111
  if (durationMs === undefined)
97
112
  return undefined;
98
- const record = { durationMs };
113
+ // Historical rows predate terminal provenance. Keep health aggregation
114
+ // backward-compatible while conservatively treating their model as configured,
115
+ // never response-observed.
116
+ const outcome = raw.outcome === "success" || raw.outcome === "error" ? raw.outcome : "success";
117
+ const modelSource = raw.modelSource === "response" || raw.modelSource === "configured" ? raw.modelSource : "configured";
118
+ const record = { durationMs, outcome, modelSource };
99
119
  for (const key of ["stage", "engine", "process", "model", "finishReason"]) {
100
120
  const decoded = asNonEmptyString(raw[key]);
101
121
  if (decoded !== undefined)
@@ -106,6 +126,9 @@ export function decodeLlmUsageRecord(value) {
106
126
  if (decoded !== undefined)
107
127
  record[key] = decoded;
108
128
  }
129
+ const errorCode = asLlmUsageErrorCode(raw.errorCode);
130
+ if (errorCode !== undefined)
131
+ record.errorCode = errorCode;
109
132
  return record;
110
133
  }
111
134
  /**
@@ -2,8 +2,7 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  /**
5
- * Embedded "agent CLI hints" rendered by `akm hints` when no other source
6
- * is available.
5
+ * Embedded agent CLI guide rendered by `akm hints` and `akm help agents`.
7
6
  *
8
7
  * Extracted from `src/cli.ts` so it does not bloat the CLI module and so
9
8
  * docs/CI tooling can re-use the same constants. Two flavors:
@@ -9,7 +9,9 @@
9
9
  * calls read from this in-memory singleton instead of re-scanning argv and
10
10
  * re-loading config on every call.
11
11
  *
12
- * Initialized from `cli.ts` before `runMain`.
12
+ * Initialized from `cli.ts` before `runCli` dispatches the command (`cli.ts`
13
+ * drives citty's `runCommand` directly rather than `runMain` — see the
14
+ * top-level driver comment there).
13
15
  */
14
16
  import { UsageError } from "../core/errors.js";
15
17
  const OUTPUT_FORMATS = ["json", "yaml", "text", "jsonl", "md", "html"];
@@ -39,6 +41,8 @@ function parseShapeMode(value) {
39
41
  export function parseFlagValue(argv, flag) {
40
42
  for (let i = 0; i < argv.length; i++) {
41
43
  const arg = argv[i];
44
+ if (arg === "--")
45
+ break;
42
46
  if (arg === flag)
43
47
  return argv[i + 1];
44
48
  if (arg.startsWith(`${flag}=`))
@@ -47,15 +51,26 @@ export function parseFlagValue(argv, flag) {
47
51
  return undefined;
48
52
  }
49
53
  export function hasBooleanFlag(argv, flag) {
50
- return argv.some((arg) => arg === flag || arg === `${flag}=true`);
54
+ for (const arg of argv) {
55
+ if (arg === "--")
56
+ return false;
57
+ if (arg === flag || arg === `${flag}=true`)
58
+ return true;
59
+ }
60
+ return false;
51
61
  }
52
62
  /**
53
63
  * Read a hyphenated arg out of citty's parsed `args` object.
54
64
  *
55
- * citty does not auto-camelise hyphenated arg keys (see `--max-pages`,
56
- * `--with-sources` for the existing convention), so command handlers end up
57
- * casting `args` to a string-indexed record at every read site. This helper
58
- * encapsulates the cast.
65
+ * Verified live: citty DOES auto-camelise a DECLARED hyphenated arg — for
66
+ * `"max-pages": { type: "string" }` in a command's `args`, citty's parsed
67
+ * object answers both `args["max-pages"]` and `args.maxPages` (a `Proxy`
68
+ * falls back through `camelCase`/`kebabCase`, and `--no-<flag>` negation is
69
+ * handled the same way for booleans). What citty's own TS types do NOT give
70
+ * callers is a statically-typed handle on that mapping, and command handlers
71
+ * here type `args` as `unknown` at the boundary — so every read site still
72
+ * needs a cast. This helper encapsulates that cast; it exists for typing
73
+ * convenience, not to work around a citty parsing limitation.
59
74
  */
60
75
  export function getHyphenatedArg(args, key) {
61
76
  if (typeof args !== "object" || args === null)
@@ -81,7 +96,7 @@ export function resolveOutputMode(argv, defaults = {}) {
81
96
  const detail = parseDetailLevel(rawDetail) ?? defaults?.detail ?? "brief";
82
97
  const shape = parseShapeMode(rawShape) ?? "human";
83
98
  const outputPath = parseFlagValue(argv, "--output");
84
- return { format, detail, shape, forAgent: shape === "agent", ...(outputPath ? { outputPath } : {}) };
99
+ return { format, detail, shape, ...(outputPath ? { outputPath } : {}) };
85
100
  }
86
101
  let _mode;
87
102
  /**
@@ -0,0 +1,80 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * Commands whose output is not an envelope, and therefore not formattable (D7).
6
+ *
7
+ * D7 makes all six `--format` values work on every command that renders through
8
+ * `output()`. A small set does not render an envelope at all: they emit a shell
9
+ * script, drive an interactive prompt, hand stdout to a child process, or print
10
+ * a document that IS the payload. Passing `--format` to one of those cannot do
11
+ * anything useful.
12
+ *
13
+ * The point of declaring the set here is that the exemption stops being
14
+ * implicit. Before D7 you discovered it by getting JSON when you asked for
15
+ * Markdown, or an exit 2 when you asked for HTML. Now the list is one grep away,
16
+ * it is documented in `STABILITY.md`, and asking for a format on an exempt
17
+ * command warns instead of silently doing something else.
18
+ *
19
+ * Names are canonical command paths resolved from the Citty tree.
20
+ */
21
+ /**
22
+ * Top-level command tokens whose entire surface is format-exempt.
23
+ */
24
+ const EXEMPT_COMMANDS = new Set([
25
+ // Emits shell completion script source for eval.
26
+ "completions",
27
+ // `migrate status`/`apply` used to be exempt here too: `runMigrationTool`
28
+ // (src/commands/migration-tool.ts) spawns the standalone
29
+ // `scripts/akm-migrate.ts` tool, which always emitted its own fixed JSON
30
+ // shape and never consulted `--format`. `src/commands/migrate-cli.ts` now
31
+ // parses that child's final result line and renders it through the normal
32
+ // `output()` pipeline (registered shape: `src/output/shapes/migrate.ts`;
33
+ // text renderer: `src/output/text/migrate.ts`), so both subcommands honour
34
+ // `--format` like any other command and are no longer listed here. Any
35
+ // progress-event lines the child prints during a real `apply` still print
36
+ // verbatim ahead of the formatted result — those are operational logging,
37
+ // not part of the result envelope, the same way a progress spinner would be.
38
+ // Document payload group: bare `help` prints the sectioned overview,
39
+ // `help migrate <version>` prints release notes, and `help agents` prints
40
+ // the embedded CLI-reference guide (`src/output/cli-hints.ts`) — none of
41
+ // the three render a result envelope.
42
+ "help",
43
+ // Embedded agent guide document.
44
+ "hints",
45
+ ]);
46
+ /**
47
+ * `<command> <subcommand>` pairs that are exempt while the rest of the group
48
+ * formats normally.
49
+ */
50
+ const EXEMPT_SUBCOMMANDS = new Set([
51
+ // Child-process passthrough (the env/secret groups otherwise format fine).
52
+ "env run",
53
+ "secret run",
54
+ // B3/B4 (W1-F): a bare absolute filesystem path IS the payload — the
55
+ // documented shell-substitution primitive (`$(akm env path <ref>)`,
56
+ // Docker `_FILE` / `--env-file`) — not a field worth wrapping in an
57
+ // envelope. Wrapping it broke every existing substitution silently: the
58
+ // CLI's default format is `json`, so an un-flagged `akm env path <ref>`
59
+ // (exactly how the substitution is always written) started emitting
60
+ // `{"path":"..."}` instead of the raw path. Unlike `config path`, this
61
+ // command has no `--all`-style multi-field variant, so the whole surface
62
+ // can be exempt without wrongly warning on a real envelope case.
63
+ "env path",
64
+ ]);
65
+ /**
66
+ * True when `--format` cannot meaningfully apply to this invocation.
67
+ *
68
+ * `commandPath` contains canonical Citty command names from the top-level
69
+ * command through the deepest resolved subcommand.
70
+ */
71
+ export function isFormatExemptCommand(commandPath) {
72
+ const command = commandPath[0];
73
+ if (command === undefined)
74
+ return false;
75
+ return EXEMPT_COMMANDS.has(command) || EXEMPT_SUBCOMMANDS.has(commandPath.join(" "));
76
+ }
77
+ /** The declared exempt set, for docs generation and tests. */
78
+ export function formatExemptSurfaces() {
79
+ return { commands: [...EXEMPT_COMMANDS], subcommands: [...EXEMPT_SUBCOMMANDS] };
80
+ }