akm-cli 0.9.16 → 0.9.17-alpha.10

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 (403) hide show
  1. package/CHANGELOG.md +2101 -0
  2. package/STABILITY.md +11 -10
  3. package/dist/akm +124 -193
  4. package/dist/akm-migrate +38 -19
  5. package/dist/assets/hints/cli-hints-full.md +6 -7
  6. package/dist/assets/improve-strategies/catchup.json +0 -3
  7. package/dist/assets/improve-strategies/consolidate.json +0 -1
  8. package/dist/assets/improve-strategies/default.json +1 -2
  9. package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
  10. package/dist/assets/improve-strategies/quick.json +1 -2
  11. package/dist/assets/improve-strategies/reflect-distill.json +1 -2
  12. package/dist/assets/improve-strategies/thorough.json +0 -3
  13. package/dist/assets/prompts/consolidate-pair.md +20 -0
  14. package/dist/assets/prompts/consolidate-system.md +4 -11
  15. package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
  16. package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
  17. package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
  18. package/dist/assets/templates/html/health.html +3 -5
  19. package/dist/cli/retired-commands.js +1 -1
  20. package/dist/cli/shared.js +6 -2
  21. package/dist/cli/unknown-flags.js +24 -1
  22. package/dist/cli.js +68 -10
  23. package/dist/commands/agent/agent-dispatch.js +1 -1
  24. package/dist/commands/command/command-execution.js +24 -62
  25. package/dist/commands/feedback-cli.js +0 -1
  26. package/dist/commands/health/accept-rate.js +6 -0
  27. package/dist/commands/health/archive-usage.js +92 -0
  28. package/dist/commands/health/checks.js +83 -74
  29. package/dist/commands/health/config-skew.js +38 -0
  30. package/dist/commands/health/data-dir-usage.js +25 -13
  31. package/dist/commands/health/egress.js +54 -0
  32. package/dist/commands/health/html-report.js +1 -42
  33. package/dist/commands/health/improve-metrics.js +136 -591
  34. package/dist/commands/health/md-report.js +1 -6
  35. package/dist/commands/health/plugin-staleness.js +53 -3
  36. package/dist/commands/health/renderers.js +12 -4
  37. package/dist/commands/health/report-view-model.js +14 -120
  38. package/dist/commands/health/types-improve.js +4 -19
  39. package/dist/commands/health/windows.js +64 -74
  40. package/dist/commands/health.js +145 -143
  41. package/dist/commands/improve/consolidate/chunking.js +26 -117
  42. package/dist/commands/improve/consolidate/continuity-check.js +137 -0
  43. package/dist/commands/improve/consolidate/pair-pass.js +791 -0
  44. package/dist/commands/improve/consolidate/sanitize.js +54 -149
  45. package/dist/commands/improve/consolidate.js +589 -1127
  46. package/dist/commands/improve/content-hash.js +16 -24
  47. package/dist/commands/improve/distill/content-repair.js +18 -100
  48. package/dist/commands/improve/distill-guards.js +20 -81
  49. package/dist/commands/improve/distill-promotion-policy.js +23 -243
  50. package/dist/commands/improve/distill.js +608 -1041
  51. package/dist/commands/improve/eligibility.js +126 -390
  52. package/dist/commands/improve/execution.js +8 -10
  53. package/dist/commands/improve/extract-prompt.js +1 -2
  54. package/dist/commands/improve/extract.js +487 -1046
  55. package/dist/commands/improve/feedback-valence.js +0 -25
  56. package/dist/commands/improve/improve-cli.js +75 -169
  57. package/dist/commands/improve/improve-result-file.js +10 -66
  58. package/dist/commands/improve/improve-strategies.js +52 -4
  59. package/dist/commands/improve/improve-usage-report.js +18 -64
  60. package/dist/commands/improve/improve.js +480 -1074
  61. package/dist/commands/improve/ledger.js +119 -0
  62. package/dist/commands/improve/locks.js +2 -8
  63. package/dist/commands/improve/loop-stages.js +415 -1073
  64. package/dist/commands/improve/memory/derived-ref.js +12 -77
  65. package/dist/commands/improve/memory/memory-belief.js +16 -118
  66. package/dist/commands/improve/memory/memory-improve.js +266 -14
  67. package/dist/commands/improve/outcome-loop.js +28 -156
  68. package/dist/commands/improve/planner.js +5 -15
  69. package/dist/commands/improve/preparation.js +779 -2319
  70. package/dist/commands/improve/proactive-maintenance.js +34 -101
  71. package/dist/commands/improve/reflect-noise.js +104 -280
  72. package/dist/commands/improve/reflect.js +642 -1353
  73. package/dist/commands/improve/retrieval-gate.js +127 -0
  74. package/dist/commands/improve/retrieval-scope.js +92 -0
  75. package/dist/commands/improve/salience.js +41 -240
  76. package/dist/commands/improve/session-asset.js +19 -100
  77. package/dist/commands/improve/stage.js +322 -0
  78. package/dist/commands/lint/base-linter.js +37 -15
  79. package/dist/commands/proposal/drain.js +261 -578
  80. package/dist/commands/proposal/proposal-cli.js +19 -20
  81. package/dist/commands/proposal/proposal-types.js +31 -24
  82. package/dist/commands/proposal/proposal.js +38 -8
  83. package/dist/commands/proposal/propose.js +134 -160
  84. package/dist/commands/proposal/repository.js +1097 -1394
  85. package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
  86. package/dist/commands/proposal/validators/proposal-validators.js +1 -1
  87. package/dist/commands/proposal/validators/proposals.js +22 -89
  88. package/dist/commands/read/curate.js +105 -462
  89. package/dist/commands/read/knowledge.js +3 -2
  90. package/dist/commands/read/search-cli.js +16 -33
  91. package/dist/commands/read/search.js +17 -23
  92. package/dist/commands/read/show.js +57 -108
  93. package/dist/commands/sources/bundle-cli.js +25 -2
  94. package/dist/commands/sources/bundle-config-ops.js +4 -0
  95. package/dist/commands/sources/dangerous-env-audit.js +1 -2
  96. package/dist/commands/sources/info.js +127 -29
  97. package/dist/commands/sources/installed-stashes.js +197 -746
  98. package/dist/commands/sources/schema-repair.js +98 -129
  99. package/dist/commands/sources/source-add.js +62 -12
  100. package/dist/commands/sources/source-manage.js +9 -2
  101. package/dist/commands/sources/stash-cli.js +24 -4
  102. package/dist/commands/tasks/explain.js +10 -13
  103. package/dist/commands/tasks/tasks-cli.js +12 -13
  104. package/dist/commands/tasks/tasks.js +350 -936
  105. package/dist/commands/tasks/validate.js +26 -24
  106. package/dist/commands/workflow/plan.js +22 -29
  107. package/dist/commands/workflow-cli.js +4 -4
  108. package/dist/core/adapter/adapters/akm-adapter.js +2 -1
  109. package/dist/core/adapter/adapters/akm-lint.js +2 -3
  110. package/dist/core/adapter/adapters/akm-metadata.js +42 -12
  111. package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
  112. package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
  113. package/dist/core/adapter/execution-source.js +17 -29
  114. package/dist/core/asset/asset-placement.js +4 -13
  115. package/dist/core/asset/frontmatter.js +106 -1
  116. package/dist/core/asset/resolve-ref.js +1 -1
  117. package/dist/core/bundle-id.js +42 -5
  118. package/dist/core/bundle-rename.js +285 -0
  119. package/dist/core/config/config-io.js +1 -2
  120. package/dist/core/config/config-schema.js +9 -34
  121. package/dist/core/config/config-walker.js +1 -1
  122. package/dist/core/config/config.js +184 -111
  123. package/dist/core/config/engine-semantics.js +0 -2
  124. package/dist/core/config/legacy-source-shape-shim.js +38 -9
  125. package/dist/core/config/schema/embedding.js +20 -5
  126. package/dist/core/config/schema/engines.js +5 -0
  127. package/dist/core/config/schema/execution.js +1 -1
  128. package/dist/core/config/schema/experimental.js +1 -1
  129. package/dist/core/config/schema/improve-processes.js +54 -125
  130. package/dist/core/config/schema/improve.js +4 -42
  131. package/dist/core/config/schema/index-config.js +9 -48
  132. package/dist/core/config/schema/scheduler.js +12 -12
  133. package/dist/core/config/schema/search.js +6 -22
  134. package/dist/core/env-secret-ref.js +0 -1
  135. package/dist/core/errors.js +8 -9
  136. package/dist/core/file-change.js +13 -5
  137. package/dist/core/file-lock.js +76 -173
  138. package/dist/core/improve-result.js +35 -7
  139. package/dist/core/improve-types.js +0 -1
  140. package/dist/core/logs-db.js +2 -2
  141. package/dist/core/loopback.js +7 -12
  142. package/dist/core/non-task-input.js +20 -0
  143. package/dist/core/parse.js +13 -16
  144. package/dist/core/paths.js +0 -24
  145. package/dist/core/redaction.js +109 -2
  146. package/dist/core/run-lock.js +2 -5
  147. package/dist/core/spawn-env.js +1 -1
  148. package/dist/core/state/migrations.js +123 -61
  149. package/dist/core/state-db-scope.js +2 -4
  150. package/dist/core/state-db.js +126 -692
  151. package/dist/core/time.js +0 -20
  152. package/dist/core/type-presentation.js +1 -9
  153. package/dist/core/write-source.js +294 -1005
  154. package/dist/execution/input-contract.js +1 -1
  155. package/dist/execution/resolved-request.js +135 -689
  156. package/dist/execution/source.js +63 -257
  157. package/dist/execution/target-ref.js +1 -1
  158. package/dist/indexer/bundle-identity-guard.js +2 -2
  159. package/dist/indexer/db/llm-cache.js +2 -2
  160. package/dist/indexer/ensure-index.js +77 -73
  161. package/dist/indexer/index-rebuild-lock.js +3 -11
  162. package/dist/indexer/index-writer-lock.js +8 -17
  163. package/dist/indexer/index-written-assets.js +141 -154
  164. package/dist/indexer/indexer.js +400 -1124
  165. package/dist/indexer/links/declared-links.js +90 -0
  166. package/dist/indexer/materialize-embeddings.js +60 -397
  167. package/dist/indexer/passes/memory-inference.js +96 -90
  168. package/dist/indexer/passes/metadata.js +132 -219
  169. package/dist/indexer/read-preflight.js +0 -7
  170. package/dist/indexer/scan/doc-to-entry.js +2 -3
  171. package/dist/indexer/scan/drain-dir.js +1 -1
  172. package/dist/indexer/search/db-search.js +190 -590
  173. package/dist/indexer/search/fts-query.js +30 -41
  174. package/dist/indexer/search/ranking.js +28 -154
  175. package/dist/indexer/search/search-attribution.js +12 -32
  176. package/dist/indexer/search/search-fields.js +11 -15
  177. package/dist/indexer/search/search-hit-enrichers.js +54 -85
  178. package/dist/indexer/search/search-source.js +1 -4
  179. package/dist/indexer/usage/usage-events.js +36 -7
  180. package/dist/indexer/walk/walker.js +3 -4
  181. package/dist/integrations/agent/engine-fallback.js +23 -40
  182. package/dist/integrations/agent/engine-resolution.js +93 -183
  183. package/dist/integrations/agent/execution.js +507 -0
  184. package/dist/integrations/agent/model-map.js +28 -156
  185. package/dist/integrations/agent/request-lowering.js +66 -141
  186. package/dist/integrations/agent/runner-dispatch.js +143 -321
  187. package/dist/integrations/agent/runner.js +54 -14
  188. package/dist/integrations/lockfile.js +53 -101
  189. package/dist/llm/client.js +18 -6
  190. package/dist/llm/embedders/deterministic.js +2 -3
  191. package/dist/llm/embedders/profile.js +71 -0
  192. package/dist/llm/embedders/remote.js +11 -17
  193. package/dist/llm/feature-gate.js +0 -8
  194. package/dist/llm/index-passes.js +3 -5
  195. package/dist/llm/memory-infer.js +1 -2
  196. package/dist/llm/structured-call.js +5 -24
  197. package/dist/output/generic-render.js +23 -11
  198. package/dist/output/html-render.js +13 -10
  199. package/dist/output/render-registry.js +3 -32
  200. package/dist/output/shapes/helpers.js +25 -38
  201. package/dist/output/shapes/passthrough.js +1 -9
  202. package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
  203. package/dist/output/text/command-format.js +69 -31
  204. package/dist/output/text/helpers.js +1 -1
  205. package/dist/output/text/migrate.js +5 -14
  206. package/dist/output/text/proposal-format.js +48 -3
  207. package/dist/output/text/show-format.js +13 -17
  208. package/dist/output/text/workflow-format.js +0 -32
  209. package/dist/output/text.js +2 -0
  210. package/dist/registry/factory.js +4 -19
  211. package/dist/registry/network.js +66 -220
  212. package/dist/registry/providers/index.js +0 -2
  213. package/dist/registry/providers/skills-sh.js +3 -14
  214. package/dist/registry/providers/static-index.js +24 -26
  215. package/dist/registry/resolve.js +55 -131
  216. package/dist/scripts/akm-migrate-node.js +42948 -92369
  217. package/dist/scripts/akm-migrate.js +42935 -92354
  218. package/dist/setup/registry-stash-loader.js +4 -13
  219. package/dist/setup/semantic-assets.js +3 -44
  220. package/dist/setup/setup.js +1 -1
  221. package/dist/setup/steps/connection.js +5 -6
  222. package/dist/setup/steps/platforms.js +2 -2
  223. package/dist/setup/steps/tasks.js +25 -15
  224. package/dist/sources/provider-factory.js +17 -18
  225. package/dist/sources/providers/filesystem.js +2 -3
  226. package/dist/sources/providers/git-install.js +7 -1
  227. package/dist/sources/providers/git-provider.js +0 -3
  228. package/dist/sources/providers/git-stash.js +83 -21
  229. package/dist/sources/providers/npm.js +2 -4
  230. package/dist/sources/providers/provider-utils.js +5 -10
  231. package/dist/sources/providers/website.js +0 -2
  232. package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
  233. package/dist/sources/website-url.js +2 -2
  234. package/dist/storage/database.js +9 -35
  235. package/dist/storage/repositories/improve-ledger-repository.js +209 -0
  236. package/dist/storage/repositories/index-connection.js +39 -72
  237. package/dist/storage/repositories/index-entries-repository.js +131 -129
  238. package/dist/storage/repositories/index-entry-mapper.js +1 -2
  239. package/dist/storage/repositories/index-entry-schema.js +101 -268
  240. package/dist/storage/repositories/index-fts-repository.js +86 -256
  241. package/dist/storage/repositories/index-links-repository.js +143 -0
  242. package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
  243. package/dist/storage/repositories/index-meta-repository.js +6 -4
  244. package/dist/storage/repositories/index-schema.js +257 -325
  245. package/dist/storage/repositories/index-utility-repository.js +8 -29
  246. package/dist/storage/repositories/index-vec-repository.js +133 -414
  247. package/dist/storage/repositories/outcome-repository.js +2 -1
  248. package/dist/storage/repositories/proposals-repository.js +104 -1
  249. package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
  250. package/dist/storage/repositories/salience-repository.js +1 -19
  251. package/dist/storage/repositories/task-history-repository.js +26 -4
  252. package/dist/storage/repositories/workflow-runs-repository.js +53 -244
  253. package/dist/storage/sqlite-migrations.js +136 -0
  254. package/dist/storage/sqlite-pragmas.js +11 -9
  255. package/dist/storage/sqlite-transaction.js +170 -0
  256. package/dist/storage/state-db-integrity.js +130 -0
  257. package/dist/tasks/activation-config.js +134 -62
  258. package/dist/tasks/backends/cron.js +191 -302
  259. package/dist/tasks/backends/exec-utils.js +2 -5
  260. package/dist/tasks/backends/launchd.js +141 -748
  261. package/dist/tasks/backends/schtasks.js +119 -623
  262. package/dist/tasks/prepare/prepare-support.js +5 -15
  263. package/dist/tasks/prepare/prepare.js +0 -2
  264. package/dist/tasks/resolve-akm-bin.js +20 -79
  265. package/dist/tasks/run/attempt-lifecycle.js +0 -1
  266. package/dist/tasks/run/load-task.js +1 -1
  267. package/dist/tasks/scheduler-binding.js +20 -238
  268. package/dist/tasks/scheduler-invocation.js +136 -244
  269. package/dist/tasks/scheduler-lock.js +53 -0
  270. package/dist/tasks/scheduler-sync.js +368 -679
  271. package/dist/tasks/source/parse-task-source.js +55 -9
  272. package/dist/tasks/source/task-source-v3-frozen.js +3 -4
  273. package/dist/tasks/source/task-to-v4.js +464 -88
  274. package/dist/workflows/authoring/authoring.js +3 -12
  275. package/dist/workflows/compile.js +211 -0
  276. package/dist/workflows/concurrency-policy.js +13 -74
  277. package/dist/workflows/exec/child-invocation.js +3 -17
  278. package/dist/workflows/exec/child-workflow.js +32 -141
  279. package/dist/workflows/exec/dispatch-redaction.js +13 -53
  280. package/dist/workflows/exec/environment.js +98 -0
  281. package/dist/workflows/exec/exec-unit.js +33 -140
  282. package/dist/workflows/exec/frozen-judge.js +7 -59
  283. package/dist/workflows/exec/native-executor.js +82 -341
  284. package/dist/workflows/exec/param-secrets.js +29 -47
  285. package/dist/workflows/exec/run-workflow.js +154 -387
  286. package/dist/workflows/exec/scheduler.js +9 -36
  287. package/dist/workflows/exec/step-work.js +127 -430
  288. package/dist/workflows/exec/unit-dispatch.js +11 -63
  289. package/dist/workflows/exec/unit-writer.js +8 -52
  290. package/dist/workflows/exec/worktree.js +39 -273
  291. package/dist/workflows/freeze/child-output-references.js +4 -15
  292. package/dist/workflows/freeze/environment.js +99 -92
  293. package/dist/workflows/freeze/freeze.js +172 -0
  294. package/dist/workflows/freeze/step-values.js +19 -21
  295. package/dist/workflows/freeze/targets/child-workflow.js +23 -92
  296. package/dist/workflows/freeze/targets/command.js +10 -33
  297. package/dist/workflows/freeze/targets/script.js +5 -12
  298. package/dist/workflows/freeze/targets/shell.js +3 -6
  299. package/dist/workflows/freeze/targets/task.js +25 -80
  300. package/dist/workflows/freeze/task-bindings.js +20 -67
  301. package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
  302. package/dist/workflows/ir/params.js +6 -51
  303. package/dist/workflows/ir/plan-hash.js +2 -34
  304. package/dist/workflows/parser.js +140 -43
  305. package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
  306. package/dist/workflows/renderer.js +36 -69
  307. package/dist/workflows/resource-limits.js +12 -120
  308. package/dist/workflows/runtime/agent-identity.js +8 -40
  309. package/dist/workflows/runtime/run-outputs.js +3 -6
  310. package/dist/workflows/runtime/run-plan.js +316 -0
  311. package/dist/workflows/runtime/runs.js +48 -200
  312. package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
  313. package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
  314. package/dist/workflows/validate-summary.js +2 -7
  315. package/docs/integration/bundling-akm.md +49 -42
  316. package/docs/migration/README.md +1 -0
  317. package/docs/migration/release-notes/0.9.17.md +43 -0
  318. package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
  319. package/docs/reference/cli.md +232 -135
  320. package/docs/reference/configuration.md +71 -57
  321. package/docs/reference/data-and-telemetry.md +20 -21
  322. package/docs/reference/tasks.md +105 -39
  323. package/docs/reference/workflow-schema.md +14 -18
  324. package/docs/reference/workflows.md +6 -9
  325. package/package.json +1 -1
  326. package/schemas/akm-config.json +115 -738
  327. package/schemas/akm-workflow.json +1 -0
  328. package/dist/assets/improve-strategies/graph-refresh.json +0 -15
  329. package/dist/assets/prompts/contradiction-judge.md +0 -33
  330. package/dist/assets/prompts/graph-extract-system.md +0 -1
  331. package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
  332. package/dist/assets/prompts/metadata-enhance-system.md +0 -1
  333. package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
  334. package/dist/commands/health/advisories.js +0 -150
  335. package/dist/commands/health/metrics.js +0 -329
  336. package/dist/commands/health/surfaces.js +0 -102
  337. package/dist/commands/improve/anti-collapse.js +0 -83
  338. package/dist/commands/improve/collapse-detector.js +0 -432
  339. package/dist/commands/improve/consolidate/eligibility.js +0 -48
  340. package/dist/commands/improve/consolidate/merge.js +0 -149
  341. package/dist/commands/improve/distill/promote-memory.js +0 -291
  342. package/dist/commands/improve/distill/quality-gate.js +0 -337
  343. package/dist/commands/improve/eval-cases.js +0 -52
  344. package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
  345. package/dist/commands/improve/proposal-envelope.js +0 -31
  346. package/dist/commands/improve/run-context.js +0 -123
  347. package/dist/commands/improve/shared.js +0 -31
  348. package/dist/commands/improve/source-identity.js +0 -28
  349. package/dist/commands/improve/triage.js +0 -96
  350. package/dist/commands/proposal/drain-policies.js +0 -151
  351. package/dist/commands/sources/update-transaction.js +0 -220
  352. package/dist/core/action-contributors.js +0 -28
  353. package/dist/core/config/config-version-shim.js +0 -101
  354. package/dist/core/fs-txn.js +0 -405
  355. package/dist/core/lexical-score.js +0 -25
  356. package/dist/core/maintenance-barrier.js +0 -167
  357. package/dist/execution/executable-identity.js +0 -105
  358. package/dist/execution/guarded-source.js +0 -427
  359. package/dist/indexer/db/graph-db.js +0 -444
  360. package/dist/indexer/graph/graph-boost.js +0 -427
  361. package/dist/indexer/graph/graph-dedup.js +0 -95
  362. package/dist/indexer/graph/graph-extraction.js +0 -1108
  363. package/dist/indexer/search/name-match.js +0 -35
  364. package/dist/indexer/search/ranking-contributors.js +0 -515
  365. package/dist/indexer/search/ranking-types.js +0 -4
  366. package/dist/indexer/walk/project-context.js +0 -192
  367. package/dist/integrations/agent/execution-cascade.js +0 -566
  368. package/dist/integrations/agent/execution-definitions.js +0 -202
  369. package/dist/integrations/agent/execution-lowering.js +0 -841
  370. package/dist/integrations/agent/execution-preparation.js +0 -98
  371. package/dist/integrations/agent/inline-execution.js +0 -74
  372. package/dist/llm/graph-extract.js +0 -728
  373. package/dist/llm/metadata-enhance.js +0 -96
  374. package/dist/registry/create-provider-registry.js +0 -29
  375. package/dist/registry/pinned-request-helper.js +0 -247
  376. package/dist/registry/pinned-transport.js +0 -717
  377. package/dist/sources/providers/index.js +0 -14
  378. package/dist/storage/engines/sqlite-migrations.js +0 -271
  379. package/dist/storage/repositories/canaries-repository.js +0 -107
  380. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
  381. package/dist/storage/repositories/registry-cache.js +0 -113
  382. package/dist/tasks/scheduler-sync-preview.js +0 -52
  383. package/dist/tasks/source/task-to-v3.js +0 -507
  384. package/dist/workflows/freeze/resolve-steps.js +0 -86
  385. package/dist/workflows/freeze/source-freeze.js +0 -64
  386. package/dist/workflows/ir/compile.js +0 -321
  387. package/dist/workflows/ir/environment-v4.js +0 -330
  388. package/dist/workflows/ir/freeze-v4.js +0 -153
  389. package/dist/workflows/ir/schema-v4.js +0 -745
  390. package/dist/workflows/ir/schema.js +0 -354
  391. package/dist/workflows/program/schema.js +0 -77
  392. package/dist/workflows/runtime/checkin.js +0 -57
  393. package/dist/workflows/runtime/plan-classifier.js +0 -196
  394. package/dist/workflows/runtime/unit-checkin.js +0 -45
  395. package/dist/workflows/runtime/unit-phases.js +0 -20
  396. package/dist/workflows/schema.js +0 -4
  397. package/dist/workflows/source-ir/compile.js +0 -200
  398. package/dist/workflows/source-ir/program.js +0 -50
  399. package/dist/workflows/source-ir/result.js +0 -26
  400. package/dist/workflows/source-ir/schema.js +0 -786
  401. package/dist/workflows/source-ir/triggers.js +0 -79
  402. package/dist/workflows/source-ir/uses.js +0 -40
  403. package/dist/workflows/validator.js +0 -60
