@wardby/cli 0.5.3 → 0.7.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 (763) hide show
  1. package/.env.example +33 -0
  2. package/README.md +25 -14
  3. package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
  4. package/dist/claude-coding-worker/context.d.ts +22 -0
  5. package/dist/claude-coding-worker/context.js +92 -0
  6. package/dist/claude-coding-worker/driver.d.ts +27 -3
  7. package/dist/claude-coding-worker/driver.js +161 -20
  8. package/dist/claude-coding-worker/main.js +34 -6
  9. package/dist/claude-coding-worker/sdk.js +25 -5
  10. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  11. package/dist/claude-coding-worker/tool-socket.js +111 -0
  12. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  13. package/dist/claude-coding-worker/transcript.js +77 -0
  14. package/dist/cli-help.d.ts +1 -1
  15. package/dist/cli-help.js +6 -2
  16. package/dist/cli-native-mode.d.ts +9 -0
  17. package/dist/cli-native-mode.js +20 -0
  18. package/dist/cli.d.ts +3 -1
  19. package/dist/cli.js +161 -11
  20. package/dist/coding/claude-context.d.ts +45 -0
  21. package/dist/coding/claude-context.js +434 -0
  22. package/dist/coding/continuation-wording.d.ts +35 -0
  23. package/dist/coding/continuation-wording.js +73 -0
  24. package/dist/coding/linked-issue-note.d.ts +23 -0
  25. package/dist/coding/linked-issue-note.js +47 -0
  26. package/dist/coding/merge-wording.d.ts +28 -0
  27. package/dist/coding/merge-wording.js +78 -0
  28. package/dist/coding/pr-description-note.d.ts +9 -0
  29. package/dist/coding/pr-description-note.js +32 -0
  30. package/dist/coding/profile.d.ts +50 -118
  31. package/dist/coding/profile.js +51 -4
  32. package/dist/coding/protected-path-wording.d.ts +8 -0
  33. package/dist/coding/protected-path-wording.js +1 -1
  34. package/dist/coding/protocol.d.ts +292 -270
  35. package/dist/coding/protocol.js +322 -15
  36. package/dist/coding/redact.d.ts +3 -0
  37. package/dist/coding/redact.js +12 -0
  38. package/dist/coding/registry/allowlist.d.ts +12 -0
  39. package/dist/coding/registry/allowlist.js +14 -1
  40. package/dist/coding/registry/audit-mode.d.ts +153 -0
  41. package/dist/coding/registry/audit-mode.js +304 -0
  42. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  43. package/dist/coding/registry/lockfile-shared.js +128 -0
  44. package/dist/coding/registry/lockfiles.js +1 -1
  45. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  46. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  47. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  48. package/dist/coding/registry/npm-lockfile.js +4 -6
  49. package/dist/coding/registry/npm.js +78 -8
  50. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  51. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  52. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  53. package/dist/coding/registry/pypi-plan.js +406 -0
  54. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  55. package/dist/coding/registry/pypi-requirements.js +155 -0
  56. package/dist/coding/registry/pypi.d.ts +3 -27
  57. package/dist/coding/registry/pypi.js +40 -154
  58. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  59. package/dist/coding/registry/refusal-hints.js +61 -0
  60. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  61. package/dist/coding/registry/refusal-wording.js +56 -0
  62. package/dist/coding/registry/report.d.ts +70 -8
  63. package/dist/coding/registry/report.js +112 -5
  64. package/dist/coding/registry/types.d.ts +58 -8
  65. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  66. package/dist/coding/registry/yarn-lockfile.js +367 -0
  67. package/dist/coding/services/catalog.d.ts +37 -351
  68. package/dist/coding/transcript/claude-code.d.ts +13 -0
  69. package/dist/coding/transcript/claude-code.js +273 -0
  70. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  71. package/dist/coding/transcript/download-protocol.js +18 -0
  72. package/dist/coding/transcript/format.d.ts +20 -0
  73. package/dist/coding/transcript/format.js +32 -0
  74. package/dist/coding/transcript/recorder.d.ts +51 -0
  75. package/dist/coding/transcript/recorder.js +225 -0
  76. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  77. package/dist/coding/transcript/resume/checkout.js +203 -0
  78. package/dist/coding/transcript/resume/command.d.ts +17 -0
  79. package/dist/coding/transcript/resume/command.js +176 -0
  80. package/dist/coding/transcript/resume/download.d.ts +20 -0
  81. package/dist/coding/transcript/resume/download.js +153 -0
  82. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  83. package/dist/coding/transcript/resume/launch.js +128 -0
  84. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  85. package/dist/coding/transcript/resume/session-file.js +79 -0
  86. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  87. package/dist/coding/transcript/resume/stand-in.js +49 -0
  88. package/dist/coding-worker/artifact.d.ts +16 -3
  89. package/dist/coding-worker/artifact.js +5 -3
  90. package/dist/coding-worker/debug-trace.d.ts +6 -5
  91. package/dist/coding-worker/debug-trace.js +13 -18
  92. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  93. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  94. package/dist/coding-worker/driver.d.ts +4 -3
  95. package/dist/coding-worker/driver.js +118 -38
  96. package/dist/coding-worker/errors.d.ts +1 -0
  97. package/dist/coding-worker/errors.js +32 -0
  98. package/dist/coding-worker/sdk.d.ts +6 -0
  99. package/dist/coding-worker/sdk.js +1 -0
  100. package/dist/coding-worker/skills.d.ts +23 -0
  101. package/dist/coding-worker/skills.js +117 -0
  102. package/dist/coding-worker/task-note.d.ts +11 -0
  103. package/dist/coding-worker/task-note.js +13 -0
  104. package/dist/coding-worker/types.d.ts +13 -0
  105. package/dist/config/dependency-cache.d.ts +23 -0
  106. package/dist/config/dependency-cache.js +32 -0
  107. package/dist/config/github-allowed-accounts.d.ts +15 -0
  108. package/dist/config/github-allowed-accounts.js +36 -0
  109. package/dist/config/low-power.d.ts +12 -0
  110. package/dist/config/low-power.js +18 -0
  111. package/dist/config/mobile.d.ts +12 -0
  112. package/dist/config/mobile.js +18 -0
  113. package/dist/config/providers.d.ts +65 -3
  114. package/dist/config/providers.js +147 -11
  115. package/dist/config/test-simulators.d.ts +82 -0
  116. package/dist/config/test-simulators.js +305 -0
  117. package/dist/core/async-context.d.ts +2 -0
  118. package/dist/core/async-context.js +12 -0
  119. package/dist/core/budget-events.d.ts +108 -0
  120. package/dist/core/budget-events.js +346 -0
  121. package/dist/core/budget-groups.d.ts +50 -1
  122. package/dist/core/budget-groups.js +236 -27
  123. package/dist/core/budget-stopped-head.d.ts +46 -0
  124. package/dist/core/budget-stopped-head.js +81 -0
  125. package/dist/core/budget-topup.d.ts +51 -0
  126. package/dist/core/budget-topup.js +156 -0
  127. package/dist/core/budget-wording.d.ts +16 -2
  128. package/dist/core/budget-wording.js +40 -2
  129. package/dist/core/coding-queue.d.ts +2 -1
  130. package/dist/core/coding-queue.js +7 -0
  131. package/dist/core/cron.d.ts +19 -1
  132. package/dist/core/cron.js +17 -0
  133. package/dist/core/datastores.js +1 -1
  134. package/dist/core/db.d.ts +16 -6
  135. package/dist/core/db.js +12 -10
  136. package/dist/core/deferred-coding.d.ts +14 -0
  137. package/dist/core/deferred-coding.js +62 -0
  138. package/dist/core/delegation-child.d.ts +25 -0
  139. package/dist/core/delegation-child.js +37 -0
  140. package/dist/core/dispatch.d.ts +53 -0
  141. package/dist/core/dispatch.js +167 -57
  142. package/dist/core/engine-native.js +10 -6
  143. package/dist/core/error-code.d.ts +38 -0
  144. package/dist/core/error-code.js +168 -0
  145. package/dist/core/grants.d.ts +19 -6
  146. package/dist/core/grants.js +55 -6
  147. package/dist/core/host-events.d.ts +67 -5
  148. package/dist/core/host-events.js +571 -37
  149. package/dist/core/host-status.d.ts +85 -3
  150. package/dist/core/host-status.js +298 -20
  151. package/dist/core/issue-bridge.d.ts +50 -6
  152. package/dist/core/issue-bridge.js +151 -20
  153. package/dist/core/issue-events.d.ts +1 -1
  154. package/dist/core/issue-events.js +16 -11
  155. package/dist/core/issue-status.d.ts +1 -1
  156. package/dist/core/issue-status.js +68 -29
  157. package/dist/core/logger.d.ts +5 -0
  158. package/dist/core/logger.js +14 -1
  159. package/dist/core/lost-run-children.d.ts +6 -0
  160. package/dist/core/lost-run-children.js +32 -0
  161. package/dist/core/mark-ready.d.ts +34 -0
  162. package/dist/core/mark-ready.js +152 -0
  163. package/dist/core/markdown-code.d.ts +8 -0
  164. package/dist/core/markdown-code.js +107 -0
  165. package/dist/core/memory-tools.js +7 -0
  166. package/dist/core/merge-order-check.d.ts +130 -0
  167. package/dist/core/merge-order-check.js +343 -0
  168. package/dist/core/notification-dispatcher.d.ts +70 -0
  169. package/dist/core/notification-dispatcher.js +368 -0
  170. package/dist/core/notification-templates.d.ts +19 -0
  171. package/dist/core/notification-templates.js +139 -0
  172. package/dist/core/notifications.d.ts +10 -0
  173. package/dist/core/notifications.js +38 -0
  174. package/dist/core/pg-auth.d.ts +22 -0
  175. package/dist/core/pg-auth.js +152 -0
  176. package/dist/core/power-composition.d.ts +16 -0
  177. package/dist/core/power-composition.js +37 -0
  178. package/dist/core/power-idle.d.ts +14 -0
  179. package/dist/core/power-idle.js +30 -0
  180. package/dist/core/power.d.ts +71 -0
  181. package/dist/core/power.js +202 -0
  182. package/dist/core/pull-request-state-sync.js +2 -2
  183. package/dist/core/reconciler.d.ts +8 -5
  184. package/dist/core/reconciler.js +37 -6
  185. package/dist/core/related-pull-requests.d.ts +59 -7
  186. package/dist/core/related-pull-requests.js +140 -25
  187. package/dist/core/reply-parts.d.ts +21 -0
  188. package/dist/core/reply-parts.js +73 -0
  189. package/dist/core/repo-access.d.ts +15 -0
  190. package/dist/core/repo-access.js +66 -0
  191. package/dist/core/review-fix.d.ts +38 -1
  192. package/dist/core/review-fix.js +209 -7
  193. package/dist/core/review-host-checks.d.ts +1 -1
  194. package/dist/core/review-host-tools.d.ts +23 -0
  195. package/dist/core/review-host-tools.js +156 -14
  196. package/dist/core/review-reads.d.ts +55 -0
  197. package/dist/core/review-reads.js +233 -0
  198. package/dist/core/run-status.d.ts +12 -0
  199. package/dist/core/run-status.js +12 -0
  200. package/dist/core/runner.d.ts +384 -5
  201. package/dist/core/runner.js +1244 -372
  202. package/dist/core/schedule-start.d.ts +12 -0
  203. package/dist/core/schedule-start.js +14 -0
  204. package/dist/core/secret-broker-config.d.ts +39 -0
  205. package/dist/core/secret-broker-config.js +112 -0
  206. package/dist/core/secret-guard.d.ts +46 -0
  207. package/dist/core/secret-guard.js +104 -0
  208. package/dist/core/secret-guarded-stores.d.ts +12 -0
  209. package/dist/core/secret-guarded-stores.js +41 -0
  210. package/dist/core/secret-spans.d.ts +50 -0
  211. package/dist/core/secret-spans.js +94 -0
  212. package/dist/core/secrets.d.ts +39 -4
  213. package/dist/core/secrets.js +148 -40
  214. package/dist/core/stop-run.d.ts +46 -0
  215. package/dist/core/stop-run.js +61 -0
  216. package/dist/core/workflow-event-recorder.d.ts +14 -0
  217. package/dist/core/workflow-event-recorder.js +120 -0
  218. package/dist/core/workflow-events.d.ts +94 -0
  219. package/dist/core/workflow-events.js +48 -0
  220. package/dist/core/workflow-run-events.d.ts +18 -0
  221. package/dist/core/workflow-run-events.js +75 -0
  222. package/dist/core/zod-json-schema.d.ts +4 -0
  223. package/dist/core/zod-json-schema.js +39 -0
  224. package/dist/core/zod3-window.d.ts +35 -0
  225. package/dist/core/zod3-window.js +124 -0
  226. package/dist/generated/prisma/browser.d.ts +92 -3
  227. package/dist/generated/prisma/client.d.ts +92 -3
  228. package/dist/generated/prisma/commonInputTypes.d.ts +364 -54
  229. package/dist/generated/prisma/enums.d.ts +37 -0
  230. package/dist/generated/prisma/enums.js +31 -0
  231. package/dist/generated/prisma/internal/class.d.ts +132 -0
  232. package/dist/generated/prisma/internal/class.js +4 -4
  233. package/dist/generated/prisma/internal/prismaNamespace.d.ts +1332 -142
  234. package/dist/generated/prisma/internal/prismaNamespace.js +227 -5
  235. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +234 -0
  236. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +227 -5
  237. package/dist/generated/prisma/models/Agent.d.ts +464 -7
  238. package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
  239. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +301 -1
  240. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  241. package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
  242. package/dist/generated/prisma/models/CodingRun.d.ts +1841 -1
  243. package/dist/generated/prisma/models/DeferredReview.d.ts +78 -1
  244. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  245. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  246. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  247. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  248. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +1713 -0
  249. package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
  250. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1551 -0
  251. package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
  252. package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
  253. package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
  254. package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
  255. package/dist/generated/prisma/models/NotificationChannel.js +1 -0
  256. package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
  257. package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
  258. package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
  259. package/dist/generated/prisma/models/NotificationThread.js +1 -0
  260. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  261. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  262. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  263. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  264. package/dist/generated/prisma/models/Run.d.ts +1619 -58
  265. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  266. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  267. package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
  268. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  269. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  270. package/dist/generated/prisma/models/Secret.d.ts +37 -1
  271. package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
  272. package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
  273. package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
  274. package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
  275. package/dist/generated/prisma/models.d.ts +12 -0
  276. package/dist/help/build.js +4 -2
  277. package/dist/help/catalog.d.ts +1 -1
  278. package/dist/help/catalog.js +31 -6
  279. package/dist/help-index.json +2584 -146
  280. package/dist/import/create.js +49 -3
  281. package/dist/import/neutral-schema.d.ts +50 -277
  282. package/dist/import/neutral-schema.js +7 -4
  283. package/dist/knowledge/check.d.ts +1 -1
  284. package/dist/knowledge/cli.d.ts +11 -1
  285. package/dist/knowledge/cli.js +37 -4
  286. package/dist/knowledge/concept.d.ts +3 -19
  287. package/dist/knowledge/location.d.ts +31 -0
  288. package/dist/knowledge/location.js +78 -0
  289. package/dist/mcp/auth/access.d.ts +11 -2
  290. package/dist/mcp/auth/access.js +15 -1
  291. package/dist/mcp/auth/ownership.d.ts +7 -7
  292. package/dist/mcp/auth/repo-authorization.js +14 -0
  293. package/dist/mcp/auth/resource-server.d.ts +2 -1
  294. package/dist/mcp/auth/resource-server.js +7 -2
  295. package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
  296. package/dist/mcp/auth/self-hosted/browser.js +19 -6
  297. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  298. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  299. package/dist/mcp/context.d.ts +6 -0
  300. package/dist/mcp/host-events/github-ingress.d.ts +25 -1
  301. package/dist/mcp/host-events/github-ingress.js +70 -1
  302. package/dist/mcp/index.d.ts +19 -0
  303. package/dist/mcp/index.js +117 -20
  304. package/dist/mcp/server.d.ts +13 -0
  305. package/dist/mcp/server.js +33 -14
  306. package/dist/mcp/tools/agents.d.ts +4 -0
  307. package/dist/mcp/tools/agents.js +277 -24
  308. package/dist/mcp/tools/datastore.js +17 -8
  309. package/dist/mcp/tools/grants.js +9 -3
  310. package/dist/mcp/tools/memory.js +11 -1
  311. package/dist/mcp/tools/notification-channels.d.ts +2 -0
  312. package/dist/mcp/tools/notification-channels.js +293 -0
  313. package/dist/mcp/tools/packages.d.ts +2 -0
  314. package/dist/mcp/tools/packages.js +195 -0
  315. package/dist/mcp/tools/power.d.ts +2 -0
  316. package/dist/mcp/tools/power.js +77 -0
  317. package/dist/mcp/tools/repositories.js +18 -5
  318. package/dist/mcp/tools/run-access.d.ts +16 -0
  319. package/dist/mcp/tools/run-access.js +25 -0
  320. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  321. package/dist/mcp/tools/run-transcript-download.js +129 -0
  322. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  323. package/dist/mcp/tools/run-transcript.js +70 -0
  324. package/dist/mcp/tools/runs.d.ts +0 -6
  325. package/dist/mcp/tools/runs.js +41 -14
  326. package/dist/mcp/tools/scheduling.js +3 -1
  327. package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
  328. package/dist/mcp/tools/secret-broker-compat.js +23 -0
  329. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
  330. package/dist/mcp/tools/secret-elicitation-form.js +205 -10
  331. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  332. package/dist/mcp/tools/secret-elicitation-server.js +10 -54
  333. package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
  334. package/dist/mcp/tools/secret-elicitation.js +110 -12
  335. package/dist/mcp/tools/secrets.js +186 -9
  336. package/dist/mcp/tools/stop-run.d.ts +2 -0
  337. package/dist/mcp/tools/stop-run.js +82 -0
  338. package/dist/mcp/tools/subagents.js +2 -2
  339. package/dist/mcp/tools/tools.d.ts +2 -2
  340. package/dist/mcp/tools/tools.js +47 -11
  341. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  342. package/dist/mcp/transport/stdio-link-host.js +67 -0
  343. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  344. package/dist/mcp/transport/streamable-http.js +41 -1
  345. package/dist/native-worker/composition.d.ts +23 -0
  346. package/dist/native-worker/composition.js +77 -0
  347. package/dist/native-worker/docker-isolation.d.ts +65 -0
  348. package/dist/native-worker/docker-isolation.js +183 -0
  349. package/dist/native-worker/docker-launcher.d.ts +110 -0
  350. package/dist/native-worker/docker-launcher.js +297 -0
  351. package/dist/native-worker/gateway-server.d.ts +77 -0
  352. package/dist/native-worker/gateway-server.js +412 -0
  353. package/dist/native-worker/gateway.d.ts +70 -0
  354. package/dist/native-worker/gateway.js +263 -0
  355. package/dist/native-worker/http-server.d.ts +24 -0
  356. package/dist/native-worker/http-server.js +113 -0
  357. package/dist/native-worker/http-transport.d.ts +17 -0
  358. package/dist/native-worker/http-transport.js +88 -0
  359. package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
  360. package/dist/native-worker/kubernetes-isolation.js +218 -0
  361. package/dist/native-worker/kubernetes-launcher.d.ts +106 -0
  362. package/dist/native-worker/kubernetes-launcher.js +375 -0
  363. package/dist/native-worker/launch.d.ts +62 -0
  364. package/dist/native-worker/launch.js +49 -0
  365. package/dist/native-worker/ledger.d.ts +125 -0
  366. package/dist/native-worker/ledger.js +245 -0
  367. package/dist/native-worker/loopback.d.ts +12 -0
  368. package/dist/native-worker/loopback.js +44 -0
  369. package/dist/native-worker/main.d.ts +8 -0
  370. package/dist/native-worker/main.js +85 -0
  371. package/dist/native-worker/protocol.d.ts +296 -0
  372. package/dist/native-worker/protocol.js +246 -0
  373. package/dist/native-worker/sandbox-executor.d.ts +83 -0
  374. package/dist/native-worker/sandbox-executor.js +284 -0
  375. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  376. package/dist/native-worker/stderr-redaction.js +237 -0
  377. package/dist/native-worker/stdio.d.ts +29 -0
  378. package/dist/native-worker/stdio.js +189 -0
  379. package/dist/native-worker/warm-delivery.d.ts +16 -0
  380. package/dist/native-worker/warm-delivery.js +33 -0
  381. package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
  382. package/dist/native-worker/warm-pool-ledger.js +73 -0
  383. package/dist/native-worker/warm-pool.d.ts +107 -0
  384. package/dist/native-worker/warm-pool.js +283 -0
  385. package/dist/native-worker/worker.d.ts +17 -0
  386. package/dist/native-worker/worker.js +141 -0
  387. package/dist/observability/metrics.js +6 -1
  388. package/dist/providers/auth/authorization-server.d.ts +3 -0
  389. package/dist/providers/auth/index.js +2 -0
  390. package/dist/providers/auth/self-hosted.d.ts +14 -2
  391. package/dist/providers/auth/self-hosted.js +54 -4
  392. package/dist/providers/chat/fake.d.ts +46 -0
  393. package/dist/providers/chat/fake.js +39 -0
  394. package/dist/providers/chat/index.d.ts +4 -0
  395. package/dist/providers/chat/index.js +8 -0
  396. package/dist/providers/chat/slack.d.ts +37 -0
  397. package/dist/providers/chat/slack.js +105 -0
  398. package/dist/providers/chat/types.d.ts +42 -0
  399. package/dist/providers/chat/types.js +19 -0
  400. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  401. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  402. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  403. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  404. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  405. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  406. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  407. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  408. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  409. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  410. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  411. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  412. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  413. package/dist/providers/coding-proxy/hold.js +86 -0
  414. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  415. package/dist/providers/coding-proxy/interrupted.js +104 -0
  416. package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
  417. package/dist/providers/coding-proxy/memory-ledger.js +84 -8
  418. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  419. package/dist/providers/coding-proxy/metering.js +27 -4
  420. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
  421. package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
  422. package/dist/providers/coding-proxy/proxy.d.ts +14 -1
  423. package/dist/providers/coding-proxy/proxy.js +166 -14
  424. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  425. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  426. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  427. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  428. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  429. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  430. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  431. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  432. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  433. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  434. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  435. package/dist/providers/coding-proxy/registry/service.js +579 -112
  436. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  437. package/dist/providers/coding-proxy/registry/store.js +54 -1
  438. package/dist/providers/coding-proxy/runtime.d.ts +4 -0
  439. package/dist/providers/coding-proxy/runtime.js +78 -16
  440. package/dist/providers/coding-proxy/server.d.ts +6 -1
  441. package/dist/providers/coding-proxy/server.js +45 -1
  442. package/dist/providers/coding-proxy/types.d.ts +65 -1
  443. package/dist/providers/datastore/types.d.ts +5 -0
  444. package/dist/providers/engine/types.d.ts +36 -2
  445. package/dist/providers/engine/types.js +39 -0
  446. package/dist/providers/executor/composition.d.ts +31 -1
  447. package/dist/providers/executor/composition.js +81 -8
  448. package/dist/providers/executor/container.d.ts +385 -9
  449. package/dist/providers/executor/container.js +1234 -99
  450. package/dist/providers/executor/dbos-status.d.ts +31 -0
  451. package/dist/providers/executor/dbos-status.js +64 -0
  452. package/dist/providers/executor/dbos.d.ts +91 -0
  453. package/dist/providers/executor/dbos.js +319 -26
  454. package/dist/providers/executor/deferred.d.ts +44 -0
  455. package/dist/providers/executor/deferred.js +100 -0
  456. package/dist/providers/executor/in-process.d.ts +9 -1
  457. package/dist/providers/executor/in-process.js +14 -4
  458. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  459. package/dist/providers/executor/linked-issue-reader.js +30 -0
  460. package/dist/providers/executor/routing.d.ts +39 -10
  461. package/dist/providers/executor/routing.js +77 -32
  462. package/dist/providers/executor/types.d.ts +25 -0
  463. package/dist/providers/index.d.ts +2 -1
  464. package/dist/providers/issue-tracker/types.d.ts +17 -0
  465. package/dist/providers/issue-tracker/types.js +39 -1
  466. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  467. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  468. package/dist/providers/jobs/docker-isolation.d.ts +8 -0
  469. package/dist/providers/jobs/docker-isolation.js +17 -0
  470. package/dist/providers/jobs/docker.d.ts +1 -0
  471. package/dist/providers/jobs/docker.js +29 -4
  472. package/dist/providers/jobs/fake-kubernetes-api.d.ts +23 -2
  473. package/dist/providers/jobs/fake-kubernetes-api.js +45 -1
  474. package/dist/providers/jobs/kubernetes-api.d.ts +25 -1
  475. package/dist/providers/jobs/kubernetes-api.js +17 -0
  476. package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
  477. package/dist/providers/jobs/kubernetes-client.js +61 -3
  478. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
  479. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
  480. package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
  481. package/dist/providers/jobs/kubernetes-isolation.js +23 -1
  482. package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
  483. package/dist/providers/jobs/kubernetes-platform.js +38 -1
  484. package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
  485. package/dist/providers/jobs/kubernetes-preflight.js +4 -2
  486. package/dist/providers/jobs/kubernetes.d.ts +42 -2
  487. package/dist/providers/jobs/kubernetes.js +178 -19
  488. package/dist/providers/jobs/metadata-probes.d.ts +11 -0
  489. package/dist/providers/jobs/metadata-probes.js +13 -0
  490. package/dist/providers/jobs/types.d.ts +42 -0
  491. package/dist/providers/jobs/types.js +13 -1
  492. package/dist/providers/llm/anthropic.js +5 -1
  493. package/dist/providers/llm/bedrock.d.ts +0 -12
  494. package/dist/providers/llm/bedrock.js +4 -0
  495. package/dist/providers/llm/claude-messages.d.ts +3 -1
  496. package/dist/providers/llm/claude-messages.js +4 -1
  497. package/dist/providers/llm/claude-provider.d.ts +2 -2
  498. package/dist/providers/llm/claude-provider.js +2 -2
  499. package/dist/providers/llm/openai.d.ts +2 -2
  500. package/dist/providers/llm/openai.js +6 -2
  501. package/dist/providers/llm/routing.d.ts +2 -2
  502. package/dist/providers/llm/routing.js +2 -2
  503. package/dist/providers/llm/types.d.ts +12 -2
  504. package/dist/providers/review-host/github-events.d.ts +9 -1
  505. package/dist/providers/review-host/github-events.js +34 -12
  506. package/dist/providers/review-host/github.d.ts +39 -2
  507. package/dist/providers/review-host/github.js +274 -29
  508. package/dist/providers/review-host/local.d.ts +8 -4
  509. package/dist/providers/review-host/local.js +49 -31
  510. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  511. package/dist/providers/review-host/patch-pages.js +176 -0
  512. package/dist/providers/review-host/review-format.d.ts +19 -1
  513. package/dist/providers/review-host/review-format.js +38 -7
  514. package/dist/providers/review-host/types.d.ts +157 -2
  515. package/dist/providers/review-host/types.js +8 -0
  516. package/dist/providers/storage/gcs.d.ts +63 -0
  517. package/dist/providers/storage/gcs.js +69 -0
  518. package/dist/providers/storage/index.d.ts +15 -0
  519. package/dist/providers/storage/index.js +14 -0
  520. package/dist/providers/storage/local.d.ts +24 -0
  521. package/dist/providers/storage/local.js +92 -0
  522. package/dist/providers/storage/meter.d.ts +14 -0
  523. package/dist/providers/storage/meter.js +34 -0
  524. package/dist/providers/storage/s3.d.ts +41 -0
  525. package/dist/providers/storage/s3.js +107 -0
  526. package/dist/providers/storage/types.d.ts +37 -3
  527. package/dist/providers/storage/types.js +21 -4
  528. package/dist/providers/vcs/git.d.ts +33 -2
  529. package/dist/providers/vcs/git.js +324 -22
  530. package/dist/providers/vcs/github-remote.d.ts +26 -3
  531. package/dist/providers/vcs/github-remote.js +124 -14
  532. package/dist/providers/vcs/github.d.ts +246 -12
  533. package/dist/providers/vcs/github.js +521 -61
  534. package/dist/providers/vcs/index.js +8 -1
  535. package/dist/providers/vcs/pr-description.d.ts +127 -0
  536. package/dist/providers/vcs/pr-description.js +270 -0
  537. package/dist/providers/vcs/remote.d.ts +33 -1
  538. package/dist/providers/vcs/routing.d.ts +4 -2
  539. package/dist/providers/vcs/routing.js +6 -0
  540. package/dist/providers/vcs/types.d.ts +80 -3
  541. package/dist/quickstart/coding-seed.d.ts +21 -3
  542. package/dist/quickstart/coding-seed.js +283 -3
  543. package/dist/quickstart/images.d.ts +2 -0
  544. package/dist/quickstart/images.js +7 -1
  545. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  546. package/dist/quickstart/reviewer-prompt.js +6 -6
  547. package/dist/quickstart-images.json +1 -1
  548. package/dist/sandbox/brokered-fetch.d.ts +23 -0
  549. package/dist/sandbox/brokered-fetch.js +37 -0
  550. package/dist/sandbox/generated/zod.bundle.js +62 -1
  551. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  552. package/dist/sandbox/host-functions.d.ts +35 -0
  553. package/dist/sandbox/host-functions.js +150 -91
  554. package/dist/sandbox/prelude.js +7 -1
  555. package/dist/sandbox/run-in-sandbox.d.ts +19 -0
  556. package/dist/sandbox/run-in-sandbox.js +28 -10
  557. package/dist/sandbox/safe-fetch.d.ts +2 -0
  558. package/dist/sandbox/safe-fetch.js +3 -1
  559. package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
  560. package/dist/sandbox/secret-broker-sigv4.js +49 -0
  561. package/dist/sandbox/secret-broker.d.ts +34 -0
  562. package/dist/sandbox/secret-broker.js +161 -0
  563. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  564. package/dist/sandbox/user-tool.d.ts +14 -0
  565. package/dist/sandbox/user-tool.js +32 -0
  566. package/dist/sandbox/zod-params.d.ts +37 -5
  567. package/dist/sandbox/zod-params.js +181 -26
  568. package/dist/serve.js +25 -0
  569. package/dist/viewer/api-schema.d.ts +372 -2454
  570. package/dist/viewer/api-schema.js +29 -0
  571. package/dist/viewer/build-schemas.js +10 -3
  572. package/dist/viewer/event-bus.d.ts +6 -0
  573. package/dist/viewer/event-bus.js +16 -7
  574. package/dist/viewer/graph.d.ts +5 -2
  575. package/dist/viewer/graph.js +7 -2
  576. package/dist/viewer/http.d.ts +0 -1
  577. package/dist/viewer/http.js +2 -2
  578. package/dist/viewer/infra.js +25 -2
  579. package/dist/viewer/limits.d.ts +4 -0
  580. package/dist/viewer/limits.js +4 -0
  581. package/dist/viewer/openapi.d.ts +15 -0
  582. package/dist/viewer/openapi.js +170 -0
  583. package/dist/wardby-bin.js +10 -0
  584. package/docs/README.md +7 -0
  585. package/docs/agent-recipes.md +114 -27
  586. package/docs/architecture-runtime.md +16 -1
  587. package/docs/code-review-agents.md +689 -45
  588. package/docs/coding-agent-setup.md +602 -12
  589. package/docs/coding-packages.md +1037 -92
  590. package/docs/coding-services.md +30 -13
  591. package/docs/coding-worker-byo-images.md +218 -6
  592. package/docs/coding-worker-isolation.md +173 -44
  593. package/docs/getting-started-gke.md +332 -129
  594. package/docs/getting-started-identity-provider.md +31 -11
  595. package/docs/getting-started.md +14 -4
  596. package/docs/jira-agents.md +22 -9
  597. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  598. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  599. package/docs/knowledge/delegation-admission-slots.md +52 -0
  600. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  601. package/docs/knowledge/import-rename-target.md +52 -0
  602. package/docs/knowledge/index.md +57 -0
  603. package/docs/knowledge/log.md +9 -0
  604. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  605. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  606. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  607. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  608. package/docs/knowledge/overview-cli.md +74 -0
  609. package/docs/knowledge/overview-coding-proxy.md +72 -0
  610. package/docs/knowledge/overview-coding.md +72 -0
  611. package/docs/knowledge/overview-config.md +60 -0
  612. package/docs/knowledge/overview-core.md +72 -0
  613. package/docs/knowledge/overview-deploy.md +83 -0
  614. package/docs/knowledge/overview-mcp.md +61 -0
  615. package/docs/knowledge/overview-prisma.md +72 -0
  616. package/docs/knowledge/overview-providers.md +89 -0
  617. package/docs/knowledge/overview-sandbox.md +83 -0
  618. package/docs/knowledge/overview-surfaces.md +83 -0
  619. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  620. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  621. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  622. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  623. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  624. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  625. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  626. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  627. package/docs/knowledge/warm-input-publication.md +30 -0
  628. package/docs/knowledge/workspace-staging-failure.md +54 -0
  629. package/docs/knowledge.md +54 -14
  630. package/docs/native-sandbox.md +731 -0
  631. package/docs/observability.md +4 -0
  632. package/docs/release-verification.md +9 -0
  633. package/docs/security-deployment.md +146 -14
  634. package/docs/slack-notifications.md +268 -0
  635. package/docs/tool-secrets.md +284 -0
  636. package/docs/viewer-api.md +46 -5
  637. package/docs/viewer-api.openapi.yml +1404 -0
  638. package/help/admin-viewer.md +29 -3
  639. package/help/agent-recipes.md +27 -0
  640. package/help/architecture-agent.md +11 -6
  641. package/help/brokered-secrets.md +79 -0
  642. package/help/build-claude-code-image.md +131 -0
  643. package/help/build-worker-image.md +6 -7
  644. package/help/builder-agent.md +19 -6
  645. package/help/code-review-agents.md +243 -10
  646. package/help/coding-packages.md +156 -6
  647. package/help/cost-attribution.md +9 -5
  648. package/help/creating-agents.md +14 -1
  649. package/help/dependency-cache.md +143 -0
  650. package/help/deploy-gke.md +23 -9
  651. package/help/deployment-targets.md +25 -14
  652. package/help/errors/budget-exhausted.md +187 -0
  653. package/help/errors/budget-group-exhausted.md +5 -1
  654. package/help/errors/coding-provider-not-configured.md +2 -2
  655. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  656. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  657. package/help/errors/continuation-closed.md +9 -12
  658. package/help/errors/database-auth-invalid.md +28 -0
  659. package/help/errors/delegation-conflict.md +24 -0
  660. package/help/errors/file-list-truncated.md +45 -0
  661. package/help/errors/full-read-required.md +49 -0
  662. package/help/errors/github-account-not-allowed.md +29 -0
  663. package/help/errors/graph-incomplete.md +43 -0
  664. package/help/errors/graph-limit.md +43 -0
  665. package/help/errors/low-power-disabled.md +29 -0
  666. package/help/errors/low-power-scale-forbidden.md +35 -0
  667. package/help/errors/low-power-wake-timeout.md +30 -0
  668. package/help/errors/merge-conflict.md +49 -0
  669. package/help/errors/mobile-disabled.md +31 -0
  670. package/help/errors/native-sandbox-capacity.md +22 -0
  671. package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
  672. package/help/errors/native-sandbox-docker-failed.md +20 -0
  673. package/help/errors/native-sandbox-gateway-error.md +20 -0
  674. package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
  675. package/help/errors/native-sandbox-image-not-pinned.md +19 -0
  676. package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
  677. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  678. package/help/errors/native-sandbox-network-unenforced.md +22 -0
  679. package/help/errors/native-sandbox-requires-catalog.md +31 -0
  680. package/help/errors/native-sandbox-unavailable.md +19 -0
  681. package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
  682. package/help/errors/native-sandbox-worker-exited.md +21 -0
  683. package/help/errors/native-sandbox-worker-lost.md +20 -0
  684. package/help/errors/native-sandbox-worker-unready.md +22 -0
  685. package/help/errors/package-not-allowed-pending.md +52 -0
  686. package/help/errors/package-not-allowed.md +51 -0
  687. package/help/errors/package-refusals.md +43 -0
  688. package/help/errors/patch-cursor-malformed.md +31 -0
  689. package/help/errors/run-lost.md +39 -0
  690. package/help/errors/run-transcript-download.md +44 -0
  691. package/help/errors/secret-broker-body-invalid.md +26 -0
  692. package/help/errors/secret-broker-changed.md +20 -0
  693. package/help/errors/secret-broker-config-invalid.md +30 -0
  694. package/help/errors/secret-broker-conflict.md +27 -0
  695. package/help/errors/secret-broker-destination-denied.md +28 -0
  696. package/help/errors/secret-broker-value-invalid.md +28 -0
  697. package/help/errors/secret-brokered.md +24 -0
  698. package/help/errors/secret-in-value.md +69 -0
  699. package/help/errors/secret-not-brokered.md +25 -0
  700. package/help/errors/slack-auth-failed.md +48 -0
  701. package/help/errors/slack-channel-unreachable.md +39 -0
  702. package/help/errors/slack-not-configured.md +33 -0
  703. package/help/errors/target-merge.md +40 -0
  704. package/help/fix-merge-conflicts.md +73 -0
  705. package/help/getting-started.md +4 -5
  706. package/help/github-app-setup.md +132 -0
  707. package/help/github.md +40 -1
  708. package/help/identity-and-access.md +7 -1
  709. package/help/jira.md +23 -6
  710. package/help/knowledge.md +16 -7
  711. package/help/local-repositories.md +3 -4
  712. package/help/low-power-mode.md +131 -0
  713. package/help/merge-order-check.md +122 -0
  714. package/help/mobile-app.md +54 -0
  715. package/help/native-capabilities.md +29 -1
  716. package/help/native-sandbox.md +150 -0
  717. package/help/observability.md +8 -0
  718. package/help/operating-agents.md +5 -0
  719. package/help/package-audit-mode.md +91 -0
  720. package/help/related-pull-requests.md +80 -16
  721. package/help/repo-instructions-and-skills.md +91 -0
  722. package/help/resume-runs-locally.md +131 -0
  723. package/help/review-fix-rounds.md +43 -1
  724. package/help/sharing-agents.md +59 -0
  725. package/help/slack-notifications.md +76 -0
  726. package/help/status-comments.md +31 -0
  727. package/help/stop-run.md +58 -0
  728. package/help/troubleshooting/budgets.md +28 -0
  729. package/help/troubleshooting/coding-workers.md +99 -7
  730. package/package.json +27 -13
  731. package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
  732. package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
  733. package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
  734. package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
  735. package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
  736. package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
  737. package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
  738. package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
  739. package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
  740. package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
  741. package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
  742. package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
  743. package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
  744. package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
  745. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  746. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  747. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  748. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  749. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  750. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  751. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  752. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  753. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  754. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  755. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  756. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  757. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  758. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  759. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  760. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  761. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  762. package/prisma/schema.prisma +631 -146
  763. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -4,26 +4,109 @@
