@wardby/cli 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (576) hide show
  1. package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
  2. package/dist/claude-coding-worker/driver.d.ts +21 -3
  3. package/dist/claude-coding-worker/driver.js +125 -17
  4. package/dist/claude-coding-worker/main.js +34 -6
  5. package/dist/claude-coding-worker/sdk.js +12 -1
  6. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  7. package/dist/claude-coding-worker/tool-socket.js +111 -0
  8. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  9. package/dist/claude-coding-worker/transcript.js +77 -0
  10. package/dist/cli-help.d.ts +1 -1
  11. package/dist/cli-help.js +1 -0
  12. package/dist/cli.js +24 -10
  13. package/dist/coding/continuation-wording.d.ts +35 -0
  14. package/dist/coding/continuation-wording.js +73 -0
  15. package/dist/coding/linked-issue-note.d.ts +23 -0
  16. package/dist/coding/linked-issue-note.js +47 -0
  17. package/dist/coding/merge-wording.d.ts +28 -0
  18. package/dist/coding/merge-wording.js +78 -0
  19. package/dist/coding/pr-description-note.d.ts +9 -0
  20. package/dist/coding/pr-description-note.js +32 -0
  21. package/dist/coding/profile.d.ts +46 -126
  22. package/dist/coding/profile.js +45 -4
  23. package/dist/coding/protected-path-wording.d.ts +8 -0
  24. package/dist/coding/protected-path-wording.js +1 -1
  25. package/dist/coding/protocol.d.ts +264 -346
  26. package/dist/coding/protocol.js +235 -12
  27. package/dist/coding/redact.d.ts +3 -0
  28. package/dist/coding/redact.js +12 -0
  29. package/dist/coding/registry/allowlist.d.ts +12 -0
  30. package/dist/coding/registry/allowlist.js +14 -1
  31. package/dist/coding/registry/audit-mode.d.ts +153 -0
  32. package/dist/coding/registry/audit-mode.js +304 -0
  33. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  34. package/dist/coding/registry/lockfile-shared.js +128 -0
  35. package/dist/coding/registry/lockfiles.js +1 -1
  36. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  37. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  38. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  39. package/dist/coding/registry/npm-lockfile.js +4 -6
  40. package/dist/coding/registry/npm.js +78 -8
  41. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  42. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  43. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  44. package/dist/coding/registry/pypi-plan.js +406 -0
  45. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  46. package/dist/coding/registry/pypi-requirements.js +155 -0
  47. package/dist/coding/registry/pypi.d.ts +3 -27
  48. package/dist/coding/registry/pypi.js +40 -154
  49. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  50. package/dist/coding/registry/refusal-hints.js +61 -0
  51. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  52. package/dist/coding/registry/refusal-wording.js +56 -0
  53. package/dist/coding/registry/report.d.ts +70 -8
  54. package/dist/coding/registry/report.js +112 -5
  55. package/dist/coding/registry/types.d.ts +58 -8
  56. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  57. package/dist/coding/registry/yarn-lockfile.js +367 -0
  58. package/dist/coding/services/catalog.d.ts +37 -351
  59. package/dist/coding/transcript/claude-code.d.ts +13 -0
  60. package/dist/coding/transcript/claude-code.js +273 -0
  61. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  62. package/dist/coding/transcript/download-protocol.js +18 -0
  63. package/dist/coding/transcript/format.d.ts +20 -0
  64. package/dist/coding/transcript/format.js +32 -0
  65. package/dist/coding/transcript/recorder.d.ts +51 -0
  66. package/dist/coding/transcript/recorder.js +225 -0
  67. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  68. package/dist/coding/transcript/resume/checkout.js +203 -0
  69. package/dist/coding/transcript/resume/command.d.ts +17 -0
  70. package/dist/coding/transcript/resume/command.js +176 -0
  71. package/dist/coding/transcript/resume/download.d.ts +20 -0
  72. package/dist/coding/transcript/resume/download.js +153 -0
  73. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  74. package/dist/coding/transcript/resume/launch.js +128 -0
  75. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  76. package/dist/coding/transcript/resume/session-file.js +79 -0
  77. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  78. package/dist/coding/transcript/resume/stand-in.js +49 -0
  79. package/dist/coding-worker/artifact.d.ts +8 -3
  80. package/dist/coding-worker/artifact.js +3 -1
  81. package/dist/coding-worker/debug-trace.d.ts +6 -5
  82. package/dist/coding-worker/debug-trace.js +13 -18
  83. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  84. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  85. package/dist/coding-worker/driver.d.ts +4 -3
  86. package/dist/coding-worker/driver.js +116 -38
  87. package/dist/coding-worker/errors.d.ts +1 -0
  88. package/dist/coding-worker/errors.js +32 -0
  89. package/dist/coding-worker/task-note.d.ts +11 -0
  90. package/dist/coding-worker/task-note.js +13 -0
  91. package/dist/coding-worker/types.d.ts +11 -0
  92. package/dist/config/dependency-cache.d.ts +23 -0
  93. package/dist/config/dependency-cache.js +32 -0
  94. package/dist/config/providers.d.ts +12 -3
  95. package/dist/config/providers.js +55 -5
  96. package/dist/config/test-simulators.d.ts +82 -0
  97. package/dist/config/test-simulators.js +305 -0
  98. package/dist/core/async-context.d.ts +2 -0
  99. package/dist/core/async-context.js +12 -0
  100. package/dist/core/budget-events.d.ts +108 -0
  101. package/dist/core/budget-events.js +346 -0
  102. package/dist/core/budget-groups.d.ts +50 -1
  103. package/dist/core/budget-groups.js +236 -27
  104. package/dist/core/budget-stopped-head.d.ts +46 -0
  105. package/dist/core/budget-stopped-head.js +81 -0
  106. package/dist/core/budget-topup.d.ts +51 -0
  107. package/dist/core/budget-topup.js +156 -0
  108. package/dist/core/budget-wording.d.ts +16 -2
  109. package/dist/core/budget-wording.js +40 -2
  110. package/dist/core/coding-queue.d.ts +2 -1
  111. package/dist/core/coding-queue.js +7 -0
  112. package/dist/core/cron.d.ts +19 -1
  113. package/dist/core/cron.js +17 -0
  114. package/dist/core/datastores.js +1 -1
  115. package/dist/core/deferred-coding.d.ts +14 -0
  116. package/dist/core/deferred-coding.js +62 -0
  117. package/dist/core/delegation-child.d.ts +25 -0
  118. package/dist/core/delegation-child.js +37 -0
  119. package/dist/core/dispatch.d.ts +42 -0
  120. package/dist/core/dispatch.js +131 -56
  121. package/dist/core/engine-native.js +1 -1
  122. package/dist/core/error-code.d.ts +38 -0
  123. package/dist/core/error-code.js +168 -0
  124. package/dist/core/grants.d.ts +19 -6
  125. package/dist/core/grants.js +55 -6
  126. package/dist/core/host-events.d.ts +18 -2
  127. package/dist/core/host-events.js +284 -24
  128. package/dist/core/host-status.d.ts +85 -3
  129. package/dist/core/host-status.js +298 -20
  130. package/dist/core/issue-bridge.d.ts +50 -6
  131. package/dist/core/issue-bridge.js +124 -33
  132. package/dist/core/issue-events.d.ts +1 -1
  133. package/dist/core/issue-events.js +4 -10
  134. package/dist/core/issue-status.d.ts +1 -1
  135. package/dist/core/issue-status.js +54 -26
  136. package/dist/core/logger.d.ts +5 -0
  137. package/dist/core/logger.js +14 -1
  138. package/dist/core/lost-run-children.d.ts +6 -0
  139. package/dist/core/lost-run-children.js +32 -0
  140. package/dist/core/mark-ready.d.ts +34 -0
  141. package/dist/core/mark-ready.js +152 -0
  142. package/dist/core/markdown-code.d.ts +8 -0
  143. package/dist/core/markdown-code.js +107 -0
  144. package/dist/core/memory-tools.js +7 -0
  145. package/dist/core/merge-order-check.d.ts +2 -1
  146. package/dist/core/merge-order-check.js +8 -1
  147. package/dist/core/notification-templates.d.ts +1 -7
  148. package/dist/core/notification-templates.js +36 -2
  149. package/dist/core/pull-request-state-sync.js +2 -2
  150. package/dist/core/reconciler.d.ts +4 -3
  151. package/dist/core/reconciler.js +8 -1
  152. package/dist/core/related-pull-requests.d.ts +11 -3
  153. package/dist/core/related-pull-requests.js +27 -14
  154. package/dist/core/reply-parts.d.ts +21 -0
  155. package/dist/core/reply-parts.js +73 -0
  156. package/dist/core/review-fix.d.ts +1 -1
  157. package/dist/core/review-fix.js +2 -1
  158. package/dist/core/review-host-checks.d.ts +1 -1
  159. package/dist/core/review-host-tools.d.ts +3 -0
  160. package/dist/core/review-host-tools.js +99 -13
  161. package/dist/core/review-reads.d.ts +55 -0
  162. package/dist/core/review-reads.js +233 -0
  163. package/dist/core/run-status.d.ts +12 -0
  164. package/dist/core/run-status.js +12 -0
  165. package/dist/core/runner.d.ts +80 -34
  166. package/dist/core/runner.js +439 -144
  167. package/dist/core/schedule-start.d.ts +12 -0
  168. package/dist/core/schedule-start.js +14 -0
  169. package/dist/core/secret-broker-config.d.ts +10 -74
  170. package/dist/core/secret-guard.d.ts +46 -0
  171. package/dist/core/secret-guard.js +104 -0
  172. package/dist/core/secret-guarded-stores.d.ts +12 -0
  173. package/dist/core/secret-guarded-stores.js +41 -0
  174. package/dist/core/secret-spans.d.ts +50 -0
  175. package/dist/core/secret-spans.js +94 -0
  176. package/dist/core/stop-run.d.ts +46 -0
  177. package/dist/core/stop-run.js +61 -0
  178. package/dist/core/workflow-events.d.ts +14 -2
  179. package/dist/core/workflow-events.js +4 -0
  180. package/dist/core/workflow-run-events.d.ts +5 -3
  181. package/dist/core/workflow-run-events.js +43 -8
  182. package/dist/core/zod-json-schema.d.ts +4 -0
  183. package/dist/core/zod-json-schema.js +39 -0
  184. package/dist/core/zod3-window.d.ts +35 -0
  185. package/dist/core/zod3-window.js +124 -0
  186. package/dist/generated/prisma/browser.d.ts +34 -3
  187. package/dist/generated/prisma/client.d.ts +34 -3
  188. package/dist/generated/prisma/commonInputTypes.d.ts +220 -60
  189. package/dist/generated/prisma/enums.d.ts +10 -0
  190. package/dist/generated/prisma/enums.js +8 -0
  191. package/dist/generated/prisma/internal/class.d.ts +44 -0
  192. package/dist/generated/prisma/internal/class.js +4 -4
  193. package/dist/generated/prisma/internal/prismaNamespace.d.ts +428 -9
  194. package/dist/generated/prisma/internal/prismaNamespace.js +92 -1
  195. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +95 -0
  196. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +92 -1
  197. package/dist/generated/prisma/models/Agent.d.ts +106 -8
  198. package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
  199. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +229 -1
  200. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  201. package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
  202. package/dist/generated/prisma/models/CodingRun.d.ts +1637 -1
  203. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  204. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  205. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  206. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  207. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
  208. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
  209. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  210. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  211. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  212. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  213. package/dist/generated/prisma/models/Run.d.ts +738 -2
  214. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  215. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  216. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  217. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  218. package/dist/generated/prisma/models.d.ts +4 -0
  219. package/dist/help-index.json +1320 -69
  220. package/dist/import/create.js +32 -3
  221. package/dist/import/neutral-schema.d.ts +50 -281
  222. package/dist/import/neutral-schema.js +5 -4
  223. package/dist/knowledge/check.d.ts +1 -1
  224. package/dist/knowledge/cli.d.ts +11 -1
  225. package/dist/knowledge/cli.js +37 -4
  226. package/dist/knowledge/concept.d.ts +3 -19
  227. package/dist/knowledge/location.d.ts +31 -0
  228. package/dist/knowledge/location.js +78 -0
  229. package/dist/mcp/auth/access.d.ts +10 -2
  230. package/dist/mcp/auth/access.js +15 -1
  231. package/dist/mcp/auth/ownership.d.ts +7 -7
  232. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  233. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  234. package/dist/mcp/host-events/github-ingress.d.ts +2 -0
  235. package/dist/mcp/host-events/github-ingress.js +2 -1
  236. package/dist/mcp/index.d.ts +6 -0
  237. package/dist/mcp/index.js +58 -10
  238. package/dist/mcp/server.d.ts +13 -0
  239. package/dist/mcp/server.js +33 -14
  240. package/dist/mcp/tools/agents.d.ts +4 -0
  241. package/dist/mcp/tools/agents.js +198 -16
  242. package/dist/mcp/tools/datastore.js +17 -8
  243. package/dist/mcp/tools/grants.js +9 -3
  244. package/dist/mcp/tools/memory.js +11 -1
  245. package/dist/mcp/tools/notification-channels.js +2 -2
  246. package/dist/mcp/tools/packages.d.ts +2 -0
  247. package/dist/mcp/tools/packages.js +195 -0
  248. package/dist/mcp/tools/repositories.js +18 -5
  249. package/dist/mcp/tools/run-access.d.ts +16 -0
  250. package/dist/mcp/tools/run-access.js +25 -0
  251. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  252. package/dist/mcp/tools/run-transcript-download.js +129 -0
  253. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  254. package/dist/mcp/tools/run-transcript.js +70 -0
  255. package/dist/mcp/tools/runs.js +34 -12
  256. package/dist/mcp/tools/scheduling.js +3 -1
  257. package/dist/mcp/tools/secret-elicitation-form.js +5 -0
  258. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  259. package/dist/mcp/tools/secret-elicitation-server.js +10 -61
  260. package/dist/mcp/tools/secrets.js +2 -2
  261. package/dist/mcp/tools/stop-run.d.ts +2 -0
  262. package/dist/mcp/tools/stop-run.js +82 -0
  263. package/dist/mcp/tools/subagents.js +2 -2
  264. package/dist/mcp/tools/tools.d.ts +1 -1
  265. package/dist/mcp/tools/tools.js +25 -9
  266. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  267. package/dist/mcp/transport/stdio-link-host.js +67 -0
  268. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  269. package/dist/mcp/transport/streamable-http.js +41 -1
  270. package/dist/native-worker/docker-launcher.d.ts +38 -2
  271. package/dist/native-worker/docker-launcher.js +65 -5
  272. package/dist/native-worker/gateway-server.d.ts +41 -3
  273. package/dist/native-worker/gateway-server.js +124 -27
  274. package/dist/native-worker/gateway.d.ts +27 -1
  275. package/dist/native-worker/gateway.js +70 -4
  276. package/dist/native-worker/http-server.d.ts +3 -1
  277. package/dist/native-worker/http-server.js +11 -7
  278. package/dist/native-worker/http-transport.js +1 -1
  279. package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
  280. package/dist/native-worker/kubernetes-launcher.js +43 -3
  281. package/dist/native-worker/launch.d.ts +18 -1
  282. package/dist/native-worker/launch.js +6 -1
  283. package/dist/native-worker/ledger.d.ts +18 -2
  284. package/dist/native-worker/ledger.js +57 -4
  285. package/dist/native-worker/loopback.js +3 -8
  286. package/dist/native-worker/main.d.ts +2 -1
  287. package/dist/native-worker/main.js +14 -3
  288. package/dist/native-worker/protocol.d.ts +129 -577
  289. package/dist/native-worker/protocol.js +47 -1
  290. package/dist/native-worker/sandbox-executor.d.ts +17 -2
  291. package/dist/native-worker/sandbox-executor.js +78 -4
  292. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  293. package/dist/native-worker/stderr-redaction.js +237 -0
  294. package/dist/native-worker/stdio.d.ts +1 -1
  295. package/dist/native-worker/stdio.js +6 -5
  296. package/dist/native-worker/warm-pool.d.ts +2 -2
  297. package/dist/native-worker/warm-pool.js +4 -4
  298. package/dist/native-worker/worker.js +28 -2
  299. package/dist/observability/metrics.js +6 -1
  300. package/dist/providers/auth/self-hosted.d.ts +1 -1
  301. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  302. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  303. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  304. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  305. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  306. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  307. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  308. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  309. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  310. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  311. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  312. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  313. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  314. package/dist/providers/coding-proxy/hold.js +86 -0
  315. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  316. package/dist/providers/coding-proxy/interrupted.js +104 -0
  317. package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
  318. package/dist/providers/coding-proxy/memory-ledger.js +84 -8
  319. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  320. package/dist/providers/coding-proxy/metering.js +27 -4
  321. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
  322. package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
  323. package/dist/providers/coding-proxy/proxy.d.ts +14 -1
  324. package/dist/providers/coding-proxy/proxy.js +166 -14
  325. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  326. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  327. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  328. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  329. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  330. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  331. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  332. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  333. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  334. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  335. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  336. package/dist/providers/coding-proxy/registry/service.js +579 -112
  337. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  338. package/dist/providers/coding-proxy/registry/store.js +54 -1
  339. package/dist/providers/coding-proxy/runtime.d.ts +4 -0
  340. package/dist/providers/coding-proxy/runtime.js +78 -16
  341. package/dist/providers/coding-proxy/server.d.ts +6 -1
  342. package/dist/providers/coding-proxy/server.js +45 -1
  343. package/dist/providers/coding-proxy/types.d.ts +65 -1
  344. package/dist/providers/datastore/types.d.ts +5 -0
  345. package/dist/providers/engine/types.d.ts +17 -2
  346. package/dist/providers/engine/types.js +17 -0
  347. package/dist/providers/executor/composition.d.ts +10 -3
  348. package/dist/providers/executor/composition.js +47 -7
  349. package/dist/providers/executor/container.d.ts +361 -8
  350. package/dist/providers/executor/container.js +1136 -91
  351. package/dist/providers/executor/dbos-status.d.ts +31 -0
  352. package/dist/providers/executor/dbos-status.js +64 -0
  353. package/dist/providers/executor/dbos.d.ts +50 -1
  354. package/dist/providers/executor/dbos.js +207 -20
  355. package/dist/providers/executor/deferred.d.ts +12 -24
  356. package/dist/providers/executor/deferred.js +10 -29
  357. package/dist/providers/executor/in-process.d.ts +9 -1
  358. package/dist/providers/executor/in-process.js +14 -4
  359. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  360. package/dist/providers/executor/linked-issue-reader.js +30 -0
  361. package/dist/providers/executor/routing.d.ts +2 -0
  362. package/dist/providers/executor/routing.js +4 -0
  363. package/dist/providers/executor/types.d.ts +13 -0
  364. package/dist/providers/index.d.ts +2 -1
  365. package/dist/providers/issue-tracker/types.d.ts +17 -0
  366. package/dist/providers/issue-tracker/types.js +39 -1
  367. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  368. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  369. package/dist/providers/jobs/docker-isolation.d.ts +8 -0
  370. package/dist/providers/jobs/docker-isolation.js +17 -0
  371. package/dist/providers/jobs/docker.d.ts +1 -0
  372. package/dist/providers/jobs/docker.js +27 -2
  373. package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
  374. package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
  375. package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
  376. package/dist/providers/jobs/kubernetes-api.js +10 -0
  377. package/dist/providers/jobs/kubernetes-client.js +10 -1
  378. package/dist/providers/jobs/kubernetes-isolation.d.ts +2 -0
  379. package/dist/providers/jobs/kubernetes-isolation.js +17 -1
  380. package/dist/providers/jobs/kubernetes.d.ts +6 -1
  381. package/dist/providers/jobs/kubernetes.js +105 -16
  382. package/dist/providers/jobs/types.d.ts +33 -0
  383. package/dist/providers/jobs/types.js +13 -1
  384. package/dist/providers/llm/anthropic.js +5 -1
  385. package/dist/providers/llm/bedrock.d.ts +0 -12
  386. package/dist/providers/llm/bedrock.js +4 -0
  387. package/dist/providers/llm/claude-messages.d.ts +3 -1
  388. package/dist/providers/llm/claude-messages.js +4 -1
  389. package/dist/providers/llm/claude-provider.d.ts +2 -2
  390. package/dist/providers/llm/claude-provider.js +2 -2
  391. package/dist/providers/llm/openai.d.ts +2 -2
  392. package/dist/providers/llm/openai.js +6 -2
  393. package/dist/providers/llm/routing.d.ts +2 -2
  394. package/dist/providers/llm/routing.js +2 -2
  395. package/dist/providers/llm/types.d.ts +12 -2
  396. package/dist/providers/review-host/github-events.d.ts +9 -1
  397. package/dist/providers/review-host/github-events.js +34 -12
  398. package/dist/providers/review-host/github.d.ts +29 -2
  399. package/dist/providers/review-host/github.js +224 -29
  400. package/dist/providers/review-host/local.d.ts +8 -4
  401. package/dist/providers/review-host/local.js +49 -31
  402. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  403. package/dist/providers/review-host/patch-pages.js +176 -0
  404. package/dist/providers/review-host/review-format.d.ts +19 -1
  405. package/dist/providers/review-host/review-format.js +38 -7
  406. package/dist/providers/review-host/types.d.ts +134 -2
  407. package/dist/providers/review-host/types.js +8 -0
  408. package/dist/providers/storage/gcs.d.ts +63 -0
  409. package/dist/providers/storage/gcs.js +69 -0
  410. package/dist/providers/storage/index.d.ts +15 -0
  411. package/dist/providers/storage/index.js +14 -0
  412. package/dist/providers/storage/local.d.ts +24 -0
  413. package/dist/providers/storage/local.js +92 -0
  414. package/dist/providers/storage/meter.d.ts +14 -0
  415. package/dist/providers/storage/meter.js +34 -0
  416. package/dist/providers/storage/s3.d.ts +41 -0
  417. package/dist/providers/storage/s3.js +107 -0
  418. package/dist/providers/storage/types.d.ts +37 -3
  419. package/dist/providers/storage/types.js +21 -4
  420. package/dist/providers/vcs/git.d.ts +33 -2
  421. package/dist/providers/vcs/git.js +324 -22
  422. package/dist/providers/vcs/github-remote.d.ts +26 -3
  423. package/dist/providers/vcs/github-remote.js +124 -14
  424. package/dist/providers/vcs/github.d.ts +214 -6
  425. package/dist/providers/vcs/github.js +447 -45
  426. package/dist/providers/vcs/index.js +8 -1
  427. package/dist/providers/vcs/pr-description.d.ts +127 -0
  428. package/dist/providers/vcs/pr-description.js +270 -0
  429. package/dist/providers/vcs/remote.d.ts +33 -1
  430. package/dist/providers/vcs/routing.d.ts +4 -2
  431. package/dist/providers/vcs/routing.js +6 -0
  432. package/dist/providers/vcs/types.d.ts +80 -3
  433. package/dist/quickstart/coding-seed.d.ts +14 -3
  434. package/dist/quickstart/coding-seed.js +213 -4
  435. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  436. package/dist/quickstart/reviewer-prompt.js +6 -6
  437. package/dist/quickstart-images.json +1 -1
  438. package/dist/sandbox/generated/zod.bundle.js +62 -1
  439. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  440. package/dist/sandbox/host-functions.d.ts +1 -0
  441. package/dist/sandbox/host-functions.js +6 -11
  442. package/dist/sandbox/secret-broker.js +3 -4
  443. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  444. package/dist/sandbox/zod-params.d.ts +37 -5
  445. package/dist/sandbox/zod-params.js +181 -26
  446. package/dist/serve.js +8 -1
  447. package/dist/viewer/api-schema.d.ts +349 -2627
  448. package/dist/viewer/api-schema.js +7 -0
  449. package/dist/viewer/build-schemas.js +6 -2
  450. package/dist/viewer/openapi.js +2 -4
  451. package/dist/wardby-bin.js +10 -0
  452. package/docs/agent-recipes.md +58 -20
  453. package/docs/code-review-agents.md +551 -41
  454. package/docs/coding-agent-setup.md +489 -7
  455. package/docs/coding-packages.md +1033 -90
  456. package/docs/coding-services.md +27 -12
  457. package/docs/coding-worker-byo-images.md +20 -0
  458. package/docs/coding-worker-isolation.md +105 -30
  459. package/docs/getting-started-gke.md +124 -137
  460. package/docs/getting-started-identity-provider.md +10 -1
  461. package/docs/getting-started.md +9 -0
  462. package/docs/jira-agents.md +17 -8
  463. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  464. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  465. package/docs/knowledge/delegation-admission-slots.md +52 -0
  466. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  467. package/docs/knowledge/import-rename-target.md +52 -0
  468. package/docs/knowledge/index.md +57 -0
  469. package/docs/knowledge/log.md +9 -0
  470. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  471. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  472. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  473. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  474. package/docs/knowledge/overview-cli.md +74 -0
  475. package/docs/knowledge/overview-coding-proxy.md +72 -0
  476. package/docs/knowledge/overview-coding.md +72 -0
  477. package/docs/knowledge/overview-config.md +60 -0
  478. package/docs/knowledge/overview-core.md +72 -0
  479. package/docs/knowledge/overview-deploy.md +83 -0
  480. package/docs/knowledge/overview-mcp.md +61 -0
  481. package/docs/knowledge/overview-prisma.md +72 -0
  482. package/docs/knowledge/overview-providers.md +89 -0
  483. package/docs/knowledge/overview-sandbox.md +83 -0
  484. package/docs/knowledge/overview-surfaces.md +83 -0
  485. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  486. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  487. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  488. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  489. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  490. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  491. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  492. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  493. package/docs/knowledge/warm-input-publication.md +30 -0
  494. package/docs/knowledge/workspace-staging-failure.md +54 -0
  495. package/docs/knowledge.md +54 -14
  496. package/docs/native-sandbox.md +119 -23
  497. package/docs/observability.md +4 -0
  498. package/docs/security-deployment.md +33 -2
  499. package/docs/slack-notifications.md +35 -19
  500. package/docs/tool-secrets.md +42 -10
  501. package/docs/viewer-api.openapi.yml +1 -1
  502. package/help/admin-viewer.md +24 -2
  503. package/help/architecture-agent.md +11 -6
  504. package/help/build-worker-image.md +3 -1
  505. package/help/builder-agent.md +19 -6
  506. package/help/code-review-agents.md +177 -6
  507. package/help/coding-packages.md +156 -6
  508. package/help/cost-attribution.md +9 -5
  509. package/help/creating-agents.md +14 -1
  510. package/help/dependency-cache.md +143 -0
  511. package/help/deploy-gke.md +15 -8
  512. package/help/errors/budget-exhausted.md +187 -0
  513. package/help/errors/budget-group-exhausted.md +5 -1
  514. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  515. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  516. package/help/errors/continuation-closed.md +9 -12
  517. package/help/errors/delegation-conflict.md +24 -0
  518. package/help/errors/file-list-truncated.md +45 -0
  519. package/help/errors/full-read-required.md +49 -0
  520. package/help/errors/github-account-not-allowed.md +4 -0
  521. package/help/errors/graph-incomplete.md +43 -0
  522. package/help/errors/graph-limit.md +43 -0
  523. package/help/errors/merge-conflict.md +49 -0
  524. package/help/errors/native-sandbox-gateway-error.md +20 -0
  525. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  526. package/help/errors/native-sandbox-worker-exited.md +3 -2
  527. package/help/errors/package-not-allowed-pending.md +52 -0
  528. package/help/errors/package-not-allowed.md +51 -0
  529. package/help/errors/package-refusals.md +43 -0
  530. package/help/errors/patch-cursor-malformed.md +31 -0
  531. package/help/errors/run-lost.md +39 -0
  532. package/help/errors/run-transcript-download.md +44 -0
  533. package/help/errors/secret-in-value.md +69 -0
  534. package/help/errors/target-merge.md +40 -0
  535. package/help/fix-merge-conflicts.md +73 -0
  536. package/help/github-app-setup.md +132 -0
  537. package/help/github.md +22 -0
  538. package/help/identity-and-access.md +2 -0
  539. package/help/jira.md +23 -6
  540. package/help/knowledge.md +16 -7
  541. package/help/local-repositories.md +1 -1
  542. package/help/low-power-mode.md +7 -1
  543. package/help/merge-order-check.md +5 -0
  544. package/help/native-capabilities.md +29 -1
  545. package/help/native-sandbox.md +15 -1
  546. package/help/operating-agents.md +5 -0
  547. package/help/package-audit-mode.md +91 -0
  548. package/help/related-pull-requests.md +10 -7
  549. package/help/resume-runs-locally.md +131 -0
  550. package/help/review-fix-rounds.md +33 -1
  551. package/help/sharing-agents.md +59 -0
  552. package/help/slack-notifications.md +19 -5
  553. package/help/status-comments.md +31 -0
  554. package/help/stop-run.md +58 -0
  555. package/help/troubleshooting/budgets.md +28 -0
  556. package/help/troubleshooting/coding-workers.md +78 -7
  557. package/package.json +17 -10
  558. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  559. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  560. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  561. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  562. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  563. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  564. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  565. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  566. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  567. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  568. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  569. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  570. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  571. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  572. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  573. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  574. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  575. package/prisma/schema.prisma +311 -97
  576. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -1,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";
