@wardby/cli 0.5.3 → 0.6.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 (370) hide show
  1. package/.env.example +33 -0
  2. package/README.md +25 -14
  3. package/dist/claude-coding-worker/context.d.ts +22 -0
  4. package/dist/claude-coding-worker/context.js +92 -0
  5. package/dist/claude-coding-worker/driver.d.ts +7 -1
  6. package/dist/claude-coding-worker/driver.js +38 -5
  7. package/dist/claude-coding-worker/sdk.js +13 -4
  8. package/dist/cli-help.d.ts +1 -1
  9. package/dist/cli-help.js +5 -2
  10. package/dist/cli-native-mode.d.ts +9 -0
  11. package/dist/cli-native-mode.js +20 -0
  12. package/dist/cli.d.ts +3 -1
  13. package/dist/cli.js +141 -5
  14. package/dist/coding/claude-context.d.ts +45 -0
  15. package/dist/coding/claude-context.js +434 -0
  16. package/dist/coding/profile.d.ts +12 -0
  17. package/dist/coding/profile.js +6 -0
  18. package/dist/coding/protocol.d.ts +104 -0
  19. package/dist/coding/protocol.js +87 -3
  20. package/dist/coding-worker/artifact.d.ts +8 -0
  21. package/dist/coding-worker/artifact.js +2 -2
  22. package/dist/coding-worker/driver.js +2 -0
  23. package/dist/coding-worker/sdk.d.ts +6 -0
  24. package/dist/coding-worker/sdk.js +1 -0
  25. package/dist/coding-worker/skills.d.ts +23 -0
  26. package/dist/coding-worker/skills.js +117 -0
  27. package/dist/coding-worker/types.d.ts +2 -0
  28. package/dist/config/github-allowed-accounts.d.ts +15 -0
  29. package/dist/config/github-allowed-accounts.js +36 -0
  30. package/dist/config/low-power.d.ts +12 -0
  31. package/dist/config/low-power.js +18 -0
  32. package/dist/config/mobile.d.ts +12 -0
  33. package/dist/config/mobile.js +18 -0
  34. package/dist/config/providers.d.ts +53 -0
  35. package/dist/config/providers.js +92 -6
  36. package/dist/core/db.d.ts +16 -6
  37. package/dist/core/db.js +12 -10
  38. package/dist/core/dispatch.d.ts +11 -0
  39. package/dist/core/dispatch.js +36 -1
  40. package/dist/core/engine-native.js +9 -5
  41. package/dist/core/host-events.d.ts +49 -3
  42. package/dist/core/host-events.js +289 -15
  43. package/dist/core/issue-bridge.js +42 -2
  44. package/dist/core/issue-events.js +12 -1
  45. package/dist/core/issue-status.js +14 -3
  46. package/dist/core/merge-order-check.d.ts +129 -0
  47. package/dist/core/merge-order-check.js +336 -0
  48. package/dist/core/notification-dispatcher.d.ts +70 -0
  49. package/dist/core/notification-dispatcher.js +368 -0
  50. package/dist/core/notification-templates.d.ts +25 -0
  51. package/dist/core/notification-templates.js +105 -0
  52. package/dist/core/notifications.d.ts +10 -0
  53. package/dist/core/notifications.js +38 -0
  54. package/dist/core/pg-auth.d.ts +22 -0
  55. package/dist/core/pg-auth.js +152 -0
  56. package/dist/core/power-composition.d.ts +16 -0
  57. package/dist/core/power-composition.js +37 -0
  58. package/dist/core/power-idle.d.ts +14 -0
  59. package/dist/core/power-idle.js +30 -0
  60. package/dist/core/power.d.ts +71 -0
  61. package/dist/core/power.js +202 -0
  62. package/dist/core/reconciler.d.ts +4 -2
  63. package/dist/core/reconciler.js +29 -5
  64. package/dist/core/related-pull-requests.d.ts +48 -4
  65. package/dist/core/related-pull-requests.js +113 -11
  66. package/dist/core/repo-access.d.ts +15 -0
  67. package/dist/core/repo-access.js +66 -0
  68. package/dist/core/review-fix.d.ts +37 -0
  69. package/dist/core/review-fix.js +207 -6
  70. package/dist/core/review-host-tools.d.ts +20 -0
  71. package/dist/core/review-host-tools.js +58 -2
  72. package/dist/core/runner.d.ts +336 -3
  73. package/dist/core/runner.js +894 -317
  74. package/dist/core/secret-broker-config.d.ts +103 -0
  75. package/dist/core/secret-broker-config.js +112 -0
  76. package/dist/core/secrets.d.ts +39 -4
  77. package/dist/core/secrets.js +148 -40
  78. package/dist/core/workflow-event-recorder.d.ts +14 -0
  79. package/dist/core/workflow-event-recorder.js +120 -0
  80. package/dist/core/workflow-events.d.ts +82 -0
  81. package/dist/core/workflow-events.js +44 -0
  82. package/dist/core/workflow-run-events.d.ts +16 -0
  83. package/dist/core/workflow-run-events.js +40 -0
  84. package/dist/generated/prisma/browser.d.ts +58 -0
  85. package/dist/generated/prisma/client.d.ts +58 -0
  86. package/dist/generated/prisma/commonInputTypes.d.ts +150 -0
  87. package/dist/generated/prisma/enums.d.ts +27 -0
  88. package/dist/generated/prisma/enums.js +23 -0
  89. package/dist/generated/prisma/internal/class.d.ts +88 -0
  90. package/dist/generated/prisma/internal/class.js +4 -4
  91. package/dist/generated/prisma/internal/prismaNamespace.d.ts +772 -1
  92. package/dist/generated/prisma/internal/prismaNamespace.js +135 -4
  93. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +139 -0
  94. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +135 -4
  95. package/dist/generated/prisma/models/Agent.d.ts +360 -1
  96. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +73 -1
  97. package/dist/generated/prisma/models/CodingRun.d.ts +205 -1
  98. package/dist/generated/prisma/models/DeferredReview.d.ts +78 -1
  99. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +1675 -0
  100. package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
  101. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1517 -0
  102. package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
  103. package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
  104. package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
  105. package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
  106. package/dist/generated/prisma/models/NotificationChannel.js +1 -0
  107. package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
  108. package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
  109. package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
  110. package/dist/generated/prisma/models/NotificationThread.js +1 -0
  111. package/dist/generated/prisma/models/Run.d.ts +826 -1
  112. package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
  113. package/dist/generated/prisma/models/Secret.d.ts +37 -1
  114. package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
  115. package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
  116. package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
  117. package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
  118. package/dist/generated/prisma/models.d.ts +8 -0
  119. package/dist/help/build.js +4 -2
  120. package/dist/help/catalog.d.ts +1 -1
  121. package/dist/help/catalog.js +31 -6
  122. package/dist/help-index.json +1363 -176
  123. package/dist/import/create.js +17 -0
  124. package/dist/import/neutral-schema.d.ts +6 -2
  125. package/dist/import/neutral-schema.js +2 -0
  126. package/dist/mcp/auth/access.d.ts +1 -0
  127. package/dist/mcp/auth/repo-authorization.js +14 -0
  128. package/dist/mcp/auth/resource-server.d.ts +2 -1
  129. package/dist/mcp/auth/resource-server.js +7 -2
  130. package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
  131. package/dist/mcp/auth/self-hosted/browser.js +19 -6
  132. package/dist/mcp/context.d.ts +6 -0
  133. package/dist/mcp/host-events/github-ingress.d.ts +23 -1
  134. package/dist/mcp/host-events/github-ingress.js +68 -0
  135. package/dist/mcp/index.d.ts +13 -0
  136. package/dist/mcp/index.js +59 -10
  137. package/dist/mcp/tools/agents.js +82 -11
  138. package/dist/mcp/tools/notification-channels.d.ts +2 -0
  139. package/dist/mcp/tools/notification-channels.js +293 -0
  140. package/dist/mcp/tools/power.d.ts +2 -0
  141. package/dist/mcp/tools/power.js +77 -0
  142. package/dist/mcp/tools/runs.d.ts +0 -6
  143. package/dist/mcp/tools/runs.js +7 -2
  144. package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
  145. package/dist/mcp/tools/secret-broker-compat.js +23 -0
  146. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
  147. package/dist/mcp/tools/secret-elicitation-form.js +200 -10
  148. package/dist/mcp/tools/secret-elicitation-server.js +8 -1
  149. package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
  150. package/dist/mcp/tools/secret-elicitation.js +110 -12
  151. package/dist/mcp/tools/secrets.js +184 -7
  152. package/dist/mcp/tools/tools.d.ts +1 -1
  153. package/dist/mcp/tools/tools.js +22 -2
  154. package/dist/native-worker/composition.d.ts +23 -0
  155. package/dist/native-worker/composition.js +77 -0
  156. package/dist/native-worker/docker-isolation.d.ts +65 -0
  157. package/dist/native-worker/docker-isolation.js +183 -0
  158. package/dist/native-worker/docker-launcher.d.ts +74 -0
  159. package/dist/native-worker/docker-launcher.js +237 -0
  160. package/dist/native-worker/gateway-server.d.ts +39 -0
  161. package/dist/native-worker/gateway-server.js +315 -0
  162. package/dist/native-worker/gateway.d.ts +44 -0
  163. package/dist/native-worker/gateway.js +197 -0
  164. package/dist/native-worker/http-server.d.ts +22 -0
  165. package/dist/native-worker/http-server.js +109 -0
  166. package/dist/native-worker/http-transport.d.ts +17 -0
  167. package/dist/native-worker/http-transport.js +88 -0
  168. package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
  169. package/dist/native-worker/kubernetes-isolation.js +218 -0
  170. package/dist/native-worker/kubernetes-launcher.d.ts +102 -0
  171. package/dist/native-worker/kubernetes-launcher.js +335 -0
  172. package/dist/native-worker/launch.d.ts +45 -0
  173. package/dist/native-worker/launch.js +44 -0
  174. package/dist/native-worker/ledger.d.ts +109 -0
  175. package/dist/native-worker/ledger.js +192 -0
  176. package/dist/native-worker/loopback.d.ts +12 -0
  177. package/dist/native-worker/loopback.js +49 -0
  178. package/dist/native-worker/main.d.ts +7 -0
  179. package/dist/native-worker/main.js +74 -0
  180. package/dist/native-worker/protocol.d.ts +744 -0
  181. package/dist/native-worker/protocol.js +200 -0
  182. package/dist/native-worker/sandbox-executor.d.ts +68 -0
  183. package/dist/native-worker/sandbox-executor.js +210 -0
  184. package/dist/native-worker/stdio.d.ts +29 -0
  185. package/dist/native-worker/stdio.js +188 -0
  186. package/dist/native-worker/warm-delivery.d.ts +16 -0
  187. package/dist/native-worker/warm-delivery.js +33 -0
  188. package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
  189. package/dist/native-worker/warm-pool-ledger.js +73 -0
  190. package/dist/native-worker/warm-pool.d.ts +107 -0
  191. package/dist/native-worker/warm-pool.js +283 -0
  192. package/dist/native-worker/worker.d.ts +17 -0
  193. package/dist/native-worker/worker.js +115 -0
  194. package/dist/providers/auth/authorization-server.d.ts +3 -0
  195. package/dist/providers/auth/index.js +2 -0
  196. package/dist/providers/auth/self-hosted.d.ts +13 -1
  197. package/dist/providers/auth/self-hosted.js +54 -4
  198. package/dist/providers/chat/fake.d.ts +46 -0
  199. package/dist/providers/chat/fake.js +39 -0
  200. package/dist/providers/chat/index.d.ts +4 -0
  201. package/dist/providers/chat/index.js +8 -0
  202. package/dist/providers/chat/slack.d.ts +37 -0
  203. package/dist/providers/chat/slack.js +105 -0
  204. package/dist/providers/chat/types.d.ts +42 -0
  205. package/dist/providers/chat/types.js +19 -0
  206. package/dist/providers/engine/types.d.ts +19 -0
  207. package/dist/providers/engine/types.js +22 -0
  208. package/dist/providers/executor/composition.d.ts +24 -1
  209. package/dist/providers/executor/composition.js +39 -6
  210. package/dist/providers/executor/container.d.ts +24 -1
  211. package/dist/providers/executor/container.js +101 -11
  212. package/dist/providers/executor/dbos.d.ts +42 -0
  213. package/dist/providers/executor/dbos.js +118 -12
  214. package/dist/providers/executor/deferred.d.ts +56 -0
  215. package/dist/providers/executor/deferred.js +119 -0
  216. package/dist/providers/executor/routing.d.ts +37 -10
  217. package/dist/providers/executor/routing.js +73 -32
  218. package/dist/providers/executor/types.d.ts +12 -0
  219. package/dist/providers/jobs/docker.js +3 -3
  220. package/dist/providers/jobs/fake-kubernetes-api.d.ts +21 -2
  221. package/dist/providers/jobs/fake-kubernetes-api.js +42 -1
  222. package/dist/providers/jobs/kubernetes-api.d.ts +17 -1
  223. package/dist/providers/jobs/kubernetes-api.js +7 -0
  224. package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
  225. package/dist/providers/jobs/kubernetes-client.js +52 -3
  226. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
  227. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
  228. package/dist/providers/jobs/kubernetes-isolation.d.ts +3 -1
  229. package/dist/providers/jobs/kubernetes-isolation.js +6 -0
  230. package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
  231. package/dist/providers/jobs/kubernetes-platform.js +38 -1
  232. package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
  233. package/dist/providers/jobs/kubernetes-preflight.js +4 -2
  234. package/dist/providers/jobs/kubernetes.d.ts +36 -1
  235. package/dist/providers/jobs/kubernetes.js +74 -4
  236. package/dist/providers/jobs/metadata-probes.d.ts +11 -0
  237. package/dist/providers/jobs/metadata-probes.js +13 -0
  238. package/dist/providers/jobs/types.d.ts +9 -0
  239. package/dist/providers/review-host/github.d.ts +11 -1
  240. package/dist/providers/review-host/github.js +50 -0
  241. package/dist/providers/review-host/types.d.ts +23 -0
  242. package/dist/providers/vcs/github.d.ts +32 -6
  243. package/dist/providers/vcs/github.js +74 -16
  244. package/dist/quickstart/coding-seed.d.ts +10 -3
  245. package/dist/quickstart/coding-seed.js +74 -3
  246. package/dist/quickstart/images.d.ts +2 -0
  247. package/dist/quickstart/images.js +7 -1
  248. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  249. package/dist/quickstart/reviewer-prompt.js +1 -1
  250. package/dist/quickstart-images.json +1 -1
  251. package/dist/sandbox/brokered-fetch.d.ts +23 -0
  252. package/dist/sandbox/brokered-fetch.js +37 -0
  253. package/dist/sandbox/host-functions.d.ts +34 -0
  254. package/dist/sandbox/host-functions.js +144 -80
  255. package/dist/sandbox/prelude.js +7 -1
  256. package/dist/sandbox/run-in-sandbox.d.ts +19 -0
  257. package/dist/sandbox/run-in-sandbox.js +28 -10
  258. package/dist/sandbox/safe-fetch.d.ts +2 -0
  259. package/dist/sandbox/safe-fetch.js +3 -1
  260. package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
  261. package/dist/sandbox/secret-broker-sigv4.js +49 -0
  262. package/dist/sandbox/secret-broker.d.ts +34 -0
  263. package/dist/sandbox/secret-broker.js +162 -0
  264. package/dist/sandbox/user-tool.d.ts +14 -0
  265. package/dist/sandbox/user-tool.js +32 -0
  266. package/dist/serve.js +18 -0
  267. package/dist/viewer/api-schema.d.ts +210 -14
  268. package/dist/viewer/api-schema.js +22 -0
  269. package/dist/viewer/build-schemas.js +4 -1
  270. package/dist/viewer/event-bus.d.ts +6 -0
  271. package/dist/viewer/event-bus.js +16 -7
  272. package/dist/viewer/graph.d.ts +5 -2
  273. package/dist/viewer/graph.js +7 -2
  274. package/dist/viewer/http.d.ts +0 -1
  275. package/dist/viewer/http.js +2 -2
  276. package/dist/viewer/infra.js +25 -2
  277. package/dist/viewer/limits.d.ts +4 -0
  278. package/dist/viewer/limits.js +4 -0
  279. package/dist/viewer/openapi.d.ts +15 -0
  280. package/dist/viewer/openapi.js +172 -0
  281. package/docs/README.md +7 -0
  282. package/docs/agent-recipes.md +57 -8
  283. package/docs/architecture-runtime.md +16 -1
  284. package/docs/code-review-agents.md +139 -5
  285. package/docs/coding-agent-setup.md +113 -5
  286. package/docs/coding-packages.md +4 -2
  287. package/docs/coding-services.md +3 -1
  288. package/docs/coding-worker-byo-images.md +198 -6
  289. package/docs/coding-worker-isolation.md +68 -14
  290. package/docs/getting-started-gke.md +225 -9
  291. package/docs/getting-started-identity-provider.md +21 -10
  292. package/docs/getting-started.md +5 -4
  293. package/docs/jira-agents.md +5 -1
  294. package/docs/native-sandbox.md +635 -0
  295. package/docs/release-verification.md +9 -0
  296. package/docs/security-deployment.md +113 -12
  297. package/docs/slack-notifications.md +252 -0
  298. package/docs/tool-secrets.md +252 -0
  299. package/docs/viewer-api.md +46 -5
  300. package/docs/viewer-api.openapi.yml +1404 -0
  301. package/help/admin-viewer.md +6 -2
  302. package/help/agent-recipes.md +27 -0
  303. package/help/architecture-agent.md +1 -1
  304. package/help/brokered-secrets.md +79 -0
  305. package/help/build-claude-code-image.md +131 -0
  306. package/help/build-worker-image.md +3 -6
  307. package/help/code-review-agents.md +68 -6
  308. package/help/deploy-gke.md +8 -1
  309. package/help/deployment-targets.md +25 -14
  310. package/help/errors/coding-provider-not-configured.md +2 -2
  311. package/help/errors/database-auth-invalid.md +28 -0
  312. package/help/errors/github-account-not-allowed.md +25 -0
  313. package/help/errors/low-power-disabled.md +29 -0
  314. package/help/errors/low-power-scale-forbidden.md +35 -0
  315. package/help/errors/low-power-wake-timeout.md +30 -0
  316. package/help/errors/mobile-disabled.md +31 -0
  317. package/help/errors/native-sandbox-capacity.md +22 -0
  318. package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
  319. package/help/errors/native-sandbox-docker-failed.md +20 -0
  320. package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
  321. package/help/errors/native-sandbox-image-not-pinned.md +19 -0
  322. package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
  323. package/help/errors/native-sandbox-network-unenforced.md +22 -0
  324. package/help/errors/native-sandbox-requires-catalog.md +31 -0
  325. package/help/errors/native-sandbox-unavailable.md +19 -0
  326. package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
  327. package/help/errors/native-sandbox-worker-exited.md +20 -0
  328. package/help/errors/native-sandbox-worker-lost.md +20 -0
  329. package/help/errors/native-sandbox-worker-unready.md +22 -0
  330. package/help/errors/secret-broker-body-invalid.md +26 -0
  331. package/help/errors/secret-broker-changed.md +20 -0
  332. package/help/errors/secret-broker-config-invalid.md +30 -0
  333. package/help/errors/secret-broker-conflict.md +27 -0
  334. package/help/errors/secret-broker-destination-denied.md +28 -0
  335. package/help/errors/secret-broker-value-invalid.md +28 -0
  336. package/help/errors/secret-brokered.md +24 -0
  337. package/help/errors/secret-not-brokered.md +25 -0
  338. package/help/errors/slack-auth-failed.md +48 -0
  339. package/help/errors/slack-channel-unreachable.md +39 -0
  340. package/help/errors/slack-not-configured.md +33 -0
  341. package/help/getting-started.md +4 -5
  342. package/help/github.md +18 -1
  343. package/help/identity-and-access.md +5 -1
  344. package/help/local-repositories.md +2 -3
  345. package/help/low-power-mode.md +125 -0
  346. package/help/merge-order-check.md +117 -0
  347. package/help/mobile-app.md +54 -0
  348. package/help/native-sandbox.md +136 -0
  349. package/help/observability.md +8 -0
  350. package/help/related-pull-requests.md +70 -9
  351. package/help/repo-instructions-and-skills.md +91 -0
  352. package/help/review-fix-rounds.md +10 -0
  353. package/help/slack-notifications.md +62 -0
  354. package/help/troubleshooting/coding-workers.md +21 -0
  355. package/package.json +11 -4
  356. package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
  357. package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
  358. package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
  359. package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
  360. package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
  361. package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
  362. package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
  363. package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
  364. package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
  365. package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
  366. package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
  367. package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
  368. package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
  369. package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
  370. package/prisma/schema.prisma +362 -91
