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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (587) hide show
  1. package/CHANGELOG.md +1190 -52
  2. package/README.md +62 -37
  3. package/SECURITY.md +46 -31
  4. package/dist/akm +162 -38
  5. package/dist/akm-migrate +44 -0
  6. package/dist/assets/backends/schtasks-template.xml +2 -1
  7. package/dist/assets/hints/cli-hints-full.md +268 -118
  8. package/dist/assets/hints/cli-hints-short.md +87 -24
  9. package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
  10. package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
  11. package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
  12. package/dist/assets/improve-strategies/frequent.json +15 -0
  13. package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
  14. package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
  15. package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
  16. package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
  17. package/dist/assets/improve-strategies/reflect-distill.json +30 -0
  18. package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
  19. package/dist/assets/prompts/consolidate-system.md +5 -5
  20. package/dist/assets/prompts/extract-session.md +2 -6
  21. package/dist/assets/prompts/memory-infer-user.md +2 -3
  22. package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
  23. package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
  24. package/dist/assets/prompts/reflect-output-repair.md +3 -0
  25. package/dist/assets/stash-skeleton/README.md +38 -10
  26. package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
  27. package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
  28. package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
  29. package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
  30. package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
  31. package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
  32. package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
  33. package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
  34. package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
  35. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
  36. package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
  37. package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
  38. package/dist/assets/tasks/core/extract.yml +3 -2
  39. package/dist/assets/tasks/core/improve.yml +2 -1
  40. package/dist/assets/tasks/core/index-refresh.yml +1 -0
  41. package/dist/assets/tasks/core/sync.yml +1 -0
  42. package/dist/assets/tasks/core/version-check.yml +2 -1
  43. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
  44. package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
  45. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
  46. package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
  47. package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
  48. package/dist/assets/templates/html/health.html +5 -4
  49. package/dist/assets/workflows/workflow-template.md +31 -15
  50. package/dist/cli/invocation.js +279 -0
  51. package/dist/cli/parse-args.js +5 -90
  52. package/dist/cli/retired-commands.js +78 -0
  53. package/dist/cli/shared.js +158 -48
  54. package/dist/cli-node.mjs +2 -1
  55. package/dist/cli.js +747 -293
  56. package/dist/commands/agent/agent-dispatch.js +19 -18
  57. package/dist/commands/agent/agent-support.js +0 -24
  58. package/dist/commands/agent/contribute-cli.js +43 -97
  59. package/dist/commands/completions.js +80 -23
  60. package/dist/commands/config-cli.js +44 -281
  61. package/dist/commands/env/env-binding.js +13 -9
  62. package/dist/commands/env/env-cli.js +76 -159
  63. package/dist/commands/env/env.js +12 -163
  64. package/dist/commands/env/marker-path.js +6 -0
  65. package/dist/commands/env/secret-cli.js +45 -61
  66. package/dist/commands/env/secret.js +32 -62
  67. package/dist/commands/feedback-cli.js +179 -85
  68. package/dist/commands/health/accept-rate.js +58 -0
  69. package/dist/commands/health/advisories.js +7 -8
  70. package/dist/commands/health/checks.js +279 -94
  71. package/dist/commands/health/html-report.js +197 -578
  72. package/dist/commands/health/improve-metrics.js +277 -246
  73. package/dist/commands/health/llm-usage.js +19 -19
  74. package/dist/commands/health/md-report.js +16 -7
  75. package/dist/commands/health/metrics.js +67 -32
  76. package/dist/commands/health/renderers.js +47 -0
  77. package/dist/commands/health/report-view-model.js +508 -0
  78. package/dist/commands/health/stash-exposure.js +1 -1
  79. package/dist/commands/health/surfaces.js +16 -56
  80. package/dist/commands/health/task-runs.js +3 -67
  81. package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
  82. package/dist/commands/health/types-improve.js +29 -0
  83. package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
  84. package/dist/commands/health/types-result.js +7 -0
  85. package/dist/commands/health/types-runs.js +4 -0
  86. package/dist/commands/health/types-session-log.js +4 -0
  87. package/dist/commands/health/types-windows.js +4 -0
  88. package/dist/commands/health/types.js +26 -21
  89. package/dist/commands/health/windows.js +2 -3
  90. package/dist/commands/health.js +296 -167
  91. package/dist/commands/improve/anti-collapse.js +5 -5
  92. package/dist/commands/improve/autonomy-gate.js +68 -0
  93. package/dist/commands/improve/collapse-detector.js +65 -52
  94. package/dist/commands/improve/consolidate/chunking.js +9 -7
  95. package/dist/commands/improve/consolidate/eligibility.js +1 -23
  96. package/dist/commands/improve/consolidate/merge.js +4 -0
  97. package/dist/commands/improve/consolidate.js +454 -1354
  98. package/dist/commands/improve/content-hash.js +39 -0
  99. package/dist/commands/improve/distill/content-repair.js +4 -10
  100. package/dist/commands/improve/distill/promote-memory.js +89 -64
  101. package/dist/commands/improve/distill/quality-gate.js +118 -42
  102. package/dist/commands/improve/distill-guards.js +1 -1
  103. package/dist/commands/improve/distill-promotion-policy.js +33 -888
  104. package/dist/commands/improve/distill.js +607 -363
  105. package/dist/commands/improve/eligibility.js +165 -79
  106. package/dist/commands/improve/extract-cli.js +35 -126
  107. package/dist/commands/improve/extract-prompt.js +6 -35
  108. package/dist/commands/improve/extract.js +640 -391
  109. package/dist/commands/improve/feedback-valence.js +2 -12
  110. package/dist/commands/improve/improve-cli.js +134 -135
  111. package/dist/commands/improve/improve-result-file.js +30 -50
  112. package/dist/commands/improve/improve-run-types.js +4 -0
  113. package/dist/commands/improve/improve-strategies.js +135 -0
  114. package/dist/commands/improve/improve.js +904 -701
  115. package/dist/commands/improve/locks.js +64 -111
  116. package/dist/commands/improve/loop-stages.js +1110 -923
  117. package/dist/commands/improve/memory/derived-ref.js +124 -0
  118. package/dist/commands/improve/memory/memory-belief.js +79 -7
  119. package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
  120. package/dist/commands/improve/memory/memory-improve.js +25 -37
  121. package/dist/commands/improve/outcome-loop.js +25 -88
  122. package/dist/commands/improve/preparation.js +1034 -813
  123. package/dist/commands/improve/proactive-maintenance.js +34 -9
  124. package/dist/commands/improve/proposal-envelope.js +31 -0
  125. package/dist/commands/improve/reflect.js +983 -794
  126. package/dist/commands/improve/run-context.js +119 -0
  127. package/dist/commands/improve/salience.js +24 -127
  128. package/dist/commands/improve/session-asset.js +7 -3
  129. package/dist/commands/improve/shared.js +14 -34
  130. package/dist/commands/improve/source-identity.js +28 -0
  131. package/dist/commands/improve/triage.js +20 -17
  132. package/dist/commands/lint/base-linter.js +340 -313
  133. package/dist/commands/lint/env-key-rules.js +31 -47
  134. package/dist/commands/lint/index.js +185 -30
  135. package/dist/commands/{events.js → log.js} +28 -38
  136. package/dist/commands/migrate-cli.js +54 -0
  137. package/dist/commands/migration-tool.js +55 -0
  138. package/dist/commands/observability-cli.js +70 -208
  139. package/dist/commands/proposal/diff-format.js +50 -0
  140. package/dist/commands/proposal/drain-policies.js +0 -6
  141. package/dist/commands/proposal/drain.js +91 -40
  142. package/dist/commands/proposal/proposal-cli.js +134 -132
  143. package/dist/commands/proposal/proposal-types.js +56 -0
  144. package/dist/commands/proposal/proposal.js +83 -65
  145. package/dist/commands/proposal/propose-cli.js +88 -0
  146. package/dist/commands/proposal/propose.js +105 -88
  147. package/dist/commands/proposal/repository.js +1303 -278
  148. package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
  149. package/dist/commands/proposal/validators/proposal-validators.js +61 -12
  150. package/dist/commands/proposal/validators/proposals.js +6 -8
  151. package/dist/commands/read/curate.js +78 -73
  152. package/dist/commands/read/knowledge.js +510 -13
  153. package/dist/commands/read/registry-search.js +2 -2
  154. package/dist/commands/read/remember-cli.js +84 -15
  155. package/dist/commands/read/search-cli.js +203 -96
  156. package/dist/commands/read/search.js +126 -94
  157. package/dist/commands/read/show.js +226 -250
  158. package/dist/commands/registry-cli.js +34 -60
  159. package/dist/commands/remember.js +18 -57
  160. package/dist/commands/sources/add-cli.js +104 -49
  161. package/dist/commands/sources/bundle-cli.js +166 -0
  162. package/dist/commands/sources/bundle-config-ops.js +63 -0
  163. package/dist/commands/sources/info.js +27 -15
  164. package/dist/commands/sources/init.js +30 -40
  165. package/dist/commands/sources/installed-stashes.js +469 -172
  166. package/dist/commands/sources/schema-repair.js +10 -9
  167. package/dist/commands/sources/self-update.js +182 -121
  168. package/dist/commands/sources/source-add.js +169 -178
  169. package/dist/commands/sources/source-clone.js +144 -41
  170. package/dist/commands/sources/source-manage.js +94 -59
  171. package/dist/commands/sources/sources-cli.js +64 -205
  172. package/dist/commands/sources/stash-cli.js +91 -54
  173. package/dist/commands/sources/stash-skeleton.js +1 -1
  174. package/dist/commands/tasks/tasks-cli.js +106 -104
  175. package/dist/commands/tasks/tasks.js +445 -262
  176. package/dist/commands/workflow-cli.js +75 -228
  177. package/dist/core/action-contributors.js +1 -1
  178. package/dist/core/activation-policy.js +49 -0
  179. package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
  180. package/dist/core/adapter/adapters/akm-adapter.js +528 -0
  181. package/dist/core/adapter/adapters/akm-lint.js +392 -0
  182. package/dist/core/adapter/adapters/akm-metadata.js +387 -0
  183. package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
  184. package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
  185. package/dist/core/adapter/adapters/claude-adapter.js +61 -0
  186. package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
  187. package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
  188. package/dist/core/adapter/adapters/index.js +80 -0
  189. package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
  190. package/dist/core/adapter/adapters/okf-adapter.js +391 -0
  191. package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
  192. package/dist/core/adapter/adapters/shared.js +286 -0
  193. package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
  194. package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
  195. package/dist/core/adapter/bundle-adapter.js +4 -0
  196. package/dist/core/adapter/detect-adapter.js +17 -0
  197. package/dist/core/adapter/recognize-match.js +44 -0
  198. package/dist/core/adapter/registry.js +56 -0
  199. package/dist/core/adapter/types.js +4 -0
  200. package/dist/core/asset/akm-markdown.js +30 -0
  201. package/dist/core/asset/asset-placement.js +243 -0
  202. package/dist/core/asset/asset-ref.js +110 -79
  203. package/dist/core/asset/asset-serialize.js +20 -0
  204. package/dist/core/asset/frontmatter.js +28 -12
  205. package/dist/core/asset/markdown.js +40 -51
  206. package/dist/core/asset/resolve-ref.js +274 -0
  207. package/dist/core/asset/stash-meta.js +2 -2
  208. package/dist/core/bundle-id.js +51 -0
  209. package/dist/core/common.js +281 -86
  210. package/dist/core/config/config-io.js +42 -128
  211. package/dist/core/config/config-schema.js +233 -855
  212. package/dist/core/config/config-sources.js +162 -39
  213. package/dist/core/config/config-types.js +16 -11
  214. package/dist/core/config/config-version.js +29 -0
  215. package/dist/core/config/config-walker.js +126 -37
  216. package/dist/core/config/config.js +154 -331
  217. package/dist/core/config/deep-merge.js +41 -0
  218. package/dist/core/config/engine-semantics.js +28 -0
  219. package/dist/core/config/experimental.js +21 -0
  220. package/dist/core/config/schema/embedding.js +38 -0
  221. package/dist/core/config/schema/engines.js +116 -0
  222. package/dist/core/config/schema/experimental.js +47 -0
  223. package/dist/core/config/schema/feedback.js +31 -0
  224. package/dist/core/config/schema/improve-processes.js +389 -0
  225. package/dist/core/config/schema/improve.js +94 -0
  226. package/dist/core/config/schema/index-config.js +176 -0
  227. package/dist/core/config/schema/output.js +18 -0
  228. package/dist/core/config/schema/primitives.js +94 -0
  229. package/dist/core/config/schema/search.js +30 -0
  230. package/dist/core/config/schema/setup.js +18 -0
  231. package/dist/core/config/schema/sources-bundles.js +169 -0
  232. package/dist/core/config/schema/workflow.js +29 -0
  233. package/dist/core/env-secret-ref.js +155 -20
  234. package/dist/core/errors.js +17 -15
  235. package/dist/core/events-types.js +4 -0
  236. package/dist/core/events.js +46 -128
  237. package/dist/core/extra-params.js +62 -0
  238. package/dist/core/file-change.js +17 -0
  239. package/dist/core/file-lock.js +202 -57
  240. package/dist/core/fs-txn.js +392 -0
  241. package/dist/core/git-message.js +59 -0
  242. package/dist/core/improve-result.js +167 -0
  243. package/dist/core/lesson-lint.js +1 -17
  244. package/dist/core/logs-db.js +1 -1
  245. package/dist/core/maintenance-barrier.js +135 -0
  246. package/dist/core/migration-operation.js +44 -0
  247. package/dist/core/mutation-target.js +78 -0
  248. package/dist/core/paths.js +22 -25
  249. package/dist/core/platform.js +10 -0
  250. package/dist/core/recognition-util.js +128 -0
  251. package/dist/core/redaction.js +392 -0
  252. package/dist/core/standards/resolve-standards-context.js +36 -65
  253. package/dist/core/standards/resolve-stash-standards.js +2 -2
  254. package/dist/core/standards/resolve-type-conventions.js +5 -5
  255. package/dist/core/state/migrations.js +242 -11
  256. package/dist/core/state-db.js +98 -10
  257. package/dist/core/structured.js +1 -1
  258. package/dist/core/subprocess.js +303 -0
  259. package/dist/core/text-truncation.js +9 -5
  260. package/dist/core/time.js +20 -0
  261. package/dist/core/type-presentation.js +130 -0
  262. package/dist/core/warn.js +0 -3
  263. package/dist/core/write-source.js +834 -118
  264. package/dist/indexer/bundle-identity-guard.js +92 -0
  265. package/dist/indexer/db/graph-db.js +1 -25
  266. package/dist/indexer/db/llm-cache.js +1 -1
  267. package/dist/indexer/ensure-index.js +30 -9
  268. package/dist/indexer/graph/graph-boost.js +9 -30
  269. package/dist/indexer/graph/graph-extraction.js +41 -27
  270. package/dist/indexer/graph/graph-types.js +4 -0
  271. package/dist/indexer/index-writer-lock.js +93 -49
  272. package/dist/indexer/index-written-assets.js +100 -53
  273. package/dist/indexer/indexer.js +746 -329
  274. package/dist/indexer/init.js +18 -25
  275. package/dist/indexer/installations.js +142 -0
  276. package/dist/indexer/passes/dir-staleness.js +18 -10
  277. package/dist/indexer/passes/memory-inference.js +25 -15
  278. package/dist/indexer/passes/metadata.js +412 -243
  279. package/dist/indexer/scan/doc-to-entry.js +160 -0
  280. package/dist/indexer/scan/drain-dir.js +134 -0
  281. package/dist/indexer/search/db-search.js +292 -108
  282. package/dist/indexer/search/fts-query.js +64 -0
  283. package/dist/indexer/search/ranking-contributors.js +145 -25
  284. package/dist/indexer/search/ranking-types.js +4 -0
  285. package/dist/indexer/search/ranking.js +28 -71
  286. package/dist/indexer/search/search-attribution.js +67 -0
  287. package/dist/indexer/search/search-fields.js +18 -3
  288. package/dist/indexer/search/search-hit-enrichers.js +30 -40
  289. package/dist/indexer/search/search-source.js +157 -111
  290. package/dist/indexer/search/semantic-status.js +4 -1
  291. package/dist/indexer/usage/usage-events.js +10 -30
  292. package/dist/indexer/walk/file-context.js +3 -45
  293. package/dist/indexer/walk/matchers.js +42 -73
  294. package/dist/indexer/walk/path-resolver.js +11 -5
  295. package/dist/indexer/walk/walker.js +42 -14
  296. package/dist/integrations/agent/builder-shared.js +7 -0
  297. package/dist/integrations/agent/builders.js +5 -58
  298. package/dist/integrations/agent/config.js +3 -143
  299. package/dist/integrations/agent/detect.js +17 -2
  300. package/dist/integrations/agent/engine-resolution.js +231 -0
  301. package/dist/integrations/agent/index.js +1 -2
  302. package/dist/integrations/agent/model-aliases.js +8 -3
  303. package/dist/integrations/agent/profiles.js +6 -99
  304. package/dist/integrations/agent/prompts.js +46 -18
  305. package/dist/integrations/agent/runner-dispatch.js +78 -13
  306. package/dist/integrations/agent/runner.js +76 -208
  307. package/dist/integrations/agent/spawn.js +48 -279
  308. package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
  309. package/dist/integrations/harnesses/aider/index.js +2 -12
  310. package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
  311. package/dist/integrations/harnesses/amazonq/index.js +3 -17
  312. package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
  313. package/dist/integrations/harnesses/claude/config-import.js +1 -3
  314. package/dist/integrations/harnesses/claude/index.js +1 -14
  315. package/dist/integrations/harnesses/claude/session-log.js +27 -75
  316. package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
  317. package/dist/integrations/harnesses/codex/index.js +2 -13
  318. package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
  319. package/dist/integrations/harnesses/copilot/index.js +1 -13
  320. package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
  321. package/dist/integrations/harnesses/gemini/index.js +1 -13
  322. package/dist/integrations/harnesses/ids.js +24 -0
  323. package/dist/integrations/harnesses/index.js +31 -33
  324. package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
  325. package/dist/integrations/harnesses/opencode/config-import.js +1 -3
  326. package/dist/integrations/harnesses/opencode/index.js +1 -18
  327. package/dist/integrations/harnesses/opencode/session-log.js +67 -125
  328. package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
  329. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
  330. package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
  331. package/dist/integrations/harnesses/openhands/index.js +2 -12
  332. package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
  333. package/dist/integrations/harnesses/pi/index.js +3 -16
  334. package/dist/integrations/harnesses/shared.js +17 -0
  335. package/dist/integrations/harnesses/types.js +38 -34
  336. package/dist/integrations/lockfile.js +211 -24
  337. package/dist/integrations/session-logs/index.js +24 -40
  338. package/dist/integrations/session-logs/provider-base.js +113 -0
  339. package/dist/llm/client.js +182 -110
  340. package/dist/llm/embedders/deterministic.js +2 -2
  341. package/dist/llm/embedders/remote.js +21 -9
  342. package/dist/llm/feature-gate.js +17 -57
  343. package/dist/llm/graph-extract.js +12 -13
  344. package/dist/llm/index-passes.js +8 -42
  345. package/dist/llm/memory-infer.js +144 -1
  346. package/dist/llm/metadata-enhance.js +45 -30
  347. package/dist/llm/structured-call.js +16 -8
  348. package/dist/llm/usage-persist.js +30 -5
  349. package/dist/llm/usage-telemetry.js +59 -6
  350. package/dist/output/cli-hints.js +1 -2
  351. package/dist/output/command-registry.js +27 -0
  352. package/dist/output/context.js +22 -7
  353. package/dist/output/format-exempt.js +80 -0
  354. package/dist/output/generic-render.js +251 -0
  355. package/dist/output/html-render.js +11 -16
  356. package/dist/output/render-registry.js +57 -0
  357. package/dist/output/renderers.js +15 -281
  358. package/dist/output/shapes/curate.js +10 -1
  359. package/dist/output/shapes/events.js +12 -7
  360. package/dist/output/shapes/helpers.js +58 -84
  361. package/dist/output/shapes/passthrough.js +8 -40
  362. package/dist/output/shapes/proposal/producer.js +15 -7
  363. package/dist/output/shapes/registry.js +12 -6
  364. package/dist/output/shapes.js +0 -9
  365. package/dist/output/text/{init.js → bundle-create.js} +3 -1
  366. package/dist/output/text/bundle-show.js +7 -0
  367. package/dist/output/text/command-format.js +562 -0
  368. package/dist/output/text/env.js +1 -3
  369. package/dist/output/text/events.js +8 -7
  370. package/dist/output/text/helpers.js +15 -1375
  371. package/dist/output/text/proposal/producer.js +4 -2
  372. package/dist/output/text/proposal-format.js +202 -0
  373. package/dist/output/text/registry-commands.js +1 -2
  374. package/dist/output/text/registry.js +12 -6
  375. package/dist/output/text/show-directives.js +117 -0
  376. package/dist/output/text/show-format.js +103 -0
  377. package/dist/output/text/sync.js +5 -0
  378. package/dist/output/text/workflow-format.js +332 -0
  379. package/dist/output/text/workflow.js +1 -2
  380. package/dist/output/text.js +10 -19
  381. package/dist/registry/factory.js +4 -6
  382. package/dist/registry/origin-resolve.js +16 -27
  383. package/dist/registry/providers/skills-sh.js +3 -3
  384. package/dist/registry/providers/static-index.js +15 -25
  385. package/dist/registry/resolve.js +43 -94
  386. package/dist/registry/semver.js +43 -0
  387. package/dist/runtime.js +81 -12
  388. package/dist/scripts/akm-migrate.js +35529 -0
  389. package/dist/setup/detect.js +5 -7
  390. package/dist/setup/detected-engines.js +136 -0
  391. package/dist/setup/engine-config.js +100 -0
  392. package/dist/setup/registry-stash-loader.js +3 -3
  393. package/dist/setup/semantic-assets.js +12 -9
  394. package/dist/setup/setup.js +444 -208
  395. package/dist/setup/steps/connection-shared.js +120 -0
  396. package/dist/setup/steps/connection.js +108 -305
  397. package/dist/setup/steps/platforms.js +13 -12
  398. package/dist/setup/steps/semantic.js +15 -3
  399. package/dist/setup/steps/sources.js +21 -15
  400. package/dist/setup/steps/stashdir.js +6 -4
  401. package/dist/setup/steps/tasks.js +236 -119
  402. package/dist/setup/steps.js +3 -2
  403. package/dist/sources/freshness.js +39 -0
  404. package/dist/sources/provider-factory.js +11 -17
  405. package/dist/sources/providers/filesystem.js +2 -3
  406. package/dist/sources/providers/git-install.js +278 -34
  407. package/dist/sources/providers/git-provider.js +54 -56
  408. package/dist/sources/providers/git-stash.js +420 -91
  409. package/dist/sources/providers/git.js +2 -2
  410. package/dist/sources/providers/npm.js +16 -19
  411. package/dist/sources/providers/provider-utils.js +47 -22
  412. package/dist/sources/providers/sync-from-ref.js +3 -9
  413. package/dist/sources/providers/website.js +2 -2
  414. package/dist/sources/resolve.js +11 -10
  415. package/dist/sources/snapshot-fetchers/types.js +4 -0
  416. package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
  417. package/dist/storage/database.js +60 -4
  418. package/dist/storage/engines/sqlite-migrations.js +156 -5
  419. package/dist/storage/locations.js +1 -2
  420. package/dist/storage/repositories/canaries-repository.js +1 -1
  421. package/dist/storage/repositories/events-repository.js +51 -11
  422. package/dist/storage/repositories/improve-runs-repository.js +6 -32
  423. package/dist/storage/repositories/index-connection.js +79 -0
  424. package/dist/storage/repositories/index-db.js +4 -3
  425. package/dist/storage/repositories/index-entries-repository.js +863 -0
  426. package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
  427. package/dist/storage/repositories/index-entry-types.js +4 -0
  428. package/dist/storage/repositories/index-fts-repository.js +167 -0
  429. package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
  430. package/dist/storage/repositories/index-meta-repository.js +49 -0
  431. package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
  432. package/dist/storage/repositories/index-sql.js +12 -0
  433. package/dist/storage/repositories/index-utility-repository.js +356 -0
  434. package/dist/storage/repositories/index-vec-repository.js +250 -0
  435. package/dist/storage/repositories/outcome-repository.js +119 -0
  436. package/dist/storage/repositories/proposals-repository.js +317 -75
  437. package/dist/storage/repositories/registry-cache.js +1 -1
  438. package/dist/storage/repositories/salience-repository.js +172 -0
  439. package/dist/storage/repositories/task-history-repository.js +110 -3
  440. package/dist/storage/repositories/workflow-runs-repository.js +68 -35
  441. package/dist/tasks/backends/cron.js +169 -46
  442. package/dist/tasks/backends/exec-utils.js +76 -3
  443. package/dist/tasks/backends/index.js +6 -9
  444. package/dist/tasks/backends/launchd.js +292 -55
  445. package/dist/tasks/backends/schtasks.js +557 -70
  446. package/dist/tasks/backends/types.js +4 -0
  447. package/dist/tasks/command-executable.js +93 -0
  448. package/dist/tasks/embedded.js +56 -38
  449. package/dist/tasks/parser.js +156 -64
  450. package/dist/tasks/resolve-akm-bin.js +144 -51
  451. package/dist/tasks/runner.js +377 -209
  452. package/dist/tasks/schedule.js +108 -19
  453. package/dist/tasks/scheduler-invocation.js +296 -0
  454. package/dist/tasks/schema.js +1 -1
  455. package/dist/tasks/task-id.js +35 -0
  456. package/dist/tasks/validator.js +30 -16
  457. package/dist/workflows/authoring/authoring.js +96 -148
  458. package/dist/workflows/authoring/scope-key.js +1 -1
  459. package/dist/workflows/cli.js +0 -20
  460. package/dist/workflows/concurrency-policy.js +15 -0
  461. package/dist/workflows/exec/brief.js +25 -59
  462. package/dist/workflows/exec/frozen-judge.js +47 -0
  463. package/dist/workflows/exec/native-executor.js +157 -94
  464. package/dist/workflows/exec/report.js +365 -200
  465. package/dist/workflows/exec/run-workflow.js +46 -40
  466. package/dist/workflows/exec/scheduler.js +12 -41
  467. package/dist/workflows/exec/step-work.js +239 -205
  468. package/dist/workflows/exec/workflow-engine-gate.js +67 -0
  469. package/dist/workflows/ir/compile.js +141 -283
  470. package/dist/workflows/ir/freeze.js +233 -0
  471. package/dist/workflows/ir/plan-hash.js +40 -5
  472. package/dist/workflows/ir/schema.js +537 -1
  473. package/dist/workflows/parser.js +878 -306
  474. package/dist/workflows/program/expressions.js +20 -208
  475. package/dist/workflows/program/schema.js +7 -10
  476. package/dist/workflows/renderer.js +99 -121
  477. package/dist/workflows/resource-limits.js +22 -0
  478. package/dist/workflows/runtime/checkin.js +1 -1
  479. package/dist/workflows/runtime/plan-classifier.js +131 -0
  480. package/dist/workflows/runtime/runs.js +200 -113
  481. package/dist/workflows/runtime/unit-checkin.js +1 -1
  482. package/dist/workflows/runtime/unit-phases.js +20 -0
  483. package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
  484. package/dist/workflows/schema.js +1 -11
  485. package/dist/workflows/validate-summary.js +4 -26
  486. package/dist/workflows/validator.js +52 -30
  487. package/docs/README.md +42 -78
  488. package/docs/migration/README.md +8 -0
  489. package/docs/migration/release-notes/0.6.0.md +1 -1
  490. package/docs/migration/release-notes/0.7.0.md +9 -8
  491. package/docs/migration/release-notes/0.9.0.md +158 -14
  492. package/docs/migration/v0.7-to-v0.8.md +46 -47
  493. package/docs/migration/v0.8-to-v0.9.md +844 -0
  494. package/docs/reference/README.md +12 -0
  495. package/docs/reference/data-and-telemetry.md +333 -0
  496. package/package.json +21 -17
  497. package/schemas/akm-asset-envelope.json +93 -0
  498. package/schemas/akm-config.json +4636 -0
  499. package/schemas/akm-task.json +87 -0
  500. package/{dist/schemas → schemas}/akm-workflow.json +127 -82
  501. package/dist/akm-migrate-storage +0 -38
  502. package/dist/assets/help/help-accept.md +0 -12
  503. package/dist/assets/help/help-improve.md +0 -84
  504. package/dist/assets/help/help-proposals.md +0 -17
  505. package/dist/assets/help/help-propose.md +0 -17
  506. package/dist/assets/help/help-reject.md +0 -11
  507. package/dist/assets/profiles/frequent.json +0 -13
  508. package/dist/assets/profiles/recombine-only.json +0 -21
  509. package/dist/assets/profiles/reflect-distill.json +0 -30
  510. package/dist/assets/profiles/synthesize.json +0 -15
  511. package/dist/assets/prompts/procedural-system.md +0 -44
  512. package/dist/assets/prompts/recombine-system.md +0 -40
  513. package/dist/assets/prompts/staleness-detect-system.md +0 -6
  514. package/dist/assets/tasks/core/backup.yml +0 -4
  515. package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
  516. package/dist/assets/templates/html/default.html +0 -78
  517. package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
  518. package/dist/assets/wiki/index-template.md +0 -12
  519. package/dist/assets/wiki/ingest-workflow-template.md +0 -83
  520. package/dist/assets/wiki/log-template.md +0 -8
  521. package/dist/assets/wiki/schema-template.md +0 -61
  522. package/dist/cli/config-migrate.js +0 -150
  523. package/dist/cli/config-validate.js +0 -39
  524. package/dist/commands/graph/graph-cli.js +0 -124
  525. package/dist/commands/graph/graph.js +0 -487
  526. package/dist/commands/improve/calibration.js +0 -161
  527. package/dist/commands/improve/dedup.js +0 -482
  528. package/dist/commands/improve/extract-watch.js +0 -140
  529. package/dist/commands/improve/hot-probation.js +0 -45
  530. package/dist/commands/improve/improve-auto-accept.js +0 -276
  531. package/dist/commands/improve/improve-profiles.js +0 -168
  532. package/dist/commands/improve/procedural.js +0 -398
  533. package/dist/commands/improve/recombine.js +0 -818
  534. package/dist/commands/improve/schema-similarity-gate.js +0 -168
  535. package/dist/commands/lint/agent-linter.js +0 -44
  536. package/dist/commands/lint/command-linter.js +0 -44
  537. package/dist/commands/lint/default-linter.js +0 -16
  538. package/dist/commands/lint/fact-linter.js +0 -39
  539. package/dist/commands/lint/knowledge-linter.js +0 -16
  540. package/dist/commands/lint/memory-linter.js +0 -61
  541. package/dist/commands/lint/registry.js +0 -41
  542. package/dist/commands/lint/skill-linter.js +0 -45
  543. package/dist/commands/lint/task-linter.js +0 -50
  544. package/dist/commands/lint/workflow-linter.js +0 -81
  545. package/dist/commands/proposal/legacy-import.js +0 -115
  546. package/dist/commands/sources/history.js +0 -196
  547. package/dist/commands/tasks/default-tasks.js +0 -186
  548. package/dist/commands/wiki-cli.js +0 -292
  549. package/dist/core/asset/asset-registry.js +0 -76
  550. package/dist/core/asset/asset-spec.js +0 -316
  551. package/dist/core/config/config-migration.js +0 -602
  552. package/dist/core/deep-merge.js +0 -38
  553. package/dist/core/eval/rank-metrics.js +0 -113
  554. package/dist/core/ripgrep/install.js +0 -163
  555. package/dist/core/ripgrep/resolve.js +0 -81
  556. package/dist/indexer/db/db.js +0 -1414
  557. package/dist/indexer/manifest.js +0 -170
  558. package/dist/indexer/passes/metadata-contributors.js +0 -31
  559. package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
  560. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
  561. package/dist/llm/call-ai.js +0 -62
  562. package/dist/llm/memory-infer-impl.js +0 -138
  563. package/dist/output/shapes/distill.js +0 -14
  564. package/dist/output/shapes/history.js +0 -11
  565. package/dist/output/text/distill.js +0 -6
  566. package/dist/output/text/enable-disable.js +0 -8
  567. package/dist/output/text/history.js +0 -6
  568. package/dist/output/text/wiki.js +0 -16
  569. package/dist/registry/build-index.js +0 -386
  570. package/dist/schemas/akm-config.json +0 -14225
  571. package/dist/scripts/migrate-storage.js +0 -13169
  572. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
  573. package/dist/scripts/migrations/v16-to-v17.js +0 -141
  574. package/dist/setup/legacy-config.js +0 -106
  575. package/dist/storage/repositories/consolidation-repository.js +0 -38
  576. package/dist/storage/repositories/recombine-repository.js +0 -213
  577. package/dist/wiki/wiki-templates.js +0 -15
  578. package/dist/wiki/wiki.js +0 -1012
  579. package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
  580. package/dist/workflows/db.js +0 -350
  581. package/dist/workflows/exec/watch.js +0 -116
  582. package/dist/workflows/program/parser.js +0 -760
  583. package/dist/workflows/program/project.js +0 -105
  584. package/docs/data-and-telemetry.md +0 -227
  585. package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
  586. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
  587. /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