@@ -2,278 +2,49 @@
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
- * The low-level exhaustive dispatch seam for the {@link RunnerSpec} transport
6
- * union (`llm | agent | sdk`). User/model work reaches this function only
7
- * after `ResolvedExecutionRequestV1` preparation and engine-owned lowering;
8
- * `dispatchLoweredExecutionRequest` supplies the direct-LLM handler. A
9
- * prompt-free native launch crosses the explicit payload-free interactive
10
- * lowerer in that same shared layer.
11
- *
12
- * Agent and SDK arms use the shared profile runners. The LLM arm deliberately
13
- * requires a handler because structured callers own their parse/fallback
14
- * contract. The `assertNever` arm keeps a fourth transport kind from becoming
15
- * an implicit fallthrough. Symbolic LLM and SDK-fallback credentials are
16
- * materialized here, at authorized operation-lease acquisition or the final
17
- * single-call boundary, then scrubbed from the result.
5
+ * Run a built execution: the one place credentials are read. A direct LLM
6
+ * goes to `chatCompletion`, an agent engine to `runAgent` (the harness builder
7
+ * turns the request into argv), an SDK engine to `runOpencodeSdk`. Every
8
+ * credential and passthrough value that could reach the child is redacted
9
+ * from the result.
18
10
  */
19
11
  import { assertNever } from "../../core/assert.js";
