akm-cli 0.10.261013-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 (477) hide show
  1. package/CHANGELOG.md +494 -3
  2. package/README.md +15 -0
  3. package/SECURITY.md +9 -8
  4. package/STABILITY.md +45 -49
  5. package/dist/assets/hints/cli-hints-full.md +15 -12
  6. package/dist/assets/opencode/akm-plugin.js +177 -0
  7. package/dist/assets/stash-skeleton/README.md +1 -1
  8. package/dist/assets/tasks/core/improve.yml +1 -1
  9. package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
  10. package/dist/assets/ui/config.js +27 -10
  11. package/dist/assets/workflows/workflow-template.md +2 -2
  12. package/dist/cli/clack.js +3 -1
  13. package/dist/cli/selection.js +33 -0
  14. package/dist/cli/shared.js +14 -1
  15. package/dist/cli/unknown-flags.js +6 -37
  16. package/dist/cli.js +69 -48
  17. package/dist/commands/agent/agent-dispatch.js +17 -25
  18. package/dist/commands/agent/contribute-cli.js +9 -8
  19. package/dist/commands/command/command-cli.js +4 -8
  20. package/dist/commands/command/command-execution.js +25 -39
  21. package/dist/commands/completions.js +1 -1
  22. package/dist/commands/config-cli.js +14 -5
  23. package/dist/commands/env/child-env.js +12 -14
  24. package/dist/commands/env/env-cli.js +2 -2
  25. package/dist/commands/env/secret-cli.js +2 -2
  26. package/dist/commands/health/checks.js +10 -849
  27. package/dist/commands/health/connections-and-harnesses-check.js +109 -0
  28. package/dist/commands/health/egress.js +3 -3
  29. package/dist/commands/health/html-report.js +9 -10
  30. package/dist/commands/health/plugin-staleness.js +18 -11
  31. package/dist/commands/health/report-view-model.js +16 -12
  32. package/dist/commands/health/semantic-search-check.js +85 -0
  33. package/dist/commands/health/type-directory-check.js +0 -3
  34. package/dist/commands/health.js +30 -42
  35. package/dist/commands/improve/consolidate/pair-pass.js +10 -25
  36. package/dist/commands/improve/consolidate.js +10 -15
  37. package/dist/commands/improve/distill.js +5 -15
  38. package/dist/commands/improve/eligibility.js +1 -1
  39. package/dist/commands/improve/execution.js +37 -40
  40. package/dist/commands/improve/extract-cli.js +6 -11
  41. package/dist/commands/improve/extract-prompt.js +2 -2
  42. package/dist/commands/improve/extract.js +67 -97
  43. package/dist/commands/improve/improve-cli.js +22 -128
  44. package/dist/commands/improve/improve-report.js +1 -1
  45. package/dist/commands/improve/improve-strategies.js +25 -108
  46. package/dist/commands/improve/improve.js +10 -14
  47. package/dist/commands/improve/loop-stages.js +3 -0
  48. package/dist/commands/improve/memory/memory-improve.js +1 -1
  49. package/dist/commands/improve/preparation.js +8 -13
  50. package/dist/commands/improve/reflect.js +203 -332
  51. package/dist/commands/improve/retrieval-scope.js +1 -1
  52. package/dist/commands/improve/session-asset.js +3 -2
  53. package/dist/commands/improve/stage.js +87 -115
  54. package/dist/commands/lint/base-linter.js +3 -3
  55. package/dist/commands/lint/index.js +2 -2
  56. package/dist/commands/models-cli.js +103 -63
  57. package/dist/commands/proposal/drain.js +26 -39
  58. package/dist/commands/proposal/proposal-cli.js +14 -18
  59. package/dist/commands/proposal/propose-cli.js +4 -2
  60. package/dist/commands/proposal/propose.js +37 -64
  61. package/dist/commands/proposal/repository.js +17 -17
  62. package/dist/commands/proposal/validators/proposal-validators.js +2 -2
  63. package/dist/commands/read/curate.js +10 -6
  64. package/dist/commands/read/registry-search.js +2 -48
  65. package/dist/commands/read/search-cli.js +1 -8
  66. package/dist/commands/read/search.js +5 -6
  67. package/dist/commands/read/show.js +2 -4
  68. package/dist/commands/remember.js +25 -40
  69. package/dist/commands/sources/bundle-config-ops.js +2 -2
  70. package/dist/commands/sources/info.js +12 -1
  71. package/dist/commands/sources/init.js +1 -1
  72. package/dist/commands/sources/installed-stashes.js +2 -2
  73. package/dist/commands/sources/migration-help.js +1 -1
  74. package/dist/commands/sources/plugin-upgrade.js +8 -15
  75. package/dist/commands/sources/schema-repair.js +4 -8
  76. package/dist/commands/sources/source-add.js +2 -2
  77. package/dist/commands/sources/source-manage.js +4 -4
  78. package/dist/commands/targets.js +175 -0
  79. package/dist/commands/tasks/explain.js +103 -68
  80. package/dist/commands/tasks/tasks-cli.js +9 -11
  81. package/dist/commands/tasks/tasks.js +37 -41
  82. package/dist/commands/ui/api.js +11 -3
  83. package/dist/commands/ui/redact.js +1 -27
  84. package/dist/commands/ui/workspace-actions.js +1 -1
  85. package/dist/commands/workflow/plan.js +1 -1
  86. package/dist/commands/workflow-cli.js +3 -4
  87. package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
  88. package/dist/core/adapter/adapters/akm-adapter.js +33 -38
  89. package/dist/core/adapter/adapters/akm-lint.js +7 -8
  90. package/dist/core/adapter/adapters/akm-task-adapter.js +3 -3
  91. package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
  92. package/dist/core/adapter/adapters/claude-adapter.js +1 -1
  93. package/dist/core/adapter/adapters/dotenv-adapter.js +3 -3
  94. package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
  95. package/dist/core/adapter/adapters/index.js +3 -4
  96. package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
  97. package/dist/core/adapter/adapters/okf-adapter.js +8 -10
  98. package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
  99. package/dist/core/adapter/adapters/shared.js +3 -3
  100. package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
  101. package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
  102. package/dist/core/adapter/detect-adapter.js +1 -1
  103. package/dist/core/adapter/execution-source.js +13 -35
  104. package/dist/core/adapter/registry.js +1 -1
  105. package/dist/core/adapter/validate-context.js +2 -4
  106. package/dist/core/asset/asset-placement.js +1 -1
  107. package/dist/core/asset/asset-ref.js +3 -3
  108. package/dist/core/closest-match.js +37 -0
  109. package/dist/core/common.js +33 -5
  110. package/dist/core/config/config-io.js +26 -18
  111. package/dist/core/config/config-schema.js +19 -106
  112. package/dist/core/config/config-sources.js +3 -3
  113. package/dist/core/config/config-types.js +4 -4
  114. package/dist/core/config/config-walker.js +50 -77
  115. package/dist/core/config/config.js +385 -93
  116. package/dist/core/config/convert-engine-references.js +114 -0
  117. package/dist/core/config/convert-engines-shared.js +40 -0
  118. package/dist/core/config/convert-engines.js +300 -0
  119. package/dist/core/config/convert-models-overlay.js +137 -0
  120. package/dist/core/config/credentials.js +304 -0
  121. package/dist/core/config/engine-semantics.js +3 -3
  122. package/dist/core/config/migrate-keys.js +222 -0
  123. package/dist/core/config/model-aliases.js +37 -0
  124. package/dist/core/config/models-file.js +34 -0
  125. package/dist/core/config/retired-engines.js +53 -0
  126. package/dist/core/config/schema/connections.js +41 -0
  127. package/dist/core/config/schema/embedding.js +2 -2
  128. package/dist/core/config/schema/harnesses.js +41 -0
  129. package/dist/core/config/schema/improve-processes.js +9 -28
  130. package/dist/core/config/schema/improve.js +36 -1
  131. package/dist/core/config/schema/index-config.js +18 -20
  132. package/dist/core/config/schema/primitives.js +41 -22
  133. package/dist/core/config/schema/search.js +6 -11
  134. package/dist/core/config/schema/sources-bundles.js +7 -7
  135. package/dist/core/config/schema/workflow.js +2 -6
  136. package/dist/core/config/unusable-entries.js +66 -0
  137. package/dist/core/content-safety.js +3 -6
  138. package/dist/core/endpoint-url.js +47 -0
  139. package/dist/core/errors.js +9 -15
  140. package/dist/core/extra-params.js +3 -3
  141. package/dist/core/improve-result.js +8 -9
  142. package/dist/core/json-schema.js +1 -1
  143. package/dist/core/lesson-lint.js +1 -1
  144. package/dist/core/llm-inference.js +80 -0
  145. package/dist/core/parse.js +2 -2
  146. package/dist/core/paths.js +32 -4
  147. package/dist/core/recognition-util.js +8 -10
  148. package/dist/core/redaction.js +78 -52
  149. package/dist/core/state/migrations.js +17 -22
  150. package/dist/core/structured.js +2 -68
  151. package/dist/core/subprocess.js +63 -22
  152. package/dist/core/type-presentation.js +10 -14
  153. package/dist/execution/input-contract.js +3 -6
  154. package/dist/execution/notices.js +49 -0
  155. package/dist/execution/resolved-request.js +24 -40
  156. package/dist/execution/source.js +21 -45
  157. package/dist/execution/target-ref.js +2 -2
  158. package/dist/indexer/bundle-identity-guard.js +6 -5
  159. package/dist/indexer/ensure-index.js +1 -1
  160. package/dist/indexer/index-writer-lock.js +1 -1
  161. package/dist/indexer/indexer.js +19 -6
  162. package/dist/indexer/installations.js +11 -14
  163. package/dist/indexer/materialize-embeddings.js +20 -16
  164. package/dist/indexer/passes/memory-inference.js +21 -50
  165. package/dist/indexer/passes/metadata.js +5 -5
  166. package/dist/indexer/scan/doc-to-entry.js +1 -1
  167. package/dist/indexer/scan/drain-dir.js +6 -8
  168. package/dist/indexer/search/db-search.js +9 -7
  169. package/dist/indexer/search/search-source.js +40 -22
  170. package/dist/indexer/usage/usage-events.js +2 -3
  171. package/dist/indexer/walk/index-context.js +2 -1
  172. package/dist/indexer/walk/matchers.js +3 -11
  173. package/dist/indexer/walk/walker.js +14 -4
  174. package/dist/integrations/agent/akm-read-tools.js +81 -0
  175. package/dist/integrations/agent/config.js +1 -1
  176. package/dist/integrations/agent/detect.js +32 -36
  177. package/dist/integrations/agent/execution.js +130 -428
  178. package/dist/integrations/agent/index.js +1 -1
  179. package/dist/integrations/agent/profiles.js +24 -28
  180. package/dist/integrations/agent/prompts.js +17 -30
  181. package/dist/integrations/agent/request-lowering.js +67 -101
  182. package/dist/integrations/agent/resolution.js +332 -0
  183. package/dist/integrations/agent/runner-dispatch.js +154 -178
  184. package/dist/integrations/agent/runner.js +20 -72
  185. package/dist/integrations/agent/runtime-port.js +4 -0
  186. package/dist/integrations/agent/runtime.js +10 -0
  187. package/dist/integrations/agent/spawn.js +65 -190
  188. package/dist/integrations/harnesses/aider/index.js +19 -39
  189. package/dist/integrations/harnesses/amazonq/index.js +17 -32
  190. package/dist/integrations/harnesses/claude/index.js +59 -28
  191. package/dist/integrations/harnesses/claude/session-log.js +7 -5
  192. package/dist/integrations/harnesses/codex/index.js +19 -31
  193. package/dist/integrations/harnesses/copilot/index.js +17 -35
  194. package/dist/integrations/harnesses/gemini/index.js +18 -34
  195. package/dist/integrations/harnesses/harness.js +36 -0
  196. package/dist/integrations/harnesses/index.js +20 -51
  197. package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
  198. package/dist/integrations/harnesses/opencode/index.js +11 -33
  199. package/dist/integrations/harnesses/opencode/roots.js +50 -0
  200. package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
  201. package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
  202. package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
  203. package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
  204. package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
  205. package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
  206. package/dist/integrations/harnesses/opencode/session-log.js +58 -137
  207. package/dist/integrations/harnesses/opencode/version.js +34 -53
  208. package/dist/integrations/harnesses/openhands/index.js +13 -37
  209. package/dist/integrations/harnesses/pi/index.js +21 -32
  210. package/dist/integrations/lockfile.js +1 -1
  211. package/dist/integrations/session-logs/index.js +11 -31
  212. package/dist/llm/client.js +93 -111
  213. package/dist/llm/embedder.js +19 -34
  214. package/dist/llm/embedders/connection.js +31 -0
  215. package/dist/llm/embedders/local-model-files.js +56 -0
  216. package/dist/llm/embedders/local.js +146 -115
  217. package/dist/llm/embedders/remote.js +26 -24
  218. package/dist/llm/embedders/types.js +1 -1
  219. package/dist/llm/index-passes.js +33 -39
  220. package/dist/llm/memory-infer.js +67 -77
  221. package/dist/llm/model-list.js +35 -0
  222. package/dist/llm/rerank-client.js +8 -14
  223. package/dist/llm/structured-call.js +45 -99
  224. package/dist/llm/structured.js +60 -0
  225. package/dist/output/renderers.js +2 -7
  226. package/dist/output/shapes/helpers.js +18 -42
  227. package/dist/output/shapes/passthrough.js +1 -0
  228. package/dist/output/shapes.js +1 -7
  229. package/dist/output/text/command-format.js +29 -37
  230. package/dist/output/text/health-format.js +8 -2
  231. package/dist/output/text/helpers.js +1 -1
  232. package/dist/output/text/migrate.js +12 -0
  233. package/dist/output/text/models.js +3 -2
  234. package/dist/output/text/registry-commands.js +1 -2
  235. package/dist/output/text/show-format.js +0 -2
  236. package/dist/output/text/targets-table.js +70 -0
  237. package/dist/output/text/workflow-format.js +7 -8
  238. package/dist/output/text.js +1 -1
  239. package/dist/registry/providers/skills-sh.js +1 -28
  240. package/dist/registry/providers/static-index.js +1 -71
  241. package/dist/runtime.js +6 -2
  242. package/dist/scripts/akm-migrate-node.js +5280 -4263
  243. package/dist/scripts/akm-migrate.js +5280 -4263
  244. package/dist/setup/detect.js +28 -273
  245. package/dist/setup/endpoint.js +36 -0
  246. package/dist/setup/semantic-assets.js +13 -19
  247. package/dist/setup/setup-flags.js +77 -0
  248. package/dist/setup/setup-plan.js +144 -0
  249. package/dist/setup/setup.js +134 -358
  250. package/dist/setup/steps/connection-shared.js +49 -101
  251. package/dist/setup/steps/connection.js +121 -524
  252. package/dist/setup/steps/embeddings.js +151 -0
  253. package/dist/setup/steps/harnesses.js +118 -0
  254. package/dist/setup/steps/platforms.js +2 -81
  255. package/dist/setup/steps.js +10 -0
  256. package/dist/setup/summary.js +67 -0
  257. package/dist/sources/freshness.js +16 -21
  258. package/dist/sources/providers/git-provider.js +2 -9
  259. package/dist/sources/providers/provider-utils.js +1 -5
  260. package/dist/sources/snapshot-fetchers/robots.js +11 -12
  261. package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
  262. package/dist/standalone/onnxruntime-library.js +52 -0
  263. package/dist/storage/repositories/improve-ledger-repository.js +1 -1
  264. package/dist/storage/repositories/improve-runs-repository.js +0 -13
  265. package/dist/storage/repositories/index-entries-repository.js +2 -2
  266. package/dist/storage/repositories/workflow-runs-repository.js +8 -15
  267. package/dist/storage/sqlite-read-snapshot.js +33 -29
  268. package/dist/tasks/log-redaction.js +7 -119
  269. package/dist/tasks/prepare/prepare-support.js +5 -5
  270. package/dist/tasks/prepare/prepare.js +5 -5
  271. package/dist/tasks/prepare/script-capture.js +3 -5
  272. package/dist/tasks/run/attempt-lifecycle.js +17 -35
  273. package/dist/tasks/run/load-task.js +8 -13
  274. package/dist/tasks/run/run-command-task.js +15 -10
  275. package/dist/tasks/run/run-native-task.js +8 -13
  276. package/dist/tasks/run/run-task.js +5 -8
  277. package/dist/tasks/run/run-workflow-task.js +12 -19
  278. package/dist/tasks/run/task-history.js +9 -17
  279. package/dist/tasks/run/task-log.js +1 -5
  280. package/dist/tasks/scheduler-invocation.js +13 -18
  281. package/dist/tasks/source/bounded-document.js +31 -76
  282. package/dist/tasks/source/project-v4.js +5 -3
  283. package/dist/tasks/source/task-input-diagnostics.js +3 -4
  284. package/dist/tasks/source/task-source-v4.js +47 -68
  285. package/dist/tasks/source-v3.js +2 -5
  286. package/dist/tasks/task-run-reserved-flags.js +1 -2
  287. package/dist/workflows/authoring/authoring.js +2 -7
  288. package/dist/workflows/concurrency-policy.js +4 -4
  289. package/dist/workflows/exec/child-workflow.js +0 -2
  290. package/dist/workflows/exec/dispatch-redaction.js +14 -83
  291. package/dist/workflows/exec/environment.js +2 -3
  292. package/dist/workflows/exec/exec-unit.js +10 -59
  293. package/dist/workflows/exec/frozen-judge.js +10 -26
  294. package/dist/workflows/exec/native-executor.js +56 -45
  295. package/dist/workflows/exec/run-workflow.js +7 -24
  296. package/dist/workflows/exec/step-work.js +9 -14
  297. package/dist/workflows/exec/unit-dispatch.js +6 -13
  298. package/dist/workflows/freeze/freeze.js +14 -32
  299. package/dist/workflows/freeze/step-values.js +5 -11
  300. package/dist/workflows/freeze/targets/command.js +3 -6
  301. package/dist/workflows/freeze/task-bindings.js +0 -1
  302. package/dist/workflows/parser.js +44 -34
  303. package/dist/workflows/plan.js +3 -1
  304. package/dist/workflows/renderer.js +6 -5
  305. package/dist/workflows/resource-limits.js +2 -2
  306. package/dist/workflows/runtime/run-plan.js +2 -1
  307. package/dist/workflows/runtime/runs.js +14 -9
  308. package/docs/README.md +10 -16
  309. package/docs/architecture/README.md +2 -37
  310. package/docs/architecture/adapters.md +2 -2
  311. package/docs/architecture/akm-core-principles.md +256 -118
  312. package/docs/architecture/architecture.md +282 -98
  313. package/docs/architecture/improvement.md +8 -2
  314. package/docs/architecture/internals/classification.md +1 -3
  315. package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
  316. package/docs/architecture/internals/health-advisories.md +35 -74
  317. package/docs/architecture/internals/improve-workflow.md +27 -26
  318. package/docs/architecture/internals/indexing.md +3 -3
  319. package/docs/architecture/internals/storage-locations.md +45 -12
  320. package/docs/architecture/persisted-data-compat.md +9 -6
  321. package/docs/architecture/specs/okf-support.md +9 -11
  322. package/docs/architecture/specs/ref.md +7 -9
  323. package/docs/architecture/testing/testing-workflow.md +164 -42
  324. package/docs/architecture/workflow-engine.md +17 -14
  325. package/docs/guides/README.md +0 -1
  326. package/docs/guides/author-bundles.md +1 -3
  327. package/docs/guides/author-workflows.md +61 -73
  328. package/docs/guides/bundles.md +4 -5
  329. package/docs/guides/discover-and-load.md +1 -1
  330. package/docs/guides/getting-started.md +49 -3
  331. package/docs/guides/improve-the-library.md +10 -4
  332. package/docs/guides/recipes/headless-install.md +11 -16
  333. package/docs/guides/run-workflows.md +6 -9
  334. package/docs/guides/scheduling.md +2 -2
  335. package/docs/guides/use-with-any-agent.md +20 -22
  336. package/docs/integration/bundling-akm.md +19 -9
  337. package/docs/maintainers/README.md +0 -3
  338. package/docs/migration/README.md +10 -3
  339. package/docs/migration/release-notes/0.10.0.md +81 -16
  340. package/docs/migration/release-notes/0.6.0.md +1 -1
  341. package/docs/migration/release-notes/0.7.0.md +1 -1
  342. package/docs/migration/release-notes/0.9.0.md +1 -1
  343. package/docs/migration/release-notes/README.md +1 -1
  344. package/docs/migration/v0.9-to-v0.10.md +295 -59
  345. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
  346. package/docs/posts/config-v2-lessons-16.md +1 -1
  347. package/docs/posts/llm-mode-reflect-13.md +1 -1
  348. package/docs/posts/release-0.6.0.md +11 -11
  349. package/docs/posts/release-0.8.0.md +4 -4
  350. package/docs/posts/workflows-vaults-09.md +1 -1
  351. package/docs/reference/README.md +1 -1
  352. package/docs/reference/asset-types.md +2 -2
  353. package/docs/reference/cli.md +356 -279
  354. package/docs/reference/configuration.md +569 -557
  355. package/docs/reference/data-and-telemetry.md +8 -5
  356. package/docs/reference/env-and-secrets.md +11 -5
  357. package/docs/reference/refs.md +3 -20
  358. package/docs/reference/registry.md +6 -27
  359. package/docs/reference/supported-formats.md +1 -1
  360. package/docs/reference/tasks.md +11 -8
  361. package/docs/reference/ui-api.md +11 -6
  362. package/docs/reference/workflow-schema.md +106 -134
  363. package/docs/reference/workflows.md +4 -6
  364. package/package.json +9 -11
  365. package/schemas/akm-config.json +1696 -2922
  366. package/schemas/akm-task.json +2 -0
  367. package/schemas/akm-workflow.json +36 -9
  368. package/ROADMAP.md +0 -112
  369. package/dist/assets/models.json +0 -35
  370. package/dist/commands/health/engine-usage.js +0 -45
  371. package/dist/core/config/schema/engines.js +0 -160
  372. package/dist/core/config/schema/execution.js +0 -23
  373. package/dist/core/spawn-env.js +0 -268
  374. package/dist/integrations/agent/builder-shared.js +0 -33
  375. package/dist/integrations/agent/builders.js +0 -43
  376. package/dist/integrations/agent/engine-fallback.js +0 -59
  377. package/dist/integrations/agent/engine-resolution.js +0 -335
  378. package/dist/integrations/agent/model-map.js +0 -475
  379. package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
  380. package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
  381. package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
  382. package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
  383. package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
  384. package/dist/integrations/harnesses/claude/config-import.js +0 -67
  385. package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
  386. package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
  387. package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
  388. package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
  389. package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
  390. package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
  391. package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
  392. package/dist/integrations/harnesses/opencode/config-import.js +0 -149
  393. package/dist/integrations/harnesses/opencode/model-config.js +0 -33
  394. package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
  395. package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
  396. package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
  397. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
  398. package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
  399. package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
  400. package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
  401. package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
  402. package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
  403. package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
  404. package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
  405. package/dist/integrations/harnesses/shared.js +0 -18
  406. package/dist/integrations/harnesses/types.js +0 -55
  407. package/dist/llm/feature-gate.js +0 -115
  408. package/dist/output/shapes/models-list.js +0 -16
  409. package/dist/output/shapes/registry-search.js +0 -10
  410. package/dist/setup/detected-engines.js +0 -136
  411. package/dist/setup/engine-config.js +0 -97
  412. package/dist/setup/harness-config-import.js +0 -47
  413. package/dist/setup/providers.js +0 -14
  414. package/dist/setup/steps/semantic.js +0 -39
  415. package/dist/workflows/exec/lowering-notices.js +0 -23
  416. package/docs/architecture/0.10-process-rules.md +0 -832
  417. package/docs/architecture/akm-architecture-decision-history.md +0 -2055
  418. package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -544
  419. package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
  420. package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
  421. package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -187
  422. package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
  423. package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
  424. package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
  425. package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
  426. package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
  427. package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
  428. package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
  429. package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
  430. package/docs/architecture/decisions/README.md +0 -62
  431. package/docs/architecture/internals/functional-contract-patterns.md +0 -340
  432. package/docs/architecture/internals/registry-network-boundary.md +0 -57
  433. package/docs/architecture/internals/search.md +0 -248
  434. package/docs/architecture/reviews/env-secret-access.md +0 -319
  435. package/docs/architecture/runtime-boundary-design.md +0 -153
  436. package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
  437. package/docs/architecture/specs/0.9.0-decisions.md +0 -532
  438. package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
  439. package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
  440. package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
  441. package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
  442. package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
  443. package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
  444. package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
  445. package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
  446. package/docs/architecture/specs/di-seams-plan.md +0 -539
  447. package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
  448. package/docs/architecture/specs/fact-asset-type.md +0 -142
  449. package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
  450. package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
  451. package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
  452. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
  453. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
  454. package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
  455. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
  456. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
  457. package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
  458. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
  459. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
  460. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
  461. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
  462. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
  463. package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
  464. package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
  465. package/docs/architecture/specs/stash-organization-conventions.md +0 -377
  466. package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
  467. package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
  468. package/docs/architecture/specs/workflow-format-unification.md +0 -432
  469. package/docs/architecture/testing/manual-testing-checklist.md +0 -3379
  470. package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
  471. package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1702
  472. package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
  473. package/docs/guides/knowledge-management.md +0 -18
  474. package/docs/maintainers/curate-workmap.md +0 -335
  475. package/docs/migration/v0.5-to-v0.6.md +0 -759
  476. package/docs/migration/v0.7-to-v0.8.md +0 -1378
  477. package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