@@ -1,1381 +1,21 @@
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 function formatInfoPlain(r) {
5
- const lines = [];
6
- if (r.version)
7
- lines.push(`version: ${String(r.version)}`);
8
- if (r.stashDir)
9
- lines.push(`stashDir: ${String(r.stashDir)}`);
10
- if (r.configPath)
11
- lines.push(`configPath: ${String(r.configPath)}`);
12
- if (r.cacheDir)
13
- lines.push(`cacheDir: ${String(r.cacheDir)}`);
14
- if (r.dbPath)
15
- lines.push(`dbPath: ${String(r.dbPath)}`);
16
- const capabilities = r.capabilities;
17
- if (capabilities) {
18
- lines.push("capabilities:");
19
- for (const [k, v] of Object.entries(capabilities)) {
20
- lines.push(` ${k}: ${typeof v === "object" ? JSON.stringify(v) : String(v)}`);
21
- }
22
- }
23
- const indexStats = r.index;
24
- if (indexStats) {
25
- lines.push("index:");
26
- for (const [k, v] of Object.entries(indexStats)) {
27
- lines.push(` ${k}: ${typeof v === "object" ? JSON.stringify(v) : String(v)}`);
28
- }
29
- }
30
- if (lines.length === 0)
31
- return JSON.stringify(r, null, 2);
32
- return lines.join("\n");
33
- }
34
- export function formatConfigPlain(r) {
35
- // Recursive flattener: prints `key=value` lines, and nested objects as
36
- // `parent.child=value`. Arrays render as JSON for compactness.
37
- const lines = [];
38
- const walk = (obj, prefix) => {
39
- for (const [k, v] of Object.entries(obj)) {
40
- const path = prefix ? `${prefix}.${k}` : k;
41
- if (v === null || v === undefined) {
42
- lines.push(`${path}=`);
43
- }
44
- else if (Array.isArray(v)) {
45
- lines.push(`${path}=${JSON.stringify(v)}`);
46
- }
47
- else if (typeof v === "object") {
48
- walk(v, path);
49
- }
50
- else {
51
- lines.push(`${path}=${String(v)}`);
52
- }
53
- }
54
- };
55
- walk(r, "");
56
- if (lines.length === 0)
57
- return "(empty config)";
58
- return lines.join("\n");
59
- }
60
- export function formatFeedbackPlain(r) {
61
- const ref = String(r.ref ?? "?");
62
- const signal = String(r.signal ?? "?");
63
- const note = typeof r.note === "string" && r.note ? ` — ${r.note}` : "";
64
- return `Recorded ${signal} feedback for ${ref}${note}`;
65
- }
66
- export function formatRememberPlain(r) {
67
- const ref = String(r.ref ?? "?");
68
- const pathValue = String(r.path ?? "?");
69
- return `Saved ${ref} at ${pathValue}`;
70
- }
71
- export function formatImportPlain(r) {
72
- const ref = String(r.ref ?? "?");
73
- const source = String(r.source ?? "?");
74
- const pathValue = String(r.path ?? "?");
75
- return `Imported ${source} → ${ref} at ${pathValue}`;
76
- }
77
- export function formatSavePlain(r) {
78
- if (r.ok === false) {
79
- const reason = typeof r.reason === "string" ? r.reason : "unknown";
80
- return `save: failed (${reason})`;
81
- }
82
- const name = typeof r.name === "string" ? r.name : "primary stash";
83
- const committed = r.committed === true;
84
- const pushed = r.pushed === true;
85
- const parts = [`save: ${name}`];
86
- parts.push(committed ? "committed" : "no changes");
87
- if (pushed)
88
- parts.push("pushed");
89
- return parts.join(" — ");
90
- }
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
- export function formatRegistryListPlain(r) {
98
- const registries = Array.isArray(r.registries) ? r.registries : [];
99
- if (registries.length === 0) {
100
- return "No registries configured. Add one with `akm registry add <url>`.";
101
- }
102
- const lines = [];
103
- for (const reg of registries) {
104
- const url = String(reg.url ?? "?");
105
- const name = typeof reg.name === "string" ? reg.name : "";
106
- const provider = typeof reg.provider === "string" ? ` (${reg.provider})` : "";
107
- const enabled = reg.enabled === false ? " [disabled]" : "";
108
- const head = name ? `${name}: ${url}` : url;
109
- lines.push(`${head}${provider}${enabled}`);
110
- }
111
- return lines.join("\n");
112
- }
113
- export function formatRegistryAddPlain(r) {
114
- if (r.added === false) {
115
- return typeof r.message === "string" ? r.message : "Registry already configured.";
116
- }
117
- const registries = Array.isArray(r.registries) ? r.registries.length : 0;
118
- return `Registry added (${registries} total).`;
119
- }
120
- export function formatRegistryRemovePlain(r) {
121
- if (r.removed === false) {
122
- return typeof r.message === "string" ? r.message : "No matching registry found.";
123
- }
124
- const entry = r.entry;
125
- const url = entry ? String(entry.url ?? entry.name ?? "?") : "?";
126
- return `Removed registry ${url}`;
127
- }
128
- export function formatRegistrySearchPlain(r, detail) {
129
- // Reuse the same renderer as `search` — both share `hits` / `registryHits`.
130
- return formatSearchPlain(r, detail);
131
- }
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
- export function formatEnvListPlain(r) {
139
- // Multi-env listing: { envs: [{ ref, path, keys }, ...] }
140
- const envs = Array.isArray(r.envs) ? r.envs : [];
141
- if (envs.length === 0) {
142
- return "No env files. Create one with `akm env create <name>`, then edit the .env file directly.";
143
- }
144
- const lines = [];
145
- for (const v of envs) {
146
- const ref = String(v.ref ?? "?");
147
- const keys = Array.isArray(v.keys) ? v.keys.map(String) : [];
148
- if (lines.length > 0)
149
- lines.push("");
150
- lines.push(`## ${ref}`);
151
- if (keys.length === 0) {
152
- lines.push("- (no keys)");
153
- continue;
154
- }
155
- for (const key of keys) {
156
- lines.push(`- ${key}`);
157
- }
158
- }
159
- return lines.join("\n");
160
- }
161
- export function formatEnvCreatePlain(r) {
162
- return `Created env ${String(r.ref ?? "?")}`;
163
- }
164
- export function formatEnvExportPlain(r) {
165
- return `Wrote ${String(r.ref ?? "?")} export script → ${String(r.out ?? "?")} (mode 0600; source it, then delete)`;
166
- }
167
- export function formatEnvRemovePlain(r) {
168
- const removed = r.removed === true;
169
- return removed ? `Removed env ${String(r.ref ?? "?")}` : `Env ${String(r.ref ?? "?")} was not present`;
170
- }
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
- export function formatWikiRegisterPlain(r) {
186
- const name = String(r.name ?? r.wiki ?? "?");
187
- const ref = String(r.ref ?? r.path ?? r.url ?? "?");
188
- return `Registered wiki ${name} → ${ref}`;
189
- }
190
- export function formatWorkflowValidatePlain(r) {
191
- const ok = r.ok !== false;
192
- const pathValue = String(r.path ?? "?");
193
- if (!ok)
194
- return `workflow validate: failed (${pathValue})`;
195
- const title = typeof r.title === "string" ? r.title : "";
196
- const stepCount = typeof r.stepCount === "number" ? r.stepCount : 0;
197
- const lines = [`workflow validate: ok — ${title || pathValue} (${stepCount} step(s))`];
198
- // Non-fatal advisories: clearly marked, printed after the ok line so `ok`
199
- // is never in doubt. Absent/empty for markdown and fully-typed programs.
200
- const warnings = Array.isArray(r.warnings) ? r.warnings : [];
201
- if (warnings.length > 0) {
202
- lines.push(` ${warnings.length} warning(s):`);
203
- for (const w of warnings) {
204
- const line = typeof w.line === "number" ? w.line : "?";
205
- lines.push(` warning: ${pathValue}:${line} — ${String(w.message ?? "")}`);
206
- }
207
- }
208
- return lines.join("\n");
209
- }
210
4
  /**
211
- * Plain-text rendering for a step-completion that was rejected by the
212
- * summary-validation gate (#506): the step stays pending and the agent gets
213
- * corrective feedback on what to finish/fix.
214
- */
215
- export function formatWorkflowCompleteRejectedPlain(r) {
216
- const stepId = String(r.stepId ?? "?");
217
- const feedback = typeof r.feedback === "string" ? r.feedback : "";
218
- const missing = Array.isArray(r.missing) ? r.missing.map((m) => String(m)) : [];
219
- const lines = [`workflow complete: rejected — step "${stepId}" does not meet its completion criteria`];
220
- if (feedback)
221
- lines.push(` feedback: ${feedback}`);
222
- if (missing.length > 0) {
223
- lines.push(" outstanding:");
224
- for (const m of missing)
225
- lines.push(` - ${m}`);
226
- }
227
- return lines.join("\n");
228
- }
229
- export function formatProposalProducerPlain(command, r) {
230
- if (r.ok === false) {
231
- const reason = String(r.reason ?? "unknown");
232
- const error = typeof r.error === "string" ? r.error : "";
233
- const lines = [`${command}: failed (${reason})`];
234
- if (error)
235
- lines.push(` error: ${error}`);
236
- if (r.ref)
237
- lines.push(` ref: ${String(r.ref)}`);
238
- if (r.exitCode !== undefined && r.exitCode !== null) {
239
- lines.push(` exitCode: ${String(r.exitCode)}`);
240
- }
241
- return lines.join("\n");
242
- }
243
- const proposal = r.proposal ?? {};
244
- const id = String(proposal.id ?? "?");
245
- const ref = String(r.ref ?? proposal.ref ?? "?");
246
- const status = String(proposal.status ?? "pending");
247
- return `${command}: queued proposal ${id} (${ref}) [${status}]`;
248
- }
249
- /**
250
- * Render a one-line gate-decision summary for the proposal list / show surfaces
251
- * (#577), e.g. `gate=deferred:below-threshold (0.72 < 0.90)`. Returns the empty
252
- * string for a missing or malformed decision so legacy proposals render cleanly.
253
- */
254
- export function formatGateDecisionSummary(raw) {
255
- if (typeof raw !== "object" || raw === null)
256
- return "";
257
- const d = raw;
258
- const outcome = typeof d.outcome === "string" ? d.outcome : undefined;
259
- if (!outcome)
260
- return "";
261
- const reason = typeof d.reason === "string" && d.reason.length > 0 ? `:${d.reason}` : "";
262
- const cmp = formatGateThresholdComparison(d);
263
- return `gate=${outcome}${reason}${cmp ? ` (${cmp})` : ""}`;
264
- }
265
- /**
266
- * Reconstruct the threshold comparison the gate applied, when both sides are
267
- * present (e.g. confidence 0.72 vs. autoAccept 0.90 → "0.72 < 0.90"). Returns
268
- * the empty string when the decision lacks the operands.
269
- */
270
- function formatGateThresholdComparison(d) {
271
- const thresholds = (typeof d.thresholds === "object" && d.thresholds !== null ? d.thresholds : {});
272
- const confidence = typeof d.confidence === "number" ? d.confidence : undefined;
273
- const autoAccept = typeof thresholds.autoAccept === "number" ? thresholds.autoAccept : undefined;
274
- if (confidence !== undefined && autoAccept !== undefined) {
275
- const op = confidence >= autoAccept ? ">=" : "<";
276
- return `${confidence.toFixed(2)} ${op} ${autoAccept.toFixed(2)}`;
277
- }
278
- // Drain bands: when the measured value is present, render the full comparison
279
- // ("210 > 200" / "1 < 5"); otherwise fall back to the bound alone (#577).
280
- const measured = typeof d.measured === "number" ? d.measured : undefined;
281
- if (typeof thresholds.maxDiffLines === "number") {
282
- return measured !== undefined
283
- ? `${measured} > ${thresholds.maxDiffLines}`
284
- : `maxDiffLines=${thresholds.maxDiffLines}`;
285
- }
286
- if (typeof thresholds.minContentLines === "number") {
287
- return measured !== undefined
288
- ? `${measured} < ${thresholds.minContentLines}`
289
- : `minContentLines=${thresholds.minContentLines}`;
290
- }
291
- return "";
292
- }
293
- export function formatProposalListPlain(r) {
294
- const proposals = Array.isArray(r.proposals) ? r.proposals : [];
295
- const total = typeof r.totalCount === "number" ? r.totalCount : proposals.length;
296
- if (proposals.length === 0) {
297
- return `${total} proposal(s).\nNo proposals.\nGenerate one with \`akm reflect <ref>\`, \`akm propose <type> <name> --task ...\`, or \`akm distill <ref>\`.`;
298
- }
299
- const lines = [`${total} proposal(s)`, ""];
300
- for (const p of proposals) {
301
- const id = String(p.id ?? "?");
302
- const ref = String(p.ref ?? "?");
303
- const status = String(p.status ?? "?");
304
- const source = String(p.source ?? "?");
305
- const created = String(p.createdAt ?? "?");
306
- // #577: surface the gate verdict inline so the queue explains itself
307
- // ("deferred: below-threshold"). Legacy proposals carry no gateDecision.
308
- const gate = formatGateDecisionSummary(p.gateDecision);
309
- const gateSuffix = gate ? ` ${gate}` : "";
310
- lines.push(`${id} [${status}] ${ref} source=${source} ${created}${gateSuffix}`);
311
- }
312
- return lines.join("\n").trimEnd();
313
- }
314
- export function formatProposalShowPlain(r) {
315
- const p = r.proposal ?? {};
316
- const lines = [];
317
- lines.push(`# proposal ${String(p.id ?? "?")}`);
318
- lines.push(`ref: ${String(p.ref ?? "?")}`);
319
- lines.push(`status: ${String(p.status ?? "?")}`);
320
- lines.push(`source: ${String(p.source ?? "?")}`);
321
- if (p.sourceRun)
322
- lines.push(`sourceRun: ${String(p.sourceRun)}`);
323
- if (p.createdAt)
324
- lines.push(`createdAt: ${String(p.createdAt)}`);
325
- if (p.updatedAt)
326
- lines.push(`updatedAt: ${String(p.updatedAt)}`);
327
- if (typeof p.confidence === "number")
328
- lines.push(`confidence: ${p.confidence.toFixed(2)}`);
329
- // #577: gate decision (auto-accepted / deferred / auto-rejected + reason +
330
- // thresholds). Absent on legacy proposals — render "unknown" so the field is
331
- // always present and the operator never sees a silent gap.
332
- const gate = p.gateDecision;
333
- if (gate && typeof gate.outcome === "string") {
334
- lines.push(`gate.decision: ${String(gate.outcome)}`);
335
- lines.push(`gate.reason: ${gate.reason ? String(gate.reason) : "unknown"}`);
336
- const cmp = formatGateThresholdComparison(gate);
337
- if (cmp)
338
- lines.push(`gate.thresholds: ${cmp}`);
339
- if (gate.gate)
340
- lines.push(`gate.by: ${String(gate.gate)}`);
341
- if (gate.decidedAt)
342
- lines.push(`gate.decidedAt: ${String(gate.decidedAt)}`);
343
- }
344
- else {
345
- lines.push("gate.decision: unknown");
346
- }
347
- const review = p.review;
348
- if (review) {
349
- lines.push(`review.outcome: ${String(review.outcome ?? "?")}`);
350
- if (review.reason)
351
- lines.push(`review.reason: ${String(review.reason)}`);
352
- if (review.decidedAt)
353
- lines.push(`review.decidedAt: ${String(review.decidedAt)}`);
354
- }
355
- const validation = r.validation;
356
- if (validation) {
357
- const findings = Array.isArray(validation.findings) ? validation.findings : [];
358
- // Partition findings by severity. `severity: "warn"` findings are
359
- // non-blocking (the validator reports `ok: true` for a warn-only proposal),
360
- // so they must read as advisory — a distinct icon/label from blocking errors.
361
- const warnings = findings.filter((f) => f.severity === "warn");
362
- const errors = findings.filter((f) => f.severity !== "warn");
363
- lines.push("");
364
- if (errors.length > 0) {
365
- const warnSuffix = warnings.length > 0 ? `, ${warnings.length} warning(s)` : "";
366
- lines.push(`✗ invalid (${errors.length} error(s)${warnSuffix})`);
367
- }
368
- else if (warnings.length > 0) {
369
- lines.push(`✓ valid (${warnings.length} warning(s))`);
370
- }
371
- else {
372
- lines.push("✓ valid");
373
- }
374
- // Errors first (blocking), then warnings (advisory, non-blocking).
375
- for (const f of errors) {
376
- lines.push(` ✗ error [${String(f.kind)}] ${String(f.message)}`);
377
- }
378
- for (const f of warnings) {
379
- lines.push(` ⚠ warning [${String(f.kind)}] ${String(f.message)} (non-blocking)`);
380
- }
381
- }
382
- const payload = p.payload;
383
- if (payload && typeof payload.content === "string") {
384
- lines.push("");
385
- lines.push("payload:");
386
- lines.push(payload.content);
387
- }
388
- return lines.join("\n").trimEnd();
389
- }
390
- export function formatProposalAcceptPlain(r) {
391
- return `Accepted proposal ${String(r.id ?? "?")} → ${String(r.ref ?? "?")} at ${String(r.assetPath ?? "?")}`;
392
- }
393
- export function formatProposalRejectPlain(r) {
394
- const reason = r.reason ? ` (${String(r.reason)})` : "";
395
- return `Rejected proposal ${String(r.id ?? "?")} (${String(r.ref ?? "?")})${reason}`;
396
- }
397
- export function formatProposalDrainPlain(r) {
398
- const policy = String(r.policy ?? "?");
399
- const applyMode = String(r.applyMode ?? "queue");
400
- const promoted = Array.isArray(r.promoted) ? r.promoted : [];
401
- const rejected = Array.isArray(r.rejected) ? r.rejected : [];
402
- const deferred = Array.isArray(r.deferred) ? r.deferred : [];
403
- const skippedByCap = Array.isArray(r.skippedByCap) ? r.skippedByCap : [];
404
- const prefix = r.dryRun === true ? "[dry-run] " : "";
405
- const lines = [
406
- `${prefix}Drained proposal queue (policy=${policy}, applyMode=${applyMode})`,
407
- ` promoted: ${promoted.length}`,
408
- ` rejected: ${rejected.length}`,
409
- ` deferred: ${deferred.length}`,
410
- ` skippedByCap: ${skippedByCap.length}`,
411
- ];
412
- for (const d of deferred) {
413
- lines.push(` - ${String(d.id ?? "?")} (${String(d.reason ?? "?")})`);
414
- }
415
- return lines.join("\n").trimEnd();
416
- }
417
- export function formatDistillPlain(r) {
418
- const outcome = String(r.outcome ?? "unknown");
419
- const inputRef = String(r.inputRef ?? "?");
420
- const lessonRef = String(r.lessonRef ?? "?");
421
- if (outcome === "queued") {
422
- const id = String(r.proposalId ?? "?");
423
- return `Distilled ${inputRef} → proposal ${id} (${lessonRef}). Run \`akm proposal show ${id}\` to review.`;
424
- }
425
- if (outcome === "validation_failed") {
426
- const findings = Array.isArray(r.findings) ? r.findings : [];
427
- const lines = [`Distillation produced an invalid lesson for ${inputRef}; no proposal queued.`];
428
- for (const f of findings) {
429
- lines.push(` - ${String(f.message ?? f.kind ?? "validation finding")}`);
430
- }
431
- return lines.join("\n");
432
- }
433
- // skipped
434
- const message = typeof r.message === "string" ? r.message : "feature disabled or LLM unavailable";
435
- return `Distill skipped for ${inputRef}: ${message}`;
436
- }
437
- export function formatProposalDiffPlain(r) {
438
- const header = r.isNew
439
- ? `# proposal ${String(r.id ?? "?")} (new asset: ${String(r.ref ?? "?")})`
440
- : `# proposal ${String(r.id ?? "?")} (update: ${String(r.ref ?? "?")})`;
441
- const unified = typeof r.unified === "string" ? r.unified : "";
442
- if (!unified)
443
- return `${header}\n(no changes)`;
444
- return `${header}\n${unified}`;
445
- }
446
- export function formatEventsPlain(r) {
447
- const events = Array.isArray(r.events) ? r.events : [];
448
- const headerParts = [];
449
- if (typeof r.ref === "string" && r.ref)
450
- headerParts.push(`ref: ${r.ref}`);
451
- if (typeof r.type === "string" && r.type)
452
- headerParts.push(`type: ${r.type}`);
453
- if (typeof r.since === "string" && r.since)
454
- headerParts.push(`since: ${r.since}`);
455
- const totalCount = typeof r.totalCount === "number" ? r.totalCount : events.length;
456
- headerParts.push(`${totalCount} event(s)`);
457
- const header = headerParts.join(" ");
458
- if (events.length === 0) {
459
- return `${header}\nNo events.`;
460
- }
461
- const lines = [header, ""];
462
- for (const event of events) {
463
- lines.push(formatEventLine(event));
464
- }
465
- return lines.join("\n").trimEnd();
466
- }
467
- export function formatEventLine(event) {
468
- const ts = String(event.ts ?? "?");
469
- const eventType = String(event.eventType ?? "?");
470
- const ref = event.ref ? String(event.ref) : null;
471
- const head = ref ? `${ts} [${eventType}] ${ref}` : `${ts} [${eventType}]`;
472
- if (event.metadata != null && event.metadata !== "") {
473
- const meta = typeof event.metadata === "string" ? event.metadata : JSON.stringify(event.metadata);
474
- return `${head}\n metadata: ${meta}`;
475
- }
476
- return head;
477
- }
478
- export function formatHistoryPlain(r) {
479
- const entries = Array.isArray(r.entries) ? r.entries : [];
480
- const headerParts = [];
481
- if (typeof r.ref === "string" && r.ref)
482
- headerParts.push(`ref: ${r.ref}`);
483
- if (typeof r.since === "string" && r.since)
484
- headerParts.push(`since: ${r.since}`);
485
- const totalCount = typeof r.totalCount === "number" ? r.totalCount : entries.length;
486
- headerParts.push(`${totalCount} event(s)`);
487
- // Show active event sources so operators know which streams were consulted.
488
- if (Array.isArray(r.sources) && r.sources.length > 0) {
489
- headerParts.push(`sources: ${r.sources.join(", ")}`);
490
- }
491
- const header = headerParts.join(" ");
492
- if (entries.length === 0) {
493
- const scope = typeof r.ref === "string" && r.ref ? ` for ${r.ref}` : "";
494
- return `${header}\nNo history${scope}.`;
495
- }
496
- const lines = [header, ""];
497
- for (const entry of entries) {
498
- const created = String(entry.createdAt ?? "?");
499
- const eventType = String(entry.eventType ?? "?");
500
- const ref = entry.ref ? String(entry.ref) : null;
501
- const signal = entry.signal ? String(entry.signal) : null;
502
- const query = entry.query ? String(entry.query) : null;
503
- const head = ref ? `${created} [${eventType}] ${ref}` : `${created} [${eventType}]`;
504
- lines.push(head);
505
- if (signal)
506
- lines.push(` signal: ${signal}`);
507
- if (query)
508
- lines.push(` query: ${query}`);
509
- if (entry.metadata != null && entry.metadata !== "") {
510
- const meta = typeof entry.metadata === "string" ? entry.metadata : JSON.stringify(entry.metadata);
511
- lines.push(` metadata: ${meta}`);
512
- }
513
- }
514
- return lines.join("\n").trimEnd();
515
- }
516
- export function formatShowPlain(r, detail) {
517
- const lines = [];
518
- if (r.type || r.name) {
519
- lines.push(`# ${String(r.type ?? "asset")}: ${String(r.name ?? "unknown")}`);
520
- }
521
- if (r.path && r.editable !== false) {
522
- lines.push(`file: ${String(r.path)}`);
523
- }
524
- if (r.origin !== undefined)
525
- lines.push(`# origin: ${String(r.origin)}`);
526
- if (r.action)
527
- lines.push(`# ${String(r.action)}`);
528
- if (r.description)
529
- lines.push(`description: ${String(r.description)}`);
530
- if (r.workflowTitle)
531
- lines.push(`workflowTitle: ${String(r.workflowTitle)}`);
532
- if (r.agent)
533
- lines.push(`agent: ${String(r.agent)}`);
534
- if (Array.isArray(r.parameters) && r.parameters.length > 0)
535
- lines.push(`parameters: ${r.parameters.join(", ")}`);
536
- if (Array.isArray(r.workflowParameters) && r.workflowParameters.length > 0) {
537
- lines.push("workflowParameters:");
538
- for (const parameter of r.workflowParameters) {
539
- const name = typeof parameter.name === "string" ? parameter.name : "unknown";
540
- const description = typeof parameter.description === "string" && parameter.description.trim() ? `: ${parameter.description}` : "";
541
- lines.push(` - ${name}${description}`);
542
- }
543
- }
544
- if (r.modelHint != null)
545
- lines.push(`modelHint: ${String(r.modelHint)}`);
546
- if (r.toolPolicy != null)
547
- lines.push(`toolPolicy: ${JSON.stringify(r.toolPolicy)}`);
548
- if (r.run)
549
- lines.push(`run: ${String(r.run)}`);
550
- if (r.setup)
551
- lines.push(`setup: ${String(r.setup)}`);
552
- if (r.cwd)
553
- lines.push(`cwd: ${String(r.cwd)}`);
554
- if (detail === "full") {
555
- if (r.path)
556
- lines.push(`path: ${String(r.path)}`);
557
- if (r.editable !== undefined)
558
- lines.push(`editable: ${String(r.editable)}`);
559
- if (r.editHint)
560
- lines.push(`editHint: ${String(r.editHint)}`);
561
- if (r.schemaVersion !== undefined)
562
- lines.push(`schemaVersion: ${String(r.schemaVersion)}`);
563
- }
564
- const related = typeof r.related === "object" && r.related !== null ? r.related : undefined;
565
- const relatedHits = related && Array.isArray(related.hits) ? related.hits : [];
566
- if (related) {
567
- lines.push("");
568
- lines.push(`related: ${String(related.total ?? relatedHits.length)}`);
569
- for (const hit of relatedHits) {
570
- lines.push(` - ${String(hit.type ?? "?")}: ${formatRelatedLabel(hit)}`);
571
- const shared = Array.isArray(hit.sharedEntities) ? hit.sharedEntities.map(String) : [];
572
- if (shared.length > 0)
573
- lines.push(` shared: ${shared.join(", ")}`);
574
- lines.push(` relationCount: ${String(hit.relationCount ?? 0)}`);
575
- }
576
- }
577
- const payloads = [r.content, r.template, r.prompt].filter((value) => value != null).map(String);
578
- if (Array.isArray(r.steps) && r.steps.length > 0) {
579
- if (lines.length > 0)
580
- lines.push("");
581
- lines.push("steps:");
582
- for (const [index, step] of r.steps.entries()) {
583
- const title = typeof step.title === "string" ? step.title : "Untitled step";
584
- const id = typeof step.id === "string" ? step.id : "unknown";
585
- lines.push(` ${index + 1}. ${title} [${id}]`);
586
- if (typeof step.instructions === "string" && step.instructions.trim()) {
587
- const instrLines = step.instructions.trim().split("\n");
588
- lines.push(` instructions: ${instrLines[0]}`);
589
- for (const instrLine of instrLines.slice(1))
590
- lines.push(` ${instrLine}`);
591
- }
592
- if (Array.isArray(step.completionCriteria) && step.completionCriteria.length > 0) {
593
- lines.push(" completion:");
594
- for (const criterion of step.completionCriteria) {
595
- lines.push(` - ${String(criterion)}`);
596
- }
597
- }
598
- }
599
- }
600
- if (payloads.length > 0) {
601
- if (lines.length > 0)
602
- lines.push("");
603
- lines.push(...payloads);
604
- }
605
- // REC-01 / REC-09: Append a type-specific directive so agents apply the
606
- // content rather than substituting training-data approximations.
607
- const assetType = typeof r.type === "string" ? r.type : null;
608
- const assetRef = typeof r.name === "string" && assetType ? `${assetType}:${r.name}` : null;
609
- // Show-loop detection: if the agent has shown this asset 3+ times without
610
- // writing anything, surface a warning so it stops cycling and acts.
611
- const showLoopCount = typeof r.showLoopWarning === "number" ? r.showLoopWarning : 0;
612
- if (showLoopCount >= 3) {
613
- lines.push("");
614
- lines.push(`WARNING: You have shown this asset ${showLoopCount} times without completing the task.`);
615
- lines.push("Stop re-reading — you have the information you need. Act on it now:");
616
- lines.push(" - Write your output file using the content above.");
617
- lines.push(` - If this asset does not contain what you need, run \`akm feedback '${assetRef ?? "<ref>"}' --negative\` and search for a different asset.`);
618
- }
619
- if (assetType === "skill" || assetType === "knowledge") {
620
- const activeRun = r.activeRun;
621
- if (activeRun) {
622
- // Active workflow: redirect agent to workflow commands instead of direct apply
623
- lines.unshift(` akm workflow complete '${activeRun.runId}'${activeRun.stepId ? ` --step '${activeRun.stepId}'` : ""}`);
624
- lines.unshift("Read this schema, then follow your workflow step's instructions to edit the workspace file. When done, mark the step complete:");
625
- lines.unshift(`WORKFLOW ACTIVE — schema shown as reference (run: ${activeRun.runId})`);
626
- lines.unshift("---");
627
- lines.unshift("");
628
- // Still show feedback line at the end but skip the APPLY directive
629
- lines.push("");
630
- lines.push(`Run \`akm feedback ${assetRef ? `'${assetRef}'` : "<ref>"} --positive\` if the step succeeds, or \`--negative\` if this schema did not help.`);
631
- }
632
- else {
633
- // No active workflow: show the APPLY directive. Branch on whether this
634
- // skill primarily teaches CLI commands (shell output) vs YAML schema.
635
- const preApplyLines = [...lines];
636
- lines.push("");
637
- lines.push("---");
638
- if (isCommandOutputSkill(preApplyLines)) {
639
- lines.push("APPLY (only if no workflow step is required for this task):");
640
- lines.push(" 1. Identify the output file from README.md (typically commands.txt).");
641
- lines.push(" 2. Write the exact command syntax from the code blocks above — replace every placeholder (`<name>`, `<value>`) with a real, concrete value from your task context. Do not write placeholder text.");
642
- lines.push(" 3. Each command should be on a single line (no backslash line continuation unless the verifier expects it).");
643
- lines.push(`Run \`akm feedback ${assetRef ? `'${assetRef}'` : "<ref>"} --positive\` after the task succeeds, or \`--negative\` if this reference did not contain the needed command syntax.`);
644
- }
645
- else {
646
- lines.push("APPLY (only if no workflow step is required for this task):");
647
- lines.push(" 1. Identify the target file from README.md — write or edit it. If the file does not yet exist, CREATE it with the full structure from this schema.");
648
- lines.push(" 2. Add/edit the fields shown above using the exact field names from this schema.");
649
- lines.push(" 3. COPY the exact YAML structure and field names from the code blocks above — do not substitute synonyms or invent nesting. Replace every placeholder value with a real, concrete value from your task context. Do not leave any field as null, empty, or a placeholder.");
650
- lines.push(`Run \`akm feedback ${assetRef ? `'${assetRef}'` : "<ref>"} --positive\` after the task succeeds, or \`--negative\` if the task fails after following this guidance.`);
651
- }
652
- }
653
- }
654
- else if (assetType === "workflow") {
655
- const workflowName = typeof r.name === "string" ? r.name : null;
656
- const workflowRef = workflowName ? `workflow:${workflowName}` : "<ref>";
657
- // Insert action directive BEFORE the workflow content by prepending to lines at the
658
- // separator position. We find where the header ends and insert after the first `---`.
659
- // Since lines already contain the full content at this point, we locate the insertion
660
- // index: right after the first `---` separator if present, otherwise after the header.
661
- const separatorIdx = lines.indexOf("---");
662
- const insertIdx = separatorIdx >= 0 ? separatorIdx + 1 : r.type || r.name ? 1 : 0;
663
- const actionDirective = [
664
- `ACTION REQUIRED: Do not execute steps manually from this output.`,
665
- `Run \`akm workflow next '${workflowRef}'\` to get your current step with exact instructions.`,
666
- "---",
667
- ];
668
- lines.splice(insertIdx, 0, "", ...actionDirective);
669
- lines.push("");
670
- lines.push("---");
671
- lines.push(`NEXT STEP: Run \`akm workflow next '${workflowRef}'\` to see the current workflow step.`);
672
- lines.push("Do not edit workspace files before completing each step with `akm workflow complete`.");
673
- }
674
- return lines.length > 0 ? lines.join("\n") : null;
675
- }
676
- /**
677
- * Detect whether a skill's rendered content primarily teaches CLI commands
678
- * rather than YAML schema. Used to select the right APPLY directive variant.
5
+ * Pure plain-text formatting helper functions shared across per-command
6
+ * text formatter modules.
679
7
  *
680
- * Heuristic: count code-block lines that start with known shell command
681
- * prefixes vs lines that look like YAML key-value pairs. If CLI lines
682
- * outnumber YAML lines (and there is at least one CLI line), treat the
683
- * skill as command-output.
684
- */
685
- function isCommandOutputSkill(lines) {
686
- const codeLines = lines.filter((l) => l.startsWith(" ") || l.startsWith("\t") || /^`/.test(l));
687
- const cliPattern = /^(az |kubectl |docker |git |helm |terraform |aws |gcloud )/;
688
- const yamlPattern = /^\s+\w+:/;
689
- const cliCount = codeLines.filter((l) => cliPattern.test(l.trim())).length;
690
- const yamlCount = codeLines.filter((l) => yamlPattern.test(l)).length;
691
- return cliCount > yamlCount && cliCount > 0;
692
- }
693
- export function formatWorkflowListPlain(result) {
694
- const runs = Array.isArray(result.runs) ? result.runs : [];
695
- if (runs.length === 0) {
696
- return "No workflow runs in the current working scope. Start one with `akm workflow next workflow:<name>` or author one with `akm workflow create <name>`.";
697
- }
698
- return runs
699
- .map((run) => {
700
- const id = typeof run.id === "string" ? run.id : "unknown";
701
- const ref = typeof run.workflowRef === "string" ? run.workflowRef : "workflow:unknown";
702
- const status = typeof run.status === "string" ? run.status : "unknown";
703
- const currentStep = typeof run.currentStepId === "string" ? ` (current: ${run.currentStepId})` : "";
704
- return `${id} ${ref} [${status}]${currentStep}`;
705
- })
706
- .join("\n");
707
- }
708
- export function formatWorkflowStatusPlain(result) {
709
- const run = typeof result.run === "object" && result.run !== null ? result.run : undefined;
710
- const workflow = typeof result.workflow === "object" && result.workflow !== null
711
- ? result.workflow
712
- : undefined;
713
- if (!run || !workflow)
714
- return null;
715
- const lines = [
716
- `workflow: ${String(workflow.ref ?? "workflow:unknown")}`,
717
- `run: ${String(run.id ?? "unknown")}`,
718
- `title: ${String(run.workflowTitle ?? workflow.title ?? "Workflow")}`,
719
- `status: ${String(run.status ?? "unknown")}`,
720
- ];
721
- if (run.currentStepId)
722
- lines.push(`currentStep: ${String(run.currentStepId)}`);
723
- const steps = Array.isArray(workflow.steps) ? workflow.steps : [];
724
- if (steps.length > 0) {
725
- lines.push("steps:");
726
- for (const step of steps) {
727
- const title = typeof step.title === "string" ? step.title : "Untitled step";
728
- const id = typeof step.id === "string" ? step.id : "unknown";
729
- const status = typeof step.status === "string" ? step.status : "unknown";
730
- lines.push(` - ${title} [${id}] (${status})`);
731
- if (typeof step.notes === "string" && step.notes.trim()) {
732
- lines.push(` notes: ${step.notes}`);
733
- }
734
- }
735
- }
736
- // `workflow status --units` (#22): the honest per-unit diagnostic surface —
737
- // failure_reason plus any journaled result/error text. Diagnostics only; the
738
- // deterministic step evidence above is unaffected.
739
- const units = Array.isArray(result.units) ? result.units : undefined;
740
- if (units) {
741
- lines.push("");
742
- lines.push(units.length > 0 ? "units:" : "units: (none journaled)");
743
- for (const unit of units) {
744
- const id = typeof unit.unitId === "string" ? unit.unitId : "unknown";
745
- const status = typeof unit.status === "string" ? unit.status : "unknown";
746
- const node = typeof unit.nodeId === "string" ? unit.nodeId : "";
747
- const attempts = typeof unit.attempts === "number" ? unit.attempts : undefined;
748
- const suffix = attempts !== undefined && attempts > 1 ? `, attempt ${attempts}` : "";
749
- lines.push(` - ${id} [${node}] (${status}${suffix})`);
750
- // Codex round-3 finding B: a `running` claim gone silent past the check-in
751
- // window — the driver likely died. Surface it (with the claim holder) so a
752
- // human can reclaim/re-run the unit, matching what `brief` reports.
753
- if (unit.stale === true) {
754
- const holder = typeof unit.claimHolder === "string" && unit.claimHolder.trim() ? ` claimed by ${unit.claimHolder}` : "";
755
- lines.push(` stale: claim went silent past the check-in window${holder} — its driver may have died`);
756
- }
757
- if (typeof unit.failureReason === "string" && unit.failureReason.trim()) {
758
- lines.push(` failure_reason: ${unit.failureReason}`);
759
- }
760
- if (typeof unit.diagnostic === "string" && unit.diagnostic.trim()) {
761
- const diagLines = unit.diagnostic.split("\n");
762
- lines.push(` diagnostic: ${diagLines[0]}`);
763
- for (const diagLine of diagLines.slice(1))
764
- lines.push(` ${diagLine}`);
765
- }
766
- }
767
- }
768
- // Review C2: the check-in `continue` directive must survive plain-text
769
- // rendering — JSON consumers saw `checkin` but the text path dropped it.
770
- const checkinLine = formatWorkflowCheckinLine(result);
771
- if (checkinLine) {
772
- lines.push("");
773
- lines.push(checkinLine);
774
- }
775
- return lines.join("\n");
776
- }
777
- /**
778
- * Render the stalled-run check-in directive (#506) when present on a
779
- * workflow-next/status result. Returns null when the run is healthy.
8
+ * This module is a re-export BARREL: the actual implementations live in
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.
15
+ *
16
+ * No registry imports — no circular dependencies.
780
17
  */
781
- function formatWorkflowCheckinLine(result) {
782
- const checkin = typeof result.checkin === "object" && result.checkin !== null
783
- ? result.checkin
784
- : undefined;
785
- if (!checkin || typeof checkin.directive !== "string" || !checkin.directive.trim())
786
- return null;
787
- return checkin.directive.trim();
788
- }
789
- export function formatWorkflowNextPlain(result) {
790
- const base = formatWorkflowStatusPlain(result);
791
- const step = typeof result.step === "object" && result.step !== null ? result.step : undefined;
792
- if (!step)
793
- return base;
794
- const lines = base ? [base, "", "next:"] : ["next:"];
795
- lines.push(` ${String(step.title ?? "Untitled step")} [${String(step.id ?? "unknown")}]`);
796
- if (typeof step.instructions === "string" && step.instructions.trim()) {
797
- const instrLines = step.instructions.trim().split("\n");
798
- lines.push(` instructions: ${instrLines[0]}`);
799
- for (const instrLine of instrLines.slice(1))
800
- lines.push(` ${instrLine}`);
801
- }
802
- const completion = Array.isArray(step.completionCriteria) ? step.completionCriteria : [];
803
- if (completion.length > 0) {
804
- lines.push(" completion:");
805
- for (const criterion of completion) {
806
- lines.push(` - ${String(criterion)}`);
807
- }
808
- }
809
- // T2-3: surface run-id as labeled field
810
- const run = typeof result.run === "object" && result.run !== null ? result.run : undefined;
811
- const runId = typeof run?.id === "string" ? run.id : null;
812
- const stepId = typeof step?.id === "string" ? step.id : null;
813
- if (runId) {
814
- lines.push("");
815
- lines.push(`runId: ${runId}`);
816
- }
817
- // T1-6: complete command
818
- if (runId && stepId) {
819
- lines.push("");
820
- lines.push("COMPLETE THIS STEP:");
821
- lines.push(` akm workflow complete '${runId}' --step '${stepId}'`);
822
- }
823
- else if (runId) {
824
- lines.push("");
825
- lines.push("COMPLETE THIS STEP:");
826
- lines.push(` akm workflow complete '${runId}' --step '<step-id>'`);
827
- }
828
- return lines.join("\n");
829
- }
830
- export function formatWorkflowRunPlain(result) {
831
- const run = typeof result.run === "object" && result.run !== null ? result.run : undefined;
832
- if (!run)
833
- return null;
834
- const lines = [`run: ${String(run.id ?? "unknown")}`, `status: ${String(run.status ?? "unknown")}`];
835
- const executed = Array.isArray(result.executed) ? result.executed : [];
836
- if (executed.length === 0) {
837
- lines.push("executed: (no steps — run was already done or blocked)");
838
- }
839
- else {
840
- lines.push("executed:");
841
- for (const step of executed) {
842
- const marker = step.ok === true ? "ok" : "FAILED";
843
- lines.push(` - ${String(step.stepId ?? "?")} [${marker}] units: ${String(step.unitCount ?? 0)}` +
844
- (Number(step.failedUnits ?? 0) > 0 ? ` (${String(step.failedUnits)} failed)` : ""));
845
- if (typeof step.summary === "string" && step.summary.trim()) {
846
- lines.push(` ${step.summary}`);
847
- }
848
- }
849
- }
850
- const gate = typeof result.gateRejection === "object" && result.gateRejection !== null
851
- ? result.gateRejection
852
- : undefined;
853
- if (gate) {
854
- lines.push(`gate rejected step ${String(gate.stepId ?? "?")}: ${String(gate.feedback ?? "")}`);
855
- const missing = Array.isArray(gate.missing) ? gate.missing : [];
856
- for (const item of missing)
857
- lines.push(` missing: ${String(item)}`);
858
- }
859
- if (result.done === true)
860
- lines.push("workflow completed.");
861
- return lines.join("\n");
862
- }
863
- export function formatWorkflowBriefPlain(result) {
864
- const run = typeof result.run === "object" && result.run !== null ? result.run : undefined;
865
- if (!run)
866
- return null;
867
- const lines = [];
868
- lines.push(`# Workflow brief: ${String(run.id ?? "unknown")}`);
869
- lines.push(`workflow: ${String(run.workflowRef ?? "?")} (${String(run.workflowTitle ?? "")})`);
870
- lines.push(`status: ${String(run.status ?? "?")}`);
871
- if (typeof result.message === "string")
872
- lines.push(result.message);
873
- const lease = typeof result.engineLease === "object" && result.engineLease !== null
874
- ? result.engineLease
875
- : undefined;
876
- if (lease) {
877
- const live = lease.live === true ? "LIVE" : "expired";
878
- lines.push(`engine lease: ${String(lease.holder ?? "?")} (until ${String(lease.until ?? "?")}) [${live}]`);
879
- }
880
- const warnings = Array.isArray(result.warnings) ? result.warnings : [];
881
- for (const w of warnings)
882
- lines.push(`! ${String(w)}`);
883
- if (result.done === true) {
884
- lines.push("");
885
- lines.push("This run is completed — no work remains.");
886
- return lines.join("\n");
887
- }
888
- const step = typeof result.step === "object" && result.step !== null ? result.step : undefined;
889
- if (!step) {
890
- return lines.join("\n");
891
- }
892
- const gate = typeof step.gate === "object" && step.gate !== null ? step.gate : undefined;
893
- lines.push("");
894
- lines.push(`## Active step: ${String(step.stepId ?? "?")} — ${String(step.title ?? "")} [${String(step.kind ?? "execute")}]`);
895
- if (gate) {
896
- const criteria = Array.isArray(gate.criteria) ? gate.criteria : [];
897
- lines.push(`gate: loop ${String(gate.currentLoop ?? 1)} of max ${String(gate.maxLoops ?? 1)}` +
898
- (criteria.length > 0 ? `; criteria: ${criteria.map(String).join("; ")}` : "; no completion criteria") +
899
- (gate.judgesArtifact === true ? " (artifact-judged)" : ""));
900
- }
901
- if (step.outputSchema !== undefined)
902
- lines.push("outputSchema: declared (see JSON output)");
903
- const feedback = typeof result.gateFeedback === "object" && result.gateFeedback !== null
904
- ? result.gateFeedback
905
- : undefined;
906
- if (feedback) {
907
- lines.push(`gate feedback (previous loop rejected): ${String(feedback.feedback ?? "")}`);
908
- const missing = Array.isArray(feedback.missing) ? feedback.missing : [];
909
- for (const m of missing)
910
- lines.push(` - missing: ${String(m)}`);
911
- }
912
- const route = typeof result.route === "object" && result.route !== null ? result.route : undefined;
913
- if (route) {
914
- lines.push("");
915
- lines.push(`## Route contract on ${String(route.input ?? "?")}`);
916
- const when = typeof route.when === "object" && route.when !== null ? route.when : {};
917
- for (const [value, target] of Object.entries(when))
918
- lines.push(` when "${value}" → ${String(target)}`);
919
- if (route.defaultStepId !== undefined)
920
- lines.push(` default → ${String(route.defaultStepId)}`);
921
- const decision = typeof route.decision === "object" && route.decision !== null
922
- ? route.decision
923
- : undefined;
924
- if (decision)
925
- lines.push(` decision NOW: value "${String(decision.value)}" → ${String(decision.selected)}`);
926
- else if (typeof route.decisionError === "string")
927
- lines.push(` decision error: ${route.decisionError}`);
928
- else
929
- lines.push(" decision: pending this step's output (evaluated after units complete)");
930
- }
931
- const workList = typeof result.workList === "object" && result.workList !== null
932
- ? result.workList
933
- : undefined;
934
- const units = workList && Array.isArray(workList.units) ? workList.units : [];
935
- if (workList?.error) {
936
- lines.push("");
937
- lines.push(`work-list error: ${String(workList.error)}`);
938
- }
939
- else if (units.length > 0) {
940
- lines.push("");
941
- lines.push(`## Units (${units.length})`);
942
- for (const u of units) {
943
- const model = u.model ? ` model=${String(u.model)}` : "";
944
- const journaled = typeof u.journaled === "object" && u.journaled !== null ? u.journaled : undefined;
945
- const jstatus = journaled ? ` [journaled: ${String(journaled.status)}]` : "";
946
- lines.push(`- ${String(u.unitId)} (runner=${String(u.runner)}${model})${jstatus}`);
947
- const env = Array.isArray(u.env) ? u.env : [];
948
- if (env.length > 0)
949
- lines.push(` env (names): ${env.map(String).join(", ")}`);
950
- if (u.outputSchema !== undefined)
951
- lines.push(" outputSchema: declared (see JSON output)");
952
- const resolved = typeof u.resolved === "object" && u.resolved !== null ? u.resolved : undefined;
953
- if (resolved && resolved.ok === false)
954
- lines.push(` RESOLUTION ERROR: ${String(resolved.error)}`);
955
- if (typeof u.report === "string")
956
- lines.push(` report: ${u.report}`);
957
- }
958
- }
959
- // Finding D: a non-dispatching step (route-only / empty / all-unresolvable)
960
- // advances via the `--settle` verb, surfaced so a driver can advance the spine.
961
- if (typeof result.settleCommand === "string") {
962
- lines.push("");
963
- lines.push("## Advance (no reportable units)");
964
- lines.push(`settle: ${result.settleCommand}`);
965
- }
966
- const guidance = typeof result.reportGuidance === "object" && result.reportGuidance !== null
967
- ? result.reportGuidance
968
- : undefined;
969
- if (guidance) {
970
- lines.push("");
971
- lines.push("## Reporting");
972
- if (typeof guidance.checkin === "string")
973
- lines.push(`heartbeat: ${guidance.checkin}`);
974
- if (typeof guidance.failure === "string")
975
- lines.push(`on failure: ${guidance.failure}`);
976
- }
977
- return lines.join("\n");
978
- }
979
- export function formatSearchPlain(r, detail) {
980
- const hits = r.hits ?? [];
981
- const registryHits = r.registryHits ?? [];
982
- const allHits = [...hits, ...registryHits];
983
- if (allHits.length === 0) {
984
- const warnings = Array.isArray(r.warnings) ? r.warnings : [];
985
- const hasSetupWarning = warnings.some((w) => String(w).toLowerCase().includes("no stash") || String(w).toLowerCase().includes("not configured"));
986
- if (hasSetupWarning) {
987
- return "No stash configured. Run `akm init` to create your working stash, then `akm index` to build the search index.";
988
- }
989
- const base = r.tip ? String(r.tip) : "No matches found.";
990
- 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`;
991
- }
992
- const lines = [];
993
- for (const hit of allHits) {
994
- const type = hit.type ?? "unknown";
995
- const name = hit.name ?? "unnamed";
996
- const score = hit.score != null ? ` (score: ${hit.score})` : "";
997
- const desc = hit.description ? ` ${hit.description}` : "";
998
- lines.push(`${type}: ${name}${score}`);
999
- if (desc)
1000
- lines.push(desc);
1001
- if (hit.id)
1002
- lines.push(` id: ${String(hit.id)}`);
1003
- if (hit.ref)
1004
- lines.push(` ref: ${String(hit.ref)}`);
1005
- if (hit.origin !== undefined)
1006
- lines.push(` origin: ${String(hit.origin)}`);
1007
- if (Array.isArray(hit.keys) && hit.keys.length > 0)
1008
- lines.push(` keys: ${hit.keys.join(", ")}`);
1009
- if (hit.size)
1010
- lines.push(` size: ${String(hit.size)}`);
1011
- if (hit.action)
1012
- lines.push(` action: ${String(hit.action)}`);
1013
- if (hit.run)
1014
- lines.push(` run: ${String(hit.run)}`);
1015
- if (Array.isArray(hit.tags) && hit.tags.length > 0)
1016
- lines.push(` tags: ${hit.tags.join(", ")}`);
1017
- // Optional v1 spec §4.2 quality marker (e.g. "curated" / "proposed").
1018
- if (typeof hit.quality === "string" && hit.quality)
1019
- lines.push(` quality: ${hit.quality}`);
1020
- // Surface optional hit-level warnings (v1 spec §4.2). The legacy
1021
- // `curated` boolean was removed in v1.
1022
- if (Array.isArray(hit.warnings) && hit.warnings.length > 0) {
1023
- lines.push(` warnings: ${hit.warnings.join("; ")}`);
1024
- }
1025
- const graph = typeof hit.graph === "object" && hit.graph !== null ? hit.graph : undefined;
1026
- if (graph) {
1027
- const entities = Array.isArray(graph.entities) ? graph.entities : [];
1028
- if (entities.length > 0) {
1029
- const matched = entities
1030
- .filter((entity) => String(entity.kind ?? "") === "matched")
1031
- .map((entity) => String(entity.name ?? "?"));
1032
- const neighbors = entities
1033
- .filter((entity) => String(entity.kind ?? "") !== "matched")
1034
- .map((entity) => String(entity.name ?? "?"));
1035
- lines.push(` graph: ${[
1036
- matched.length > 0 ? `query match=${matched.join(", ")}` : undefined,
1037
- neighbors.length > 0 ? `neighbors=${neighbors.join(", ")}` : undefined,
1038
- ]
1039
- .filter(Boolean)
1040
- .join("; ")}`);
1041
- }
1042
- }
1043
- if (detail === "full") {
1044
- if (hit.path)
1045
- lines.push(` path: ${String(hit.path)}`);
1046
- if (hit.editable != null)
1047
- lines.push(` editable: ${String(hit.editable)}`);
1048
- if (hit.editHint)
1049
- lines.push(` editHint: ${String(hit.editHint)}`);
1050
- const whyMatched = hit.whyMatched;
1051
- if (whyMatched && whyMatched.length > 0) {
1052
- lines.push(` whyMatched: ${whyMatched.join(", ")}`);
1053
- }
1054
- }
1055
- lines.push(""); // blank line between hits
1056
- }
1057
- if (detail === "full" && r.timing) {
1058
- const timing = r.timing;
1059
- const parts = [];
1060
- if (timing.totalMs != null)
1061
- parts.push(`total: ${timing.totalMs}ms`);
1062
- if (timing.rankMs != null)
1063
- parts.push(`rank: ${timing.rankMs}ms`);
1064
- if (timing.embedMs != null)
1065
- parts.push(`embed: ${timing.embedMs}ms`);
1066
- if (parts.length > 0)
1067
- lines.push(`timing: ${parts.join(", ")}`);
1068
- }
1069
- // REC-02: When stash hits exist, tell the agent the next required step so it
1070
- // doesn't skip `akm show` and write from training memory instead.
1071
- if (hits.length >= 1) {
1072
- // Prefer skill/command/agent type hits for the "Next:" ref — knowledge docs are
1073
- // supplementary context, not the authoritative schema agents should load first.
1074
- const preferredHit = hits.find((h) => h.type === "skill" || h.type === "command" || h.type === "agent") ?? hits[0];
1075
- const topRef = typeof preferredHit.ref === "string" ? preferredHit.ref : null;
1076
- const hasWorkflowHit = hits.some((h) => h.type === "workflow");
1077
- if (topRef) {
1078
- if (hasWorkflowHit) {
1079
- const workflowRef = hits.find((h) => h.type === "workflow");
1080
- const wfRef = workflowRef && typeof workflowRef.ref === "string" ? workflowRef.ref : topRef;
1081
- lines.push(`Next: akm show '${topRef}' | To start a workflow: akm workflow next '${wfRef}'`);
1082
- lines.push("After running workflow next: follow each step and run `akm workflow complete <run-id> --step <step-id>` when done.");
1083
- }
1084
- else {
1085
- lines.push(`Next: akm show '${topRef}'`);
1086
- lines.push("After reading the asset: check whether a workflow applies before editing — if so, use `akm workflow next` instead.");
1087
- }
1088
- }
1089
- }
1090
- return lines.join("\n").trimEnd();
1091
- }
1092
- export function formatWikiListPlain(r) {
1093
- const wikis = Array.isArray(r.wikis) ? r.wikis : [];
1094
- if (wikis.length === 0)
1095
- return "No wikis. Create one with `akm wiki create <name>` or register one with `akm wiki register <name> <path-or-repo>`.";
1096
- const lines = ["NAME\tPAGES\tRAWS\tLAST-MODIFIED"];
1097
- for (const w of wikis) {
1098
- const name = typeof w.name === "string" ? w.name : "?";
1099
- const pages = typeof w.pages === "number" ? w.pages : 0;
1100
- const raws = typeof w.raws === "number" ? w.raws : 0;
1101
- const modified = typeof w.lastModified === "string" ? w.lastModified : "-";
1102
- lines.push(`${name}\t${pages}\t${raws}\t${modified}`);
1103
- }
1104
- return lines.join("\n");
1105
- }
1106
- export function formatWikiShowPlain(r) {
1107
- const lines = [];
1108
- if (r.name)
1109
- lines.push(`# wiki: ${String(r.name)}`);
1110
- if (r.path)
1111
- lines.push(`path: ${String(r.path)}`);
1112
- if (r.description)
1113
- lines.push(`description: ${String(r.description)}`);
1114
- if (typeof r.pages === "number")
1115
- lines.push(`pages: ${r.pages}`);
1116
- if (typeof r.raws === "number")
1117
- lines.push(`raws: ${r.raws}`);
1118
- if (r.lastModified)
1119
- lines.push(`lastModified: ${String(r.lastModified)}`);
1120
- const recentLog = Array.isArray(r.recentLog) ? r.recentLog : [];
1121
- if (recentLog.length > 0) {
1122
- lines.push("", "recent log:");
1123
- for (const entry of recentLog) {
1124
- lines.push(entry);
1125
- lines.push("");
1126
- }
1127
- }
1128
- return lines.join("\n").trimEnd();
1129
- }
1130
- export function formatWikiCreatePlain(r) {
1131
- const created = Array.isArray(r.created) ? r.created : [];
1132
- const skipped = Array.isArray(r.skipped) ? r.skipped : [];
1133
- const lines = [`Created wiki ${String(r.ref ?? r.name)} at ${String(r.path ?? "?")}`];
1134
- if (created.length > 0)
1135
- lines.push(` created: ${created.length} file(s)`);
1136
- if (skipped.length > 0)
1137
- lines.push(` skipped: ${skipped.length} existing file(s)`);
1138
- return lines.join("\n");
1139
- }
1140
- export function formatWikiRemovePlain(r) {
1141
- const preserved = r.preservedRaw === true;
1142
- const removed = Array.isArray(r.removed) ? r.removed.length : 0;
1143
- const base = `Removed wiki ${String(r.name ?? "?")} (${removed} path(s))`;
1144
- return preserved ? `${base}; raw/ preserved at ${String(r.rawPath ?? "raw/")}` : base;
1145
- }
1146
- export function formatWikiPagesPlain(r) {
1147
- const pages = Array.isArray(r.pages) ? r.pages : [];
1148
- if (pages.length === 0)
1149
- return `No pages in wiki:${String(r.wiki ?? "?")}.`;
1150
- const lines = [];
1151
- for (const p of pages) {
1152
- const ref = String(p.ref ?? "?");
1153
- const kind = typeof p.pageKind === "string" ? ` [${p.pageKind}]` : "";
1154
- const desc = typeof p.description === "string" && p.description ? ` — ${p.description}` : "";
1155
- lines.push(`${ref}${kind}${desc}`);
1156
- }
1157
- return lines.join("\n");
1158
- }
1159
- export function formatWikiStashPlain(r) {
1160
- const slug = String(r.slug ?? "?");
1161
- const pathValue = String(r.path ?? "?");
1162
- return `Stashed ${slug} → ${pathValue}`;
1163
- }
1164
- export function formatWikiLintPlain(r) {
1165
- const findings = Array.isArray(r.findings) ? r.findings : [];
1166
- const pagesScanned = typeof r.pagesScanned === "number" ? r.pagesScanned : 0;
1167
- const rawsScanned = typeof r.rawsScanned === "number" ? r.rawsScanned : 0;
1168
- const header = `${findings.length} finding(s) in wiki:${String(r.wiki ?? "?")} (${pagesScanned} page(s), ${rawsScanned} raw(s))`;
1169
- if (findings.length === 0)
1170
- return `${header} — clean.`;
1171
- const lines = [header];
1172
- for (const f of findings) {
1173
- const kind = String(f.kind ?? "?");
1174
- const message = String(f.message ?? "");
1175
- lines.push(`- [${kind}] ${message}`);
1176
- }
1177
- return lines.join("\n");
1178
- }
1179
- export function formatWikiIngestPlain(r) {
1180
- if (typeof r.workflow === "string")
1181
- return r.workflow;
1182
- return JSON.stringify(r, null, 2);
1183
- }
1184
- export function formatCuratePlain(r, detail) {
1185
- const query = typeof r.query === "string" ? r.query : "";
1186
- const summary = typeof r.summary === "string" ? r.summary : "";
1187
- const items = Array.isArray(r.items) ? r.items : [];
1188
- const lines = [`Curated results for "${query}"`];
1189
- if (summary)
1190
- lines.push(summary);
1191
- if (items.length === 0) {
1192
- if (r.tip)
1193
- lines.push(String(r.tip));
1194
- return lines.join("\n");
1195
- }
1196
- for (const item of items) {
1197
- const type = typeof item.type === "string" ? item.type : "unknown";
1198
- const name = typeof item.name === "string" ? item.name : "unnamed";
1199
- lines.push("");
1200
- lines.push(`[${type}] ${name}`);
1201
- if (item.description)
1202
- lines.push(` ${String(item.description)}`);
1203
- if (item.preview)
1204
- lines.push(` preview: ${String(item.preview)}`);
1205
- if (item.ref)
1206
- lines.push(` ref: ${String(item.ref)}`);
1207
- if (item.id)
1208
- lines.push(` id: ${String(item.id)}`);
1209
- if (Array.isArray(item.keys) && item.keys.length > 0) {
1210
- lines.push(` keys: ${item.keys.join(", ")}`);
1211
- }
1212
- if (Array.isArray(item.parameters) && item.parameters.length > 0) {
1213
- lines.push(` parameters: ${item.parameters.join(", ")}`);
1214
- }
1215
- if (item.run)
1216
- lines.push(` run: ${String(item.run)}`);
1217
- if (item.followUp)
1218
- lines.push(` show: ${String(item.followUp)}`);
1219
- if (Array.isArray(item.supportRefs) && item.supportRefs.length > 0) {
1220
- for (const support of item.supportRefs) {
1221
- if (!support.ref)
1222
- continue;
1223
- const label = typeof support.type === "string" ? `[${support.type}] ` : "";
1224
- const why = typeof support.reason === "string" ? ` — ${support.reason}` : "";
1225
- lines.push(` support: ${label}${String(support.ref)}${why}`);
1226
- }
1227
- }
1228
- if (detail !== "brief" && item.reason)
1229
- lines.push(` why: ${String(item.reason)}`);
1230
- }
1231
- const warnings = Array.isArray(r.warnings) ? r.warnings : [];
1232
- if (warnings.length > 0) {
1233
- lines.push("");
1234
- lines.push("Warnings:");
1235
- for (const warning of warnings) {
1236
- lines.push(`- ${String(warning)}`);
1237
- }
1238
- }
1239
- lines.push("");
1240
- lines.push("Next steps:");
1241
- lines.push(" 1. Run `akm show <ref>` for the best result above to read the full schema.");
1242
- lines.push(" 2. Edit the workspace file using the schema field names and your task-specific values.");
1243
- lines.push(" 3. Run `akm feedback <ref> --positive` when the task succeeds.");
1244
- lines.push("To search further: akm search '<query>'");
1245
- return lines.join("\n");
1246
- }
1247
- export function formatInitPlain(r) {
1248
- let out = `Stash initialized at ${r.stashDir ?? "unknown"}`;
1249
- // When --dir scaffolded a secondary stash but the default was deliberately
1250
- // left untouched, tell the user instead of silently repointing their default.
1251
- if (r.defaultStashUpdated === false && typeof r.previousStashDir === "string" && r.previousStashDir) {
1252
- out += `\nYour default stash is unchanged (${r.previousStashDir}). Re-run with --set-default to make ${r.stashDir} the default.`;
1253
- }
1254
- else if (r.configPath) {
1255
- out += `\nConfig saved to ${r.configPath}`;
1256
- }
1257
- return out;
1258
- }
1259
- export function formatIndexPlain(r) {
1260
- const indexResult = r;
1261
- let out = `Indexed ${indexResult.totalEntries ?? 0} entries from ${indexResult.directoriesScanned ?? 0} directories (mode: ${indexResult.mode ?? "unknown"})`;
1262
- const warnings = indexResult.warnings;
1263
- if (Array.isArray(warnings) && warnings.length > 0) {
1264
- out += `\nWarnings (${warnings.length}):`;
1265
- for (const message of warnings)
1266
- out += `\n - ${String(message)}`;
1267
- }
1268
- const verification = indexResult.verification;
1269
- if (verification?.ok === false && verification.message) {
1270
- out += `\nVerification: ${String(verification.message)}`;
1271
- }
1272
- const timing = indexResult.timing;
1273
- if (timing) {
1274
- out +=
1275
- `\nTiming: total ${timing.totalMs}ms` +
1276
- `, preflight ${timing.preflightMs}ms` +
1277
- `, walk ${timing.walkMs}ms` +
1278
- `, llm ${timing.llmMs}ms` +
1279
- `, embeddings ${timing.embedMs}ms` +
1280
- `, fts ${timing.ftsMs}ms` +
1281
- `, finalize ${timing.finalizeMs}ms` +
1282
- `, clean ${timing.cleanMs}ms` +
1283
- `, end-to-end ${timing.endToEndMs}ms`;
1284
- }
1285
- return out;
1286
- }
1287
- export function formatListPlain(r) {
1288
- const sources = Array.isArray(r.sources) ? r.sources : [];
1289
- if (sources.length === 0)
1290
- return "No sources configured. Use `akm add` to add a source.";
1291
- const lines = [];
1292
- for (const src of sources) {
1293
- const kind = typeof src.kind === "string" ? src.kind : "unknown";
1294
- const name = typeof src.name === "string" ? src.name : "unnamed";
1295
- const ver = typeof src.version === "string" ? ` v${src.version}` : "";
1296
- const prov = typeof src.provider === "string" ? ` (${src.provider})` : "";
1297
- const flags = [];
1298
- if (typeof src.wiki === "string")
1299
- flags.push(`wiki:${src.wiki}`);
1300
- if (src.updatable === true)
1301
- flags.push("updatable");
1302
- if (src.writable === true)
1303
- flags.push("writable");
1304
- const flagText = flags.length > 0 ? ` [${flags.join(", ")}]` : "";
1305
- lines.push(`[${kind}] ${name}${ver}${prov}${flagText}`);
1306
- }
1307
- lines.push("");
1308
- lines.push("To search: akm search '<query>' | To view an asset: akm show <ref>");
1309
- return lines.join("\n");
1310
- }
1311
- export function formatAddPlain(r) {
1312
- const index = r.index;
1313
- const scanned = index?.directoriesScanned ?? 0;
1314
- const total = index?.totalEntries ?? 0;
1315
- const lines = [`Installed ${r.ref} (${scanned} directories scanned, ${total} total assets indexed)`];
1316
- const warnings = index?.warnings;
1317
- if (Array.isArray(warnings) && warnings.length > 0) {
1318
- lines.push(`Warnings (${warnings.length}):`);
1319
- for (const message of warnings)
1320
- lines.push(` - ${String(message)}`);
1321
- }
1322
- return lines.join("\n");
1323
- }
1324
- export function formatRemovePlain(r) {
1325
- const target = r.target ?? r.ref ?? "";
1326
- const ok = r.ok !== false ? "OK" : "FAILED";
1327
- return `remove: ${target} ${ok}`;
1328
- }
1329
- export function formatUpdatePlain(r) {
1330
- const processed = r.processed;
1331
- if (!processed?.length)
1332
- return `update: nothing to update`;
1333
- const lines = processed.map((item) => {
1334
- const changed = item.changed;
1335
- const installed = item.installed;
1336
- const previous = item.previous;
1337
- if (changed?.any) {
1338
- const prev = previous?.resolvedVersion ?? "unknown";
1339
- const next = installed?.resolvedVersion ?? "unknown";
1340
- return `update: ${item.id} v${prev} → v${next}`;
1341
- }
1342
- return `update: ${item.id} (unchanged)`;
1343
- });
1344
- return lines.join("\n");
1345
- }
1346
- export function formatUpgradePlain(r) {
1347
- if (r.upgraded === true) {
1348
- return `akm upgraded: v${r.currentVersion} → v${r.newVersion}`;
1349
- }
1350
- if (r.updateAvailable === true) {
1351
- return `akm v${r.currentVersion} → v${r.latestVersion} available (run 'akm upgrade' to install)`;
1352
- }
1353
- if (r.updateAvailable === false && r.latestVersion) {
1354
- return `akm v${r.currentVersion} is already the latest version`;
1355
- }
1356
- if (r.message)
1357
- return String(r.message);
1358
- return null;
1359
- }
1360
- export function formatClonePlain(r) {
1361
- const dst = r.destination?.path ?? "unknown";
1362
- const remote = r.remoteFetched ? " (fetched from remote)" : "";
1363
- const over = r.overwritten ? " (overwritten)" : "";
1364
- return `Cloned${remote} → ${dst}${over}`;
1365
- }
1366
- export function formatWorkflowCreatePlain(r) {
1367
- if (r.ref && r.path) {
1368
- return `Created ${String(r.ref)} at ${String(r.path)}`;
1369
- }
1370
- return null;
1371
- }
1372
- export function formatWorkflowResumePlain(r) {
1373
- return formatWorkflowStatusPlain(r) ?? `Resumed workflow run ${String(r.id ?? r.runId ?? "?")}`;
1374
- }
1375
- function formatRelatedLabel(hit) {
1376
- const ref = typeof hit.ref === "string" ? hit.ref : undefined;
1377
- if (ref)
1378
- return ref;
1379
- const pathValue = typeof hit.path === "string" ? hit.path : "?";
1380
- return pathValue.split("/").pop() ?? pathValue;
1381
- }
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 { formatGateDecisionSummary, formatProposalAcceptPlain, formatProposalDiffPlain, formatProposalDrainPlain, formatProposalListPlain, formatProposalProducerPlain, formatProposalRejectPlain, formatProposalShowPlain, } from "./proposal-format.js";
20
+ export { formatShowPlain } from "./show-format.js";
21
+ export { formatWorkflowBriefPlain, formatWorkflowCompleteRejectedPlain, formatWorkflowCreatePlain, formatWorkflowListPlain, formatWorkflowNextPlain, formatWorkflowResumePlain, formatWorkflowRunPlain, formatWorkflowStatusPlain, } from "./workflow-format.js";