@wardby/cli 0.6.0 → 0.8.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 (740) hide show
  1. package/.env.example +5 -5
  2. package/README.md +6 -1
  3. package/deploy/local/docker-compose.quickstart-coding.yml +19 -0
  4. package/dist/claude-coding-worker/driver.d.ts +33 -3
  5. package/dist/claude-coding-worker/driver.js +151 -21
  6. package/dist/claude-coding-worker/main.js +38 -6
  7. package/dist/claude-coding-worker/sdk.js +29 -2
  8. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  9. package/dist/claude-coding-worker/tool-socket.js +111 -0
  10. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  11. package/dist/claude-coding-worker/transcript.js +77 -0
  12. package/dist/claude-plugin/command.d.ts +61 -0
  13. package/dist/claude-plugin/command.js +376 -0
  14. package/dist/cli-help.d.ts +1 -1
  15. package/dist/cli-help.js +3 -1
  16. package/dist/cli.js +71 -13
  17. package/dist/coding/code-host.d.ts +16 -0
  18. package/dist/coding/code-host.js +60 -0
  19. package/dist/coding/continuation-wording.d.ts +35 -0
  20. package/dist/coding/continuation-wording.js +73 -0
  21. package/dist/coding/linked-issue-note.d.ts +23 -0
  22. package/dist/coding/linked-issue-note.js +47 -0
  23. package/dist/coding/mcp-token.d.ts +12 -0
  24. package/dist/coding/mcp-token.js +26 -0
  25. package/dist/coding/merge-wording.d.ts +28 -0
  26. package/dist/coding/merge-wording.js +78 -0
  27. package/dist/coding/pr-description-note.d.ts +9 -0
  28. package/dist/coding/pr-description-note.js +32 -0
  29. package/dist/coding/profile.d.ts +46 -126
  30. package/dist/coding/profile.js +45 -4
  31. package/dist/coding/protected-path-wording.d.ts +8 -0
  32. package/dist/coding/protected-path-wording.js +1 -1
  33. package/dist/coding/protocol.d.ts +264 -346
  34. package/dist/coding/protocol.js +237 -12
  35. package/dist/coding/redact.d.ts +3 -0
  36. package/dist/coding/redact.js +17 -0
  37. package/dist/coding/registry/allowlist.d.ts +12 -0
  38. package/dist/coding/registry/allowlist.js +14 -1
  39. package/dist/coding/registry/audit-mode.d.ts +153 -0
  40. package/dist/coding/registry/audit-mode.js +304 -0
  41. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  42. package/dist/coding/registry/lockfile-shared.js +128 -0
  43. package/dist/coding/registry/lockfiles.js +1 -1
  44. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  45. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  46. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  47. package/dist/coding/registry/npm-lockfile.js +4 -6
  48. package/dist/coding/registry/npm.js +78 -8
  49. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  50. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  51. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  52. package/dist/coding/registry/pypi-plan.js +406 -0
  53. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  54. package/dist/coding/registry/pypi-requirements.js +155 -0
  55. package/dist/coding/registry/pypi.d.ts +3 -27
  56. package/dist/coding/registry/pypi.js +40 -154
  57. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  58. package/dist/coding/registry/refusal-hints.js +61 -0
  59. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  60. package/dist/coding/registry/refusal-wording.js +56 -0
  61. package/dist/coding/registry/report.d.ts +70 -8
  62. package/dist/coding/registry/report.js +112 -5
  63. package/dist/coding/registry/types.d.ts +58 -8
  64. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  65. package/dist/coding/registry/yarn-lockfile.js +367 -0
  66. package/dist/coding/services/catalog.d.ts +37 -351
  67. package/dist/coding/transcript/claude-code.d.ts +13 -0
  68. package/dist/coding/transcript/claude-code.js +273 -0
  69. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  70. package/dist/coding/transcript/download-protocol.js +18 -0
  71. package/dist/coding/transcript/format.d.ts +20 -0
  72. package/dist/coding/transcript/format.js +32 -0
  73. package/dist/coding/transcript/recorder.d.ts +52 -0
  74. package/dist/coding/transcript/recorder.js +225 -0
  75. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  76. package/dist/coding/transcript/resume/checkout.js +203 -0
  77. package/dist/coding/transcript/resume/command.d.ts +17 -0
  78. package/dist/coding/transcript/resume/command.js +176 -0
  79. package/dist/coding/transcript/resume/download.d.ts +20 -0
  80. package/dist/coding/transcript/resume/download.js +153 -0
  81. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  82. package/dist/coding/transcript/resume/launch.js +128 -0
  83. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  84. package/dist/coding/transcript/resume/session-file.js +79 -0
  85. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  86. package/dist/coding/transcript/resume/stand-in.js +49 -0
  87. package/dist/coding-worker/artifact.d.ts +8 -3
  88. package/dist/coding-worker/artifact.js +3 -1
  89. package/dist/coding-worker/debug-trace.d.ts +9 -6
  90. package/dist/coding-worker/debug-trace.js +16 -19
  91. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  92. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  93. package/dist/coding-worker/driver.d.ts +4 -3
  94. package/dist/coding-worker/driver.js +124 -39
  95. package/dist/coding-worker/errors.d.ts +1 -0
  96. package/dist/coding-worker/errors.js +32 -0
  97. package/dist/coding-worker/main.js +5 -1
  98. package/dist/coding-worker/mcp-config.d.ts +27 -0
  99. package/dist/coding-worker/mcp-config.js +32 -0
  100. package/dist/coding-worker/sdk.d.ts +36 -0
  101. package/dist/coding-worker/sdk.js +28 -1
  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 +15 -0
  105. package/dist/config/dependency-cache.d.ts +23 -0
  106. package/dist/config/dependency-cache.js +32 -0
  107. package/dist/config/mcp-call-limit.d.ts +8 -0
  108. package/dist/config/mcp-call-limit.js +18 -0
  109. package/dist/config/mcp-servers.d.ts +8 -0
  110. package/dist/config/mcp-servers.js +12 -0
  111. package/dist/config/providers.d.ts +12 -3
  112. package/dist/config/providers.js +55 -5
  113. package/dist/config/test-simulators.d.ts +92 -0
  114. package/dist/config/test-simulators.js +333 -0
  115. package/dist/config/tool-timeout.d.ts +1 -0
  116. package/dist/config/tool-timeout.js +18 -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-mcp.d.ts +36 -0
  130. package/dist/core/coding-mcp.js +253 -0
  131. package/dist/core/coding-queue.d.ts +2 -1
  132. package/dist/core/coding-queue.js +7 -0
  133. package/dist/core/coding-repository.d.ts +46 -0
  134. package/dist/core/coding-repository.js +92 -0
  135. package/dist/core/cron.d.ts +19 -1
  136. package/dist/core/cron.js +17 -0
  137. package/dist/core/datastores.js +1 -1
  138. package/dist/core/deferred-coding.d.ts +14 -0
  139. package/dist/core/deferred-coding.js +62 -0
  140. package/dist/core/delegation-child.d.ts +25 -0
  141. package/dist/core/delegation-child.js +37 -0
  142. package/dist/core/delegation-slots.d.ts +27 -0
  143. package/dist/core/delegation-slots.js +44 -0
  144. package/dist/core/dispatch.d.ts +48 -2
  145. package/dist/core/dispatch.js +166 -66
  146. package/dist/core/engine-native.js +1 -1
  147. package/dist/core/error-code.d.ts +38 -0
  148. package/dist/core/error-code.js +169 -0
  149. package/dist/core/grants.d.ts +46 -8
  150. package/dist/core/grants.js +99 -8
  151. package/dist/core/host-events.d.ts +18 -2
  152. package/dist/core/host-events.js +291 -27
  153. package/dist/core/host-status.d.ts +85 -3
  154. package/dist/core/host-status.js +300 -22
  155. package/dist/core/issue-bridge.d.ts +50 -6
  156. package/dist/core/issue-bridge.js +124 -33
  157. package/dist/core/issue-events.d.ts +1 -1
  158. package/dist/core/issue-events.js +4 -10
  159. package/dist/core/issue-status.d.ts +1 -1
  160. package/dist/core/issue-status.js +58 -29
  161. package/dist/core/logger.d.ts +5 -0
  162. package/dist/core/logger.js +14 -1
  163. package/dist/core/lost-run-children.d.ts +6 -0
  164. package/dist/core/lost-run-children.js +32 -0
  165. package/dist/core/mark-ready.d.ts +34 -0
  166. package/dist/core/mark-ready.js +152 -0
  167. package/dist/core/markdown-code.d.ts +8 -0
  168. package/dist/core/markdown-code.js +107 -0
  169. package/dist/core/mcp-client/client.d.ts +47 -0
  170. package/dist/core/mcp-client/client.js +141 -0
  171. package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
  172. package/dist/core/mcp-client/jsonrpc.js +54 -0
  173. package/dist/core/mcp-client/results.d.ts +13 -0
  174. package/dist/core/mcp-client/results.js +42 -0
  175. package/dist/core/mcp-servers.d.ts +90 -0
  176. package/dist/core/mcp-servers.js +230 -0
  177. package/dist/core/mcp-tools.d.ts +108 -0
  178. package/dist/core/mcp-tools.js +287 -0
  179. package/dist/core/memory-tools.js +7 -0
  180. package/dist/core/merge-order-check.d.ts +2 -1
  181. package/dist/core/merge-order-check.js +44 -18
  182. package/dist/core/notification-dispatcher.js +2 -1
  183. package/dist/core/notification-templates.d.ts +1 -7
  184. package/dist/core/notification-templates.js +36 -2
  185. package/dist/core/pull-request-state-sync.js +2 -2
  186. package/dist/core/reconciler.d.ts +4 -3
  187. package/dist/core/reconciler.js +8 -1
  188. package/dist/core/related-pull-requests.d.ts +11 -3
  189. package/dist/core/related-pull-requests.js +49 -20
  190. package/dist/core/reply-parts.d.ts +21 -0
  191. package/dist/core/reply-parts.js +73 -0
  192. package/dist/core/review-fix.d.ts +1 -1
  193. package/dist/core/review-fix.js +4 -3
  194. package/dist/core/review-host-checks.d.ts +1 -1
  195. package/dist/core/review-host-tools.d.ts +3 -0
  196. package/dist/core/review-host-tools.js +102 -14
  197. package/dist/core/review-reads.d.ts +55 -0
  198. package/dist/core/review-reads.js +233 -0
  199. package/dist/core/run-status.d.ts +12 -0
  200. package/dist/core/run-status.js +12 -0
  201. package/dist/core/runner.d.ts +145 -49
  202. package/dist/core/runner.js +719 -216
  203. package/dist/core/schedule-start.d.ts +12 -0
  204. package/dist/core/schedule-start.js +14 -0
  205. package/dist/core/secret-broker-config.d.ts +12 -74
  206. package/dist/core/secret-broker-config.js +1 -1
  207. package/dist/core/secret-guard.d.ts +49 -0
  208. package/dist/core/secret-guard.js +119 -0
  209. package/dist/core/secret-guarded-stores.d.ts +12 -0
  210. package/dist/core/secret-guarded-stores.js +41 -0
  211. package/dist/core/secret-spans.d.ts +50 -0
  212. package/dist/core/secret-spans.js +94 -0
  213. package/dist/core/secrets.d.ts +11 -1
  214. package/dist/core/secrets.js +27 -1
  215. package/dist/core/serializable-retry.d.ts +18 -0
  216. package/dist/core/serializable-retry.js +43 -0
  217. package/dist/core/stop-run.d.ts +46 -0
  218. package/dist/core/stop-run.js +61 -0
  219. package/dist/core/tool-admin.d.ts +5 -1
  220. package/dist/core/tool-admin.js +7 -2
  221. package/dist/core/tool-names.d.ts +13 -0
  222. package/dist/core/tool-names.js +20 -0
  223. package/dist/core/webhooks.d.ts +4 -0
  224. package/dist/core/webhooks.js +68 -49
  225. package/dist/core/workflow-events.d.ts +14 -2
  226. package/dist/core/workflow-events.js +4 -0
  227. package/dist/core/workflow-run-events.d.ts +5 -3
  228. package/dist/core/workflow-run-events.js +45 -9
  229. package/dist/core/zod-json-schema.d.ts +4 -0
  230. package/dist/core/zod-json-schema.js +39 -0
  231. package/dist/core/zod3-window.d.ts +35 -0
  232. package/dist/core/zod3-window.js +124 -0
  233. package/dist/generated/prisma/browser.d.ts +65 -3
  234. package/dist/generated/prisma/client.d.ts +65 -3
  235. package/dist/generated/prisma/commonInputTypes.d.ts +266 -106
  236. package/dist/generated/prisma/enums.d.ts +10 -0
  237. package/dist/generated/prisma/enums.js +8 -0
  238. package/dist/generated/prisma/internal/class.d.ts +110 -0
  239. package/dist/generated/prisma/internal/class.js +4 -4
  240. package/dist/generated/prisma/internal/prismaNamespace.d.ts +957 -9
  241. package/dist/generated/prisma/internal/prismaNamespace.js +166 -2
  242. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +174 -0
  243. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +166 -2
  244. package/dist/generated/prisma/models/Agent.d.ts +377 -8
  245. package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
  246. package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
  247. package/dist/generated/prisma/models/AgentRepository.d.ts +81 -1
  248. package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
  249. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +228 -7
  250. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  251. package/dist/generated/prisma/models/CodingProxySession.d.ts +232 -2
  252. package/dist/generated/prisma/models/CodingRun.d.ts +1712 -1
  253. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  254. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  255. package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
  256. package/dist/generated/prisma/models/HostProvider.js +1 -0
  257. package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
  258. package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
  259. package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
  260. package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
  261. package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
  262. package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
  263. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  264. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  265. package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
  266. package/dist/generated/prisma/models/McpServer.js +1 -0
  267. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +77 -1
  268. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
  269. package/dist/generated/prisma/models/Principal.d.ts +167 -0
  270. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  271. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  272. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  273. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  274. package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
  275. package/dist/generated/prisma/models/Run.d.ts +738 -2
  276. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  277. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  278. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  279. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  280. package/dist/generated/prisma/models/Secret.d.ts +387 -0
  281. package/dist/generated/prisma/models/Tool.d.ts +223 -1
  282. package/dist/generated/prisma/models.d.ts +10 -0
  283. package/dist/help/search.js +12 -3
  284. package/dist/help-index.json +2033 -110
  285. package/dist/import/create.js +48 -4
  286. package/dist/import/neutral-schema.d.ts +51 -281
  287. package/dist/import/neutral-schema.js +7 -4
  288. package/dist/knowledge/check.d.ts +1 -1
  289. package/dist/knowledge/cli.d.ts +11 -1
  290. package/dist/knowledge/cli.js +37 -4
  291. package/dist/knowledge/concept.d.ts +3 -19
  292. package/dist/knowledge/location.d.ts +31 -0
  293. package/dist/knowledge/location.js +78 -0
  294. package/dist/mcp/auth/access.d.ts +10 -2
  295. package/dist/mcp/auth/access.js +15 -1
  296. package/dist/mcp/auth/grants-cli.d.ts +6 -4
  297. package/dist/mcp/auth/grants-cli.js +42 -3
  298. package/dist/mcp/auth/ownership.d.ts +7 -7
  299. package/dist/mcp/auth/resource-server.d.ts +3 -1
  300. package/dist/mcp/auth/resource-server.js +17 -2
  301. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  302. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  303. package/dist/mcp/context.d.ts +3 -0
  304. package/dist/mcp/host-events/github-ingress.d.ts +2 -0
  305. package/dist/mcp/host-events/github-ingress.js +2 -1
  306. package/dist/mcp/index.d.ts +6 -0
  307. package/dist/mcp/index.js +69 -10
  308. package/dist/mcp/server.d.ts +13 -0
  309. package/dist/mcp/server.js +33 -14
  310. package/dist/mcp/tools/agents.d.ts +4 -0
  311. package/dist/mcp/tools/agents.js +295 -28
  312. package/dist/mcp/tools/datastore.js +17 -8
  313. package/dist/mcp/tools/grants.js +73 -29
  314. package/dist/mcp/tools/host-providers.d.ts +2 -0
  315. package/dist/mcp/tools/host-providers.js +215 -0
  316. package/dist/mcp/tools/mcp-servers.d.ts +26 -0
  317. package/dist/mcp/tools/mcp-servers.js +481 -0
  318. package/dist/mcp/tools/memory.js +11 -1
  319. package/dist/mcp/tools/notification-channels.js +2 -2
  320. package/dist/mcp/tools/packages.d.ts +2 -0
  321. package/dist/mcp/tools/packages.js +195 -0
  322. package/dist/mcp/tools/repositories.js +65 -12
  323. package/dist/mcp/tools/run-access.d.ts +16 -0
  324. package/dist/mcp/tools/run-access.js +25 -0
  325. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  326. package/dist/mcp/tools/run-transcript-download.js +129 -0
  327. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  328. package/dist/mcp/tools/run-transcript.js +70 -0
  329. package/dist/mcp/tools/runs.js +209 -27
  330. package/dist/mcp/tools/scheduling.js +3 -1
  331. package/dist/mcp/tools/secret-elicitation-form.js +5 -0
  332. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  333. package/dist/mcp/tools/secret-elicitation-server.js +10 -61
  334. package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
  335. package/dist/mcp/tools/secret-elicitation.js +25 -2
  336. package/dist/mcp/tools/secrets.js +40 -6
  337. package/dist/mcp/tools/stop-run.d.ts +2 -0
  338. package/dist/mcp/tools/stop-run.js +82 -0
  339. package/dist/mcp/tools/subagents.js +2 -2
  340. package/dist/mcp/tools/tools.d.ts +7 -5
  341. package/dist/mcp/tools/tools.js +64 -16
  342. package/dist/mcp/tools/trigger.js +28 -6
  343. package/dist/mcp/transport/http-limits.d.ts +2 -0
  344. package/dist/mcp/transport/http-limits.js +6 -2
  345. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  346. package/dist/mcp/transport/stdio-link-host.js +67 -0
  347. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  348. package/dist/mcp/transport/streamable-http.js +41 -1
  349. package/dist/mcp/webhooks/ingress.js +10 -0
  350. package/dist/native-worker/docker-launcher.d.ts +38 -2
  351. package/dist/native-worker/docker-launcher.js +65 -5
  352. package/dist/native-worker/gateway-server.d.ts +55 -3
  353. package/dist/native-worker/gateway-server.js +152 -34
  354. package/dist/native-worker/gateway.d.ts +29 -1
  355. package/dist/native-worker/gateway.js +74 -4
  356. package/dist/native-worker/http-server.d.ts +7 -1
  357. package/dist/native-worker/http-server.js +62 -7
  358. package/dist/native-worker/http-transport.js +1 -1
  359. package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
  360. package/dist/native-worker/kubernetes-launcher.js +43 -3
  361. package/dist/native-worker/launch.d.ts +18 -1
  362. package/dist/native-worker/launch.js +6 -1
  363. package/dist/native-worker/ledger.d.ts +24 -4
  364. package/dist/native-worker/ledger.js +62 -8
  365. package/dist/native-worker/loopback.js +3 -8
  366. package/dist/native-worker/main.d.ts +2 -1
  367. package/dist/native-worker/main.js +14 -3
  368. package/dist/native-worker/protocol.d.ts +130 -577
  369. package/dist/native-worker/protocol.js +51 -2
  370. package/dist/native-worker/sandbox-executor.d.ts +17 -2
  371. package/dist/native-worker/sandbox-executor.js +78 -4
  372. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  373. package/dist/native-worker/stderr-redaction.js +237 -0
  374. package/dist/native-worker/stdio.d.ts +1 -1
  375. package/dist/native-worker/stdio.js +6 -5
  376. package/dist/native-worker/warm-pool.d.ts +2 -2
  377. package/dist/native-worker/warm-pool.js +4 -4
  378. package/dist/native-worker/worker.js +28 -2
  379. package/dist/observability/metrics.js +6 -1
  380. package/dist/providers/auth/self-hosted.d.ts +1 -1
  381. package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
  382. package/dist/providers/coding-proxy/capability-hash.js +5 -0
  383. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  384. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  385. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  386. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  387. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  388. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  389. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  390. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  391. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  392. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  393. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  394. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  395. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  396. package/dist/providers/coding-proxy/hold.js +86 -0
  397. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  398. package/dist/providers/coding-proxy/interrupted.js +104 -0
  399. package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
  400. package/dist/providers/coding-proxy/mcp-route.js +166 -0
  401. package/dist/providers/coding-proxy/memory-ledger.d.ts +17 -2
  402. package/dist/providers/coding-proxy/memory-ledger.js +99 -8
  403. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  404. package/dist/providers/coding-proxy/metering.js +27 -4
  405. package/dist/providers/coding-proxy/prisma-ledger.d.ts +16 -2
  406. package/dist/providers/coding-proxy/prisma-ledger.js +209 -69
  407. package/dist/providers/coding-proxy/proxy.d.ts +21 -2
  408. package/dist/providers/coding-proxy/proxy.js +300 -48
  409. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  410. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  411. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  412. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  413. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  414. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  415. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  416. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  417. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  418. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  419. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  420. package/dist/providers/coding-proxy/registry/service.js +579 -112
  421. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  422. package/dist/providers/coding-proxy/registry/store.js +54 -1
  423. package/dist/providers/coding-proxy/runtime.d.ts +10 -0
  424. package/dist/providers/coding-proxy/runtime.js +109 -16
  425. package/dist/providers/coding-proxy/server.d.ts +9 -1
  426. package/dist/providers/coding-proxy/server.js +55 -1
  427. package/dist/providers/coding-proxy/types.d.ts +78 -1
  428. package/dist/providers/datastore/types.d.ts +5 -0
  429. package/dist/providers/engine/types.d.ts +17 -2
  430. package/dist/providers/engine/types.js +17 -0
  431. package/dist/providers/executor/composition.d.ts +10 -3
  432. package/dist/providers/executor/composition.js +52 -7
  433. package/dist/providers/executor/container.d.ts +394 -9
  434. package/dist/providers/executor/container.js +1210 -96
  435. package/dist/providers/executor/dbos-status.d.ts +31 -0
  436. package/dist/providers/executor/dbos-status.js +64 -0
  437. package/dist/providers/executor/dbos.d.ts +50 -1
  438. package/dist/providers/executor/dbos.js +207 -20
  439. package/dist/providers/executor/deferred.d.ts +12 -24
  440. package/dist/providers/executor/deferred.js +10 -29
  441. package/dist/providers/executor/in-process.d.ts +9 -1
  442. package/dist/providers/executor/in-process.js +14 -4
  443. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  444. package/dist/providers/executor/linked-issue-reader.js +30 -0
  445. package/dist/providers/executor/routing.d.ts +2 -0
  446. package/dist/providers/executor/routing.js +4 -0
  447. package/dist/providers/executor/types.d.ts +13 -0
  448. package/dist/providers/host-tools/invoke.d.ts +37 -0
  449. package/dist/providers/host-tools/invoke.js +117 -0
  450. package/dist/providers/host-tools/operations.d.ts +65 -0
  451. package/dist/providers/host-tools/operations.js +149 -0
  452. package/dist/providers/host-tools/registry.d.ts +79 -0
  453. package/dist/providers/host-tools/registry.js +362 -0
  454. package/dist/providers/host-tools/request-guard.d.ts +17 -0
  455. package/dist/providers/host-tools/request-guard.js +99 -0
  456. package/dist/providers/host-tools/self-test.d.ts +64 -0
  457. package/dist/providers/host-tools/self-test.js +142 -0
  458. package/dist/providers/index.d.ts +2 -1
  459. package/dist/providers/issue-tracker/types.d.ts +17 -0
  460. package/dist/providers/issue-tracker/types.js +39 -1
  461. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  462. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  463. package/dist/providers/jobs/docker-isolation.d.ts +10 -2
  464. package/dist/providers/jobs/docker-isolation.js +47 -8
  465. package/dist/providers/jobs/docker.d.ts +9 -0
  466. package/dist/providers/jobs/docker.js +60 -11
  467. package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
  468. package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
  469. package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
  470. package/dist/providers/jobs/kubernetes-api.js +10 -0
  471. package/dist/providers/jobs/kubernetes-client.js +10 -1
  472. package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
  473. package/dist/providers/jobs/kubernetes-isolation.js +32 -3
  474. package/dist/providers/jobs/kubernetes.d.ts +11 -1
  475. package/dist/providers/jobs/kubernetes.js +111 -17
  476. package/dist/providers/jobs/types.d.ts +39 -0
  477. package/dist/providers/jobs/types.js +13 -1
  478. package/dist/providers/llm/anthropic.js +5 -1
  479. package/dist/providers/llm/bedrock.d.ts +0 -12
  480. package/dist/providers/llm/bedrock.js +4 -0
  481. package/dist/providers/llm/claude-messages.d.ts +3 -1
  482. package/dist/providers/llm/claude-messages.js +4 -1
  483. package/dist/providers/llm/claude-provider.d.ts +2 -2
  484. package/dist/providers/llm/claude-provider.js +2 -2
  485. package/dist/providers/llm/openai.d.ts +2 -2
  486. package/dist/providers/llm/openai.js +6 -2
  487. package/dist/providers/llm/routing.d.ts +2 -2
  488. package/dist/providers/llm/routing.js +2 -2
  489. package/dist/providers/llm/types.d.ts +12 -2
  490. package/dist/providers/review-host/github-events.d.ts +9 -1
  491. package/dist/providers/review-host/github-events.js +34 -12
  492. package/dist/providers/review-host/github.d.ts +29 -2
  493. package/dist/providers/review-host/github.js +224 -29
  494. package/dist/providers/review-host/local.d.ts +8 -4
  495. package/dist/providers/review-host/local.js +49 -31
  496. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  497. package/dist/providers/review-host/patch-pages.js +176 -0
  498. package/dist/providers/review-host/review-format.d.ts +19 -1
  499. package/dist/providers/review-host/review-format.js +38 -7
  500. package/dist/providers/review-host/types.d.ts +140 -6
  501. package/dist/providers/review-host/types.js +9 -1
  502. package/dist/providers/storage/gcs.d.ts +63 -0
  503. package/dist/providers/storage/gcs.js +69 -0
  504. package/dist/providers/storage/index.d.ts +15 -0
  505. package/dist/providers/storage/index.js +14 -0
  506. package/dist/providers/storage/local.d.ts +24 -0
  507. package/dist/providers/storage/local.js +92 -0
  508. package/dist/providers/storage/meter.d.ts +14 -0
  509. package/dist/providers/storage/meter.js +34 -0
  510. package/dist/providers/storage/s3.d.ts +41 -0
  511. package/dist/providers/storage/s3.js +107 -0
  512. package/dist/providers/storage/types.d.ts +37 -3
  513. package/dist/providers/storage/types.js +21 -4
  514. package/dist/providers/vcs/git.d.ts +39 -4
  515. package/dist/providers/vcs/git.js +339 -26
  516. package/dist/providers/vcs/github-remote.d.ts +26 -3
  517. package/dist/providers/vcs/github-remote.js +124 -14
  518. package/dist/providers/vcs/github.d.ts +183 -44
  519. package/dist/providers/vcs/github.js +455 -56
  520. package/dist/providers/vcs/index.d.ts +1 -1
  521. package/dist/providers/vcs/index.js +9 -2
  522. package/dist/providers/vcs/pr-description.d.ts +127 -0
  523. package/dist/providers/vcs/pr-description.js +270 -0
  524. package/dist/providers/vcs/remote.d.ts +37 -1
  525. package/dist/providers/vcs/remote.js +7 -1
  526. package/dist/providers/vcs/routing.d.ts +16 -8
  527. package/dist/providers/vcs/routing.js +27 -6
  528. package/dist/providers/vcs/types.d.ts +150 -5
  529. package/dist/quickstart/coding-seed.d.ts +14 -3
  530. package/dist/quickstart/coding-seed.js +213 -4
  531. package/dist/quickstart/index.d.ts +5 -0
  532. package/dist/quickstart/index.js +21 -0
  533. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  534. package/dist/quickstart/reviewer-prompt.js +6 -6
  535. package/dist/quickstart-images.json +1 -1
  536. package/dist/sandbox/eval-core.d.ts +12 -2
  537. package/dist/sandbox/eval-core.js +20 -4
  538. package/dist/sandbox/generated/zod.bundle.js +62 -1
  539. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  540. package/dist/sandbox/host-functions.d.ts +5 -0
  541. package/dist/sandbox/host-functions.js +13 -13
  542. package/dist/sandbox/limits.d.ts +4 -1
  543. package/dist/sandbox/limits.js +4 -1
  544. package/dist/sandbox/run-in-sandbox.d.ts +6 -0
  545. package/dist/sandbox/run-in-sandbox.js +14 -2
  546. package/dist/sandbox/safe-fetch.d.ts +2 -0
  547. package/dist/sandbox/safe-fetch.js +1 -1
  548. package/dist/sandbox/secret-broker.d.ts +1 -0
  549. package/dist/sandbox/secret-broker.js +4 -5
  550. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  551. package/dist/sandbox/tool-timeout.d.ts +32 -0
  552. package/dist/sandbox/tool-timeout.js +52 -0
  553. package/dist/sandbox/user-tool.d.ts +8 -1
  554. package/dist/sandbox/user-tool.js +9 -3
  555. package/dist/sandbox/zod-params.d.ts +37 -5
  556. package/dist/sandbox/zod-params.js +181 -26
  557. package/dist/serve.js +8 -1
  558. package/dist/viewer/api-schema.d.ts +349 -2627
  559. package/dist/viewer/api-schema.js +7 -0
  560. package/dist/viewer/build-schemas.js +6 -2
  561. package/dist/viewer/graph.js +2 -1
  562. package/dist/viewer/openapi.js +2 -4
  563. package/dist/wardby-bin.js +15 -0
  564. package/docs/README.md +11 -1
  565. package/docs/agent-recipes.md +95 -24
  566. package/docs/architecture-runtime.md +1 -1
  567. package/docs/claude-code-plugin.md +164 -0
  568. package/docs/code-review-agents.md +557 -41
  569. package/docs/coding-agent-setup.md +566 -8
  570. package/docs/coding-packages.md +1033 -90
  571. package/docs/coding-services.md +27 -12
  572. package/docs/coding-worker-byo-images.md +24 -2
  573. package/docs/coding-worker-isolation.md +183 -37
  574. package/docs/debugging-agent-runs.md +242 -0
  575. package/docs/getting-started-gke.md +129 -141
  576. package/docs/getting-started-identity-provider.md +53 -38
  577. package/docs/getting-started.md +17 -0
  578. package/docs/host-providers.md +294 -0
  579. package/docs/jira-agents.md +17 -8
  580. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  581. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  582. package/docs/knowledge/delegation-admission-slots.md +52 -0
  583. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  584. package/docs/knowledge/import-rename-target.md +52 -0
  585. package/docs/knowledge/index.md +57 -0
  586. package/docs/knowledge/log.md +9 -0
  587. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  588. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  589. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  590. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  591. package/docs/knowledge/overview-cli.md +74 -0
  592. package/docs/knowledge/overview-coding-proxy.md +72 -0
  593. package/docs/knowledge/overview-coding.md +72 -0
  594. package/docs/knowledge/overview-config.md +60 -0
  595. package/docs/knowledge/overview-core.md +72 -0
  596. package/docs/knowledge/overview-deploy.md +83 -0
  597. package/docs/knowledge/overview-mcp.md +61 -0
  598. package/docs/knowledge/overview-prisma.md +72 -0
  599. package/docs/knowledge/overview-providers.md +89 -0
  600. package/docs/knowledge/overview-sandbox.md +83 -0
  601. package/docs/knowledge/overview-surfaces.md +83 -0
  602. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  603. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  604. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  605. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  606. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  607. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  608. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  609. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  610. package/docs/knowledge/warm-input-publication.md +30 -0
  611. package/docs/knowledge/workspace-staging-failure.md +54 -0
  612. package/docs/knowledge.md +54 -14
  613. package/docs/mcp-servers.md +254 -0
  614. package/docs/native-sandbox.md +143 -31
  615. package/docs/observability.md +4 -0
  616. package/docs/security-deployment.md +139 -29
  617. package/docs/slack-notifications.md +35 -19
  618. package/docs/tool-secrets.md +45 -10
  619. package/docs/viewer-api.md +6 -0
  620. package/docs/viewer-api.openapi.yml +1 -1
  621. package/help/admin-viewer.md +28 -2
  622. package/help/agent-recipes.md +33 -2
  623. package/help/architecture-agent.md +11 -6
  624. package/help/brokered-secrets.md +3 -0
  625. package/help/build-claude-code-image.md +1 -1
  626. package/help/build-worker-image.md +3 -1
  627. package/help/builder-agent.md +19 -6
  628. package/help/claude-code-run-pane.md +40 -0
  629. package/help/code-review-agents.md +177 -6
  630. package/help/coding-packages.md +156 -6
  631. package/help/cost-attribution.md +9 -5
  632. package/help/creating-agents.md +14 -1
  633. package/help/dependency-cache.md +143 -0
  634. package/help/deploy-gke.md +15 -8
  635. package/help/errors/budget-exhausted.md +187 -0
  636. package/help/errors/budget-group-exhausted.md +5 -1
  637. package/help/errors/coding-mcp-pins-unavailable.md +35 -0
  638. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  639. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  640. package/help/errors/continuation-closed.md +9 -12
  641. package/help/errors/database-auth-invalid.md +1 -1
  642. package/help/errors/delegation-conflict.md +24 -0
  643. package/help/errors/file-list-truncated.md +45 -0
  644. package/help/errors/full-read-required.md +49 -0
  645. package/help/errors/github-account-not-allowed.md +4 -0
  646. package/help/errors/graph-incomplete.md +43 -0
  647. package/help/errors/graph-limit.md +43 -0
  648. package/help/errors/host-provider-error.md +40 -0
  649. package/help/errors/host-tool-failed.md +36 -0
  650. package/help/errors/mcp-call-limit.md +22 -0
  651. package/help/errors/mcp-call-timeout.md +22 -0
  652. package/help/errors/mcp-server-auth-failed.md +22 -0
  653. package/help/errors/mcp-server-credentials-unavailable.md +45 -0
  654. package/help/errors/mcp-server-error.md +28 -0
  655. package/help/errors/mcp-server-unreachable.md +22 -0
  656. package/help/errors/mcp-servers-off.md +21 -0
  657. package/help/errors/mcp-tool-not-allowed.md +26 -0
  658. package/help/errors/mcp-tool-removed.md +22 -0
  659. package/help/errors/mcp-unavailable.md +25 -0
  660. package/help/errors/merge-conflict.md +49 -0
  661. package/help/errors/native-sandbox-capacity.md +1 -1
  662. package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
  663. package/help/errors/native-sandbox-docker-failed.md +1 -1
  664. package/help/errors/native-sandbox-gateway-error.md +20 -0
  665. package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
  666. package/help/errors/native-sandbox-image-not-pinned.md +1 -1
  667. package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
  668. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  669. package/help/errors/native-sandbox-network-unenforced.md +1 -1
  670. package/help/errors/native-sandbox-requires-catalog.md +1 -1
  671. package/help/errors/native-sandbox-unavailable.md +1 -1
  672. package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
  673. package/help/errors/native-sandbox-worker-exited.md +4 -3
  674. package/help/errors/native-sandbox-worker-lost.md +1 -1
  675. package/help/errors/native-sandbox-worker-unready.md +1 -1
  676. package/help/errors/package-not-allowed-pending.md +52 -0
  677. package/help/errors/package-not-allowed.md +51 -0
  678. package/help/errors/package-refusals.md +43 -0
  679. package/help/errors/patch-cursor-malformed.md +31 -0
  680. package/help/errors/repository-not-listed.md +36 -0
  681. package/help/errors/repository-required.md +36 -0
  682. package/help/errors/run-lost.md +39 -0
  683. package/help/errors/run-transcript-download.md +44 -0
  684. package/help/errors/secret-in-value.md +69 -0
  685. package/help/errors/target-merge.md +40 -0
  686. package/help/errors/tool-timeout.md +38 -0
  687. package/help/fix-merge-conflicts.md +73 -0
  688. package/help/github-app-setup.md +132 -0
  689. package/help/github.md +22 -0
  690. package/help/host-providers.md +40 -0
  691. package/help/identity-and-access.md +6 -1
  692. package/help/jira.md +23 -6
  693. package/help/knowledge.md +16 -7
  694. package/help/local-repositories.md +1 -1
  695. package/help/low-power-mode.md +7 -1
  696. package/help/mcp-servers.md +73 -0
  697. package/help/mcp.md +7 -2
  698. package/help/merge-order-check.md +5 -0
  699. package/help/native-capabilities.md +55 -1
  700. package/help/native-sandbox.md +16 -2
  701. package/help/operating-agents.md +21 -0
  702. package/help/package-audit-mode.md +91 -0
  703. package/help/related-pull-requests.md +17 -10
  704. package/help/repo-instructions-and-skills.md +3 -1
  705. package/help/resume-runs-locally.md +134 -0
  706. package/help/review-fix-rounds.md +33 -1
  707. package/help/sharing-agents.md +59 -0
  708. package/help/slack-notifications.md +19 -5
  709. package/help/status-comments.md +31 -0
  710. package/help/stop-run.md +58 -0
  711. package/help/troubleshooting/budgets.md +28 -0
  712. package/help/troubleshooting/coding-workers.md +86 -7
  713. package/help/troubleshooting/debugging-agent-runs.md +29 -0
  714. package/package.json +18 -10
  715. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  716. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  717. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  718. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  719. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  720. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  721. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  722. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  723. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  724. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  725. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  726. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  727. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  728. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  729. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  730. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  731. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  732. package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
  733. package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
  734. package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
  735. package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
  736. package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
  737. package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
  738. package/prisma/schema.prisma +468 -109
  739. package/scripts/git-askpass.sh +1 -1
  740. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -0,0 +1,195 @@
