@wardby/cli 0.7.0 → 0.9.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 (367) hide show
  1. package/.env.example +5 -5
  2. package/README.md +6 -1
  3. package/deploy/local/docker-compose.quickstart-coding.yml +11 -0
  4. package/dist/claude-coding-worker/driver.d.ts +12 -0
  5. package/dist/claude-coding-worker/driver.js +29 -7
  6. package/dist/claude-coding-worker/main.js +5 -1
  7. package/dist/claude-coding-worker/sdk.js +17 -1
  8. package/dist/claude-plugin/command.d.ts +64 -0
  9. package/dist/claude-plugin/command.js +379 -0
  10. package/dist/cli-help.d.ts +1 -1
  11. package/dist/cli-help.js +2 -1
  12. package/dist/cli.js +71 -3
  13. package/dist/coding/code-host.d.ts +16 -0
  14. package/dist/coding/code-host.js +60 -0
  15. package/dist/coding/mcp-token.d.ts +12 -0
  16. package/dist/coding/mcp-token.js +26 -0
  17. package/dist/coding/protocol.js +2 -0
  18. package/dist/coding/redact.js +6 -1
  19. package/dist/coding/transcript/recorder.d.ts +5 -4
  20. package/dist/coding/transcript/recorder.js +3 -9
  21. package/dist/coding-worker/debug-trace.d.ts +3 -1
  22. package/dist/coding-worker/debug-trace.js +4 -2
  23. package/dist/coding-worker/driver.js +8 -1
  24. package/dist/coding-worker/main.js +5 -1
  25. package/dist/coding-worker/mcp-config.d.ts +27 -0
  26. package/dist/coding-worker/mcp-config.js +32 -0
  27. package/dist/coding-worker/sdk.d.ts +36 -0
  28. package/dist/coding-worker/sdk.js +28 -1
  29. package/dist/coding-worker/types.d.ts +4 -0
  30. package/dist/config/mcp-call-limit.d.ts +8 -0
  31. package/dist/config/mcp-call-limit.js +18 -0
  32. package/dist/config/mcp-servers.d.ts +8 -0
  33. package/dist/config/mcp-servers.js +12 -0
  34. package/dist/config/test-simulators.d.ts +10 -0
  35. package/dist/config/test-simulators.js +28 -0
  36. package/dist/config/tool-timeout.d.ts +1 -0
  37. package/dist/config/tool-timeout.js +18 -0
  38. package/dist/core/coding-mcp.d.ts +36 -0
  39. package/dist/core/coding-mcp.js +253 -0
  40. package/dist/core/coding-repository.d.ts +46 -0
  41. package/dist/core/coding-repository.js +92 -0
  42. package/dist/core/delegation-slots.d.ts +27 -0
  43. package/dist/core/delegation-slots.js +44 -0
  44. package/dist/core/dispatch.d.ts +6 -2
  45. package/dist/core/dispatch.js +39 -11
  46. package/dist/core/engine-native.d.ts +2 -0
  47. package/dist/core/engine-native.js +13 -0
  48. package/dist/core/error-code.js +2 -0
  49. package/dist/core/grants.d.ts +28 -3
  50. package/dist/core/grants.js +46 -4
  51. package/dist/core/host-events.js +7 -3
  52. package/dist/core/host-status.js +2 -2
  53. package/dist/core/issue-status.js +4 -3
  54. package/dist/core/listen-address.d.ts +10 -0
  55. package/dist/core/listen-address.js +14 -0
  56. package/dist/core/mark-ready.d.ts +1 -1
  57. package/dist/core/mark-ready.js +1 -1
  58. package/dist/core/mcp-client/client.d.ts +47 -0
  59. package/dist/core/mcp-client/client.js +141 -0
  60. package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
  61. package/dist/core/mcp-client/jsonrpc.js +54 -0
  62. package/dist/core/mcp-client/results.d.ts +13 -0
  63. package/dist/core/mcp-client/results.js +42 -0
  64. package/dist/core/mcp-servers.d.ts +90 -0
  65. package/dist/core/mcp-servers.js +230 -0
  66. package/dist/core/mcp-tools.d.ts +108 -0
  67. package/dist/core/mcp-tools.js +287 -0
  68. package/dist/core/merge-order-check.js +38 -19
  69. package/dist/core/notification-dispatcher.js +2 -1
  70. package/dist/core/power-idle.d.ts +8 -2
  71. package/dist/core/power-idle.js +17 -3
  72. package/dist/core/power.d.ts +5 -0
  73. package/dist/core/power.js +5 -0
  74. package/dist/core/related-pull-requests.js +26 -10
  75. package/dist/core/retention-days.d.ts +5 -0
  76. package/dist/core/retention-days.js +14 -0
  77. package/dist/core/review-fix.js +2 -2
  78. package/dist/core/review-host-tools.js +3 -1
  79. package/dist/core/run-steps/config.d.ts +25 -0
  80. package/dist/core/run-steps/config.js +40 -0
  81. package/dist/core/run-steps/control-chars.d.ts +16 -0
  82. package/dist/core/run-steps/control-chars.js +26 -0
  83. package/dist/core/run-steps/detail.d.ts +32 -0
  84. package/dist/core/run-steps/detail.js +240 -0
  85. package/dist/core/run-steps/extract.d.ts +52 -0
  86. package/dist/core/run-steps/extract.js +467 -0
  87. package/dist/core/run-steps/ingress.d.ts +51 -0
  88. package/dist/core/run-steps/ingress.js +160 -0
  89. package/dist/core/run-steps/last-step.d.ts +15 -0
  90. package/dist/core/run-steps/last-step.js +35 -0
  91. package/dist/core/run-steps/native.d.ts +48 -0
  92. package/dist/core/run-steps/native.js +164 -0
  93. package/dist/core/run-steps/seen.d.ts +16 -0
  94. package/dist/core/run-steps/seen.js +35 -0
  95. package/dist/core/run-steps/summarize.d.ts +57 -0
  96. package/dist/core/run-steps/summarize.js +304 -0
  97. package/dist/core/run-steps/sweep.d.ts +21 -0
  98. package/dist/core/run-steps/sweep.js +41 -0
  99. package/dist/core/run-steps/types.d.ts +89 -0
  100. package/dist/core/run-steps/types.js +39 -0
  101. package/dist/core/run-steps/wire.d.ts +35 -0
  102. package/dist/core/run-steps/wire.js +47 -0
  103. package/dist/core/run-steps/writer.d.ts +49 -0
  104. package/dist/core/run-steps/writer.js +279 -0
  105. package/dist/core/runner.d.ts +70 -16
  106. package/dist/core/runner.js +296 -74
  107. package/dist/core/secret-broker-config.d.ts +2 -0
  108. package/dist/core/secret-broker-config.js +1 -1
  109. package/dist/core/secret-guard.d.ts +5 -2
  110. package/dist/core/secret-guard.js +22 -7
  111. package/dist/core/secrets.d.ts +11 -1
  112. package/dist/core/secrets.js +27 -1
  113. package/dist/core/serializable-retry.d.ts +18 -0
  114. package/dist/core/serializable-retry.js +43 -0
  115. package/dist/core/tool-admin.d.ts +5 -1
  116. package/dist/core/tool-admin.js +7 -2
  117. package/dist/core/tool-names.d.ts +13 -0
  118. package/dist/core/tool-names.js +20 -0
  119. package/dist/core/webhooks.d.ts +4 -0
  120. package/dist/core/webhooks.js +68 -49
  121. package/dist/core/workflow-run-events.js +2 -1
  122. package/dist/generated/prisma/browser.d.ts +39 -0
  123. package/dist/generated/prisma/client.d.ts +39 -0
  124. package/dist/generated/prisma/commonInputTypes.d.ts +80 -50
  125. package/dist/generated/prisma/enums.d.ts +6 -0
  126. package/dist/generated/prisma/enums.js +5 -0
  127. package/dist/generated/prisma/internal/class.d.ts +77 -0
  128. package/dist/generated/prisma/internal/class.js +4 -4
  129. package/dist/generated/prisma/internal/prismaNamespace.d.ts +632 -1
  130. package/dist/generated/prisma/internal/prismaNamespace.js +94 -3
  131. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +98 -0
  132. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +94 -3
  133. package/dist/generated/prisma/models/Agent.d.ts +372 -1
  134. package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
  135. package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
  136. package/dist/generated/prisma/models/AgentRepository.d.ts +40 -1
  137. package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
  138. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +0 -7
  139. package/dist/generated/prisma/models/CodingProxySession.d.ts +159 -2
  140. package/dist/generated/prisma/models/CodingRun.d.ts +76 -1
  141. package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
  142. package/dist/generated/prisma/models/HostProvider.js +1 -0
  143. package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
  144. package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
  145. package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
  146. package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
  147. package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
  148. package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
  149. package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
  150. package/dist/generated/prisma/models/McpServer.js +1 -0
  151. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
  152. package/dist/generated/prisma/models/Principal.d.ts +167 -0
  153. package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
  154. package/dist/generated/prisma/models/Run.d.ts +503 -1
  155. package/dist/generated/prisma/models/RunStep.d.ts +1453 -0
  156. package/dist/generated/prisma/models/RunStep.js +1 -0
  157. package/dist/generated/prisma/models/Secret.d.ts +387 -0
  158. package/dist/generated/prisma/models/Tool.d.ts +223 -1
  159. package/dist/generated/prisma/models.d.ts +7 -0
  160. package/dist/help/search.js +12 -3
  161. package/dist/help-index.json +812 -52
  162. package/dist/import/create.js +16 -1
  163. package/dist/import/neutral-schema.d.ts +1 -0
  164. package/dist/import/neutral-schema.js +2 -0
  165. package/dist/mcp/auth/access.d.ts +1 -0
  166. package/dist/mcp/auth/grants-cli.d.ts +6 -4
  167. package/dist/mcp/auth/grants-cli.js +42 -3
  168. package/dist/mcp/auth/resource-server.d.ts +3 -1
  169. package/dist/mcp/auth/resource-server.js +17 -2
  170. package/dist/mcp/context.d.ts +6 -0
  171. package/dist/mcp/index.js +21 -0
  172. package/dist/mcp/tools/agents.js +135 -20
  173. package/dist/mcp/tools/grants.js +66 -28
  174. package/dist/mcp/tools/host-providers.d.ts +2 -0
  175. package/dist/mcp/tools/host-providers.js +215 -0
  176. package/dist/mcp/tools/mcp-servers.d.ts +26 -0
  177. package/dist/mcp/tools/mcp-servers.js +481 -0
  178. package/dist/mcp/tools/power.js +2 -2
  179. package/dist/mcp/tools/repositories.js +50 -10
  180. package/dist/mcp/tools/run-access.d.ts +7 -0
  181. package/dist/mcp/tools/run-access.js +14 -0
  182. package/dist/mcp/tools/run-steps.d.ts +16 -0
  183. package/dist/mcp/tools/run-steps.js +85 -0
  184. package/dist/mcp/tools/runs.js +186 -18
  185. package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
  186. package/dist/mcp/tools/secret-elicitation.js +25 -2
  187. package/dist/mcp/tools/secrets.js +38 -4
  188. package/dist/mcp/tools/tools.d.ts +6 -4
  189. package/dist/mcp/tools/tools.js +40 -8
  190. package/dist/mcp/tools/trigger.js +28 -6
  191. package/dist/mcp/transport/http-limits.d.ts +2 -0
  192. package/dist/mcp/transport/http-limits.js +6 -2
  193. package/dist/mcp/webhooks/ingress.js +10 -0
  194. package/dist/native-worker/gateway-server.d.ts +18 -1
  195. package/dist/native-worker/gateway-server.js +38 -9
  196. package/dist/native-worker/gateway.d.ts +5 -0
  197. package/dist/native-worker/gateway.js +13 -1
  198. package/dist/native-worker/http-server.d.ts +6 -4
  199. package/dist/native-worker/http-server.js +53 -8
  200. package/dist/native-worker/ledger.d.ts +6 -2
  201. package/dist/native-worker/ledger.js +5 -4
  202. package/dist/native-worker/protocol.d.ts +1 -0
  203. package/dist/native-worker/protocol.js +4 -1
  204. package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
  205. package/dist/providers/coding-proxy/capability-hash.js +5 -0
  206. package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
  207. package/dist/providers/coding-proxy/mcp-route.js +166 -0
  208. package/dist/providers/coding-proxy/memory-ledger.d.ts +2 -0
  209. package/dist/providers/coding-proxy/memory-ledger.js +16 -0
  210. package/dist/providers/coding-proxy/prisma-ledger.d.ts +1 -0
  211. package/dist/providers/coding-proxy/prisma-ledger.js +36 -2
  212. package/dist/providers/coding-proxy/proxy.d.ts +33 -1
  213. package/dist/providers/coding-proxy/proxy.js +266 -75
  214. package/dist/providers/coding-proxy/run-step-forwarder.d.ts +42 -0
  215. package/dist/providers/coding-proxy/run-step-forwarder.js +206 -0
  216. package/dist/providers/coding-proxy/runtime.d.ts +13 -0
  217. package/dist/providers/coding-proxy/runtime.js +87 -4
  218. package/dist/providers/coding-proxy/server.d.ts +3 -0
  219. package/dist/providers/coding-proxy/server.js +10 -0
  220. package/dist/providers/coding-proxy/types.d.ts +18 -0
  221. package/dist/providers/engine/types.d.ts +26 -0
  222. package/dist/providers/executor/composition.js +5 -0
  223. package/dist/providers/executor/container.d.ts +47 -1
  224. package/dist/providers/executor/container.js +84 -8
  225. package/dist/providers/host-tools/invoke.d.ts +37 -0
  226. package/dist/providers/host-tools/invoke.js +117 -0
  227. package/dist/providers/host-tools/operations.d.ts +65 -0
  228. package/dist/providers/host-tools/operations.js +149 -0
  229. package/dist/providers/host-tools/registry.d.ts +79 -0
  230. package/dist/providers/host-tools/registry.js +362 -0
  231. package/dist/providers/host-tools/request-guard.d.ts +17 -0
  232. package/dist/providers/host-tools/request-guard.js +99 -0
  233. package/dist/providers/host-tools/self-test.d.ts +64 -0
  234. package/dist/providers/host-tools/self-test.js +142 -0
  235. package/dist/providers/jobs/docker-isolation.d.ts +2 -2
  236. package/dist/providers/jobs/docker-isolation.js +30 -8
  237. package/dist/providers/jobs/docker.d.ts +8 -0
  238. package/dist/providers/jobs/docker.js +33 -9
  239. package/dist/providers/jobs/kubernetes-isolation.d.ts +3 -1
  240. package/dist/providers/jobs/kubernetes-isolation.js +15 -2
  241. package/dist/providers/jobs/kubernetes.d.ts +13 -0
  242. package/dist/providers/jobs/kubernetes.js +28 -5
  243. package/dist/providers/jobs/types.d.ts +6 -0
  244. package/dist/providers/review-host/types.d.ts +6 -4
  245. package/dist/providers/review-host/types.js +1 -1
  246. package/dist/providers/vcs/git.d.ts +6 -2
  247. package/dist/providers/vcs/git.js +15 -4
  248. package/dist/providers/vcs/github.d.ts +2 -71
  249. package/dist/providers/vcs/github.js +8 -11
  250. package/dist/providers/vcs/index.d.ts +1 -1
  251. package/dist/providers/vcs/index.js +1 -1
  252. package/dist/providers/vcs/remote.d.ts +4 -0
  253. package/dist/providers/vcs/remote.js +7 -1
  254. package/dist/providers/vcs/routing.d.ts +12 -6
  255. package/dist/providers/vcs/routing.js +21 -6
  256. package/dist/providers/vcs/types.d.ts +71 -3
  257. package/dist/quickstart/index.d.ts +5 -0
  258. package/dist/quickstart/index.js +21 -0
  259. package/dist/quickstart-images.json +1 -1
  260. package/dist/sandbox/eval-core.d.ts +12 -2
  261. package/dist/sandbox/eval-core.js +20 -4
  262. package/dist/sandbox/host-functions.d.ts +4 -0
  263. package/dist/sandbox/host-functions.js +7 -2
  264. package/dist/sandbox/limits.d.ts +4 -1
  265. package/dist/sandbox/limits.js +4 -1
  266. package/dist/sandbox/run-in-sandbox.d.ts +6 -0
  267. package/dist/sandbox/run-in-sandbox.js +14 -2
  268. package/dist/sandbox/safe-fetch.d.ts +2 -0
  269. package/dist/sandbox/safe-fetch.js +1 -1
  270. package/dist/sandbox/secret-broker.d.ts +1 -0
  271. package/dist/sandbox/secret-broker.js +1 -1
  272. package/dist/sandbox/tool-timeout.d.ts +32 -0
  273. package/dist/sandbox/tool-timeout.js +52 -0
  274. package/dist/sandbox/user-tool.d.ts +8 -1
  275. package/dist/sandbox/user-tool.js +9 -3
  276. package/dist/serve.js +26 -18
  277. package/dist/viewer/api-schema.d.ts +66 -0
  278. package/dist/viewer/api-schema.js +31 -0
  279. package/dist/viewer/graph.js +2 -1
  280. package/dist/viewer/openapi.js +2 -1
  281. package/dist/viewer/run-detail.d.ts +2 -0
  282. package/dist/viewer/run-detail.js +26 -1
  283. package/dist/wardby-bin.js +5 -0
  284. package/docs/README.md +11 -1
  285. package/docs/agent-recipes.md +37 -4
  286. package/docs/architecture-runtime.md +1 -1
  287. package/docs/claude-code-plugin.md +208 -0
  288. package/docs/code-review-agents.md +6 -0
  289. package/docs/coding-agent-setup.md +94 -1
  290. package/docs/coding-worker-byo-images.md +4 -2
  291. package/docs/coding-worker-isolation.md +94 -7
  292. package/docs/debugging-agent-runs.md +354 -0
  293. package/docs/getting-started-gke.md +33 -11
  294. package/docs/getting-started-identity-provider.md +43 -37
  295. package/docs/getting-started.md +8 -0
  296. package/docs/host-providers.md +294 -0
  297. package/docs/mcp-servers.md +263 -0
  298. package/docs/native-sandbox.md +31 -9
  299. package/docs/security-deployment.md +161 -31
  300. package/docs/tool-secrets.md +3 -0
  301. package/docs/viewer-api.md +27 -12
  302. package/docs/viewer-api.openapi.yml +78 -2
  303. package/help/admin-viewer.md +5 -0
  304. package/help/agent-recipes.md +33 -2
  305. package/help/brokered-secrets.md +3 -0
  306. package/help/build-claude-code-image.md +1 -1
  307. package/help/claude-code-run-pane.md +63 -0
  308. package/help/deploy-gke.md +5 -0
  309. package/help/errors/coding-mcp-gateway-unavailable.md +46 -0
  310. package/help/errors/coding-mcp-pins-unavailable.md +35 -0
  311. package/help/errors/database-auth-invalid.md +1 -1
  312. package/help/errors/host-provider-error.md +40 -0
  313. package/help/errors/host-tool-failed.md +36 -0
  314. package/help/errors/mcp-call-limit.md +22 -0
  315. package/help/errors/mcp-call-timeout.md +22 -0
  316. package/help/errors/mcp-server-auth-failed.md +22 -0
  317. package/help/errors/mcp-server-credentials-unavailable.md +45 -0
  318. package/help/errors/mcp-server-error.md +28 -0
  319. package/help/errors/mcp-server-unreachable.md +22 -0
  320. package/help/errors/mcp-servers-off.md +21 -0
  321. package/help/errors/mcp-tool-not-allowed.md +26 -0
  322. package/help/errors/mcp-tool-removed.md +22 -0
  323. package/help/errors/mcp-unavailable.md +25 -0
  324. package/help/errors/native-sandbox-capacity.md +1 -1
  325. package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
  326. package/help/errors/native-sandbox-docker-failed.md +1 -1
  327. package/help/errors/native-sandbox-gateway-error.md +1 -1
  328. package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
  329. package/help/errors/native-sandbox-image-not-pinned.md +1 -1
  330. package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
  331. package/help/errors/native-sandbox-network-unenforced.md +1 -1
  332. package/help/errors/native-sandbox-requires-catalog.md +1 -1
  333. package/help/errors/native-sandbox-unavailable.md +1 -1
  334. package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
  335. package/help/errors/native-sandbox-worker-exited.md +1 -1
  336. package/help/errors/native-sandbox-worker-lost.md +1 -1
  337. package/help/errors/native-sandbox-worker-unready.md +1 -1
  338. package/help/errors/repository-not-listed.md +36 -0
  339. package/help/errors/repository-required.md +36 -0
  340. package/help/errors/tool-timeout.md +38 -0
  341. package/help/host-providers.md +40 -0
  342. package/help/identity-and-access.md +4 -1
  343. package/help/low-power-mode.md +19 -8
  344. package/help/mcp-servers.md +73 -0
  345. package/help/mcp.md +9 -2
  346. package/help/native-capabilities.md +27 -1
  347. package/help/native-sandbox.md +1 -1
  348. package/help/operating-agents.md +16 -0
  349. package/help/related-pull-requests.md +7 -3
  350. package/help/repo-instructions-and-skills.md +3 -1
  351. package/help/resume-runs-locally.md +7 -0
  352. package/help/run-steps.md +140 -0
  353. package/help/stop-run.md +1 -1
  354. package/help/troubleshooting/coding-workers.md +9 -1
  355. package/help/troubleshooting/debugging-agent-runs.md +29 -0
  356. package/package.json +2 -1
  357. package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
  358. package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
  359. package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
  360. package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
  361. package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
  362. package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
  363. package/prisma/migrations/20261110000000_run_steps/migration.sql +26 -0
  364. package/prisma/migrations/20261111000000_run_steps_viewer_notify/migration.sql +59 -0
  365. package/prisma/migrations/20261112000000_run_steps_detail/migration.sql +9 -0
  366. package/prisma/schema.prisma +211 -14
  367. package/scripts/git-askpass.sh +1 -1
