akm-cli 0.10.261012-beta → 0.10.261014-beta

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 (518) hide show
  1. package/CHANGELOG.md +710 -3
  2. package/README.md +15 -0
  3. package/SECURITY.md +11 -10
  4. package/STABILITY.md +47 -51
  5. package/dist/assets/hints/cli-hints-full.md +21 -19
  6. package/dist/assets/hints/cli-hints-short.md +3 -4
  7. package/dist/assets/opencode/akm-plugin.js +177 -0
  8. package/dist/assets/stash-skeleton/README.md +1 -1
  9. package/dist/assets/tasks/core/improve.yml +1 -1
  10. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
  11. package/dist/assets/ui/config.js +27 -10
  12. package/dist/assets/workflows/workflow-template.md +2 -2
  13. package/dist/cli/clack.js +3 -1
  14. package/dist/cli/selection.js +33 -0
  15. package/dist/cli/shared.js +14 -1
  16. package/dist/cli/unknown-flags.js +6 -37
  17. package/dist/cli.js +69 -48
  18. package/dist/commands/agent/agent-dispatch.js +17 -25
  19. package/dist/commands/agent/contribute-cli.js +9 -8
  20. package/dist/commands/command/command-cli.js +4 -8
  21. package/dist/commands/command/command-execution.js +25 -39
  22. package/dist/commands/command/execution-source-loader.js +10 -14
  23. package/dist/commands/completions.js +1 -1
  24. package/dist/commands/config-cli.js +14 -5
  25. package/dist/commands/env/child-env.js +12 -14
  26. package/dist/commands/env/env-binding.js +47 -58
  27. package/dist/commands/env/env-cli.js +22 -24
  28. package/dist/commands/env/env.js +10 -58
  29. package/dist/commands/env/secret-cli.js +11 -29
  30. package/dist/commands/env/secret.js +3 -10
  31. package/dist/commands/health/checks.js +10 -849
  32. package/dist/commands/health/connections-and-harnesses-check.js +109 -0
  33. package/dist/commands/health/egress.js +3 -3
  34. package/dist/commands/health/html-report.js +9 -10
  35. package/dist/commands/health/plugin-staleness.js +18 -11
  36. package/dist/commands/health/report-view-model.js +16 -12
  37. package/dist/commands/health/scheduler-binary.js +1 -1
  38. package/dist/commands/health/semantic-search-check.js +85 -0
  39. package/dist/commands/health/type-directory-check.js +0 -3
  40. package/dist/commands/health.js +30 -42
  41. package/dist/commands/improve/consolidate/pair-pass.js +10 -25
  42. package/dist/commands/improve/consolidate.js +10 -15
  43. package/dist/commands/improve/distill.js +5 -17
  44. package/dist/commands/improve/eligibility.js +1 -3
  45. package/dist/commands/improve/execution.js +37 -40
  46. package/dist/commands/improve/extract-cli.js +6 -11
  47. package/dist/commands/improve/extract-prompt.js +2 -2
  48. package/dist/commands/improve/extract.js +67 -97
  49. package/dist/commands/improve/improve-cli.js +22 -128
  50. package/dist/commands/improve/improve-report.js +1 -1
  51. package/dist/commands/improve/improve-strategies.js +25 -108
  52. package/dist/commands/improve/improve.js +10 -14
  53. package/dist/commands/improve/loop-stages.js +3 -0
  54. package/dist/commands/improve/memory/memory-improve.js +1 -1
  55. package/dist/commands/improve/preparation.js +8 -13
  56. package/dist/commands/improve/reflect.js +203 -332
  57. package/dist/commands/improve/retrieval-scope.js +1 -1
  58. package/dist/commands/improve/session-asset.js +3 -2
  59. package/dist/commands/improve/stage.js +87 -115
  60. package/dist/commands/lint/base-linter.js +3 -3
  61. package/dist/commands/lint/env-key-rules.js +7 -6
  62. package/dist/commands/lint/index.js +3 -3
  63. package/dist/commands/models-cli.js +103 -63
  64. package/dist/commands/proposal/drain.js +26 -39
  65. package/dist/commands/proposal/proposal-cli.js +14 -18
  66. package/dist/commands/proposal/propose-cli.js +4 -2
  67. package/dist/commands/proposal/propose.js +37 -64
  68. package/dist/commands/proposal/repository.js +17 -17
  69. package/dist/commands/proposal/validators/proposal-validators.js +3 -6
  70. package/dist/commands/read/curate.js +10 -6
  71. package/dist/commands/read/registry-search.js +2 -48
  72. package/dist/commands/read/search-cli.js +1 -8
  73. package/dist/commands/read/search.js +5 -6
  74. package/dist/commands/read/show.js +6 -29
  75. package/dist/commands/remember.js +25 -40
  76. package/dist/commands/sources/add-cli.js +8 -63
  77. package/dist/commands/sources/bundle-cli.js +8 -9
  78. package/dist/commands/sources/bundle-config-ops.js +2 -2
  79. package/dist/commands/sources/info.js +12 -1
  80. package/dist/commands/sources/init.js +1 -1
  81. package/dist/commands/sources/installed-stashes.js +119 -63
  82. package/dist/commands/sources/migration-help.js +1 -1
  83. package/dist/commands/sources/plugin-upgrade.js +8 -15
  84. package/dist/commands/sources/schema-repair.js +4 -10
  85. package/dist/commands/sources/source-add.js +2 -2
  86. package/dist/commands/sources/source-clone.js +31 -7
  87. package/dist/commands/sources/source-manage.js +4 -4
  88. package/dist/commands/targets.js +175 -0
  89. package/dist/commands/tasks/explain.js +104 -69
  90. package/dist/commands/tasks/tasks-cli.js +9 -11
  91. package/dist/commands/tasks/tasks.js +75 -97
  92. package/dist/commands/ui/api.js +11 -3
  93. package/dist/commands/ui/redact.js +5 -31
  94. package/dist/commands/ui/workspace-actions.js +1 -1
  95. package/dist/commands/workflow/plan.js +48 -9
  96. package/dist/commands/workflow-cli.js +40 -45
  97. package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
  98. package/dist/core/adapter/adapters/akm-adapter.js +36 -41
  99. package/dist/core/adapter/adapters/akm-lint.js +10 -12
  100. package/dist/core/adapter/adapters/akm-metadata.js +2 -2
  101. package/dist/core/adapter/adapters/akm-task-adapter.js +8 -9
  102. package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
  103. package/dist/core/adapter/adapters/claude-adapter.js +1 -1
  104. package/dist/core/adapter/adapters/dotenv-adapter.js +7 -6
  105. package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
  106. package/dist/core/adapter/adapters/index.js +3 -4
  107. package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
  108. package/dist/core/adapter/adapters/okf-adapter.js +8 -10
  109. package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
  110. package/dist/core/adapter/adapters/shared.js +3 -3
  111. package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
  112. package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
  113. package/dist/core/adapter/detect-adapter.js +1 -1
  114. package/dist/core/adapter/execution-source.js +13 -35
  115. package/dist/core/adapter/registry.js +1 -1
  116. package/dist/core/adapter/validate-context.js +2 -4
  117. package/dist/core/asset/asset-placement.js +1 -1
  118. package/dist/core/asset/asset-ref.js +3 -3
  119. package/dist/core/asset/resolve-ref.js +5 -0
  120. package/dist/core/bundle-rename.js +12 -4
  121. package/dist/core/closest-match.js +37 -0
  122. package/dist/core/common.js +37 -57
  123. package/dist/core/config/config-io.js +26 -18
  124. package/dist/core/config/config-schema.js +19 -106
  125. package/dist/core/config/config-sources.js +3 -3
  126. package/dist/core/config/config-types.js +4 -4
  127. package/dist/core/config/config-walker.js +50 -77
  128. package/dist/core/config/config.js +438 -109
  129. package/dist/core/config/convert-engine-references.js +114 -0
  130. package/dist/core/config/convert-engines-shared.js +40 -0
  131. package/dist/core/config/convert-engines.js +300 -0
  132. package/dist/core/config/convert-models-overlay.js +137 -0
  133. package/dist/core/config/credentials.js +304 -0
  134. package/dist/core/config/engine-semantics.js +3 -3
  135. package/dist/core/config/migrate-keys.js +222 -0
  136. package/dist/core/config/model-aliases.js +37 -0
  137. package/dist/core/config/models-file.js +34 -0
  138. package/dist/core/config/retired-engines.js +53 -0
  139. package/dist/core/config/schema/connections.js +41 -0
  140. package/dist/core/config/schema/embedding.js +2 -2
  141. package/dist/core/config/schema/harnesses.js +41 -0
  142. package/dist/core/config/schema/improve-processes.js +9 -28
  143. package/dist/core/config/schema/improve.js +36 -1
  144. package/dist/core/config/schema/index-config.js +18 -20
  145. package/dist/core/config/schema/primitives.js +42 -17
  146. package/dist/core/config/schema/search.js +6 -11
  147. package/dist/core/config/schema/sources-bundles.js +9 -9
  148. package/dist/core/config/schema/workflow.js +2 -6
  149. package/dist/core/config/unusable-entries.js +66 -0
  150. package/dist/core/content-safety.js +3 -6
  151. package/dist/core/endpoint-url.js +47 -0
  152. package/dist/core/env-secret-ref.js +84 -73
  153. package/dist/core/errors.js +10 -16
  154. package/dist/core/extra-params.js +3 -3
  155. package/dist/core/improve-result.js +8 -9
  156. package/dist/core/json-schema.js +1 -1
  157. package/dist/core/lesson-lint.js +1 -1
  158. package/dist/core/llm-inference.js +80 -0
  159. package/dist/core/parse.js +2 -2
  160. package/dist/core/paths.js +33 -10
  161. package/dist/core/recognition-util.js +8 -10
  162. package/dist/core/redaction.js +94 -55
  163. package/dist/core/ref-token.js +82 -0
  164. package/dist/core/secret-value.js +14 -0
  165. package/dist/core/state/migrations.js +17 -22
  166. package/dist/core/structured.js +2 -68
  167. package/dist/core/subprocess.js +63 -22
  168. package/dist/core/type-presentation.js +10 -14
  169. package/dist/core/write-source.js +20 -4
  170. package/dist/execution/input-contract.js +3 -6
  171. package/dist/execution/notices.js +49 -0
  172. package/dist/execution/resolved-request.js +24 -40
  173. package/dist/execution/source.js +21 -45
  174. package/dist/execution/target-ref.js +2 -2
  175. package/dist/indexer/bundle-identity-guard.js +6 -5
  176. package/dist/indexer/ensure-index.js +1 -1
  177. package/dist/indexer/index-writer-lock.js +1 -1
  178. package/dist/indexer/indexer.js +46 -42
  179. package/dist/indexer/installations.js +12 -22
  180. package/dist/indexer/lookup/adapter-concept-owner.js +40 -14
  181. package/dist/indexer/materialize-embeddings.js +20 -16
  182. package/dist/indexer/passes/memory-inference.js +21 -50
  183. package/dist/indexer/passes/metadata.js +5 -5
  184. package/dist/indexer/scan/doc-to-entry.js +1 -1
  185. package/dist/indexer/scan/drain-dir.js +9 -11
  186. package/dist/indexer/search/db-search.js +9 -7
  187. package/dist/indexer/search/search-source.js +42 -22
  188. package/dist/indexer/usage/usage-events.js +2 -3
  189. package/dist/indexer/walk/index-context.js +2 -1
  190. package/dist/indexer/walk/matchers.js +3 -11
  191. package/dist/indexer/walk/path-resolver.js +13 -68
  192. package/dist/indexer/walk/walker.js +32 -26
  193. package/dist/integrations/agent/akm-read-tools.js +81 -0
  194. package/dist/integrations/agent/config.js +1 -1
  195. package/dist/integrations/agent/detect.js +32 -36
  196. package/dist/integrations/agent/execution.js +130 -428
  197. package/dist/integrations/agent/index.js +1 -1
  198. package/dist/integrations/agent/profiles.js +24 -28
  199. package/dist/integrations/agent/prompts.js +17 -30
  200. package/dist/integrations/agent/request-lowering.js +67 -101
  201. package/dist/integrations/agent/resolution.js +332 -0
  202. package/dist/integrations/agent/runner-dispatch.js +156 -181
  203. package/dist/integrations/agent/runner.js +20 -70
  204. package/dist/integrations/agent/runtime-port.js +4 -0
  205. package/dist/integrations/agent/runtime.js +10 -0
  206. package/dist/integrations/agent/spawn.js +65 -190
  207. package/dist/integrations/harnesses/aider/index.js +19 -39
  208. package/dist/integrations/harnesses/amazonq/index.js +17 -32
  209. package/dist/integrations/harnesses/claude/index.js +59 -28
  210. package/dist/integrations/harnesses/claude/session-log.js +7 -5
  211. package/dist/integrations/harnesses/codex/index.js +19 -31
  212. package/dist/integrations/harnesses/copilot/index.js +17 -35
  213. package/dist/integrations/harnesses/gemini/index.js +18 -34
  214. package/dist/integrations/harnesses/harness.js +36 -0
  215. package/dist/integrations/harnesses/index.js +20 -51
  216. package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
  217. package/dist/integrations/harnesses/opencode/index.js +11 -33
  218. package/dist/integrations/harnesses/opencode/roots.js +50 -0
  219. package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
  220. package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
  221. package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
  222. package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
  223. package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
  224. package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
  225. package/dist/integrations/harnesses/opencode/session-log.js +58 -137
  226. package/dist/integrations/harnesses/opencode/version.js +34 -53
  227. package/dist/integrations/harnesses/openhands/index.js +13 -37
  228. package/dist/integrations/harnesses/pi/index.js +21 -32
  229. package/dist/integrations/lockfile.js +1 -1
  230. package/dist/integrations/session-logs/index.js +11 -31
  231. package/dist/llm/client.js +93 -111
  232. package/dist/llm/embedder.js +19 -34
  233. package/dist/llm/embedders/connection.js +31 -0
  234. package/dist/llm/embedders/local-model-files.js +56 -0
  235. package/dist/llm/embedders/local.js +146 -115
  236. package/dist/llm/embedders/remote.js +26 -23
  237. package/dist/llm/embedders/types.js +1 -1
  238. package/dist/llm/index-passes.js +33 -39
  239. package/dist/llm/memory-infer.js +67 -77
  240. package/dist/llm/model-list.js +35 -0
  241. package/dist/llm/rerank-client.js +8 -14
  242. package/dist/llm/structured-call.js +45 -99
  243. package/dist/llm/structured.js +60 -0
  244. package/dist/output/renderers.js +2 -8
  245. package/dist/output/shapes/helpers.js +18 -44
  246. package/dist/output/shapes/passthrough.js +1 -0
  247. package/dist/output/shapes.js +1 -7
  248. package/dist/output/text/command-format.js +41 -39
  249. package/dist/output/text/health-format.js +8 -2
  250. package/dist/output/text/helpers.js +1 -1
  251. package/dist/output/text/migrate.js +12 -0
  252. package/dist/output/text/models.js +3 -2
  253. package/dist/output/text/registry-commands.js +1 -2
  254. package/dist/output/text/show-directives.js +16 -28
  255. package/dist/output/text/show-format.js +0 -2
  256. package/dist/output/text/targets-table.js +70 -0
  257. package/dist/output/text/workflow-format.js +44 -15
  258. package/dist/output/text.js +1 -1
  259. package/dist/registry/providers/skills-sh.js +1 -28
  260. package/dist/registry/providers/static-index.js +1 -71
  261. package/dist/runtime.js +6 -2
  262. package/dist/scripts/akm-migrate-node.js +47095 -44905
  263. package/dist/scripts/akm-migrate.js +46946 -44755
  264. package/dist/setup/detect.js +28 -273
  265. package/dist/setup/endpoint.js +36 -0
  266. package/dist/setup/semantic-assets.js +13 -19
  267. package/dist/setup/setup-flags.js +77 -0
  268. package/dist/setup/setup-plan.js +144 -0
  269. package/dist/setup/setup.js +134 -358
  270. package/dist/setup/steps/connection-shared.js +49 -101
  271. package/dist/setup/steps/connection.js +121 -524
  272. package/dist/setup/steps/embeddings.js +151 -0
  273. package/dist/setup/steps/harnesses.js +118 -0
  274. package/dist/setup/steps/platforms.js +2 -81
  275. package/dist/setup/steps/tasks.js +1 -2
  276. package/dist/setup/steps.js +10 -0
  277. package/dist/setup/summary.js +67 -0
  278. package/dist/sources/freshness.js +16 -21
  279. package/dist/sources/providers/git-provider.js +2 -9
  280. package/dist/sources/providers/provider-utils.js +13 -5
  281. package/dist/sources/resolve.js +12 -16
  282. package/dist/sources/snapshot-fetchers/robots.js +11 -12
  283. package/dist/sources/snapshot-fetchers/secret-seam.js +2 -4
  284. package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
  285. package/dist/sources/snapshot-fetchers/x.js +1 -1
  286. package/dist/standalone/onnxruntime-library.js +52 -0
  287. package/dist/storage/repositories/improve-ledger-repository.js +1 -1
  288. package/dist/storage/repositories/improve-runs-repository.js +0 -13
  289. package/dist/storage/repositories/index-entries-repository.js +2 -2
  290. package/dist/storage/repositories/proposals-repository.js +2 -2
  291. package/dist/storage/repositories/task-history-repository.js +2 -2
  292. package/dist/storage/repositories/workflow-runs-repository.js +44 -129
  293. package/dist/storage/sqlite-read-snapshot.js +33 -29
  294. package/dist/tasks/embedded.js +1 -1
  295. package/dist/tasks/log-redaction.js +7 -119
  296. package/dist/tasks/prepare/prepare-support.js +8 -7
  297. package/dist/tasks/prepare/prepare.js +8 -9
  298. package/dist/tasks/prepare/script-capture.js +9 -25
  299. package/dist/tasks/run/attempt-lifecycle.js +17 -35
  300. package/dist/tasks/run/load-task.js +54 -27
  301. package/dist/tasks/run/run-command-task.js +15 -10
  302. package/dist/tasks/run/run-native-task.js +8 -21
  303. package/dist/tasks/run/run-task.js +5 -8
  304. package/dist/tasks/run/run-workflow-task.js +14 -21
  305. package/dist/tasks/run/task-history.js +9 -17
  306. package/dist/tasks/run/task-log.js +1 -5
  307. package/dist/tasks/scheduler-invocation.js +13 -18
  308. package/dist/tasks/scheduler-sync.js +0 -1
  309. package/dist/tasks/source/bounded-document.js +31 -117
  310. package/dist/tasks/source/parse-task-source.js +0 -1
  311. package/dist/tasks/source/project-v4.js +5 -3
  312. package/dist/tasks/source/task-input-diagnostics.js +3 -4
  313. package/dist/tasks/source/task-source-v4.js +48 -72
  314. package/dist/tasks/source-v3.js +2 -5
  315. package/dist/tasks/task-run-reserved-flags.js +1 -2
  316. package/dist/workflows/authoring/authoring.js +2 -7
  317. package/dist/workflows/compile.js +1 -15
  318. package/dist/workflows/concurrency-policy.js +4 -4
  319. package/dist/workflows/exec/child-workflow.js +1 -4
  320. package/dist/workflows/exec/dispatch-redaction.js +35 -86
  321. package/dist/workflows/exec/environment.js +13 -77
  322. package/dist/workflows/exec/exec-unit.js +14 -55
  323. package/dist/workflows/exec/frozen-judge.js +26 -28
  324. package/dist/workflows/exec/native-executor.js +126 -71
  325. package/dist/workflows/exec/run-workflow.js +38 -42
  326. package/dist/workflows/exec/step-work.js +13 -17
  327. package/dist/workflows/exec/unit-dispatch.js +7 -21
  328. package/dist/workflows/freeze/environment.js +14 -119
  329. package/dist/workflows/freeze/freeze.js +14 -33
  330. package/dist/workflows/freeze/step-values.js +6 -13
  331. package/dist/workflows/freeze/targets/child-workflow.js +3 -5
  332. package/dist/workflows/freeze/targets/command.js +9 -15
  333. package/dist/workflows/freeze/targets/shell.js +0 -3
  334. package/dist/workflows/freeze/task-bindings.js +0 -1
  335. package/dist/workflows/parser.js +50 -59
  336. package/dist/workflows/plan.js +8 -2
  337. package/dist/workflows/renderer.js +83 -9
  338. package/dist/workflows/resource-limits.js +2 -2
  339. package/dist/workflows/runtime/run-plan.js +38 -23
  340. package/dist/workflows/runtime/runs.js +55 -93
  341. package/dist/workflows/runtime/workflow-asset-loader.js +55 -86
  342. package/dist/workflows/source-files.js +7 -19
  343. package/docs/README.md +10 -16
  344. package/docs/architecture/README.md +2 -37
  345. package/docs/architecture/adapters.md +2 -2
  346. package/docs/architecture/akm-core-principles.md +256 -118
  347. package/docs/architecture/architecture.md +283 -99
  348. package/docs/architecture/improvement.md +8 -2
  349. package/docs/architecture/internals/classification.md +1 -3
  350. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
  351. package/docs/architecture/internals/health-advisories.md +35 -74
  352. package/docs/architecture/internals/improve-workflow.md +27 -26
  353. package/docs/architecture/internals/indexing.md +3 -3
  354. package/docs/architecture/internals/storage-locations.md +48 -15
  355. package/docs/architecture/persisted-data-compat.md +10 -6
  356. package/docs/architecture/specs/okf-support.md +9 -11
  357. package/docs/architecture/specs/ref.md +7 -9
  358. package/docs/architecture/testing/testing-workflow.md +172 -52
  359. package/docs/architecture/workflow-engine.md +51 -34
  360. package/docs/guides/README.md +0 -1
  361. package/docs/guides/author-bundles.md +15 -20
  362. package/docs/guides/author-workflows.md +93 -71
  363. package/docs/guides/bundles.md +20 -16
  364. package/docs/guides/discover-and-load.md +1 -1
  365. package/docs/guides/getting-started.md +49 -3
  366. package/docs/guides/improve-the-library.md +10 -4
  367. package/docs/guides/recipes/headless-install.md +11 -16
  368. package/docs/guides/run-workflows.md +29 -20
  369. package/docs/guides/scheduling.md +2 -2
  370. package/docs/guides/use-with-any-agent.md +20 -22
  371. package/docs/integration/bundling-akm.md +19 -9
  372. package/docs/maintainers/README.md +2 -6
  373. package/docs/maintainers/release-checklist.md +73 -126
  374. package/docs/migration/README.md +10 -3
  375. package/docs/migration/release-notes/0.10.0.md +81 -16
  376. package/docs/migration/release-notes/0.6.0.md +1 -1
  377. package/docs/migration/release-notes/0.7.0.md +1 -1
  378. package/docs/migration/release-notes/0.9.0.md +1 -1
  379. package/docs/migration/release-notes/README.md +1 -1
  380. package/docs/migration/v0.9-to-v0.10.md +300 -60
  381. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
  382. package/docs/posts/config-v2-lessons-16.md +1 -1
  383. package/docs/posts/llm-mode-reflect-13.md +1 -1
  384. package/docs/posts/release-0.6.0.md +11 -11
  385. package/docs/posts/release-0.8.0.md +4 -4
  386. package/docs/posts/workflows-vaults-09.md +1 -1
  387. package/docs/reference/README.md +1 -1
  388. package/docs/reference/asset-types.md +2 -2
  389. package/docs/reference/cli.md +477 -388
  390. package/docs/reference/configuration.md +569 -550
  391. package/docs/reference/data-and-telemetry.md +9 -6
  392. package/docs/reference/env-and-secrets.md +72 -15
  393. package/docs/reference/refs.md +3 -20
  394. package/docs/reference/registry.md +12 -38
  395. package/docs/reference/supported-formats.md +1 -1
  396. package/docs/reference/tasks.md +22 -11
  397. package/docs/reference/ui-api.md +14 -9
  398. package/docs/reference/workflow-schema.md +199 -154
  399. package/docs/reference/workflows.md +4 -6
  400. package/package.json +9 -11
  401. package/schemas/akm-config.json +1696 -2922
  402. package/schemas/akm-task.json +4 -4
  403. package/schemas/akm-workflow.json +36 -9
  404. package/ROADMAP.md +0 -112
  405. package/dist/assets/models.json +0 -35
  406. package/dist/commands/health/engine-usage.js +0 -45
  407. package/dist/commands/sources/dangerous-env-audit.js +0 -134
  408. package/dist/core/activation-policy.js +0 -67
  409. package/dist/core/config/schema/engines.js +0 -160
  410. package/dist/core/config/schema/execution.js +0 -23
  411. package/dist/core/spawn-env.js +0 -268
  412. package/dist/execution/directory-identity.js +0 -78
  413. package/dist/integrations/agent/builder-shared.js +0 -33
  414. package/dist/integrations/agent/builders.js +0 -43
  415. package/dist/integrations/agent/engine-fallback.js +0 -59
  416. package/dist/integrations/agent/engine-resolution.js +0 -333
  417. package/dist/integrations/agent/model-map.js +0 -475
  418. package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
  419. package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
  420. package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
  421. package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
  422. package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
  423. package/dist/integrations/harnesses/claude/config-import.js +0 -67
  424. package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
  425. package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
  426. package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
  427. package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
  428. package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
  429. package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
  430. package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
  431. package/dist/integrations/harnesses/opencode/config-import.js +0 -149
  432. package/dist/integrations/harnesses/opencode/model-config.js +0 -33
  433. package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
  434. package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
  435. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
  436. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
  437. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
  438. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
  439. package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
  440. package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
  441. package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
  442. package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
  443. package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
  444. package/dist/integrations/harnesses/shared.js +0 -18
  445. package/dist/integrations/harnesses/types.js +0 -55
  446. package/dist/llm/feature-gate.js +0 -115
  447. package/dist/output/shapes/models-list.js +0 -16
  448. package/dist/output/shapes/registry-search.js +0 -10
  449. package/dist/setup/detected-engines.js +0 -136
  450. package/dist/setup/engine-config.js +0 -97
  451. package/dist/setup/harness-config-import.js +0 -47
  452. package/dist/setup/providers.js +0 -14
  453. package/dist/setup/steps/semantic.js +0 -39
  454. package/dist/workflows/authoring/scope-key.js +0 -79
  455. package/dist/workflows/exec/lowering-notices.js +0 -23
  456. package/dist/workflows/source-semantics.js +0 -110
  457. package/docs/architecture/0.10-process-rules.md +0 -832
  458. package/docs/architecture/akm-architecture-decision-history.md +0 -2055
  459. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -550
  460. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
  461. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
  462. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -189
  463. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
  464. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
  465. package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
  466. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
  467. package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
  468. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
  469. package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
  470. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
  471. package/docs/architecture/decisions/README.md +0 -62
  472. package/docs/architecture/internals/functional-contract-patterns.md +0 -340
  473. package/docs/architecture/internals/registry-network-boundary.md +0 -57
  474. package/docs/architecture/internals/search.md +0 -248
  475. package/docs/architecture/reviews/env-secret-access.md +0 -319
  476. package/docs/architecture/runtime-boundary-design.md +0 -153
  477. package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
  478. package/docs/architecture/specs/0.9.0-decisions.md +0 -532
  479. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
  480. package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
  481. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
  482. package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
  483. package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
  484. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
  485. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
  486. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
  487. package/docs/architecture/specs/di-seams-plan.md +0 -539
  488. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
  489. package/docs/architecture/specs/fact-asset-type.md +0 -142
  490. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
  491. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
  492. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
  493. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
  494. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
  495. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
  496. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
  497. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
  498. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
  499. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
  500. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
  501. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
  502. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
  503. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
  504. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
  505. package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
  506. package/docs/architecture/specs/stash-organization-conventions.md +0 -377
  507. package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
  508. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
  509. package/docs/architecture/specs/workflow-format-unification.md +0 -432
  510. package/docs/architecture/testing/manual-testing-checklist.md +0 -3411
  511. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
  512. package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1720
  513. package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
  514. package/docs/guides/knowledge-management.md +0 -18
  515. package/docs/maintainers/curate-workmap.md +0 -335
  516. package/docs/migration/v0.5-to-v0.6.md +0 -759
  517. package/docs/migration/v0.7-to-v0.8.md +0 -1378
  518. package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
