akm-cli 0.8.6 → 0.8.14

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 (324) hide show
  1. package/CHANGELOG.md +442 -0
  2. package/dist/assets/help/help-proposals.md +1 -2
  3. package/dist/assets/hints/cli-hints-full.md +34 -19
  4. package/dist/assets/hints/cli-hints-short.md +1 -1
  5. package/dist/assets/profiles/catchup.json +13 -0
  6. package/dist/assets/profiles/consolidate.json +13 -0
  7. package/dist/assets/profiles/frequent.json +13 -0
  8. package/dist/assets/tasks/core/backup.yml +4 -0
  9. package/dist/assets/tasks/core/extract.yml +4 -0
  10. package/dist/assets/tasks/core/improve.yml +4 -0
  11. package/dist/assets/tasks/core/index-refresh.yml +4 -0
  12. package/dist/assets/tasks/core/sync.yml +4 -0
  13. package/dist/assets/tasks/core/update-stashes.yml +4 -0
  14. package/dist/assets/tasks/core/version-check.yml +4 -0
  15. package/dist/assets/templates/html/default.html +78 -0
  16. package/dist/assets/templates/html/health.html +560 -0
  17. package/dist/assets/templates/html/vendor/echarts.min.js +45 -0
  18. package/dist/cli/config-migrate.js +6 -6
  19. package/dist/cli/config-validate.js +4 -4
  20. package/dist/cli/confirm.js +3 -3
  21. package/dist/cli/parse-args.js +1 -1
  22. package/dist/cli/shared.js +72 -19
  23. package/dist/cli-node.mjs +26 -0
  24. package/dist/cli.js +206 -3866
  25. package/dist/commands/{agent-dispatch.js → agent/agent-dispatch.js} +6 -6
  26. package/dist/commands/{agent-support.js → agent/agent-support.js} +2 -2
  27. package/dist/commands/agent/contribute-cli.js +200 -0
  28. package/dist/commands/completions.js +1 -1
  29. package/dist/commands/config-cli.js +230 -3
  30. package/dist/commands/db-cli.js +2 -2
  31. package/dist/commands/env/env-cli.js +529 -0
  32. package/dist/commands/env/env.js +410 -0
  33. package/dist/commands/env/secret-cli.js +259 -0
  34. package/dist/commands/{secret.js → env/secret.js} +6 -47
  35. package/dist/commands/events.js +4 -4
  36. package/dist/commands/feedback-cli.js +18 -34
  37. package/dist/commands/graph/graph-cli.js +132 -0
  38. package/dist/commands/{graph.js → graph/graph.js} +22 -16
  39. package/dist/commands/health/checks.js +279 -0
  40. package/dist/commands/health/html-report.js +448 -0
  41. package/dist/commands/health.js +189 -266
  42. package/dist/commands/{consolidate.js → improve/consolidate.js} +63 -38
  43. package/dist/commands/{distill-promotion-policy.js → improve/distill-promotion-policy.js} +3 -3
  44. package/dist/commands/{distill.js → improve/distill.js} +39 -18
  45. package/dist/commands/{eval-cases.js → improve/eval-cases.js} +1 -1
  46. package/dist/commands/{extract-cli.js → improve/extract-cli.js} +4 -4
  47. package/dist/commands/{extract-prompt.js → improve/extract-prompt.js} +2 -2
  48. package/dist/commands/{extract.js → improve/extract.js} +221 -26
  49. package/dist/commands/{improve-auto-accept.js → improve/improve-auto-accept.js} +30 -4
  50. package/dist/commands/{improve-cli.js → improve/improve-cli.js} +44 -22
  51. package/dist/commands/{improve-profiles.js → improve/improve-profiles.js} +13 -7
  52. package/dist/commands/{improve-result-file.js → improve/improve-result-file.js} +1 -1
  53. package/dist/commands/{improve.js → improve/improve.js} +672 -292
  54. package/dist/{core → commands/improve/memory}/memory-belief.js +2 -2
  55. package/dist/{core → commands/improve/memory}/memory-contradiction-detect.js +5 -5
  56. package/dist/{core → commands/improve/memory}/memory-improve.js +4 -4
  57. package/dist/commands/improve/reflect-noise.js +0 -0
  58. package/dist/commands/{reflect.js → improve/reflect.js} +58 -28
  59. package/dist/commands/improve/session-asset.js +248 -0
  60. package/dist/commands/lint/agent-linter.js +1 -1
  61. package/dist/commands/lint/base-linter.js +55 -37
  62. package/dist/commands/lint/command-linter.js +1 -1
  63. package/dist/commands/lint/default-linter.js +1 -1
  64. package/dist/commands/lint/env-key-rules.js +1 -1
  65. package/dist/commands/lint/index.js +19 -25
  66. package/dist/commands/lint/knowledge-linter.js +1 -1
  67. package/dist/commands/lint/memory-linter.js +1 -1
  68. package/dist/commands/lint/registry.js +8 -8
  69. package/dist/commands/lint/skill-linter.js +1 -1
  70. package/dist/commands/lint/task-linter.js +1 -1
  71. package/dist/commands/lint/workflow-linter.js +1 -1
  72. package/dist/commands/lint.js +1 -1
  73. package/dist/commands/observability-cli.js +244 -0
  74. package/dist/commands/proposal/drain-policies.js +3 -3
  75. package/dist/commands/proposal/drain.js +87 -15
  76. package/dist/commands/proposal/proposal-cli.js +490 -0
  77. package/dist/commands/{proposal.js → proposal/proposal.js} +17 -6
  78. package/dist/commands/{propose.js → proposal/propose.js} +11 -11
  79. package/dist/{core → commands/proposal/validators}/proposal-quality-validators.js +8 -3
  80. package/dist/{core → commands/proposal/validators}/proposal-validators.js +5 -5
  81. package/dist/{core → commands/proposal/validators}/proposals.js +374 -345
  82. package/dist/commands/{curate.js → read/curate.js} +7 -7
  83. package/dist/commands/{knowledge.js → read/knowledge.js} +22 -9
  84. package/dist/commands/{registry-search.js → read/registry-search.js} +5 -5
  85. package/dist/commands/{remember-cli.js → read/remember-cli.js} +15 -7
  86. package/dist/commands/read/search-cli.js +207 -0
  87. package/dist/commands/{search.js → read/search.js} +22 -27
  88. package/dist/commands/{show.js → read/show.js} +31 -45
  89. package/dist/commands/registry-cli.js +8 -8
  90. package/dist/commands/remember.js +14 -10
  91. package/dist/commands/sources/add-cli.js +293 -0
  92. package/dist/commands/{history.js → sources/history.js} +27 -25
  93. package/dist/commands/{info.js → sources/info.js} +6 -6
  94. package/dist/commands/{init.js → sources/init.js} +6 -6
  95. package/dist/commands/{installed-stashes.js → sources/installed-stashes.js} +12 -12
  96. package/dist/commands/{migration-help.js → sources/migration-help.js} +3 -2
  97. package/dist/commands/{schema-repair.js → sources/schema-repair.js} +8 -8
  98. package/dist/commands/{self-update.js → sources/self-update.js} +10 -9
  99. package/dist/commands/{source-add.js → sources/source-add.js} +10 -10
  100. package/dist/commands/{source-clone.js → sources/source-clone.js} +7 -7
  101. package/dist/commands/{source-manage.js → sources/source-manage.js} +4 -4
  102. package/dist/commands/sources/sources-cli.js +305 -0
  103. package/dist/commands/sources/stash-cli.js +219 -0
  104. package/dist/commands/{stash-skeleton.js → sources/stash-skeleton.js} +2 -1
  105. package/dist/commands/tasks/default-tasks.js +173 -0
  106. package/dist/commands/tasks/tasks-cli.js +210 -0
  107. package/dist/commands/{tasks.js → tasks/tasks.js} +14 -14
  108. package/dist/commands/wiki-cli.js +307 -0
  109. package/dist/commands/workflow-cli.js +329 -0
  110. package/dist/core/action-contributors.js +1 -1
  111. package/dist/core/assert.js +40 -0
  112. package/dist/core/asset/asset-create.js +54 -0
  113. package/dist/core/{asset-ref.js → asset/asset-ref.js} +21 -4
  114. package/dist/core/{asset-registry.js → asset/asset-registry.js} +3 -3
  115. package/dist/core/{asset-spec.js → asset/asset-spec.js} +17 -31
  116. package/dist/core/{markdown.js → asset/markdown.js} +1 -1
  117. package/dist/core/{stash-meta.js → asset/stash-meta.js} +1 -1
  118. package/dist/core/best-effort.js +64 -0
  119. package/dist/core/common.js +32 -18
  120. package/dist/core/{config-io.js → config/config-io.js} +29 -19
  121. package/dist/core/{config-migration.js → config/config-migration.js} +11 -9
  122. package/dist/core/{config-schema.js → config/config-schema.js} +50 -7
  123. package/dist/core/config/config-types.js +16 -0
  124. package/dist/core/{config-walker.js → config/config-walker.js} +2 -2
  125. package/dist/core/{config.js → config/config.js} +10 -8
  126. package/dist/core/env-secret-ref.js +90 -0
  127. package/dist/core/errors.js +13 -3
  128. package/dist/core/events.js +27 -4
  129. package/dist/core/file-lock.js +1 -1
  130. package/dist/core/improve-types.js +48 -0
  131. package/dist/core/lesson-lint.js +2 -2
  132. package/dist/core/logs-db.js +304 -0
  133. package/dist/core/paths.js +2 -2
  134. package/dist/core/ripgrep/install.js +2 -2
  135. package/dist/core/ripgrep/resolve.js +2 -2
  136. package/dist/core/state-db.js +195 -60
  137. package/dist/core/text-truncation.js +148 -0
  138. package/dist/core/time.js +1 -1
  139. package/dist/core/write-source.js +98 -85
  140. package/dist/indexer/{db-backup.js → db/db-backup.js} +9 -24
  141. package/dist/indexer/{db.js → db/db.js} +128 -118
  142. package/dist/indexer/{graph-db.js → db/graph-db.js} +9 -4
  143. package/dist/indexer/{llm-cache.js → db/llm-cache.js} +15 -12
  144. package/dist/indexer/ensure-index.js +4 -4
  145. package/dist/indexer/{graph-boost.js → graph/graph-boost.js} +1 -1
  146. package/dist/indexer/{graph-extraction.js → graph/graph-extraction.js} +55 -13
  147. package/dist/indexer/indexer.js +37 -30
  148. package/dist/indexer/init.js +54 -0
  149. package/dist/indexer/manifest.js +10 -10
  150. package/dist/indexer/{memory-inference.js → passes/memory-inference.js} +141 -33
  151. package/dist/indexer/{metadata-contributors.js → passes/metadata-contributors.js} +10 -8
  152. package/dist/indexer/{metadata.js → passes/metadata.js} +15 -19
  153. package/dist/indexer/{staleness-detect.js → passes/staleness-detect.js} +53 -12
  154. package/dist/indexer/{db-search.js → search/db-search.js} +28 -16
  155. package/dist/indexer/{ranking-contributors.js → search/ranking-contributors.js} +1 -1
  156. package/dist/indexer/{ranking.js → search/ranking.js} +2 -2
  157. package/dist/indexer/{search-hit-enrichers.js → search/search-hit-enrichers.js} +3 -3
  158. package/dist/indexer/{search-source.js → search/search-source.js} +8 -8
  159. package/dist/indexer/{semantic-status.js → search/semantic-status.js} +3 -3
  160. package/dist/indexer/usage/unmigrated-vaults-guard.js +94 -0
  161. package/dist/indexer/{usage-events.js → usage/usage-events.js} +32 -0
  162. package/dist/indexer/{file-context.js → walk/file-context.js} +10 -15
  163. package/dist/indexer/{matchers.js → walk/matchers.js} +13 -9
  164. package/dist/indexer/{path-resolver.js → walk/path-resolver.js} +6 -6
  165. package/dist/indexer/{project-context.js → walk/project-context.js} +1 -1
  166. package/dist/indexer/{walker.js → walk/walker.js} +4 -3
  167. package/dist/integrations/agent/builder-shared.js +39 -0
  168. package/dist/integrations/agent/builders.js +14 -81
  169. package/dist/integrations/agent/config.js +6 -4
  170. package/dist/integrations/agent/detect.js +1 -1
  171. package/dist/integrations/agent/index.js +23 -8
  172. package/dist/integrations/agent/prompts.js +2 -3
  173. package/dist/integrations/agent/runner.js +22 -3
  174. package/dist/integrations/agent/spawn.js +9 -10
  175. package/dist/integrations/harnesses/claude/agent-builder.js +48 -0
  176. package/dist/integrations/harnesses/claude/config-import.js +70 -0
  177. package/dist/integrations/harnesses/claude/index.js +64 -0
  178. package/dist/integrations/{session-logs/providers/claude-code.js → harnesses/claude/session-log.js} +32 -5
  179. package/dist/integrations/harnesses/index.js +144 -0
  180. package/dist/integrations/harnesses/opencode/agent-builder.js +43 -0
  181. package/dist/integrations/harnesses/opencode/config-import.js +82 -0
  182. package/dist/integrations/harnesses/opencode/index.js +59 -0
  183. package/dist/integrations/{session-logs/providers/opencode.js → harnesses/opencode/session-log.js} +1 -1
  184. package/dist/integrations/harnesses/opencode-sdk/index.js +49 -0
  185. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +234 -0
  186. package/dist/integrations/harnesses/types.js +43 -0
  187. package/dist/integrations/lockfile.js +7 -16
  188. package/dist/integrations/session-logs/index.js +82 -9
  189. package/dist/llm/call-ai.js +4 -4
  190. package/dist/llm/client.js +146 -6
  191. package/dist/llm/embedder.js +6 -6
  192. package/dist/llm/embedders/local.js +9 -22
  193. package/dist/llm/embedders/remote.js +2 -2
  194. package/dist/llm/embedders/types.js +1 -1
  195. package/dist/llm/graph-extract.js +31 -12
  196. package/dist/llm/index-passes.js +1 -1
  197. package/dist/llm/memory-infer.js +12 -5
  198. package/dist/llm/metadata-enhance.js +2 -2
  199. package/dist/llm/usage-persist.js +77 -0
  200. package/dist/llm/usage-telemetry.js +103 -0
  201. package/dist/output/context.js +9 -46
  202. package/dist/output/html-render.js +73 -0
  203. package/dist/output/renderers.js +88 -58
  204. package/dist/output/shapes/curate.js +7 -3
  205. package/dist/output/shapes/distill.js +7 -3
  206. package/dist/output/shapes/env-list.js +18 -16
  207. package/dist/output/shapes/events.js +5 -4
  208. package/dist/output/shapes/helpers.js +19 -5
  209. package/dist/output/shapes/history.js +7 -3
  210. package/dist/output/shapes/passthrough.js +8 -11
  211. package/dist/output/shapes/{proposal-accept.js → proposal/accept.js} +7 -3
  212. package/dist/output/shapes/{proposal-diff.js → proposal/diff.js} +7 -3
  213. package/dist/output/shapes/{proposal-list.js → proposal/list.js} +7 -3
  214. package/dist/output/shapes/{proposal-producer.js → proposal/producer.js} +5 -4
  215. package/dist/output/shapes/{proposal-reject.js → proposal/reject.js} +7 -3
  216. package/dist/output/shapes/{proposal-show.js → proposal/show.js} +7 -3
  217. package/dist/output/shapes/registry-search.js +7 -3
  218. package/dist/output/shapes/registry.js +12 -0
  219. package/dist/output/shapes/search.js +7 -3
  220. package/dist/output/shapes/secret-list.js +18 -16
  221. package/dist/output/shapes/show.js +7 -3
  222. package/dist/output/shapes.js +55 -30
  223. package/dist/output/text/add.js +2 -3
  224. package/dist/output/text/clone.js +2 -3
  225. package/dist/output/text/config.js +2 -3
  226. package/dist/output/text/curate.js +4 -3
  227. package/dist/output/text/distill.js +2 -3
  228. package/dist/output/text/enable-disable.js +5 -4
  229. package/dist/output/text/env.js +13 -0
  230. package/dist/output/text/events.js +5 -4
  231. package/dist/output/text/feedback.js +4 -3
  232. package/dist/output/text/helpers.js +123 -40
  233. package/dist/output/text/history.js +2 -3
  234. package/dist/output/text/import.js +2 -3
  235. package/dist/output/text/index.js +2 -3
  236. package/dist/output/text/info.js +2 -3
  237. package/dist/output/text/init.js +2 -3
  238. package/dist/output/text/list.js +2 -3
  239. package/dist/output/text/proposal/producer.js +9 -0
  240. package/dist/output/text/proposal/proposal.js +13 -0
  241. package/dist/output/text/registry-commands.js +8 -7
  242. package/dist/output/text/registry.js +12 -0
  243. package/dist/output/text/remember.js +4 -3
  244. package/dist/output/text/remove.js +2 -3
  245. package/dist/output/text/save.js +2 -3
  246. package/dist/output/text/search.js +4 -3
  247. package/dist/output/text/show.js +4 -3
  248. package/dist/output/text/update.js +2 -3
  249. package/dist/output/text/upgrade.js +2 -3
  250. package/dist/output/text/wiki.js +12 -11
  251. package/dist/output/text/workflow.js +12 -10
  252. package/dist/output/text.js +66 -32
  253. package/dist/registry/build-index.js +11 -10
  254. package/dist/registry/factory.js +1 -1
  255. package/dist/registry/origin-resolve.js +1 -1
  256. package/dist/registry/providers/index.js +2 -2
  257. package/dist/registry/providers/skills-sh.js +91 -72
  258. package/dist/registry/providers/static-index.js +75 -52
  259. package/dist/registry/resolve.js +3 -3
  260. package/dist/runtime.js +242 -0
  261. package/dist/scripts/migrate-storage.js +1654 -683
  262. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +254 -168
  263. package/dist/setup/detect.js +311 -9
  264. package/dist/setup/harness-config-import.js +6 -120
  265. package/dist/setup/setup.js +454 -43
  266. package/dist/sources/include.js +1 -1
  267. package/dist/sources/provider-factory.js +2 -2
  268. package/dist/sources/providers/filesystem.js +3 -3
  269. package/dist/sources/providers/git.js +9 -9
  270. package/dist/sources/providers/index.js +4 -4
  271. package/dist/sources/providers/npm.js +6 -6
  272. package/dist/sources/providers/provider-utils.js +13 -20
  273. package/dist/sources/providers/sync-from-ref.js +5 -5
  274. package/dist/sources/providers/tar-utils.js +2 -2
  275. package/dist/sources/providers/website.js +2 -2
  276. package/dist/sources/resolve.js +5 -5
  277. package/dist/sources/website-ingest.js +5 -5
  278. package/dist/storage/database.js +102 -0
  279. package/dist/storage/engines/sqlite-migrations.js +42 -0
  280. package/dist/storage/locations.js +25 -0
  281. package/dist/storage/repositories/index-db.js +43 -0
  282. package/dist/storage/repositories/workflow-runs-repository.js +141 -0
  283. package/dist/tasks/backends/cron.js +4 -4
  284. package/dist/tasks/backends/exec-utils.js +32 -0
  285. package/dist/tasks/backends/index.js +3 -3
  286. package/dist/tasks/backends/launchd.js +7 -14
  287. package/dist/tasks/backends/schtasks.js +7 -16
  288. package/dist/tasks/embedded.js +71 -0
  289. package/dist/tasks/parser.js +2 -2
  290. package/dist/tasks/resolveAkmBin.js +1 -1
  291. package/dist/tasks/runner.js +127 -31
  292. package/dist/tasks/schedule.js +1 -1
  293. package/dist/tasks/validator.js +7 -7
  294. package/dist/text-import-hook.mjs +51 -0
  295. package/dist/version.js +2 -1
  296. package/dist/wiki/wiki.js +7 -7
  297. package/dist/workflows/{authoring.js → authoring/authoring.js} +6 -6
  298. package/dist/workflows/{scope-key.js → authoring/scope-key.js} +1 -1
  299. package/dist/workflows/cli.js +1 -1
  300. package/dist/workflows/db.js +54 -32
  301. package/dist/workflows/parser.js +4 -4
  302. package/dist/workflows/renderer.js +5 -5
  303. package/dist/workflows/runtime/agent-identity.js +56 -0
  304. package/dist/workflows/runtime/checkin.js +57 -0
  305. package/dist/workflows/{runs.js → runtime/runs.js} +197 -101
  306. package/dist/workflows/validate-summary.js +82 -0
  307. package/docs/README.md +1 -1
  308. package/docs/data-and-telemetry.md +6 -6
  309. package/package.json +17 -8
  310. package/dist/commands/add-cli.js +0 -279
  311. package/dist/commands/env.js +0 -213
  312. package/dist/integrations/agent/sdk-runner.js +0 -126
  313. package/dist/output/shapes/vault-list.js +0 -19
  314. package/dist/output/text/proposal-producer.js +0 -8
  315. package/dist/output/text/proposal.js +0 -12
  316. package/dist/output/text/vault.js +0 -16
  317. /package/dist/core/{asset-serialize.js → asset/asset-serialize.js} +0 -0
  318. /package/dist/core/{frontmatter.js → asset/frontmatter.js} +0 -0
  319. /package/dist/core/{config-sources.js → config/config-sources.js} +0 -0
  320. /package/dist/indexer/{graph-dedup.js → graph/graph-dedup.js} +0 -0
  321. /package/dist/{core/config-types.js → indexer/passes/pass-context.js} +0 -0
  322. /package/dist/indexer/{search-fields.js → search/search-fields.js} +0 -0
  323. /package/dist/indexer/{index-context.js → walk/index-context.js} +0 -0
  324. /package/dist/workflows/{document-cache.js → runtime/document-cache.js} +0 -0
