@wardby/cli 0.6.0 → 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 (576) hide show
  1. package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
  2. package/dist/claude-coding-worker/driver.d.ts +21 -3
  3. package/dist/claude-coding-worker/driver.js +125 -17
  4. package/dist/claude-coding-worker/main.js +34 -6
  5. package/dist/claude-coding-worker/sdk.js +12 -1
  6. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  7. package/dist/claude-coding-worker/tool-socket.js +111 -0
  8. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  9. package/dist/claude-coding-worker/transcript.js +77 -0
  10. package/dist/cli-help.d.ts +1 -1
  11. package/dist/cli-help.js +1 -0
  12. package/dist/cli.js +24 -10
  13. package/dist/coding/continuation-wording.d.ts +35 -0
  14. package/dist/coding/continuation-wording.js +73 -0
  15. package/dist/coding/linked-issue-note.d.ts +23 -0
  16. package/dist/coding/linked-issue-note.js +47 -0
  17. package/dist/coding/merge-wording.d.ts +28 -0
  18. package/dist/coding/merge-wording.js +78 -0
  19. package/dist/coding/pr-description-note.d.ts +9 -0
  20. package/dist/coding/pr-description-note.js +32 -0
  21. package/dist/coding/profile.d.ts +46 -126
  22. package/dist/coding/profile.js +45 -4
  23. package/dist/coding/protected-path-wording.d.ts +8 -0
  24. package/dist/coding/protected-path-wording.js +1 -1
  25. package/dist/coding/protocol.d.ts +264 -346
  26. package/dist/coding/protocol.js +235 -12
  27. package/dist/coding/redact.d.ts +3 -0
  28. package/dist/coding/redact.js +12 -0
  29. package/dist/coding/registry/allowlist.d.ts +12 -0
  30. package/dist/coding/registry/allowlist.js +14 -1
  31. package/dist/coding/registry/audit-mode.d.ts +153 -0
  32. package/dist/coding/registry/audit-mode.js +304 -0
  33. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  34. package/dist/coding/registry/lockfile-shared.js +128 -0
  35. package/dist/coding/registry/lockfiles.js +1 -1
  36. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  37. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  38. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  39. package/dist/coding/registry/npm-lockfile.js +4 -6
  40. package/dist/coding/registry/npm.js +78 -8
  41. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  42. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  43. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  44. package/dist/coding/registry/pypi-plan.js +406 -0
  45. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  46. package/dist/coding/registry/pypi-requirements.js +155 -0
  47. package/dist/coding/registry/pypi.d.ts +3 -27
  48. package/dist/coding/registry/pypi.js +40 -154
  49. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  50. package/dist/coding/registry/refusal-hints.js +61 -0
  51. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  52. package/dist/coding/registry/refusal-wording.js +56 -0
  53. package/dist/coding/registry/report.d.ts +70 -8
  54. package/dist/coding/registry/report.js +112 -5
  55. package/dist/coding/registry/types.d.ts +58 -8
  56. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  57. package/dist/coding/registry/yarn-lockfile.js +367 -0
  58. package/dist/coding/services/catalog.d.ts +37 -351
  59. package/dist/coding/transcript/claude-code.d.ts +13 -0
  60. package/dist/coding/transcript/claude-code.js +273 -0
  61. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  62. package/dist/coding/transcript/download-protocol.js +18 -0
  63. package/dist/coding/transcript/format.d.ts +20 -0
  64. package/dist/coding/transcript/format.js +32 -0
  65. package/dist/coding/transcript/recorder.d.ts +51 -0
  66. package/dist/coding/transcript/recorder.js +225 -0
  67. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  68. package/dist/coding/transcript/resume/checkout.js +203 -0
  69. package/dist/coding/transcript/resume/command.d.ts +17 -0
  70. package/dist/coding/transcript/resume/command.js +176 -0
  71. package/dist/coding/transcript/resume/download.d.ts +20 -0
  72. package/dist/coding/transcript/resume/download.js +153 -0
  73. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  74. package/dist/coding/transcript/resume/launch.js +128 -0
  75. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  76. package/dist/coding/transcript/resume/session-file.js +79 -0
  77. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  78. package/dist/coding/transcript/resume/stand-in.js +49 -0
  79. package/dist/coding-worker/artifact.d.ts +8 -3
  80. package/dist/coding-worker/artifact.js +3 -1
  81. package/dist/coding-worker/debug-trace.d.ts +6 -5
  82. package/dist/coding-worker/debug-trace.js +13 -18
  83. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  84. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  85. package/dist/coding-worker/driver.d.ts +4 -3
  86. package/dist/coding-worker/driver.js +116 -38
  87. package/dist/coding-worker/errors.d.ts +1 -0
  88. package/dist/coding-worker/errors.js +32 -0
  89. package/dist/coding-worker/task-note.d.ts +11 -0
  90. package/dist/coding-worker/task-note.js +13 -0
  91. package/dist/coding-worker/types.d.ts +11 -0
  92. package/dist/config/dependency-cache.d.ts +23 -0
  93. package/dist/config/dependency-cache.js +32 -0
  94. package/dist/config/providers.d.ts +12 -3
  95. package/dist/config/providers.js +55 -5
  96. package/dist/config/test-simulators.d.ts +82 -0
  97. package/dist/config/test-simulators.js +305 -0
  98. package/dist/core/async-context.d.ts +2 -0
  99. package/dist/core/async-context.js +12 -0
  100. package/dist/core/budget-events.d.ts +108 -0
  101. package/dist/core/budget-events.js +346 -0
  102. package/dist/core/budget-groups.d.ts +50 -1
  103. package/dist/core/budget-groups.js +236 -27
  104. package/dist/core/budget-stopped-head.d.ts +46 -0
  105. package/dist/core/budget-stopped-head.js +81 -0
  106. package/dist/core/budget-topup.d.ts +51 -0
  107. package/dist/core/budget-topup.js +156 -0
  108. package/dist/core/budget-wording.d.ts +16 -2
  109. package/dist/core/budget-wording.js +40 -2
  110. package/dist/core/coding-queue.d.ts +2 -1
  111. package/dist/core/coding-queue.js +7 -0
  112. package/dist/core/cron.d.ts +19 -1
  113. package/dist/core/cron.js +17 -0
  114. package/dist/core/datastores.js +1 -1
  115. package/dist/core/deferred-coding.d.ts +14 -0
  116. package/dist/core/deferred-coding.js +62 -0
  117. package/dist/core/delegation-child.d.ts +25 -0
  118. package/dist/core/delegation-child.js +37 -0
  119. package/dist/core/dispatch.d.ts +42 -0
  120. package/dist/core/dispatch.js +131 -56
  121. package/dist/core/engine-native.js +1 -1
  122. package/dist/core/error-code.d.ts +38 -0
  123. package/dist/core/error-code.js +168 -0
  124. package/dist/core/grants.d.ts +19 -6
  125. package/dist/core/grants.js +55 -6
  126. package/dist/core/host-events.d.ts +18 -2
  127. package/dist/core/host-events.js +284 -24
  128. package/dist/core/host-status.d.ts +85 -3
  129. package/dist/core/host-status.js +298 -20
  130. package/dist/core/issue-bridge.d.ts +50 -6
  131. package/dist/core/issue-bridge.js +124 -33
  132. package/dist/core/issue-events.d.ts +1 -1
  133. package/dist/core/issue-events.js +4 -10
  134. package/dist/core/issue-status.d.ts +1 -1
  135. package/dist/core/issue-status.js +54 -26
  136. package/dist/core/logger.d.ts +5 -0
  137. package/dist/core/logger.js +14 -1
  138. package/dist/core/lost-run-children.d.ts +6 -0
  139. package/dist/core/lost-run-children.js +32 -0
  140. package/dist/core/mark-ready.d.ts +34 -0
  141. package/dist/core/mark-ready.js +152 -0
  142. package/dist/core/markdown-code.d.ts +8 -0
  143. package/dist/core/markdown-code.js +107 -0
  144. package/dist/core/memory-tools.js +7 -0
  145. package/dist/core/merge-order-check.d.ts +2 -1
  146. package/dist/core/merge-order-check.js +8 -1
  147. package/dist/core/notification-templates.d.ts +1 -7
  148. package/dist/core/notification-templates.js +36 -2
  149. package/dist/core/pull-request-state-sync.js +2 -2
  150. package/dist/core/reconciler.d.ts +4 -3
  151. package/dist/core/reconciler.js +8 -1
  152. package/dist/core/related-pull-requests.d.ts +11 -3
  153. package/dist/core/related-pull-requests.js +27 -14
  154. package/dist/core/reply-parts.d.ts +21 -0
  155. package/dist/core/reply-parts.js +73 -0
  156. package/dist/core/review-fix.d.ts +1 -1
  157. package/dist/core/review-fix.js +2 -1
  158. package/dist/core/review-host-checks.d.ts +1 -1
  159. package/dist/core/review-host-tools.d.ts +3 -0
  160. package/dist/core/review-host-tools.js +99 -13
  161. package/dist/core/review-reads.d.ts +55 -0
  162. package/dist/core/review-reads.js +233 -0
  163. package/dist/core/run-status.d.ts +12 -0
  164. package/dist/core/run-status.js +12 -0
  165. package/dist/core/runner.d.ts +80 -34
  166. package/dist/core/runner.js +439 -144
  167. package/dist/core/schedule-start.d.ts +12 -0
  168. package/dist/core/schedule-start.js +14 -0
  169. package/dist/core/secret-broker-config.d.ts +10 -74
  170. package/dist/core/secret-guard.d.ts +46 -0
  171. package/dist/core/secret-guard.js +104 -0
  172. package/dist/core/secret-guarded-stores.d.ts +12 -0
  173. package/dist/core/secret-guarded-stores.js +41 -0
  174. package/dist/core/secret-spans.d.ts +50 -0
  175. package/dist/core/secret-spans.js +94 -0
  176. package/dist/core/stop-run.d.ts +46 -0
  177. package/dist/core/stop-run.js +61 -0
  178. package/dist/core/workflow-events.d.ts +14 -2
  179. package/dist/core/workflow-events.js +4 -0
  180. package/dist/core/workflow-run-events.d.ts +5 -3
  181. package/dist/core/workflow-run-events.js +43 -8
  182. package/dist/core/zod-json-schema.d.ts +4 -0
  183. package/dist/core/zod-json-schema.js +39 -0
  184. package/dist/core/zod3-window.d.ts +35 -0
  185. package/dist/core/zod3-window.js +124 -0
  186. package/dist/generated/prisma/browser.d.ts +34 -3
  187. package/dist/generated/prisma/client.d.ts +34 -3
  188. package/dist/generated/prisma/commonInputTypes.d.ts +220 -60
  189. package/dist/generated/prisma/enums.d.ts +10 -0
  190. package/dist/generated/prisma/enums.js +8 -0
  191. package/dist/generated/prisma/internal/class.d.ts +44 -0
  192. package/dist/generated/prisma/internal/class.js +4 -4
  193. package/dist/generated/prisma/internal/prismaNamespace.d.ts +428 -9
  194. package/dist/generated/prisma/internal/prismaNamespace.js +92 -1
  195. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +95 -0
  196. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +92 -1
  197. package/dist/generated/prisma/models/Agent.d.ts +106 -8
  198. package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
  199. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +229 -1
  200. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  201. package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
  202. package/dist/generated/prisma/models/CodingRun.d.ts +1637 -1
  203. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  204. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  205. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  206. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  207. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
  208. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
  209. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  210. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  211. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  212. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  213. package/dist/generated/prisma/models/Run.d.ts +738 -2
  214. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  215. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  216. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  217. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  218. package/dist/generated/prisma/models.d.ts +4 -0
  219. package/dist/help-index.json +1320 -69
  220. package/dist/import/create.js +32 -3
  221. package/dist/import/neutral-schema.d.ts +50 -281
  222. package/dist/import/neutral-schema.js +5 -4
  223. package/dist/knowledge/check.d.ts +1 -1
  224. package/dist/knowledge/cli.d.ts +11 -1
  225. package/dist/knowledge/cli.js +37 -4
  226. package/dist/knowledge/concept.d.ts +3 -19
  227. package/dist/knowledge/location.d.ts +31 -0
  228. package/dist/knowledge/location.js +78 -0
  229. package/dist/mcp/auth/access.d.ts +10 -2
  230. package/dist/mcp/auth/access.js +15 -1
  231. package/dist/mcp/auth/ownership.d.ts +7 -7
  232. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  233. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  234. package/dist/mcp/host-events/github-ingress.d.ts +2 -0
  235. package/dist/mcp/host-events/github-ingress.js +2 -1
  236. package/dist/mcp/index.d.ts +6 -0
  237. package/dist/mcp/index.js +58 -10
  238. package/dist/mcp/server.d.ts +13 -0
  239. package/dist/mcp/server.js +33 -14
  240. package/dist/mcp/tools/agents.d.ts +4 -0
  241. package/dist/mcp/tools/agents.js +198 -16
  242. package/dist/mcp/tools/datastore.js +17 -8
  243. package/dist/mcp/tools/grants.js +9 -3
  244. package/dist/mcp/tools/memory.js +11 -1
  245. package/dist/mcp/tools/notification-channels.js +2 -2
  246. package/dist/mcp/tools/packages.d.ts +2 -0
  247. package/dist/mcp/tools/packages.js +195 -0
  248. package/dist/mcp/tools/repositories.js +18 -5
  249. package/dist/mcp/tools/run-access.d.ts +16 -0
  250. package/dist/mcp/tools/run-access.js +25 -0
  251. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  252. package/dist/mcp/tools/run-transcript-download.js +129 -0
  253. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  254. package/dist/mcp/tools/run-transcript.js +70 -0
  255. package/dist/mcp/tools/runs.js +34 -12
  256. package/dist/mcp/tools/scheduling.js +3 -1
  257. package/dist/mcp/tools/secret-elicitation-form.js +5 -0
  258. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  259. package/dist/mcp/tools/secret-elicitation-server.js +10 -61
  260. package/dist/mcp/tools/secrets.js +2 -2
  261. package/dist/mcp/tools/stop-run.d.ts +2 -0
  262. package/dist/mcp/tools/stop-run.js +82 -0
  263. package/dist/mcp/tools/subagents.js +2 -2
  264. package/dist/mcp/tools/tools.d.ts +1 -1
  265. package/dist/mcp/tools/tools.js +25 -9
  266. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  267. package/dist/mcp/transport/stdio-link-host.js +67 -0
  268. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  269. package/dist/mcp/transport/streamable-http.js +41 -1
  270. package/dist/native-worker/docker-launcher.d.ts +38 -2
  271. package/dist/native-worker/docker-launcher.js +65 -5
  272. package/dist/native-worker/gateway-server.d.ts +41 -3
  273. package/dist/native-worker/gateway-server.js +124 -27
  274. package/dist/native-worker/gateway.d.ts +27 -1
  275. package/dist/native-worker/gateway.js +70 -4
  276. package/dist/native-worker/http-server.d.ts +3 -1
  277. package/dist/native-worker/http-server.js +11 -7
  278. package/dist/native-worker/http-transport.js +1 -1
  279. package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
  280. package/dist/native-worker/kubernetes-launcher.js +43 -3
  281. package/dist/native-worker/launch.d.ts +18 -1
  282. package/dist/native-worker/launch.js +6 -1
  283. package/dist/native-worker/ledger.d.ts +18 -2
  284. package/dist/native-worker/ledger.js +57 -4
  285. package/dist/native-worker/loopback.js +3 -8
  286. package/dist/native-worker/main.d.ts +2 -1
  287. package/dist/native-worker/main.js +14 -3
  288. package/dist/native-worker/protocol.d.ts +129 -577
  289. package/dist/native-worker/protocol.js +47 -1
  290. package/dist/native-worker/sandbox-executor.d.ts +17 -2
  291. package/dist/native-worker/sandbox-executor.js +78 -4
  292. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  293. package/dist/native-worker/stderr-redaction.js +237 -0
  294. package/dist/native-worker/stdio.d.ts +1 -1
  295. package/dist/native-worker/stdio.js +6 -5
  296. package/dist/native-worker/warm-pool.d.ts +2 -2
  297. package/dist/native-worker/warm-pool.js +4 -4
  298. package/dist/native-worker/worker.js +28 -2
  299. package/dist/observability/metrics.js +6 -1
  300. package/dist/providers/auth/self-hosted.d.ts +1 -1
  301. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  302. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  303. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  304. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  305. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  306. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  307. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  308. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  309. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  310. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  311. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  312. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  313. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  314. package/dist/providers/coding-proxy/hold.js +86 -0
  315. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  316. package/dist/providers/coding-proxy/interrupted.js +104 -0
  317. package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
  318. package/dist/providers/coding-proxy/memory-ledger.js +84 -8
  319. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  320. package/dist/providers/coding-proxy/metering.js +27 -4
  321. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
  322. package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
  323. package/dist/providers/coding-proxy/proxy.d.ts +14 -1
  324. package/dist/providers/coding-proxy/proxy.js +166 -14
  325. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  326. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  327. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  328. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  329. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  330. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  331. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  332. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  333. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  334. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  335. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  336. package/dist/providers/coding-proxy/registry/service.js +579 -112
  337. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  338. package/dist/providers/coding-proxy/registry/store.js +54 -1
  339. package/dist/providers/coding-proxy/runtime.d.ts +4 -0
  340. package/dist/providers/coding-proxy/runtime.js +78 -16
  341. package/dist/providers/coding-proxy/server.d.ts +6 -1
  342. package/dist/providers/coding-proxy/server.js +45 -1
  343. package/dist/providers/coding-proxy/types.d.ts +65 -1
  344. package/dist/providers/datastore/types.d.ts +5 -0
  345. package/dist/providers/engine/types.d.ts +17 -2
  346. package/dist/providers/engine/types.js +17 -0
  347. package/dist/providers/executor/composition.d.ts +10 -3
  348. package/dist/providers/executor/composition.js +47 -7
  349. package/dist/providers/executor/container.d.ts +361 -8
  350. package/dist/providers/executor/container.js +1136 -91
  351. package/dist/providers/executor/dbos-status.d.ts +31 -0
  352. package/dist/providers/executor/dbos-status.js +64 -0
  353. package/dist/providers/executor/dbos.d.ts +50 -1
  354. package/dist/providers/executor/dbos.js +207 -20
  355. package/dist/providers/executor/deferred.d.ts +12 -24
  356. package/dist/providers/executor/deferred.js +10 -29
  357. package/dist/providers/executor/in-process.d.ts +9 -1
  358. package/dist/providers/executor/in-process.js +14 -4
  359. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  360. package/dist/providers/executor/linked-issue-reader.js +30 -0
  361. package/dist/providers/executor/routing.d.ts +2 -0
  362. package/dist/providers/executor/routing.js +4 -0
  363. package/dist/providers/executor/types.d.ts +13 -0
  364. package/dist/providers/index.d.ts +2 -1
  365. package/dist/providers/issue-tracker/types.d.ts +17 -0
  366. package/dist/providers/issue-tracker/types.js +39 -1
  367. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  368. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  369. package/dist/providers/jobs/docker-isolation.d.ts +8 -0
  370. package/dist/providers/jobs/docker-isolation.js +17 -0
  371. package/dist/providers/jobs/docker.d.ts +1 -0
  372. package/dist/providers/jobs/docker.js +27 -2
  373. package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
  374. package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
  375. package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
  376. package/dist/providers/jobs/kubernetes-api.js +10 -0
  377. package/dist/providers/jobs/kubernetes-client.js +10 -1
  378. package/dist/providers/jobs/kubernetes-isolation.d.ts +2 -0
  379. package/dist/providers/jobs/kubernetes-isolation.js +17 -1
  380. package/dist/providers/jobs/kubernetes.d.ts +6 -1
  381. package/dist/providers/jobs/kubernetes.js +105 -16
  382. package/dist/providers/jobs/types.d.ts +33 -0
  383. package/dist/providers/jobs/types.js +13 -1
  384. package/dist/providers/llm/anthropic.js +5 -1
  385. package/dist/providers/llm/bedrock.d.ts +0 -12
  386. package/dist/providers/llm/bedrock.js +4 -0
  387. package/dist/providers/llm/claude-messages.d.ts +3 -1
  388. package/dist/providers/llm/claude-messages.js +4 -1
  389. package/dist/providers/llm/claude-provider.d.ts +2 -2
  390. package/dist/providers/llm/claude-provider.js +2 -2
  391. package/dist/providers/llm/openai.d.ts +2 -2
  392. package/dist/providers/llm/openai.js +6 -2
  393. package/dist/providers/llm/routing.d.ts +2 -2
  394. package/dist/providers/llm/routing.js +2 -2
  395. package/dist/providers/llm/types.d.ts +12 -2
  396. package/dist/providers/review-host/github-events.d.ts +9 -1
  397. package/dist/providers/review-host/github-events.js +34 -12
  398. package/dist/providers/review-host/github.d.ts +29 -2
  399. package/dist/providers/review-host/github.js +224 -29
  400. package/dist/providers/review-host/local.d.ts +8 -4
  401. package/dist/providers/review-host/local.js +49 -31
  402. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  403. package/dist/providers/review-host/patch-pages.js +176 -0
  404. package/dist/providers/review-host/review-format.d.ts +19 -1
  405. package/dist/providers/review-host/review-format.js +38 -7
  406. package/dist/providers/review-host/types.d.ts +134 -2
  407. package/dist/providers/review-host/types.js +8 -0
  408. package/dist/providers/storage/gcs.d.ts +63 -0
  409. package/dist/providers/storage/gcs.js +69 -0
  410. package/dist/providers/storage/index.d.ts +15 -0
  411. package/dist/providers/storage/index.js +14 -0
  412. package/dist/providers/storage/local.d.ts +24 -0
  413. package/dist/providers/storage/local.js +92 -0
  414. package/dist/providers/storage/meter.d.ts +14 -0
  415. package/dist/providers/storage/meter.js +34 -0
  416. package/dist/providers/storage/s3.d.ts +41 -0
  417. package/dist/providers/storage/s3.js +107 -0
  418. package/dist/providers/storage/types.d.ts +37 -3
  419. package/dist/providers/storage/types.js +21 -4
  420. package/dist/providers/vcs/git.d.ts +33 -2
  421. package/dist/providers/vcs/git.js +324 -22
  422. package/dist/providers/vcs/github-remote.d.ts +26 -3
  423. package/dist/providers/vcs/github-remote.js +124 -14
  424. package/dist/providers/vcs/github.d.ts +214 -6
  425. package/dist/providers/vcs/github.js +447 -45
  426. package/dist/providers/vcs/index.js +8 -1
  427. package/dist/providers/vcs/pr-description.d.ts +127 -0
  428. package/dist/providers/vcs/pr-description.js +270 -0
  429. package/dist/providers/vcs/remote.d.ts +33 -1
  430. package/dist/providers/vcs/routing.d.ts +4 -2
  431. package/dist/providers/vcs/routing.js +6 -0
  432. package/dist/providers/vcs/types.d.ts +80 -3
  433. package/dist/quickstart/coding-seed.d.ts +14 -3
  434. package/dist/quickstart/coding-seed.js +213 -4
  435. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  436. package/dist/quickstart/reviewer-prompt.js +6 -6
  437. package/dist/quickstart-images.json +1 -1
  438. package/dist/sandbox/generated/zod.bundle.js +62 -1
  439. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  440. package/dist/sandbox/host-functions.d.ts +1 -0
  441. package/dist/sandbox/host-functions.js +6 -11
  442. package/dist/sandbox/secret-broker.js +3 -4
  443. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  444. package/dist/sandbox/zod-params.d.ts +37 -5
  445. package/dist/sandbox/zod-params.js +181 -26
  446. package/dist/serve.js +8 -1
  447. package/dist/viewer/api-schema.d.ts +349 -2627
  448. package/dist/viewer/api-schema.js +7 -0
  449. package/dist/viewer/build-schemas.js +6 -2
  450. package/dist/viewer/openapi.js +2 -4
  451. package/dist/wardby-bin.js +10 -0
  452. package/docs/agent-recipes.md +58 -20
  453. package/docs/code-review-agents.md +551 -41
  454. package/docs/coding-agent-setup.md +489 -7
  455. package/docs/coding-packages.md +1033 -90
  456. package/docs/coding-services.md +27 -12
  457. package/docs/coding-worker-byo-images.md +20 -0
  458. package/docs/coding-worker-isolation.md +105 -30
  459. package/docs/getting-started-gke.md +124 -137
  460. package/docs/getting-started-identity-provider.md +10 -1
  461. package/docs/getting-started.md +9 -0
  462. package/docs/jira-agents.md +17 -8
  463. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  464. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  465. package/docs/knowledge/delegation-admission-slots.md +52 -0
  466. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  467. package/docs/knowledge/import-rename-target.md +52 -0
  468. package/docs/knowledge/index.md +57 -0
  469. package/docs/knowledge/log.md +9 -0
  470. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  471. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  472. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  473. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  474. package/docs/knowledge/overview-cli.md +74 -0
  475. package/docs/knowledge/overview-coding-proxy.md +72 -0
  476. package/docs/knowledge/overview-coding.md +72 -0
  477. package/docs/knowledge/overview-config.md +60 -0
  478. package/docs/knowledge/overview-core.md +72 -0
  479. package/docs/knowledge/overview-deploy.md +83 -0
  480. package/docs/knowledge/overview-mcp.md +61 -0
  481. package/docs/knowledge/overview-prisma.md +72 -0
  482. package/docs/knowledge/overview-providers.md +89 -0
  483. package/docs/knowledge/overview-sandbox.md +83 -0
  484. package/docs/knowledge/overview-surfaces.md +83 -0
  485. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  486. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  487. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  488. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  489. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  490. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  491. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  492. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  493. package/docs/knowledge/warm-input-publication.md +30 -0
  494. package/docs/knowledge/workspace-staging-failure.md +54 -0
  495. package/docs/knowledge.md +54 -14
  496. package/docs/native-sandbox.md +119 -23
  497. package/docs/observability.md +4 -0
  498. package/docs/security-deployment.md +33 -2
  499. package/docs/slack-notifications.md +35 -19
  500. package/docs/tool-secrets.md +42 -10
  501. package/docs/viewer-api.openapi.yml +1 -1
  502. package/help/admin-viewer.md +24 -2
  503. package/help/architecture-agent.md +11 -6
  504. package/help/build-worker-image.md +3 -1
  505. package/help/builder-agent.md +19 -6
  506. package/help/code-review-agents.md +177 -6
  507. package/help/coding-packages.md +156 -6
  508. package/help/cost-attribution.md +9 -5
  509. package/help/creating-agents.md +14 -1
  510. package/help/dependency-cache.md +143 -0
  511. package/help/deploy-gke.md +15 -8
  512. package/help/errors/budget-exhausted.md +187 -0
  513. package/help/errors/budget-group-exhausted.md +5 -1
  514. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  515. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  516. package/help/errors/continuation-closed.md +9 -12
  517. package/help/errors/delegation-conflict.md +24 -0
  518. package/help/errors/file-list-truncated.md +45 -0
  519. package/help/errors/full-read-required.md +49 -0
  520. package/help/errors/github-account-not-allowed.md +4 -0
  521. package/help/errors/graph-incomplete.md +43 -0
  522. package/help/errors/graph-limit.md +43 -0
  523. package/help/errors/merge-conflict.md +49 -0
  524. package/help/errors/native-sandbox-gateway-error.md +20 -0
  525. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  526. package/help/errors/native-sandbox-worker-exited.md +3 -2
  527. package/help/errors/package-not-allowed-pending.md +52 -0
  528. package/help/errors/package-not-allowed.md +51 -0
  529. package/help/errors/package-refusals.md +43 -0
  530. package/help/errors/patch-cursor-malformed.md +31 -0
  531. package/help/errors/run-lost.md +39 -0
  532. package/help/errors/run-transcript-download.md +44 -0
  533. package/help/errors/secret-in-value.md +69 -0
  534. package/help/errors/target-merge.md +40 -0
  535. package/help/fix-merge-conflicts.md +73 -0
  536. package/help/github-app-setup.md +132 -0
  537. package/help/github.md +22 -0
  538. package/help/identity-and-access.md +2 -0
  539. package/help/jira.md +23 -6
  540. package/help/knowledge.md +16 -7
  541. package/help/local-repositories.md +1 -1
  542. package/help/low-power-mode.md +7 -1
  543. package/help/merge-order-check.md +5 -0
  544. package/help/native-capabilities.md +29 -1
  545. package/help/native-sandbox.md +15 -1
  546. package/help/operating-agents.md +5 -0
  547. package/help/package-audit-mode.md +91 -0
  548. package/help/related-pull-requests.md +10 -7
  549. package/help/resume-runs-locally.md +131 -0
  550. package/help/review-fix-rounds.md +33 -1
  551. package/help/sharing-agents.md +59 -0
  552. package/help/slack-notifications.md +19 -5
  553. package/help/status-comments.md +31 -0
  554. package/help/stop-run.md +58 -0
  555. package/help/troubleshooting/budgets.md +28 -0
  556. package/help/troubleshooting/coding-workers.md +78 -7
  557. package/package.json +17 -10
  558. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  559. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  560. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  561. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  562. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  563. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  564. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  565. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  566. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  567. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  568. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  569. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  570. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  571. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  572. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  573. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  574. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  575. package/prisma/schema.prisma +311 -97
  576. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -1,9 +1,11 @@