@@ -0,0 +1,151 @@
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
+ * Setup step 4: embeddings. A model the connection serves, akm's built-in local
6
+ * embedder, another endpoint, or off (which is semantic search off).
7
+ */
8
+ import * as p from "../../cli/clack.js";
9
+ import { defaultConnection, } from "../../core/config/config.js";
10
+ import { apiKeyReference, resolveApiKey, storedCredential } from "../../core/config/credentials.js";
11
+ import { sameEndpoint } from "../../core/endpoint-url.js";
12
+ import { UsageError } from "../../core/errors.js";
13
+ import { redactUrlCredentials } from "../../core/redaction.js";
14
+ import { isEmbeddingModel } from "../../llm/model-list.js";
15
+ import { prompt } from "../prompt.js";
16
+ import { describeSemanticSearchAssets, isRemoteEmbeddingConfig } from "../semantic-assets.js";
17
+ import { applySetupAnswers } from "../setup-plan.js";
18
+ import { listModels, pickModel, promptApiKey, promptEndpoint, promptModelName, warnUser } from "./connection-shared.js";
19
+ /**
20
+ * The connection that will serve an embedding model once this run's answers are saved: the default connection
21
+ * of the config as it will be, which is not necessarily the one this run just answered (a further `--name`
22
+ * connection is not the default, and with several none of which is called `default` there is none).
23
+ */
24
+ function servingConnection(input) {
25
+ const projected = input.connection
26
+ ? { ...input.current, ...applySetupAnswers(input.current, { connection: input.connection }).patch }
27
+ : input.current;
28
+ return defaultConnection(projected);
29
+ }
30
+ /** The embedding models the serving connection lists: this run's listing, when this run was about that connection. */
31
+ function servedModels(input) {
32
+ const serving = servingConnection(input);
33
+ return serving !== undefined && input.connection?.name === serving.name ? input.listed.filter(isEmbeddingModel) : [];
34
+ }
35
+ /**
36
+ * A key belongs to the endpoint it was given for. When the embedding endpoint changes and no
37
+ * key comes with the new one, the current key is not carried over; say so.
38
+ */
39
+ function warnOfDroppedKey(current, endpoint, keyGiven, interactive) {
40
+ if (keyGiven || current?.endpoint === undefined || sameEndpoint(current.endpoint, endpoint))
41
+ return;
42
+ if (apiKeyReference(current.apiKey) === undefined && storedCredential({ service: "embedding" }) === undefined)
43
+ return;
44
+ warnUser(`The embedding endpoint changed, so its current key is not used with ${redactUrlCredentials(endpoint)}. Give the new endpoint's key with --embedding-api-key-env (or at the prompt).`, interactive);
45
+ }
46
+ function fromFlags(input) {
47
+ const { flags } = input;
48
+ if (flags.embedding === "off" || flags.embedding === "local")
49
+ return { kind: flags.embedding };
50
+ const model = flags.embedding;
51
+ if (flags.embeddingEndpoint !== undefined) {
52
+ warnOfDroppedKey(input.current.embedding, flags.embeddingEndpoint, Boolean(flags.embeddingApiKeyEnv), false);
53
+ return {
54
+ kind: "endpoint",
55
+ endpoint: flags.embeddingEndpoint,
56
+ model,
57
+ ...(flags.embeddingApiKeyEnv ? { key: { env: flags.embeddingApiKeyEnv } } : {}),
58
+ };
59
+ }
60
+ if (servingConnection(input) === undefined) {
61
+ const several = Object.keys(input.connection
62
+ ? { ...input.current.connections, [input.connection.name]: 1 }
63
+ : (input.current.connections ?? {})).length > 1;
64
+ throw new UsageError(several
65
+ ? `--embedding ${model} is served by the default connection, and none of the connections is called "default". Name one default (akm setup --name default), or pass --embedding-endpoint.`
66
+ : `--embedding ${model} is served by the default connection, and none is configured. Pass --endpoint (or --embedding-endpoint).`, "MISSING_REQUIRED_ARGUMENT");
67
+ }
68
+ return { kind: "connection", model };
69
+ }
70
+ /** The embedding block this answer leaves the config with, for the note that says what setup downloads. */
71
+ function embeddingAfter(input, answer) {
72
+ if (answer.kind === "endpoint")
73
+ return { endpoint: answer.endpoint, model: answer.model };
74
+ if (answer.kind === "connection")
75
+ return { endpoint: servingConnection(input)?.connection.endpoint, model: answer.model };
76
+ return answer.kind === "off" ? input.current.embedding : undefined;
77
+ }
78
+ async function askSource(input) {
79
+ const { current } = input;
80
+ const served = servedModels(input);
81
+ const hasServing = servingConnection(input) !== undefined;
82
+ const heldModel = hasServing && current.embedding?.endpoint === undefined ? current.embedding?.model : undefined;
83
+ const connectionModels = [...new Set([...(heldModel ? [heldModel] : []), ...served])];
84
+ const options = [
85
+ ...connectionModels.map((model) => ({ value: `model:${model}`, label: model, hint: "served by the connection" })),
86
+ { value: "local", label: "Built-in local embedder", hint: "no server needed" },
87
+ { value: "endpoint", label: "Another endpoint" },
88
+ { value: "off", label: "Off", hint: "keyword search only" },
89
+ ];
90
+ const initialValue = current.embedding?.endpoint
91
+ ? "endpoint"
92
+ : heldModel
93
+ ? `model:${heldModel}`
94
+ : served[0]
95
+ ? `model:${served[0]}`
96
+ : "local";
97
+ const choice = await prompt(() => p.select({ message: "Which embedding source should akm use?", options, initialValue }));
98
+ if (choice === "local" || choice === "off")
99
+ return { kind: choice };
100
+ if (choice !== "endpoint")
101
+ return { kind: "connection", model: choice.slice("model:".length) };
102
+ const endpoint = await promptEndpoint({
103
+ message: "Embedding endpoint URL:",
104
+ ...(current.embedding?.endpoint ? { initialValue: current.embedding.endpoint } : {}),
105
+ });
106
+ if (endpoint === undefined)
107
+ return { kind: "local" };
108
+ // A key belongs to the endpoint it was given for, so the current one is offered for that endpoint alone.
109
+ const unchangedEndpoint = current.embedding?.endpoint !== undefined && sameEndpoint(current.embedding.endpoint, endpoint);
110
+ const held = unchangedEndpoint
111
+ ? resolveApiKey(current.embedding?.apiKey, { service: "embedding" }, endpoint, process.env, true)
112
+ : undefined;
113
+ const typed = await promptApiKey(held !== undefined ? "Embedding API key (blank keeps the current one)" : "Embedding API key (blank for none)");
114
+ const key = typed ? { pasted: typed } : undefined;
115
+ warnOfDroppedKey(current.embedding, endpoint, key !== undefined, true);
116
+ const listed = input.probe ? await listModels(endpoint, typed ?? (unchangedEndpoint ? held : undefined), true) : [];
117
+ const embeddingModels = listed.filter(isEmbeddingModel);
118
+ const model = listed.length > 0
119
+ ? await pickModel("Embedding model:", embeddingModels.length > 0 ? embeddingModels : listed, current.embedding?.model)
120
+ : await promptModelName({ message: "Embedding model name:", initialValue: current.embedding?.model });
121
+ return { kind: "endpoint", endpoint, model, ...(key ? { key } : {}) };
122
+ }
123
+ export async function stepEmbeddings(input) {
124
+ const { current, flags, interactive } = input;
125
+ const unchanged = { mode: current.semanticSearchMode, prepareAssets: false };
126
+ if (flags.embedding !== undefined) {
127
+ const answer = fromFlags(input);
128
+ return { answer, semantic: { mode: answer.kind === "off" ? "off" : "auto", prepareAssets: false } };
129
+ }
130
+ if (!interactive) {
131
+ // The default: a model the new default connection serves. A rerun, another connection, or an embedding
132
+ // block the config already has is the user's earlier choice and stays.
133
+ const model = servedModels(input)[0];
134
+ if (model === undefined || current.embedding !== undefined || !input.addedDefaultConnection) {
135
+ return { semantic: unchanged };
136
+ }
137
+ return { answer: { kind: "connection", model }, semantic: { mode: "auto", prepareAssets: false } };
138
+ }
139
+ const answer = await askSource(input);
140
+ if (answer.kind === "off")
141
+ return { answer, semantic: { mode: "off", prepareAssets: false } };
142
+ const after = embeddingAfter(input, answer);
143
+ p.note(describeSemanticSearchAssets(after).join("\n"), "Semantic Search Assets");
144
+ const prepareAssets = await prompt(() => p.confirm({
145
+ message: isRemoteEmbeddingConfig(after)
146
+ ? "Check the embedding endpoint and verify semantic search now?"
147
+ : "Download and verify semantic-search assets now?",
148
+ initialValue: true,
149
+ }));
150
+ return { answer, semantic: { mode: "auto", prepareAssets } };
151
+ }
@@ -0,0 +1,118 @@
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
+ * Setup steps 1 and 2: which agent programs to enable as harnesses, which of
6
+ * them agent work runs on, and whether akm's own model calls (improve, judging,
7
+ * extraction) may run through it too.
8
+ */
9
+ import * as p from "../../cli/clack.js";
10
+ import { defaultConnection, defaultHarness } from "../../core/config/config.js";
11
+ import { warn } from "../../core/warn.js";
12
+ import { getHarness } from "../../integrations/harnesses/index.js";
13
+ import { prompt } from "../prompt.js";
14
+ import { harnessEntries } from "../setup-plan.js";
15
+ import { runsReadOnly, unrestrictedModelWorkNote } from "../summary.js";
16
+ function readOnlyNote(platform, bin) {
17
+ return runsReadOnly(platform, bin)
18
+ ? "model calls are limited to reading and searching"
19
+ : "model calls cannot be restricted to read-only";
20
+ }
21
+ function configuredPlatforms(current) {
22
+ return [...new Set(Object.entries(current.harnesses ?? {}).map(([name, harness]) => harness.platform ?? name))];
23
+ }
24
+ /** The platform agent work runs on in the config, if any. */
25
+ function currentDefaultPlatform(current) {
26
+ const found = defaultHarness(current);
27
+ return found ? (found.harness.platform ?? found.name) : undefined;
28
+ }
29
+ /** The `bin` the config sets for the first entry of `platform`, if it sets one: the program setup will judge. */
30
+ function configuredBin(current, platform) {
31
+ return Object.entries(current.harnesses ?? {}).find(([name, harness]) => (harness.platform ?? name) === platform)?.[1]
32
+ .bin;
33
+ }
34
+ /** The harness agent work runs on once `answer` is applied: the entry the config will hold, with its own `bin`. */
35
+ function selectedHarness(current, answer) {
36
+ const harnesses = answer ? harnessEntries(current.harnesses, answer.platforms, answer.default) : current.harnesses;
37
+ return defaultHarness({ harnesses });
38
+ }
39
+ export async function stepHarnesses(input) {
40
+ const { current, installed, flags } = input;
41
+ const configured = configuredPlatforms(current);
42
+ const installedPlatforms = installed.map((harness) => harness.platform);
43
+ let answer;
44
+ if (flags.harness) {
45
+ for (const platform of flags.harness) {
46
+ if (!installedPlatforms.includes(platform)) {
47
+ warn(`[akm setup] ${platform} was not found on PATH; enabling it anyway.`);
48
+ }
49
+ }
50
+ answer = { platforms: [...new Set([...configured, ...flags.harness])], default: flags.harness[0] };
51
+ }
52
+ else if (!input.interactive) {
53
+ if (configured.length === 0 && installedPlatforms.length > 0) {
54
+ answer = { platforms: installedPlatforms, default: installedPlatforms[0] };
55
+ }
56
+ }
57
+ else {
58
+ answer = await askHarnesses(current, installed, configured);
59
+ }
60
+ // `modelWork` is whether the default harness may take akm's model calls, once that has been decided.
61
+ const result = (modelCallsOnHarness, modelWork) => ({
62
+ ...(answer ? { answer } : {}),
63
+ modelCallsOnHarness,
64
+ ...(modelWork !== undefined ? { modelWork } : {}),
65
+ });
66
+ // Model calls can go to a harness only when one is enabled and no connection exists or is being added.
67
+ const selected = selectedHarness(current, answer);
68
+ if (selected === undefined || defaultConnection(current) !== undefined || flags.endpoint !== undefined) {
69
+ return result(false);
70
+ }
71
+ const defaultPlatform = selected.harness.platform ?? selected.name;
72
+ const readOnly = runsReadOnly(defaultPlatform, selected.harness.bin);
73
+ // A saved `modelWork: false` is the user's choice: only the question's "yes" changes it, never a default.
74
+ const declined = selected.harness.modelWork === false;
75
+ if (!input.interactive)
76
+ return declined ? result(false, false) : result(readOnly, readOnly);
77
+ const yes = await prompt(() => p.confirm({
78
+ message: `Use ${defaultPlatform} for akm's own model calls too (improve, judging, extraction)? ${readOnly ? "Model calls are limited to reading and searching." : unrestrictedModelWorkNote(defaultPlatform)}`,
79
+ initialValue: !declined,
80
+ }));
81
+ // Said again once it is chosen, so it stays in the transcript beside the answer.
82
+ if (yes && !readOnly)
83
+ p.log.warn(unrestrictedModelWorkNote(defaultPlatform));
84
+ return result(yes, yes);
85
+ }
86
+ async function askHarnesses(current, installed, configured) {
87
+ const installedPlatforms = installed.map((harness) => harness.platform);
88
+ const candidates = [...new Set([...installedPlatforms, ...configured])];
89
+ if (candidates.length === 0) {
90
+ p.log.info("No agent programs found on PATH. Agent work runs on akm's own runtime over a connection (set one up next).");
91
+ return undefined;
92
+ }
93
+ const selected = await prompt(() => p.multiselect({
94
+ message: "Which agent programs should akm use? (agent work runs on them)",
95
+ options: candidates.map((platform) => ({
96
+ value: platform,
97
+ label: getHarness(platform)?.displayName ?? platform,
98
+ hint: `${installed.find((harness) => harness.platform === platform)?.path ?? "not found on PATH"}; ${readOnlyNote(platform, configuredBin(current, platform))}`,
99
+ })),
100
+ initialValues: configured.length > 0 ? [...configured] : installedPlatforms,
101
+ required: false,
102
+ }));
103
+ if (selected.length === 0)
104
+ return { platforms: [] };
105
+ const wanted = currentDefaultPlatform(current);
106
+ const initialValue = wanted && selected.includes(wanted) ? wanted : selected[0];
107
+ const chosen = selected.length === 1
108
+ ? selected[0]
109
+ : await prompt(() => p.select({
110
+ message: "Which one should agent work run on by default?",
111
+ options: selected.map((platform) => ({
112
+ value: platform,
113
+ label: getHarness(platform)?.displayName ?? platform,
114
+ })),
115
+ initialValue,
116
+ }));
117
+ return { platforms: selected, default: chosen };
118
+ }
@@ -2,13 +2,11 @@
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
- * Setup wizard steps for agent platforms and agent-CLI selection: detect
6
- * agent platform config dirs as stash sources, and pick a default agent CLI.
5
+ * Setup wizard step for agent platforms: detect agent platform config dirs
6
+ * and offer them as bundle sources.
7
7
  */