12
+ import { UsageError } from "../../core/errors.js";
20
13
  import { collectSensitiveValues, isEnvPassthroughValueSafeToExpose, redactSensitiveText, redactSensitiveValue, } from "../../core/redaction.js";
21
- import { spawnEnvNamesFor } from "../../core/spawn-env.js";
22
- import { closeServer as disposeOpencodeSdkServers, opencodeSdkServerEnvironmentNames, runOpencodeSdk, } from "../harnesses/opencode-sdk/sdk-runner.js";
23
- import { lookupApiKeyFileValue, lookupApiKeySecretRefValue, lookupCredentialFromEnv, materializeLlmConnection, materializeLlmConnectionWithCredential, resolveLlmCredentialValue, } from "./engine-resolution.js";
24
- import { materializeLlmRunnerConnection, materializeLlmRunnerConnectionWithCredential, } from "./runner.js";
14
+ import { chatCompletion, LlmCallError } from "../../llm/client.js";
15
+ import { closeServer as disposeOpencodeSdkServers, runOpencodeSdk } from "../harnesses/opencode-sdk/sdk-runner.js";
16
+ import { lookupApiKeyFileValue, lookupApiKeySecretRefValue, lookupCredentialFromEnv, resolveEngine, } from "./engine-resolution.js";
17
+ import { materializeLlmRunnerConnection, materializeSdkFallbackConnection } from "./runner.js";
25
18
  import { runAgent } from "./spawn.js";
