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
@@ -1,30 +1,83 @@
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
+ /**
5
+ * `akm info`'s real result (`InfoResponse`, `src/sources/types.ts`) carries
6
+ * `defaultBundle`/`assetTypes`/`searchModes`/`semanticSearch`/`registries`/
7
+ * `sourceProviders`/`indexStats` — this formatter used to check for
8
+ * `configPath`/`cacheDir`/`dbPath`/`capabilities`/`index` instead, none of
9
+ * which `InfoResponse` has ever had, so every one of those `if` guards was
10
+ * always false and those five real fields silently never appeared in
11
+ * `--format text` output (the plain fallthrough JSON check three lines below
12
+ * papered over it: `lines` was never empty because `version`/`bundleDir`
13
+ * always matched, so the "render everything" escape hatch never fired
14
+ * either — same class of bug as `akm health`/`akm lint`'s raw-JSON-array
15
+ * dump: `--format text` claiming to render a shape it wasn't actually
16
+ * rendering). The legacy field checks stay (harmless no-ops on the current
17
+ * shape) in case another producer still emits them; the real fields are
18
+ * added alongside.
19
+ */
4
20
  export function formatInfoPlain(r) {
5
21
  const lines = [];
6
22
  if (r.version)
7
23
  lines.push(`version: ${String(r.version)}`);
8
- if (r.stashDir)
9
- lines.push(`stashDir: ${String(r.stashDir)}`);
24
+ if (r.bundleDir)
25
+ lines.push(`bundleDir: ${String(r.bundleDir)}`);
26
+ if (r.defaultBundle !== undefined) {
27
+ lines.push(`defaultBundle: ${r.defaultBundle === null ? "(none)" : String(r.defaultBundle)}`);
28
+ }
10
29
  if (r.configPath)
11
30
  lines.push(`configPath: ${String(r.configPath)}`);
12
31
  if (r.cacheDir)
13
32
  lines.push(`cacheDir: ${String(r.cacheDir)}`);
14
33
  if (r.dbPath)
15
34
  lines.push(`dbPath: ${String(r.dbPath)}`);
35
+ if (Array.isArray(r.assetTypes) && r.assetTypes.length > 0) {
36
+ lines.push(`assetTypes: ${r.assetTypes.join(", ")}`);
37
+ }
38
+ if (Array.isArray(r.searchModes) && r.searchModes.length > 0) {
39
+ lines.push(`searchModes: ${r.searchModes.join(", ")}`);
40
+ }
41
+ const semanticSearch = r.semanticSearch;
42
+ if (semanticSearch) {
43
+ lines.push("semanticSearch:");
44
+ for (const [k, v] of Object.entries(semanticSearch)) {
45
+ lines.push(` ${k}: ${String(v)}`);
46
+ }
47
+ }
48
+ const registries = Array.isArray(r.registries) ? r.registries : undefined;
49
+ if (registries) {
50
+ lines.push(`registries (${registries.length}):`);
51
+ for (const reg of registries) {
52
+ const name = typeof reg.name === "string" ? `${reg.name}: ` : "";
53
+ const provider = typeof reg.provider === "string" ? ` (${reg.provider})` : "";
54
+ const disabled = reg.enabled === false ? " [disabled]" : "";
55
+ lines.push(` ${name}${String(reg.url ?? "?")}${provider}${disabled}`);
56
+ }
57
+ }
58
+ const sourceProviders = Array.isArray(r.sourceProviders)
59
+ ? r.sourceProviders
60
+ : undefined;
61
+ if (sourceProviders) {
62
+ lines.push(`sourceProviders (${sourceProviders.length}):`);
63
+ for (const source of sourceProviders) {
64
+ const label = source.name ?? source.path ?? source.url ?? source.type ?? "?";
65
+ const disabled = source.enabled === false ? " [disabled]" : "";
66
+ lines.push(` [${String(source.type ?? "?")}] ${String(label)}${disabled}`);
67
+ }
68
+ }
16
69
  const capabilities = r.capabilities;
17
70
  if (capabilities) {
18
71
  lines.push("capabilities:");
19
72
  for (const [k, v] of Object.entries(capabilities)) {
20
- lines.push(` ${k}: ${typeof v === "object" ? JSON.stringify(v) : String(v)}`);
73
+ lines.push(` ${k}: ${typeof v === "object" && v !== null ? JSON.stringify(v) : String(v)}`);
21
74
  }
22
75
  }
23
- const indexStats = r.index;
76
+ const indexStats = (r.indexStats ?? r.index);
24
77
  if (indexStats) {
25
- lines.push("index:");
78
+ lines.push("indexStats:");
26
79
  for (const [k, v] of Object.entries(indexStats)) {
27
- lines.push(` ${k}: ${typeof v === "object" ? JSON.stringify(v) : String(v)}`);
80
+ lines.push(` ${k}: ${typeof v === "object" && v !== null ? JSON.stringify(v) : String(v)}`);
28
81
  }
29
82
  }
30
83
  if (lines.length === 0)
@@ -74,26 +127,20 @@ export function formatImportPlain(r) {
74
127
  const pathValue = String(r.path ?? "?");
75
128
  return `Imported ${source} → ${ref} at ${pathValue}`;
76
129
  }
77
- export function formatSavePlain(r) {
130
+ export function formatSyncPlain(r) {
78
131
  if (r.ok === false) {
79
132
  const reason = typeof r.reason === "string" ? r.reason : "unknown";
80
- return `save: failed (${reason})`;
133
+ return `sync: failed (${reason})`;
81
134
  }
82
- const name = typeof r.name === "string" ? r.name : "primary stash";
135
+ const name = typeof r.name === "string" ? r.name : "primary bundle";
83
136
  const committed = r.committed === true;
84
137
  const pushed = r.pushed === true;
85
- const parts = [`save: ${name}`];
138
+ const parts = [`sync: ${name}`];
86
139
  parts.push(committed ? "committed" : "no changes");
87
140
  if (pushed)
88
141
  parts.push("pushed");
89
142
  return parts.join(" — ");
90
143
  }
91
- export function formatToggleComponentPlain(command, r) {
92
- const verb = command === "enable" ? "Enabled" : "Disabled";
93
- const component = String(r.component ?? "?");
94
- const changed = r.changed === true;
95
- return changed ? `${verb} ${component}` : `${component} was already ${command}d`;
96
- }
97
144
  export function formatRegistryListPlain(r) {
98
145
  const registries = Array.isArray(r.registries) ? r.registries : [];
99
146
  if (registries.length === 0) {
@@ -129,12 +176,6 @@ export function formatRegistrySearchPlain(r, detail) {
129
176
  // Reuse the same renderer as `search` — both share `hits` / `registryHits`.
130
177
  return formatSearchPlain(r, detail);
131
178
  }
132
- export function formatRegistryBuildIndexPlain(r) {
133
- const outPath = String(r.outPath ?? "?");
134
- const total = typeof r.totalKits === "number" ? r.totalKits : 0;
135
- const version = typeof r.version === "number" ? `v${r.version}` : "";
136
- return `Wrote registry index ${version} (${total} kits) → ${outPath}`.replace(/\s+/g, " ").trim();
137
- }
138
179
  export function formatEnvListPlain(r) {
139
180
  // Multi-env listing: { envs: [{ ref, path, keys }, ...] }
140
181
  const envs = Array.isArray(r.envs) ? r.envs : [];
@@ -168,20 +209,6 @@ export function formatEnvRemovePlain(r) {
168
209
  const removed = r.removed === true;
169
210
  return removed ? `Removed env ${String(r.ref ?? "?")}` : `Env ${String(r.ref ?? "?")} was not present`;
170
211
  }
171
- export function formatEnvSetPlain(r) {
172
- return `Set ${String(r.key ?? "?")} in env ${String(r.ref ?? "?")} (value not displayed)`;
173
- }
174
- export function formatEnvUnsetPlain(r) {
175
- const removed = Array.isArray(r.removed) ? r.removed.map(String) : [];
176
- const missing = Array.isArray(r.missing) ? r.missing.map(String) : [];
177
- const ref = String(r.ref ?? "?");
178
- const parts = [];
179
- if (removed.length > 0)
180
- parts.push(`Removed ${removed.join(", ")} from env ${ref}`);
181
- if (missing.length > 0)
182
- parts.push(`Not present in env ${ref}: ${missing.join(", ")}`);
183
- return parts.join("\n") || `No keys changed in env ${ref}`;
184
- }
185
212
  export function formatEventsPlain(r) {
186
213
  const events = Array.isArray(r.events) ? r.events : [];
187
214
  const headerParts = [];
@@ -214,56 +241,18 @@ export function formatEventLine(event) {
214
241
  }
215
242
  return head;
216
243
  }
217
- export function formatHistoryPlain(r) {
218
- const entries = Array.isArray(r.entries) ? r.entries : [];
219
- const headerParts = [];
220
- if (typeof r.ref === "string" && r.ref)
221
- headerParts.push(`ref: ${r.ref}`);
222
- if (typeof r.since === "string" && r.since)
223
- headerParts.push(`since: ${r.since}`);
224
- const totalCount = typeof r.totalCount === "number" ? r.totalCount : entries.length;
225
- headerParts.push(`${totalCount} event(s)`);
226
- // Show active event sources so operators know which streams were consulted.
227
- if (Array.isArray(r.sources) && r.sources.length > 0) {
228
- headerParts.push(`sources: ${r.sources.join(", ")}`);
229
- }
230
- const header = headerParts.join(" ");
231
- if (entries.length === 0) {
232
- const scope = typeof r.ref === "string" && r.ref ? ` for ${r.ref}` : "";
233
- return `${header}\nNo history${scope}.`;
234
- }
235
- const lines = [header, ""];
236
- for (const entry of entries) {
237
- const created = String(entry.createdAt ?? "?");
238
- const eventType = String(entry.eventType ?? "?");
239
- const ref = entry.ref ? String(entry.ref) : null;
240
- const signal = entry.signal ? String(entry.signal) : null;
241
- const query = entry.query ? String(entry.query) : null;
242
- const head = ref ? `${created} [${eventType}] ${ref}` : `${created} [${eventType}]`;
243
- lines.push(head);
244
- if (signal)
245
- lines.push(` signal: ${signal}`);
246
- if (query)
247
- lines.push(` query: ${query}`);
248
- if (entry.metadata != null && entry.metadata !== "") {
249
- const meta = typeof entry.metadata === "string" ? entry.metadata : JSON.stringify(entry.metadata);
250
- lines.push(` metadata: ${meta}`);
251
- }
252
- }
253
- return lines.join("\n").trimEnd();
254
- }
255
244
  export function formatSearchPlain(r, detail) {
256
245
  const hits = r.hits ?? [];
257
246
  const registryHits = r.registryHits ?? [];
258
247
  const allHits = [...hits, ...registryHits];
259
248
  if (allHits.length === 0) {
260
249
  const warnings = Array.isArray(r.warnings) ? r.warnings : [];
261
- const hasSetupWarning = warnings.some((w) => String(w).toLowerCase().includes("no stash") || String(w).toLowerCase().includes("not configured"));
250
+ const hasSetupWarning = warnings.some((w) => String(w).toLowerCase().includes("no bundle") || String(w).toLowerCase().includes("not configured"));
262
251
  if (hasSetupWarning) {
263
- return "No stash configured. Run `akm init` to create your working stash, then `akm index` to build the search index.";
252
+ return "No bundle configured. Run `akm bundle create` to create your working bundle, then `akm index` to build the search index.";
264
253
  }
265
254
  const base = r.tip ? String(r.tip) : "No matches found.";
266
- return `${base}\nTry:\n akm search '<broader-term>' # fewer keywords\n akm list # see all configured sources\n akm curate '<query>' # let akm select the best match`;
255
+ return `${base}\nTry:\n akm search '<broader-term>' # fewer keywords\n akm bundle list # see all configured sources\n akm curate '<query>' # let akm select the best match`;
267
256
  }
268
257
  const lines = [];
269
258
  for (const hit of allHits) {
@@ -293,8 +282,7 @@ export function formatSearchPlain(r, detail) {
293
282
  // Optional v1 spec §4.2 quality marker (e.g. "curated" / "proposed").
294
283
  if (typeof hit.quality === "string" && hit.quality)
295
284
  lines.push(` quality: ${hit.quality}`);
296
- // Surface optional hit-level warnings (v1 spec §4.2). The legacy
297
- // `curated` boolean was removed in v1.
285
+ // Surface optional hit-level warnings (v1 spec §4.2).
298
286
  if (Array.isArray(hit.warnings) && hit.warnings.length > 0) {
299
287
  lines.push(` warnings: ${hit.warnings.join("; ")}`);
300
288
  }
@@ -354,12 +342,12 @@ export function formatSearchPlain(r, detail) {
354
342
  if (hasWorkflowHit) {
355
343
  const workflowRef = hits.find((h) => h.type === "workflow");
356
344
  const wfRef = workflowRef && typeof workflowRef.ref === "string" ? workflowRef.ref : topRef;
357
- lines.push(`Next: akm show '${topRef}' | To start a workflow: akm workflow next '${wfRef}'`);
358
- lines.push("After running workflow next: follow each step and run `akm workflow complete <run-id> --step <step-id>` when done.");
345
+ lines.push(`Next: akm show '${topRef}' | To execute a workflow: akm workflow run '${wfRef}'`);
346
+ lines.push("Inspect the workflow before running it; `workflow run` executes and verifies its steps automatically.");
359
347
  }
360
348
  else {
361
349
  lines.push(`Next: akm show '${topRef}'`);
362
- lines.push("After reading the asset: check whether a workflow applies before editing — if so, use `akm workflow next` instead.");
350
+ lines.push("After reading the asset: check whether a workflow applies before editing — if so, inspect it and use `akm workflow run`.");
363
351
  }
364
352
  }
365
353
  }
@@ -429,11 +417,11 @@ export function formatCuratePlain(r, detail) {
429
417
  return lines.join("\n");
430
418
  }
431
419
  export function formatInitPlain(r) {
432
- let out = `Stash initialized at ${r.stashDir ?? "unknown"}`;
433
- // When --dir scaffolded a secondary stash but the default was deliberately
420
+ let out = `Bundle initialized at ${r.bundleDir ?? "unknown"}`;
421
+ // When --dir scaffolded a secondary bundle but the default was deliberately
434
422
  // left untouched, tell the user instead of silently repointing their default.
435
- if (r.defaultStashUpdated === false && typeof r.previousStashDir === "string" && r.previousStashDir) {
436
- out += `\nYour default stash is unchanged (${r.previousStashDir}). Re-run with --set-default to make ${r.stashDir} the default.`;
423
+ if (r.defaultBundleUpdated === false && typeof r.previousBundleDir === "string" && r.previousBundleDir) {
424
+ out += `\nYour default bundle is unchanged (${r.previousBundleDir}). Re-run with --set-default to make ${r.bundleDir} the default.`;
437
425
  }
438
426
  else if (r.configPath) {
439
427
  out += `\nConfig saved to ${r.configPath}`;
@@ -471,7 +459,7 @@ export function formatIndexPlain(r) {
471
459
  export function formatListPlain(r) {
472
460
  const sources = Array.isArray(r.sources) ? r.sources : [];
473
461
  if (sources.length === 0)
474
- return "No sources configured. Use `akm add` to add a source.";
462
+ return "No sources configured. Use `akm bundle add` to add a source.";
475
463
  const lines = [];
476
464
  for (const src of sources) {
477
465
  const kind = typeof src.kind === "string" ? src.kind : "unknown";
@@ -479,8 +467,8 @@ export function formatListPlain(r) {
479
467
  const ver = typeof src.version === "string" ? ` v${src.version}` : "";
480
468
  const prov = typeof src.provider === "string" ? ` (${src.provider})` : "";
481
469
  const flags = [];
482
- if (src.updatable === true)
483
- flags.push("updatable");
470
+ if (src.default === true)
471
+ flags.push("default");
484
472
  if (src.writable === true)
485
473
  flags.push("writable");
486
474
  const flagText = flags.length > 0 ? ` [${flags.join(", ")}]` : "";
@@ -490,7 +478,52 @@ export function formatListPlain(r) {
490
478
  lines.push("To search: akm search '<query>' | To view an asset: akm show <ref>");
491
479
  return lines.join("\n");
492
480
  }
481
+ /** Render a single `SourceEntry` — `akm bundle show <name>`'s detail view of one `list` row. */
482
+ export function formatBundleShowPlain(r) {
483
+ const name = typeof r.name === "string" ? r.name : "unknown";
484
+ const kind = typeof r.kind === "string" ? r.kind : "unknown";
485
+ const lines = [`${name} [${kind}]`];
486
+ if (r.default === true)
487
+ lines.push(" default: true");
488
+ if (r.writable === true)
489
+ lines.push(" writable: true");
490
+ if (typeof r.version === "string")
491
+ lines.push(` version: ${r.version}`);
492
+ if (typeof r.provider === "string")
493
+ lines.push(` provider: ${r.provider}`);
494
+ if (typeof r.path === "string")
495
+ lines.push(` path: ${r.path}`);
496
+ if (typeof r.ref === "string")
497
+ lines.push(` ref: ${r.ref}`);
498
+ if (typeof r.registryId === "string")
499
+ lines.push(` registryId: ${r.registryId}`);
500
+ lines.push(` items: ${typeof r.itemCount === "number" ? r.itemCount : 0}`);
501
+ const byType = r.byType;
502
+ if (byType && Object.keys(byType).length > 0) {
503
+ lines.push(` byType: ${Object.entries(byType)
504
+ .map(([t, n]) => `${t}=${n}`)
505
+ .join(", ")}`);
506
+ }
507
+ const status = r.status;
508
+ if (status?.exists === false)
509
+ lines.push(" status: MISSING on disk");
510
+ return lines.join("\n");
511
+ }
493
512
  export function formatAddPlain(r) {
513
+ // `akm bundle add <ref>` (source-add.ts `AddResponse`) and `akm bundle add
514
+ // <target> --provider <kind>` (source-manage.ts `SourceAddResult`) are
515
+ // genuinely different operations that happen to share the "add" command
516
+ // name: the former eagerly fetches and indexes content, the latter only
517
+ // writes a desired locator to config — nothing is synced until a later
518
+ // `akm bundle update`. Force-fitting the declarative shape's `added`/`entry`/`message`
519
+ // fields into the "Installed <ref> (N scanned...)" wording produced
520
+ // "Installed undefined (0 directories scanned...)" (R-014) because it
521
+ // implied a sync that never happened. `AddResponse` always carries an
522
+ // `index` block (even when zero entries were scanned); `SourceAddResult`
523
+ // never does — that is the reliable shape discriminator used below to
524
+ // render each honestly instead of unifying them.
525
+ if (!("index" in r))
526
+ return formatDeclarativeAddPlain(r);
494
527
  const index = r.index;
495
528
  const scanned = index?.directoriesScanned ?? 0;
496
529
  const total = index?.totalEntries ?? 0;
@@ -503,27 +536,62 @@ export function formatAddPlain(r) {
503
536
  }
504
537
  return lines.join("\n");
505
538
  }
539
+ /** Render a `SourceAddResult` (declarative `--provider` add) — see {@link formatAddPlain}. */
540
+ function formatDeclarativeAddPlain(r) {
541
+ if (r.added !== true) {
542
+ return typeof r.message === "string" ? r.message : "add: no changes";
543
+ }
544
+ const entry = r.entry;
545
+ const kind = typeof entry?.type === "string" ? entry.type : "source";
546
+ const name = (typeof entry?.name === "string" && entry.name) ||
547
+ (typeof entry?.path === "string" && entry.path) ||
548
+ (typeof entry?.url === "string" && entry.url) ||
549
+ "source";
550
+ // A filesystem bundle reflects files already on disk — nothing to fetch,
551
+ // just index it. Every other declarative kind (git/website/npm) is a
552
+ // locator only; its content is not materialized until `akm bundle update`.
553
+ if (kind === "filesystem") {
554
+ return `Added ${name} (filesystem) — run \`akm index\` to index it.`;
555
+ }
556
+ return `Added ${name} (${kind}) — not yet synced; run \`akm bundle update ${name}\` to fetch it.`;
557
+ }
506
558
  export function formatRemovePlain(r) {
507
559
  const target = r.target ?? r.ref ?? "";
508
560
  const ok = r.ok !== false ? "OK" : "FAILED";
509
561
  return `remove: ${target} ${ok}`;
510
562
  }
511
563
  export function formatUpdatePlain(r) {
564
+ // R-015: `processed` alone conflated three cases into one empty array —
565
+ // a true no-op (--all with nothing configured), a source this call flatly
566
+ // never looked at (a plain source under --all), and a plain git/website
567
+ // source that WAS just synced successfully but has no `UpdateResultItem`
568
+ // shape to report (no version/lock to diff). All three rendered as the
569
+ // same misleading "nothing to update". `plainSynced` and `skipped` (see
570
+ // sources/types.ts) cover the other two so this can report accurately.
512
571
  const processed = r.processed;
513
- if (!processed?.length)
514
- return `update: nothing to update`;
515
- const lines = processed.map((item) => {
572
+ const plainSynced = r.plainSynced;
573
+ const skipped = r.skipped;
574
+ const lines = [];
575
+ for (const item of processed ?? []) {
516
576
  const changed = item.changed;
517
577
  const installed = item.installed;
518
578
  const previous = item.previous;
519
579
  if (changed?.any) {
520
580
  const prev = previous?.resolvedVersion ?? "unknown";
521
581
  const next = installed?.resolvedVersion ?? "unknown";
522
- return `update: ${item.id} v${prev} → v${next}`;
582
+ lines.push(`update: ${item.id} v${prev} → v${next}`);
523
583
  }
524
- return `update: ${item.id} (unchanged)`;
525
- });
526
- return lines.join("\n");
584
+ else {
585
+ lines.push(`update: ${item.id} (unchanged)`);
586
+ }
587
+ }
588
+ for (const item of plainSynced ?? []) {
589
+ lines.push(`update: ${item.id} synced (${item.kind})`);
590
+ }
591
+ for (const item of skipped ?? []) {
592
+ lines.push(`update: ${item.id} skipped — ${item.reason}`);
593
+ }
594
+ return lines.length > 0 ? lines.join("\n") : `update: nothing to update`;
527
595
  }
528
596
  export function formatUpgradePlain(r) {
529
597
  if (r.upgraded === true) {
@@ -2,12 +2,10 @@
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
  // Output text formatters for `akm env *` commands.
5
- import { formatEnvCreatePlain, formatEnvExportPlain, formatEnvListPlain, formatEnvRemovePlain, formatEnvSetPlain, formatEnvUnsetPlain, } from "./helpers.js";
5
+ import { formatEnvCreatePlain, formatEnvExportPlain, formatEnvListPlain, formatEnvRemovePlain } from "./helpers.js";
6
6
  export const envFormatters = [
7
7
  { command: "env-list", handler: (r) => formatEnvListPlain(r) },
8
8
  { command: "env-create", handler: (r) => formatEnvCreatePlain(r) },
9
9
  { command: "env-export", handler: (r) => formatEnvExportPlain(r) },
10
10
  { command: "env-remove", handler: (r) => formatEnvRemovePlain(r) },
11
- { command: "env-set", handler: (r) => formatEnvSetPlain(r) },
12
- { command: "env-unset", handler: (r) => formatEnvUnsetPlain(r) },
13
11
  ];
@@ -1,11 +1,12 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- // Output text formatters for `akm events list` / `akm events tail` (#204).
5
- // Both share a renderer; `events-tail` is also called per-event by the streaming
6
- // code path via `formatEventLine`.
4
+ // Output text formatter for `akm log` (#204).
5
+ //
6
+ // R-060: renamed from `events-list` to `log-list` — see
7
+ // src/output/shapes/events.ts for the full rationale.
8
+ //
9
+ // 0.9.0 CLI overhaul (S3): `log tail` (and its `log-tail` formatter entry)
10
+ // was dropped along with the command.
7
11
  import { formatEventsPlain } from "./helpers.js";
8
- export const eventsFormatters = [
9
- { command: "events-list", handler: (r) => formatEventsPlain(r) },
10
- { command: "events-tail", handler: (r) => formatEventsPlain(r) },
11
- ];
12
+ export const eventsFormatters = [{ command: "log-list", handler: (r) => formatEventsPlain(r) }];
@@ -0,0 +1,103 @@
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
+ import { flattenForText } from "../generic-render.js";
5
+ import { renderStatusEntries, summarizeCounts } from "./status-list.js";
6
+ const STATUS_GLYPH = { fail: "✗", warn: "⚠", unknown: "?", pass: "✓" };
7
+ const STATUS_RANK = { fail: 0, warn: 1, unknown: 2, pass: 3 };
8
+ /** Worst-first, for both the section summary and (via `STATUS_RANK`) row order. */
9
+ const STATUS_ORDER = ["fail", "warn", "unknown", "pass"];
10
+ /** One evidence field per line, `key: value` — objects/arrays JSON-compact, matching `formatInfoPlain`'s nested-field convention. */
11
+ function evidenceLines(evidence) {
12
+ if (!evidence)
13
+ return [];
14
+ return Object.entries(evidence).map(([key, value]) => `${key}: ${value !== null && typeof value === "object" ? JSON.stringify(value) : String(value)}`);
15
+ }
16
+ function checkStatusEntry(check, detail) {
17
+ const status = check.status ?? "unknown";
18
+ const meta = [check.kind, check.confidence].filter((v) => !!v).join(", ");
19
+ return {
20
+ severityRank: STATUS_RANK[status] ?? 9,
21
+ glyph: STATUS_GLYPH[status] ?? "?",
22
+ headline: `${check.name} [${status}${meta ? `, ${meta}` : ""}] ${check.message ?? ""}`.trimEnd(),
23
+ // Evidence is diagnostic detail, not the headline signal — gated behind
24
+ // --detail the same way `formatSearchPlain`/`formatCuratePlain` gate
25
+ // their own verbose fields (full path/editHint/whyMatched, "why" reasoning).
26
+ detailLines: detail === "brief" ? [] : evidenceLines(check.evidence),
27
+ };
28
+ }
29
+ /** Render one `hardChecks`/`advisories` section: a count summary header, then worst-first rows. */
30
+ function renderCheckSection(title, checks, detail) {
31
+ if (checks.length === 0)
32
+ return [`${title}: (none)`];
33
+ const counts = {};
34
+ for (const check of checks) {
35
+ const status = check.status ?? "unknown";
36
+ counts[status] = (counts[status] ?? 0) + 1;
37
+ }
38
+ const summary = summarizeCounts(counts, STATUS_ORDER);
39
+ const header = `${title} (${checks.length}${summary ? ` — ${summary}` : ""})`;
40
+ return [header, ...renderStatusEntries(checks.map((check) => checkStatusEntry(check, detail)))];
41
+ }
42
+ function sessionAdvisoryEntry(advisory) {
43
+ const isFailure = advisory.isFailurePattern === true;
44
+ return {
45
+ severityRank: isFailure ? 0 : 1,
46
+ glyph: (isFailure ? STATUS_GLYPH.warn : STATUS_GLYPH.pass) ?? "?",
47
+ headline: `${advisory.topic ?? "?"} (x${advisory.frequency ?? 0}, source: ${advisory.source ?? "?"})`,
48
+ };
49
+ }
50
+ function renderSessionLogAdvisories(advisories) {
51
+ if (advisories.length === 0)
52
+ return [];
53
+ return [`sessionLogAdvisories (${advisories.length})`, ...renderStatusEntries(advisories.map(sessionAdvisoryEntry))];
54
+ }
55
+ /** Fields already rendered explicitly above — everything else in `r` falls to the `flattenForText` sweep below. */
56
+ const HANDLED_KEYS = new Set([
57
+ "ok",
58
+ "status",
59
+ "since",
60
+ "hardChecks",
61
+ "advisories",
62
+ "sessionLogAdvisories",
63
+ "shape",
64
+ "schemaVersion",
65
+ ]);
66
+ export function formatHealthPlain(r, detail) {
67
+ if (r === null || typeof r !== "object")
68
+ return null;
69
+ const lines = [];
70
+ if (typeof r.ok === "boolean")
71
+ lines.push(`ok: ${r.ok}`);
72
+ if (typeof r.status === "string")
73
+ lines.push(`status: ${r.status}`);
74
+ if (typeof r.since === "string")
75
+ lines.push(`since: ${r.since}`);
76
+ const hardChecks = Array.isArray(r.hardChecks) ? r.hardChecks : [];
77
+ const advisories = Array.isArray(r.advisories) ? r.advisories : [];
78
+ const sessionLogAdvisories = Array.isArray(r.sessionLogAdvisories)
79
+ ? r.sessionLogAdvisories
80
+ : [];
81
+ lines.push("", ...renderCheckSection("hardChecks", hardChecks, detail));
82
+ lines.push("", ...renderCheckSection("advisories", advisories, detail));
83
+ const sessionLines = renderSessionLogAdvisories(sessionLogAdvisories);
84
+ if (sessionLines.length > 0)
85
+ lines.push("", ...sessionLines);
86
+ if (detail === "brief" &&
87
+ [...hardChecks, ...advisories].some((c) => c.evidence && Object.keys(c.evidence).length > 0)) {
88
+ lines.push("", "(evidence omitted at --detail brief; re-run with --detail normal or --detail full to see it)");
89
+ }
90
+ // Everything else (metrics, improve, and the optional runs/windows/deltas/
91
+ // report datasets) is a nested scalar tree, not the array-of-records shape
92
+ // this formatter exists to fix — keep the existing dotted-path convention
93
+ // for it rather than inventing a second one.
94
+ for (const [key, value] of Object.entries(r)) {
95
+ if (HANDLED_KEYS.has(key) || value === undefined)
96
+ continue;
97
+ const fieldLines = [];
98
+ flattenForText(value, key, fieldLines);
99
+ if (fieldLines.length > 0)
100
+ lines.push("", ...fieldLines);
101
+ }
102
+ return lines.join("\n").trim();
103
+ }
@@ -0,0 +1,7 @@
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
+ import { formatHealthPlain } from "./helpers.js";
5
+ export const healthFormatters = [
6
+ { command: "health", handler: (r, detail) => formatHealthPlain(r, detail) },
7
+ ];
@@ -7,15 +7,17 @@
7
7
  *
8
8
  * This module is a re-export BARREL: the actual implementations live in
9
9
  * cohesive sibling modules (`show-format.ts`, `show-directives.ts`,
10
- * `workflow-format.ts`, `proposal-format.ts`, `command-format.ts`) split out
11
- * of what used to be a single 1418-line / 59-function file. Every name that
12
- * was previously importable from `"./helpers"` (directly, or transitively via
13
- * `../text.ts`) stays importable from here unchanged — no import site needed
14
- * to move.
10
+ * `workflow-format.ts`, `proposal-format.ts`, `command-format.ts`,
11
+ * `health-format.ts`, `lint-format.ts`) split out of what used to be a
12
+ * single 1418-line / 59-function file. Every name that was previously
13
+ * importable from `"./helpers"` (directly, or transitively via `../text.ts`)
14
+ * stays importable from here unchanged — no import site needed to move.
15
15
  *
16
16
  * No registry imports — no circular dependencies.
17
17
  */
18
- export { formatAddPlain, formatClonePlain, formatConfigPlain, formatCuratePlain, formatEnvCreatePlain, formatEnvExportPlain, formatEnvListPlain, formatEnvRemovePlain, formatEnvSetPlain, formatEnvUnsetPlain, formatEventLine, formatEventsPlain, formatFeedbackPlain, formatHistoryPlain, formatImportPlain, formatIndexPlain, formatInfoPlain, formatInitPlain, formatListPlain, formatRegistryAddPlain, formatRegistryBuildIndexPlain, formatRegistryListPlain, formatRegistryRemovePlain, formatRegistrySearchPlain, formatRememberPlain, formatRemovePlain, formatSavePlain, formatSearchPlain, formatToggleComponentPlain, formatUpdatePlain, formatUpgradePlain, } from "./command-format.js";
19
- export { formatDistillPlain, formatGateDecisionSummary, formatProposalAcceptPlain, formatProposalDiffPlain, formatProposalDrainPlain, formatProposalListPlain, formatProposalProducerPlain, formatProposalRejectPlain, formatProposalShowPlain, } from "./proposal-format.js";
18
+ export { formatAddPlain, formatBundleShowPlain, formatClonePlain, formatConfigPlain, formatCuratePlain, formatEnvCreatePlain, formatEnvExportPlain, formatEnvListPlain, formatEnvRemovePlain, formatEventLine, formatEventsPlain, formatFeedbackPlain, formatImportPlain, formatIndexPlain, formatInfoPlain, formatInitPlain, formatListPlain, formatRegistryAddPlain, formatRegistryListPlain, formatRegistryRemovePlain, formatRegistrySearchPlain, formatRememberPlain, formatRemovePlain, formatSearchPlain, formatSyncPlain, formatUpdatePlain, formatUpgradePlain, } from "./command-format.js";
19
+ export { formatHealthPlain } from "./health-format.js";
20
+ export { formatLintPlain } from "./lint-format.js";
21
+ export { formatGateDecisionSummary, formatProposalAcceptPlain, formatProposalDiffPlain, formatProposalDrainPlain, formatProposalListPlain, formatProposalProducerPlain, formatProposalRejectPlain, formatProposalShowPlain, } from "./proposal-format.js";
20
22
  export { formatShowPlain } from "./show-format.js";
21
- export { formatWorkflowBriefPlain, formatWorkflowCompleteRejectedPlain, formatWorkflowCreatePlain, formatWorkflowListPlain, formatWorkflowNextPlain, formatWorkflowResumePlain, formatWorkflowRunPlain, formatWorkflowStatusPlain, formatWorkflowValidatePlain, } from "./workflow-format.js";
23
+ export { formatWorkflowCreatePlain, formatWorkflowListPlain, formatWorkflowResumePlain, formatWorkflowRunPlain, formatWorkflowStatusPlain, } from "./workflow-format.js";
@@ -0,0 +1,43 @@
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
+ import { renderStatusEntries } from "./status-list.js";
5
+ /**
6
+ * `fixed === true` succeeded; `"failed"` is an attempted-and-failed fix (worse
7
+ * than an unfixed, merely-flagged issue, which in turn is worse than a clean
8
+ * success). `severityRank` ascends from most urgent — see
9
+ * {@link renderStatusEntries} — so the three states must get three DISTINCT
10
+ * ranks or a failed fix can sort behind a successful one in the same section.
11
+ */
12
+ function glyphFor(fixed) {
13
+ if (fixed === "failed")
14
+ return { glyph: "✗", severityRank: 0 };
15
+ if (fixed === true)
16
+ return { glyph: "✓", severityRank: 2 };
17
+ return { glyph: "⚠", severityRank: 1 };
18
+ }
19
+ function issueEntry(issue) {
20
+ const { glyph, severityRank } = glyphFor(issue.fixed);
21
+ return { severityRank, glyph, headline: `${issue.file} [${issue.issue}] ${issue.detail}` };
22
+ }
23
+ function renderIssueSection(title, issues) {
24
+ if (issues.length === 0)
25
+ return [`${title}: (none)`];
26
+ return [`${title} (${issues.length})`, ...renderStatusEntries(issues.map(issueEntry))];
27
+ }
28
+ export function formatLintPlain(r) {
29
+ if (r === null || typeof r !== "object")
30
+ return null;
31
+ const fixed = Array.isArray(r.fixed) ? r.fixed : [];
32
+ const flagged = Array.isArray(r.flagged) ? r.flagged : [];
33
+ const summary = r.summary;
34
+ const lines = [];
35
+ if (typeof r.ok === "boolean")
36
+ lines.push(`ok: ${r.ok}`);
37
+ lines.push(`summary: fixed=${summary?.fixed ?? fixed.length} flagged=${summary?.flagged ?? flagged.length}`);
38
+ // Flagged (still needs attention) surfaces before fixed (already handled)
39
+ // so a scan of the output hits the actionable items first.
40
+ lines.push("", ...renderIssueSection("flagged", flagged));
41
+ lines.push("", ...renderIssueSection("fixed", fixed));
42
+ return lines.join("\n").trim();
43
+ }
@@ -1,5 +1,5 @@
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 { formatSavePlain } from "./helpers.js";
5
- export const saveFormatters = [{ command: "save", handler: (r) => formatSavePlain(r) }];
4
+ import { formatLintPlain } from "./helpers.js";
5
+ export const lintFormatters = [{ command: "lint", handler: (r) => formatLintPlain(r) }];