1
- import { McpError } from "../errors.js";
2
- import { agentAccess, requireAgentAccess } from "../auth/access.js";
3
- import { publicCodingRunResult } from "../../coding/protocol.js";
1
+ import { requireAgentAccess } from "../auth/access.js";
2
+ import { findReadableRun } from "./run-access.js";
3
+ import { publicCodingRunResult, sanitizeDependencyCacheReport } from "../../coding/protocol.js";
4
4
  import { countPlanRefusals, summarizeRegistryFetches } from "../../coding/registry/report.js";
5
+ import { summarizePackageAudit } from "../../coding/registry/audit-mode.js";
5
6
  import { storedServiceLabels } from "../../coding/services/catalog.js";
6
7
  import { textResult } from "./text-result.js";
8
+ import { loadBudgetEvents } from "../../core/budget-events.js";
7
9
  /**
8
10
  * Run visibility (resource-sharing grants spec §3.5, A6): a run's output is
9
11
  * the triggerer's and the agent owner's, never every reader's. The owner
@@ -56,17 +58,9 @@ export function registerRunTools(mcp) {
56
58
  scope: "agents:read",
57
59
  inputSchema: { type: "object", properties: { runId: { type: "string" } }, required: ["runId"] },
58
60
  handler: async (args, ctx) => {
59
- const run = await ctx.db.run.findUnique({ where: { id: args.runId } });
60
- const notFound = new McpError(404, `Run "${args.runId}" not found.`);
61
- if (!run)
62
- throw notFound;
63
61
  // Its triggerer keeps seeing it even after losing access to the agent;
64
62
  // otherwise only the agent's owner. read on the agent is not enough.
65
- if (run.triggeredById !== ctx.principal.id) {
66
- const agent = await ctx.db.agent.findUnique({ where: { id: run.agentId } });
67
- if (!agent || (await agentAccess(ctx, agent)) !== "owner")
68
- throw notFound;
69
- }
63
+ const run = await findReadableRun(ctx, args.runId);
70
64
  const codingRun = await ctx.db.codingRun.findUnique({
71
65
  where: { runId: run.id },
72
66
  select: {
@@ -75,9 +69,16 @@ export function registerRunTools(mcp) {
75
69
  failureCategory: true,
76
70
  diagnosticId: true,
77
71
  debugTrace: true,
72
+ debugTraceMaxMb: true,
78
73
  services: true,
79
74
  resultBranch: true,
80
75
  baseSha: true,
76
+ dependencyCacheResult: true,
77
+ prDescriptionOutcome: true,
78
+ packageAuditMode: true,
79
+ budgetBaseUsd: true,
80
+ budgetReservedUsd: true,
81
+ budgetLimitUsd: true,
81
82
  },
82
83
  });
83
84
  const localPr = await ctx.db.localPullRequest.findUnique({
@@ -102,6 +103,12 @@ export function registerRunTools(mcp) {
102
103
  refused: countPlanRefusals(registryFetches),
103
104
  }
104
105
  : undefined;
106
+ // Package audit mode, fixed at dispatch: what the registry served only
107
+ // because of it (empty when nothing was), read only for a run that had it.
108
+ const packageAuditMode = codingRun?.packageAuditMode ?? null;
109
+ const packageAudit = packageAuditMode
110
+ ? summarizePackageAudit(await ctx.db.registryAuditRecord.findMany({ where: { runId: run.id }, orderBy: { createdAt: "asc" } })).entries
111
+ : undefined;
105
112
  // A failed coding run's error is only an opaque id; these two say which
106
113
  // stage failed and are the key an operator searches the control-plane
107
114
  // log for (the real reason is logged there, never persisted). Both are
@@ -110,17 +117,31 @@ export function registerRunTools(mcp) {
110
117
  const diagnosticId = codingRun?.diagnosticId ?? undefined;
111
118
  // Which services the run started with ("postgres 16"); never their images or environments.
112
119
  const services = codingRun ? storedServiceLabels(codingRun.services) : [];
120
+ // The worker's dependency cache report (stable codes, folder names and numbers only), re-bounded on read.
121
+ const dependencyCache = codingRun?.dependencyCacheResult !== null && codingRun?.dependencyCacheResult !== undefined
122
+ ? sanitizeDependencyCacheReport(codingRun.dependencyCacheResult)
123
+ : undefined;
124
+ // Well-formed refusals only, with group, lead and agent budget filled as the run error's are.
125
+ const budgetEvents = await loadBudgetEvents(ctx.db, run.id);
113
126
  return textResult({
114
127
  ...withOperatorMode(run),
128
+ ...(budgetEvents.length > 0 ? { budgetEvents } : {}),
129
+ ...(codingRun?.budgetReservedUsd != null ? { budgetReservedUsd: Number(codingRun.budgetReservedUsd) } : {}),
130
+ ...(codingRun?.budgetBaseUsd != null ? { budgetBaseUsd: Number(codingRun.budgetBaseUsd) } : {}),
131
+ // The most overrun top-ups may raise budgetReservedUsd to; absent = the reservation is the limit.
132
+ ...(codingRun?.budgetLimitUsd != null ? { budgetLimitUsd: Number(codingRun.budgetLimitUsd) } : {}),
115
133
  ...(codingResult ? { codingResult } : {}),
116
134
  ...(failureCategory ? { failureCategory } : {}),
117
135
  ...(diagnosticId ? { diagnosticId } : {}),
118
136
  ...(codingQueuedAt ? { codingQueuedAt } : {}),
119
137
  // An admin turned on the debug trace: the worker's full trace is in its pod log.
120
138
  ...(codingRun?.debugTrace ? { debugTrace: true } : {}),
139
+ ...(codingRun?.debugTrace && codingRun.debugTraceMaxMb ? { debugTraceMaxMb: codingRun.debugTraceMaxMb } : {}),
121
140
  ...(services.length > 0 ? { services } : {}),
122
141
  ...(codingRun?.resultBranch ? { resultBranch: codingRun.resultBranch } : {}),
123
142
  ...(codingRun?.baseSha ? { baseSha: codingRun.baseSha } : {}),
143
+ ...(dependencyCache ? { dependencyCache } : {}),
144
+ ...(codingRun?.prDescriptionOutcome ? { prDescriptionOutcome: codingRun.prDescriptionOutcome } : {}),
124
145
  ...(localPr
125
146
  ? {
126
147
  review: {
@@ -137,6 +158,7 @@ export function registerRunTools(mcp) {
137
158
  }
138
159
  : {}),
139
160
  ...(codingRun ? { packages, packageRefusals, packagePlan } : {}),
161
+ ...(packageAuditMode ? { packageAuditMode, packageAudit } : {}),
140
162
  });
141
163
  },
142
164
  });
@@ -1,5 +1,6 @@
1
1
  import { Prisma } from "#prisma";
2
2
  import { validateCronExpression } from "../../core/cron.js";
3
+ import { scheduleStartFields } from "../../core/schedule-start.js";
3
4
  import { McpError } from "../errors.js";
4
5
  import { assertAgentAccess, requireAgentAccess } from "../auth/access.js";
5
6
  import { textResult } from "./text-result.js";
@@ -24,9 +25,10 @@ export function registerSchedulingTools(mcp) {
24
25
  if (existing.kind === "coding" && !existing.codingProfile?.defaultTask) {
25
26
  throw new McpError(400, "A default task is required before enabling a coding-agent schedule.");
26
27
  }
28
+ const next = { schedule: args.schedule, timezone: args.timezone, scheduleEnabled: true };
27
29
  return tx.agent.update({
28
30
  where: { id: args.agentId },
29
- data: { schedule: args.schedule, timezone: args.timezone, scheduleEnabled: true },
31
+ data: { ...next, ...(await scheduleStartFields(tx, existing, next)) },
30
32
  });
31
33
  }, { isolationLevel: Prisma.TransactionIsolationLevel.Serializable });
32
34
  return textResult(agent);
@@ -123,6 +123,11 @@ export async function handleSecretElicitationForm(method, token, readFormBody, r
123
123
  if (!token)
124
124
  throw new Error("missing token");
125
125
  payload = await deps.verify(token);
126
+ // Other links share the signing key (a run transcript download, a tool's
127
+ // requestState): only a secret link's kind opens this form.
128
+ if (payload.kind !== undefined && payload.kind !== "create" && payload.kind !== "unbroker") {
129
+ throw new Error("not a secret link");
130
+ }
126
131
  }
127
132
  catch {
128
133
  html(res, 400, "<h1>Link expired</h1><p>This link is invalid or has expired. Return to your MCP client and try again.</p>");
@@ -1,5 +1,11 @@
1
1
  import type { SecretFormDeps } from "./secret-elicitation-form.js";
2
+ import { type StdioLinkHandler } from "../transport/stdio-link-host.js";
3
+ /** The loopback path the form is served at on stdio. */
4
+ export declare const STDIO_SECRET_PATH = "/secret";
2
5
  export interface StdioSecretElicitationHost {
3
6
  urlFor(token: string): Promise<string>;
4
7
  }
