@oisincoveney/pipeline 3.24.2 → 4.0.0

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 (382) hide show
  1. package/README.md +14 -2
  2. package/defaults/pipeline.yaml +23 -5
  3. package/defaults/profiles.yaml +104 -21
  4. package/dist/argo-graph.js +90 -88
  5. package/dist/argo-submit.d.ts +110 -138
  6. package/dist/argo-submit.js +363 -378
  7. package/dist/argo-workflow.d.ts +156 -177
  8. package/dist/argo-workflow.js +96 -138
  9. package/dist/backlog.js +5 -4
  10. package/dist/bench/eval-report.js +21 -12
  11. package/dist/claude-settings-config.js +23 -31
  12. package/dist/claude-user-config.js +6 -16
  13. package/dist/cli/bootstrap-commands.js +3 -3
  14. package/dist/cli/doctor.d.ts +1 -1
  15. package/dist/cli/doctor.js +176 -171
  16. package/dist/cli/factory-commands.js +13 -13
  17. package/dist/cli/format.js +92 -86
  18. package/dist/cli/loop-commands.js +21 -21
  19. package/dist/cli/mcp-gateway-commands.js +12 -12
  20. package/dist/cli/plan-commands.js +85 -116
  21. package/dist/cli/program.d.ts +3 -3
  22. package/dist/cli/program.js +41 -43
  23. package/dist/cli/run-command.d.ts +1 -1
  24. package/dist/cli/run-command.js +25 -25
  25. package/dist/cli/run-commands.js +31 -29
  26. package/dist/cli/run-resolver.d.ts +1 -1
  27. package/dist/cli/run-resolver.js +30 -32
  28. package/dist/cli/run-service.d.ts +2 -3
  29. package/dist/cli/run-service.js +229 -239
  30. package/dist/cli/submit-options.js +85 -83
  31. package/dist/cluster-doctor.js +147 -175
  32. package/dist/codex-config.js +24 -30
  33. package/dist/commands/bench-command.js +9 -7
  34. package/dist/commands/coordinator-command.js +35 -0
  35. package/dist/commands/pipeline-command.js +13 -7
  36. package/dist/commands/runner-command-command.js +39 -24
  37. package/dist/commands/runner-node-command.js +31 -0
  38. package/dist/commands/ticket/complete.js +29 -33
  39. package/dist/commands/ticket/create.js +84 -82
  40. package/dist/commands/ticket/graph-check.js +11 -11
  41. package/dist/commands/ticket/next.js +36 -36
  42. package/dist/commands/ticket/sequence.js +11 -12
  43. package/dist/commands/ticket/shared.d.ts +5 -2
  44. package/dist/commands/ticket/shared.js +63 -66
  45. package/dist/commands/ticket/start.js +58 -67
  46. package/dist/commands/ticket-command.js +2 -2
  47. package/dist/config/defaults.d.ts +139 -140
  48. package/dist/config/defaults.js +81 -80
  49. package/dist/config/lint.js +52 -64
  50. package/dist/config/load.d.ts +4 -5
  51. package/dist/config/load.js +64 -74
  52. package/dist/config/schema/catalog.d.ts +2 -1
  53. package/dist/config/schema/catalog.js +3 -2
  54. package/dist/config/schema/mcp.js +46 -52
  55. package/dist/config/schemas.d.ts +382 -528
  56. package/dist/config/schemas.js +400 -398
  57. package/dist/config/validate.d.ts +1 -2
  58. package/dist/config/validate.js +236 -201
  59. package/dist/config.d.ts +2 -2
  60. package/dist/context/repo-map.js +105 -119
  61. package/dist/coordinator/composition.js +169 -0
  62. package/dist/coordinator/config.js +71 -0
  63. package/dist/coordinator/run-owner.js +64 -0
  64. package/dist/coordinator/wave-advance.js +148 -0
  65. package/dist/coordinator/wave-scheduler.js +50 -0
  66. package/dist/credentials/broker.d.ts +6 -8
  67. package/dist/credentials/broker.js +17 -16
  68. package/dist/credentials/codex-config.js +15 -19
  69. package/dist/credentials/file-targets.js +9 -15
  70. package/dist/credentials/local-codex-auth-sync.js +55 -58
  71. package/dist/credentials/opencode-config.js +28 -32
  72. package/dist/credentials/runner.js +13 -13
  73. package/dist/effect-sync-errors.js +28 -0
  74. package/dist/factory/create-experiment.js +285 -121
  75. package/dist/factory/exec.js +10 -12
  76. package/dist/factory/git-credentials.js +4 -4
  77. package/dist/factory/stamp-answers.js +10 -11
  78. package/dist/factory/template-update.js +65 -44
  79. package/dist/factory-lane.d.ts +26 -40
  80. package/dist/factory-lane.js +26 -25
  81. package/dist/gates.js +3 -3
  82. package/dist/git-remote-url.js +17 -19
  83. package/dist/hooks.d.ts +26 -26
  84. package/dist/hooks.js +20 -22
  85. package/dist/index.d.ts +4 -3
  86. package/dist/index.js +27 -36
  87. package/dist/install-commands/claude-code.js +100 -92
  88. package/dist/install-commands/host-selection.js +3 -6
  89. package/dist/install-commands/opencode.js +264 -259
  90. package/dist/install-commands/planner.js +163 -181
  91. package/dist/install-commands/result-format.js +1 -3
  92. package/dist/install-commands/shared.js +25 -42
  93. package/dist/install-commands/writer.js +22 -25
  94. package/dist/install-commands.js +8 -8
  95. package/dist/jscpd-output.js +29 -0
  96. package/dist/json-config-merge.js +14 -20
  97. package/dist/json-line-values.js +17 -6
  98. package/dist/loop/argo-poll.d.ts +0 -1
  99. package/dist/loop/argo-poll.js +15 -95
  100. package/dist/loop/backlog-records.js +1 -3
  101. package/dist/loop/controller-deps.js +150 -161
  102. package/dist/loop/controller.js +164 -186
  103. package/dist/loop/gh-checks.js +62 -61
  104. package/dist/loop/gh-runner.js +22 -25
  105. package/dist/loop/loop-command.js +66 -58
  106. package/dist/loop/loop-controller-entrypoint.js +29 -30
  107. package/dist/loop/merge.js +36 -40
  108. package/dist/loop/run-terminal-poll.js +69 -0
  109. package/dist/mcp/gateway-config.js +25 -29
  110. package/dist/mcp/gateway-doctor.js +77 -119
  111. package/dist/mcp/gateway-reconcile.js +17 -22
  112. package/dist/mcp/gateway-runtime.js +1 -3
  113. package/dist/mcp/host-config.js +37 -40
  114. package/dist/mcp/host-renderers.js +10 -18
  115. package/dist/mcp/repo-local-backends.js +51 -54
  116. package/dist/mcp/toolhive-vmcp.js +39 -39
  117. package/dist/model-resolver.js +29 -33
  118. package/dist/moka-global-config.d.ts +78 -55
  119. package/dist/moka-global-config.js +93 -92
  120. package/dist/moka-submit.d.ts +2179 -866
  121. package/dist/moka-submit.js +97 -99
  122. package/dist/opencode-project-config.js +34 -40
  123. package/dist/package-assets.js +1 -3
  124. package/dist/path-refs.js +2 -2
  125. package/dist/pipeline-init.js +25 -25
  126. package/dist/pipeline-runtime.d.ts +15 -14
  127. package/dist/pipeline-runtime.js +51 -50
  128. package/dist/planned-node.js +6 -3
  129. package/dist/planning/compile.d.ts +5 -5
  130. package/dist/planning/compile.js +140 -139
  131. package/dist/planning/dependency-refs.js +5 -5
  132. package/dist/planning/generate.d.ts +1296 -1296
  133. package/dist/planning/generate.js +307 -314
  134. package/dist/planning/graph.d.ts +0 -1
  135. package/dist/planning/graph.js +131 -149
  136. package/dist/remote/argo/model.d.ts +104 -122
  137. package/dist/remote/argo/model.js +205 -197
  138. package/dist/remote/argo/policy.js +39 -47
  139. package/dist/remote/argo/storage.js +81 -85
  140. package/dist/remote/jobs/execution-identity.js +70 -0
  141. package/dist/remote/jobs/job-outcome.js +108 -0
  142. package/dist/remote/jobs/manifest.js +96 -0
  143. package/dist/remote/jobs/model.d.ts +158 -0
  144. package/dist/remote/jobs/model.js +162 -0
  145. package/dist/remote/jobs/node-bootstrap.js +213 -0
  146. package/dist/remote/jobs/policy.js +123 -0
  147. package/dist/remote/jobs/reconcile.js +100 -0
  148. package/dist/remote/jobs/run-spec-client.js +64 -0
  149. package/dist/remote/jobs/run-spec-path.js +31 -0
  150. package/dist/remote/jobs/run-spec-server.d.ts +34 -0
  151. package/dist/remote/jobs/run-spec-server.js +116 -0
  152. package/dist/remote/jobs/submit.d.ts +23 -0
  153. package/dist/remote/jobs/submit.js +116 -0
  154. package/dist/remote/jobs/watch.js +59 -0
  155. package/dist/remote/submit/argo-submission.d.ts +3 -1
  156. package/dist/remote/submit/argo-submission.js +53 -58
  157. package/dist/remote/submit/compilation.d.ts +2 -0
  158. package/dist/remote/submit/compilation.js +46 -49
  159. package/dist/remote/submit/event-boundary.js +62 -76
  160. package/dist/remote/submit/hook-events.d.ts +6 -0
  161. package/dist/remote/submit/io.d.ts +7 -1
  162. package/dist/remote/submit/io.js +40 -43
  163. package/dist/remote/submit/jobs-submission.d.ts +59 -0
  164. package/dist/remote/submit/jobs-submission.js +97 -0
  165. package/dist/remote/submit/jobs-submit-result.d.ts +25 -0
  166. package/dist/remote/submit/jobs-submit-result.js +34 -0
  167. package/dist/remote/submit/options.d.ts +49 -0
  168. package/dist/remote/submit/options.js +27 -0
  169. package/dist/remote/submit/service.d.ts +40 -1
  170. package/dist/remote/submit/service.js +67 -49
  171. package/dist/run-control/command-context.js +6 -8
  172. package/dist/run-control/commands.js +10 -10
  173. package/dist/run-control/contracts.d.ts +52 -101
  174. package/dist/run-control/contracts.js +83 -69
  175. package/dist/run-control/detach.js +66 -72
  176. package/dist/run-control/execution-store.js +0 -0
  177. package/dist/run-control/file-errors.js +1 -3
  178. package/dist/run-control/logical-segment.js +3 -3
  179. package/dist/run-control/next-node.js +67 -78
  180. package/dist/run-control/postgres/postgres-run-control-store.js +196 -225
  181. package/dist/run-control/resume-command.js +34 -41
  182. package/dist/run-control/run-artifacts-command.js +84 -105
  183. package/dist/run-control/run-command-domain.js +7 -11
  184. package/dist/run-control/run-control-store.js +9 -9
  185. package/dist/run-control/run-query-command.js +73 -100
  186. package/dist/run-control/run-record.js +5 -3
  187. package/dist/run-control/run-state-lock.js +5 -5
  188. package/dist/run-control/runtime-event-projection.js +38 -50
  189. package/dist/run-control/runtime-reporter.js +86 -102
  190. package/dist/run-control/stop-command.js +42 -53
  191. package/dist/run-control/store-fs-effects.js +3 -1
  192. package/dist/run-control/store-manifest.js +38 -13
  193. package/dist/run-control/store-paths.js +3 -3
  194. package/dist/run-control/store.js +1 -1
  195. package/dist/run-control/submit-result.js +21 -21
  196. package/dist/run-control/supervisor.js +78 -68
  197. package/dist/run-control/workspace.js +2 -2
  198. package/dist/run-state/git-refs.js +258 -307
  199. package/dist/runner/opencode-excludes.js +4 -4
  200. package/dist/runner/subprocess-result.js +28 -37
  201. package/dist/runner/subprocess.js +41 -41
  202. package/dist/runner/timeouts.js +14 -13
  203. package/dist/runner-command/dynamic-command.js +46 -39
  204. package/dist/runner-command/environment-commands.js +91 -0
  205. package/dist/runner-command/finalize.js +174 -153
  206. package/dist/runner-command/lifecycle-context.js +115 -130
  207. package/dist/runner-command/lifecycle.js +78 -72
  208. package/dist/runner-command/pre-schedule.js +203 -223
  209. package/dist/runner-command/run.js +450 -448
  210. package/dist/runner-command/schedule-source-options.js +8 -10
  211. package/dist/runner-command/select-ready-wave.js +39 -30
  212. package/dist/runner-command/task-descriptor.js +11 -17
  213. package/dist/runner-command-contract.d.ts +147 -157
  214. package/dist/runner-command-contract.js +403 -411
  215. package/dist/runner-event-schema.d.ts +364 -505
  216. package/dist/runner-event-schema.js +187 -175
  217. package/dist/runner-event-sink.js +37 -43
  218. package/dist/runner-output.js +6 -6
  219. package/dist/runner.d.ts +57 -37
  220. package/dist/runner.js +176 -127
  221. package/dist/runtime/actor-ids.d.ts +1 -0
  222. package/dist/runtime/actor-ids.js +2 -2
  223. package/dist/runtime/agent-node/agent-node.js +99 -110
  224. package/dist/runtime/agent-node/handoff-finalization.js +23 -24
  225. package/dist/runtime/agent-node/model-selection.js +19 -22
  226. package/dist/runtime/agent-node/output-finalization.js +174 -204
  227. package/dist/runtime/agent-node/prompt-rendering.js +208 -251
  228. package/dist/runtime/agent-node/session-execution.js +43 -39
  229. package/dist/runtime/builtins/builtins.js +218 -284
  230. package/dist/runtime/changed-files/changed-files.js +29 -34
  231. package/dist/runtime/command-executor/command-executor.js +31 -23
  232. package/dist/runtime/config-error.js +1 -3
  233. package/dist/runtime/context/context.js +35 -37
  234. package/dist/runtime/contracts/contracts.d.ts +3 -0
  235. package/dist/runtime/contracts/index.d.ts +1 -1
  236. package/dist/runtime/detached-race.js +11 -14
  237. package/dist/runtime/drain-merge/drain-merge.js +139 -164
  238. package/dist/runtime/durable-store/acquisition.js +5 -3
  239. package/dist/runtime/durable-store/durable-store.d.ts +3 -1
  240. package/dist/runtime/durable-store/postgres/client.js +29 -0
  241. package/dist/runtime/durable-store/postgres/migrate-substrate.js +34 -29
  242. package/dist/runtime/durable-store/postgres/postgres-store.js +18 -20
  243. package/dist/runtime/events/events.js +273 -331
  244. package/dist/runtime/events/index.js +2 -2
  245. package/dist/runtime/execution-envelope.js +44 -0
  246. package/dist/runtime/gates/adjudication/llm-judge.js +21 -24
  247. package/dist/runtime/gates/adjudication/structured-claim.js +15 -16
  248. package/dist/runtime/gates/adjudicator/adjudicator.js +27 -27
  249. package/dist/runtime/gates/adjudicator/index.js +2 -2
  250. package/dist/runtime/gates/contract.js +5 -9
  251. package/dist/runtime/gates/gates.js +9 -8
  252. package/dist/runtime/gates/kinds/acceptance/acceptance.js +68 -71
  253. package/dist/runtime/gates/kinds/acceptance/index.js +2 -2
  254. package/dist/runtime/gates/kinds/artifact/artifact.js +4 -4
  255. package/dist/runtime/gates/kinds/artifact/index.js +2 -2
  256. package/dist/runtime/gates/kinds/builtin/builtin.js +4 -4
  257. package/dist/runtime/gates/kinds/builtin/index.js +2 -2
  258. package/dist/runtime/gates/kinds/changed-files/changed-files.js +31 -35
  259. package/dist/runtime/gates/kinds/changed-files/index.js +2 -2
  260. package/dist/runtime/gates/kinds/command/command.js +3 -3
  261. package/dist/runtime/gates/kinds/command/index.js +2 -2
  262. package/dist/runtime/gates/kinds/json-schema/index.js +2 -2
  263. package/dist/runtime/gates/kinds/json-schema/json-schema.js +7 -6
  264. package/dist/runtime/gates/kinds/verdict/index.js +2 -2
  265. package/dist/runtime/gates/kinds/verdict/verdict.js +3 -3
  266. package/dist/runtime/gates/orchestrator.js +72 -86
  267. package/dist/runtime/gates/registry.js +1 -3
  268. package/dist/runtime/handoff.d.ts +2 -1
  269. package/dist/runtime/handoff.js +43 -46
  270. package/dist/runtime/hooks/command-hook.js +57 -71
  271. package/dist/runtime/hooks/context.js +21 -25
  272. package/dist/runtime/hooks/events.js +84 -100
  273. package/dist/runtime/hooks/execution.js +6 -12
  274. package/dist/runtime/hooks/hooks.js +34 -23
  275. package/dist/runtime/hooks/invocation.js +23 -29
  276. package/dist/runtime/hooks/module-hook.js +36 -35
  277. package/dist/runtime/hooks/policy.js +32 -29
  278. package/dist/runtime/hooks/results.js +56 -66
  279. package/dist/runtime/journal-acquisition.d.ts +3 -2
  280. package/dist/runtime/journal-acquisition.js +14 -14
  281. package/dist/runtime/json-validation/json-validation.js +51 -72
  282. package/dist/runtime/launch-plan-args.js +39 -0
  283. package/dist/runtime/local-scheduler.js +46 -48
  284. package/dist/runtime/node-execution.js +376 -445
  285. package/dist/runtime/node-protocol/node-protocol.js +36 -79
  286. package/dist/runtime/node-state-store.d.ts +4 -1
  287. package/dist/runtime/node-state-store.js +13 -57
  288. package/dist/runtime/node-state-tracker.js +46 -54
  289. package/dist/runtime/open-pull-request/open-pull-request.js +201 -187
  290. package/dist/runtime/opencode-adapter.js +23 -24
  291. package/dist/runtime/opencode-agent-name.js +6 -6
  292. package/dist/runtime/opencode-runtime.js +115 -93
  293. package/dist/runtime/opencode-server.js +39 -53
  294. package/dist/runtime/opencode-session-executor.js +312 -344
  295. package/dist/runtime/parallel-node/parallel-node.js +123 -134
  296. package/dist/runtime/parallel-worktrees/parallel-worktrees.js +90 -73
  297. package/dist/runtime/protected-paths/protected-paths.js +70 -71
  298. package/dist/runtime/remediation/remediation.js +202 -231
  299. package/dist/runtime/retry.js +8 -10
  300. package/dist/runtime/run-journal.d.ts +2 -0
  301. package/dist/runtime/run-journal.js +7 -7
  302. package/dist/runtime/runtime-results.js +54 -69
  303. package/dist/runtime/scheduled-dependencies.d.ts +2 -1
  304. package/dist/runtime/scheduled-dependencies.js +61 -75
  305. package/dist/runtime/scheduler.js +179 -202
  306. package/dist/runtime/services/agent-node-runtime-service.js +3 -3
  307. package/dist/runtime/services/backlog-service.d.ts +1 -2
  308. package/dist/runtime/services/backlog-service.js +8 -14
  309. package/dist/runtime/services/command-executor-service.js +1 -1
  310. package/dist/runtime/services/config-io-service.js +24 -21
  311. package/dist/runtime/services/drain-merge-git-service.js +1 -1
  312. package/dist/runtime/services/file-system-service.js +9 -7
  313. package/dist/runtime/services/git-porcelain-service.js +6 -6
  314. package/dist/runtime/services/kubernetes-argo-service.d.ts +10 -3
  315. package/dist/runtime/services/kubernetes-argo-service.js +90 -84
  316. package/dist/runtime/services/kubernetes-jobs-read-service.js +115 -0
  317. package/dist/runtime/services/kubernetes-jobs-service.d.ts +37 -0
  318. package/dist/runtime/services/kubernetes-jobs-service.js +45 -0
  319. package/dist/runtime/services/kubernetes-jobs-watch-service.js +61 -0
  320. package/dist/runtime/services/kubernetes-lease-service.js +21 -0
  321. package/dist/runtime/services/mcp-gateway-service.js +143 -94
  322. package/dist/runtime/services/open-pull-request-git-service.js +1 -3
  323. package/dist/runtime/services/opencode-runtime-server-service.js +10 -12
  324. package/dist/runtime/services/opencode-sdk-service.js +7 -7
  325. package/dist/runtime/services/repo-io-service.js +10 -12
  326. package/dist/runtime/services/run-journal-file-service.js +2 -2
  327. package/dist/runtime/services/runner-command-io-service.js +48 -52
  328. package/dist/runtime/services/runner-event-sink-http-service.js +32 -39
  329. package/dist/runtime/step/step-node.js +15 -15
  330. package/dist/runtime/workflow-execution.js +56 -57
  331. package/dist/runtime/workflow-lifecycle.js +82 -101
  332. package/dist/runtime/yeet-event-record.js +104 -0
  333. package/dist/runtime/yeet-executor.js +184 -0
  334. package/dist/safe-json.js +16 -16
  335. package/dist/schedule/backlog-context.js +122 -116
  336. package/dist/schedule/baseline.js +249 -255
  337. package/dist/schedule/passes/coverage.js +63 -68
  338. package/dist/schedule/passes/drain-merge.js +34 -40
  339. package/dist/schedule/passes/ids.js +15 -17
  340. package/dist/schedule/passes/models.js +40 -37
  341. package/dist/schedule/passes/open-pull-request.js +16 -20
  342. package/dist/schedule/passes/references.js +18 -22
  343. package/dist/schedule/prompts.js +135 -141
  344. package/dist/schedule/scheduling-roles.js +8 -14
  345. package/dist/schema-boundary.d.ts +4 -0
  346. package/dist/schema-boundary.js +145 -0
  347. package/dist/serialized-write-queue.js +2 -2
  348. package/dist/standard-output-schemas.js +61 -59
  349. package/dist/strings.js +12 -12
  350. package/dist/task-ref.js +5 -5
  351. package/dist/tickets/apply-ticket-plan.js +52 -61
  352. package/dist/tickets/backlog-task-store.d.ts +15 -23
  353. package/dist/tickets/backlog-task-store.js +82 -94
  354. package/dist/tickets/completion/complete-ticket.js +53 -59
  355. package/dist/tickets/ticket-graph-dto.d.ts +24 -48
  356. package/dist/tickets/ticket-graph-dto.js +40 -40
  357. package/dist/tickets/ticket-graph.d.ts +7 -2
  358. package/dist/tickets/ticket-graph.js +36 -50
  359. package/dist/tickets/ticket-plan-command-args.js +6 -10
  360. package/dist/tickets/ticket-plan-render.js +10 -16
  361. package/dist/tickets/ticket-plan.d.ts +32 -41
  362. package/dist/tickets/ticket-plan.js +97 -77
  363. package/dist/tickets/ticket-selection.d.ts +3 -1
  364. package/dist/tickets/ticket-selection.js +37 -52
  365. package/dist/tickets/ticket-task-index.js +13 -17
  366. package/dist/tickets/validation-error-format.js +3 -10
  367. package/dist/token-estimator.js +12 -7
  368. package/dist/unknown-fields.js +21 -0
  369. package/dist/workflow-submit-contract.d.ts +9 -10
  370. package/dist/workflow-submit-contract.js +10 -9
  371. package/docs/adr-moka-postgres-schema-isolation.md +48 -0
  372. package/docs/adr-opencode-first-goal-loop-runtime.md +11 -11
  373. package/docs/config-architecture.md +13 -13
  374. package/docs/mcp-host-isolation.md +1 -0
  375. package/docs/moka-orchestrator-design.md +3 -3
  376. package/docs/operator-guide.md +1 -1
  377. package/docs/pipeline-console-runner-contract.md +10 -6
  378. package/docs/runtime-actor-model.md +18 -18
  379. package/docs/runtime-test-subsystems.md +200 -0
  380. package/docs/slash-command-adapter-contract.md +3 -3
  381. package/package.json +49 -85
  382. package/dist/config/schema/reference-validation.js +0 -83
