@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,45 @@
1
+ /**
2
+ * Starting a sandbox-mode run against the HTTP gateway (native sandbox phase 3):
3
+ * create its gateway session, launch a worker with the session's one-time
4
+ * capability on its stdin, and return. Nothing waits on the worker — whichever
5
+ * gateway replica serves its `finish` makes the terminal write. Phase 4's
6
+ * executors launch the worker in a container or pod; `processWorkerLauncher`
7
+ * runs it as a local child process.
8
+ */
9
+ import { type NativeRunProviders, type RunnerDb } from "../core/runner.js";
10
+ import type { Run } from "#prisma";
11
+ import { PrismaGatewayLedger } from "./ledger.js";
12
+ import type { WorkerInput } from "./protocol.js";
13
+ import type { WorkerProcessSpec } from "./stdio.js";
14
+ export interface WorkerHandle {
15
+ /** Resolves with the worker's exit code (null when it was killed or never started). */
16
+ exited: Promise<number | null>;
17
+ kill(): void;
18
+ }
19
+ /** Starts a worker for an HTTP-gateway input and returns at once. */
20
+ export interface DetachedWorkerLauncher {
21
+ launch(input: WorkerInput): Promise<WorkerHandle>;
22
+ /**
23
+ * False when the worker's network isolation only takes effect after it starts (a Kubernetes
24
+ * NetworkPolicy): its session is then created not ready, and the launcher marks it ready once
25
+ * proven. Absent or true: ready at creation (Docker's network exists before the container).
26
+ */
27
+ readonly networkReadyAtLaunch?: boolean;
28
+ }
29
+ /** The worker as a local child process with an empty environment (by default), its input on stdin. */
30
+ export declare function processWorkerLauncher(spec: WorkerProcessSpec): DetachedWorkerLauncher;
31
+ export type StartSandboxRunOutcome = {
32
+ kind: "launched";
33
+ sessionId: string;
34
+ handle: WorkerHandle;
35
+ } | {
36
+ kind: "ended";
37
+ run: Run;
38
+ };
39
+ export declare function startSandboxRun(options: {
40
+ runId: string;
41
+ providers: NativeRunProviders;
42
+ db: RunnerDb & ConstructorParameters<typeof PrismaGatewayLedger>[0];
43
+ gatewayUrl: string;
44
+ launcher: DetachedWorkerLauncher;
45
+ }): Promise<StartSandboxRunOutcome>;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Starting a sandbox-mode run against the HTTP gateway (native sandbox phase 3):
3
+ * create its gateway session, launch a worker with the session's one-time
4
+ * capability on its stdin, and return. Nothing waits on the worker — whichever
5
+ * gateway replica serves its `finish` makes the terminal write. Phase 4's
6
+ * executors launch the worker in a container or pod; `processWorkerLauncher`
7
+ * runs it as a local child process.
8
+ */
9
+ import { spawn } from "node:child_process";
10
+ import { createSandboxSession } from "../core/runner.js";
11
+ import { PrismaGatewayLedger } from "./ledger.js";
12
+ /** The worker as a local child process with an empty environment (by default), its input on stdin. */
13
+ export function processWorkerLauncher(spec) {
14
+ return {
15
+ async launch(input) {
16
+ const child = spawn(spec.command, spec.args, {
17
+ env: spec.env ?? {},
18
+ cwd: spec.cwd,
19
+ stdio: ["pipe", "ignore", "inherit"],
20
+ });
21
+ const exited = new Promise((resolve) => {
22
+ child.on("error", () => resolve(null));
23
+ child.on("exit", (code) => resolve(code));
24
+ });
25
+ child.stdin.on("error", () => { });
26
+ child.stdin.end(`${JSON.stringify(input)}\n`);
27
+ return { exited, kill: () => child.kill("SIGKILL") };
28
+ },
29
+ };
30
+ }
31
+ export async function startSandboxRun(options) {
32
+ const session = await createSandboxSession({
33
+ runId: options.runId,
34
+ providers: options.providers,
35
+ db: options.db,
36
+ ledger: new PrismaGatewayLedger(options.db),
37
+ gatewayUrl: options.gatewayUrl,
38
+ networkReady: options.launcher.networkReadyAtLaunch !== false,
39
+ });
40
+ if (session.kind === "ended")
41
+ return session;
42
+ const handle = await options.launcher.launch(session.input);
43
+ return { kind: "launched", sessionId: session.sessionId, handle };
44
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * The native sandbox gateway's durable state (native sandbox phase 3): one
3
+ * session per sandbox-mode run, and one call row per worker callId. Modelled on
4
+ * the coding proxy's PrismaProxyLedger — a model call reserves against the
5
+ * session budget under a row lock on the session before the provider is
6
+ * called, and is settled at its actual cost after — so any control-plane
7
+ * replica can serve any call, and a restart loses nothing.
8
+ */
9
+ import type { Prisma, PrismaClient } from "#prisma";
10
+ export type GatewayLedgerDb = Pick<PrismaClient, "$transaction" | "$queryRaw" | "nativeGatewaySession" | "nativeGatewayCall">;
11
+ export interface GatewaySessionRecord {
12
+ id: string;
13
+ runId: string;
14
+ status: "active" | "finished" | "cancelled";
15
+ deadlineAt: Date;
16
+ budgetUsd: number;
17
+ snapshot: unknown;
18
+ networkReadyAt: Date | null;
19
+ }
20
+ export interface CreateGatewaySessionInput {
21
+ runId: string;
22
+ capabilityHash: string;
23
+ deadlineAt: Date;
24
+ budgetUsd: number;
25
+ snapshot: Prisma.InputJsonValue;
26
+ /** Set at creation when the launcher's isolation exists before the worker does (Docker). */
27
+ networkReadyAt?: Date | null;
28
+ }
29
+ export type ReserveOutcome = {
30
+ outcome: "reserved";
31
+ } | {
32
+ outcome: "duplicate";
33
+ } | {
34
+ outcome: "inactive";
35
+ reason: "ended" | "expired";
36
+ } | {
37
+ outcome: "budget_exhausted";
38
+ };
39
+ export interface SettledUsage {
40
+ inputTokens: number;
41
+ outputTokens: number;
42
+ cachedInputTokens: number;
43
+ cacheWriteTokens: number;
44
+ costUsd: number;
45
+ }
46
+ export interface GatewayTotals {
47
+ tokensIn: number;
48
+ tokensOut: number;
49
+ costUsd: number;
50
+ cachedInputTokens: number;
51
+ cacheWriteTokens: number;
52
+ /** Settled cost plus every live (reserved or uncertain) reservation: what the budget is checked against. */
53
+ heldUsd: number;
54
+ }
55
+ export type ClaimOutcome = {
56
+ outcome: "claimed";
57
+ } | {
58
+ outcome: "in_flight";
59
+ } | {
60
+ outcome: "done";
61
+ result: unknown;
62
+ };
63
+ export interface DelegationState {
64
+ status: "pending" | "waiting_budget" | "completed";
65
+ childRunId: string | null;
66
+ childAgentId: string | null;
67
+ /** When the delegation was first called: its wait bounds count from here. */
68
+ createdAt: Date;
69
+ }
70
+ export declare class PrismaGatewayLedger {
71
+ private readonly db;
72
+ constructor(db: GatewayLedgerDb);
73
+ createSession(input: CreateGatewaySessionInput): Promise<GatewaySessionRecord>;
74
+ /** The session a capability belongs to, whatever its status; the caller decides what each status allows. */
75
+ findSessionByCapabilityHash(capabilityHash: string): Promise<GatewaySessionRecord | null>;
76
+ /** Records that the worker's network isolation was proven: the gateway serves it from now on. */
77
+ markNetworkReady(sessionId: string, at?: Date): Promise<void>;
78
+ /** markNetworkReady by the session's run (a launcher knows the run, not the session). */
79
+ markNetworkReadyForRun(runId: string, at?: Date): Promise<void>;
80
+ endSession(sessionId: string, status: "finished" | "cancelled"): Promise<void>;
81
+ /** Reserves `reservationUsd` for a model call, or says why not. Serialized per session. */
82
+ reserve(input: {
83
+ sessionId: string;
84
+ callId: string;
85
+ reservationUsd: number;
86
+ now: Date;
87
+ }): Promise<ReserveOutcome>;
88
+ /** Settles a reserved (or uncertain) model call at what it actually cost. */
89
+ complete(sessionId: string, callId: string, usage: SettledUsage): Promise<void>;
90
+ /** Frees a reservation the provider never billed (it refused the request). */
91
+ release(sessionId: string, callId: string): Promise<void>;
92
+ /** The outcome is unknown (the connection broke mid-call): the reservation stays held. */
93
+ markUncertain(sessionId: string, callId: string): Promise<void>;
94
+ totals(sessionId: string): Promise<GatewayTotals>;
95
+ /** Claims a one-shot call by callId: the first claimant runs it, a repeat waits or replays. */
96
+ claim(sessionId: string, callId: string, method: string): Promise<ClaimOutcome>;
97
+ recordResult(sessionId: string, callId: string, result: Prisma.InputJsonValue): Promise<void>;
98
+ /** A delegation's durable progress: its sub-agent, whether it waits for budget, and its child run once started. */
99
+ setDelegation(sessionId: string, callId: string, state: {
100
+ status: "pending" | "waiting_budget";
101
+ childAgentId: string;
102
+ childRunId?: string;
103
+ }): Promise<void>;
104
+ delegation(sessionId: string, callId: string): Promise<DelegationState | null>;
105
+ /** The sub-agents other delegations of this run are waiting for budget to start. */
106
+ waitingChildAgentIds(sessionId: string, exceptCallId: string): Promise<string[]>;
107
+ /** Delegations of this session whose child run is started and not yet reported. */
108
+ openDelegationChildren(sessionId: string): Promise<string[]>;
109
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * The native sandbox gateway's durable state (native sandbox phase 3): one
3
+ * session per sandbox-mode run, and one call row per worker callId. Modelled on
4
+ * the coding proxy's PrismaProxyLedger — a model call reserves against the
5
+ * session budget under a row lock on the session before the provider is
6
+ * called, and is settled at its actual cost after — so any control-plane
7
+ * replica can serve any call, and a restart loses nothing.
8
+ */
9
+ const LEDGER_TX = { maxWait: 5_000, timeout: 20_000 };
10
+ function toSession(row) {
11
+ return { ...row, budgetUsd: Number(row.budgetUsd) };
12
+ }
13
+ export class PrismaGatewayLedger {
14
+ db;
15
+ constructor(db) {
16
+ this.db = db;
17
+ }
18
+ async createSession(input) {
19
+ return toSession(await this.db.nativeGatewaySession.create({ data: input }));
20
+ }
21
+ /** The session a capability belongs to, whatever its status; the caller decides what each status allows. */
22
+ async findSessionByCapabilityHash(capabilityHash) {
23
+ const row = await this.db.nativeGatewaySession.findUnique({ where: { capabilityHash } });
24
+ return row ? toSession(row) : null;
25
+ }
26
+ /** Records that the worker's network isolation was proven: the gateway serves it from now on. */
27
+ async markNetworkReady(sessionId, at = new Date()) {
28
+ await this.db.nativeGatewaySession.updateMany({
29
+ where: { id: sessionId, networkReadyAt: null },
30
+ data: { networkReadyAt: at },
31
+ });
32
+ }
33
+ /** markNetworkReady by the session's run (a launcher knows the run, not the session). */
34
+ async markNetworkReadyForRun(runId, at = new Date()) {
35
+ await this.db.nativeGatewaySession.updateMany({
36
+ where: { runId, networkReadyAt: null },
37
+ data: { networkReadyAt: at },
38
+ });
39
+ }
40
+ async endSession(sessionId, status) {
41
+ await this.db.nativeGatewaySession.updateMany({ where: { id: sessionId, status: "active" }, data: { status } });
42
+ }
43
+ /** Reserves `reservationUsd` for a model call, or says why not. Serialized per session. */
44
+ async reserve(input) {
45
+ return this.db.$transaction(async (tx) => {
46
+ const locked = await tx.$queryRaw `
47
+ SELECT "status", "deadlineAt", "budgetUsd" FROM "NativeGatewaySession" WHERE "id" = ${input.sessionId} FOR UPDATE`;
48
+ const session = locked[0];
49
+ if (!session || session.status !== "active")
50
+ return { outcome: "inactive", reason: "ended" };
51
+ if (input.now.getTime() >= session.deadlineAt.getTime())
52
+ return { outcome: "inactive", reason: "expired" };
53
+ const existing = await tx.nativeGatewayCall.findUnique({
54
+ where: { sessionId_callId: { sessionId: input.sessionId, callId: input.callId } },
55
+ });
56
+ if (existing)
57
+ return { outcome: "duplicate" };
58
+ const held = await heldUsd(tx, input.sessionId);
59
+ if (held + input.reservationUsd >= Number(session.budgetUsd)) {
60
+ await tx.nativeGatewaySession.updateMany({
61
+ where: { id: input.sessionId, budgetExhaustedAt: null },
62
+ data: { budgetExhaustedAt: input.now },
63
+ });
64
+ return { outcome: "budget_exhausted" };
65
+ }
66
+ await tx.nativeGatewayCall.create({
67
+ data: {
68
+ sessionId: input.sessionId,
69
+ callId: input.callId,
70
+ method: "llm.stream",
71
+ status: "reserved",
72
+ reservationUsd: input.reservationUsd,
73
+ },
74
+ });
75
+ return { outcome: "reserved" };
76
+ }, LEDGER_TX);
77
+ }
78
+ /** Settles a reserved (or uncertain) model call at what it actually cost. */
79
+ async complete(sessionId, callId, usage) {
80
+ await this.db.nativeGatewayCall.updateMany({
81
+ where: { sessionId, callId, status: { in: ["reserved", "uncertain"] } },
82
+ data: {
83
+ status: "completed",
84
+ actualCostUsd: usage.costUsd,
85
+ inputTokens: usage.inputTokens,
86
+ outputTokens: usage.outputTokens,
87
+ cachedInputTokens: usage.cachedInputTokens,
88
+ cacheWriteTokens: usage.cacheWriteTokens,
89
+ completedAt: new Date(),
90
+ },
91
+ });
92
+ }
93
+ /** Frees a reservation the provider never billed (it refused the request). */
94
+ async release(sessionId, callId) {
95
+ await this.db.nativeGatewayCall.updateMany({
96
+ where: { sessionId, callId, status: "reserved" },
97
+ data: { status: "released", completedAt: new Date() },
98
+ });
99
+ }
100
+ /** The outcome is unknown (the connection broke mid-call): the reservation stays held. */
101
+ async markUncertain(sessionId, callId) {
102
+ await this.db.nativeGatewayCall.updateMany({
103
+ where: { sessionId, callId, status: "reserved" },
104
+ data: { status: "uncertain" },
105
+ });
106
+ }
107
+ async totals(sessionId) {
108
+ const completed = await this.db.nativeGatewayCall.aggregate({
109
+ where: { sessionId, status: "completed", method: "llm.stream" },
110
+ _sum: {
111
+ inputTokens: true,
112
+ outputTokens: true,
113
+ cachedInputTokens: true,
114
+ cacheWriteTokens: true,
115
+ actualCostUsd: true,
116
+ },
117
+ });
118
+ return {
119
+ tokensIn: completed._sum.inputTokens ?? 0,
120
+ tokensOut: completed._sum.outputTokens ?? 0,
121
+ cachedInputTokens: completed._sum.cachedInputTokens ?? 0,
122
+ cacheWriteTokens: completed._sum.cacheWriteTokens ?? 0,
123
+ costUsd: Number(completed._sum.actualCostUsd ?? 0),
124
+ heldUsd: await heldUsd(this.db, sessionId),
125
+ };
126
+ }
127
+ /** Claims a one-shot call by callId: the first claimant runs it, a repeat waits or replays. */
128
+ async claim(sessionId, callId, method) {
129
+ const created = await this.db.nativeGatewayCall.createMany({
130
+ data: [{ sessionId, callId, method, status: "pending" }],
131
+ skipDuplicates: true,
132
+ });
133
+ if (created.count === 1)
134
+ return { outcome: "claimed" };
135
+ const row = await this.db.nativeGatewayCall.findUnique({ where: { sessionId_callId: { sessionId, callId } } });
136
+ if (row?.status === "completed")
137
+ return { outcome: "done", result: row.result };
138
+ return { outcome: "in_flight" };
139
+ }
140
+ async recordResult(sessionId, callId, result) {
141
+ await this.db.nativeGatewayCall.updateMany({
142
+ where: { sessionId, callId },
143
+ data: { status: "completed", result, completedAt: new Date() },
144
+ });
145
+ }
146
+ /** A delegation's durable progress: its sub-agent, whether it waits for budget, and its child run once started. */
147
+ async setDelegation(sessionId, callId, state) {
148
+ await this.db.nativeGatewayCall.updateMany({
149
+ where: { sessionId, callId, status: { in: ["pending", "waiting_budget"] } },
150
+ data: {
151
+ status: state.status,
152
+ childAgentId: state.childAgentId,
153
+ ...(state.childRunId ? { childRunId: state.childRunId } : {}),
154
+ },
155
+ });
156
+ }
157
+ async delegation(sessionId, callId) {
158
+ const row = await this.db.nativeGatewayCall.findUnique({ where: { sessionId_callId: { sessionId, callId } } });
159
+ if (!row)
160
+ return null;
161
+ const status = row.status === "waiting_budget" ? "waiting_budget" : row.status === "completed" ? "completed" : "pending";
162
+ return { status, childRunId: row.childRunId, childAgentId: row.childAgentId, createdAt: row.createdAt };
163
+ }
164
+ /** The sub-agents other delegations of this run are waiting for budget to start. */
165
+ async waitingChildAgentIds(sessionId, exceptCallId) {
166
+ const rows = await this.db.nativeGatewayCall.findMany({
167
+ where: { sessionId, status: "waiting_budget", callId: { not: exceptCallId }, childAgentId: { not: null } },
168
+ select: { childAgentId: true },
169
+ });
170
+ return rows.map((row) => row.childAgentId);
171
+ }
172
+ /** Delegations of this session whose child run is started and not yet reported. */
173
+ async openDelegationChildren(sessionId) {
174
+ const rows = await this.db.nativeGatewayCall.findMany({
175
+ where: { sessionId, status: "pending", childRunId: { not: null } },
176
+ select: { childRunId: true },
177
+ });
178
+ return rows.map((row) => row.childRunId);
179
+ }
180
+ }
181
+ async function heldUsd(db, sessionId) {
182
+ const rows = await db.$queryRaw `
183
+ SELECT COALESCE(SUM(
184
+ CASE
185
+ WHEN "status" = 'completed' THEN COALESCE("actualCostUsd", 0)
186
+ WHEN "status" IN ('reserved', 'uncertain') THEN COALESCE("reservationUsd", 0)
187
+ ELSE 0
188
+ END
189
+ ), 0) AS "held"
190
+ FROM "NativeGatewayCall" WHERE "sessionId" = ${sessionId} AND "method" = 'llm.stream'`;
191
+ return Number(rows[0]?.held ?? 0);
192
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The in-process harness transport: the worker and gateway in one process,
3
+ * with every message (worker input, requests, results, stream events, errors)
4
+ * forced through a JSON round trip so nothing crosses by reference — the same
5
+ * shape a real transport has. For tests and local development; never a
6
+ * sandbox (the worker runs in the server's own process).
7
+ */
8
+ import type { NativeGateway, WorkerLauncher } from "./gateway.js";
9
+ import { type GatewayTransport } from "./worker.js";
10
+ export declare function createLoopbackTransport(gateway: NativeGateway): GatewayTransport;
11
+ /** Runs the worker in this process over the loopback transport. */
12
+ export declare const loopbackLauncher: WorkerLauncher;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * The in-process harness transport: the worker and gateway in one process,
3
+ * with every message (worker input, requests, results, stream events, errors)
4
+ * forced through a JSON round trip so nothing crosses by reference — the same
5
+ * shape a real transport has. For tests and local development; never a
6
+ * sandbox (the worker runs in the server's own process).
7
+ */
8
+ import { GatewayError, parseMessage, WorkerInputSchema } from "./protocol.js";
9
+ import { runNativeWorker } from "./worker.js";
10
+ const wire = (value) => (value === undefined ? value : JSON.parse(JSON.stringify(value)));
11
+ function asGatewayError(err) {
12
+ if (err instanceof GatewayError)
13
+ return new GatewayError(err.code, err.message);
14
+ return new GatewayError("internal", err instanceof Error ? err.message : String(err));
15
+ }
16
+ export function createLoopbackTransport(gateway) {
17
+ return {
18
+ async call(request) {
19
+ try {
20
+ return wire(await gateway.call(wire(request)));
21
+ }
22
+ catch (err) {
23
+ throw asGatewayError(err);
24
+ }
25
+ },
26
+ async *stream(request) {
27
+ try {
28
+ for await (const event of gateway.stream(wire(request)))
29
+ yield wire(event);
30
+ }
31
+ catch (err) {
32
+ throw asGatewayError(err);
33
+ }
34
+ },
35
+ };
36
+ }
37
+ /** Runs the worker in this process over the loopback transport. */
38
+ export const loopbackLauncher = {
39
+ async run(input, gateway) {
40
+ try {
41
+ const parsed = parseMessage(JSON.stringify(input), WorkerInputSchema);
42
+ await runNativeWorker(parsed, createLoopbackTransport(gateway));
43
+ return { exitCode: 0 };
44
+ }
45
+ catch {
46
+ return { exitCode: 1 };
47
+ }
48
+ },
49
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Native sandbox worker process entry. Reads its WorkerInput as the first line
3
+ * on stdin, runs the run's engine against the gateway on stdin/stdout
4
+ * (stdio.ts), and exits 0 once it has sent its result. stdout carries only
5
+ * protocol frames; diagnostics (and the shared logger) go to stderr.
6
+ */
7
+ export {};
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Native sandbox worker process entry. Reads its WorkerInput as the first line
3
+ * on stdin, runs the run's engine against the gateway on stdin/stdout
4
+ * (stdio.ts), and exits 0 once it has sent its result. stdout carries only
5
+ * protocol frames; diagnostics (and the shared logger) go to stderr.
6
+ */
7
+ import { readFile, stat } from "node:fs/promises";
8
+ import { parseMessage, WorkerInputSchema } from "./protocol.js";
9
+ import { createHttpTransport } from "./http-transport.js";
10
+ import { createStdioTransport } from "./stdio.js";
11
+ import { WARM_WORKER_UNCLAIMED_EXIT } from "./warm-delivery.js";
12
+ import { runNativeWorker } from "./worker.js";
13
+ function firstLine() {
14
+ return new Promise((resolve, reject) => {
15
+ let buffer = "";
16
+ const onData = (chunk) => {
17
+ buffer += chunk.toString();
18
+ const newline = buffer.indexOf("\n");
19
+ if (newline >= 0) {
20
+ process.stdin.off("data", onData);
21
+ resolve(buffer.slice(0, newline));
22
+ }
23
+ };
24
+ process.stdin.on("data", onData);
25
+ process.stdin.once("end", () => reject(new Error("stdin closed before the worker input arrived")));
26
+ });
27
+ }
28
+ class UnclaimedError extends Error {
29
+ }
30
+ /**
31
+ * A warm pool worker (NATIVE_WORKER_INPUT_WAIT_MS set) starts before any run exists: it waits for
32
+ * its input file, delivered after a run claims it (warm-delivery.ts), and gives up after the wait.
33
+ */
34
+ async function waitForFile(file, waitMs) {
35
+ const until = Date.now() + waitMs;
36
+ for (;;) {
37
+ if (await stat(file).then(() => true, () => false))
38
+ return;
39
+ if (Date.now() >= until)
40
+ throw new UnclaimedError("no run claimed this warm worker in time");
41
+ await new Promise((resolve) => setTimeout(resolve, 50));
42
+ }
43
+ }
44
+ /**
45
+ * The input's source: a file when NATIVE_WORKER_INPUT_FILE names one (a Kubernetes pod mounts it
46
+ * read-only from the run's Secret; a warm worker waits for it), otherwise the first line on stdin
47
+ * (Docker, local).
48
+ */
49
+ async function readInput() {
50
+ const file = process.env.NATIVE_WORKER_INPUT_FILE;
51
+ if (!file)
52
+ return firstLine();
53
+ const waitMs = Number(process.env.NATIVE_WORKER_INPUT_WAIT_MS ?? "");
54
+ if (Number.isFinite(waitMs) && waitMs > 0)
55
+ await waitForFile(file, waitMs);
56
+ return (await readFile(file, "utf8")).trim();
57
+ }
58
+ async function main() {
59
+ const input = parseMessage(await readInput(), WorkerInputSchema);
60
+ // The gateway answers only after the worker asks, so choosing the transport after the input
61
+ // line misses nothing.
62
+ const transport = input.gateway
63
+ ? createHttpTransport({ url: input.gateway.url, capability: input.gateway.capability })
64
+ : createStdioTransport(process.stdin, process.stdout);
65
+ await runNativeWorker(input, transport);
66
+ }
67
+ main().then(() => process.exit(0), (err) => {
68
+ if (err instanceof UnclaimedError) {
69
+ process.stderr.write(`native sandbox worker: ${err.message}\n`);
70
+ process.exit(WARM_WORKER_UNCLAIMED_EXIT);
71
+ }
72
+ process.stderr.write(`native sandbox worker failed: ${err instanceof Error ? err.message : String(err)}\n`);
73
+ process.exit(1);
74
+ });