@@ -0,0 +1,279 @@
1
+ /**
2
+ * The one writer of RunStep rows. Every source hands it batches (RunStepSink). Before anything is
3
+ * stored, each step's text is redacted by exact value against the secret values the loader covers:
4
+ * the agent's secrets (readable and brokered) and its attached MCP servers' secrets, the same source
5
+ * the transcript recorder uses; run capabilities are masked by token shape. The native-sandbox
6
+ * gateway capability is passed by the gateway as `extraSecretValues` and redacted the same way. A batch whose run's secret values
7
+ * can't be read writes nothing (fail closed). A step whose kind is unknown, whose callId is invalid or
8
+ * would change under redaction is dropped and not counted in stepsDropped; only steps past the cap are
9
+ * counted, once per callId. One run's batches are written in arrival order, within one process only
10
+ * (step/result ordering across processes is not guaranteed), under a row lock on the run, so seq has
11
+ * no gaps or duplicates whichever process writes. Known limits: a dropped step may be counted again
12
+ * after a process restart, after its run is evicted from the remembered set, past the per-run id
13
+ * limit, or when two processes write the same run. A result is matched only to a stored callId, which
14
+ * is already clean, so a result's callId is never persisted. At the detail level (the run's
15
+ * Run.runStepsLevel, fixed at dispatch), each step's detail text is redacted the same way
16
+ * (stepDetailer) before it is cut and stored; below it, detail material in a batch is dropped
17
+ * unread. Step text, input and output lose terminal control sequences and control characters
18
+ * (plainText: exact values masked on the raw text first, then stripControlSequences, then the full
19
+ * redaction), so no reader is sent an escape sequence. Log lines
20
+ * carry the run id, a fixed event code and an error's name: never text, never an error's message.
21
+ */
22
+ import { createHash } from "node:crypto";
23
+ import { REDACTED, redactSecrets } from "../../coding/redact.js";
24
+ import { logger } from "../logger.js";
25
+ import { loadAgentSecretValues } from "../secret-guard.js";
26
+ import { MIN_REDACTABLE_SECRET_LENGTH } from "../secret-spans.js";
27
+ import { loadRunStepRetentionDays, loadRunStepsLevel, recordedRunStepsLevel } from "./config.js";
28
+ import { stripControlSequences } from "./control-chars.js";
29
+ import { joinDetail, stepDetailer } from "./detail.js";
30
+ import { stepSummarizer } from "./summarize.js";
31
+ import { MAX_RUN_STEPS, MAX_STEP_DETAIL_CHARS, STEP_CALL_ID, STEP_STATUS, STEP_TOOL_NAME, tailOf, } from "./types.js";
32
+ const stepsLog = logger.child({ module: "run-steps" });
33
+ const DAY_MS = 24 * 60 * 60 * 1000;
34
+ const TX = { maxWait: 5_000, timeout: 10_000 };
35
+ /** How long flush() waits for queued writes at shutdown. */
36
+ export const FLUSH_TIMEOUT_MS = 5_000;
37
+ /** Over-cap callIds remembered (as 32-character hashes): at most this many per run and in all. */
38
+ const DROPPED_PER_RUN = 10_000;
39
+ const DROPPED_TOTAL = 200_000;
40
+ const callKey = (callId) => createHash("sha256").update(callId).digest("hex").slice(0, 32);
41
+ function uniqueByCallId(steps) {
42
+ const seen = new Set();
43
+ return steps.filter((step) => {
44
+ if (!STEP_CALL_ID.test(step.callId) || seen.has(step.callId))
45
+ return false;
46
+ seen.add(step.callId);
47
+ return true;
48
+ });
49
+ }
50
+ /** A private-use character: stands in for a masked value while control sequences are stripped. */
51
+ const HELD = "\uE000";
52
+ /**
53
+ * Untrusted text as plain text, safely: every secret value is masked on the raw text first, whole
54
+ * and partial (StepDetailer.premask: the text's edges and every line and ellipsis boundary), then
55
+ * control sequences are stripped (stripControlSequences), and only then does the full redaction
56
+ * run. Stripping first could take a secret's first character as a malformed sequence's final byte
57
+ * (`ESC Z` + value) and leave the rest of it matching nothing; the full redaction after the strip
58
+ * still masks a value that only the strip joined (one split by colour codes). The mask is a
59
+ * placeholder no sequence pattern can take as a byte of its own (a sequence before `[REDACTED]`
60
+ * would eat its "["), swapped for the marker after the strip.
61
+ */
62
+ function plainText(raw, premask, headWasCut = false) {
63
+ if (!premask)
64
+ return stripControlSequences(raw);
65
+ const held = premask(raw.replaceAll(HELD, ""), headWasCut, HELD);
66
+ return stripControlSequences(held).replaceAll(HELD, REDACTED);
67
+ }
68
+ /**
69
+ * A result's detail suffix: its end taken from the raw output first (tailOf), so the premask's head
70
+ * check runs at the cut the detailer will see, then plainText, then the detailer.
71
+ */
72
+ function plainOutput(raw, outputCut, premask, detailer) {
73
+ const source = tailOf(raw);
74
+ const cut = outputCut || source.cut;
75
+ return detailer.output({ output: plainText(source.text, premask, cut), outputCut: cut });
76
+ }
77
+ /** `step` without its detail-only input. */
78
+ function withoutInput(step) {
79
+ if (step.kind !== "tool" || step.input === undefined)
80
+ return step;
81
+ const { input: _input, inputTruncated: _inputTruncated, ...rest } = step;
82
+ return rest;
83
+ }
84
+ /** A step's text and input as plainText. */
85
+ function plainStep(step, premask) {
86
+ if (step.kind === "said")
87
+ return { ...step, text: plainText(step.text, premask) };
88
+ const input = step.input === undefined ? {} : { input: plainText(step.input, premask) };
89
+ return { ...step, text: plainText(step.text, premask), ...input };
90
+ }
91
+ function safeToolName(tool, secretValues) {
92
+ const shown = redactSecrets(tool, secretValues);
93
+ return STEP_TOOL_NAME.test(shown) ? shown : "tool";
94
+ }
95
+ export class RunStepWriter {
96
+ deps;
97
+ queues = new Map();
98
+ /**
99
+ * Hashes of the callIds already counted in stepsDropped, so history resent past the cap is not
100
+ * counted again. Least recently used run first; bounded in total, whatever the ids' length.
101
+ */
102
+ droppedIds = new Map();
103
+ constructor(deps) {
104
+ this.deps = deps;
105
+ }
106
+ record(runId, batch, extraSecretValues = []) {
107
+ if (this.deps.level === "off")
108
+ return Promise.resolve();
109
+ if (batch.steps.length === 0 && batch.results.length === 0)
110
+ return Promise.resolve();
111
+ const previous = this.queues.get(runId) ?? Promise.resolve();
112
+ const next = previous
113
+ .then(() => this.write(runId, batch, extraSecretValues))
114
+ .catch((err) => {
115
+ (this.deps.log ?? stepsLog).warn({ runId, event: "run_steps_write_failed", errorName: err instanceof Error ? err.name : typeof err }, "could not record a run's steps; they were dropped");
116
+ });
117
+ this.queues.set(runId, next);
118
+ void next.then(() => {
119
+ if (this.queues.get(runId) === next)
120
+ this.queues.delete(runId);
121
+ });
122
+ return next;
123
+ }
124
+ /**
125
+ * Resolves when every write queued so far has settled, or after `timeoutMs`: called before the
126
+ * process disconnects from the database, so a run's last steps are not cut off. Never rejects.
127
+ */
128
+ async flush(timeoutMs = FLUSH_TIMEOUT_MS) {
129
+ const pending = [...this.queues.values()];
130
+ if (pending.length === 0)
131
+ return;
132
+ let timer;
133
+ const bound = new Promise((resolve) => {
134
+ timer = setTimeout(resolve, timeoutMs);
135
+ });
136
+ try {
137
+ await Promise.race([Promise.allSettled(pending), bound]);
138
+ }
139
+ finally {
140
+ clearTimeout(timer);
141
+ }
142
+ }
143
+ now() {
144
+ return (this.deps.now ?? (() => new Date()))();
145
+ }
146
+ async write(runId, batch, extraSecretValues) {
147
+ const { db } = this.deps;
148
+ const run = await db.run.findUnique({ where: { id: runId }, select: { agentId: true, runStepsLevel: true } });
149
+ if (!run)
150
+ return;
151
+ const level = recordedRunStepsLevel(run.runStepsLevel, this.deps.level);
152
+ if (level === "off")
153
+ return;
154
+ const detailed = level === "detail";
155
+ // Below detail a tool's input is never stored, so it is dropped here, before any redaction.
156
+ const extracted = uniqueByCallId(batch.steps.filter((step) => step.kind === "tool" || step.kind === "said")).map((step) => (detailed ? step : withoutInput(step)));
157
+ const results = batch.results.filter((r) => STEP_CALL_ID.test(r.callId) && STEP_STATUS.test(r.status));
158
+ const outputs = detailed && results.some((r) => typeof r.output === "string");
159
+ // Read fresh for every batch that stores text (steps, or outputs at detail), never cached: a
160
+ // rotated or newly attached secret must be covered. Rejects (and the batch is dropped) when the
161
+ // values can't be read: never an unredacted write.
162
+ const needsValues = extracted.length > 0 || outputs;
163
+ const own = needsValues ? await this.deps.secretValues(run.agentId) : [];
164
+ const extras = needsValues ? extraSecretValues.filter(Boolean) : [];
165
+ const rawValues = [...own, ...extras];
166
+ // Each value also as plain text, as the step text is: a value holding a control character
167
+ // (never a stripped form too short to redact safely).
168
+ const values = [
169
+ ...new Set(rawValues.flatMap((value) => {
170
+ const plain = stripControlSequences(value);
171
+ return plain.length >= MIN_REDACTABLE_SECRET_LENGTH ? [value, plain] : [value];
172
+ })),
173
+ ];
174
+ // The summary forms are built once per batch, on the first row; the detailer (whose premask
175
+ // every text goes through first) once per batch that has any secret value.
176
+ let summarize;
177
+ let detailer;
178
+ const detailOf = () => (detailer ??= stepDetailer(values));
179
+ const premask = values.length > 0 ? (raw, headWasCut, marker) => detailOf().premask(raw, headWasCut, marker) : undefined;
180
+ const steps = extracted.map((step) => plainStep(step, premask));
181
+ const at = this.now();
182
+ const expiresAt = new Date(at.getTime() + this.deps.retentionDays * DAY_MS);
183
+ // callId is stored as text: a step whose callId holds a secret value is not stored at all.
184
+ const clean = steps.filter((step) => redactSecrets(step.callId, values) === step.callId);
185
+ const rows = clean.map((step) => ({
186
+ kind: step.kind,
187
+ tool: step.kind === "tool" ? safeToolName(step.tool, values) : null,
188
+ callId: step.callId,
189
+ summary: (summarize ??= stepSummarizer(values))(step),
190
+ detail: detailed ? detailOf().step(step).slice(0, MAX_STEP_DETAIL_CHARS) : null,
191
+ at,
192
+ expiresAt,
193
+ }));
194
+ const maxSteps = this.deps.maxSteps ?? MAX_RUN_STEPS;
195
+ const counted = this.droppedIds.get(runId) ?? new Set();
196
+ if (this.droppedIds.has(runId)) {
197
+ this.droppedIds.delete(runId);
198
+ this.droppedIds.set(runId, counted);
199
+ }
200
+ // Each result's detail suffix, computed before the transaction: redaction is CPU work, and the
201
+ // transaction holds the run's row lock.
202
+ const suffixes = results.map((result) => outputs && typeof result.output === "string"
203
+ ? plainOutput(result.output, result.outputCut === true, premask, detailOf())
204
+ : undefined);
205
+ const newlyDropped = [];
206
+ await db.$transaction(async (tx) => {
207
+ await tx.$queryRaw `SELECT 1 FROM "Run" WHERE "id" = ${runId} FOR UPDATE`;
208
+ if (rows.length > 0) {
209
+ const existing = await tx.runStep.findMany({
210
+ where: { runId, callId: { in: rows.map((row) => row.callId) } },
211
+ select: { callId: true },
212
+ });
213
+ const known = new Set(existing.map((row) => row.callId));
214
+ const fresh = rows.filter((row) => !known.has(row.callId));
215
+ const last = await tx.runStep.findFirst({ where: { runId }, orderBy: { seq: "desc" }, select: { seq: true } });
216
+ const start = last?.seq ?? 0;
217
+ const kept = fresh.slice(0, Math.max(0, maxSteps - start));
218
+ if (kept.length > 0) {
219
+ await tx.runStep.createMany({ data: kept.map((row, index) => ({ ...row, runId, seq: start + index + 1 })) });
220
+ }
221
+ const over = fresh.slice(kept.length).filter((row) => !counted.has(callKey(row.callId)));
222
+ newlyDropped.push(...over.map((row) => row.callId));
223
+ const dropped = over.length;
224
+ if (dropped > 0)
225
+ await tx.run.update({ where: { id: runId }, data: { stepsDropped: { increment: dropped } } });
226
+ }
227
+ for (const [index, result] of results.entries()) {
228
+ const suffix = suffixes[index];
229
+ if (suffix === undefined) {
230
+ // The first status wins: a result resent with the history, or replayed, changes nothing.
231
+ await tx.runStep.updateMany({
232
+ where: { runId, callId: result.callId, kind: "tool", status: null },
233
+ data: { status: result.status },
234
+ });
235
+ continue;
236
+ }
237
+ const open = await tx.runStep.findFirst({
238
+ where: { runId, callId: result.callId, kind: "tool", status: null },
239
+ select: { id: true, detail: true },
240
+ });
241
+ if (!open)
242
+ continue;
243
+ await tx.runStep.update({
244
+ where: { id: open.id },
245
+ data: { status: result.status, detail: joinDetail(open.detail, suffix) },
246
+ });
247
+ }
248
+ }, TX);
249
+ if (newlyDropped.length > 0)
250
+ this.rememberDropped(runId, counted, newlyDropped);
251
+ }
252
+ rememberDropped(runId, counted, ids) {
253
+ const limits = this.deps.droppedLimits ?? { perRun: DROPPED_PER_RUN, total: DROPPED_TOTAL };
254
+ for (const id of ids)
255
+ if (counted.size < limits.perRun)
256
+ counted.add(callKey(id));
257
+ this.droppedIds.delete(runId);
258
+ this.droppedIds.set(runId, counted);
259
+ while (this.rememberedDroppedCount() > limits.total && this.droppedIds.size > 1) {
260
+ this.droppedIds.delete(this.droppedIds.keys().next().value);
261
+ }
262
+ }
263
+ /** How many dropped callIds are remembered in all (tests). */
264
+ rememberedDroppedCount() {
265
+ let total = 0;
266
+ for (const set of this.droppedIds.values())
267
+ total += set.size;
268
+ return total;
269
+ }
270
+ }
271
+ /** The process's writer: settings from the environment (an invalid value throws, naming it). */
272
+ export function buildRunStepWriter(db, cipher, env = process.env) {
273
+ return new RunStepWriter({
274
+ db,
275
+ level: loadRunStepsLevel(env),
276
+ retentionDays: loadRunStepRetentionDays(env),
277
+ secretValues: async (agentId) => (await loadAgentSecretValues(db, cipher, agentId)).flatMap((entry) => entry.values),
278
+ });
279
+ }
@@ -21,6 +21,7 @@ import { Prisma, type PrismaClient, type Run, type RunTrigger } from "#prisma";
21
21
  import type { ProviderRegistry } from "../providers/index.js";