4
4
  * value/ciphertext at the source); this file adds ownership on top.
5
5
  */
6
6
  import { inputRequired, inputResponse } from "@modelcontextprotocol/server";
7
- import { createSecret, listSecrets, attachSecret, detachSecret, deleteSecret } from "../../core/secrets.js";
7
+ import { createSecret, listSecrets, attachSecret, detachSecret, deleteSecret, setSecretBroker, } from "../../core/secrets.js";
8
+ import { brokerConfigHash, parseSecretBrokerConfig } from "../../core/secret-broker-config.js";
8
9
  import { McpError } from "../errors.js";
9
10
  import { requireOwnedSecret } from "../auth/ownership.js";
10
- import { requireAgentAccess, requireBindingOwner } from "../auth/access.js";
11
- import { getSecretElicitationOutcome } from "./secret-elicitation.js";
11
+ import { requireAgentAccess, requireBindable, requireBindingOwner } from "../auth/access.js";
12
+ import { clearUnbrokerOutcome, getSecretElicitationOutcome, } from "./secret-elicitation.js";
13
+ import { allowedSecretNames, brokerCompatibilityWarnings } from "./secret-broker-compat.js";
12
14
  import { textResult } from "./text-result.js";
15
+ const BROKER_SCHEMA_DOC = '{ hosts: exact hostnames, pathPrefixes?: ["/..."], placement: { kind: "header", name, format containing {value} } | { kind: "query", name } | { kind: "body", field } | { kind: "aws-sigv4", region, service } }';
16
+ /** Validates a caller-supplied broker config; an invalid one is the caller's 400. */
17
+ function parseBrokerArg(input) {
18
+ try {
19
+ return parseSecretBrokerConfig(input);
20
+ }
21
+ catch (err) {
22
+ throw new McpError(400, err instanceof Error ? err.message : String(err));
23
+ }
24
+ }
25
+ /** Maps core/secrets.ts's coded errors to MCP statuses; anything else propagates unchanged. */
26
+ function mapSecretError(err) {
27
+ const message = err instanceof Error ? err.message : String(err);
28
+ if (message.startsWith("secret_not_found"))
29
+ throw new McpError(404, message);
30
+ if (message.startsWith("secret_broker_config_invalid") || message.startsWith("secret_broker_value_invalid")) {
31
+ throw new McpError(400, message);
32
+ }
33
+ throw err;
34
+ }
35
+ /**
36
+ * Non-blocking warnings: tools that can see this secret (under any alias it is
37
+ * attached as) but still read it with secrets.get(), which a brokered secret refuses.
38
+ */
39
+ async function brokerWarningsForSecret(db, ownerId, name) {
40
+ const bindings = await db.agentSecret.findMany({
41
+ where: { secret: { ownerId, name } },
42
+ select: { agentId: true, boundName: true },
43
+ });
44
+ if (!bindings.length)
45
+ return [];
46
+ const aliasesByAgent = new Map();
47
+ for (const b of bindings) {
48
+ const aliases = aliasesByAgent.get(b.agentId) ?? new Set();
49
+ aliases.add(b.boundName);
50
+ aliasesByAgent.set(b.agentId, aliases);
51
+ }
52
+ const attachments = await db.agentTool.findMany({
53
+ where: { agentId: { in: [...aliasesByAgent.keys()] } },
54
+ include: { tool: { select: { name: true, code: true } } },
55
+ });
56
+ const warnings = new Set();
57
+ for (const a of attachments) {
58
+ const tools = [{ name: a.tool.name, code: a.tool.code, allowedSecrets: allowedSecretNames(a.allowedSecrets) }];
59
+ for (const w of brokerCompatibilityWarnings(tools, aliasesByAgent.get(a.agentId)))
60
+ warnings.add(w);
61
+ }
62
+ return [...warnings];
63
+ }
64
+ function withWarnings(body, warnings) {
65
+ return warnings.length ? { ...body, warnings } : body;
66
+ }
67
+ async function findOwnSecret(ctx, name) {
68
+ const secret = await ctx.db.secret.findUnique({ where: { ownerId_name: { ownerId: ctx.principal.id, name } } });
69
+ if (!secret)
70
+ throw new McpError(404, `secret_not_found: no secret named "${name}"`);
71
+ return secret;
72
+ }
13
73
  export function registerSecretsTools(mcp, opts) {
14
74
  mcp.registerTool({
15
75
  name: "create_secret",
16
76
  scope: "secrets:write",
17
- description: 'Creates a secret. Omit "value" to enter it securely via a one-time browser link instead of passing it as a plaintext argument.',
77
+ description: 'Creates a secret. Omit "value" to enter it securely via a one-time browser link instead of passing it as a plaintext argument. Pass "broker" ({ hosts, pathPrefixes?, placement }) to make it brokered: tools can then only send it to those hosts with fetch(url, { secrets: [name] }) and can never read it. See the help article "brokered-secrets".',
18
78
  inputSchema: {
19
79
  type: "object",
20
- properties: { name: { type: "string" }, value: { type: "string" } },
80
+ properties: {
81
+ name: { type: "string" },
82
+ value: { type: "string" },
83
+ broker: { type: "object", description: `Optional broker config: ${BROKER_SCHEMA_DOC}` },
84
+ },
21
85
  required: ["name"],
22
86
  },
23
87
  handler: async (args, ctx) => {
88
+ const broker = args.broker === undefined ? undefined : parseBrokerArg(args.broker);
24
89
  if (args.value !== undefined) {
25
- const secret = await createSecret(args.name, args.value, ctx.principal.id, ctx.providers.secrets, ctx.db);
26
- return textResult({ id: secret.id, name: secret.name, keyId: secret.keyId, createdAt: secret.createdAt });
90
+ let secret;
91
+ try {
92
+ secret = await createSecret(args.name, args.value, ctx.principal.id, ctx.providers.secrets, ctx.db, {
93
+ broker,
94
+ via: "mcp",
95
+ });
96
+ }
97
+ catch (err) {
98
+ mapSecretError(err);
99
+ }
100
+ // A fresh broker config supersedes any earlier, browser-confirmed removal still on record.
101
+ if (broker)
102
+ await clearUnbrokerOutcome(ctx.principal.id, args.name, ctx.db);
103
+ return textResult({
104
+ id: secret.id,
105
+ name: secret.name,
106
+ keyId: secret.keyId,
107
+ createdAt: secret.createdAt,
108
+ broker: secret.broker == null ? null : parseSecretBrokerConfig(secret.broker),
109
+ });
27
110
  }
28
111
  if (opts.protocolElicitation) {
29
112
  const state = ctx.mcpReq.requestState();
@@ -43,7 +126,12 @@ export function registerSecretsTools(mcp, opts) {
43
126
  throw new McpError(400, existingOutcome.error);
44
127
  return textResult(existingOutcome.secret);
45
128
  }
46
- const payload = { ownerId: ctx.principal.id, secretName: args.name };
129
+ const payload = {
130
+ ownerId: ctx.principal.id,
131
+ secretName: args.name,
132
+ kind: "create",
133
+ ...(broker ? { broker } : {}),
134
+ };
47
135
  const token = await mcp.mintRequestState(payload);
48
136
  const url = await opts.buildElicitationUrl(token);
49
137
  if (opts.protocolElicitation) {
@@ -66,6 +154,95 @@ export function registerSecretsTools(mcp, opts) {
66
154
  });
67
155
  },
68
156
  });
157
+ mcp.registerTool({
158
+ name: "set_secret_broker",
159
+ scope: "secrets:write",
160
+ description: 'Sets or changes a secret\'s broker config ({ hosts, pathPrefixes?, placement }), so tools can only send it to those hosts with fetch(url, { secrets: [name] }) and never read it. broker: null removes brokering, which must be confirmed by a person in the browser link this returns. Every change is audited. See the help article "brokered-secrets".',
161
+ inputSchema: {
162
+ type: "object",
163
+ properties: {
164
+ name: { type: "string" },
165
+ broker: {
166
+ type: ["object", "null"],
167
+ description: `The broker config ${BROKER_SCHEMA_DOC}, or null to remove brokering (browser-confirmed).`,
168
+ },
169
+ },
170
+ required: ["name", "broker"],
171
+ },
172
+ handler: async (args, ctx) => {
173
+ const ownerId = ctx.principal.id;
174
+ if (args.broker !== null) {
175
+ const broker = parseBrokerArg(args.broker);
176
+ await findOwnSecret(ctx, args.name);
177
+ let change;
178
+ try {
179
+ change = await setSecretBroker(ctx.db, ctx.providers.secrets, {
180
+ ownerId,
181
+ name: args.name,
182
+ broker,
183
+ actorId: ownerId,
184
+ via: "mcp",
185
+ });
186
+ }
187
+ catch (err) {
188
+ mapSecretError(err);
189
+ }
190
+ await clearUnbrokerOutcome(ownerId, args.name, ctx.db);
191
+ const warnings = await brokerWarningsForSecret(ctx.db, ownerId, args.name);
192
+ return textResult(withWarnings({ name: args.name, before: change.before, broker: change.after }, warnings));
193
+ }
194
+ // broker: null — never removed here. Only a person submitting the
195
+ // browser form (fulfillUnbrokerElicitation) removes it; this call hands
196
+ // out the link and, once that has happened, reports it.
197
+ if (opts.protocolElicitation) {
198
+ const state = ctx.mcpReq.requestState();
199
+ if (state) {
200
+ const view = inputResponse(ctx.mcpReq.inputResponses, "confirmUnbroker");
201
+ if (view.kind === "elicit" && view.action !== "accept") {
202
+ throw new McpError(400, `Removing brokering was ${view.action}d.`);
203
+ }
204
+ }
205
+ }
206
+ const existingOutcome = await getSecretElicitationOutcome(ownerId, args.name, ctx.db, "unbroker");
207
+ if (existingOutcome) {
208
+ if (!existingOutcome.ok)
209
+ mapSecretError(new Error(existingOutcome.error));
210
+ return textResult({ unbrokered: true, secret: existingOutcome.secret });
211
+ }
212
+ const secret = await findOwnSecret(ctx, args.name);
213
+ if (secret.broker == null) {
214
+ // Nothing to remove, so nothing for a person to confirm.
215
+ const metadata = (await listSecrets(ownerId, ctx.db)).find((s) => s.id === secret.id);
216
+ return textResult({ unbrokered: true, secret: metadata });
217
+ }
218
+ // The hash pins the link to the config being confirmed: if it changes before
219
+ // the person submits, fulfillUnbrokerElicitation refuses (secret_broker_changed).
220
+ const payload = {
221
+ ownerId,
222
+ secretName: args.name,
223
+ kind: "unbroker",
224
+ brokerHash: brokerConfigHash(parseSecretBrokerConfig(secret.broker)),
225
+ };
226
+ const token = await mcp.mintRequestState(payload);
227
+ const url = await opts.buildElicitationUrl(token);
228
+ if (opts.protocolElicitation) {
229
+ return inputRequired({
230
+ requestState: token,
231
+ inputRequests: {
232
+ confirmUnbroker: inputRequired.elicitUrl({
233
+ url,
234
+ message: `Confirm removing brokering for secret "${args.name}" in your browser.`,
235
+ }),
236
+ },
237
+ });
238
+ }
239
+ return textResult({
240
+ status: "pending",
241
+ message: `Open this link in your browser to confirm removing brokering for secret "${args.name}", then call set_secret_broker again with broker: null to finish.`,
242
+ url,
243
+ });
244
+ },
245
+ });
69
246
  mcp.registerTool({
70
247
  name: "list_secrets",
71
248
  scope: "secrets:write",
@@ -92,7 +269,7 @@ export function registerSecretsTools(mcp, opts) {
92
269
  // (A2/S2-2): a binding hands the value to every tool the owner lets
93
270
  // read it. Not even the stdio operator crosses owners.
94
271
  const { agent } = await requireAgentAccess(ctx, args.agentId, "read");
95
- requireBindingOwner(ctx, agent);
272
+ await requireBindable(ctx, agent);
96
273
  const ownerId = agent.ownerId;
97
274
  try {
98
275
  // Resolved among the agent owner's secrets (== the caller here).
@@ -0,0 +1,2 @@
1
+ import type { WardbyMcpServer } from "../server.js";
2
+ export declare function registerStopRunTool(mcp: WardbyMcpServer): void;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * stop_run: stops a run that is still pending (including a coding run queued for a slot) or
3
+ * running, and the delegated child runs it has in flight (src/core/stop-run.ts). A run that already
4
+ * finished is returned unchanged, so calling it again is harmless.
5
+ *
6
+ * Access mirrors trigger_agent: stopping a run needs execute on its agent. Runs are visible only to
7
+ * the agent's owner and to the run's triggerer (get_run's rule), so anyone else gets the same 404 as
8
+ * for a missing run; a triggerer whose access to the agent has dropped below execute gets a 403.
9
+ */
10
+ import { z } from "zod";
11
+ import { atLeast } from "../../core/grants.js";
12
+ import { stopRun } from "../../core/stop-run.js";
13
+ import { agentAccess, insufficientAgentAccess } from "../auth/access.js";
14
+ import { McpError } from "../errors.js";
15
+ import { textResult } from "./text-result.js";
16
+ const StopRunSchema = z
17
+ .object({
18
+ runId: z.string().trim().min(1).max(128),
19
+ reason: z.string().trim().max(500).optional(),
20
+ })
21
+ .strict();
22
+ export function registerStopRunTool(mcp) {
23
+ mcp.registerTool({
24
+ name: "stop_run",
25
+ scope: "runs:trigger",
26
+ description: "Stop a run that is pending, queued, or running, and the sub-agent runs it delegated that are still in " +
27
+ "flight. The run ends as `cancelled`; a coding run's worker is stopped and opens or updates no pull " +
28
+ "request. A run that already finished is returned unchanged. Needs execute access to the run's agent.",
29
+ inputSchema: {
30
+ type: "object",
31
+ additionalProperties: false,
32
+ properties: {
33
+ runId: { type: "string" },
34
+ reason: {
35
+ type: "string",
36
+ description: "Why the run is being stopped; recorded on the run (up to 500 characters).",
37
+ },
38
+ },
39
+ required: ["runId"],
40
+ },
41
+ handler: async (raw, ctx) => {
42
+ const parsed = StopRunSchema.safeParse(raw);
43
+ if (!parsed.success) {
44
+ const details = parsed.error.issues.map((i) => `${i.path.join(".") || "input"}: ${i.message}`).join("; ");
45
+ throw new McpError(400, `Invalid stop_run arguments: ${details}`);
46
+ }
47
+ const { runId, reason } = parsed.data;
48
+ const notFound = new McpError(404, `Run "${runId}" not found.`);
49
+ const run = await ctx.db.run.findUnique({
50
+ where: { id: runId },
51
+ select: { id: true, agentId: true, triggeredById: true },
52
+ });
53
+ if (!run)
54
+ throw notFound;
55
+ const agent = await ctx.db.agent.findUnique({ where: { id: run.agentId }, select: { id: true, ownerId: true } });
56
+ if (!agent)
57
+ throw notFound;
58
+ const access = await agentAccess(ctx, agent);
59
+ const isTriggerer = run.triggeredById !== null && run.triggeredById === ctx.principal.id;
60
+ // Visible to the agent's owner and the run's triggerer only, exactly as get_run.
61
+ if (access !== "owner" && !isTriggerer)
62
+ throw notFound;
63
+ if (!atLeast("agent", access, "execute"))
64
+ throw insufficientAgentAccess(agent.id, "execute", access);
65
+ const result = await stopRun({
66
+ db: ctx.db,
67
+ executor: ctx.providers.executor,
68
+ runId,
69
+ stoppedBy: ctx.principal.id,
70
+ reason,
71
+ });
72
+ const message = !result.stopRequested
73
+ ? `Run already finished as ${result.status}; nothing was changed.`
74
+ : result.status === "cancelled"
75
+ ? "Run stopped."
76
+ : result.status === "pending" || result.status === "running"
77
+ ? `Stop requested; the run is still ${result.status}. Check it again with get_run.`
78
+ : `The run finished as ${result.status} before the stop took effect.`;
79
+ return textResult({ ...result, message });
80
+ },
81
+ });
82
+ }
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { Prisma } from "#prisma";
16
16
  import { atLeast, canDelegate } from "../../core/grants.js";
17
- import { agentAccess, agentAccessResolver, agentNotFound, requireAgentAccess, requireBindingOwner, } from "../auth/access.js";
17
+ import { agentAccess, agentAccessResolver, agentNotFound, requireAgentAccess, requireBindable, } from "../auth/access.js";
18
18
  import { McpError } from "../errors.js";
19
19
  import { textResult } from "./text-result.js";
20
20
  /**
@@ -68,7 +68,7 @@ export function registerSubAgentTools(mcp) {
68
68
  throw new McpError(400, "An agent cannot be its own sub-agent.");
69
69
  }
70
70
  const { agent: parent } = await requireAgentAccess(ctx, args.parentAgentId, "read");
71
- requireBindingOwner(ctx, parent);
71
+ await requireBindable(ctx, parent);
72
72
  // The caller could trigger the child anyway; the edge must not widen that.
73
73
  const { agent: child } = await requireAgentAccess(ctx, args.childAgentId, "execute");
74
74
  if (parent.ownerId === null) {
@@ -19,14 +19,14 @@ import type { WardbyMcpServer } from "../server.js";
19
19
  */
20
20
  export declare function projectTool(tool: Tool, principalId: string): {
21
21
  name: string;
22
+ updatedAt: Date;
22
23
  code: string;
23
24
  createdAt: Date;
24
- updatedAt: Date;
25
25
  id: string;
26
26
  ownerId: string | null;
27
27
  description: string;
28
- paramsZod: string;
29
28
  jsonSchema: import("@prisma/client/runtime/client").JsonValue;
29
+ paramsZod: string;
30
30
  } | {
31
31
  id: string;
32
32
  name: string;
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import { Prisma } from "#prisma";
13
13
  import { deriveJsonSchema, validateParams } from "../../sandbox/zod-params.js";
14
+ import { cachedZod4Compatibility, toolSubject, withZod3ToolWarnings, zod3SampleArgsWarning, zod3ToolWarnings, zod3WindowWarning, } from "../../core/zod3-window.js";
14
15
  import { runInSandbox } from "../../sandbox/run-in-sandbox.js";
15
16
  import { ToolCapabilitiesPatchSchema } from "../../sandbox/tool-capabilities.js";
16
17
  import { buildSharedDatastoreAccessor } from "../../core/datastores.js";
@@ -19,8 +20,9 @@ import { ToolAttachedError, deleteToolGuarded, hasToolChanges, prepareToolUpdate
19
20
  import { McpError } from "../errors.js";
20
21
  import { requireOwnedTool, requireStrictlyOwnedTool, assertStrictlyOwnedTool, visibleToPrincipal, canRead, } from "../auth/ownership.js";
21
22
  import { agentAccessResolver, assertAgentAccess, requireAgentAccess } from "../auth/access.js";
22
- import { atLeast } from "../../core/grants.js";
23
+ import { atLeast, isPublicWritable } from "../../core/grants.js";
23
24
  import { textResult } from "./text-result.js";
25
+ import { brokerCompatibilityWarnings } from "./secret-broker-compat.js";
24
26
  /**
25
27
  * Names the agents the caller can read (its own and ones granted to it)
26
28
  * and only counts the rest, so a refusal never reveals another principal's
@@ -48,6 +50,22 @@ export function projectTool(tool, principalId) {
48
50
  ? { id: tool.id, name: tool.name, description: tool.description, public: true }
49
51
  : { id: tool.id, name: tool.name, description: tool.description, public: false, ownerIsCaller: false };
50
52
  }
53
+ /**
54
+ * Non-blocking: which of the secrets just granted to this attachment are
55
+ * brokered on the agent, and does the tool still read them with
56
+ * secrets.get()? Reveals only that fact about a tool the caller may not own
57
+ * (attach_tool already lets the agent's owner grant capabilities to such code).
58
+ */
59
+ async function brokeredSecretWarnings(db, agentId, tool, allowedSecrets) {
60
+ if (!tool || !allowedSecrets?.length)
61
+ return [];
62
+ const bindings = await db.agentSecret.findMany({
63
+ where: { agentId, boundName: { in: [...allowedSecrets] } },
64
+ include: { secret: { select: { broker: true } } },
65
+ });
66
+ const brokered = new Set(bindings.filter((b) => b.secret.broker != null).map((b) => b.boundName));
67
+ return brokerCompatibilityWarnings([{ ...tool, allowedSecrets }], brokered);
68
+ }
51
69
  /** Refuses a name one of the runner's built-ins would shadow (see core/tool-names.ts). */
52
70
  function assertToolNameAllowed(name) {
53
71
  const reason = reservedToolNameReason(name);
@@ -85,7 +103,8 @@ export function registerToolAuthoringTools(mcp) {
85
103
  ownerId: ctx.principal.id,
86
104
  },
87
105
  });
88
- return textResult(tool);
106
+ const warnings = await zod3ToolWarnings(toolSubject(tool.name), args.paramsZod);
107
+ return textResult(warnings.length ? { ...tool, warnings } : tool);
89
108
  }
90
109
  catch (err) {
91
110
  if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2002") {
@@ -128,7 +147,8 @@ export function registerToolAuthoringTools(mcp) {
128
147
  // landing between the check and the write.
129
148
  try {
130
149
  const tool = await updateToolGuarded(ctx.db, args.toolId, prepared.data, (row) => assertStrictlyOwnedTool(row, args.toolId, ctx.principal.id));
131
- return textResult(tool);
150
+ const warnings = args.paramsZod === undefined ? [] : await zod3ToolWarnings(toolSubject(tool.name), args.paramsZod);
151
+ return textResult(warnings.length ? { ...tool, warnings } : tool);
132
152
  }
133
153
  catch (err) {
134
154
  if (err instanceof ToolAttachedError) {
@@ -176,7 +196,7 @@ export function registerToolAuthoringTools(mcp) {
176
196
  mcp.registerTool({
177
197
  name: "dry_run_tool",
178
198
  scope: "tools:write",
179
- description: "Test-runs tool code against sample args without persisting it. Fetch is denied by default, same as a freshly attached tool — pass allowedHosts to test code that calls fetch().",
199
+ description: "Test-runs tool code against sample args without persisting it. Fetch is denied by default, same as a freshly attached tool — pass allowedHosts to test code that calls fetch(). For this release a paramsZod is still compiled with Zod 3; a `warnings` list in the result means the next release, which compiles it with Zod 4 only, will reject it or treat the sample args differently.",
180
200
  inputSchema: {
181
201
  type: "object",
182
202
  properties: {
@@ -200,10 +220,19 @@ export function registerToolAuthoringTools(mcp) {
200
220
  }
201
221
  const jsonSchema = schemaResult.value;
202
222
  const validated = await validateParams(args.paramsZod, args.sampleArgs);
223
+ // Zod 3 compatibility window: would the next release (Zod 4 only) compile
224
+ // this schema, and treat the sample arguments the same way?
225
+ const subject = "This paramsZod";
226
+ const compatibility = await cachedZod4Compatibility(args.paramsZod);
227
+ const compatWarning = compatibility.compatible === true
228
+ ? zod3SampleArgsWarning(subject, validated, await validateParams(args.paramsZod, args.sampleArgs, ["v4"]))
229
+ : zod3WindowWarning(subject, compatibility);
230
+ const warnings = compatWarning ? { warnings: [compatWarning] } : {};
203
231
  if (!validated.ok) {
204
232
  return textResult({
205
233
  jsonSchema,
206
234
  result: { ok: false, errorKind: validated.errorKind, errorMessage: validated.errorMessage },
235
+ ...warnings,
207
236
  });
208
237
  }
209
238
  // No real agent exists for a dry run — the caller's own principal
@@ -226,13 +255,13 @@ export function registerToolAuthoringTools(mcp) {
226
255
  toolName: "dry_run_tool",
227
256
  allowedFetchHosts: hosts.data.allowedHosts ?? [],
228
257
  });
229
- return textResult({ jsonSchema, result: sandboxResult });
258
+ return textResult({ jsonSchema, result: sandboxResult, ...warnings });
230
259
  },
231
260
  });
232
261
  mcp.registerTool({
233
262
  name: "attach_tool",
234
263
  scope: "tools:write",
235
- description: "Attaches a tool to an agent (needs write on the agent). The four capability fields (allowedSecrets, allowedDatastorePrefixes, allowedHosts, allowedSharedDatastorePrefixes) are the agent owner's to grant: anyone else passing one gets 403, and their attachment runs with none until the owner re-runs attach_tool with the capabilities. When the owner grants an attachment it had not granted before (someone else attached it, or the agent changed owner), every capability not passed is reset to empty, so state each one you want. Granting capabilities to a tool someone else owns vouches for code you can't read (only its owner sees it); the tool's owner can't change it while it's attached to your agent, and detaching drops your grant.",
264
+ description: "Attaches a tool to an agent (needs write on the agent). The four capability fields (allowedSecrets, allowedDatastorePrefixes, allowedHosts, allowedSharedDatastorePrefixes) are the agent owner's to grant: anyone else passing one gets 403, and their attachment runs with none until the owner re-runs attach_tool with the capabilities. When the owner grants an attachment it had not granted before (someone else attached it, or the agent changed owner), every capability not passed is reset to empty, so state each one you want. Granting capabilities to a tool someone else owns vouches for code you can't read (only its owner sees it); the tool's owner can't change it while it's attached to your agent, and detaching drops your grant. Granting a brokered secret lets the tool send it only via fetch(url, { secrets: [name] }), never read it; the result includes warnings when the tool calls secrets.get() on one.",
236
265
  inputSchema: {
237
266
  type: "object",
238
267
  properties: {
@@ -263,6 +292,7 @@ export function registerToolAuthoringTools(mcp) {
263
292
  throw new McpError(400, `Invalid tool capabilities: ${patch.error.issues.map((i) => i.message).join("; ")}`);
264
293
  }
265
294
  const capabilitiesPassed = Object.values(patch.data).some((value) => value !== undefined);
295
+ let attachedTool;
266
296
  await ctx.db.$transaction(async (tx) => {
267
297
  const { agent } = await assertAgentAccess(ctx, await tx.agent.findUnique({ where: { id: args.agentId } }), args.agentId, "write", tx);
268
298
  if (agent.kind === "coding") {
@@ -276,6 +306,9 @@ export function registerToolAuthoringTools(mcp) {
276
306
  if (capabilitiesPassed && !isOwner) {
277
307
  throw new McpError(403, "Only the agent's owner can grant capabilities to an attachment; ask them to re-run attach_tool with the capabilities.");
278
308
  }
309
+ if (capabilitiesPassed && (await isPublicWritable(tx, agent.id))) {
310
+ throw new McpError(409, `Agent "${agent.id}" is writable by everyone, so tool capabilities cannot be granted on it; revoke or lower the everyone grant first.`);
311
+ }
279
312
  const existing = await tx.agentTool.findUnique({
280
313
  where: { agentId_toolId: { agentId: args.agentId, toolId: args.toolId } },
281
314
  });
@@ -290,6 +323,7 @@ export function registerToolAuthoringTools(mcp) {
290
323
  // The runtime dispatches by name, and names are only unique per
291
324
  // owner: a second same-named tool on one agent would be a
292
325
  // duplicate tool name to the model and silently shadow one of them.
326
+ attachedTool = { name: tool.name, code: tool.code };
293
327
  const clash = await findSameNamedAttachedTool(tx, args.agentId, tool);
294
328
  if (clash) {
295
329
  // The clashing tool may be another principal's private one (a
@@ -330,7 +364,8 @@ export function registerToolAuthoringTools(mcp) {
330
364
  update: ownerGrant,
331
365
  });
332
366
  }, { isolationLevel: Prisma.TransactionIsolationLevel.Serializable });
333
- return textResult({ attached: true });
367
+ const warnings = await brokeredSecretWarnings(ctx.db, args.agentId, attachedTool, patch.data.allowedSecrets);
368
+ return textResult(warnings.length ? { attached: true, warnings } : { attached: true });
334
369
  },
335
370
  });
336
371
  mcp.registerTool({
@@ -354,19 +389,20 @@ export function registerToolAuthoringTools(mcp) {
354
389
  scope: "tools:write",
355
390
  inputSchema: { type: "object", properties: { agentId: { type: "string" } } },
356
391
  handler: async (args, ctx) => {
357
- const project = (tool) => projectTool(tool, ctx.principal.id);
392
+ // Zod 3 window: the caller's own tools carry their warnings (cached per paramsZod text).
393
+ const project = (tool) => withZod3ToolWarnings(projectTool(tool, ctx.principal.id));
358
394
  if (args.agentId) {
359
395
  const { access } = await requireAgentAccess(ctx, args.agentId, "read");
360
396
  const rows = await ctx.db.agentTool.findMany({ where: { agentId: args.agentId }, include: { tool: true } });
361
397
  // The agent's owner sees every tool on it (projected: code only for
362
398
  // the tool's own owner); anyone else only tools they could see anyway.
363
- return textResult(rows
399
+ return textResult(await Promise.all(rows
364
400
  .map((r) => r.tool)
365
401
  .filter((tool) => access === "owner" || canRead(tool.ownerId, ctx.principal.id))
366
- .map(project));
402
+ .map(project)));
367
403
  }
368
404
  const tools = await ctx.db.tool.findMany({ where: visibleToPrincipal(ctx.principal.id) });
369
- return textResult(tools.filter((tool) => canRead(tool.ownerId, ctx.principal.id)).map(project));
405
+ return textResult(await Promise.all(tools.filter((tool) => canRead(tool.ownerId, ctx.principal.id)).map(project)));
370
406
  },
371
407
  });
372
408
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * stdio-only host for the signed links some tools hand out (the secret-entry
3
+ * form, a run transcript download): an ephemeral, loopback-only HTTP server,
4
+ * started lazily on the first link and closed after a period of inactivity.
5
+ * stdio's MCP process has no other listener (see stdio.ts); this one exists
6
+ * only while a link may be in use, consistent with stdio's "no token; the
7
+ * operator is trusted" model: reachable only from this same machine, and
8
+ * only a holder of a signed link can do anything with it.
9
+ *
10
+ * Request logging: none. A link's token travels in its `t` query parameter
11
+ * and must never be logged.
12
+ */
13
+ import { type IncomingMessage, type ServerResponse } from "node:http";
14
+ /** Handles one request for a path; receives the `t` query parameter. Must not log the token. */
15
+ export type StdioLinkHandler = (req: IncomingMessage, res: ServerResponse, token: string | null) => Promise<void>;
16
+ export interface StdioLinkHost {
17
+ /** The loopback URL for `path` carrying `token`; starts the server if it is not running. */
18
+ urlFor(path: string, token: string): Promise<string>;
19
+ }
20
+ export declare function createStdioLinkHost(routes: Record<string, StdioLinkHandler>): StdioLinkHost;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * stdio-only host for the signed links some tools hand out (the secret-entry
3
+ * form, a run transcript download): an ephemeral, loopback-only HTTP server,
4
+ * started lazily on the first link and closed after a period of inactivity.
5
+ * stdio's MCP process has no other listener (see stdio.ts); this one exists
6
+ * only while a link may be in use, consistent with stdio's "no token; the
7
+ * operator is trusted" model: reachable only from this same machine, and
8
+ * only a holder of a signed link can do anything with it.
9
+ *
10
+ * Request logging: none. A link's token travels in its `t` query parameter
11
+ * and must never be logged.
12
+ */
13
+ import { createServer } from "node:http";
14
+ /** Matches the requestState codec's own TTL (server.ts): no point outliving the tokens it serves. */
15
+ const IDLE_SHUTDOWN_MS = 10 * 60_000;
16
+ export function createStdioLinkHost(routes) {
17
+ let server;
18
+ let port = 0;
19
+ let idleTimer;
20
+ function scheduleIdleShutdown() {
21
+ if (idleTimer)
22
+ clearTimeout(idleTimer);
23
+ idleTimer = setTimeout(() => {
24
+ server?.close();
25
+ server = undefined;
26
+ }, IDLE_SHUTDOWN_MS);
27
+ idleTimer.unref();
28
+ }
29
+ async function ensureServer() {
30
+ if (server) {
31
+ scheduleIdleShutdown();
32
+ return port;
33
+ }
34
+ const s = createServer((req, res) => {
35
+ scheduleIdleShutdown();
36
+ const url = new URL(req.url ?? "/", "http://127.0.0.1");
37
+ const handler = Object.hasOwn(routes, url.pathname) ? routes[url.pathname] : undefined;
38
+ if (!handler) {
39
+ res.writeHead(404).end();
40
+ return;
41
+ }
42
+ // A failure here must never become an unhandled rejection: that would take
43
+ // down the whole stdio MCP process, not just this request.
44
+ handler(req, res, url.searchParams.get("t")).catch(() => {
45
+ if (!res.headersSent)
46
+ res.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
47
+ if (!res.writableEnded)
48
+ res.end("Internal error");
49
+ });
50
+ });
51
+ server = s;
52
+ await new Promise((resolve, reject) => {
53
+ s.once("error", reject);
54
+ s.listen(0, "127.0.0.1", resolve);
55
+ });
56
+ const address = s.address();
57
+ port = typeof address === "object" && address ? address.port : 0;
58
+ scheduleIdleShutdown();
59
+ return port;
60
+ }
61
+ return {
62
+ async urlFor(path, token) {
63
+ const p = await ensureServer();
64
+ return `http://127.0.0.1:${p}${path}?t=${encodeURIComponent(token)}`;
65
+ },
66
+ };
67
+ }
@@ -8,7 +8,16 @@ import type { McpProviders } from "../context.js";
8
8
  import { type GitHubIngressDeps } from "../host-events/github-ingress.js";
9
9
  import { type JiraIngressDeps } from "../host-events/jira-ingress.js";
10
10
  import { type HostUserCallbackDeps } from "../host-events/github-user-callback.js";
11
+ import type { BlobStore } from "../../providers/storage/types.js";
11
12
  import { type ViewerApi } from "../../viewer/http.js";
13
+ /**
14
+ * close() waits this long for open requests to finish, then cuts them. A
15
+ * connected MCP client's event stream never ends on its own, so without a
16
+ * limit close() would hold shutdown until the pod is killed. On Kubernetes
17
+ * the load balancer has already moved traffic away by then (preStop), and
18
+ * clients reconnect to another instance.
19
+ */
20
+ export declare const CLOSE_GRACE_MS = 10000;
12
21
  export interface HttpServerConfig {
13
22
  canonicalUri: string;
14
23
  httpBind: {
@@ -40,6 +49,10 @@ export interface StartHttpServerOptions {
40
49
  };
41
50
  /** The admin viewer API (/admin/api/*); absent = those paths answer 404. */
42
51
  viewer?: ViewerApi;
52
+ /** The blob store run transcripts are served from (get_run_transcript links); absent = they answer 503. */
53
+ blobs?: BlobStore;
54
+ /** How long close() lets open requests finish before cutting them (default CLOSE_GRACE_MS). */
55
+ closeGraceMs?: number;
43
56
  }
44
57
  export interface HttpServerHandle {
45
58
  port: number;