@@ -10,99 +10,14 @@
10
10
  import fs from "node:fs";
11
11
  import os from "node:os";
12
12
  import path from "node:path";
13
- import { runManagedSubprocess } from "../core/subprocess.js";
14
- import { defaultWhich } from "../integrations/agent/detect.js";
15
- import { getBuiltinAgentProfile, OPENCODE_SDK_SERVER_BIN } from "../integrations/agent/profiles.js";
16
- import { AGENT_DISPATCH_HARNESSES, SESSION_LOG_HARNESSES } from "../integrations/harnesses/index.js";
17
- import { detectOpencodeMajor, resolveOpencodeBin } from "../integrations/harnesses/opencode/version.js";
18
- import { detectHarnessConfigs } from "./harness-config-import.js";
13
+ import { defaultWhich, detectAgentCliProfiles } from "../integrations/agent/detect.js";
14
+ import { HARNESS_CONFIG_PLATFORMS, SESSION_LOG_HARNESSES } from "../integrations/harnesses/index.js";
15
+ import { listEndpointModels } from "../llm/model-list.js";
19
16
  let detectOverrides;
20
17
  /** TEST-ONLY. Swap the network/host probes; pass undefined to restore. */
21
18
  export function _setDetectForTests(fakes) {
22
19
  detectOverrides = fakes;
23
20
  }