8
8
  import * as p from "../../cli/clack.js";
9
- import { detectAgentCliProfiles, pickDefaultAgentProfile } from "../../integrations/agent/index.js";
10
9
  import { detectAgentPlatforms } from "../detect.js";
11
- import { readAgentEngineSelection } from "../engine-config.js";
12
10
  import { prompt } from "../prompt.js";
13
11
  // The just-computed source list is threaded through the private setup draft.
14
12
  export async function stepAgentPlatforms(current) {
@@ -46,80 +44,3 @@ export async function stepAgentPlatforms(current) {
46
44
  }
47
45
  return entries;
48
46
  }
49
- /**
50
- * Print a feature capability summary after both connection steps are complete.
51
- */
52
- export function printCapabilitySummary(smallModelSkipped, agentConfigured) {
53
- const lines = ["Setup complete. Here's what's enabled:", ""];
54
- lines.push(" ✓ akm search, akm curate, akm show, akm index, akm remember — always available");
55
- if (!smallModelSkipped) {
56
- lines.push(" ✓ akm improve, akm remember --enrich — small model configured");
57
- }
58
- else {
59
- lines.push(" ✗ akm improve, akm remember --enrich — run `akm setup` to enable");
60
- }
61
- if (agentConfigured) {
62
- lines.push(" ✓ akm proposal new, akm improve, akm task — agent configured");
63
- }
64
- else {
65
- lines.push(" ✗ akm proposal new, akm improve, akm task — run `akm setup` to enable");
66
- }
67
- p.note(lines.join("\n"), "Feature Summary");
68
- }
69
- export async function stepAgentSelection(current, detections) {
70
- const currentAgentBlock = readAgentEngineSelection(current);
71
- const available = detections.filter((d) => d.available);
72
- if (available.length === 0) {
73
- return currentAgentBlock;
74
- }
75
- const initialValue = pickDefaultAgentProfile(detections, currentAgentBlock?.default) ?? available[0]?.name;
76
- const selectedDefault = await prompt(() => p.select({
77
- message: "Which detected agent CLI should be the default?",
78
- options: [
79
- ...available.map((d) => ({
80
- value: d.name,
81
- label: d.name,
82
- hint: d.resolvedPath ?? d.bin,
83
- })),
84
- { value: "disabled", label: "Disabled", hint: "do not configure a default agent CLI" },
85
- ],
86
- initialValue,
87
- }));
88
- if (selectedDefault === "disabled") {
89
- if (!currentAgentBlock?.engines) {
90
- return undefined;
91
- }
92
- return {
93
- ...(currentAgentBlock ?? {}),
94
- default: undefined,
95
- };
96
- }
97
- return {
98
- ...(currentAgentBlock ?? {}),
99
- default: selectedDefault,
100
- };
101
- }
102
- /**
103
- * Detect installed agent CLIs and produce an updated `agent` config block
104
- * with a sensible `default` (the first detected profile that the user has
105
- * not already overridden).
106
- *
107
- * Pure-ish: file system / PATH probes are routed through `detectFn` so
108
- * tests can drive the branches without touching the real PATH.
109
- *
110
- * @internal Exported for testing only.
111
- */
112
- export function stepAgentCliDetection(current, detectFn = detectAgentCliProfiles) {
113
- const detections = detectFn(current);
114
- const currentAgentBlock = readAgentEngineSelection(current);
115
- const defaultName = pickDefaultAgentProfile(detections, currentAgentBlock?.default);
116
- // No installed agents found and no existing config → leave block absent.
117
- if (!defaultName && !currentAgentBlock) {
118
- return { detections };
119
- }
120
- const agent = {
121
- ...(currentAgentBlock ?? {}),
122
- ...(defaultName ? { default: defaultName } : {}),
123
- };
124
- return { agent, detections };
125
- }
@@ -17,6 +17,16 @@ export function createSetupContext(initial, options) {
17
17
  apply(delta) {
18
18
  acc = deepMergeConfig(acc, delta);
19
19
  },
20
+ replace(keys) {
21
+ const next = { ...acc };
22
+ for (const [key, value] of Object.entries(keys)) {
23
+ if (value === undefined)
24
+ delete next[key];
25
+ else
26
+ next[key] = value;
27
+ }
28
+ acc = next;
29
+ },
20
30
  };