@@ -0,0 +1,200 @@
1
+ /**
2
+ * The native sandbox worker contract, version 1 (docs/private native sandbox
3
+ * plan, phase 2). The worker runs the unchanged NativeEngine; everything it
4
+ * needs from outside — model calls, built-in tools, privileged sandbox
5
+ * bridges, progress, streamed text, and the terminal result — is a call to the
6
+ * trusted gateway. The worker is untrusted: the gateway validates every
7
+ * request against these schemas, and nothing in WorkerInput can carry a
8
+ * secret value or a credential.
9
+ *
10
+ * Transport-neutral: the same messages travel in-process (loopback), over a
11
+ * child process's stdio, and (phase 3) over HTTP.
12
+ */
13
+ import { z } from "zod";
14
+ import { LLM_EFFORT_LEVELS } from "../providers/llm/types.js";
15
+ export const NATIVE_WORKER_PROTOCOL_VERSION = 1;
16
+ /** Above the sandbox's 12 MiB bridge-result cap, plus envelope. */
17
+ export const MAX_MESSAGE_BYTES = 16 * 1024 * 1024;
18
+ export class ProtocolError extends Error {
19
+ code;
20
+ constructor(code, message) {
21
+ super(message ? `${code}: ${message}` : code);
22
+ this.code = code;
23
+ this.name = "ProtocolError";
24
+ }
25
+ }
26
+ export class GatewayError extends Error {
27
+ code;
28
+ constructor(code, message) {
29
+ super(message);
30
+ this.code = code;
31
+ this.name = "GatewayError";
32
+ }
33
+ }
34
+ const runId = z.string().min(1).max(64);
35
+ const callId = z.string().min(1).max(128);
36
+ const LlmMessageSchema = z
37
+ .object({
38
+ role: z.enum(["system", "user", "assistant", "tool"]),
39
+ content: z.string(),
40
+ toolCallId: z.string().optional(),
41
+ name: z.string().optional(),
42
+ toolCalls: z.array(z.object({ id: z.string(), name: z.string(), argsJson: z.string() }).strict()).optional(),
43
+ })
44
+ .strict();
45
+ const LlmToolDefSchema = z
46
+ .object({ name: z.string(), description: z.string(), parameters: z.record(z.string(), z.unknown()) })
47
+ .strict();
48
+ export const LlmRequestSchema = z
49
+ .object({
50
+ model: z.string(),
51
+ messages: z.array(LlmMessageSchema),
52
+ tools: z.array(LlmToolDefSchema).optional(),
53
+ maxTokens: z.number().int().positive().optional(),
54
+ temperature: z.number().optional(),
55
+ stopSequences: z.array(z.string()).optional(),
56
+ effort: z.enum(LLM_EFFORT_LEVELS).optional(),
57
+ })
58
+ .strict();
59
+ export const LlmStreamEventSchema = z.discriminatedUnion("type", [
60
+ z.object({ type: z.literal("text"), delta: z.string() }).strict(),
61
+ z.object({ type: z.literal("tool_call"), id: z.string(), name: z.string(), argsJson: z.string() }).strict(),
62
+ z
63
+ .object({
64
+ type: z.literal("done"),
65
+ stopReason: z.string(),
66
+ usage: z
67
+ .object({
68
+ inputTokens: z.number(),
69
+ outputTokens: z.number(),
70
+ cachedInputTokens: z.number().optional(),
71
+ cacheWriteTokens: z.number().optional(),
72
+ costUsd: z.number(),
73
+ })
74
+ .strict(),
75
+ })
76
+ .strict(),
77
+ ]);
78
+ const LoadedToolSchema = z
79
+ .object({ name: z.string(), description: z.string(), jsonSchema: z.record(z.string(), z.unknown()) })
80
+ .strict();
81
+ /** A user tool as the worker runs it: code and schema only. Capabilities stay on the gateway. */
82
+ const WorkerUserToolSchema = z.object({ code: z.string(), paramsZod: z.string() }).strict();
83
+ const PricingSchema = z
84
+ .object({
85
+ provider: z.string(),
86
+ modelId: z.string(),
87
+ encoding: z.enum(["cl100k_base", "o200k_base"]),
88
+ inputPerMTok: z.number(),
89
+ outputPerMTok: z.number(),
90
+ cachedInputPerMTok: z.number(),
91
+ cacheWritePerMTok: z.number(),
92
+ efforts: z.array(z.enum(LLM_EFFORT_LEVELS)),
93
+ thinkingMode: z.string(),
94
+ })
95
+ .strict();
96
+ /** Everything the worker is given, once, at start. No secret values and no credentials. */
97
+ export const WorkerInputSchema = z
98
+ .object({
99
+ v: z.literal(NATIVE_WORKER_PROTOCOL_VERSION),
100
+ runId,
101
+ agent: z
102
+ .object({
103
+ systemPrompt: z.string(),
104
+ model: z.string(),
105
+ budgetUsd: z.number().nonnegative(),
106
+ maxTurns: z.number().int().positive(),
107
+ effort: z.enum(LLM_EFFORT_LEVELS).optional(),
108
+ untrustedContext: z.string().optional(),
109
+ })
110
+ .strict(),
111
+ tools: z.array(LoadedToolSchema),
112
+ /** Names the gateway serves (memory, repo_*, jira_*, sub-agent memory, delegate_to_*). */
113
+ builtinTools: z.array(z.string()),
114
+ /** User tools the worker runs itself, by name. */
115
+ userTools: z.record(z.string(), WorkerUserToolSchema),
116
+ /** Tool names whose calls in one turn may run at the same time (delegations, when opted in). */
117
+ runsConcurrently: z.array(z.string()),
118
+ /** The run's pinned catalog entry, so the engine's local budget checks price without a network call. */
119
+ pricing: PricingSchema,
120
+ /**
121
+ * Where and how to reach the HTTP gateway. Absent: the gateway is on this process's stdio.
122
+ * The capability is given once, here, on the worker's stdin; it is never in its environment,
123
+ * argv, or the server's stored snapshot (only its hash is stored).
124
+ */
125
+ gateway: z
126
+ .object({ url: z.string().url(), capability: z.string().min(32).max(256) })
127
+ .strict()
128
+ .optional(),
129
+ })
130
+ .strict();
131
+ const UsageTotalsSchema = z.object({ tokensIn: z.number(), tokensOut: z.number(), costUsd: z.number() }).strict();
132
+ /** Each gateway method and its params. */
133
+ export const GatewayParamsSchemas = {
134
+ "llm.stream": z.object({ request: LlmRequestSchema }).strict(),
135
+ "llm.countTokens": z
136
+ .object({ model: z.string(), messages: z.array(LlmMessageSchema), tools: z.array(LlmToolDefSchema).optional() })
137
+ .strict(),
138
+ "builtin.call": z.object({ name: z.string().max(200), argsJson: z.string() }).strict(),
139
+ /** `invocation` names one tool call, so its bridges share one privileged host (secret redaction is per call). */
140
+ "host.call": z
141
+ .object({
142
+ tool: z.string().max(200),
143
+ invocation: z.string().min(1).max(128),
144
+ bridge: z.string().max(64),
145
+ argsJson: z.string(),
146
+ })
147
+ .strict(),
148
+ progress: z.object({ turns: z.number().int().nonnegative(), usage: UsageTotalsSchema }).strict(),
149
+ text: z.object({ seq: z.number().int().nonnegative(), delta: z.string() }).strict(),
150
+ finish: z
151
+ .object({
152
+ status: z.enum(["succeeded", "budget_exhausted", "refused", "failed"]),
153
+ finalText: z.string(),
154
+ turns: z.number().int().nonnegative(),
155
+ error: z.string().optional(),
156
+ })
157
+ .strict(),
158
+ };
159
+ export const GatewayRequestSchema = z
160
+ .object({
161
+ v: z.literal(NATIVE_WORKER_PROTOCOL_VERSION),
162
+ runId,
163
+ callId,
164
+ method: z.enum(Object.keys(GatewayParamsSchemas)),
165
+ params: z.unknown(),
166
+ })
167
+ .strict();
168
+ /** Rejects before parsing a message too large to accept. */
169
+ export function assertMessageSize(text) {
170
+ if (Buffer.byteLength(text) > MAX_MESSAGE_BYTES)
171
+ throw new ProtocolError("message_too_large");
172
+ }
173
+ function checkVersion(raw) {
174
+ if (raw && typeof raw === "object" && "v" in raw && raw.v !== NATIVE_WORKER_PROTOCOL_VERSION) {
175
+ throw new ProtocolError("unsupported_protocol_version");
176
+ }
177
+ }
178
+ /** Parses a JSON message text with the size cap, version check, and schema. */
179
+ export function parseMessage(text, schema) {
180
+ assertMessageSize(text);
181
+ let raw;
182
+ try {
183
+ raw = JSON.parse(text);
184
+ }
185
+ catch {
186
+ throw new ProtocolError("message_not_json");
187
+ }
188
+ checkVersion(raw);
189
+ const parsed = schema.safeParse(raw);
190
+ if (!parsed.success)
191
+ throw new ProtocolError("message_invalid", parsed.error.issues[0]?.message);
192
+ return parsed.data;
193
+ }
194
+ /** A gateway request's params, validated for its method. */
195
+ export function parseParams(method, params) {
196
+ const parsed = GatewayParamsSchemas[method].safeParse(params);
197
+ if (!parsed.success)
198
+ throw new ProtocolError("message_invalid", parsed.error.issues[0]?.message);
199
+ return parsed.data;
200
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The Executor for sandbox-mode native runs (docs/native-sandbox.md). Phase 1's
3
+ * RoutingExecutor sends every run whose snapshot says `sandbox` here.
4
+ *
5
+ * - start: creates the run's gateway session (pinning the run and recording
6
+ * `native-sandbox` as its backend before any worker exists), launches the
7
+ * worker, and returns. Whichever gateway replica serves the worker's
8
+ * `finish` makes the terminal write; this executor only watches for a
9
+ * worker that exits without one, and for its deadline.
10
+ * - stop: ends the session (every further gateway call is refused), kills the
11
+ * worker, records the run cancelled, and stops its open delegations.
12
+ * - recover: answers the reconciler from the worker's container state, and
13
+ * never launches one.
14
+ * - launch: the janitor removes workers whose runs have ended.
15
+ */
16
+ import { type NativeRunProviders, type RunnerDb } from "../core/runner.js";
17
+ import type { ExecutionRecoveryResult, Executor, PersistedExecutionHandle } from "../providers/executor/types.js";
18
+ import type { NativeWorkerState } from "./docker-launcher.js";
19
+ import { type DetachedWorkerLauncher, type WorkerHandle } from "./launch.js";
20
+ import { type GatewayLedgerDb } from "./ledger.js";
21
+ /** What the executor needs from a worker launcher (DockerNativeWorkerLauncher, or a test double). */
22
+ export interface ManagedWorkerLauncher extends DetachedWorkerLauncher {
23
+ handle(runId: string): WorkerHandle;
24
+ inspect(runId: string): Promise<NativeWorkerState>;
25
+ kill(runId: string): Promise<void>;
26
+ remove(runId: string): Promise<void>;
27
+ listWorkers(): Promise<{
28
+ name: string;
29
+ runHash: string;
30
+ }[]>;
31
+ removeByWorkerName(name: string): Promise<void>;
32
+ /** The URL workers dial, when only the launcher can know it (a Kubernetes Service's ClusterIP). */
33
+ resolveGatewayUrl?(): Promise<string>;
34
+ /** Background upkeep the long-lived process runs from the executor's `launch()` (the warm pool's). */
35
+ start?(): Promise<void>;
36
+ }
37
+ export interface NativeSandboxExecutorOptions {
38
+ db: RunnerDb & GatewayLedgerDb;
39
+ /** The server's providers: the run's load, and its terminal writes when the worker cannot make them. */
40
+ providers: NativeRunProviders;
41
+ launcher: ManagedWorkerLauncher;
42
+ /** What workers dial: the gateway's alias on their run network. */
43
+ gatewayUrl: string;
44
+ /** NATIVE_SANDBOX_MAX_CONCURRENT: a start past this many active sessions fails with native_sandbox_capacity. */
45
+ maxConcurrent?: number;
46
+ now?: () => number;
47
+ }
48
+ export declare const NATIVE_SANDBOX_WORKER_EXITED = "native_sandbox_worker_exited";
49
+ export declare const NATIVE_SANDBOX_DEADLINE = "native_sandbox_deadline_exceeded";
50
+ export declare class NativeSandboxExecutor implements Executor {
51
+ private readonly options;
52
+ private readonly ledger;
53
+ private readonly watching;
54
+ private readonly deadlineKilled;
55
+ constructor(options: NativeSandboxExecutorOptions);
56
+ private now;
57
+ private finishContext;
58
+ start(runId: string): Promise<void>;
59
+ /** Watches one worker in this process: its exit, and its deadline. */
60
+ private watch;
61
+ private onWorkerExit;
62
+ private endSession;
63
+ stop(runId: string, reason?: string): Promise<void>;
64
+ recover(handle: PersistedExecutionHandle): Promise<ExecutionRecoveryResult>;
65
+ /** Startup janitor: removes worker containers whose runs have ended or passed their deadline. Starts the warm pool. */
66
+ launch(): Promise<void>;
67
+ sweep(): Promise<number>;
68
+ }
@@ -0,0 +1,210 @@
1
+ /**
2
+ * The Executor for sandbox-mode native runs (docs/native-sandbox.md). Phase 1's
3
+ * RoutingExecutor sends every run whose snapshot says `sandbox` here.
4
+ *
5
+ * - start: creates the run's gateway session (pinning the run and recording
6
+ * `native-sandbox` as its backend before any worker exists), launches the
7
+ * worker, and returns. Whichever gateway replica serves the worker's
8
+ * `finish` makes the terminal write; this executor only watches for a
9
+ * worker that exits without one, and for its deadline.
10
+ * - stop: ends the session (every further gateway call is refused), kills the
11
+ * worker, records the run cancelled, and stops its open delegations.
12
+ * - recover: answers the reconciler from the worker's container state, and
13
+ * never launches one.
14
+ * - launch: the janitor removes workers whose runs have ended.
15
+ */
16
+ import { logger } from "../core/logger.js";
17
+ import { failNativeRun, nativeRunIntegrations, RunCancelledError, NATIVE_SANDBOX_BACKEND, } from "../core/runner.js";
18
+ import { nativeRunLabel } from "./docker-isolation.js";
19
+ import { startSandboxRun } from "./launch.js";
20
+ import { NATIVE_SANDBOX_CAPACITY } from "./kubernetes-launcher.js";
21
+ import { PrismaGatewayLedger } from "./ledger.js";
22
+ const executorLog = logger.child({ module: "native-sandbox-executor" });
23
+ const isUniqueViolation = (err) => typeof err === "object" && err !== null && err.code === "P2002";
24
+ export const NATIVE_SANDBOX_WORKER_EXITED = "native_sandbox_worker_exited";
25
+ export const NATIVE_SANDBOX_DEADLINE = "native_sandbox_deadline_exceeded";
26
+ export class NativeSandboxExecutor {
27
+ options;
28
+ ledger;
29
+ watching = new Map();
30
+ deadlineKilled = new Set();
31
+ constructor(options) {
32
+ this.options = options;
33
+ this.ledger = new PrismaGatewayLedger(options.db);
34
+ }
35
+ now() {
36
+ return this.options.now?.() ?? Date.now();
37
+ }
38
+ finishContext(runId) {
39
+ const { db, providers } = this.options;
40
+ return { runId, db, providers, ...nativeRunIntegrations(providers, db) };
41
+ }
42
+ async start(runId) {
43
+ const { db, providers, launcher, gatewayUrl } = this.options;
44
+ // A second start (a retried dispatch) attaches to the run's worker; it never launches another.
45
+ const existing = await db.nativeGatewaySession.findUnique({ where: { runId }, select: { deadlineAt: true } });
46
+ if (existing) {
47
+ this.watch(runId, launcher.handle(runId), existing.deadlineAt);
48
+ return;
49
+ }
50
+ // Fail fast rather than queue (a warm pool's job): every replica counts the same sessions, and a
51
+ // near-simultaneous start that overshoots by one is still bounded by the cluster's ResourceQuota.
52
+ const cap = this.options.maxConcurrent;
53
+ if (cap !== undefined && (await db.nativeGatewaySession.count({ where: { status: "active" } })) >= cap) {
54
+ throw new Error(`${NATIVE_SANDBOX_CAPACITY}: ${cap} sandbox runs are already active (NATIVE_SANDBOX_MAX_CONCURRENT).`);
55
+ }
56
+ let outcome;
57
+ try {
58
+ const url = launcher.resolveGatewayUrl ? await launcher.resolveGatewayUrl() : gatewayUrl;
59
+ outcome = await startSandboxRun({ runId, providers, db, gatewayUrl: url, launcher });
60
+ }
61
+ catch (err) {
62
+ // A concurrent start won the race for the run's one session: attach to its worker.
63
+ if (!isUniqueViolation(err)) {
64
+ // The launch failed after the session was created (e.g. isolation could not be proven):
65
+ // end the session so nothing can use its capability; the caller fails the run.
66
+ await this.endSession(runId, "cancelled").catch(() => { });
67
+ throw err;
68
+ }
69
+ const raced = await db.nativeGatewaySession.findUniqueOrThrow({ where: { runId }, select: { deadlineAt: true } });
70
+ this.watch(runId, launcher.handle(runId), raced.deadlineAt);
71
+ return;
72
+ }
73
+ if (outcome.kind === "ended")
74
+ return;
75
+ const session = await db.nativeGatewaySession.findUniqueOrThrow({
76
+ where: { id: outcome.sessionId },
77
+ select: { deadlineAt: true },
78
+ });
79
+ this.watch(runId, outcome.handle, session.deadlineAt);
80
+ }
81
+ /** Watches one worker in this process: its exit, and its deadline. */
82
+ watch(runId, handle, deadlineAt) {
83
+ if (this.watching.has(runId))
84
+ return;
85
+ const msLeft = deadlineAt.getTime() - this.now();
86
+ const timer = msLeft > 0
87
+ ? setTimeout(() => {
88
+ this.deadlineKilled.add(runId);
89
+ handle.kill();
90
+ }, msLeft)
91
+ : undefined;
92
+ if (msLeft <= 0) {
93
+ this.deadlineKilled.add(runId);
94
+ handle.kill();
95
+ }
96
+ this.watching.set(runId, timer);
97
+ void handle.exited
98
+ .then((code) => this.onWorkerExit(runId, code))
99
+ .catch((err) => executorLog.error({ err, runId }, "watching a native sandbox worker failed"));
100
+ }
101
+ async onWorkerExit(runId, exitCode) {
102
+ const timer = this.watching.get(runId);
103
+ if (timer)
104
+ clearTimeout(timer);
105
+ this.watching.delete(runId);
106
+ const { db } = this.options;
107
+ const run = await db.run.findUnique({ where: { id: runId }, select: { status: true } });
108
+ if (run && (run.status === "pending" || run.status === "running")) {
109
+ // The worker ended without its `finish`: nothing will write a result for it, so this does.
110
+ const reason = this.deadlineKilled.has(runId)
111
+ ? `${NATIVE_SANDBOX_DEADLINE}: the sandbox run passed its deadline and its worker was stopped.`
112
+ : `${NATIVE_SANDBOX_WORKER_EXITED}: the sandbox worker exited (code ${exitCode ?? "unknown"}) without a result.`;
113
+ await failNativeRun(this.finishContext(runId), new Error(reason));
114
+ }
115
+ this.deadlineKilled.delete(runId);
116
+ await this.endSession(runId, "finished");
117
+ await this.options.launcher.remove(runId).catch((err) => {
118
+ executorLog.warn({ err, runId }, "removing a native sandbox worker failed; the janitor will retry");
119
+ });
120
+ }
121
+ async endSession(runId, status) {
122
+ const session = await this.options.db.nativeGatewaySession.findUnique({ where: { runId }, select: { id: true } });
123
+ if (session)
124
+ await this.ledger.endSession(session.id, status);
125
+ return session?.id;
126
+ }
127
+ async stop(runId, reason) {
128
+ // Recorded first, before the session ends or the worker is killed: either of those makes the
129
+ // worker exit, and its exit watcher must then find the run already ended (and leave it
130
+ // cancelled) rather than record the exit as a failure.
131
+ await failNativeRun(this.finishContext(runId), new RunCancelledError(reason ?? "The run was cancelled."));
132
+ const sessionId = await this.endSession(runId, "cancelled");
133
+ await this.options.launcher.kill(runId).catch(() => { });
134
+ if (sessionId) {
135
+ // Its delegations' children belong to the server's executor; a child left running would
136
+ // spend on behalf of a parent that no longer waits for it.
137
+ for (const child of await this.ledger.openDelegationChildren(sessionId)) {
138
+ await this.options.providers.executor?.stop(child, "parent run cancelled").catch((err) => {
139
+ executorLog.warn({ err, runId, child }, "failed to stop a cancelled sandbox run's child");
140
+ });
141
+ }
142
+ }
143
+ await this.options.launcher.remove(runId).catch(() => { });
144
+ }
145
+ async recover(handle) {
146
+ if (handle.backend !== NATIVE_SANDBOX_BACKEND) {
147
+ return { state: "lost", reason: `NativeSandboxExecutor cannot recover backend "${handle.backend}".` };
148
+ }
149
+ const runId = handle.runId;
150
+ const { db, launcher } = this.options;
151
+ const [state, run, session] = await Promise.all([
152
+ launcher.inspect(runId),
153
+ db.run.findUnique({ where: { id: runId }, select: { status: true } }),
154
+ db.nativeGatewaySession.findUnique({ where: { runId }, select: { status: true, deadlineAt: true } }),
155
+ ]);
156
+ const runEnded = !run || !(run.status === "pending" || run.status === "running");
157
+ if (state.state === "running") {
158
+ if (runEnded) {
159
+ await launcher.kill(runId).catch(() => { });
160
+ await launcher.remove(runId).catch(() => { });
161
+ return { state: "terminal" };
162
+ }
163
+ // Re-attach (a restarted server): watch its exit and deadline from here.
164
+ if (session)
165
+ this.watch(runId, launcher.handle(runId), session.deadlineAt);
166
+ return { state: "active" };
167
+ }
168
+ if (state.state === "exited") {
169
+ await this.onWorkerExit(runId, state.exitCode);
170
+ return { state: "terminal" };
171
+ }
172
+ if (runEnded || session?.status === "finished")
173
+ return { state: "terminal" };
174
+ return {
175
+ state: "lost",
176
+ reason: "native_sandbox_worker_lost: the run's sandbox worker is gone and left no result; it was not relaunched.",
177
+ };
178
+ }
179
+ /** Startup janitor: removes worker containers whose runs have ended or passed their deadline. Starts the warm pool. */
180
+ async launch() {
181
+ await this.sweep().catch((err) => executorLog.warn({ err }, "native sandbox janitor failed"));
182
+ await this.options.launcher
183
+ .start?.()
184
+ .catch((err) => executorLog.warn({ err }, "native warm pool failed to start"));
185
+ }
186
+ async sweep() {
187
+ const { db, launcher } = this.options;
188
+ const workers = await launcher.listWorkers();
189
+ if (workers.length === 0)
190
+ return 0;
191
+ const sessions = await db.nativeGatewaySession.findMany({
192
+ select: { runId: true, status: true, deadlineAt: true, run: { select: { status: true } } },
193
+ });
194
+ // Docker labels carry the full run hash; Kubernetes label values carry its first 40 characters.
195
+ const labelled = sessions.map((s) => ({ hash: nativeRunLabel(s.runId), session: s }));
196
+ let removed = 0;
197
+ for (const worker of workers) {
198
+ const session = labelled.find((l) => l.hash.startsWith(worker.runHash))?.session;
199
+ const live = session &&
200
+ session.status === "active" &&
201
+ session.deadlineAt.getTime() > this.now() &&
202
+ (session.run.status === "pending" || session.run.status === "running");
203
+ if (live)
204
+ continue;
205
+ await launcher.removeByWorkerName(worker.name);
206
+ removed += 1;
207
+ }
208
+ return removed;
209
+ }
210
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The worker contract over a child process's stdin/stdout, as newline-delimited
3
+ * JSON. The control plane writes the WorkerInput as the first line, then
4
+ * answers the worker's requests; the worker writes requests and reads answers.
5
+ * Both directions are capped at MAX_MESSAGE_BYTES per line. stderr is the
6
+ * worker's diagnostics only.
7
+ *
8
+ * Frames, worker → control: { id, request }
9
+ * Frames, control → worker: { id, ok: true, result } | { id, ok: false, error: { code, message } }
10
+ * | { id, event } (llm.stream events) | { id, end: true }
11
+ */
12
+ import type { Readable, Writable } from "node:stream";
13
+ import type { NativeGateway, WorkerLauncher } from "./gateway.js";
14
+ import type { GatewayTransport } from "./worker.js";
15
+ /** Splits a byte stream into lines, refusing any line over the cap. */
16
+ export declare function readLines(stream: Readable, onLine: (line: string) => void, onError: (err: Error) => void): void;
17
+ /** The worker's side: requests out on `output`, answers in on `input`. */
18
+ export declare function createStdioTransport(input: Readable, output: Writable): GatewayTransport;
19
+ /** Serves one worker's requests from `gateway`, answering on `output`. */
20
+ export declare function serveStdioWorker(input: Readable, output: Writable, gateway: NativeGateway): void;
21
+ export interface WorkerProcessSpec {
22
+ command: string;
23
+ args: string[];
24
+ /** The worker's whole environment. Defaults to empty: it needs nothing from the server's. */
25
+ env?: Record<string, string>;
26
+ cwd?: string;
27
+ }
28
+ /** Launches the worker as a child process speaking this transport on its stdio. */
29
+ export declare function createProcessLauncher(spec: WorkerProcessSpec): WorkerLauncher;