@@ -2,88 +2,74 @@ import { loadPipelineConfig } from "../config/load.js";
2
2
  import "../config.js";
3
3
  import { createOpencodeExecutor, createOpencodeSessionRegistry } from "./opencode-session-executor.js";
4
4
  import { OpencodeRuntimeServerService, OpencodeRuntimeServerServiceLive } from "./services/opencode-runtime-server-service.js";
5
- import { Effect } from "effect";
5
+ import { createYeetExecutor } from "./yeet-executor.js";
6
+ import { Effect, Option } from "effect";
6
7
  //#region src/runtime/opencode-runtime.ts
8
+ const NO_AVAILABLE_MODELS = Option.none();
7
9
  /**
8
10
  * True when the config declares any opencode runner, i.e. the SDK transport is
9
11
  * relevant for this run. Command-only configs never start a server.
10
12
  */
11
- function configUsesOpencode(config) {
12
- return Object.values(config.runners).some((runner) => runner.type === "opencode");
13
- }
14
- /**
15
- * Return an SDK-backed executor plus a release() that tears the server down.
16
- * The opencode server is started LAZILY on the first executor call, not at
17
- * lease time: a run whose ready nodes are all command/builtin (or that fails
18
- * before any agent node executes) never spawns opencode, so the binary is only
19
- * required when an agent node actually runs. release() is a no-op if the server
20
- * was never started. Caller owns the lifecycle:
21
- *
22
- * const lease = await leaseOpencodeRuntime({ config, worktreePath });
23
- * try { ...run with lease.executor... } finally { await lease.release(); }
24
- */
25
- function leaseOpencodeRuntime(input) {
26
- return Effect.runPromise(Effect.provide(leaseOpencodeRuntimeEffect(input), OpencodeRuntimeServerServiceLive));
27
- }
28
- function withOpencodeRuntime(options, run) {
29
- return Effect.gen(function* () {
30
- if (options.executor) return yield* run(options);
31
- const { config, worktreePath } = resolveConfigForRun(options);
32
- if (configUsesOpencode(config)) return yield* runWithLeasedOpencode(options, config, worktreePath, run);
33
- return yield* run({
34
- ...options,
35
- config
36
- });
37
- });
38
- }
39
- function resolveConfigForRun(options) {
13
+ const configUsesOpencode = (config) => Object.values(config.runners).some((runner) => runner.type === "opencode");
14
+ const resolveConfigForRun = (options) => {
40
15
  const worktreePath = options.worktreePath ?? process.cwd();
41
16
  return {
42
17
  config: options.config ?? loadPipelineConfig(worktreePath),
43
18
  worktreePath
44
19
  };
45
- }
46
- function runWithLeasedOpencode(options, config, worktreePath, run) {
47
- return Effect.scoped(Effect.gen(function* () {
48
- const lease = yield* Effect.acquireRelease(Effect.tryPromise(() => leaseOpencodeRuntime({
49
- config,
50
- ...options.reporter ? { onSession: opencodeSessionReporter(options.reporter) } : {},
51
- ...options.signal ? { signal: options.signal } : {},
52
- worktreePath
53
- })), (lease) => Effect.promise(() => lease.release()));
54
- const availableModels = yield* Effect.promise(() => lease.availableModels());
55
- return yield* run({
56
- ...options,
57
- config,
58
- executor: lease.executor,
59
- ...availableModels ? { availableModels } : {}
60
- });
61
- }));
62
- }
63
- function opencodeSessionReporter(reporter) {
64
- return (nodeId, sessionId) => {
65
- reporter({
66
- nodeId,
67
- sessionId,
68
- type: "node.session"
69
- });
20
+ };
21
+ const opencodeSessionReporter = (reporter) => (nodeId, sessionId) => {
22
+ reporter({
23
+ nodeId,
24
+ sessionId,
25
+ type: "node.session"
26
+ });
27
+ };
28
+ /**
29
+ * Collect every model the leased server can resolve (each authenticated
30
+ * provider's models as `provider/model`) from the opencode `/config/providers`
31
+ * endpoint, for availability-aware model selection.
32
+ */
33
+ const queryAvailableOpencodeModels = async (client) => {
34
+ const providers = (await client.config.providers()).data?.providers ?? [];
35
+ return new Set(providers.flatMap((provider) => Object.keys(provider.models).map((modelId) => `${provider.id}/${modelId}`)));
36
+ };
37
+ const ensureExecutorEffect = (input, registry) => Effect.gen(function* effectBody() {
38
+ const handle = yield* (yield* OpencodeRuntimeServerService).open(input);
39
+ return {
40
+ delegate: createOpencodeExecutor({
41
+ client: handle.client,
42
+ directory: input.worktreePath,
43
+ ...input.onSession ? { onSession: input.onSession } : {},
44
+ registry
45
+ }),
46
+ handle
70
47
  };
71
- }
72
- function leaseOpencodeRuntimeEffect(input) {
48
+ });
49
+ const leaseOpencodeRuntimeEffect = (input) => {
73
50
  const registry = createOpencodeSessionRegistry();
74
- let handle;
75
- let pending;
76
- let availableModelsPending;
77
- const ensureExecutor = () => {
78
- pending ??= Effect.runPromise(Effect.provide(ensureExecutorEffect(input, registry), OpencodeRuntimeServerServiceLive)).then((executor) => {
79
- handle = executor.handle;
80
- return executor.delegate;
51
+ let handle = Option.none();
52
+ let pending = Option.none();
53
+ let availableModelsPending = Option.none();
54
+ const ensureExecutor = async () => {
55
+ return await Option.getOrElse(pending, async () => {
56
+ const next = Effect.runPromise(Effect.provide(ensureExecutorEffect(input, registry), OpencodeRuntimeServerServiceLive)).then((executor) => {
57
+ handle = Option.some(executor.handle);
58
+ return executor.delegate;
59
+ });
60
+ pending = Option.some(next);
61
+ return await next;
81
62
  });
82
- return pending;
83
63
  };
84
- const resolveAvailableModels = () => {
85
- availableModelsPending ??= ensureExecutor().then(() => handle ? queryAvailableOpencodeModels(handle.client) : void 0).catch(() => void 0);
86
- return availableModelsPending;
64
+ const resolveAvailableModels = async () => {
65
+ return await Option.getOrElse(availableModelsPending, async () => {
66
+ const next = ensureExecutor().then(async () => {
67
+ if (Option.isNone(handle)) return Option.none();
68
+ return Option.some(await queryAvailableOpencodeModels(handle.value.client));
69
+ }).catch(() => NO_AVAILABLE_MODELS);
70
+ availableModelsPending = Option.some(next);
71
+ return await next;
72
+ });
87
73
  };
88
74
  return Effect.succeed({
89
75
  availableModels: resolveAvailableModels,
@@ -91,35 +77,71 @@ function leaseOpencodeRuntimeEffect(input) {
91
77
  return await (await ensureExecutor())(plan, options);
92
78
  },
93
79
  release: async () => {
94
- if (handle) {
95
- await handle.close();
96
- handle = void 0;
80
+ if (Option.isSome(handle)) {
81
+ await handle.value.close();
82
+ handle = Option.none();
97
83
  }
98
84
  }
99
85
  });
100
- }
86
+ };
101
87
  /**
102
- * Collect every model the leased server can resolve (each authenticated
103
- * provider's models as `provider/model`) from the opencode `/config/providers`
104
- * endpoint, for availability-aware model selection.
88
+ * Return an SDK-backed executor plus a release() that tears the server down.
89
+ * The opencode server is started LAZILY on the first executor call, not at
90
+ * lease time: a run whose ready nodes are all command/builtin (or that fails
91
+ * before any agent node executes) never spawns opencode, so the binary is only
92
+ * required when an agent node actually runs. release() is a no-op if the server
93
+ * was never started. Caller owns the lifecycle:
94
+ *
95
+ * const lease = await leaseOpencodeRuntime({ config, worktreePath });
96
+ * try { ...run with lease.executor... } finally { await lease.release(); }
105
97
  */
106
- async function queryAvailableOpencodeModels(client) {
107
- const providers = (await client.config.providers()).data?.providers ?? [];
108
- return new Set(providers.flatMap((provider) => Object.keys(provider.models ?? {}).map((modelId) => `${provider.id}/${modelId}`)));
109
- }
110
- function ensureExecutorEffect(input, registry) {
111
- return Effect.gen(function* () {
112
- const handle = yield* (yield* OpencodeRuntimeServerService).open(input);
113
- return {
114
- delegate: createOpencodeExecutor({
115
- client: handle.client,
116
- directory: input.worktreePath,
117
- ...input.onSession ? { onSession: input.onSession } : {},
118
- registry
119
- }),
120
- handle
121
- };
98
+ const leaseOpencodeRuntime = async (input) => await Effect.runPromise(Effect.provide(leaseOpencodeRuntimeEffect(input), OpencodeRuntimeServerServiceLive));
99
+ const runWithLeasedOpencode = (options, config, worktreePath, run, lease) => Effect.scoped(Effect.gen(function* effectBody() {
100
+ const acquired = yield* Effect.acquireRelease(Effect.tryPromise(async () => await lease({
101
+ config,
102
+ ...options.reporter === void 0 ? {} : { onSession: opencodeSessionReporter(options.reporter) },
103
+ ...options.signal === void 0 ? {} : { signal: options.signal },
104
+ worktreePath
105
+ })), (leased) => Effect.promise(async () => {
106
+ await leased.release();
107
+ }));
108
+ const availableModels = yield* Effect.promise(async () => await acquired.availableModels());
109
+ return yield* run({
110
+ ...options,
111
+ config,
112
+ executor: acquired.executor,
113
+ ...Option.isSome(availableModels) ? { availableModels: availableModels.value } : {}
114
+ });
115
+ }));
116
+ /**
117
+ * Build the yeet-backed executor for this run and hand it to `run`. Unlike the
118
+ * SDK transport, yeet needs no leased server (it spawns `yeet run opencode` per
119
+ * node), so there is nothing to release. Session ids are reported through the
120
+ * same reporter seam as the SDK path.
121
+ */
122
+ const runWithYeetExecutor = (options, config, run, createExecutor) => {
123
+ const deps = options.reporter === void 0 ? {} : { onSession: opencodeSessionReporter(options.reporter) };
124
+ return run({
125
+ ...options,
126
+ config,
127
+ executor: createExecutor(deps)
128
+ });
129
+ };
130
+ /**
131
+ * Which transport drives opencode agent nodes for this config. The gate lives
132
+ * in config (`runtime.executor`) and defaults to the in-process SDK session
133
+ * executor; "yeet" selects the subprocess yeet runtime (ENG-18.1).
134
+ */
135
+ const resolveOpencodeExecutorKind = (config) => config.runtime.executor;
136
+ const withOpencodeRuntime = (options, run, overrides = {}) => Effect.gen(function* effectBody() {
137
+ if (options.executor !== void 0) return yield* run(options);
138
+ const { config, worktreePath } = resolveConfigForRun(options);
139
+ if (!configUsesOpencode(config)) return yield* run({
140
+ ...options,
141
+ config
122
142
  });
123
- }
143
+ if (resolveOpencodeExecutorKind(config) === "yeet") return yield* runWithYeetExecutor(options, config, run, overrides.createYeetExecutor ?? createYeetExecutor);
144
+ return yield* runWithLeasedOpencode(options, config, worktreePath, run, overrides.leaseOpencodeRuntime ?? leaseOpencodeRuntime);
145
+ });
124
146
  //#endregion
125
- export { configUsesOpencode, leaseOpencodeRuntime, withOpencodeRuntime };
147
+ export { configUsesOpencode, leaseOpencodeRuntime, resolveOpencodeExecutorKind, withOpencodeRuntime };
@@ -6,63 +6,30 @@ const DEFAULT_STARTUP_TIMEOUT_MS = 3e4;
6
6
  var OpencodeServerStartupError = class extends Data.TaggedError("OpencodeServerStartupError") {
7
7
  constructor(message, options) {
8
8
  super({
9
- message,
10
- cause: options?.cause
9
+ cause: options?.cause,
10
+ message
11
11
  });
12
12
  }
13
13
  };
14
- function openOpencodeServer(options) {
15
- return Effect.runPromise(Effect.provide(openOpencodeServerEffect(options), OpencodeSdkServiceLive));
16
- }
17
- function openOpencodeServerEffect(options) {
18
- const externalUrl = options.serverUrl ?? process.env.OPENCODE_SERVER_URL ?? "";
19
- if (externalUrl.length > 0) return connectExternalServer(externalUrl, options.directory).pipe(Effect.mapError(startupError));
20
- return spawnOwnedServer(options);
21
- }
22
- function connectExternalServer(url, directory) {
23
- return Effect.gen(function* () {
24
- return {
25
- close: () => Promise.resolve(),
26
- client: yield* (yield* OpencodeSdkService).createClient({
27
- baseUrl: url,
28
- directory
29
- }),
30
- owned: false,
31
- url
32
- };
33
- });
34
- }
35
- function spawnOwnedServer(options) {
36
- return Effect.gen(function* () {
37
- const { client, server } = yield* (yield* OpencodeSdkService).spawnServer(spawnArgs(options), options.spawn);
38
- return ownedHandle(client, server, options.directory);
39
- }).pipe(Effect.catch((error) => Effect.fail(startupError(error))));
40
- }
41
- function startupError(error) {
42
- return new OpencodeServerStartupError(`Failed to start opencode server: ${errorText(error)}`, { cause: error });
43
- }
44
- function spawnArgs(options) {
14
+ const connectExternalServer = (url, directory) => Effect.gen(function* effectBody() {
45
15
  return {
46
- port: 0,
47
- ...options.signal ? { signal: options.signal } : {},
48
- timeout: options.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS
49
- };
50
- }
51
- function ownedHandle(client, server, directory) {
52
- return {
53
- close: () => {
54
- server.close();
55
- return Promise.resolve();
56
- },
57
- client: withDirectory(client, server.url, directory),
58
- owned: true,
59
- url: server.url
16
+ client: yield* (yield* OpencodeSdkService).createClient({
17
+ baseUrl: url,
18
+ directory
19
+ }),
20
+ close: async () => {},
21
+ owned: false,
22
+ url
60
23
  };
61
- }
62
- function errorText(error) {
63
- return error instanceof Error ? error.message : String(error);
64
- }
65
- function withDirectory(fallback, url, directory) {
24
+ });
25
+ const spawnArgs = (options) => ({
26
+ port: 0,
27
+ ...options.signal ? { signal: options.signal } : {},
28
+ timeout: options.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS
29
+ });
30
+ const errorText = (error) => error instanceof Error ? error.message : String(error);
31
+ const startupError = (error) => new OpencodeServerStartupError(`Failed to start opencode server: ${errorText(error)}`, { cause: error });
32
+ const withDirectory = (fallback, url, directory) => {
66
33
  try {
67
34
  return createOpencodeClient({
68
35
  baseUrl: url,
@@ -71,6 +38,25 @@ function withDirectory(fallback, url, directory) {
71
38
  } catch {
72
39
  return fallback;
73
40
  }
74
- }
41
+ };
42
+ const ownedHandle = (client, server, directory) => ({
43
+ client: withDirectory(client, server.url, directory),
44
+ close: async () => {
45
+ server.close();
46
+ await Promise.resolve();
47
+ },
48
+ owned: true,
49
+ url: server.url
50
+ });
51
+ const spawnOwnedServer = (options) => Effect.gen(function* effectBody() {
52
+ const { client, server } = yield* (yield* OpencodeSdkService).spawnServer(spawnArgs(options), options.spawn);
53
+ return ownedHandle(client, server, options.directory);
54
+ }).pipe(Effect.catch((error) => Effect.fail(startupError(error))));
55
+ const openOpencodeServerEffect = (options) => {
56
+ const externalUrl = options.serverUrl ?? process.env.OPENCODE_SERVER_URL ?? "";
57
+ if (externalUrl.length > 0) return connectExternalServer(externalUrl, options.directory).pipe(Effect.mapError(startupError));
58
+ return spawnOwnedServer(options);
59
+ };
60
+ const openOpencodeServer = async (options) => await Effect.runPromise(Effect.provide(openOpencodeServerEffect(options), OpencodeSdkServiceLive));
75
61
  //#endregion
76
62
  export { OpencodeServerStartupError, openOpencodeServer };