@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
@@ -1,10 +1,28 @@
1
1
  import type { PackageAllowlist } from "../../../coding/registry/allowlist.js";
2
+ import type { AuditAdvisory, AuditRelation, PackageAuditMode, PackageAuditVerdict } from "../../../coding/registry/audit-mode.js";
2
3
  import type { DeclaredDependency, FileDependency } from "../../../coding/registry/types.js";
3
4
  export interface RegistryRunContext {
4
5
  runId: string;
5
6
  deadlineAt: Date;
6
7
  allowlist: PackageAllowlist;
7
8
  policy: unknown;
9
+ /** The run's repository (CodingRun.repository), a cache-key input. */
10
+ repository: string;
11
+ /** The image whose environment the install runs in: CodingRun.toolImage ?? workerImage; null when neither is recorded. */
12
+ cacheImage: string | null;
13
+ /** Whether the run's agent enabled the dependency cache, fixed at dispatch (CodingRun.dependencyCache). */
14
+ dependencyCache: boolean;
15
+ /** Package audit mode, fixed at dispatch (CodingRun.packageAuditMode); null = normal enforcement. */
16
+ packageAudit: PackageAuditMode | null;
17
+ }
18
+ /** A coding proxy session's dependency cache state (CodingProxySession). */
19
+ export interface DependencyCacheSessionState {
20
+ /** Lockfile hashes this session's plans approved with no refusals, while unsealed. */
21
+ lockHashes: string[];
22
+ /** When the run's dependency step ended; after it the cache refuses the session. */
23
+ sealedAt: Date | null;
24
+ /** When the session was created: the upload window starts here. */
25
+ createdAt: Date;
8
26
  }