@@ -3,12 +3,12 @@
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
- import { stripJsonComments } from "../core/config";
7
- import { unifiedDiff, withConfigLock, writeConfigAtomic } from "../core/config-io";
8
- import { migrateConfigShape } from "../core/config-migration";
9
- import { getCacheDir, getConfigPath } from "../core/paths";
10
- import { warn } from "../core/warn";
11
- export { migrateConfigShape } from "../core/config-migration";
6
+ import { stripJsonComments } from "../core/config/config.js";
7
+ import { unifiedDiff, withConfigLock, writeConfigAtomic } from "../core/config/config-io.js";
8
+ import { migrateConfigShape } from "../core/config/config-migration.js";
9
+ import { getCacheDir, getConfigPath } from "../core/paths.js";
10
+ import { warn } from "../core/warn.js";
11
+ export { migrateConfigShape } from "../core/config/config-migration.js";
12
12
  const PROJECT_CONFIG_RELATIVE_PATH = path.join(".akm", "config.json");
13
13
  function backupConfigFile(configPath) {
14
14
  if (!fs.existsSync(configPath))
@@ -9,10 +9,10 @@
9
9
  * Exits non-zero on errors so it composes well in CI hooks.
10
10
  */
11
11
  import fs from "node:fs";
12
- import { parseConfigText } from "../core/config-io";
13
- import { validateConfigShape } from "../core/config-schema";
14
- import { ConfigError } from "../core/errors";
15
- import { getConfigPath } from "../core/paths";
12
+ import { parseConfigText } from "../core/config/config-io.js";
13
+ import { validateConfigShape } from "../core/config/config-schema.js";
14
+ import { ConfigError } from "../core/errors.js";
15
+ import { getConfigPath } from "../core/paths.js";
16
16
  export async function runConfigValidate() {
17
17
  const configPath = getConfigPath();
18
18
  if (!fs.existsSync(configPath)) {
@@ -7,7 +7,7 @@
7
7
  * ## Usage
8
8
  *
9
9
  * ```ts
10
- * import { confirmDestructive } from "../cli/confirm";
10
+ * import { confirmDestructive } from "../cli/confirm.js";
11
11
  *
12
12
  * async function run({ args }) {
13
13
  * const yes = await confirmDestructive(
@@ -26,7 +26,7 @@
26
26
  * accidental destruction in scripts that forget to pass `-y`.
27
27
  *
28
28
  * This is intentionally stricter than many CLIs that silently proceed in
29
- * non-TTY mode. The rationale: vault keys, sources, and proposals cannot be
29
+ * non-TTY mode. The rationale: secrets, sources, and proposals cannot be
30
30
  * recovered after deletion, so the cost of requiring `--yes` in scripts is
31
31
  * low and the cost of accidental deletion is high.
32
32
  *
@@ -36,7 +36,7 @@
36
36
  * output. The auto-migration banner is similarly exempt from `--quiet`.
37
37
  */
38
38
  import * as p from "@clack/prompts";
39
- import { UsageError } from "../core/errors";
39
+ import { UsageError } from "../core/errors.js";
40
40
  /**
41
41
  * Prompt the user to confirm a destructive action.
42
42
  *
@@ -7,7 +7,7 @@
7
7
  * These were extracted from `src/cli.ts` to eliminate repetition and keep the
8
8
  * main CLI file focused on command definitions and routing.
9
9
  */
10
- import { UsageError } from "../core/errors";
10
+ import { UsageError } from "../core/errors.js";
11
11
  // ── Subcommand detection ─────────────────────────────────────────────────────
12
12
  /**
13
13
  * Return true when `args._[0]` is a member of `validSet`.
@@ -7,11 +7,14 @@
7
7
  *
8
8
  * Exported: output, runWithJsonErrors, parseAllFlagValues, emitJsonError
9
9
  */
10
+ import { defineCommand } from "citty";
10
11
  import { stringify as yamlStringify } from "yaml";
11
- import { ConfigError, NotFoundError, UsageError } from "../core/errors";
12
- import { getOutputMode } from "../output/context";
13
- import { shapeForCommand } from "../output/shapes";
14
- import { formatPlain, outputJsonl } from "../output/text";
12
+ import { assertNever } from "../core/assert.js";
13
+ import { AkmError } from "../core/errors.js";
14
+ import { getOutputMode } from "../output/context.js";
15
+ import { DEFAULT_TEMPLATE, deliverRendered, escapeHtml, renderHtml, resolveTemplatePath } from "../output/html-render.js";
16
+ import { shapeForCommand } from "../output/shapes.js";
17
+ import { formatPlain, outputJsonl } from "../output/text.js";
15
18
  // ── Exit codes ───────────────────────────────────────────────────────────────
16
19
  /**
17
20
  * Canonical process exit-code table for the akm CLI. Single source of truth —
@@ -22,6 +25,7 @@ import { formatPlain, outputJsonl } from "../output/text";
22
25
  * 1 general / not-found
23
26
  * 2 usage error
24
27
  * 4 health warn (health command only)
28
+ * 70 internal / unclassified (sysexits EX_SOFTWARE — akm threw unexpectedly)
25
29
  * 78 config error
26
30
  */
27
31
  export const EXIT_CODES = {
@@ -29,17 +33,35 @@ export const EXIT_CODES = {
29
33
  GENERAL: 1,
30
34
  USAGE: 2,
31
35
  HEALTH_WARN: 4,
36
+ // sysexits.h EX_SOFTWARE. Distinct from GENERAL(1) so scripts can tell an
37
+ // expected "not found" outcome from akm itself throwing an unexpected error.
38
+ INTERNAL: 70,
32
39
  CONFIG: 78,
33
40
  };
34
41
  // ── Helpers ──────────────────────────────────────────────────────────────────
42
+ /**
43
+ * Map a thrown value to a process exit code.
44
+ *
45
+ * Known, classified errors (instances of `AkmError`) are dispatched through an
46
+ * exhaustive switch on the `kind` discriminant — `assertNever` makes a missing
47
+ * case a compile-time error, so adding a new error class can't silently inherit
48
+ * the wrong code. Anything that is NOT an `AkmError` is treated as a genuinely
49
+ * unexpected internal failure and maps to INTERNAL(70) rather than GENERAL(1),
50
+ * so callers can distinguish "akm threw" from a normal not-found outcome.
51
+ */
35
52
  function classifyExitCode(error) {
36
- if (error instanceof UsageError)
37
- return EXIT_CODES.USAGE;
38
- if (error instanceof ConfigError)
39
- return EXIT_CODES.CONFIG;
40
- if (error instanceof NotFoundError)
41
- return EXIT_CODES.GENERAL;
42
- return EXIT_CODES.GENERAL;
53
+ if (!(error instanceof AkmError))
54
+ return EXIT_CODES.INTERNAL;
55
+ switch (error.kind) {
56
+ case "usage":
57
+ return EXIT_CODES.USAGE;
58
+ case "config":
59
+ return EXIT_CODES.CONFIG;
60
+ case "not-found":
61
+ return EXIT_CODES.GENERAL;
62
+ default:
63
+ return assertNever(error.kind, "classifyExitCode");
64
+ }
43
65
  }
44
66
  function extractHint(error) {
45
67
  if (error instanceof Error && "hint" in error && typeof error.hint === "function") {
@@ -55,9 +77,9 @@ export function emitJsonError(error) {
55
77
  const message = error instanceof Error ? error.message : String(error);
56
78
  const hint = extractHint(error);
57
79
  const exitCode = classifyExitCode(error);
58
- const code = error instanceof UsageError || error instanceof ConfigError || error instanceof NotFoundError
59
- ? error.code
60
- : undefined;
80
+ // Classified akm errors carry a stable machine-readable `code`; unexpected
81
+ // internal errors have none.
82
+ const code = error instanceof AkmError ? error.code : undefined;
61
83
  console.error(JSON.stringify({ ok: false, error: message, ...(code ? { code } : {}), hint }, null, 2));
62
84
  process.exit(exitCode);
63
85
  }
@@ -74,7 +96,26 @@ export async function runWithJsonErrors(fn) {
74
96
  }
75
97
  }
76
98
  /**
77
- * Render a command result according to the active output mode (json/jsonl/yaml/text).
99
+ * Define a citty command whose `run` body is automatically wrapped in
100
+ * `runWithJsonErrors`, so the handler emits a byte-identical JSON error
101
+ * envelope (stdout/stderr/exit-code) on throw without the boilerplate. A
102
+ * command without a `run` (a pure subcommand group) is passed through
103
+ * unchanged.
104
+ */
105
+ export function defineJsonCommand(def) {
106
+ const { run, ...rest } = def;
107
+ if (!run)
108
+ return defineCommand({ ...rest });
109
+ return defineCommand({
110
+ ...rest,
111
+ run: (context) => runWithJsonErrors(() => run(context)),
112
+ });
113
+ }
114
+ /**
115
+ * Render a command result according to the active output mode
116
+ * (json/jsonl/yaml/text/md/html). When `--output <path>` is set, the rendered
117
+ * document is written to that file instead of stdout (jsonl excepted — it is
118
+ * a line-streaming protocol and always goes to stdout).
78
119
  */
79
120
  export function output(command, result) {
80
121
  const mode = getOutputMode();
@@ -85,14 +126,14 @@ export function output(command, result) {
85
126
  }
86
127
  switch (mode.format) {
87
128
  case "json":
88
- console.log(JSON.stringify(shaped, null, 2));
129
+ deliverRendered(JSON.stringify(shaped, null, 2), mode.outputPath);
89
130
  return;
90
131
  case "yaml":
91
- console.log(yamlStringify(shaped));
132
+ deliverRendered(yamlStringify(shaped), mode.outputPath);
92
133
  return;
93
134
  case "text": {
94
135
  const plain = formatPlain(command, shaped, mode.detail);
95
- console.log(plain ?? JSON.stringify(shaped, null, 2));
136
+ deliverRendered(plain ?? JSON.stringify(shaped, null, 2), mode.outputPath);
96
137
  return;
97
138
  }
98
139
  case "md":
@@ -100,8 +141,20 @@ export function output(command, result) {
100
141
  // per-run / window-compare table renderings. Commands that don't
101
142
  // implement an md renderer fall back to the JSON envelope so
102
143
  // pipelines never get an empty stdout.
103
- console.log(JSON.stringify(shaped, null, 2));
144
+ deliverRendered(JSON.stringify(shaped, null, 2), mode.outputPath);
104
145
  return;
146
+ case "html": {
147
+ // Generic fallback: render the JSON envelope inside the dark-mode
148
+ // default template. Commands with a bespoke HTML template (`akm health`)
149
+ // intercept before reaching output(), same as the `md` intercept.
150
+ const html = renderHtml(resolveTemplatePath(DEFAULT_TEMPLATE), {
151
+ "%%COMMAND%%": escapeHtml(command),
152
+ "%%CONTENT_JSON%%": escapeHtml(JSON.stringify(shaped, null, 2)),
153
+ "%%GENERATED_AT%%": new Date().toISOString(),
154
+ });
155
+ deliverRendered(html, mode.outputPath);
156
+ return;
157
+ }
105
158
  }
106
159
  }
107
160
  /**
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ // This Source Code Form is subject to the terms of the Mozilla Public
3
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
+
6
+ // Node entry wrapper for akm.
7
+ //
8
+ // The primary entry `dist/cli.js` carries a `#!/usr/bin/env bun` shebang and,
9
+ // when run under Node, relies on a text-import loader hook for its embedded
10
+ // `.md`/`.xml` assets (Bun loads those natively; Node needs a hook). Those
11
+ // imports are static and hoisted, so the hook MUST be registered before the
12
+ // module graph is evaluated — i.e. before `cli.js` is imported. This wrapper
13
+ // does exactly that: register the hook, then dynamically import the real CLI.
14
+ //
15
+ // Bun users never touch this file; it exists solely so `node dist/cli-node.mjs`
16
+ // (and the `test:node-smoke` script / Node CI matrix) can run akm end-to-end.
17
+
18
+ import { register } from "node:module";
19
+
20
+ register("./text-import-hook.mjs", import.meta.url);
21
+
22
+ // cli.js gates its startup block on `import.meta.main`, which is false when we
23
+ // `import()` it here. Opt in explicitly so the CLI actually runs `runMain`.
24
+ process.env.AKM_NODE_ENTRY = "1";
25
+
26
+ await import("./cli.js");