24
- // ── Ollama Detection ────────────────────────────────────────────────────────
25
- const OLLAMA_BASE = "http://localhost:11434";
26
- /**
27
- * Detect if Ollama is running and list available models.
28
- *
29
- * Tries the HTTP API first (`/api/tags`), then falls back to `ollama list`
30
- * via subprocess. Returns available models sorted alphabetically.
31
- */
32
- export async function detectOllama() {
33
- if (detectOverrides?.detectOllama)
34
- return detectOverrides.detectOllama();
35
- const result = { available: false, models: [], endpoint: OLLAMA_BASE };
36
- // Try HTTP API first
37
- try {
38
- const response = await fetch(`${OLLAMA_BASE}/api/tags`, {
39
- signal: AbortSignal.timeout(3000),
40
- });
41
- if (response.ok) {
42
- const data = (await response.json());
43
- if (Array.isArray(data.models)) {
44
- result.models = data.models
45
- .map((m) => (typeof m.name === "string" ? m.name.replace(/:latest$/, "") : ""))
46
- .filter(Boolean)
47
- .sort();
48
- result.available = true;
49
- return result;
50
- }
51
- }
52
- }
53
- catch {
54
- // HTTP failed — try CLI fallback
55
- }
56
- // CLI fallback — bounded (10 s) so a wedged `ollama` can't hang detection.
57
- try {
58
- const { stdout: text, exitCode } = await runManagedSubprocess(["ollama", "list"], {
59
- capture: true,
60
- timeoutMs: 10_000,
61
- });
62
- if (exitCode === 0 && text.trim()) {
63
- const lines = text.trim().split("\n").slice(1); // skip header
64
- result.models = lines
65
- .map((line) => {
66
- const name = line.split(/\s+/)[0]?.replace(/:latest$/, "");
67
- return name || "";
68
- })
69
- .filter(Boolean)
70
- .sort();
71
- result.available = true;
72
- }
73
- }
74
- catch {
75
- // Ollama not installed or not in PATH
76
- }
77
- return result;
78
- }
79
- const LMSTUDIO_BASE = "http://localhost:1234";
80
- /**
81
- * Detect if LM Studio is running and list available models.
82
- * Probes the OpenAI-compatible /v1/models endpoint.
83
- */
84
- export async function detectLMStudio() {
85
- const result = { available: false, models: [], endpoint: LMSTUDIO_BASE };
86
- try {
87
- const response = await fetch(`${LMSTUDIO_BASE}/v1/models`, {
88
- signal: AbortSignal.timeout(2000),
89
- });
90
- if (response.ok) {
91
- const data = (await response.json());
92
- if (Array.isArray(data.data)) {
93
- result.models = data.data
94
- .map((m) => (typeof m.id === "string" ? m.id : ""))
95
- .filter(Boolean)
96
- .sort();
97
- result.available = true;
98
- }
99
- }
100
- }
101
- catch {
102
- // LM Studio not running or not accessible
103
- }
104
- return result;
105
- }
106
21
  // ── Agent Platform Detection ────────────────────────────────────────────────