8
+ /** The secret form as a link-host route. */
9
+ export declare function secretFormRoute(deps: SecretFormDeps): StdioLinkHandler;
10
+ /** A link host serving only the secret form (the composition root shares one host across routes). */
5
11
  export declare function createStdioSecretElicitationHost(deps: SecretFormDeps): StdioSecretElicitationHost;
@@ -1,64 +1,13 @@
1
- /**
2
- * stdio-only host for the secret-entry form: an ephemeral, loopback-only
3
- * HTTP server, started lazily on the first pending elicitation and closed
4
- * after a period of inactivity. stdio's MCP process has no other listener
5
- * (see mcp/transport/stdio.ts) — this one exists only while a secret entry
6
- * is actually pending, consistent with stdio's "no token; the operator is
7
- * trusted" model: reachable only from this same machine, and only a holder
8
- * of the one-time signed URL can do anything with it.
9
- */
10
- import { createServer } from "node:http";
11
1
  import { handleSecretElicitationForm, readFormBody } from "./secret-elicitation-form.js";
12
- /** Matches the requestState codec's own TTL (server.ts) — no point outliving the tokens it serves. */
13
- const IDLE_SHUTDOWN_MS = 10 * 60_000;
2
+ import { createStdioLinkHost } from "../transport/stdio-link-host.js";
3
+ /** The loopback path the form is served at on stdio. */
4
+ export const STDIO_SECRET_PATH = "/secret";
5
+ /** The secret form as a link-host route. */
6
+ export function secretFormRoute(deps) {
7
+ return (req, res, token) => handleSecretElicitationForm(req.method, token, () => readFormBody(req), res, deps);
8
+ }
9
+ /** A link host serving only the secret form (the composition root shares one host across routes). */
14
10
  export function createStdioSecretElicitationHost(deps) {
15
- let server;
16
- let port = 0;
17
- let idleTimer;
18
- function scheduleIdleShutdown() {
19
- if (idleTimer)
20
- clearTimeout(idleTimer);
21
- idleTimer = setTimeout(() => {
22
- server?.close();
23
- server = undefined;
24
- }, IDLE_SHUTDOWN_MS);
25
- idleTimer.unref();
26
- }
27
- async function ensureServer() {
28
- if (server) {
29
- scheduleIdleShutdown();
30
- return port;
31
- }
32
- const s = createServer((req, res) => {
33
- scheduleIdleShutdown();
34
- const url = new URL(req.url ?? "/", "http://127.0.0.1");
35
- if (url.pathname !== "/secret") {
36
- res.writeHead(404).end();
37
- return;
38
- }
39
- // A failure here must never become an unhandled rejection: that would take
40
- // down the whole stdio MCP process, not just this request.
41
- handleSecretElicitationForm(req.method, url.searchParams.get("t"), () => readFormBody(req), res, deps).catch(() => {
42
- if (!res.headersSent)
43
- res.writeHead(500, { "content-type": "text/plain; charset=utf-8" });
44
- if (!res.writableEnded)
45
- res.end("Internal error");
46
- });
47
- });
48
- server = s;
49
- await new Promise((resolve, reject) => {
50
- s.once("error", reject);
51
- s.listen(0, "127.0.0.1", resolve);
52
- });
53
- const address = s.address();
54
- port = typeof address === "object" && address ? address.port : 0;
55
- scheduleIdleShutdown();
56
- return port;
57
- }
58
- return {
59
- async urlFor(token) {
60
- const p = await ensureServer();
61
- return `http://127.0.0.1:${p}/secret?t=${encodeURIComponent(token)}`;
62
- },
63
- };
11
+ const host = createStdioLinkHost({ [STDIO_SECRET_PATH]: secretFormRoute(deps) });
12
+ return { urlFor: (token) => host.urlFor(STDIO_SECRET_PATH, token) };
64
13
  }