1
+ /**
2
+ * approve_audited_packages: promotes what package audit mode recorded on a
3
+ * run (docs/coding-packages.md#package-audit-mode) into the agent's package
4
+ * allowlist, as bare names. Only `top-level` records are promoted by
5
+ * default; an `unknown` one (a direct download, or after a plan fallback)
6
+ * may really be a dependency of an allowlisted package, so it is promoted
7
+ * only when `names` lists it. A `transitive` one follows its parent once that is allowlisted,
8
+ * and an `allowed` one is already on the allowlist graph (it was recorded
9
+ * only for the advisories full mode served past, which approving cannot
10
+ * waive). For a parent run, each coding sub-run's names go to that sub-run's
11
+ * own agent. Same gate as packageAllowlist: packages:approve or agents:admin,
12
+ * and only the agent's owner. Every agent is checked before any is written,
13
+ * and all are written in one transaction, so a refusal changes nothing.
14
+ * Package audit mode itself is left as it is.
15
+ */
16
+ import { Prisma } from "#prisma";
17
+ import { z } from "zod";
18
+ import { matchRoot, parseAllowlist } from "../../coding/registry/allowlist.js";
19
+ import { UNKNOWN_RELATION_LABEL } from "../../coding/registry/audit-mode.js";
20
+ import { REGISTRY_ADAPTERS } from "../../coding/registry/adapters.js";
21
+ import { logger } from "../../core/logger.js";
22
+ import { agentAccess } from "../auth/access.js";
23
+ import { requireAnyScope } from "../auth/resource-server.js";
24
+ import { McpError } from "../errors.js";
25
+ import { textResult } from "./text-result.js";
26
+ const packagesLog = logger.child({ module: "mcp-packages" });
27
+ /** codingProfile.packageAllowlist's own cap per ecosystem (coding/profile.ts). */
28
+ const MAX_ALLOWLIST_ENTRIES = 256;
29
+ const ApproveSchema = z
30
+ .object({
31
+ runId: z.string().trim().min(1).max(128),
32
+ names: z.array(z.string().min(1).max(256)).min(1).max(MAX_ALLOWLIST_ENTRIES).optional(),
33
+ })
34
+ .strict();
35
+ export function registerPackageTools(mcp) {
36
+ mcp.registerTool({
37
+ name: "approve_audited_packages",
38
+ scope: "agents:write",
39
+ description: "Add the packages a run installed under package audit mode to its agent's codingProfile.packageAllowlist, as " +
40
+ "bare names (the top-level records in get_run's packageAudit; their dependencies then follow through the " +
41
+ "allowlist graph). Records with relation unknown may be dependencies of allowlisted packages: they are added only " +
42
+ "when `names` lists them, and are returned as `unknown` otherwise. For a parent run, each coding sub-run's " +
43
+ "packages go to that sub-run's agent; nothing is changed unless every agent can be. `names` limits it to those " +
44
+ "names. Needs packages:approve or agents:admin, and only the agent's owner may use it. Does not turn package " +
45
+ "audit mode off.",
46
+ inputSchema: {
47
+ type: "object",
48
+ additionalProperties: false,
49
+ properties: {
50
+ runId: { type: "string", description: "The run whose package audit to approve (get_run's packageAudit)." },
51
+ names: {
52
+ type: "array",
53
+ items: { type: "string" },
54
+ description: "Only these package names (as get_run lists them), including any with relation unknown to add; omitted means every top-level one.",
55
+ },
56
+ },
57
+ required: ["runId"],
58
+ },
59
+ handler: async (raw, ctx) => {
60
+ const parsed = ApproveSchema.safeParse(raw);
61
+ if (!parsed.success) {
62
+ const details = parsed.error.issues.map((i) => `${i.path.join(".") || "input"}: ${i.message}`).join("; ");
63
+ throw new McpError(400, `Invalid approve_audited_packages arguments: ${details}`);
64
+ }
65
+ const { runId, names } = parsed.data;
66
+ // The same gate as changing packageAllowlist through update_agent.
67
+ requireAnyScope(ctx, ctx.canonicalUri, "packages:approve", "agents:admin");
68
+ // Visible to the agent's owner and the run's triggerer only, exactly as get_run.
69
+ const notFound = new McpError(404, `Run "${runId}" not found.`);
70
+ const run = await ctx.db.run.findUnique({
71
+ where: { id: runId },
72
+ select: { id: true, agentId: true, triggeredById: true },
73
+ });
74
+ if (!run)
75
+ throw notFound;
76
+ if (run.triggeredById !== ctx.principal.id) {
77
+ const agent = await ctx.db.agent.findUnique({ where: { id: run.agentId } });
78
+ if (!agent || (await agentAccess(ctx, agent)) !== "owner")
79
+ throw notFound;
80
+ }
81
+ // The coding runs whose records count, with the agent each one belongs to.
82
+ const coding = await ctx.db.codingRun.findUnique({ where: { runId }, select: { runId: true } });
83
+ const targets = coding
84
+ ? [{ runId, agentId: run.agentId }]
85
+ : (await ctx.db.run.findMany({
86
+ where: { parentRunId: runId },
87
+ select: { id: true, agentId: true, codingRun: { select: { runId: true } } },
88
+ }))
89
+ .filter((child) => child.codingRun)
90
+ .map((child) => ({ runId: child.id, agentId: child.agentId }));
91
+ const agentOf = new Map(targets.map((target) => [target.runId, target.agentId]));
92
+ const records = targets.length > 0
93
+ ? await ctx.db.registryAuditRecord.findMany({
94
+ where: { runId: { in: targets.map((target) => target.runId) } },
95
+ select: { runId: true, ecosystem: true, name: true, relation: true },
96
+ orderBy: { createdAt: "asc" },
97
+ })
98
+ : [];
99
+ const wanted = names ? new Set(names) : null;
100
+ /** agentId -> ecosystem -> names to add, first-seen order. */
101
+ const byAgent = new Map();
102
+ /** Unknown-relation names left out (not named), per ecosystem + name. */
103
+ const skippedUnknown = new Map();
104
+ const topLevel = new Set(records.filter((r) => r.relation === "top-level").map((r) => `${r.runId}\0${r.ecosystem}\0${r.name}`));
105
+ for (const record of records) {
106
+ if (record.relation !== "top-level" && record.relation !== "unknown")
107
+ continue;
108
+ if (wanted ? !wanted.has(record.name) : record.relation !== "top-level") {
109
+ if (!wanted && !topLevel.has(`${record.runId}\0${record.ecosystem}\0${record.name}`))
110
+ skippedUnknown.set(`${record.ecosystem}\0${record.name}`, {
111
+ ecosystem: record.ecosystem,
112
+ name: record.name,
113
+ });
114
+ continue;
115
+ }
116
+ const agentId = agentOf.get(record.runId);
117
+ const ecosystems = byAgent.get(agentId) ?? new Map();
118
+ byAgent.set(agentId, ecosystems);
119
+ ecosystems.set(record.ecosystem, (ecosystems.get(record.ecosystem) ?? new Set()).add(record.name));
120
+ }
121
+ // One transaction: every agent is checked (owner, coding, the cap) before any is written.
122
+ const results = await ctx.db.$transaction(async (tx) => {
123
+ const planned = [];
124
+ for (const [agentId, ecosystems] of byAgent) {
125
+ const agent = await tx.agent.findUnique({ where: { id: agentId }, include: { codingProfile: true } });
126
+ if (!agent?.codingProfile || agent.kind !== "coding") {
127
+ throw new McpError(400, `Agent "${agentId}" is not a coding agent.`);
128
+ }
129
+ // Strict, like update_agent's coding profile: the owner only.
130
+ if (agent.ownerId === null || agent.ownerId !== ctx.principal.id) {
131
+ throw new McpError(403, `Agent "${agentId}": only its owner can change its package allowlist.`);
132
+ }
133
+ const current = (agent.codingProfile.packageAllowlist ?? {});
134
+ const parsedCurrent = parseAllowlist(current, REGISTRY_ADAPTERS);
135
+ const next = Object.fromEntries(Object.entries(current).map(([ecosystem, entries]) => [ecosystem, [...entries]]));
136
+ const added = {};
137
+ for (const [ecosystem, candidates] of ecosystems) {
138
+ const adapter = REGISTRY_ADAPTERS.get(ecosystem);
139
+ if (!adapter)
140
+ continue;
141
+ const entries = parsedCurrent.get(ecosystem) ?? [];
142
+ const list = next[ecosystem] ?? [];
143
+ for (const name of candidates) {
144
+ // Already allowed (exactly, by a ranged entry, or a wildcard): an entry's range is the owner's.
145
+ if (list.includes(name) || matchRoot(entries, adapter.normalizeName(name)))
146
+ continue;
147
+ list.push(name);
148
+ (added[ecosystem] ??= []).push(name);
149
+ }
150
+ if (list.length > MAX_ALLOWLIST_ENTRIES) {
151
+ throw new McpError(400, `Agent "${agentId}": approving these would put ${list.length} ${ecosystem} entries on its allowlist; the limit is ${MAX_ALLOWLIST_ENTRIES}. Approve fewer with \`names\`, or replace some entries with a scope wildcard. Nothing was changed.`);
152
+ }
153
+ if (list.length > 0)
154
+ next[ecosystem] = list;
155
+ }
156
+ // Every added name is a registry name the proxy normalized: still parsed, so the stored allowlist stays valid.
157
+ parseAllowlist(next, REGISTRY_ADAPTERS);
158
+ planned.push({ agentId, added, packageAllowlist: next });
159
+ }
160
+ for (const result of planned) {
161
+ if (Object.keys(result.added).length === 0)
162
+ continue;
163
+ await tx.codingAgentProfile.update({
164
+ where: { agentId: result.agentId },
165
+ data: { packageAllowlist: result.packageAllowlist },
166
+ });
167
+ }
168
+ return planned;
169
+ }, { isolationLevel: Prisma.TransactionIsolationLevel.Serializable });
170
+ for (const result of results) {
171
+ const count = Object.values(result.added).reduce((sum, list) => sum + list.length, 0);
172
+ if (count > 0) {
173
+ packagesLog.info({
174
+ event: "coding.package_audit.promoted",
175
+ agentId: result.agentId,
176
+ runId,
177
+ added: count,
178
+ by: ctx.principal.id,
179
+ }, "audited packages added to the allowlist");
180
+ }
181
+ }
182
+ const unknown = [...skippedUnknown.values()];
183
+ return textResult({
184
+ runId,
185
+ agents: results,
186
+ ...(unknown.length > 0
187
+ ? {
188
+ unknown,
189
+ unknownNote: `${UNKNOWN_RELATION_LABEL.toLowerCase()}. List one in \`names\` to add it.`,
190
+ }
191
+ : {}),
192
+ });
193
+ },
194
+ });
195
+ }
@@ -12,8 +12,9 @@
12
12
  * See docs/private/2026-09-26-repo-access-authorization-spec-and-plan.md.