107
22
  /**
108
23
  * Setup stash-source candidates, derived from the unified harness registry
@@ -115,7 +30,7 @@ export async function detectLMStudio() {
115
30
  * "detection trap" (sessions never reached the improve pipeline).
116
31
  *
117
32
  * The registry is now the single source of which harnesses are real stash
118
- * sources: a candidate must (a) have `capabilities.sessionLogs === true` AND
33
+ * sources: a candidate must (a) register a `sessionLogProvider` AND
119
34
  * (b) declare a `setupDetectionDir`. `SESSION_LOG_HARNESSES` already filters by
120
35
  * (a), so dropping the four dead options is automatic — they aren't even in the
121
36
  * registry. Adding a new session-log harness with a detection dir makes it
@@ -145,71 +60,12 @@ export function detectAgentPlatforms() {
145
60
  path: path.join(home, p.relPath),
146
61
  }));
147
62
  }
148
- /**
149
- * Map of env var NAME → { provider, kind }. The key NAMES are the only thing
150
- * this module ever inspects from `process.env`; values are never touched.
151
- */
152
- const PROVIDER_ENV_VARS = [
153
- { name: "ANTHROPIC_API_KEY", provider: "anthropic", kind: "apiKey" },
154
- { name: "OPENAI_API_KEY", provider: "openai", kind: "apiKey" },
155
- { name: "GEMINI_API_KEY", provider: "gemini", kind: "apiKey" },
156
- { name: "GOOGLE_API_KEY", provider: "gemini", kind: "apiKey" },
157
- { name: "GROQ_API_KEY", provider: "groq", kind: "apiKey" },
158
- { name: "OLLAMA_HOST", provider: "ollama", kind: "endpoint" },
159
- { name: "OLLAMA_BASE_URL", provider: "ollama", kind: "endpoint" },
160
- { name: "LM_STUDIO_BASE_URL", provider: "lmstudio", kind: "endpoint" },
161
- { name: "LM_STUDIO_API_BASE", provider: "lmstudio", kind: "endpoint" },
162
- { name: "LMSTUDIO_BASE_URL", provider: "lmstudio", kind: "endpoint" },
163
- { name: "LMSTUDIO_API_BASE", provider: "lmstudio", kind: "endpoint" },
164
- { name: "AKM_LLM_API_KEY", provider: "akm-llm", kind: "apiKey" },
165
- { name: "AKM_LLM_ENDPOINT", provider: "akm-llm", kind: "endpoint" },
166
- { name: "AKM_LLM_BASE_URL", provider: "akm-llm", kind: "endpoint" },
167
- ];
168
- /**
169
- * Scan `process.env` for the presence of known provider configuration env var
170
- * NAMES and return inferred providers.
171
- *
172
- * Pure function — no network, no filesystem. It reads only whether each known
173
- * key is *defined and non-empty*; it never reads, returns, or logs the value.
174
- *
175
- * @param envSource Env to inspect. Defaults to `process.env`. Tests inject a
176
- * fake env so a real API key is never required.
177
- * @returns Inferred providers, each carrying the env var NAME only.
178
- */
179
- export function scanProviderEnvVars(envSource = process.env) {
180
- const results = [];
181
- for (const entry of PROVIDER_ENV_VARS) {
182
- const value = envSource[entry.name];
183
- const present = typeof value === "string" && value.trim().length > 0;
184
- if (!present)
185
- continue;
186
- results.push({ provider: entry.provider, envVar: entry.name, kind: entry.kind });
187
- }
188
- return results;
189
- }
190
- /** Default endpoints probed in addition to any harness-config base URLs. */
63
+ /** Local servers that usually speak the OpenAI-compatible API. */
191
64
  const DEFAULT_LOCAL_ENDPOINTS = [
192
65
  { baseUrl: "http://localhost:11434", label: "Ollama" },
193
66
  { baseUrl: "http://localhost:1234", label: "LM Studio" },
194
67
  { baseUrl: "http://localhost:8080", label: "Local (8080)" },
195
68
  ];