22
22
  import type { EngineProgress, EngineResult, LoadedTool } from "../providers/engine/types.js";
23
23
  import { RunOwnershipLostError, type StepRunner } from "../providers/engine/types.js";
24
+ import type { RunStepSink } from "./run-steps/types.js";
24
25
  import { type PrivilegedHost } from "../sandbox/host-functions.js";
25
26
  import type { safeFetch } from "../sandbox/safe-fetch.js";
26
27
  import { type RunDrivability, type WorkerLauncher } from "../native-worker/gateway.js";
@@ -36,6 +37,42 @@ import { ReviewReadLedger } from "./review-reads.js";
36
37
  import { type RepoAccessGate } from "./repo-access.js";
37
38
  import { type BudgetEventView } from "./budget-events.js";
38
39
  export declare const runnerLog: import("pino").Logger<never, boolean>;
40
+ /**
41
+ * Sub-agent dispatch uses one synthetic tool per declared child, named by the
42
+ * boundName it's attached
43
+ * under. The parent's tool call blocks until the child run reaches a
44
+ * terminal state, and its result comes back as this tool call's result.
45
+ * A run delegates at most maxDelegationsPerRun times (default one: a
46
+ * classifier deciding plan-vs-implement commits to exactly one child) and to
47
+ * each child at most once. With Agent.parallelDelegations, the delegate_to_*
48
+ * calls of one turn run at the same time (NativeEngine.runToolCalls); their
49
+ * admission (the checks below plus the child row) is still one at a time,
50
+ * through the run's delegation gate, and a child refused for budget while a
51
+ * sibling runs waits for that sibling to finish (delegation-siblings.ts).
52
+ *
53
+ * Two execution paths depending on the child's `kind`:
54
+ * - `native`: calls `executeRun` directly, bypassing any `Executor` — the
55
+ * created Run row is never marked `executionManaged`, so the reconciler
56
+ * leaves it alone even if it runs long, the same way an attended
57
+ * `wardby run` foreground execution does. Fast, in-process, no durability
58
+ * machinery needed for a native turn loop.
59
+ * - `coding`: a coding-kind child needs a real Docker container (Codex),
60
+ * which `executeRun` explicitly refuses to drive itself. Goes through
61
+ * `dispatchRun` (the same persistence path webhooks/trigger_agent use)
62
+ * with `awaitExecution: true`, so the already-existing `RoutingExecutor`
63
+ * sends it to the container backend and this call blocks until it's
64
+ * terminal — reusing proven infrastructure rather than re-implementing
65
+ * container dispatch. Marked `executionManaged: true` here (unlike the
66
+ * native path) since a long-running container crash mid-dispatch is
67
+ * exactly the case the reconciler exists for. Under the coding
68
+ * concurrency cap `Executor.start` can resolve with the child merely
69
+ * queued (still pending), so the call then polls the child row until it
70
+ * is terminal — see `waitForCodingChild`.
71
+ *
72
+ * The `delegate_to_` prefix lives in core/tool-names.ts, which reserves it
73
+ * so no user tool can be created under a name this dispatch would shadow.
74
+ */
75
+ export declare function delegateToolDef(boundName: string, parallel: boolean, repositories?: readonly string[]): LoadedTool;
39
76
  declare const DelegateArgs: z.ZodObject<{
40
77
  task: z.ZodString;
41
78
  datastoreRef: z.ZodOptional<z.ZodObject<{
@@ -45,6 +82,7 @@ declare const DelegateArgs: z.ZodObject<{
45
82
  grantParentMemoryKeys: z.ZodOptional<z.ZodArray<z.ZodString>>;
46
83
  continuePriorRun: z.ZodOptional<z.ZodString>;
47
84
  mergeOrder: z.ZodOptional<z.ZodNumber>;
85
+ repository: z.ZodOptional<z.ZodString>;
48
86
  }, z.core.$strict>;
49
87
  /** A delegate_to_* call's arguments, or the tool result refusing them. */
50
88
  export declare function parseDelegateArgs(argsJson: string): {
@@ -52,18 +90,6 @@ export declare function parseDelegateArgs(argsJson: string): {
52
90
  } | {
53
91
  refusal: string;
54
92
  };
55
- /**
56
- * At most `limit` dispatches per run (default one: a classifier deciding plan-vs-implement
57
- * commits to exactly one child), and never the same child twice, so a retry can't leave two
58
- * children racing on the same task. A delegation waiting for budget holds its place.
59
- */
60
- export declare function delegationLimitRefusal(input: {
61
- priorChildAgentIds: readonly string[];
62
- waitingChildAgentIds: readonly string[];
63
- childAgentId: string;
64
- boundName: string;
65
- limit: number;
66
- }): string | null;
67
93
  declare const DELEGATION_CHILD_SELECT: {
68
94
  readonly id: true;
69
95
  readonly kind: true;
@@ -71,10 +97,13 @@ declare const DELEGATION_CHILD_SELECT: {
71
97
  readonly budgetUsd: true;
72
98
  readonly ownerId: true;
73
99
  readonly nativeExecutionMode: true;
100
+ readonly runSteps: true;
74
101
  readonly codingProfile: {
75
102
  readonly select: {
76
103
  readonly allowWebhookTaskOverride: true;
77
104
  readonly timeoutSec: true;
105
+ readonly repository: true;
106
+ readonly baseRef: true;
78
107
  };
79
108
  };
80
109
  };
@@ -105,7 +134,7 @@ export declare function nativeChildResult(run: Pick<Run, "status" | "finalText"
105
134
  * also satisfies `dispatch.ts`'s `DispatchDb`, needed for dispatching a
106
135
  * coding-kind sub-agent from inside a running native turn loop.
107
136
  */
108
- export type RunnerDb = Pick<PrismaClient, "agent" | "run" | "agentTool" | "agentSecret" | "agentDatastore" | "budgetGroup" | "agentSubAgent" | "resourceGrant" | "codingRun" | "registryFetch" | "registryAuditRecord" | "task" | "webhook" | "$transaction" | "$queryRaw" | "agentRepository" | "runModelUsage" | "runHostCheck" | "runBudgetEvent" | "runHostStatus" | "hostIdentity" | "agentIssueProject" | "issuePullRequest" | "runIssueStatus" | "issueFingerprint" | "workItem" | "deferredReview" | "runAttribution">;
137
+ export type RunnerDb = Pick<PrismaClient, "agent" | "run" | "agentTool" | "agentSecret" | "agentMcpServer" | "secret" | "agentDatastore" | "budgetGroup" | "agentSubAgent" | "resourceGrant" | "codingRun" | "registryFetch" | "registryAuditRecord" | "task" | "webhook" | "$transaction" | "$queryRaw" | "agentRepository" | "runModelUsage" | "runHostCheck" | "runBudgetEvent" | "runHostStatus" | "hostIdentity" | "agentIssueProject" | "issuePullRequest" | "runIssueStatus" | "issueFingerprint" | "workItem" | "deferredReview" | "runAttribution">;
109
138
  /** The providers a native run needs; `executor`, `reviewHosts` and `issueTrackers` are optional capabilities. */
110
139
  export type NativeRunProviders = Pick<ProviderRegistry, "llm" | "engine" | "datastore" | "secrets" | "memory"> & {
111
140
  executor?: ProviderRegistry["executor"];
@@ -121,6 +150,8 @@ export type NativeRunProviders = Pick<ProviderRegistry, "llm" | "engine" | "data
121
150
  nativeSandbox?: WorkerLauncher;
122
151
  /** Overrides the sandbox's outbound network call — tests only. */
123
152
  sandboxFetch?: typeof safeFetch;
153
+ /** Records runs' steps (src/core/run-steps/writer.ts); absent = no steps are recorded. */
154
+ runSteps?: RunStepSink;
124
155
  };
125
156
  /**
126
157
  * Raised when a run's step boundary observed a cancellation (DbosExecutor's
@@ -262,8 +293,6 @@ export interface LoadNativeRunOptions {
262
293
  * order diverges from the record.
263
294
  */
264
295
  export declare function loadNativeRun(options: LoadNativeRunOptions): Promise<{
265
- repositoryLinks: RepositoryLink[];
266
- issueProjectLinks: IssueProjectLink[];
267
296
  agent: {
268
297
  untrustedContext?: string | undefined;
269
298
  effort?: "low" | "medium" | "high" | "xhigh" | "max" | undefined;
@@ -275,6 +304,7 @@ export declare function loadNativeRun(options: LoadNativeRunOptions): Promise<{
275
304
  tools: LoadedTool[];
276
305
  toolsByName: {
277
306
  [k: string]: {
307
+ timeoutMs?: number | undefined;
278
308
  code: string;
279
309
  paramsZod: string;
280
310
  allowedSecrets: string[];
@@ -283,6 +313,9 @@ export declare function loadNativeRun(options: LoadNativeRunOptions): Promise<{
283
313
  allowedSharedDatastorePrefixes: Record<string, string[]>;
284
314
  };
285
315
  };
316
+ mcpTools?: import("./mcp-tools.js").McpToolPin[] | undefined;
317
+ repositoryLinks: RepositoryLink[];
318
+ issueProjectLinks: IssueProjectLink[];
286
319
  parallelDelegations?: boolean | undefined;
287
320
  maxDelegationsPerRun?: number | undefined;
288
321
  agentId: string;
@@ -311,6 +344,8 @@ export interface NativeRunToolsOptions {
311
344
  issueTrackers: IssueTrackerRegistry | undefined;
312
345
  /** What earlier requests of this run read (a sandbox run's gateway restores it per request); fresh otherwise. */
313
346
  reviewReads?: ReviewReadLedger;
347
+ /** A sandboxed run's session deadline (the gateway's); an MCP tool call never runs past it. */
348
+ deadlineAt?: Date;
314
349
  }
315
350
  /** An attached user tool as the load step pinned it: its code, schema, and consented capabilities. */
316
351
  export type LoadedUserTool = LoadedNativeRun["toolsByName"][string];
@@ -336,6 +371,7 @@ export declare function readRedactionValues(accessor: SecretsAccessor, names: re
336
371
  */
337
372
  export declare function createNativeRunTools(options: NativeRunToolsOptions): {
338
373
  toolsByName: Map<string, {
374
+ timeoutMs?: number | undefined;
339
375
  code: string;
340
376
  paramsZod: string;
341
377
  allowedSecrets: string[];
@@ -348,6 +384,13 @@ export declare function createNativeRunTools(options: NativeRunToolsOptions): {
348
384
  readableSecretValues: (name: string) => Promise<string[]>;
349
385
  runUserTool: (name: string, argsJson: string) => Promise<string>;
350
386
  runSandboxTool: (name: string, argsJson: string, callId?: string) => Promise<string>;
387
+ toolTimeoutMs: (name: string) => number | undefined;
388
+ watchStop: () => {
389
+ signal: AbortSignal;
390
+ done: () => void;
391
+ };
392
+ /** Every secret value of the agent's attached MCP servers (never handed to a worker; redaction only). */
393
+ mcpSecretValues: () => Promise<string[]>;
351
394
  };
352
395
  /**
353
396
  * Live progress for observers (MCP get_run, the viewer). Absolute totals, so a DBOS replay
@@ -374,6 +417,17 @@ export declare function finishNativeRun(ctx: NativeRunFinishContext, model: stri
374
417
  export declare function failNativeRun(ctx: NativeRunFinishContext, err: unknown): Promise<Run>;
375
418
  /** The terminal write for a run that cannot continue (it ends `lost` with `reason`), then the same settle path. */
376
419
  export declare function loseNativeRun(ctx: NativeRunFinishContext, reason: string): Promise<Run>;
420
+ /** How often a user tool call in progress checks whether its run was stopped. */
421
+ export declare const TOOL_STOP_POLL_MS = 2000;
422
+ /**
423
+ * Aborts `signal` once the run is no longer drivable (stop_run, a cancelled task, a parent's
424
+ * stop). Polls every `intervalMs`, starting one interval in, so a quick call reads nothing; a
425
+ * failed read changes nothing and the next tick reads again. `done()` stops the polling.
426
+ */
427
+ export declare function watchRunStop(db: RunnerDb, runId: string, intervalMs?: number): {
428
+ signal: AbortSignal;
429
+ done: () => void;
430
+ };
377
431
  /** Where a run stands for the native gateway: still drivable, cancelled (its task), or otherwise ended. */
378
432
  export declare function runDrivability(db: RunnerDb, runId: string): Promise<RunDrivability>;
379
433
  /**
@@ -383,7 +437,7 @@ export declare function runDrivability(db: RunnerDb, runId: string): Promise<Run
383
437
  */
384
438
  export declare function sandboxWorkerInput(runId: string, loaded: LoadedNativeRun, tools: Pick<ReturnType<typeof createNativeRunTools>, "builtinHandler" | "toolsByName">): WorkerInput;
385
439
  /** What the durable delegation needs from the gateway ledger (src/native-worker/ledger.ts). */
386
- export type DelegationLedger = Pick<PrismaGatewayLedger, "claim" | "recordResult" | "setDelegation" | "delegation" | "waitingChildAgentIds">;
440
+ export type DelegationLedger = Pick<PrismaGatewayLedger, "claim" | "recordResult" | "setDelegation" | "delegation" | "waitingDelegations">;
387
441
  export interface DurableDelegationContext {
388
442
  runId: string;
389
443
  existingRun: Run;