9
27
  export interface RegistryFetchRecord {
10
28
  runId: string;
@@ -31,6 +49,32 @@ export interface ApprovedVersion {
31
49
  name: string;
32
50
  version: string;
33
51
  integrity: string;
52
+ /** Blocking advisories the run's accepted set waived for this version,
53
+ * when the plan kept it only by that waiver; absent or empty otherwise. */
54
+ acceptedAdvisories?: readonly string[];
55
+ /** Audit-mode plans only: why this approval is audited (outside the
56
+ * allowlist, or kept past advisories in full mode). Absent = a normal approval. */
57
+ audit?: PackageAuditVerdict;
58
+ }
59
+ /** What a download of a plan-approved version needs. */
60
+ export interface ApprovedDownload {
61
+ integrity: string;
62
+ downloadUrl: string;
63
+ /** Advisories the approval waived (empty when none). */
64
+ acceptedAdvisories: string[];
65
+ /** The approval's audit verdict; absent for a normal approval. */
66
+ audit?: PackageAuditVerdict;
67
+ }
68
+ /** One RegistryAuditRecord: a version a run's registry served only because of package audit mode. */
69
+ export interface RegistryAuditInsert {
70
+ runId: string;
71
+ ecosystem: string;
72
+ name: string;
73
+ version: string;
74
+ relation: AuditRelation;
75
+ via?: string;
76
+ sizeBytes?: number;
77
+ advisories: readonly AuditAdvisory[];
34
78
  }
35
79
  /** One exact version a lockfile plan definitively refused for a run. */
36
80
  export interface PlanRefusedVersion {
@@ -52,13 +96,25 @@ export interface PlanRefusedVersion {
52
96
  export declare function extraAllowanceName(name: string, extra: string): string;
53
97
  /** The extra in an allowance row name for `name`, or null when the row is not one of its extras. */
54
98
  export declare function extraOfAllowanceName(rowName: string, name: string): string | null;
99
+ /** The `auditedVia` of an audited allowance whose relation a lockfile plan
100
+ * could not tell (`unknown`): no package name is empty. */
101
+ export declare const AUDITED_VIA_UNKNOWN = "";
55
102
  /** Run-scoped store over the registry-only token session lookup and the
56
103
  * RegistryAllowance/RegistryFetch tables (Task 5). Backs the registry proxy:
57
104
  * it never sees the model capability, only the derived registry token. */
58
105
  export interface RegistryStore {
59
106
  findRunByRegistryTokenHash(hash: string, now: Date): Promise<RegistryRunContext | null>;
60
107
  isAllowedDependency(runId: string, ecosystem: string, name: string): Promise<boolean>;
108
+ /** The run's allowance of `name` (null = none): `auditedVia` is the audited package that declared it,
109
+ * AUDITED_VIA_UNKNOWN when no one is known to, or null. */
110
+ findAllowance(runId: string, ecosystem: string, name: string): Promise<{
111
+ auditedVia: string | null;
112
+ } | null>;
61
113
  addAllowances(runId: string, ecosystem: string, names: readonly string[]): Promise<void>;
114
+ /** Like addAllowances, each name tagged with the audited package that declared it; existing rows are kept. */
115
+ addAuditedAllowances(runId: string, ecosystem: string, names: readonly string[], auditedVia: string): Promise<void>;
116
+ /** Insert-only; a row for the same run/ecosystem/name/version already present is kept. */
117
+ recordAudit(record: RegistryAuditInsert): Promise<void>;
62
118
  /** The extras the run allows for `name` (normalized, sorted). */
63
119
  allowedExtras(runId: string, ecosystem: string, name: string): Promise<string[]>;
64
120
  /** Records extras the run allows for each package (an existing one is kept). */
@@ -73,6 +129,10 @@ export interface RegistryStore {
73
129
  listFetches(runId: string): Promise<(RegistryFetchRecord & {
74
130
  createdAt: Date;
75
131
  })[]>;
132
+ /** The run's refused rows recorded at or after `since`, newest first, at most `limit`. */
133
+ listRecentRefusals(runId: string, since: Date, limit: number): Promise<(RegistryFetchRecord & {
134
+ createdAt: Date;
135
+ })[]>;
76
136
  /** Stored facts for these versions (any not stored are absent). */
77
137
  getVersionFacts(ecosystem: string, versions: readonly {
78
138
  name: string;
@@ -83,11 +143,9 @@ export interface RegistryStore {
83
143
  /** Approves exact versions for the run (an existing approval is kept). */
84
144
  approveVersions(runId: string, ecosystem: string, versions: readonly ApprovedVersion[]): Promise<void>;
85
145
  /** The run's approval of this exact version, with its download URL (from
86
- * the version's fact), or null. */
87
- findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<{
88
- integrity: string;
89
- downloadUrl: string;
90
- } | null>;
146
+ * the version's fact) and any advisories it was approved by waiving, or
147
+ * null. */
148
+ findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<ApprovedDownload | null>;
91
149
  /** Stores the run's plan refusals (an existing one is kept). */
92
150
  refusePlanVersions(runId: string, ecosystem: string, versions: readonly PlanRefusedVersion[]): Promise<void>;
93
151
  /** The run's plan refusal of this exact version, or null. */
@@ -96,12 +154,21 @@ export interface RegistryStore {
96
154
  reason: string;
97
155
  publishedAt: Date | null;
98
156
  } | null>;
157
+ /** Adds a lockfile hash to the run's session, atomically and only while
158
+ * the session is unsealed, does not already hold it, and holds fewer
159
+ * than `max`; otherwise does nothing. */
160
+ recordDependencyCacheLockHash(runId: string, lockHash: string, max: number): Promise<void>;
99
161
  }
100
162
  /** In-memory adapter for tests. `contexts` is settable directly so tests can
101
163
  * seed a run without going through a full proxy session. */
102
164
  export declare class MemoryRegistryStore implements RegistryStore {
103
165
  readonly contexts: Map<string, RegistryRunContext>;
104
166
  readonly allowances: Set<string>;
167
+ /** `runId\0ecosystem\0name` -> the audited package that declared the allowance (first writer). */
168
+ readonly auditedVia: Map<string, string>;
169
+ readonly audits: (RegistryAuditInsert & {
170
+ createdAt: Date;
171
+ })[];
105
172
  readonly fetches: (RegistryFetchRecord & {
106
173
  createdAt: Date;
107
174
  })[];
@@ -111,9 +178,16 @@ export declare class MemoryRegistryStore implements RegistryStore {
111
178
  readonly approvals: Map<string, ApprovedVersion>;
112
179
  /** `runId\0ecosystem\0name\0version` -> plan refusal. */
113
180
  readonly planRefusals: Map<string, PlanRefusedVersion>;
181
+ /** runId -> dependency cache session state (shareable with the cache's memory store). */
182
+ readonly cacheSessions: Map<string, DependencyCacheSessionState>;
114
183
  findRunByRegistryTokenHash(hash: string, now: Date): Promise<RegistryRunContext | null>;
115
184
  isAllowedDependency(runId: string, ecosystem: string, name: string): Promise<boolean>;
185
+ findAllowance(runId: string, ecosystem: string, name: string): Promise<{
186
+ auditedVia: string | null;
187
+ } | null>;
116
188
  addAllowances(runId: string, ecosystem: string, names: readonly string[]): Promise<void>;
189
+ addAuditedAllowances(runId: string, ecosystem: string, names: readonly string[], auditedVia: string): Promise<void>;
190
+ recordAudit(record: RegistryAuditInsert): Promise<void>;
117
191
  allowedExtras(runId: string, ecosystem: string, name: string): Promise<string[]>;
118
192
  addExtraAllowances(runId: string, ecosystem: string, dependencies: readonly FileDependency[]): Promise<void>;
119
193
  recordFetch(record: RegistryFetchRecord): Promise<void>;
@@ -125,20 +199,21 @@ export declare class MemoryRegistryStore implements RegistryStore {
125
199
  listFetches(runId: string): Promise<(RegistryFetchRecord & {
126
200
  createdAt: Date;
127
201
  })[]>;
202
+ listRecentRefusals(runId: string, since: Date, limit: number): Promise<(RegistryFetchRecord & {
203
+ createdAt: Date;
204
+ })[]>;
128
205
  getVersionFacts(ecosystem: string, versions: readonly {
129
206
  name: string;
130
207
  version: string;
131
208
  }[]): Promise<StoredVersionFact[]>;
132
209
  putVersionFacts(ecosystem: string, facts: readonly StoredVersionFact[]): Promise<void>;
133
210
  approveVersions(runId: string, ecosystem: string, versions: readonly ApprovedVersion[]): Promise<void>;
134
- findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<{
135
- integrity: string;
136
- downloadUrl: string;
137
- } | null>;
211
+ findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<ApprovedDownload | null>;
138
212
  refusePlanVersions(runId: string, ecosystem: string, versions: readonly PlanRefusedVersion[]): Promise<void>;
139
213
  findPlanRefusal(runId: string, ecosystem: string, name: string, version: string): Promise<{
140
214
  code: string;
141
215
  reason: string;
142
216
  publishedAt: Date | null;
143
217
  } | null>;
218
+ recordDependencyCacheLockHash(runId: string, lockHash: string, max: number): Promise<void>;
144
219
  }
@@ -17,11 +17,17 @@ export function extraOfAllowanceName(rowName, name) {
17
17
  const extra = rowName.slice(prefix.length, -1);
18
18
  return /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(extra) ? extra : null;
19
19
  }
20
+ /** The `auditedVia` of an audited allowance whose relation a lockfile plan
21
+ * could not tell (`unknown`): no package name is empty. */
22
+ export const AUDITED_VIA_UNKNOWN = "";
20
23
  /** In-memory adapter for tests. `contexts` is settable directly so tests can
21
24
  * seed a run without going through a full proxy session. */
22
25
  export class MemoryRegistryStore {
23
26
  contexts = new Map();
24
27
  allowances = new Set();
28
+ /** `runId\0ecosystem\0name` -> the audited package that declared the allowance (first writer). */
29
+ auditedVia = new Map();
30
+ audits = [];
25
31
  fetches = [];
26
32
  /** `ecosystem\0name\0version` -> fact. */
27
33
  facts = new Map();
@@ -29,6 +35,8 @@ export class MemoryRegistryStore {
29
35
  approvals = new Map();
30
36
  /** `runId\0ecosystem\0name\0version` -> plan refusal. */
31
37
  planRefusals = new Map();
38
+ /** runId -> dependency cache session state (shareable with the cache's memory store). */
39
+ cacheSessions = new Map();
32
40
  async findRunByRegistryTokenHash(hash, now) {
33
41
  const context = this.contexts.get(hash);
34
42
  return context && context.deadlineAt > now ? context : null;
@@ -39,10 +47,32 @@ export class MemoryRegistryStore {
39
47
  return false;
40
48
  return this.allowances.has(`${runId}\0${ecosystem}\0${name}`);
41
49
  }
50
+ async findAllowance(runId, ecosystem, name) {
51
+ if (!(await this.isAllowedDependency(runId, ecosystem, name)))
52
+ return null;
53
+ return { auditedVia: this.auditedVia.get(`${runId}\0${ecosystem}\0${name}`) ?? null };
54
+ }
42
55
  async addAllowances(runId, ecosystem, names) {
43
56
  for (const name of names)
44
57
  this.allowances.add(`${runId}\0${ecosystem}\0${name}`);
45
58
  }
59
+ async addAuditedAllowances(runId, ecosystem, names, auditedVia) {
60
+ for (const name of names) {
61
+ const key = `${runId}\0${ecosystem}\0${name}`;
62
+ if (this.allowances.has(key))
63
+ continue;
64
+ this.allowances.add(key);
65
+ this.auditedVia.set(key, auditedVia);
66
+ }
67
+ }
68
+ async recordAudit(record) {
69
+ const same = (row) => row.runId === record.runId &&
70
+ row.ecosystem === record.ecosystem &&
71
+ row.name === record.name &&
72
+ row.version === record.version;
73
+ if (!this.audits.some(same))
74
+ this.audits.push({ ...record, createdAt: new Date() });
75
+ }
46
76
  async allowedExtras(runId, ecosystem, name) {
47
77
  const prefix = `${runId}\0${ecosystem}\0`;
48
78
  return [...this.allowances]
@@ -67,6 +97,12 @@ export class MemoryRegistryStore {
67
97
  async listFetches(runId) {
68
98
  return this.fetches.filter((fetch) => fetch.runId === runId);
69
99
  }
100
+ async listRecentRefusals(runId, since, limit) {
101
+ return this.fetches
102
+ .filter((fetch) => fetch.runId === runId && fetch.outcome === "refused" && fetch.createdAt >= since)
103
+ .reverse()
104
+ .slice(0, limit);
105
+ }
70
106
  async getVersionFacts(ecosystem, versions) {
71
107
  return versions.flatMap(({ name, version }) => this.facts.get(`${ecosystem}\0${name}\0${version}`) ?? []);
72
108
  }
@@ -87,7 +123,14 @@ export class MemoryRegistryStore {
87
123
  async findApprovedVersion(runId, ecosystem, name, version) {
88
124
  const approval = this.approvals.get(`${runId}\0${ecosystem}\0${name}\0${version}`);
89
125
  const fact = this.facts.get(`${ecosystem}\0${name}\0${version}`);
90
- return approval && fact ? { integrity: approval.integrity, downloadUrl: fact.downloadUrl } : null;
126
+ return approval && fact
127
+ ? {
128
+ integrity: approval.integrity,
129
+ downloadUrl: fact.downloadUrl,
130
+ acceptedAdvisories: [...(approval.acceptedAdvisories ?? [])],
131
+ ...(approval.audit ? { audit: approval.audit } : {}),
132
+ }
133
+ : null;
91
134
  }
92
135
  async refusePlanVersions(runId, ecosystem, versions) {
93
136
  for (const refusal of versions) {
@@ -100,4 +143,14 @@ export class MemoryRegistryStore {
100
143
  const refusal = this.planRefusals.get(`${runId}\0${ecosystem}\0${name}\0${version}`);
101
144
  return refusal ? { code: refusal.code, reason: refusal.reason, publishedAt: refusal.publishedAt ?? null } : null;
102
145
  }
146
+ async recordDependencyCacheLockHash(runId, lockHash, max) {
147
+ let session = this.cacheSessions.get(runId);
148
+ if (!session) {
149
+ session = { lockHashes: [], sealedAt: null, createdAt: new Date() };
150
+ this.cacheSessions.set(runId, session);
151
+ }
152
+ if (session.sealedAt || session.lockHashes.includes(lockHash) || session.lockHashes.length >= max)
153
+ return;
154
+ session.lockHashes.push(lockHash);
155
+ }
103
156
  }
@@ -1,5 +1,7 @@
1
1
  import type { PrismaClient } from "#prisma";
2
2
  import type { UpstreamFetch } from "../../coding/registry/types.js";
3
+ import { type BlobStoreConfig } from "../storage/index.js";
4
+ import type { BlobStore } from "../storage/types.js";
3
5
  import { startDenyPortListener } from "./deny-port.js";
4
6
  import { type PinnedProxyFetchOptions } from "./secure-fetch.js";
5
7
  import { startCodingProxyServer, type CodingProxyServerHandle } from "./server.js";
@@ -12,6 +14,12 @@ import type { ProxyAuditSink } from "./types.js";
12
14
  * JSON). Exported so its header-mapping can be unit-tested directly,
13
15
  * without needing a live upstream. */
14
16
  export declare function createRegistryUpstream(pinned: typeof globalThis.fetch): UpstreamFetch;
17
+ /**
18
+ * WARDBY_MCP_GATEWAY_URL: the native gateway's base URL, which the /mcp route forwards to (its
19
+ * /coding-mcp route). Unset or empty: /mcp answers 503 mcp_unavailable. Anything but an http(s) URL
20
+ * without credentials, query or fragment stops start-up (the value is not echoed).
21
+ */
22
+ export declare function loadMcpGatewayUrl(env: NodeJS.ProcessEnv): string | undefined;
15
23
  export interface CodingProxyRuntimeOptions {
16
24
  db: PrismaClient;
17
25
  /** The package registry's own client, so its traffic (many concurrent
@@ -25,6 +33,8 @@ export interface CodingProxyRuntimeOptions {
25
33
  * upstream hosts are actually passed to the pinned-fetch allowlist. */
26
34
  createPinnedFetch?: (options: PinnedProxyFetchOptions) => typeof globalThis.fetch;
27
35
  audit?: ProxyAuditSink;
36
+ /** Overridable for tests: builds the dependency cache's blob store. */
37
+ createBlobStore?: (config: BlobStoreConfig) => BlobStore;
28
38
  onRequest?: (event: {
29
39
  protocol: "openai-responses" | "anthropic-messages" | "other";
30
40
  status: number;
@@ -1,8 +1,16 @@
1
+ import { loadDependencyCacheConfig } from "../../config/dependency-cache.js";
2
+ import { createSimulatorModelFetch, createSimulatorRegistryFetch, startupTestSimulators, } from "../../config/test-simulators.js";
1
3
  import { logger } from "../../core/logger.js";
2
4
  import { REGISTRY_ADAPTERS } from "../../coding/registry/adapters.js";
3
5
  import { CODING_PROXY_ALIAS, CODING_PROXY_DENY_PORT, CODING_PROXY_PORT } from "../jobs/docker-isolation.js";
6
+ import { createBlobStore } from "../storage/index.js";
7
+ import { startEviction } from "./dependency-cache/eviction.js";
8
+ import { PrismaDependencyCacheStore } from "./dependency-cache/prisma-store.js";
9
+ import { ModelRequestSeal } from "./dependency-cache/model-request-seal.js";
10
+ import { DependencyCacheService } from "./dependency-cache/service.js";
4
11
  import { startDenyPortListener } from "./deny-port.js";
5
12
  import { EnvironmentCredentialResolver } from "./environment-credentials.js";
13
+ import { createMcpRoute } from "./mcp-route.js";
6
14
  import { createMockUpstream, mockUpstreamFromEnv } from "./mock-upstream.js";
7
15
  import { CodingProxy } from "./proxy.js";
8
16
  import { PrismaProxyLedger } from "./prisma-ledger.js";
@@ -10,7 +18,7 @@ import { OsvAudit } from "./registry/audit.js";
10
18
  import { PrismaRegistryStore } from "./registry/prisma-store.js";
11
19
  import { DEFAULT_PLAN_MAX_ENTRIES, DEFAULT_PLAN_TIMEOUT_MS } from "./registry/plan.js";
12
20
  import { DEFAULT_GRAPH_TIMEOUT_MS, DEFAULT_MAX_GRAPH_PACKAGES, DEFAULT_PLAN_MAX_PER_RUN, RegistryService, } from "./registry/service.js";
13
- import { createPinnedProxyFetch } from "./secure-fetch.js";
21
+ import { createPinnedProxyFetch, PROXY_EGRESS_ERROR } from "./secure-fetch.js";
14
22
  import { startCodingProxyServer } from "./server.js";
15
23
  const MIB = 1024 * 1024;
16
24
  function positiveInt(value, fallback) {
@@ -37,9 +45,37 @@ export function createRegistryUpstream(pinned) {
37
45
  },
38
46
  });
39
47
  }
48
+ /**
49
+ * WARDBY_MCP_GATEWAY_URL: the native gateway's base URL, which the /mcp route forwards to (its
50
+ * /coding-mcp route). Unset or empty: /mcp answers 503 mcp_unavailable. Anything but an http(s) URL
51
+ * without credentials, query or fragment stops start-up (the value is not echoed).
52
+ */
53
+ export function loadMcpGatewayUrl(env) {
54
+ const value = env.WARDBY_MCP_GATEWAY_URL?.trim();
55
+ if (!value)
56
+ return undefined;
57
+ let url;
58
+ try {
59
+ url = new URL(value);
60
+ }
61
+ catch {
62
+ url = undefined;
63
+ }
64
+ if (!url ||
65
+ (url.protocol !== "http:" && url.protocol !== "https:") ||
66
+ url.username ||
67
+ url.password ||
68
+ url.search ||
69
+ url.hash) {
70
+ throw new Error("WARDBY_MCP_GATEWAY_URL must be an http(s) URL without credentials, query or fragment");
71
+ }
72
+ return url.href.replace(/\/+$/, "");
73
+ }
40
74
  /** Starts the trusted proxy with the fixed worker-only Docker endpoint, plus the deny port the enforcement witness probes. */
41
75
  export async function startConfiguredCodingProxy(options) {
42
76
  const env = options.env ?? process.env;
77
+ // Throws on an invalid setting, before anything listens.
78
+ const cacheConfig = loadDependencyCacheConfig(env);
43
79
  // Throws (mock_upstream_guard) on a partial or malformed setting, before anything listens.
44
80
  const mock = mockUpstreamFromEnv(env);
45
81
  if (mock) {
@@ -48,21 +84,24 @@ export async function startConfiguredCodingProxy(options) {
48
84
  const audit = mock
49
85
  ? (event) => options.audit?.({ ...event, mockUpstream: true })
50
86
  : options.audit;
51
- const proxy = new CodingProxy({
52
- ledger: new PrismaProxyLedger(options.db),
53
- credentials: new EnvironmentCredentialResolver(env),
54
- audit,
55
- ...(mock ? { fetch: createMockUpstream(mock) } : {}),
56
- });
87
+ // Throws on an invalid setting, before anything listens.
88
+ const mcpGatewayUrl = loadMcpGatewayUrl(env);
89
+ // Throws (test_simulators_refused) on any refusal, before anything listens.
90
+ const simulators = startupTestSimulators("coding-proxy", env);
57
91
  const buildPinnedFetch = options.createPinnedFetch ?? createPinnedProxyFetch;
58
92
  const upstreamHosts = [...new Set([...REGISTRY_ADAPTERS.values()].flatMap((adapter) => adapter.upstreamHosts))];
59
- const pinned = buildPinnedFetch({ allowedHosts: [...upstreamHosts, "api.osv.dev"] });
93
+ // WARDBY_TEST_SIMULATORS (test only): the registry hosts go to their simulators, and every
94
+ // other host is still refused.
95
+ const pinned = simulators
96
+ ? createSimulatorRegistryFetch(simulators, () => new Error(PROXY_EGRESS_ERROR))
97
+ : buildPinnedFetch({ allowedHosts: [...upstreamHosts, "api.osv.dev"] });
60
98
  const upstream = createRegistryUpstream(pinned);
61
99
  const metadataTimeoutMs = positiveInt(env.REGISTRY_METADATA_TIMEOUT_MS, 30_000);
62
100
  const maxMetadataBytes = positiveInt(env.REGISTRY_MAX_METADATA_MB, 64) * MIB;
101
+ const registryStore = new PrismaRegistryStore(options.registryDb ?? options.db);
63
102
  const registry = new RegistryService({
64
103
  adapters: REGISTRY_ADAPTERS,
65
- store: new PrismaRegistryStore(options.registryDb ?? options.db),
104
+ store: registryStore,
66
105
  audit: new OsvAudit({
67
106
  fetch: upstream,
68
107
  failOpen: env.REGISTRY_AUDIT_FAIL_OPEN === "true",
@@ -85,14 +124,66 @@ export async function startConfiguredCodingProxy(options) {
85
124
  idleTimeoutMs: positiveInt(env.REGISTRY_IDLE_TIMEOUT_MS, 120_000),
86
125
  },
87
126
  });
88
- const startServer = options.startServer ?? startCodingProxyServer;
89
- const server = await startServer(proxy, {
90
- host: "0.0.0.0",
91
- port: CODING_PROXY_PORT,
92
- expectedHost: `${CODING_PROXY_ALIAS}:${CODING_PROXY_PORT}`,
93
- registry,
94
- onRequest: options.onRequest,
127
+ let dependencyCache;
128
+ let modelRequestSeal;
129
+ let eviction;
130
+ if (cacheConfig.enabled) {
131
+ const blobs = (options.createBlobStore ?? createBlobStore)(cacheConfig.blobStore);
132
+ const cacheStore = new PrismaDependencyCacheStore(options.registryDb ?? options.db);
133
+ modelRequestSeal = new ModelRequestSeal(cacheStore);
134
+ dependencyCache = new DependencyCacheService({
135
+ registry: registryStore,
136
+ store: cacheStore,
137
+ blobs,
138
+ maxSnapshotBytes: cacheConfig.maxSnapshotBytes,
139
+ uploadMs: cacheConfig.uploadMs,
140
+ });
141
+ eviction = startEviction({
142
+ store: cacheStore,
143
+ blobs,
144
+ limits: {
145
+ maxAgeMs: cacheConfig.maxAgeMs,
146
+ repoCapBytes: cacheConfig.repoCapBytes,
147
+ totalCapBytes: cacheConfig.totalCapBytes,
148
+ },
149
+ });
150
+ }
151
+ else if (cacheConfig.reason === "no_blob_store") {
152
+ logger.warn({ module: "coding-proxy-runtime", event: "proxy.dependency_cache_no_blob_store" }, "coding proxy: WARDBY_DEPENDENCY_CACHE=true but no BLOB_STORE is configured; the dependency cache is off");
153
+ }
154
+ const seal = modelRequestSeal;
155
+ const ledger = new PrismaProxyLedger(options.db);
156
+ const proxy = new CodingProxy({
157
+ ledger,
158
+ credentials: new EnvironmentCredentialResolver(env),
159
+ audit,
160
+ // WARDBY_TEST_SIMULATORS (test only; refused alongside the mock upstream): the scripted model,
161
+ // with every credential header dropped.
162
+ ...(simulators
163
+ ? { fetch: createSimulatorModelFetch(simulators, () => new Error(PROXY_EGRESS_ERROR)) }
164
+ : mock
165
+ ? { fetch: createMockUpstream(mock) }
166
+ : {}),
167
+ // The run's first model request closes its dependency cache (no-op for a run with it off).
168
+ ...(seal ? { onModelRequest: (runId) => seal.onModelRequest(runId) } : {}),
95
169
  });
170
+ const startServer = options.startServer ?? startCodingProxyServer;
171
+ let server;
172
+ try {
173
+ server = await startServer(proxy, {
174
+ host: "0.0.0.0",
175
+ port: CODING_PROXY_PORT,
176
+ expectedHost: `${CODING_PROXY_ALIAS}:${CODING_PROXY_PORT}`,
177
+ registry,
178
+ ...(dependencyCache ? { dependencyCache } : {}),
179
+ mcp: createMcpRoute({ ledger, gatewayUrl: mcpGatewayUrl }),
180
+ onRequest: options.onRequest,
181
+ });
182
+ }
183
+ catch (error) {
184
+ eviction?.stop();
185
+ throw error;
186
+ }
96
187
  let deny;
97
188
  try {
98
189
  deny = await (options.startDenyPort ?? startDenyPortListener)("0.0.0.0", CODING_PROXY_DENY_PORT);
@@ -100,12 +191,14 @@ export async function startConfiguredCodingProxy(options) {
100
191
  catch (error) {
101
192
  // A proxy without its witness must not stay up: the launcher's gate would never be able to
102
193
  // prove a policy is enforced, and every launch would fail at the gate instead of at startup.
194
+ eviction?.stop();
103
195
  await server.close();
104
196
  throw error;
105
197
  }
106
198
  return {
107
199
  port: server.port,
108
200
  close: async () => {
201
+ eviction?.stop();
109
202
  await deny.close();
110
203
  await server.close();
111
204
  },
@@ -1,6 +1,8 @@
1
+ import { type IncomingMessage, type ServerResponse } from "node:http";
1
2
  import type { ProxyAuditEvent } from "./types.js";
2
3
  import { type CodingProxy } from "./proxy.js";
3
4
  import { type RegistryService } from "./registry/service.js";
5
+ import type { DependencyCacheService } from "./dependency-cache/service.js";
4
6
  import type { ProxyProtocol } from "./types.js";
5
7
  declare const proxyLog: import("pino").Logger<never, boolean>;
6
8
  /**
@@ -13,7 +15,13 @@ export interface CodingProxyServerConfig {
13
15
  host: string;
14
16
  port: number;
15
17
  expectedHost?: string;
16
- registry?: Pick<RegistryService, "handle"> & Partial<Pick<RegistryService, "plan">>;
18
+ registry?: Pick<RegistryService, "handle"> & Partial<Pick<RegistryService, "plan" | "refusals">>;
19
+ /** The dependency cache (`/cache/...`); absent when the deployment has it off. */
20
+ dependencyCache?: Pick<DependencyCacheService, "handle" | "uploadMs">;
21
+ /** Time to receive a whole request (default HTTP_LIMITS.requestMs); a cache upload gets its upload window instead. */
22
+ requestMs?: number;
23
+ /** The worker's MCP route (`/mcp`, createMcpRoute); absent, /mcp is not found. */
24
+ mcp?: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
17
25
  onRequest?: (event: {
18
26
  protocol: ProxyProtocol | "other";
19
27
  status: number;
@@ -6,6 +6,7 @@ import { logger } from "../../core/logger.js";
6
6
  import { CodingProxyError, PROXY_MAX_BODY_BYTES } from "./proxy.js";
7
7
  import { RegistryError } from "../../coding/registry/types.js";
8
8
  import { MAX_PLAN_BODY_BYTES } from "./registry/service.js";
9
+ import { MCP_ROUTE_PATH } from "./mcp-route.js";
9
10
  const proxyLog = logger.child({ module: "coding-proxy" });
10
11
  /**
11
12
  * Writes a proxy audit event to the operator log. The events carry ids,
@@ -99,6 +100,12 @@ function readPlanBody(request, signal) {
99
100
  failed();
100
101
  });
101
102
  }
103
+ /** An error answer to a request whose body was not read: close the
104
+ * connection rather than read (or keep) what the client is still sending. */
105
+ function closeIfBodyUnread(request, response) {
106
+ if (!request.complete && !response.headersSent)
107
+ response.setHeader("connection", "close");
108
+ }
102
109
  function routeProtocol(method, url) {
103
110
  if (method !== "POST")
104
111
  return undefined;
@@ -130,8 +137,25 @@ function responseSink(response) {
130
137
  };
131
138
  }
132
139
  export async function startCodingProxyServer(proxy, config) {
140
+ const requestMs = config.requestMs ?? HTTP_LIMITS.requestMs;
141
+ // A snapshot upload (up to WARDBY_DEPENDENCY_CACHE_MAX_SNAPSHOT_MB) cannot
142
+ // arrive within requestMs, and Node's requestTimeout is server-wide: with
143
+ // the cache on it is widened to cover the upload window (which the cache
144
+ // enforces on the upload itself), and every request gets a requestMs timer
145
+ // of its own. Only the cache lifts that timer, and only for an upload it
146
+ // has authenticated, found eligible and given its upload slot.
147
+ const extendedRequests = config.dependencyCache !== undefined;
133
148
  const server = createServer({ maxHeaderSize: 16 * 1024, requireHostHeader: true }, (request, response) => {
134
149
  const startedAt = performance.now();
150
+ const bodyTimer = extendedRequests
151
+ ? setTimeout(() => {
152
+ if (!request.complete)
153
+ request.socket.destroy();
154
+ }, requestMs).unref()
155
+ : undefined;
156
+ // Done with once the response is over (finished or closed early).
157
+ if (bodyTimer)
158
+ response.once("close", () => clearTimeout(bodyTimer));
135
159
  const protocol = routeProtocol(request.method, request.url) ?? "other";
136
160
  response.once("finish", () => {
137
161
  try {
@@ -143,9 +167,19 @@ export async function startCodingProxyServer(proxy, config) {
143
167
  });
144
168
  void (async () => {
145
169
  if (config.expectedHost && request.headers.host !== config.expectedHost) {
170
+ closeIfBodyUnread(request, response);
146
171
  sendError(response, 403, "invalid_host");
147
172
  return;
148
173
  }
174
+ if (request.url?.startsWith("/cache/")) {
175
+ if (!config.dependencyCache) {
176
+ closeIfBodyUnread(request, response);
177
+ sendError(response, 404, "not_found");
178
+ return;
179
+ }
180
+ await config.dependencyCache.handle(request, response, registryToken(request.headers.authorization), () => clearTimeout(bodyTimer));
181
+ return;
182
+ }
149
183
  if (request.url?.startsWith("/registry/")) {
150
184
  if (!config.registry) {
151
185
  sendError(response, 404, "not_found");
@@ -187,6 +221,16 @@ export async function startCodingProxyServer(proxy, config) {
187
221
  sendError(response, 405, "method_not_allowed");
188
222
  return;
189
223
  }
224
+ // The run's recent refusals, for clients that don't print the 403 body (pip, uv).
225
+ const refusals = request.url.match(/^\/registry\/-\/refusals(?:\?(.*))?$/);
226
+ if (refusals && config.registry.refusals) {
227
+ const since = new URLSearchParams(refusals[1] ?? "").get("since");
228
+ sendRegistry(response, await config.registry.refusals({
229
+ token: registryToken(request.headers.authorization),
230
+ ...(since ? { since: new Date(since) } : {}),
231
+ }));
232
+ return;
233
+ }
190
234
  const match = request.url.match(/^\/registry\/([a-z0-9-]+)\/(.*)$/);
191
235
  if (!match) {
192
236
  sendError(response, 404, "not_found");
@@ -223,6 +267,15 @@ export async function startCodingProxyServer(proxy, config) {
223
267
  });
224
268
  return;
225
269
  }
270
+ if (request.url === MCP_ROUTE_PATH || request.url?.startsWith(`${MCP_ROUTE_PATH}?`)) {
271
+ if (!config.mcp) {
272
+ closeIfBodyUnread(request, response);
273
+ sendError(response, 404, "not_found");
274
+ return;
275
+ }
276
+ await config.mcp(request, response);
277
+ return;
278
+ }
226
279
  if (request.method === "HEAD" && request.url === "/api/hello") {
227
280
  response.writeHead(200, { "cache-control": "no-store" }).end();
228
281
  return;
@@ -269,6 +322,7 @@ export async function startCodingProxyServer(proxy, config) {
269
322
  response.destroy();
270
323
  return;
271
324
  }
325
+ closeIfBodyUnread(request, response);
272
326
  if (error instanceof CodingProxyError || error instanceof HttpBoundaryError) {
273
327
  proxyLog.info({ event: "request.rejected", code: error instanceof CodingProxyError ? error.code : error.message }, "coding proxy request rejected");
274
328
  sendError(response, error.status, error instanceof CodingProxyError ? error.code : error.message);
@@ -283,7 +337,7 @@ export async function startCodingProxyServer(proxy, config) {
283
337
  sendError(response, 500, "internal_error");
284
338
  });
285
339
  });
286
- server.requestTimeout = HTTP_LIMITS.requestMs;
340
+ server.requestTimeout = extendedRequests ? requestMs + config.dependencyCache.uploadMs : requestMs;
287
341
  server.headersTimeout = HTTP_LIMITS.headersMs;
288
342
  server.keepAliveTimeout = 5_000;
289
343
  server.maxRequestsPerSocket = 100;