196
- /**
197
- * Pick a sensible default model from a list via a name heuristic.
198
- *
199
- * Preference order: an explicit "instruct" variant, then the longest name
200
- * (a rough proxy for the larger / more-capable variant), then the first.
201
- * Returns `undefined` for an empty list.
202
- */
203
- export function pickDefaultModel(models) {
204
- const cleaned = models.filter((m) => typeof m === "string" && m.trim().length > 0);
205
- if (cleaned.length === 0)
206
- return undefined;
207
- const instruct = cleaned.filter((m) => /instruct/i.test(m));
208
- const pool = instruct.length > 0 ? instruct : cleaned;
209
- // Prefer the longest name as a proxy for the larger/most-specific variant,
210
- // breaking ties by sort order for determinism.
211
- return [...pool].sort((a, b) => b.length - a.length || a.localeCompare(b))[0];
212
- }
213
69
  /**
214
70
  * Probe a single OpenAI-compatible `/v1/models` endpoint.
215
71
  *
@@ -217,48 +73,19 @@ export function pickDefaultModel(models) {
217
73
  * `available: false` result rather than throwing.
218
74
  */
219
75
  export async function probeLocalEndpoint(baseUrl, label, timeoutMs = 2000) {
220
- const result = { baseUrl, label, available: false, models: [] };
221
- const url = `${baseUrl.replace(/\/$/, "")}/v1/models`;
222
- try {
223
- const response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
224
- if (response.ok) {
225
- const data = (await response.json());
226
- if (Array.isArray(data.data)) {
227
- result.models = data.data
228
- .map((m) => (typeof m.id === "string" ? m.id : ""))
229
- .filter(Boolean)
230
- .sort();
231
- result.available = true;
232
- result.defaultModel = pickDefaultModel(result.models);
233
- }
234
- }
235
- }
236
- catch {
237
- // Endpoint down/unreachable — leave available=false.
238
- }
239
- return result;
76
+ const listed = await listEndpointModels({ endpoint: `${baseUrl.replace(/\/$/, "")}/v1` }, timeoutMs);
77
+ return listed.ok
78
+ ? { baseUrl, label, available: true, models: [...listed.models].sort() }
79
+ : { baseUrl, label, available: false, models: [] };
240
80
  }