13
13
  */
14
14
  import { Prisma } from "#prisma";
15
- import { isLocalRepository, normalizeGitHubRepository, normalizeLocalRepository } from "../../coding/protocol.js";
16
- import { requireAgentAccess, requireBindingOwner } from "../auth/access.js";
15
+ import { CodingBaseRefSchema, isLocalRepository, normalizeGitHubRepository, normalizeLocalRepository, } from "../../coding/protocol.js";
16
+ import { codeProviderOf, normalizeHostedRepository } from "../../coding/code-host.js";
17
+ import { assertAgentAccess, requireAgentAccess, requireBindable, requireBindingOwner, requireNotPublicWritable, } from "../auth/access.js";
17
18
  import { authorizeRepositoryForSet, canonicalLocalRepository } from "../auth/repo-authorization.js";
18
19
  import { requireScope } from "../auth/resource-server.js";
19
20
  import { McpError } from "../errors.js";
@@ -27,6 +28,9 @@ function normalizeRepository(provider, repository) {
27
28
  return normalizeLocalRepository(repository);
28
29
  if (provider === "github")
29
30
  return normalizeGitHubRepository(repository);
31
+ const normalized = normalizeHostedRepository(repository);
32
+ if (codeProviderOf(normalized) === provider)
33
+ return normalized;
30
34
  }