21
31
  }
22
32
  /**
@@ -0,0 +1,67 @@
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
+ * What runs where, in words, once setup has chosen: model calls, agent work and
6
+ * embeddings. The words are read off the table `akm info` and `akm health`
7
+ * print (`../commands/targets.ts`), so the summary says what those say and what
8
+ * a call does.
9
+ */
10
+ import { targetRows } from "../commands/targets.js";
11
+ import { getHarness } from "../integrations/harnesses/index.js";
12
+ /**
13
+ * Whether akm can run this platform's program with its tools limited to reading and searching for model calls:
14
+ * `bin` when the harness sets one, else the platform's own.
15
+ */
16
+ export function runsReadOnly(platform, bin) {
17
+ const harness = getHarness(platform);
18
+ return harness !== undefined && (harness.confinableInstalled?.(bin ?? harness.profile.bin) ?? harness.confinable);
19
+ }
20
+ /** What setup says, wherever it names a harness that takes akm's model calls and cannot be restricted. */
21
+ export function unrestrictedModelWorkNote(name) {
22
+ return `Model work on ${name} cannot be restricted: it can edit files and run commands.`;
23
+ }
24
+ function modelSuffix(row) {
25
+ return row.model ? ` (${row.model})` : "";
26
+ }
27
+ /** Model calls or agent work: where the row says it runs, or what is wrong with the config that stops it. */
28
+ function describeWork(row, rows, modelWork) {
29
+ if (row.problem)
30
+ return row.problem;
31
+ if (row.kind === "connection") {
32
+ return `${modelWork ? "connection" : "akm's own runtime over connection"} "${row.target}"${modelSuffix(row)}`;
33
+ }
34
+ if (row.kind === "harness") {
35
+ const platform = rows.find((r) => r.type === "harness" && r.name === row.target);
36
+ const restriction = modelWork && platform?.type === "harness"
37
+ ? runsReadOnly(platform.platform, platform.bin)
38
+ ? ", limited to reading and searching"
39
+ : `. ${unrestrictedModelWorkNote(`"${row.target}"`)}`
40
+ : "";
41
+ return `harness "${row.target}"${modelSuffix(row)}${restriction}`;
42
+ }
43
+ const declined = modelWork
44
+ ? rows.find((r) => r.type === "harness" && r.modelWork === false)
45
+ : undefined;
46
+ return declined
47
+ ? `off: no connection is configured, and harness "${declined.name}" is set not to take model calls. Add a connection with \`akm setup --endpoint URL\`.`
48
+ : "off: no connection or harness is configured";
49
+ }
50
+ function describeEmbeddings(row) {
51
+ if (row.kind === "local")
52
+ return `akm's built-in local embedder${modelSuffix(row)}`;
53
+ if (row.kind === "connection")
54
+ return `${row.model ?? "a model"} on connection "${row.target}"`;
55
+ if (row.kind === "endpoint")
56
+ return `${row.model ?? "a model"} at ${row.target}`;
57
+ return "off";
58
+ }
59
+ export function describeRuns(config) {
60
+ const rows = targetRows({ config });
61
+ const work = (name) => rows.find((r) => r.type === "process" && r.process === name);
62
+ return {
63
+ modelCalls: describeWork(work("improve"), rows, true),
64
+ agentWork: describeWork(work("agents"), rows, false),
65
+ embeddings: describeEmbeddings(work("embedding")),
66
+ };
67
+ }
@@ -2,38 +2,33 @@
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
- * Shared freshness-window skeleton for mirror caches (git repos, website
6
- * snapshots). A marker file's mtime records the last successful refresh:
7
- * within `ttlMs` the cached copy is served without refreshing; on refresh
8
- * failure the cached copy is still served while the marker is younger than
9
- * `staleMs`, so search stays available through upstream outages.
5
+ * Shared materialization skeleton for mirror caches (git repos, website
6
+ * snapshots). A marker file records that the mirror was materialized on this
7
+ * host and its mtime records the last successful refresh. A usable
8
+ * materialized mirror is served as-is: age never triggers a refresh. Only a
9
+ * missing marker, an unusable mirror, or `force` (`akm bundle update`) does.
10
+ * A failed refresh is reported, never masked: the refresh implementations
11
+ * leave the previous copy on disk, so search keeps serving it, but the caller
12
+ * sees the error.
10
13
  */