241
81
  /**
242
- * Probe the default local endpoints (Ollama 11434, LM Studio 1234, generic
243
- * 8080) plus any base URLs found in imported harness configs.
82
+ * Probe the default local endpoints (Ollama 11434, LM Studio 1234, generic 8080).
244
83
  *
245
84
  * Never throws: every endpoint being down yields a list of unavailable
246
85
  * results, not an error.
247
- *
248
- * @param harnessBaseUrls Extra base URLs to probe (e.g. from harness configs).
249
86
  */
250
- export async function detectLocalServers(harnessBaseUrls = []) {
251
- const endpoints = [...DEFAULT_LOCAL_ENDPOINTS];
252
- for (const raw of harnessBaseUrls) {
253
- if (typeof raw !== "string" || raw.trim().length === 0)
254
- continue;
255
- // Strip a trailing /v1 (and trailing slash) so we probe consistently.
256
- const baseUrl = raw.replace(/\/$/, "").replace(/\/v1$/, "");
257
- if (!endpoints.some((e) => e.baseUrl === baseUrl)) {
258
- endpoints.push({ baseUrl, label: `Harness (${baseUrl})` });
259
- }
260
- }
261
- return Promise.all(endpoints.map((e) => probeLocalEndpoint(e.baseUrl, e.label)));
87
+ export async function detectLocalServers() {
88
+ return Promise.all(DEFAULT_LOCAL_ENDPOINTS.map((e) => probeLocalEndpoint(e.baseUrl, e.label)));
262
89
  }
263
90
  /**
264
91
  * Suggest stash directories, ranked (lower rank = higher priority).
@@ -334,86 +161,28 @@ function findGitRepoRoot(start) {
334
161
  }
335
162
  }
336
163
  /**
337
- * Detect the best agent harness, preferring in-process/SDK dispatch over CLI
338
- * subprocess dispatch:
339
- * 1. `opencode-sdk` — the embedded SDK, when the server binary it spawns is
340
- * on PATH.
341
- * 2. the first dispatch-capable CLI harness whose binary is on PATH, in
342
- * registry order (`opencode`, `claude`, `codex`, ...).
343
- * 3. none.
344
- *
345
- * The SDK import resolving is NOT evidence the SDK path can run: `@opencode-ai/sdk`
346
- * (OpenCode 1) and `@opencode/client` (OpenCode 2; the binary's detected major
347
- * selects) are hard dependencies of akm-cli itself, so `import()` always succeeds and an
348
- * import-only check would report `opencode-sdk` on every machine — including
349
- * ones where the first agentic command then dies with spawn ENOENT. The SDK
350
- * runner spawns `opencode serve` (see `harnesses/opencode-sdk/sdk-runner.ts`),
351
- * so the binary probe is what actually decides. The package cannot substitute
352
- * for the binary under any driver: it declares `"dependencies": {}` and its
353
- * own `createOpencodeServer` spawns the same `opencode serve`.
354
- *
355
- * Pure aside from the dynamic import resolution (which performs no network).
164
+ * The agent programs on PATH that can be enabled as a harness, in registry
165
+ * order. A harness is installed when its binary is found; OpenCode is detected
166
+ * like any other.
356
167
  */
357
- export async function detectHarness(whichFn = defaultWhich) {
358
- // Probed once; reused below so the `opencode` CLI fallback doesn't repeat
359
- // the identical full-PATH walk this just performed.
360
- const opencodePath = whichFn(resolveOpencodeBin(undefined, whichFn));
361
- if (opencodePath) {
362
- try {
363
- // The client package of the major the binary reports.
364
- if (detectOpencodeMajor(opencodePath).major === 1)
365
- await import("@opencode-ai/sdk");
366
- else
367
- await import("@opencode/client");
368
- return "opencode-sdk";
369
- }
370
- catch {
371
- // SDK genuinely unavailable (e.g. externalized in a standalone build).
372
- // Fall through — the `opencode` CLI harness is probed below.
373
- }
374
- }
375
- for (const harness of AGENT_DISPATCH_HARNESSES) {
376
- // The SDK harness dispatches without a CLI profile and was decided above;
377
- // an explicit skip so a future `profile` for it can't silently
378
- // reintroduce it here after the import guard already rejected it.
379
- if (harness.id === "opencode-sdk")
380
- continue;
381
- const bin = getBuiltinAgentProfile(harness.id)?.bin;
382
- if (!bin)
383
- continue;
384
- const found = bin === OPENCODE_SDK_SERVER_BIN ? opencodePath : whichFn(bin);
385
- if (found)
386
- return harness.id;
387
- }
388
- return "none";
168
+ export function detectInstalledHarnesses(whichFn = defaultWhich) {
169
+ const enableable = new Set(HARNESS_CONFIG_PLATFORMS);
170
+ return detectAgentCliProfiles(undefined, whichFn).flatMap((found) => found.available && found.resolvedPath && enableable.has(found.name)
171
+ ? [{ platform: found.name, bin: found.bin, path: found.resolvedPath }]
172
+ : []);
389
173
  }
390
174
  /**
391
175
  * Run the full environment-detection pipeline once and return a single typed
392
- * result. Orchestrates env-var scan, harness config import, harness selection,
393
- * local-server probes, and stash-dir suggestions.
394
- *
395
- * SAFETY: No API key VALUE is ever read, stored, logged, or returned — only
396
- * env var NAMES. Tolerant of every detector failing.
176
+ * result. Orchestrates harness detection, local-server probes, and stash-dir
177
+ * suggestions. Tolerant of every detector failing.
397
178
  *
398
179
  * @param opts.existingStashDir Current config stashDir (no-op suggestion).
399
- * @param opts.envSource Env to scan. Defaults to `process.env`.
400
180
  * @param opts.whichFn Binary lookup. Tests inject a stub.
181
+ * @param opts.probe Contact the local servers. False for an offline run.
401
182
  */
402
183
  export async function detectEnvironment(opts) {
403
- const envSource = opts?.envSource ?? process.env;
404
184
  const whichFn = opts?.whichFn ?? defaultWhich;
405
- let harnessConfigs = [];
406
- try {
407
- harnessConfigs = detectHarnessConfigs();
408
- }
409
- catch {
410
- harnessConfigs = [];
411
- }
412
- const harnessBaseUrls = harnessConfigs.map((c) => c.baseUrl).filter((u) => typeof u === "string");
413
- const [harness, localServers] = await Promise.all([
414
- detectHarness(whichFn),
415
- detectLocalServers(harnessBaseUrls).catch(() => []),
416
- ]);
185
+ const localServers = opts?.probe === false ? [] : await detectLocalServers().catch(() => []);
417
186
  let agentPlatforms = [];
418
187
  try {
419
188
  agentPlatforms = detectAgentPlatforms();
@@ -422,9 +191,7 @@ export async function detectEnvironment(opts) {
422
191
  agentPlatforms = [];
423
192
  }
424
193
  return {
425
- harness,
426
- providers: scanProviderEnvVars(envSource),
427
- harnessConfigs,
194
+ harnesses: detectInstalledHarnesses(whichFn),
428
195
  localServers,
429
196
  stashSuggestions: detectStashDir({
430
197
  existingStashDir: opts?.existingStashDir,
@@ -434,29 +201,17 @@ export async function detectEnvironment(opts) {
434
201
  agentPlatforms,
435
202
  };
436
203
  }
437
- /**
438
- * Render a compact, human-readable "Detected environment" summary block.
439
- * Contains env var NAMES only — never any value.
440
- */
204
+ /** Render a compact, human-readable "Detected environment" summary block. */
441
205
  export function renderDetectionSummary(env) {
442
206
  const lines = ["Detected environment:"];
443
- lines.push(` Harness: ${env.harness}`);
207
+ lines.push(` Harnesses: ${env.harnesses.length > 0 ? env.harnesses.map((h) => h.platform).join(", ") : "none on PATH"}`);
444
208
  const liveServers = env.localServers.filter((s) => s.available);
445
209
  if (liveServers.length > 0) {
446
- lines.push(` Local servers: ${liveServers
447
- .map((s) => `${s.label}${s.defaultModel ? ` (${s.defaultModel})` : ""}`)
448
- .join(", ")}`);
210
+ lines.push(` Local servers: ${liveServers.map((s) => s.label).join(", ")}`);
449
211
  }
450
212
  else {
451
213
  lines.push(" Local servers: none reachable");
452
214
  }
453
- if (env.providers.length > 0) {
454
- // NAMES only — never values.
455
- lines.push(` Provider keys: ${env.providers.map((p) => `${p.provider}:${p.envVar}`).join(", ")}`);
456
- }
457
- else {
458
- lines.push(" Provider keys: none in environment");
459
- }
460
215
  const topStash = env.stashSuggestions[0];
461
216
  if (topStash) {
462
217
  lines.push(` Stash suggest: ${topStash.path} (${topStash.reason})`);
@@ -0,0 +1,36 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * The endpoint as a connection stores it: the OpenAI-compatible base URL
6
+ * (`…/v1`), whatever form the user typed it in.
7
+ */
8
+ /** The base URL for `input`, or a thrown Error saying what is wrong with it. */
9
+ export function normalizeEndpoint(input) {
10
+ let url;
11
+ try {
12
+ url = new URL(input.trim());
13
+ }
14
+ catch {
15
+ throw new Error("endpoint must be a complete URL such as http://localhost:11434/v1");
16
+ }
17
+ if (url.protocol !== "http:" && url.protocol !== "https:")
18
+ throw new Error("endpoint must use http or https");
19
+ if (url.username || url.password || url.search || url.hash)
20
+ throw new Error("endpoint cannot contain credentials, query, or fragment");
21
+ let pathname = url.pathname.replace(/\/+$/, "").replace(/\/chat\/completions$/, "");
22
+ if (!pathname.endsWith("/v1") && !pathname.includes("/openai"))
23
+ pathname += "/v1";
24
+ url.pathname = pathname;
25
+ return url.toString().replace(/\/$/, "");
26
+ }
27
+ /** `normalizeEndpoint` as a prompt validator: the problem, or `undefined` when the URL is fine. */
28
+ export function endpointProblem(input) {
29
+ try {
30
+ normalizeEndpoint(input);
31
+ return undefined;
32
+ }
33
+ catch (err) {
34
+ return err instanceof Error ? err.message : String(err);
35
+ }
36
+ }
@@ -2,15 +2,16 @@
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
4
  /**
5
- * Semantic-search asset preparation for the setup wizard. Transformers.js is
6
- * a normal external package dependency; setup never mutates the installed CLI.
7
- * This module only prepares the model.
5
+ * Semantic-search asset preparation for the setup wizard. The embedding
6
+ * runtime (onnxruntime-node) is a normal package dependency; setup never
7
+ * mutates the installed CLI. This module only prepares the model.
8
8
  */
9
9
  import * as p from "../cli/clack.js";
10
10
  import { isHttpUrl } from "../core/common.js";
11
- import { checkEmbeddingAvailability, DEFAULT_LOCAL_MODEL, isTransformersAvailable } from "../llm/embedder.js";
11
+ import { checkEmbeddingAvailability, DEFAULT_LOCAL_MODEL } from "../llm/embedder.js";
12
+ import { effectiveEmbedding } from "../llm/embedders/connection.js";
12
13
  // Approximate first-download size of the default local model (DEFAULT_LOCAL_MODEL), used in the setup note.
13
- const LOCAL_MODEL_APPROX_SIZE_MB = 130;
14
+ const LOCAL_MODEL_APPROX_SIZE_MB = 127;
14
15
  export function isRemoteEmbeddingConfig(embedding) {
15
16
  return isHttpUrl(embedding?.endpoint);
16
17
  }
@@ -26,29 +27,22 @@ export function describeSemanticSearchAssets(embedding) {
26
27
  ];
27
28
  }
28
29
  export async function prepareSemanticSearchAssets(config) {
29
- const remote = isRemoteEmbeddingConfig(config.embedding);
30
- // Local embeddings require the declared Transformers dependency.
31
- if (!remote) {
32
- if (!isTransformersAvailable()) {
33
- const message = "The @huggingface/transformers dependency is unavailable. Reinstall akm-cli, then re-run `akm setup` or `akm index --full --verbose`.";
34
- p.log.warn(message);
35
- return { ok: false, reason: "missing-package", message };
36
- }
37
- }
30
+ const embedding = effectiveEmbedding(config);
31
+ const remote = isRemoteEmbeddingConfig(embedding);
38
32
  const spin = p.spinner();
39
33
  spin.start(remote
40
34
  ? "Checking remote embedding endpoint..."
41
- : `Downloading local embedding model (${config.embedding?.localModel ?? DEFAULT_LOCAL_MODEL})...`);
42
- const result = await checkEmbeddingAvailability(config.embedding);
35
+ : `Downloading local embedding model (${embedding?.localModel ?? DEFAULT_LOCAL_MODEL})...`);
36
+ const result = await checkEmbeddingAvailability(embedding);
43
37
  if (!result.available) {
44
38
  spin.stop("Semantic-search assets could not be prepared.");
45
39
  if (result.reason === "remote-unreachable") {
46
40
  p.log.warn("The remote embedding endpoint is not reachable. Check your endpoint and credentials, then retry `akm index --full --verbose`.");
47
41
  return { ok: false, reason: "remote-network", message: "The remote embedding endpoint is not reachable." };
48
42
  }
49
- else if (result.reason === "missing-package") {
50
- p.log.warn("The @huggingface/transformers dependency is unavailable. Reinstall akm-cli, then re-run `akm setup` or `akm index --full --verbose`.");
51
- return { ok: false, reason: "missing-package", message: "The local embedding runtime is unavailable." };
43
+ else if (result.reason === "runtime-unavailable") {
44
+ p.log.warn(`${result.message}\nSet \`embedding.endpoint\` to use a remote embedding service instead.`);
45
+ return { ok: false, reason: "runtime-unavailable", message: result.message };
52
46
  }
53
47
  else {
54
48
  p.log.warn(`The local embedding model could not be downloaded: ${result.message}\n` +
@@ -0,0 +1,77 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * The flags of `akm setup` that answer its questions, checked once before
6
+ * setup prompts, contacts anything or writes. A flag answers its question; a
7
+ * question no flag answers is asked, or, under `--yes`, takes the detected
8
+ * default.
9
+ */
10
+ import { ENGINE_NAME_PATTERN_SOURCE } from "../core/config/engine-semantics.js";
11
+ import { UsageError } from "../core/errors.js";
12
+ import { HARNESS_CONFIG_PLATFORMS } from "../integrations/harnesses/index.js";
13
+ import { normalizeEndpoint } from "./endpoint.js";
14
+ const ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
15
+ const NAME = new RegExp(ENGINE_NAME_PATTERN_SOURCE);
16
+ function bad(flag, problem) {
17
+ throw new UsageError(`--${flag}: ${problem}`, "INVALID_FLAG_VALUE");
18
+ }
19
+ function endpointFlag(flag, value) {
20
+ if (value === undefined)
21
+ return undefined;
22
+ try {
23
+ return normalizeEndpoint(value);
24
+ }
25
+ catch (err) {
26
+ return bad(flag, err instanceof Error ? err.message : String(err));
27
+ }
28
+ }
29
+ function envNameFlag(flag, value) {
30
+ if (value === undefined)
31
+ return undefined;
32
+ if (!ENV_NAME.test(value))
33
+ bad(flag, "name the environment variable that holds the key, not the key itself");
34
+ return value;
35
+ }
36
+ export function parseSetupFlags(raw) {
37
+ const endpoint = endpointFlag("endpoint", raw.endpoint);
38
+ const embeddingEndpoint = endpointFlag("embedding-endpoint", raw.embeddingEndpoint);
39
+ const apiKeyEnv = envNameFlag("api-key-env", raw.apiKeyEnv);
40
+ const embeddingApiKeyEnv = envNameFlag("embedding-api-key-env", raw.embeddingApiKeyEnv);
41
+ if (raw.name !== undefined && !NAME.test(raw.name)) {
42
+ bad("name", "use lowercase kebab-case, not beginning with akm-");
43
+ }
44
+ let harness;
45
+ if (raw.harness !== undefined) {
46
+ harness = raw.harness
47
+ .split(",")
48
+ .map((entry) => entry.trim())
49
+ .filter(Boolean);
50
+ const unknown = harness.filter((platform) => !HARNESS_CONFIG_PLATFORMS.includes(platform));
51
+ if (harness.length === 0 || unknown.length > 0) {
52
+ bad("harness", `${unknown.length > 0 ? `unknown platform ${unknown.join(", ")}; ` : ""}use a comma-separated list of ${HARNESS_CONFIG_PLATFORMS.join(", ")}`);
53
+ }
54
+ }
55
+ const embedding = raw.embedding?.trim();
56
+ if (raw.embedding !== undefined && !embedding)
57
+ bad("embedding", "name a model, or local, or off");
58
+ if (embeddingEndpoint !== undefined && (embedding === undefined || embedding === "local" || embedding === "off")) {
59
+ bad("embedding-endpoint", "needs --embedding <model>, the model that endpoint serves");
60
+ }
61
+ if (embeddingApiKeyEnv !== undefined && embeddingEndpoint === undefined) {
62
+ bad("embedding-api-key-env", "needs --embedding-endpoint; an embedding model on the connection uses its key");
63
+ }
64
+ return {
65
+ ...(endpoint !== undefined ? { endpoint } : {}),
66
+ ...(apiKeyEnv !== undefined ? { apiKeyEnv } : {}),
67
+ ...(raw.name !== undefined ? { name: raw.name } : {}),
68
+ ...(harness !== undefined ? { harness } : {}),
69
+ ...(embedding !== undefined ? { embedding } : {}),
70
+ ...(embeddingEndpoint !== undefined ? { embeddingEndpoint } : {}),
71
+ ...(embeddingApiKeyEnv !== undefined ? { embeddingApiKeyEnv } : {}),
72
+ };
73
+ }
74
+ /** Whether any flag answers a question. */
75
+ export function hasSetupFlags(flags) {
76
+ return Object.keys(flags).length > 0;
77
+ }