@@ -8,7 +8,7 @@ import { createSecret, listSecrets, attachSecret, detachSecret, deleteSecret, se
8
8
  import { brokerConfigHash, parseSecretBrokerConfig } from "../../core/secret-broker-config.js";
9
9
  import { McpError } from "../errors.js";
10
10
  import { requireOwnedSecret } from "../auth/ownership.js";
11
- import { requireAgentAccess, requireBindingOwner } from "../auth/access.js";
11
+ import { requireAgentAccess, requireBindable, requireBindingOwner } from "../auth/access.js";
12
12
  import { clearUnbrokerOutcome, getSecretElicitationOutcome, } from "./secret-elicitation.js";
13
13
  import { allowedSecretNames, brokerCompatibilityWarnings } from "./secret-broker-compat.js";
14
14
  import { textResult } from "./text-result.js";
@@ -269,7 +269,7 @@ export function registerSecretsTools(mcp, opts) {
269
269
  // (A2/S2-2): a binding hands the value to every tool the owner lets
270
270
  // read it. Not even the stdio operator crosses owners.
271
271
  const { agent } = await requireAgentAccess(ctx, args.agentId, "read");
272
- requireBindingOwner(ctx, agent);
272
+ await requireBindable(ctx, agent);
273
273
  const ownerId = agent.ownerId;
274
274
  try {
275
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,9 +19,9 @@ 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;
@@ -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,7 +20,7 @@ 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";
24
25
  import { brokerCompatibilityWarnings } from "./secret-broker-compat.js";
25
26
  /**
@@ -102,7 +103,8 @@ export function registerToolAuthoringTools(mcp) {
102
103
  ownerId: ctx.principal.id,
103
104
  },
104
105
  });
105
- return textResult(tool);
106
+ const warnings = await zod3ToolWarnings(toolSubject(tool.name), args.paramsZod);
107
+ return textResult(warnings.length ? { ...tool, warnings } : tool);
106
108
  }
107
109
  catch (err) {
108
110
  if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === "P2002") {
@@ -145,7 +147,8 @@ export function registerToolAuthoringTools(mcp) {
145
147
  // landing between the check and the write.
146
148
  try {
147
149
  const tool = await updateToolGuarded(ctx.db, args.toolId, prepared.data, (row) => assertStrictlyOwnedTool(row, args.toolId, ctx.principal.id));
148
- return textResult(tool);
150
+ const warnings = args.paramsZod === undefined ? [] : await zod3ToolWarnings(toolSubject(tool.name), args.paramsZod);
151
+ return textResult(warnings.length ? { ...tool, warnings } : tool);
149
152
  }
150
153
  catch (err) {
151
154
  if (err instanceof ToolAttachedError) {
@@ -193,7 +196,7 @@ export function registerToolAuthoringTools(mcp) {
193
196
  mcp.registerTool({
194
197
  name: "dry_run_tool",
195
198
  scope: "tools:write",
196
- 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.",
197
200
  inputSchema: {
198
201
  type: "object",
199
202
  properties: {
@@ -217,10 +220,19 @@ export function registerToolAuthoringTools(mcp) {
217
220
  }
218
221
  const jsonSchema = schemaResult.value;
219
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] } : {};
220
231
  if (!validated.ok) {
221
232
  return textResult({
222
233
  jsonSchema,
223
234
  result: { ok: false, errorKind: validated.errorKind, errorMessage: validated.errorMessage },
235
+ ...warnings,
224
236
  });
225
237
  }
226
238
  // No real agent exists for a dry run — the caller's own principal
@@ -243,7 +255,7 @@ export function registerToolAuthoringTools(mcp) {
243
255
  toolName: "dry_run_tool",
244
256
  allowedFetchHosts: hosts.data.allowedHosts ?? [],
245
257
  });
246
- return textResult({ jsonSchema, result: sandboxResult });
258
+ return textResult({ jsonSchema, result: sandboxResult, ...warnings });
247
259
  },
248
260
  });
249
261
  mcp.registerTool({
@@ -294,6 +306,9 @@ export function registerToolAuthoringTools(mcp) {
294
306
  if (capabilitiesPassed && !isOwner) {
295
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.");
296
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
+ }
297
312
  const existing = await tx.agentTool.findUnique({
298
313
  where: { agentId_toolId: { agentId: args.agentId, toolId: args.toolId } },
299
314
  });
@@ -374,19 +389,20 @@ export function registerToolAuthoringTools(mcp) {
374
389
  scope: "tools:write",
375
390
  inputSchema: { type: "object", properties: { agentId: { type: "string" } } },
376
391
  handler: async (args, ctx) => {
377
- 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));
378
394
  if (args.agentId) {
379
395
  const { access } = await requireAgentAccess(ctx, args.agentId, "read");
380
396
  const rows = await ctx.db.agentTool.findMany({ where: { agentId: args.agentId }, include: { tool: true } });
381
397
  // The agent's owner sees every tool on it (projected: code only for
382
398
  // the tool's own owner); anyone else only tools they could see anyway.
383
- return textResult(rows
399
+ return textResult(await Promise.all(rows
384
400
  .map((r) => r.tool)
385
401
  .filter((tool) => access === "owner" || canRead(tool.ownerId, ctx.principal.id))
386
- .map(project));
402
+ .map(project)));
387
403
  }
388
404
  const tools = await ctx.db.tool.findMany({ where: visibleToPrincipal(ctx.principal.id) });
389
- 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)));
390
406
  },
391
407
  });
392
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;