11
14
  import fs from "node:fs";
12
- import { isExpired } from "./providers/provider-utils.js";
13
15
  /**
14
- * Run the fresh → refresh → stale-fallback ladder around `refresh()`.
15
- * Resolves when the cached copy is usable (fresh, refreshed, or stale-but-
16
- * within-window); rethrows the refresh error otherwise.
16
+ * Run the materialized → refresh ladder around `refresh()`. Resolves when the
17
+ * cached copy is usable as-is or has just been refreshed; a failed refresh
18
+ * rethrows its error.
17
19
  */
18
20
  export async function withFreshnessCache(options) {
19
21
  const usable = options.isUsable ?? (() => true);
20
- let mtime = 0;
22
+ let materialized = false;
21
23
  try {
22
- mtime = fs.statSync(options.markerPath).mtimeMs;
24
+ fs.statSync(options.markerPath);
25
+ materialized = true;
23
26
  }
24
27
  catch {
25
28
  /* no marker — never successfully refreshed */
26
29
  }
27
- if (!options.force && mtime && !isExpired(mtime, options.ttlMs) && usable()) {
30
+ if (!options.force && materialized && usable()) {
28
31
  return;
29
32
  }
30
- try {
31
- await options.refresh();
32
- }
33
- catch (err) {
34
- if (options.allowStaleOnRefreshFailure !== false && mtime && !isExpired(mtime, options.staleMs) && usable()) {
35
- return;
36
- }
37
- throw err;
38
- }
33
+ await options.refresh();
39
34
  }
@@ -13,10 +13,6 @@ import { validateGitUrl } from "../../registry/resolve.js";
13
13
  import { withFreshnessCache } from "../freshness.js";
14
14
  import { assertNoIgnoredPathOverwrite, cloneRepo, inspectGitUpstream, runGit } from "./git-install.js";
15
15
  import { sanitizeString } from "./provider-utils.js";
16
- /** Cache TTL before refreshing the mirrored repo (12 hours). */
17
- const CACHE_TTL_MS = 12 * 60 * 60 * 1000;
18
- /** Maximum stale age allowed when refresh fails (7 days). */
19
- const CACHE_STALE_MS = 7 * 24 * 60 * 60 * 1000;
20
16
  /**
21
17
  * Git source provider — clones (and re-pulls) a remote repo into a local
22
18
  * cache directory. Implements the {@link SourceProvider} interface.
@@ -75,10 +71,7 @@ export async function ensureGitMirror(repo, cachePaths, options) {
75
71
  const writable = options?.writable === true;
76
72
  await withFreshnessCache({
77
73
  markerPath: cachePaths.indexPath,
78
- ttlMs: CACHE_TTL_MS,
79
- staleMs: CACHE_STALE_MS,
80
74
  force: options?.force === true,
81
- allowStaleOnRefreshFailure: !(options?.force === true && writable),
82
75
  isUsable: () => !requireRepoDir || hasExtractedRepo(cachePaths.repoDir),
83
76
  refresh: async () => {
84
77
  fs.mkdirSync(cachePaths.rootDir, { recursive: true });
@@ -96,8 +89,8 @@ export async function ensureGitMirror(repo, cachePaths, options) {
96
89
  }
97
90
  /**
98
91
  * Sync mode for a long-lived configured git stash. Mirrors the repo into the
99
- * shared registry-index cache (12h TTL) and exposes the working tree as the
100
- * stash content directory.
92
+ * shared registry-index cache and exposes the working tree as the stash
93
+ * content directory. A mirror that already exists is reused unless `force`.
101
94
  */
102
95
  export async function syncMirroredRepo(config, options) {
103
96
  if (!config.url) {
@@ -17,13 +17,9 @@ export function sanitizeString(value, maxLength = 255) {
17
17
  // biome-ignore lint/suspicious/noControlCharactersInRegex: intentional — strip control chars from untrusted remote data
18
18
  return value.replace(/[\u0000-\u001f\u007f]/g, "").slice(0, maxLength);
19
19
  }
20
- /** Check whether a cached timestamp has exceeded its TTL. */
21
- export function isExpired(mtimeMs, ttlMs) {
22
- return Date.now() - mtimeMs > ttlMs;
23
- }
24
20
  /**
25
21
  * True when ANY built-in adapter's install-time `looksLikeRoot` probe claims
26
- * `root` — the spec §1.2 ordered probe reduced to "is this the root of a bundle
22
+ * `root` — the ordered probe reduced to "is this the root of a bundle
27
23
  * of some format family?". A probe that throws (unreadable dir, race) does not
28
24
  * claim the root.
29
25
  */
@@ -4,8 +4,7 @@
4
4
  /**
5
5
  * robots.txt parsing, matching, and a crawl-scoped fetch/cache policy.
6
6
  *
7
- * Behavioral reference: docs/plans/specs/p1-robots.md (authoritative). This
8
- * module is a clean rewrite against akm's contracts, not a port of any
7
+ * This module is a clean rewrite against akm's contracts, not a port of any
9
8
  * upstream source file.
10
9
  *
11
10
  * Pure by design: no fetching happens here (see `RobotsTxtLoader`/
@@ -14,7 +13,7 @@
14
13
  * `createRobotsPolicy` returns so it dies with the crawl that created it —
15
14
  * a module-level `origin -> RobotsRuleSet` map would leak `disallowAll`
16
15
  * results across crawls and across the test suite's process-wide `bun test`
17
- * run (see spec §6.1). The module-level `WeakMap` below is a different
16
+ * run. The module-level `WeakMap` below is a different
18
17
  * category: it memoizes a pure function of an individual rule object's own
19
18
  * `pattern` field, keyed by that object's identity. It cannot leak meaning
20
19
  * between origins or tests — distinct `parseRobotsTxt` calls (even for
@@ -40,7 +39,7 @@ export const ROBOTS_USER_AGENT_HEADER = "akm-cli website provider";
40
39
  /**
41
40
  * Frozen so a stray mutation (e.g. an accidental `.rules.push(...)` somewhere
42
41
  * that borrows one of these as a starting point) can never poison every other
43
- * crawl sharing this instance (spec §10, Review log 2026-08-01 finding 1).
42
+ * crawl sharing this instance.
44
43
  */
45
44
  const EMPTY_ROBOTS_RULES = Object.freeze([]);
46
45
  export const ALLOW_ALL_RULES = Object.freeze({
@@ -128,8 +127,8 @@ export function parseRobotsTxt(text) {
128
127
  pattern: value,
129
128
  specificity: value.length,
130
129
  };
131
- // Compile once, here, at parse time — not on every URL check (spec
132
- // §6.4, review finding robots.ts:238). See `compiledPatternCache`.
130
+ // Compile once, here, at parse time — not on every URL check. See
131
+ // `compiledPatternCache`.
133
132
  compiledPatternCache.set(rule, compilePatternSegments(value));
134
133
  current.rules.push(rule);
135
134
  continue;
@@ -185,7 +184,7 @@ function isUnreservedByte(byte) {
185
184
  * fallback) and match targets (`isPathAllowedByRobots`), so a percent-encoded
186
185
  * alias of a disallowed path — e.g. a link written as `/%73ecret/` — cannot
187
186
  * bypass `Disallow: /secret/` simply because `URL.pathname` preserves
188
- * %-escapes verbatim. Reserved-octet patterns like spec §4.3 M-31's
187
+ * %-escapes verbatim. Reserved-octet patterns like
189
188
  * `/caf%C3%A9` are untouched on both sides (0xC3/0xA9 are not unreserved),
190
189
  * so they keep matching themselves exactly as before.
191
190
  */
@@ -211,10 +210,10 @@ function compilePatternSegments(pattern) {
211
210
  }
212
211
  /**
213
212
  * Per-rule-object cache of the compiled pattern (see the file-level doc
214
- * comment for why this is not "module-level state" in the sense spec §6.1
215
- * forbids). `parseRobotsTxt` populates this eagerly, once, when it creates
216
- * each `RobotsPathRule` — the compile-once requirement from spec §6.4 /
217
- * review finding robots.ts:238. `compiledPatternFor` below is a defensive
213
+ * comment for why this is not "module-level state" in the sense that comment
214
+ * rules out). `parseRobotsTxt` populates this eagerly, once, when it creates
215
+ * each `RobotsPathRule` — the compile-once requirement.
216
+ * `compiledPatternFor` below is a defensive
218
217
  * fallback for `RobotsRuleSet`s assembled by hand (e.g. test fixtures)
219
218
  * rather than via `parseRobotsTxt`; it still compiles at most once per rule
220
219
  * object, just lazily on first use instead of at parse time.
@@ -324,7 +323,7 @@ export function createRobotsPolicy(load) {
324
323
  const pending = load(robotsUrl).then(outcomeToRuleSet);
325
324
  // A rejected fetch must not poison the cache: the next lookup for this
326
325
  // origin should retry the loader rather than replaying the same failure
327
- // forever (spec §4.4 L-04).
326
+ // forever.
328
327
  pending.catch(() => {
329
328
  if (cache.get(origin) === pending)
330
329
  cache.delete(origin);