@@ -25,6 +27,8 @@ export interface CodingProxyRuntimeOptions {
25
27
  * upstream hosts are actually passed to the pinned-fetch allowlist. */
26
28
  createPinnedFetch?: (options: PinnedProxyFetchOptions) => typeof globalThis.fetch;
27
29
  audit?: ProxyAuditSink;
30
+ /** Overridable for tests: builds the dependency cache's blob store. */
31
+ createBlobStore?: (config: BlobStoreConfig) => BlobStore;
28
32
  onRequest?: (event: {
29
33
  protocol: "openai-responses" | "anthropic-messages" | "other";
30
34
  status: number;
@@ -1,6 +1,13 @@
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";
6
13
  import { createMockUpstream, mockUpstreamFromEnv } from "./mock-upstream.js";
@@ -10,7 +17,7 @@ import { OsvAudit } from "./registry/audit.js";
10
17
  import { PrismaRegistryStore } from "./registry/prisma-store.js";
11
18
  import { DEFAULT_PLAN_MAX_ENTRIES, DEFAULT_PLAN_TIMEOUT_MS } from "./registry/plan.js";
12
19
  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";
20
+ import { createPinnedProxyFetch, PROXY_EGRESS_ERROR } from "./secure-fetch.js";
14
21
  import { startCodingProxyServer } from "./server.js";
15
22
  const MIB = 1024 * 1024;
16
23
  function positiveInt(value, fallback) {
@@ -40,6 +47,8 @@ export function createRegistryUpstream(pinned) {
40
47
  /** Starts the trusted proxy with the fixed worker-only Docker endpoint, plus the deny port the enforcement witness probes. */
41
48
  export async function startConfiguredCodingProxy(options) {
42
49
  const env = options.env ?? process.env;
50
+ // Throws on an invalid setting, before anything listens.
51
+ const cacheConfig = loadDependencyCacheConfig(env);
43
52
  // Throws (mock_upstream_guard) on a partial or malformed setting, before anything listens.
44
53
  const mock = mockUpstreamFromEnv(env);
45
54
  if (mock) {
@@ -48,21 +57,22 @@ export async function startConfiguredCodingProxy(options) {
48
57
  const audit = mock
49
58
  ? (event) => options.audit?.({ ...event, mockUpstream: true })
50
59
  : 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
- });
60
+ // Throws (test_simulators_refused) on any refusal, before anything listens.
61
+ const simulators = startupTestSimulators("coding-proxy", env);
57
62
  const buildPinnedFetch = options.createPinnedFetch ?? createPinnedProxyFetch;
58
63
  const upstreamHosts = [...new Set([...REGISTRY_ADAPTERS.values()].flatMap((adapter) => adapter.upstreamHosts))];
59
- const pinned = buildPinnedFetch({ allowedHosts: [...upstreamHosts, "api.osv.dev"] });
64
+ // WARDBY_TEST_SIMULATORS (test only): the registry hosts go to their simulators, and every
65
+ // other host is still refused.
66
+ const pinned = simulators
67
+ ? createSimulatorRegistryFetch(simulators, () => new Error(PROXY_EGRESS_ERROR))
68
+ : buildPinnedFetch({ allowedHosts: [...upstreamHosts, "api.osv.dev"] });
60
69
  const upstream = createRegistryUpstream(pinned);
61
70
  const metadataTimeoutMs = positiveInt(env.REGISTRY_METADATA_TIMEOUT_MS, 30_000);
62
71
  const maxMetadataBytes = positiveInt(env.REGISTRY_MAX_METADATA_MB, 64) * MIB;
72
+ const registryStore = new PrismaRegistryStore(options.registryDb ?? options.db);
63
73
  const registry = new RegistryService({
64
74
  adapters: REGISTRY_ADAPTERS,
65
- store: new PrismaRegistryStore(options.registryDb ?? options.db),
75
+ store: registryStore,
66
76
  audit: new OsvAudit({
67
77
  fetch: upstream,
68
78
  failOpen: env.REGISTRY_AUDIT_FAIL_OPEN === "true",
@@ -85,14 +95,64 @@ export async function startConfiguredCodingProxy(options) {
85
95
  idleTimeoutMs: positiveInt(env.REGISTRY_IDLE_TIMEOUT_MS, 120_000),
86
96
  },
87
97
  });
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,
98
+ let dependencyCache;
99
+ let modelRequestSeal;
100
+ let eviction;
101
+ if (cacheConfig.enabled) {
102
+ const blobs = (options.createBlobStore ?? createBlobStore)(cacheConfig.blobStore);
103
+ const cacheStore = new PrismaDependencyCacheStore(options.registryDb ?? options.db);
104
+ modelRequestSeal = new ModelRequestSeal(cacheStore);
105
+ dependencyCache = new DependencyCacheService({
106
+ registry: registryStore,
107
+ store: cacheStore,
108
+ blobs,
109
+ maxSnapshotBytes: cacheConfig.maxSnapshotBytes,
110
+ uploadMs: cacheConfig.uploadMs,
111
+ });
112
+ eviction = startEviction({
113
+ store: cacheStore,
114
+ blobs,
115
+ limits: {
116
+ maxAgeMs: cacheConfig.maxAgeMs,
117
+ repoCapBytes: cacheConfig.repoCapBytes,
118
+ totalCapBytes: cacheConfig.totalCapBytes,
119
+ },
120
+ });
121
+ }
122
+ else if (cacheConfig.reason === "no_blob_store") {
123
+ 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");
124
+ }
125
+ const seal = modelRequestSeal;
126
+ const proxy = new CodingProxy({
127
+ ledger: new PrismaProxyLedger(options.db),
128
+ credentials: new EnvironmentCredentialResolver(env),
129
+ audit,
130
+ // WARDBY_TEST_SIMULATORS (test only; refused alongside the mock upstream): the scripted model,
131
+ // with every credential header dropped.
132
+ ...(simulators
133
+ ? { fetch: createSimulatorModelFetch(simulators, () => new Error(PROXY_EGRESS_ERROR)) }
134
+ : mock
135
+ ? { fetch: createMockUpstream(mock) }
136
+ : {}),
137
+ // The run's first model request closes its dependency cache (no-op for a run with it off).
138
+ ...(seal ? { onModelRequest: (runId) => seal.onModelRequest(runId) } : {}),
95
139
  });
140
+ const startServer = options.startServer ?? startCodingProxyServer;
141
+ let server;
142
+ try {
143
+ server = await startServer(proxy, {
144
+ host: "0.0.0.0",
145
+ port: CODING_PROXY_PORT,
146
+ expectedHost: `${CODING_PROXY_ALIAS}:${CODING_PROXY_PORT}`,
147
+ registry,
148
+ ...(dependencyCache ? { dependencyCache } : {}),
149
+ onRequest: options.onRequest,
150
+ });
151
+ }
152
+ catch (error) {
153
+ eviction?.stop();
154
+ throw error;
155
+ }
96
156
  let deny;
97
157
  try {
98
158
  deny = await (options.startDenyPort ?? startDenyPortListener)("0.0.0.0", CODING_PROXY_DENY_PORT);
@@ -100,12 +160,14 @@ export async function startConfiguredCodingProxy(options) {
100
160
  catch (error) {
101
161
  // A proxy without its witness must not stay up: the launcher's gate would never be able to
102
162
  // prove a policy is enforced, and every launch would fail at the gate instead of at startup.
163
+ eviction?.stop();
103
164
  await server.close();
104
165
  throw error;
105
166
  }
106
167
  return {
107
168
  port: server.port,
108
169
  close: async () => {
170
+ eviction?.stop();
109
171
  await deny.close();
110
172
  await server.close();
111
173
  },
@@ -1,6 +1,7 @@
1
1
  import type { ProxyAuditEvent } from "./types.js";
2
2
  import { type CodingProxy } from "./proxy.js";
3
3
  import { type RegistryService } from "./registry/service.js";
4
+ import type { DependencyCacheService } from "./dependency-cache/service.js";
4
5
  import type { ProxyProtocol } from "./types.js";
5
6
  declare const proxyLog: import("pino").Logger<never, boolean>;
6
7
  /**
@@ -13,7 +14,11 @@ export interface CodingProxyServerConfig {
13
14
  host: string;
14
15
  port: number;
15
16
  expectedHost?: string;
16
- registry?: Pick<RegistryService, "handle"> & Partial<Pick<RegistryService, "plan">>;
17
+ registry?: Pick<RegistryService, "handle"> & Partial<Pick<RegistryService, "plan" | "refusals">>;
18
+ /** The dependency cache (`/cache/...`); absent when the deployment has it off. */
19
+ dependencyCache?: Pick<DependencyCacheService, "handle" | "uploadMs">;
20
+ /** Time to receive a whole request (default HTTP_LIMITS.requestMs); a cache upload gets its upload window instead. */
21
+ requestMs?: number;
17
22
  onRequest?: (event: {
18
23
  protocol: ProxyProtocol | "other";
19
24
  status: number;
@@ -99,6 +99,12 @@ function readPlanBody(request, signal) {
99
99
  failed();
100
100
  });
101
101
  }
102
+ /** An error answer to a request whose body was not read: close the
103
+ * connection rather than read (or keep) what the client is still sending. */
104
+ function closeIfBodyUnread(request, response) {
105
+ if (!request.complete && !response.headersSent)
106
+ response.setHeader("connection", "close");
107
+ }
102
108
  function routeProtocol(method, url) {
103
109
  if (method !== "POST")
104
110
  return undefined;
@@ -130,8 +136,25 @@ function responseSink(response) {
130
136
  };
131
137
  }
132
138
  export async function startCodingProxyServer(proxy, config) {
139
+ const requestMs = config.requestMs ?? HTTP_LIMITS.requestMs;
140
+ // A snapshot upload (up to WARDBY_DEPENDENCY_CACHE_MAX_SNAPSHOT_MB) cannot
141
+ // arrive within requestMs, and Node's requestTimeout is server-wide: with
142
+ // the cache on it is widened to cover the upload window (which the cache
143
+ // enforces on the upload itself), and every request gets a requestMs timer
144
+ // of its own. Only the cache lifts that timer, and only for an upload it
145
+ // has authenticated, found eligible and given its upload slot.
146
+ const extendedRequests = config.dependencyCache !== undefined;
133
147
  const server = createServer({ maxHeaderSize: 16 * 1024, requireHostHeader: true }, (request, response) => {
134
148
  const startedAt = performance.now();
149
+ const bodyTimer = extendedRequests
150
+ ? setTimeout(() => {
151
+ if (!request.complete)
152
+ request.socket.destroy();
153
+ }, requestMs).unref()
154
+ : undefined;
155
+ // Done with once the response is over (finished or closed early).
156
+ if (bodyTimer)
157
+ response.once("close", () => clearTimeout(bodyTimer));
135
158
  const protocol = routeProtocol(request.method, request.url) ?? "other";
136
159
  response.once("finish", () => {
137
160
  try {
@@ -143,9 +166,19 @@ export async function startCodingProxyServer(proxy, config) {
143
166
  });
144
167
  void (async () => {
145
168
  if (config.expectedHost && request.headers.host !== config.expectedHost) {
169
+ closeIfBodyUnread(request, response);
146
170
  sendError(response, 403, "invalid_host");
147
171
  return;
148
172
  }
173
+ if (request.url?.startsWith("/cache/")) {
174
+ if (!config.dependencyCache) {
175
+ closeIfBodyUnread(request, response);
176
+ sendError(response, 404, "not_found");
177
+ return;
178
+ }
179
+ await config.dependencyCache.handle(request, response, registryToken(request.headers.authorization), () => clearTimeout(bodyTimer));
180
+ return;
181
+ }
149
182
  if (request.url?.startsWith("/registry/")) {
150
183
  if (!config.registry) {
151
184
  sendError(response, 404, "not_found");
@@ -187,6 +220,16 @@ export async function startCodingProxyServer(proxy, config) {
187
220
  sendError(response, 405, "method_not_allowed");
188
221
  return;
189
222
  }
223
+ // The run's recent refusals, for clients that don't print the 403 body (pip, uv).
224
+ const refusals = request.url.match(/^\/registry\/-\/refusals(?:\?(.*))?$/);
225
+ if (refusals && config.registry.refusals) {
226
+ const since = new URLSearchParams(refusals[1] ?? "").get("since");
227
+ sendRegistry(response, await config.registry.refusals({
228
+ token: registryToken(request.headers.authorization),
229
+ ...(since ? { since: new Date(since) } : {}),
230
+ }));
231
+ return;
232
+ }
190
233
  const match = request.url.match(/^\/registry\/([a-z0-9-]+)\/(.*)$/);
191
234
  if (!match) {
192
235
  sendError(response, 404, "not_found");
@@ -269,6 +312,7 @@ export async function startCodingProxyServer(proxy, config) {
269
312
  response.destroy();
270
313
  return;
271
314
  }
315
+ closeIfBodyUnread(request, response);
272
316
  if (error instanceof CodingProxyError || error instanceof HttpBoundaryError) {
273
317
  proxyLog.info({ event: "request.rejected", code: error instanceof CodingProxyError ? error.code : error.message }, "coding proxy request rejected");
274
318
  sendError(response, error.status, error instanceof CodingProxyError ? error.code : error.message);
@@ -283,7 +327,7 @@ export async function startCodingProxyServer(proxy, config) {
283
327
  sendError(response, 500, "internal_error");
284
328
  });
285
329
  });
286
- server.requestTimeout = HTTP_LIMITS.requestMs;
330
+ server.requestTimeout = extendedRequests ? requestMs + config.dependencyCache.uploadMs : requestMs;
287
331
  server.headersTimeout = HTTP_LIMITS.headersMs;
288
332
  server.keepAliveTimeout = 5_000;
289
333
  server.maxRequestsPerSocket = 100;