31
35
  catch {
32
36
  // fall through
@@ -58,7 +62,7 @@ export function registerRepositoryTools(mcp) {
58
62
  mcp.registerTool({
59
63
  name: "link_repository",
60
64
  scope: "agents:write",
61
- description: "Links a native agent you own to a repository on a code-review host, with its access, event triggers, and checkName. " +
65
+ description: "Links an agent you own to a repository on a code-review host, with its access, event triggers, and checkName. " +
62
66
  "Triggers: pull_request (review each PR push), mention (answer @mentions), push (start on merges to the default branch), " +
63
67
  "review_fix (automatic review fix rounds). The review_fix trigger makes this agent the one wardby starts, automatically " +
64
68
  "and without a human comment, when wardby's own review check requests changes on a pull request a wardby coding run " +
@@ -68,9 +72,10 @@ export function registerRepositoryTools(mcp) {
68
72
  "pull_request trigger, and is unique per repository. waitForCi (only with the pull_request trigger) holds this agent's " +
69
73
  "review on a pushed head until that head's own CI finishes, instead of racing it; APPROVE is refused while CI on the " +
70
74
  "head is failing or still running. Re-linking an already-linked repository replaces its access, triggers, checkName, " +
71
- "reviewFixMaxRounds, and waitForCi (an omitted field is cleared, not kept) and re-checks access — always send the full " +
72
- "desired state. A local repository (local:/abs/path, inside the server's trusted roots) takes no triggers or checkName: " +
73
- "it supports manual reviews only (trigger_agent with review).",
75
+ "reviewFixMaxRounds, waitForCi, markReadyWhenPassing, and baseRef (an omitted field is cleared, not kept) and re-checks access " +
76
+ "— always send the full desired state. A local repository (local:/abs/path, inside the server's trusted roots) takes " +
77
+ "no triggers or checkName: it supports manual reviews only (trigger_agent with review). " +
78
+ "On a coding agent, adds a repository its runs may work in, with write access and no triggers: a GitHub repository or a local one.",
74
79
  inputSchema: {
75
80
  type: "object",
76
81
  additionalProperties: false,
@@ -92,6 +97,17 @@ export function registerRepositoryTools(mcp) {
92
97
  description: "Only with the pull_request trigger: hold this agent's review on a pushed head until that head's own CI " +
93
98
  "finishes, instead of racing it (default false).",
94
99
  },
100
+ markReadyWhenPassing: {
101
+ type: "boolean",
102
+ description: "Only on a write link: mark the draft pull requests this agent, or a coding agent it delegated to " +
103
+ "(directly or through sub-agents), opens here ready for review, once, " +
104
+ "after every Wardby review check passed, CI is green and the wardby merge order check (if any) " +
105
+ "is success (default false).",
106
+ },
107
+ baseRef: {
108
+ type: "string",
109
+ description: "Coding agents only: the base branch for runs in this repository. Default: the coding profile's baseRef.",
110
+ },
95
111
  adminOverride: {
96
112
  type: "boolean",
97
113
  description: "Admins only (agents:admin with the admin role): approve this link without checking GitHub access, recorded as an admin approval. Allowed on any agent that has an owner, not only the admin's own.",
@@ -106,16 +122,21 @@ export function registerRepositoryTools(mcp) {
106
122
  let agent;
107
123
  if (args.adminOverride === true) {
108
124
  requireScope(ctx, ctx.canonicalUri, "agents:admin");
109
- agent = await ctx.db.agent.findUnique({ where: { id: args.agentId } });
125
+ agent = await ctx.db.agent.findUnique({
126
+ where: { id: args.agentId },
127
+ include: { codingProfile: { select: { repository: true } } },
128
+ });
110
129
  if (!agent)
111
130
  throw new McpError(404, `Agent "${args.agentId}" not found.`);
131
+ await requireNotPublicWritable(agent, ctx.db);
112
132
  }
113
133
  else {
114
- agent = (await requireAgentAccess(ctx, args.agentId, "read")).agent;
115
- requireBindingOwner(ctx, agent);
116
- }
117
- if (agent.kind !== "native") {
118
- throw new McpError(400, "Repository links are for native agents only; coding agents use codingProfile.repository.");
134
+ const row = await ctx.db.agent.findUnique({
135
+ where: { id: args.agentId },
136
+ include: { codingProfile: { select: { repository: true } } },
137
+ });
138
+ agent = (await assertAgentAccess(ctx, row, args.agentId, "read")).agent;
139
+ await requireBindable(ctx, agent);
119
140
  }
120
141
  const provider = args.provider ?? (isLocalRepository(args.repository) ? "local" : "github");
121
142
  if ((provider === "local") !== isLocalRepository(args.repository)) {
@@ -125,6 +146,32 @@ export function registerRepositoryTools(mcp) {
125
146
  ? await canonicalLocalRepository(args.repository)
126
147
  : normalizeRepository(provider, args.repository);
127
148
  const triggers = [...new Set(args.triggers ?? [])];
149
+ if (agent.kind === "coding") {
150
+ if (args.access !== "write")
151
+ throw new McpError(400, "A coding agent's repository link needs write access.");
152
+ // As codingProfile.repository: anything else would pass here and fail every run at dispatch.
153
+ // What a coding run can work in, matching the coding profile.
154
+ if (provider !== "github" && provider !== "local") {
155
+ throw new McpError(400, "A coding agent's repository link must be a GitHub repository or a local: path.");
156
+ }
157
+ if (triggers.length > 0 ||
158
+ args.checkName !== undefined ||
159
+ args.reviewFixMaxRounds !== undefined ||
160
+ args.waitForCi !== undefined ||
161
+ args.markReadyWhenPassing !== undefined) {
162
+ throw new McpError(400, "A coding agent's repository link takes no triggers, checkName, reviewFixMaxRounds, waitForCi or markReadyWhenPassing.");
163
+ }
164
+ if (agent.codingProfile?.repository === repository) {
165
+ throw new McpError(400, `${repository} is already its default repository (codingProfile.repository).`);
166
+ }
167
+ }
168
+ else if (args.baseRef !== undefined) {
169
+ throw new McpError(400, "baseRef applies only to a coding agent's repository link.");
170
+ }
171
+ const parsedBaseRef = args.baseRef === undefined ? null : CodingBaseRefSchema.safeParse(args.baseRef);
172
+ if (parsedBaseRef && !parsedBaseRef.success)
173
+ throw new McpError(400, "baseRef must be a safe branch ref.");
174
+ const baseRef = parsedBaseRef ? parsedBaseRef.data : null;
128
175
  if (provider === "local") {
129
176
  if (triggers.length > 0)
130
177
  throw new McpError(400, "local repositories support manual review only");
@@ -154,6 +201,10 @@ export function registerRepositoryTools(mcp) {
154
201
  if (waitForCi && !triggers.includes("pull_request")) {
155
202
  throw new McpError(400, "waitForCi needs the pull_request trigger.");
156
203
  }
204
+ const markReadyWhenPassing = args.markReadyWhenPassing ?? false;
205
+ if (markReadyWhenPassing && args.access !== "write") {
206
+ throw new McpError(400, "markReadyWhenPassing needs write access.");
207
+ }
157
208
  // The host call happens before, and outside, the serializable transaction.
158
209
  const authorization = await authorizeRepositoryForSet(ctx, {
159
210
  ownerId: agent.ownerId,
@@ -172,6 +223,8 @@ export function registerRepositoryTools(mcp) {
172
223
  checkName,
173
224
  reviewFixMaxRounds,
174
225
  waitForCi,
226
+ markReadyWhenPassing,
227
+ baseRef,
175
228
  ...authorization,
176
229
  };
177
230
  return tx.agentRepository.upsert({
@@ -0,0 +1,16 @@
1
+ import type { PrismaClient, Run } from "#prisma";
2
+ import type { McpRequestContext } from "../context.js";
3
+ import { type GrantDb } from "../../core/grants.js";
4
+ /** Who is asking to read a run: a principal, and whether it is the stdio local operator. */
5
+ export interface RunReader {
6
+ principalId: string;
7
+ operator?: boolean;
8
+ }
9
+ /**
10
+ * Run visibility (resource-sharing grants spec §3.5, A6): a run's triggerer
11
+ * keeps seeing it even after losing access to the agent; otherwise only the
12
+ * agent's owner (or the stdio operator). Read on the agent is not enough.
13
+ */
14
+ export declare function canReadRun(db: GrantDb & Pick<PrismaClient, "agent">, run: Pick<Run, "agentId" | "triggeredById">, reader: RunReader): Promise<boolean>;
15
+ /** The run, when the caller may read it (canReadRun); otherwise the same 404 a missing run gets. */
16
+ export declare function findReadableRun(ctx: McpRequestContext, runId: string): Promise<Run>;
@@ -0,0 +1,25 @@
1
+ import { McpError } from "../errors.js";
2
+ import { effectiveAccess } from "../../core/grants.js";
3
+ /**
4
+ * Run visibility (resource-sharing grants spec §3.5, A6): a run's triggerer
5
+ * keeps seeing it even after losing access to the agent; otherwise only the
6
+ * agent's owner (or the stdio operator). Read on the agent is not enough.
7
+ */
8
+ export async function canReadRun(db, run, reader) {
9
+ if (run.triggeredById !== null && run.triggeredById === reader.principalId)
10
+ return true;
11
+ const agent = await db.agent.findUnique({ where: { id: run.agentId }, select: { id: true, ownerId: true } });
12
+ if (!agent)
13
+ return false;
14
+ return ((await effectiveAccess(db, "agent", agent, reader.principalId, { operator: reader.operator === true })) === "owner");
15
+ }
16
+ /** The run, when the caller may read it (canReadRun); otherwise the same 404 a missing run gets. */
17
+ export async function findReadableRun(ctx, runId) {
18
+ const run = await ctx.db.run.findUnique({ where: { id: runId } });
19
+ const notFound = new McpError(404, `Run "${runId}" not found.`);
20
+ if (!run)
21
+ throw notFound;
22
+ if (!(await canReadRun(ctx.db, run, { principalId: ctx.principal.id, operator: ctx.operator })))
23
+ throw notFound;
24
+ return run;
25
+ }
@@ -0,0 +1,30 @@
1
+ import type { ServerResponse } from "node:http";
2
+ import type { PrismaClient } from "#prisma";
3
+ import type { BlobStore } from "../../providers/storage/types.js";
4
+ import { RUN_TRANSCRIPT_DOWNLOAD_PATH, RUN_TRANSCRIPT_LINK_TTL_MS, TRANSCRIPT_META_HEADER, TRANSCRIPT_SESSION_HEADER, TRANSCRIPT_SHA256_HEADER } from "../../coding/transcript/download-protocol.js";
5
+ export { RUN_TRANSCRIPT_DOWNLOAD_PATH, RUN_TRANSCRIPT_LINK_TTL_MS, TRANSCRIPT_META_HEADER, TRANSCRIPT_SESSION_HEADER, TRANSCRIPT_SHA256_HEADER, };
6
+ /**
7
+ * Which host serves a link. A stdio link (which may carry the operator flag) is never accepted by
8
+ * the HTTP route, even when REQUEST_STATE_KEY is shared and its signature verifies there.
9
+ */
10
+ export type RunTranscriptLinkAudience = "stdio" | "http";
11
+ export interface RunTranscriptLinkPayload {
12
+ kind: "run-transcript";
13
+ runId: string;
14
+ principalId: string;
15
+ /** The host that minted the link, and the only one that serves it. */
16
+ aud: RunTranscriptLinkAudience;
17
+ /** The stdio local operator: owner of every run for access checks. Only ever on a stdio link. */
18
+ operator?: boolean;
19
+ /** Epoch ms after which the link is refused. */
20
+ exp: number;
21
+ }
22
+ export interface RunTranscriptDownloadDeps {
23
+ verify: (token: string) => Promise<unknown>;
24
+ /** The host serving this route: only links minted for it are accepted. */
25
+ audience: RunTranscriptLinkAudience;
26
+ db: Pick<PrismaClient, "run" | "agent" | "resourceGrant" | "codingRun" | "runTranscript">;
27
+ blobs: BlobStore | undefined;
28
+ now?: () => Date;
29
+ }
30
+ export declare function handleRunTranscriptDownload(method: string | undefined, token: string | null, res: ServerResponse, deps: RunTranscriptDownloadDeps): Promise<void>;
@@ -0,0 +1,129 @@
1
+ /**
2
+ * The download behind `get_run_transcript`'s link: a short-lived signed token
3
+ * (the MCP server's requestState codec, so HMAC + expiry) that names one run
4
+ * and the principal it was minted for. Served by both hosts: the HTTP
5
+ * transport's mounted route (streamable-http.ts) and, on stdio, the
6
+ * ephemeral loopback server (stdio-link-host.ts).
7
+ *
8
+ * The token is a bearer capability. It travels only in the `t` query
9
+ * parameter; nothing here logs it, and no response or error echoes it.
10
+ * Every refusal is a fixed code. On download, access is checked again
11
+ * (canReadRun, as get_run) for the principal in the token, so a link stops
12
+ * working when that principal loses access.
13
+ */
14
+ import { createHash } from "node:crypto";
15
+ import { canReadRun } from "./run-access.js";
16
+ import { RUN_TRANSCRIPT_DOWNLOAD_PATH, RUN_TRANSCRIPT_LINK_TTL_MS, TRANSCRIPT_META_HEADER, TRANSCRIPT_SESSION_HEADER, TRANSCRIPT_SHA256_HEADER, } from "../../coding/transcript/download-protocol.js";
17
+ // The route path and headers are shared with `wardby resume` (download-protocol.ts).
18
+ export { RUN_TRANSCRIPT_DOWNLOAD_PATH, RUN_TRANSCRIPT_LINK_TTL_MS, TRANSCRIPT_META_HEADER, TRANSCRIPT_SESSION_HEADER, TRANSCRIPT_SHA256_HEADER, };
19
+ const STATUS = {
20
+ link_invalid: 403,
21
+ not_found: 404,
22
+ transcript_expired: 410,
23
+ transcript_unavailable: 503,
24
+ transcript_corrupt: 500,
25
+ };
26
+ function refuse(res, code) {
27
+ res
28
+ .writeHead(STATUS[code], {
29
+ "content-type": "application/json",
30
+ "cache-control": "no-store",
31
+ "referrer-policy": "no-referrer",
32
+ })
33
+ .end(JSON.stringify({ error: code }));
34
+ }
35
+ function isPayload(value) {
36
+ const v = value;
37
+ return (!!v &&
38
+ v.kind === "run-transcript" &&
39
+ typeof v.runId === "string" &&
40
+ typeof v.principalId === "string" &&
41
+ typeof v.exp === "number" &&
42
+ (v.aud === "stdio" || v.aud === "http") &&
43
+ (v.operator === undefined || typeof v.operator === "boolean") &&
44
+ // The operator flag belongs to stdio only.
45
+ !(v.aud === "http" && v.operator !== undefined));
46
+ }
47
+ export async function handleRunTranscriptDownload(method, token, res, deps) {
48
+ if (method !== "GET") {
49
+ res.writeHead(405, { allow: "GET", "cache-control": "no-store" }).end();
50
+ return;
51
+ }
52
+ const now = (deps.now ?? (() => new Date()))();
53
+ let payload;
54
+ try {
55
+ if (!token)
56
+ throw new Error("missing");
57
+ payload = await deps.verify(token);
58
+ }
59
+ catch {
60
+ refuse(res, "link_invalid");
61
+ return;
62
+ }
63
+ if (!isPayload(payload) || payload.aud !== deps.audience || payload.exp <= now.getTime()) {
64
+ refuse(res, "link_invalid");
65
+ return;
66
+ }
67
+ const run = await deps.db.run.findUnique({
68
+ where: { id: payload.runId },
69
+ select: { id: true, agentId: true, triggeredById: true },
70
+ });
71
+ if (!run || !(await canReadRun(deps.db, run, { principalId: payload.principalId, operator: payload.operator }))) {
72
+ refuse(res, "not_found");
73
+ return;
74
+ }
75
+ const [row, codingRun] = await Promise.all([
76
+ deps.db.runTranscript.findUnique({ where: { runId: run.id } }),
77
+ deps.db.codingRun.findUnique({
78
+ where: { runId: run.id },
79
+ select: { repository: true, headRef: true, resultBranch: true, baseSha: true, provider: true },
80
+ }),
81
+ ]);
82
+ if (!row || !codingRun || row.status !== "stored" || !row.blobKey || !row.sha256 || !row.sessionId) {
83
+ refuse(res, "not_found");
84
+ return;
85
+ }
86
+ if (row.expiresAt.getTime() <= now.getTime()) {
87
+ refuse(res, "transcript_expired");
88
+ return;
89
+ }
90
+ if (!deps.blobs) {
91
+ refuse(res, "transcript_unavailable");
92
+ return;
93
+ }
94
+ let bytes;
95
+ try {
96
+ bytes = await deps.blobs.get(row.blobKey);
97
+ }
98
+ catch {
99
+ refuse(res, "transcript_unavailable");
100
+ return;
101
+ }
102
+ // The stored object must still be what was recorded.
103
+ if (createHash("sha256").update(bytes).digest("hex") !== row.sha256) {
104
+ refuse(res, "transcript_corrupt");
105
+ return;
106
+ }
107
+ const meta = {
108
+ runId: run.id,
109
+ sessionId: row.sessionId,
110
+ provider: row.provider,
111
+ repository: codingRun.repository,
112
+ headRef: codingRun.headRef,
113
+ resultBranch: codingRun.resultBranch,
114
+ baseSha: codingRun.baseSha,
115
+ sha256: row.sha256,
116
+ };
117
+ res
118
+ .writeHead(200, {
119
+ "content-type": "application/gzip",
120
+ "content-length": String(bytes.byteLength),
121
+ "cache-control": "no-store",
122
+ "referrer-policy": "no-referrer",
123
+ "x-content-type-options": "nosniff",
124
+ [TRANSCRIPT_SHA256_HEADER]: row.sha256,
125
+ [TRANSCRIPT_SESSION_HEADER]: row.sessionId,
126
+ [TRANSCRIPT_META_HEADER]: Buffer.from(JSON.stringify(meta)).toString("base64url"),
127
+ })
128
+ .end(bytes);
129
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * get_run_transcript: the way to continue a coding run's session locally.
3
+ * The transcript itself never enters the caller's context: the tool returns
4
+ * a short-lived signed download link and the command that imports it
5
+ * (`npx @wardby/cli@latest resume -`, which reads the link from standard input). Same access as get_run.
6
+ */
7
+ import type { WardbyMcpServer } from "../server.js";
8
+ import { type RunTranscriptLinkAudience } from "./run-transcript-download.js";
9
+ /** Builds the download URL for a minted token (HTTP: the canonical origin; stdio: the loopback server). */
10
+ export type RunTranscriptUrlBuilder = (token: string) => Promise<string>;
11
+ export interface RunTranscriptToolOptions {
12
+ downloadUrl: RunTranscriptUrlBuilder;
13
+ /** Whether the server has a blob store to serve transcripts from. */
14
+ blobStoreConfigured: boolean;
15
+ /** The host that serves the links this server mints (stdio's loopback server, or the HTTP route). */
16
+ audience: RunTranscriptLinkAudience;
17
+ now?: () => Date;
18
+ }
19
+ export declare function registerRunTranscriptTool(mcp: WardbyMcpServer, opts: RunTranscriptToolOptions): void;
@@ -0,0 +1,70 @@
1
+ import { textResult } from "./text-result.js";
2
+ import { findReadableRun } from "./run-access.js";
3
+ import { RUN_TRANSCRIPT_LINK_TTL_MS, } from "./run-transcript-download.js";
4
+ /** What each status other than `stored` means, for the caller. */
5
+ const MEANINGS = {
6
+ none: "No transcript was recorded for this run. Turn on codingProfile.sessionResume for the agent; it applies to runs started after that.",
7
+ too_large: "The run's transcript was larger than RUN_TRANSCRIPT_MAX_BYTES, so it was not stored.",
8
+ not_captured: "No transcript was stored for this run (see reason): for example the server had no blob store, the run was stopped or timed out, or it never finished a turn.",
9
+ failed: "Storing this run's transcript failed (see reason). Nothing was stored.",
10
+ expired: "The transcript was deleted after RUN_TRANSCRIPT_RETENTION_DAYS.",
11
+ unavailable: "The transcript was stored, but this server has no blob store configured to serve it from.",
12
+ unsupported: "Resuming this kind of run locally is not supported yet: only Claude Code coding runs can be resumed.",
13
+ };
14
+ function notStored(runId, status, reason) {
15
+ return textResult({ runId, status, ...(reason ? { reason } : {}), meaning: MEANINGS[status] });
16
+ }
17
+ export function registerRunTranscriptTool(mcp, opts) {
18
+ mcp.registerTool({
19
+ name: "get_run_transcript",
20
+ description: "Get a short-lived download link for a Claude Code coding run's session transcript, and the command that continues the session locally (npx @wardby/cli@latest resume -, which asks for the link). Give the user the command and the link to run in a terminal inside a clone of the run's repository; do not fetch the link yourself. Same access as get_run. The link works for 10 minutes.",
21
+ scope: "agents:read",
22
+ inputSchema: { type: "object", properties: { runId: { type: "string" } }, required: ["runId"] },
23
+ handler: async (args, ctx) => {
24
+ const run = await findReadableRun(ctx, args.runId);
25
+ const codingRun = await ctx.db.codingRun.findUnique({
26
+ where: { runId: run.id },
27
+ select: { provider: true, repository: true, headRef: true, resultBranch: true, baseSha: true },
28
+ });
29
+ if (!codingRun)
30
+ return notStored(run.id, "unsupported", "not_a_coding_run");
31
+ if (codingRun.provider !== "claude-code")
32
+ return notStored(run.id, "unsupported", "provider_unsupported");
33
+ const row = await ctx.db.runTranscript.findUnique({ where: { runId: run.id } });
34
+ if (!row)
35
+ return notStored(run.id, "none");
36
+ if (row.status !== "stored" || !row.sessionId)
37
+ return notStored(run.id, row.status, row.reason);
38
+ const now = (opts.now ?? (() => new Date()))();
39
+ if (row.expiresAt.getTime() <= now.getTime())
40
+ return notStored(run.id, "expired");
41
+ if (!opts.blobStoreConfigured)
42
+ return notStored(run.id, "unavailable", "no_blob_store");
43
+ const exp = now.getTime() + RUN_TRANSCRIPT_LINK_TTL_MS;
44
+ const payload = {
45
+ kind: "run-transcript",
46
+ runId: run.id,
47
+ principalId: ctx.principal.id,
48
+ aud: opts.audience,
49
+ ...(ctx.operator && opts.audience === "stdio" ? { operator: true } : {}),
50
+ exp,
51
+ };
52
+ const url = await opts.downloadUrl(await mcp.mintRequestState(payload));
53
+ const linkExpiresAt = new Date(exp).toISOString();
54
+ return textResult({
55
+ runId: run.id,
56
+ status: "stored",
57
+ sessionId: row.sessionId,
58
+ provider: codingRun.provider,
59
+ repository: codingRun.repository,
60
+ branch: codingRun.resultBranch ?? codingRun.headRef,
61
+ baseSha: codingRun.baseSha,
62
+ sizeBytes: row.sizeBytes,
63
+ expiresAt: row.expiresAt.toISOString(),
64
+ download: { url, expiresAt: linkExpiresAt },
65
+ command: "npx @wardby/cli@latest resume -",
66
+ note: "Run the command in a terminal, inside a clone of the repository (not needed for a local: repository), and paste download.url when it asks. Reading the link this way keeps it out of shell history and the process list. The link is a credential for this transcript until it expires: do not share it.",
67
+ });
68
+ },
69
+ });
70
+ }