26
- const liveRunnerDispatchLeases = new WeakMap();
27
- const issuedRunnerDispatchLeases = new WeakSet();
28
- const disposedRunnerDispatchLeases = new WeakSet();
29
- function credentialBinding(credential) {
30
- return credential ? { names: [...credential.names], required: credential.required } : null;
31
- }
32
- function passthroughBinding(spec) {
33
- return [...new Set(spec.profile.envPassthrough)].sort();
34
- }
35
- function dispatchEnvironmentNames(spec) {
36
- switch (spec.kind) {
37
- case "llm":
38
- return [];
39
- case "agent":
40
- return spawnEnvNamesFor(spec.profile.envPassthrough);
41
- case "sdk":
42
- return opencodeSdkServerEnvironmentNames(spec.profile);
43
- default:
44
- return assertNever(spec);
45
- }
46
- }
47
- function snapshotDispatchEnvironment(spec, envSource) {
48
- const snapshot = new Map();
49
- const read = (name) => {
50
- if (!snapshot.has(name))
51
- snapshot.set(name, envSource[name]);
52
- return snapshot.get(name);
53
- };
54
- const environmentSource = new Proxy(Object.create(null), {
55
- get(_target, property) {
56
- return typeof property === "string" ? snapshot.get(property) : undefined;
57
- },
58
- });
59
- for (const name of dispatchEnvironmentNames(spec))
60
- read(name);
61
- const passthroughSensitiveValues = new Set();
62
- if (spec.kind !== "llm") {
63
- for (const name of new Set(spec.profile.envPassthrough)) {
64
- const value = snapshot.get(name);
65
- if (!isEnvPassthroughValueSafeToExpose(name, value) && value)
66
- passthroughSensitiveValues.add(value);
67
- }
19
+ const OPERATIONAL_OPTIONS = [
20
+ "stdio",
21
+ "parseOutput",
22
+ "signal",
23
+ "envSource",
24
+ "spawn",
25
+ "setTimeoutFn",
26
+ "clearTimeoutFn",
27
+ "onEvent",
28
+ ];
29
+ /** Every value that can reach one dispatch and must never be echoed back: credentials and secret-looking env. */
30
+ export function collectDispatchSensitiveValues(runner, opts, envSource = opts.envSource ?? process.env) {
31
+ const values = [];
32
+ if (runner.kind === "llm") {
33
+ values.push(runner.connection.apiKey, lookupCredentialFromEnv(runner.credential, envSource), runner.apiKeyFile ? lookupApiKeyFileValue(runner.apiKeyFile) : undefined, runner.apiKeySecretRef ? lookupApiKeySecretRefValue(runner.apiKeySecretRef) : undefined);
68
34
  }
69
- return { environmentSnapshot: snapshot, environmentSource, passthroughSensitiveValues, read };
70
- }
71
- /** Bind only transport identity; request model/inference/schema/timeout remain per-call. */
72
- function runnerLeaseBinding(spec) {
73
- switch (spec.kind) {
74
- case "llm":
75
- return JSON.stringify({
76
- kind: spec.kind,
77
- engine: spec.engine ?? null,
78
- endpoint: spec.connection.endpoint,
79
- provider: spec.connection.provider ?? null,
80
- credential: credentialBinding(spec.credential),
81
- apiKeyFile: spec.apiKeyFile ?? null,
82
- });
83
- case "agent":
84
- return JSON.stringify({
85
- kind: spec.kind,
86
- engine: spec.engine ?? null,
87
- platform: spec.profile.platform ?? null,
88
- name: spec.profile.name,
89
- bin: spec.profile.bin,
90
- envPassthrough: passthroughBinding(spec),
91
- });
92
- case "sdk":
93
- return JSON.stringify({
94
- kind: spec.kind,
95
- engine: spec.engine ?? null,
96
- platform: spec.profile.platform ?? null,
97
- name: spec.profile.name,
98
- bin: spec.profile.bin,
99
- envPassthrough: passthroughBinding(spec),
100
- fallbackEndpoint: spec.fallbackConnection?.endpoint ?? null,
101
- fallbackProvider: spec.fallbackConnection?.provider ?? null,
102
- fallbackCredential: credentialBinding(spec.fallbackCredential),
103
- fallbackApiKeyFile: spec.fallbackApiKeyFile ?? null,
104
- });
105
- default:
106
- return assertNever(spec);
107
- }
108
- }
109
- function requireRunnerDispatchLease(lease, spec) {
110
- if (typeof lease !== "object" || lease === null)
111
- throw new TypeError("invalid dispatch lease");
112
- const state = liveRunnerDispatchLeases.get(lease);
113
- if (!state) {
114
- if (issuedRunnerDispatchLeases.has(lease) && disposedRunnerDispatchLeases.has(lease)) {
115
- throw new TypeError("dispatch lease is disposed");
35
+ else {
36
+ if (runner.kind === "sdk") {
37
+ values.push(runner.fallbackConnection?.apiKey, lookupCredentialFromEnv(runner.fallbackCredential, envSource), runner.fallbackApiKeyFile ? lookupApiKeyFileValue(runner.fallbackApiKeyFile) : undefined, runner.fallbackApiKeySecretRef ? lookupApiKeySecretRefValue(runner.fallbackApiKeySecretRef) : undefined);
116
38
  }
117
- throw new TypeError("invalid dispatch lease");
118
- }
119
- if (spec && state.binding !== runnerLeaseBinding(spec)) {
120
- throw new TypeError("dispatch lease does not match the lowered runner transport");
121
- }
122
- return state;
123
- }
124
- /** @internal Verify provenance, liveness, and transport binding without exposing state. */
125
- export function assertRunnerDispatchLease(lease, spec) {
126
- requireRunnerDispatchLease(lease, spec);
127
- }
128
- /** @internal Acquire only through execution-lowering after authorization/provenance validation. */
129
- export function acquireRunnerDispatchLease(spec, envSource = process.env) {
130
- const environment = snapshotDispatchEnvironment(spec, envSource);
131
- const credentialSource = new Proxy(Object.create(null), {
132
- get(_target, property) {
133
- return typeof property === "string" ? environment.read(property) : undefined;
134
- },
135
- });
136
- const primaryCredential = spec.kind === "llm"
137
- ? resolveLlmCredentialValue(spec.engine, spec.credential, spec.apiKeyFile, spec.apiKeySecretRef, credentialSource)
138
- : undefined;
139
- const fallbackCredential = spec.kind === "sdk"
140
- ? resolveLlmCredentialValue(spec.engine, spec.fallbackCredential, spec.fallbackApiKeyFile, spec.fallbackApiKeySecretRef, credentialSource)
141
- : undefined;
142
- const handle = Object.create(null);
143
- Object.defineProperty(handle, "toJSON", {
144
- configurable: false,
145
- enumerable: false,
146
- writable: false,
147
- value: () => {
148
- throw new TypeError("dispatch lease is not serializable");
149
- },
150
- });
151
- Object.freeze(handle);
152
- const sensitiveValues = collectSensitiveValues([
153
- primaryCredential,
154
- fallbackCredential,
155
- ...environment.passthroughSensitiveValues,
156
- ]);
157
- liveRunnerDispatchLeases.set(handle, {
158
- binding: runnerLeaseBinding(spec),
159
- primaryCredential,
160
- fallbackCredential,
161
- environmentSnapshot: environment.environmentSnapshot,
162
- environmentSource: environment.environmentSource,
163
- sensitiveValues,
164
- });
165
- issuedRunnerDispatchLeases.add(handle);
166
- return handle;
167
- }
168
- /** @internal Scrub private material and invalidate one issued handle. */
169
- export function disposeRunnerDispatchLease(lease) {
170
- if (typeof lease !== "object" || lease === null || !issuedRunnerDispatchLeases.has(lease)) {
171
- throw new TypeError("invalid dispatch lease");
172
- }
173
- const state = liveRunnerDispatchLeases.get(lease);
174
- if (!state)
175
- return;
176
- state.primaryCredential = undefined;
177
- state.fallbackCredential = undefined;
178
- state.environmentSnapshot.clear();
179
- state.sensitiveValues.fill("");
180
- state.sensitiveValues = [];
181
- liveRunnerDispatchLeases.delete(lease);
182
- disposedRunnerDispatchLeases.add(lease);
183
- }
184
- /** @internal Redact with private credential material without exposing its values. */
185
- export function redactWithRunnerDispatchLease(lease, value) {
186
- return redactSensitiveText(value, requireRunnerDispatchLease(lease).sensitiveValues);
187
- }
188
- /**
189
- * Release every long-lived resource the dispatch runners CACHE for reuse, so a
190
- * one-shot process (the CLI) can exit cleanly once dispatching is done.
191
- *
192
- * The `sdk` runner keeps a per-material registry of `opencode serve` CHILD
193
- * PROCESSES (see `opencode-sdk/sdk-runner.ts`), started lazily and reused
194
- * across units within a process. Each live child is an OS handle that keeps
195
- * Bun's event loop open — and the registry's own teardown is wired ONLY to
196
- * `process.once('exit')`, which never fires while such a child holds the loop
197
- * open. That is a deadlock: a successful `akm workflow run` that dispatched via
198
- * the SDK path would hang the CLI (owner finding 4) because the process is
199
- * never idle enough for the exit hook to run and close the children it is
200
- * waiting on.
201
- *
202
- * The CLI composition root and workflow engine call this in `finally` blocks to
203
- * drain the registry deterministically before relying on the event loop. Started
204
- * servers close synchronously; in-flight starts are awaited and closed on
205
- * arrival. When no SDK server was started this is an idempotent no-op.
206
- */
207
- export async function disposeDispatchResources() {
208
- await disposeOpencodeSdkServers();
209
- }
210
- /** Collect every materialized value that can reach one runner dispatch. */
211
- export function collectDispatchSensitiveValues(spec, opts, envSource = opts.envSource ?? process.env) {
212
- const values = new Set();
213
- const add = (value) => {
214
- if (value !== undefined && value.length > 0)
215
- values.add(value);
216
- };
217
- const addConnection = (connection) => add(connection?.apiKey);
218
- if (spec.kind === "llm")
219
- addConnection(spec.connection);
220
- if (spec.kind === "sdk")
221
- addConnection(spec.fallbackConnection);
222
- if (spec.kind === "llm")
223
- add(lookupCredentialFromEnv(spec.credential, envSource));
224
- if (spec.kind === "sdk")
225
- add(lookupCredentialFromEnv(spec.fallbackCredential, envSource));
226
- // #905: a file-backed credential is read at dispatch, so it must be in the
227
- // scrub set for the same reason the env-backed one is.
228
- if (spec.kind === "llm" && spec.apiKeyFile)
229
- add(lookupApiKeyFileValue(spec.apiKeyFile));
230
- if (spec.kind === "sdk" && spec.fallbackApiKeyFile)
231
- add(lookupApiKeyFileValue(spec.fallbackApiKeyFile));
232
- // #953: a secret-store-backed credential is read at dispatch too — same
233
- // best-effort scrub-set inclusion rationale.
234
- if (spec.kind === "llm" && spec.apiKeySecretRef)
235
- add(lookupApiKeySecretRefValue(spec.apiKeySecretRef));
236
- if (spec.kind === "sdk" && spec.fallbackApiKeySecretRef)
237
- add(lookupApiKeySecretRefValue(spec.fallbackApiKeySecretRef));
238
- if (spec.kind !== "llm") {
239
- for (const value of Object.values(spec.profile.env ?? {}))
240
- add(value);
241
- for (const name of spec.profile.envPassthrough) {
242
- const value = envSource[name];
243
- if (!isEnvPassthroughValueSafeToExpose(name, value))
244
- add(value);
39
+ values.push(...Object.values(runner.profile.env ?? {}));
40
+ for (const name of runner.profile.envPassthrough) {
41
+ if (!isEnvPassthroughValueSafeToExpose(name, envSource[name]))
42
+ values.push(envSource[name]);
245
43
  }
246
44
  }
247
45
  for (const [name, value] of Object.entries(opts.env ?? {})) {
248
46
  if (!isEnvPassthroughValueSafeToExpose(name, value))
249
- add(value);
250
- }
251
- return collectSensitiveValues(values);
252
- }
253
- function collectNonCredentialDispatchSensitiveValues(spec, opts, envSource = opts.envSource ?? process.env, includeProfilePassthrough = true) {
254
- const values = new Set();
255
- const add = (value) => {
256
- if (value !== undefined && value.length > 0)
257
- values.add(value);
258
- };
259
- if (spec.kind === "llm")
260
- add(spec.connection.apiKey);
261
- if (spec.kind === "sdk")
262
- add(spec.fallbackConnection?.apiKey);
263
- if (spec.kind !== "llm") {
264
- for (const value of Object.values(spec.profile.env ?? {}))
265
- add(value);
266
- if (includeProfilePassthrough) {
267
- for (const name of spec.profile.envPassthrough) {
268
- const value = envSource[name];
269
- if (!isEnvPassthroughValueSafeToExpose(name, value))
270
- add(value);
271
- }
272
- }
273
- }
274
- for (const [name, value] of Object.entries(opts.env ?? {})) {
275
- if (!isEnvPassthroughValueSafeToExpose(name, value))
276
- add(value);
47
+ values.push(value);
277
48
  }
278
49
  return collectSensitiveValues(values);
279
50
  }
@@ -286,75 +57,126 @@ function redactResult(result, sensitiveValues) {
286
57
  ...(result.parsed !== undefined ? { parsed: redactSensitiveValue(result.parsed, sensitiveValues) } : {}),
287
58
  };
288
59
  }
289
- /**
290
- * Dispatch a {@link RunnerSpec} to its runner and return the raw
291
- * {@link AgentRunResult}. `opts` is the {@link RunAgentOptions} for the profile
292
- * (`agent` / `sdk`) arms. Callers keep their per-call options; a bound lease
293
- * replaces only `envSource` with its private immutable environment snapshot.
294
- */
295
- export async function executeRunner(spec, prompt, opts, seams = {}, lease) {
296
- const withSpecOptions = (timeoutMs, workspace, environmentSource) => ({
297
- ...opts,
298
- ...(Object.hasOwn(opts, "timeoutMs") ? {} : timeoutMs !== undefined ? { timeoutMs } : {}),
299
- ...(opts.cwd === undefined && workspace ? { cwd: workspace } : {}),
300
- ...(environmentSource ? { envSource: environmentSource } : {}),
301
- });
60
+ function llmFailureReason(error) {
61
+ if (!(error instanceof LlmCallError))
62
+ return "spawn_failed";
63
+ switch (error.code) {
64
+ case "aborted":
65
+ return "aborted";
66
+ case "timeout":
67
+ return "timeout";
68
+ case "rate_limited":
69
+ return "llm_rate_limit";
70
+ case "parse_error":
71
+ case "provider_html_error":
72
+ return "parse_error";
73
+ default:
74
+ return "spawn_failed";
75
+ }
76
+ }
77
+ async function dispatchRunner(runner, prompt, opts, seams, llm) {
78
+ const envSource = opts.envSource ?? process.env;
79
+ const secrets = collectDispatchSensitiveValues(runner, opts, envSource);
302
80
  let result;
303
- const dispatchSensitiveValues = [];
304
- const leaseState = lease ? requireRunnerDispatchLease(lease, spec) : undefined;
305
- const preDispatchSensitiveValues = leaseState
306
- ? collectSensitiveValues([
307
- ...leaseState.sensitiveValues,
308
- ...collectNonCredentialDispatchSensitiveValues(spec, opts, undefined, false),
309
- ])
310
- : collectDispatchSensitiveValues(spec, opts);
311
- switch (spec.kind) {
81
+ switch (runner.kind) {
312
82
  case "llm": {
313
- if (!seams.llm) {
314
- throw new Error("executeRunner: an `llm` runner requires a `seams.llm` handler (no default LLM dispatch).");
315
- }
316
- const connection = leaseState
317
- ? materializeLlmRunnerConnectionWithCredential(spec, leaseState.primaryCredential)
318
- : materializeLlmRunnerConnection(spec);
83
+ if (!llm)
84
+ throw new Error("an llm runner dispatches only a built execution's chat messages");
85
+ const connection = materializeLlmRunnerConnection(runner, envSource);
319
86
  if (connection.apiKey)
320
- dispatchSensitiveValues.push(connection.apiKey);
321
- result = await seams.llm({ ...spec, connection }, prompt, withSpecOptions(spec.timeoutMs));
87
+ secrets.push(connection.apiKey);
88
+ result = await llm(connection, opts);
322
89
  break;
323
90
  }
324
- case "agent": {
325
- const run = seams.runAgent ?? runAgent;
326
- result = await run(spec.profile, prompt, withSpecOptions(spec.timeoutMs, spec.profile.workspace, leaseState?.environmentSource));
91
+ case "agent":
92
+ result = await (seams.runAgent ?? runAgent)(runner.profile, prompt, opts);
327
93
  break;
328
- }
329
94
  case "sdk": {
330
- const run = seams.runSdk ?? runOpencodeSdk;
331
- const fallbackMaterial = spec.fallbackConnection
332
- ? {
333
- engine: spec.engine ?? "unnamed-sdk-fallback",
334
- connection: spec.fallbackConnection,
335
- ...(spec.fallbackCredential ? { credential: spec.fallbackCredential } : {}),
336
- ...(spec.fallbackApiKeyFile ? { apiKeyFile: spec.fallbackApiKeyFile } : {}),
337
- timeoutMs: spec.fallbackTimeoutMs !== undefined
338
- ? spec.fallbackTimeoutMs
339
- : Object.hasOwn(spec.fallbackConnection, "timeoutMs")
340
- ? (spec.fallbackConnection.timeoutMs ?? null)
341
- : null,
342
- }
343
- : undefined;
344
- const fallbackConnection = fallbackMaterial
345
- ? leaseState
346
- ? materializeLlmConnectionWithCredential(fallbackMaterial, leaseState.fallbackCredential)
347
- : materializeLlmConnection(fallbackMaterial)
348
- : undefined;
95
+ const fallbackConnection = materializeSdkFallbackConnection(runner, envSource);
349
96
  if (fallbackConnection?.apiKey)
350
- dispatchSensitiveValues.push(fallbackConnection.apiKey);
351
- result = await run(spec.profile, prompt, withSpecOptions(spec.timeoutMs, spec.profile.workspace, leaseState?.environmentSource), fallbackConnection);
97
+ secrets.push(fallbackConnection.apiKey);
98
+ result = await (seams.runSdk ?? runOpencodeSdk)(runner.profile, prompt, opts, fallbackConnection);
352
99
  break;
353
100
  }
354
101
  default:
355
- // Exhaustiveness arm: a 4th RunnerSpec kind becomes a compile error here.
356
- return assertNever(spec);
102
+ return assertNever(runner);
103
+ }
104
+ return redactResult(result, collectSensitiveValues(secrets));
105
+ }
106
+ /** Run a built execution. Credentials are read here, once per call, and never returned. */
107
+ export async function runExecution(execution, options = {}) {
108
+ const opts = { ...execution.options };
109
+ const operational = options.runOptions ?? {};
110
+ for (const key of OPERATIONAL_OPTIONS) {
111
+ if (operational[key] !== undefined)
112
+ opts[key] = operational[key];
113
+ }
114
+ if (options.eventSource !== undefined) {
115
+ opts.env = { ...execution.options.env, AKM_EVENT_SOURCE: options.eventSource };
357
116
  }
358
- const sensitiveValues = collectSensitiveValues([...preDispatchSensitiveValues, ...dispatchSensitiveValues]);
359
- return redactResult(result, sensitiveValues);
117
+ const chat = options.chat ?? chatCompletion;
118
+ const llm = async (connection, callOpts) => {
119
+ const started = Date.now();
120
+ try {
121
+ const stdout = await chat(connection, [...(execution.messages ?? [])], {
122
+ ...execution.chatOptions,
123
+ ...(Object.hasOwn(callOpts, "timeoutMs") ? { timeoutMs: callOpts.timeoutMs } : {}),
124
+ ...(callOpts.signal ? { signal: callOpts.signal } : {}),
125
+ ...(options.onRetryAttempt ? { onRetryAttempt: options.onRetryAttempt } : {}),
126
+ });
127
+ return { ok: true, exitCode: 0, stdout, stderr: "", durationMs: Date.now() - started };
128
+ }
129
+ catch (error) {
130
+ // Returned rather than thrown so the redaction below covers provider bodies.
131
+ return {
132
+ ok: false,
133
+ exitCode: null,
134
+ stdout: "",
135
+ stderr: "",
136
+ durationMs: Date.now() - started,
137
+ error: error instanceof Error ? error.message : String(error),
138
+ reason: llmFailureReason(error),
139
+ ...(error instanceof LlmCallError ? { llmErrorCode: error.code } : {}),
140
+ };
141
+ }
142
+ };
143
+ return dispatchRunner(execution.runner, execution.prompt, opts, options, llm);
144
+ }
145
+ /** `akm agent`: launch an agent engine interactively, with no prompt of its own. */
146
+ export async function executeInteractiveAgentInvocation(input, seams = {}) {
147
+ const runner = resolveEngine(input.engine, input.config);
148
+ if (runner.kind === "llm") {
149
+ throw new UsageError(`Engine "${input.engine}" is an LLM engine; akm agent requires an agent engine.`, "INVALID_FLAG_VALUE");
150
+ }
151
+ const opts = {
152
+ stdio: runner.kind === "sdk" ? runner.profile.stdio : "interactive",
153
+ parseOutput: "text",
154
+ ...(input.timeoutMs !== undefined
155
+ ? { timeoutMs: input.timeoutMs }
156
+ : runner.timeoutMs !== undefined
157
+ ? { timeoutMs: runner.timeoutMs }
158
+ : {}),
159
+ ...(input.cwd ? { cwd: input.cwd } : runner.profile.workspace ? { cwd: runner.profile.workspace } : {}),
160
+ };
161
+ return { engine: input.engine, result: await dispatchRunner(runner, "", opts, seams) };
162
+ }
163
+ /**
164
+ * Close the `opencode serve` children the SDK runner keeps for reuse. Its own
165
+ * teardown hangs off `process.once("exit")`, which never fires while a child
166
+ * holds the event loop open, so the CLI and workflow engine call this in
167
+ * `finally` blocks. A no-op when no SDK server was started.
168
+ */
169
+ export async function disposeDispatchResources() {
170
+ await disposeOpencodeSdkServers();
171
+ }
172
+ /**
173
+ * Fail fast, before an operation makes any durable change, when `runner`'s
174
+ * required credential is missing. Reads it and keeps nothing: every dispatch
175
+ * reads it again.
176
+ */
177
+ export function assertRunnerCredentials(runner, envSource) {
178
+ if (runner.kind === "llm")
179
+ materializeLlmRunnerConnection(runner, envSource);
180
+ if (runner.kind === "sdk")
181
+ materializeSdkFallbackConnection(runner, envSource);
360
182
  }
@@ -1,28 +1,68 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
- import { materializeLlmConnection, materializeLlmConnectionWithCredential, } from "./engine-resolution.js";
5
- /** Resolve the current credential value for one frozen LLM runner at dispatch. */
6
- export function materializeLlmRunnerConnection(runner) {
7
- return materializeLlmConnection({
4
+ import { materializeLlmConnection } from "./engine-resolution.js";
5
+ /** The symbolic LLM use behind one llm runner; nothing is read here. */
6
+ export function llmUseFromRunner(runner) {
7
+ return {
8
8
  engine: runner.engine,
9
9
  connection: runner.connection,
10
10
  ...(runner.credential ? { credential: runner.credential } : {}),
11
11
  ...(runner.apiKeyFile ? { apiKeyFile: runner.apiKeyFile } : {}),
12
12
  ...(runner.apiKeySecretRef ? { apiKeySecretRef: runner.apiKeySecretRef } : {}),
13
13
  timeoutMs: runner.timeoutMs ?? null,
14
- });
14
+ };
15
15
  }
16
- /** Inject an already-snapshotted credential without consulting live process state. */
17
- export function materializeLlmRunnerConnectionWithCredential(runner, credentialValue) {
18
- return materializeLlmConnectionWithCredential({
16
+ /** The symbolic LLM use behind an sdk runner's provider fallback, when it has one. */
17
+ export function sdkFallbackUseFromRunner(runner) {
18
+ if (!runner.fallbackConnection)
19
+ return undefined;
20
+ return {
19
21
  engine: runner.engine,
20
- connection: runner.connection,
21
- ...(runner.credential ? { credential: runner.credential } : {}),
22
- ...(runner.apiKeyFile ? { apiKeyFile: runner.apiKeyFile } : {}),
23
- ...(runner.apiKeySecretRef ? { apiKeySecretRef: runner.apiKeySecretRef } : {}),
24
- timeoutMs: runner.timeoutMs ?? null,
25
- }, credentialValue);
22
+ connection: runner.fallbackConnection,
23
+ ...(runner.fallbackCredential ? { credential: runner.fallbackCredential } : {}),
24
+ ...(runner.fallbackApiKeyFile ? { apiKeyFile: runner.fallbackApiKeyFile } : {}),
25
+ ...(runner.fallbackApiKeySecretRef ? { apiKeySecretRef: runner.fallbackApiKeySecretRef } : {}),
26
+ timeoutMs: runner.fallbackTimeoutMs !== undefined ? runner.fallbackTimeoutMs : (runner.fallbackConnection.timeoutMs ?? null),
27
+ };
28
+ }
29
+ /** Read the current credential and inject it: the dispatch boundary for one llm runner. */
30
+ export function materializeLlmRunnerConnection(runner, envSource = process.env) {
31
+ return materializeLlmConnection(llmUseFromRunner(runner), envSource);
32
+ }
33
+ /** The same for an sdk runner's provider fallback, when it has one. */
34
+ export function materializeSdkFallbackConnection(runner, envSource = process.env) {
35
+ const use = sdkFallbackUseFromRunner(runner);
36
+ return use ? materializeLlmConnection(use, envSource) : undefined;
37
+ }
38
+ function isRecord(value) {
39
+ return value !== null && typeof value === "object" && !Array.isArray(value);
40
+ }
41
+ /**
42
+ * Read a journaled runner back. Tolerant: unknown keys are kept and missing
43
+ * profile defaults are filled in; only a shape nothing could dispatch is refused.
44
+ */
45
+ export function decodeFrozenRunnerSpec(value) {
46
+ if (!isRecord(value) || typeof value.engine !== "string") {
47
+ throw new TypeError("a frozen runner must be an object with an engine name");
48
+ }
49
+ if (value.kind === "llm") {
50
+ if (!isRecord(value.connection) || typeof value.connection.endpoint !== "string") {
51
+ throw new TypeError("a frozen llm runner must carry connection.endpoint");
52
+ }
53
+ return value;
54
+ }
55
+ if (value.kind !== "agent" && value.kind !== "sdk") {
56
+ throw new TypeError("a frozen runner's kind must be llm, agent, or sdk");
57
+ }
58
+ const profile = value.profile;
59
+ if (!isRecord(profile) || typeof profile.name !== "string" || typeof profile.bin !== "string") {
60
+ throw new TypeError("a frozen agent runner must carry profile.name and profile.bin");
61
+ }
62
+ return {
63
+ ...value,
64
+ profile: { args: [], envPassthrough: [], stdio: "captured", parseOutput: "text", ...profile },
65
+ };
26
66
  }
27
67
  export function runnerIsLlm(runner) {
28
68
  return runner.kind === "llm";