@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
@@ -4,24 +4,38 @@
4
4
  * lockfile claims is trusted:
5
5
  *
6
6
  * - every entry's integrity must equal the registry's own for that exact
7
- * version (a per-version fact read from the registry, stored forever);
7
+ * version (a per-version fact read from the registry, stored forever),
8
+ * unless the format records no npm integrity at all (yarn Berry): then
9
+ * the approval is the exact name@version, and the download is checked
10
+ * against the registry's integrity alone;
8
11
  * - edges come from the registry too: a parent version's declared
9
12
  * dependencies, resolved to lockfile entries by the client's own rule
10
13
  * (npm: nearest ancestor node_modules), and kept only when the entry is
11
14
  * the declared package at a version inside the declared range;
12
- * - reachability starts at the projects' dependencies that are allowlist
13
- * roots (at a version inside the root's range) and follows only verified
14
- * edges, through versions old enough and without a HIGH/CRITICAL advisory.
15
+ * - reachability starts at every lockfile entry that is an allowlist root
16
+ * (at a version inside the root's range), wherever it sits and whether or
17
+ * not a project declares it, and follows only verified
18
+ * edges, through versions old enough and without a HIGH/CRITICAL advisory
19
+ * (one the run's accepted set waives does not count; malware always does).
20
+ *
21
+ * PyPI dependency lines may be gated on extras: an entry is expanded with the
22
+ * extras it is installed with (a start's allowlist entry's, then those its
23
+ * parents' lines ask of it), and a plain install follows none.
15
24
  *
16
25
  * A refused entry refuses itself and whatever is reachable only through it;
17
- * everything else is approved, as exact name@version pairs. The work is
26
+ * everything else is approved, as exact name@version pairs (an ecosystem
27
+ * that `approves: "names"` turns them into name allowances). In package
28
+ * audit mode every registry entry is a start as well: one the allowlist does
29
+ * not reach is approved when it passes every other check, marked with its
30
+ * audit verdict (and, in `full`, a version kept only past non-malware
31
+ * blocking advisories is approved and marked too). The work is
18
32
  * bounded: facts are fetched only for entries reached (so a lockfile of
19
33
  * unrelated packages costs nothing upstream), with bounded concurrency and a
20
34
  * deadline.
21
35
  */
22
36
  import { matchRoot } from "../../../coding/registry/allowlist.js";
23
37
  import { RegistryError, } from "../../../coding/registry/types.js";
24
- import { versionKey } from "./audit.js";
38
+ import { auditAdvisoryOf, splitWaived, versionKey } from "./audit.js";
25
39
  export const DEFAULT_PLAN_MAX_ENTRIES = 5000;
26
40
  export const DEFAULT_PLAN_TIMEOUT_MS = 120_000;
27
41
  /** Per-version documents fetched at once (each is a few KB). */
@@ -61,21 +75,29 @@ export async function verifyLockfilePlan(input) {
61
75
  reason: entry.unsupportedReason ?? "cannot be verified against the registry",
62
76
  });
63
77
  }
64
- // Starting points: what the projects themselves declare, when it is an
65
- // allowlist root at a version inside the root's range.
78
+ // Starting points: every registry entry that is an allowlist root at a
79
+ // version inside the root's range, wherever it sits in the lockfile and
80
+ // whether or not a project declares it. An allowlisted name may be
81
+ // installed by name anyway (the download path allows the same name@version:
82
+ // `authorize` matches the name with `matchRoot`, and `keptVersions`
83
+ // applies the root's range, release age and advisories), so an `overrides`-forced version of it, which no parent's
84
+ // declared range reaches, is a start in its own right. Every start still
85
+ // passes the fact checks below (integrity, release age, advisories), and
86
+ // edges are still followed only inside declared ranges.
66
87
  const starts = new Set();
67
- for (const project of lockfile.projects) {
68
- for (const dependency of project.dependencies) {
69
- const entry = lockfile.resolve(project.path, dependency.key);
70
- if (!entry || entry.kind !== "registry" || entry.name !== dependency.name)
71
- continue;
72
- const root = matchRoot(input.roots, adapter.normalizeName(entry.name));
73
- if (!root)
74
- continue;
75
- if (root.range && !safeSatisfies(adapter, entry.version, root.range))
76
- continue;
77
- starts.add(entry);
78
- }
88
+ // The extras each reached entry is installed with (PyPI): a start's are its
89
+ // allowlist entry's, a child's those its parents' lines ask of it.
90
+ const extrasOf = new Map();
91
+ for (const entry of lockfile.entries) {
92
+ if (entry.kind !== "registry")
93
+ continue;
94
+ const root = matchRoot(input.roots, adapter.normalizeName(entry.name));
95
+ if (!root)
96
+ continue;
97
+ if (root.range && !safeSatisfies(adapter, entry.version, root.range))
98
+ continue;
99
+ starts.add(entry);
100
+ extrasOf.set(entry, new Set(root.extras ?? []));
79
101
  }
80
102
  // Breadth first over verified edges, fetching facts one layer at a time
81
103
  // (only for entries actually reached).
@@ -83,11 +105,28 @@ export async function verifyLockfilePlan(input) {
83
105
  const edges = new Map();
84
106
  const candidates = new Set();
85
107
  const visited = new Set(starts);
108
+ // Package audit mode: every other registry entry starts too, except an
109
+ // allowlisted name outside its entry's own range (an owner's explicit
110
+ // restriction, never widened by audit mode). Visited after the roots'
111
+ // graph, so facts load in the same bounded layers.
112
+ const auditStarts = input.auditMode
113
+ ? lockfile.entries.filter((entry) => entry.kind === "registry" &&
114
+ !starts.has(entry) &&
115
+ !outsideRootRange(input, adapter.normalizeName(entry.name), entry.version))
116
+ : [];
86
117
  let layer = [...starts];
87
- while (layer.length > 0) {
118
+ let auditSeeded = false;
119
+ while (layer.length > 0 || (!auditSeeded && auditStarts.length > 0)) {
120
+ if (layer.length === 0) {
121
+ auditSeeded = true;
122
+ layer = auditStarts.filter((entry) => !visited.has(entry));
123
+ for (const entry of layer)
124
+ visited.add(entry);
125
+ continue;
126
+ }
88
127
  signal.throwIfAborted();
89
128
  await loadFacts(input, layer, outcomes);
90
- const next = [];
129
+ const next = new Set();
91
130
  for (const entry of layer) {
92
131
  const outcome = outcomes.get(versionKey(entry.name, entry.version));
93
132
  if ("refusal" in outcome) {
@@ -95,7 +134,8 @@ export async function verifyLockfilePlan(input) {
95
134
  continue;
96
135
  }
97
136
  const { fact } = outcome;
98
- if (entry.integrity === null || entry.integrity.trim() !== fact.integrity) {
137
+ if (lockfile.integrity !== "registry" &&
138
+ (entry.integrity === null || entry.integrity.trim() !== fact.integrity)) {
99
139
  refusals.set(entry, {
100
140
  code: "wardby_lockfile_integrity_mismatch",
101
141
  reason: `the lockfile's integrity is not the registry's for ${entry.name}@${entry.version}`,
@@ -113,34 +153,63 @@ export async function verifyLockfilePlan(input) {
113
153
  }
114
154
  candidates.add(entry);
115
155
  const children = [];
116
- for (const dependency of fact.dependencies) {
117
- const child = lockfile.resolve(entry.path, dependency.key);
118
- if (!child || child.kind !== "registry" || child.name !== dependency.name)
119
- continue;
120
- if (!support.edgeSatisfies(child.version, dependency.range))
121
- continue;
122
- children.push(child);
123
- if (!visited.has(child)) {
124
- visited.add(child);
125
- next.push(child);
156
+ const dependencies = support.dependenciesOf
157
+ ? support.dependenciesOf(fact, [...(extrasOf.get(entry) ?? [])].sort())
158
+ : fact.dependencies;
159
+ for (const dependency of dependencies) {
160
+ const resolved = lockfile.resolveAll
161
+ ? lockfile.resolveAll(entry.path, dependency.key)
162
+ : [lockfile.resolve(entry.path, dependency.key)];
163
+ for (const child of resolved) {
164
+ if (!child || child.kind !== "registry" || child.name !== dependency.name)
165
+ continue;
166
+ if (!support.edgeSatisfies(child.version, dependency.range))
167
+ continue;
168
+ children.push(child);
169
+ const asked = dependency.extras ?? [];
170
+ if (!visited.has(child)) {
171
+ visited.add(child);
172
+ extrasOf.set(child, new Set(asked));
173
+ next.add(child);
174
+ continue;
175
+ }
176
+ // Reached again with extras it lacked: expanded again, now with them
177
+ // (extras only grow, so this ends).
178
+ const known = extrasOf.get(child) ?? new Set();
179
+ if (asked.some((extra) => !known.has(extra))) {
180
+ for (const extra of asked)
181
+ known.add(extra);
182
+ extrasOf.set(child, known);
183
+ next.add(child);
184
+ }
126
185
  }
127
186
  }
128
187
  edges.set(entry, children);
129
188
  }
130
- layer = next;
189
+ layer = [...next];
131
190
  }
132
191
  // One advisory lookup for every candidate version.
133
192
  const withheld = await input.audit([...new Map([...candidates].map((entry) => [versionKey(entry.name, entry.version), entry])).values()].map(({ name, version }) => ({ name, version })), signal);
193
+ // Advisories the run's accepted set waived, per approved name@version,
194
+ // and (full mode) the blocking ones served past.
195
+ const waivers = new Map();
196
+ const auditAdvisories = new Map();
134
197
  for (const entry of candidates) {
135
- const ids = withheld.get(versionKey(entry.name, entry.version));
136
- if (ids && ids.length > 0) {
198
+ const key = versionKey(entry.name, entry.version);
199
+ const split = splitWaived(withheld.get(key) ?? [], input.accepted, { auditAll: input.auditMode === "full" });
200
+ if (split.audited.length > 0)
201
+ auditAdvisories.set(key, split.audited.map(auditAdvisoryOf));
202
+ if (split.withheld.length > 0) {
137
203
  candidates.delete(entry);
138
204
  refusals.set(entry, {
139
205
  code: "wardby_version_filtered",
140
- reason: `withheld by advisory ${ids.join(", ")} (high severity or malware)`,
206
+ reason: `withheld by advisory ${split.withheld.map(({ id }) => id).join(", ")} (high severity or malware)`,
141
207
  intrinsic: true,
142
208
  });
143
209
  }
210
+ else if (split.waived.length > 0) {
211
+ waivers.set(key, split.waived.map(({ id }) => id));
212
+ }
144
213
  }
145
214
  // Reachability again, now only through entries that passed every check:
146
215
  // a refused entry refuses whatever is reachable only through it.
@@ -157,16 +226,38 @@ export async function verifyLockfilePlan(input) {
157
226
  queue.push(child);
158
227
  }
159
228
  }
229
+ // Package audit mode: every other entry that passed every check is
230
+ // approved too, marked with how it reached the lockfile.
231
+ const relations = input.auditMode
232
+ ? auditRelations(input, approvedEntries, candidates, edges)
233
+ : new Map();
160
234
  const approved = new Map();
161
- for (const entry of approvedEntries) {
162
- const outcome = outcomes.get(versionKey(entry.name, entry.version));
163
- if (outcome && "fact" in outcome)
164
- approved.set(versionKey(entry.name, entry.version), {
165
- name: entry.name,
166
- version: entry.version,
167
- integrity: outcome.fact.integrity,
168
- });
169
- }
235
+ const approve = (entry, relation) => {
236
+ const key = versionKey(entry.name, entry.version);
237
+ const outcome = outcomes.get(key);
238
+ if (!outcome || !("fact" in outcome) || approved.has(key))
239
+ return;
240
+ const acceptedAdvisories = waivers.get(key);
241
+ const advisories = auditAdvisories.get(key);
242
+ const audit = relation
243
+ ? { ...relation, ...(advisories ? { advisories } : {}) }
244
+ : advisories
245
+ ? { relation: "allowed", advisories }
246
+ : undefined;
247
+ approved.set(key, {
248
+ name: entry.name,
249
+ version: entry.version,
250
+ integrity: outcome.fact.integrity,
251
+ ...(acceptedAdvisories ? { acceptedAdvisories } : {}),
252
+ ...(audit ? { audit } : {}),
253
+ });
254
+ };
255
+ // Approvals through the allowlist first: an exact version approved both
256
+ // ways is not audited.
257
+ for (const entry of approvedEntries)
258
+ approve(entry, undefined);
259
+ for (const [entry, relation] of relations)
260
+ approve(entry, relation);
170
261
  const refused = new Map();
171
262
  for (const entry of lockfile.entries) {
172
263
  if (entry.kind === "bundled")
@@ -182,7 +273,59 @@ export async function verifyLockfilePlan(input) {
182
273
  }
183
274
  // An entry refused at one place in the tree but approved at another (the
184
275
  // same name@version) is approved: approvals are per exact version.
185
- return { approved: [...approved.values()], refused: [...refused.values()] };
276
+ const approvals = [...approved.values()];
277
+ return {
278
+ approved: approvals,
279
+ refused: [...refused.values()],
280
+ audited: approvals.filter((approval) => approval.audit).length,
281
+ };
282
+ }
283
+ /** Whether `name@version` is an allowlisted name at a version its entry's range excludes. */
284
+ function outsideRootRange(input, name, version) {
285
+ const root = matchRoot(input.roots, name);
286
+ return !!root?.range && !safeSatisfies(input.adapter, version, root.range);
287
+ }
288
+ /**
289
+ * How each candidate the allowlist does not reach came into the lockfile
290
+ * (package audit mode): `top-level` when a lockfile project declares it,
291
+ * `transitive` when an audited top-level entry reaches it over verified
292
+ * edges (`via` its nearest such ancestor, breadth first), otherwise
293
+ * `unknown`. Best effort: it decides only what a reviewer is shown.
294
+ */
295
+ function auditRelations(input, approvedEntries, candidates, edges) {
296
+ const { lockfile } = input;
297
+ // An allowlisted name outside its entry's range is never audited in,
298
+ // even when an audited package declares it.
299
+ const audited = new Set([...candidates].filter((entry) => !approvedEntries.has(entry) && !outsideRootRange(input, input.adapter.normalizeName(entry.name), entry.version)));
300
+ const relations = new Map();
301
+ const declared = new Set();
302
+ for (const project of lockfile.projects)
303
+ for (const dependency of project.dependencies) {
304
+ const entry = lockfile.resolve(project.path, dependency.key);
305
+ if (entry)
306
+ declared.add(entry);
307
+ }
308
+ const queue = [];
309
+ for (const entry of audited)
310
+ if (declared.has(entry)) {
311
+ relations.set(entry, { relation: "top-level" });
312
+ queue.push(entry);
313
+ }
314
+ const via = new Map(queue.map((entry) => [entry, entry.name]));
315
+ while (queue.length > 0) {
316
+ const entry = queue.shift();
317
+ for (const child of edges.get(entry) ?? []) {
318
+ if (via.has(child) || !audited.has(child))
319
+ continue;
320
+ via.set(child, via.get(entry));
321
+ relations.set(child, { relation: "transitive", via: via.get(entry) });
322
+ queue.push(child);
323
+ }
324
+ }
325
+ for (const entry of audited)
326
+ if (!relations.has(entry))
327
+ relations.set(entry, { relation: "unknown" });
328
+ return relations;
186
329
  }
187
330
  function safeSatisfies(adapter, version, range) {
188
331
  try {
@@ -213,6 +356,7 @@ async function loadFacts(input, layer, outcomes) {
213
356
  if (missing.length === 0)
214
357
  return;
215
358
  const fresh = new Map();
359
+ const complete = [];
216
360
  await eachLimited(missing, input.factConcurrency ?? DEFAULT_PLAN_FACT_CONCURRENCY, async ({ name, version }) => {
217
361
  const key = versionKey(name, version);
218
362
  try {
@@ -227,6 +371,13 @@ async function loadFacts(input, layer, outcomes) {
227
371
  });
228
372
  return;
229
373
  }
374
+ // A registry that gives the publish time with the version (PyPI) needs no second read.
375
+ if (fact.publishedAt) {
376
+ const stored = { ...fact, publishedAt: fact.publishedAt };
377
+ complete.push(stored);
378
+ outcomes.set(key, checkedFact(input, stored));
379
+ return;
380
+ }
230
381
  fresh.set(key, fact);
231
382
  }
232
383
  catch (error) {
@@ -239,7 +390,6 @@ async function loadFacts(input, layer, outcomes) {
239
390
  const byName = new Map();
240
391
  for (const fact of fresh.values())
241
392
  byName.set(fact.name, [...(byName.get(fact.name) ?? []), fact.version]);
242
- const complete = [];
243
393
  await eachLimited([...byName.entries()], input.timeConcurrency ?? DEFAULT_PLAN_TIME_CONCURRENCY, async ([name, versions]) => {
244
394
  let times;
245
395
  try {
@@ -300,5 +450,8 @@ function upstreamRefusal(error) {
300
450
  return { code: "wardby_metadata_too_large", reason: error.message };
301
451
  if (error instanceof RegistryError && error.code === "wardby_package_not_found")
302
452
  return { code: "wardby_package_not_found", reason: error.message };
453
+ // A release with nothing the registry may serve (PyPI: no wheel) stays so.
454
+ if (error instanceof RegistryError && error.code === "wardby_file_not_allowed")
455
+ return { code: "wardby_file_not_allowed", reason: error.message, intrinsic: true };
303
456
  return { code: "wardby_upstream_error", reason: "the registry could not be read for it; try again" };
304
457
  }
@@ -1,12 +1,17 @@
1
1
  import type { PrismaClient } from "#prisma";
2
2
  import type { FileDependency } from "../../../coding/registry/types.js";
3
- import type { ApprovedVersion, PlanRefusedVersion, RegistryFetchRecord, RegistryRunContext, RegistryStore, StoredVersionFact } from "./store.js";
3
+ import type { ApprovedDownload, ApprovedVersion, PlanRefusedVersion, RegistryAuditInsert, RegistryFetchRecord, RegistryRunContext, RegistryStore, StoredVersionFact } from "./store.js";
4
4
  export declare class PrismaRegistryStore implements RegistryStore {
5
5
  private readonly db;
6
6
  constructor(db: PrismaClient);
7
7
  findRunByRegistryTokenHash(hash: string, now: Date): Promise<RegistryRunContext | null>;
8
8
  isAllowedDependency(runId: string, ecosystem: string, name: string): Promise<boolean>;
9
+ findAllowance(runId: string, ecosystem: string, name: string): Promise<{
10
+ auditedVia: string | null;
11
+ } | null>;
9
12
  addAllowances(runId: string, ecosystem: string, names: readonly string[]): Promise<void>;
13
+ addAuditedAllowances(runId: string, ecosystem: string, names: readonly string[], auditedVia: string): Promise<void>;
14
+ recordAudit(record: RegistryAuditInsert): Promise<void>;
10
15
  allowedExtras(runId: string, ecosystem: string, name: string): Promise<string[]>;
11
16
  addExtraAllowances(runId: string, ecosystem: string, dependencies: readonly FileDependency[]): Promise<void>;
12
17
  recordFetch(record: RegistryFetchRecord): Promise<void>;
@@ -18,20 +23,21 @@ export declare class PrismaRegistryStore implements RegistryStore {
18
23
  listFetches(runId: string): Promise<(RegistryFetchRecord & {
19
24
  createdAt: Date;
20
25
  })[]>;
26
+ listRecentRefusals(runId: string, since: Date, limit: number): Promise<(RegistryFetchRecord & {
27
+ createdAt: Date;
28
+ })[]>;
21
29
  getVersionFacts(ecosystem: string, versions: readonly {
22
30
  name: string;
23
31
  version: string;
24
32
  }[]): Promise<StoredVersionFact[]>;
25
33
  putVersionFacts(ecosystem: string, facts: readonly StoredVersionFact[]): Promise<void>;
26
34
  approveVersions(runId: string, ecosystem: string, versions: readonly ApprovedVersion[]): Promise<void>;
27
- findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<{
28
- integrity: string;
29
- downloadUrl: string;
30
- } | null>;
35
+ findApprovedVersion(runId: string, ecosystem: string, name: string, version: string): Promise<ApprovedDownload | null>;
31
36
  refusePlanVersions(runId: string, ecosystem: string, versions: readonly PlanRefusedVersion[]): Promise<void>;
32
37
  findPlanRefusal(runId: string, ecosystem: string, name: string, version: string): Promise<{
33
38
  code: string;
34
39
  reason: string;
35
40
  publishedAt: Date | null;
36
41
  } | null>;
42
+ recordDependencyCacheLockHash(runId: string, lockHash: string, max: number): Promise<void>;
37
43
  }
@@ -1,3 +1,4 @@
1
+ import { isPackageAuditMode, parsePackageAuditVerdict } from "../../../coding/registry/audit-mode.js";
1
2
  import { extraAllowanceName, extraOfAllowanceName } from "./store.js";
2
3
  /** Versions looked up per query, so a 5000-entry lockfile is a handful of
3
4
  * bounded queries rather than one enormous OR. */
@@ -14,7 +15,17 @@ export class PrismaRegistryStore {
14
15
  runId: true,
15
16
  status: true,
16
17
  deadlineAt: true,
17
- run: { select: { packageAllowlist: true, packagePolicy: true } },
18
+ run: {
19
+ select: {
20
+ packageAllowlist: true,
21
+ packagePolicy: true,
22
+ repository: true,
23
+ workerImage: true,
24
+ toolImage: true,
25
+ dependencyCache: true,
26
+ packageAuditMode: true,
27
+ },
28
+ },
18
29
  },
19
30
  });
20
31
  if (!session || session.status !== "active" || session.deadlineAt <= now)
@@ -24,6 +35,10 @@ export class PrismaRegistryStore {
24
35
  deadlineAt: session.deadlineAt,
25
36
  allowlist: (session.run.packageAllowlist ?? {}),
26
37
  policy: session.run.packagePolicy,
38
+ repository: session.run.repository,
39
+ cacheImage: session.run.toolImage ?? session.run.workerImage,
40
+ dependencyCache: session.run.dependencyCache,
41
+ packageAudit: isPackageAuditMode(session.run.packageAuditMode) ? session.run.packageAuditMode : null,
27
42
  };
28
43
  }
29
44
  async isAllowedDependency(runId, ecosystem, name) {
@@ -36,6 +51,15 @@ export class PrismaRegistryStore {
36
51
  });
37
52
  return row !== null;
38
53
  }
54
+ async findAllowance(runId, ecosystem, name) {
55
+ // An extra's row (`name[extra]`) is never a package allowance.
56
+ if (name.includes("["))
57
+ return null;
58
+ return this.db.registryAllowance.findUnique({
59
+ where: { runId_ecosystem_name: { runId, ecosystem, name } },
60
+ select: { auditedVia: true },
61
+ });
62
+ }
39
63
  async addAllowances(runId, ecosystem, names) {
40
64
  if (names.length === 0)
41
65
  return;
@@ -44,6 +68,32 @@ export class PrismaRegistryStore {
44
68
  skipDuplicates: true,
45
69
  });
46
70
  }
71
+ async addAuditedAllowances(runId, ecosystem, names, auditedVia) {
72
+ if (names.length === 0)
73
+ return;
74
+ // Insert-only (the proxy has no UPDATE): an existing row keeps its first writer.
75
+ await this.db.registryAllowance.createMany({
76
+ data: [...new Set(names)].map((name) => ({ runId, ecosystem, name, auditedVia })),
77
+ skipDuplicates: true,
78
+ });
79
+ }
80
+ async recordAudit(record) {
81
+ await this.db.registryAuditRecord.createMany({
82
+ data: [
83
+ {
84
+ runId: record.runId,
85
+ ecosystem: record.ecosystem,
86
+ name: record.name,
87
+ version: record.version,
88
+ relation: record.relation,
89
+ via: record.via ?? null,
90
+ sizeBytes: record.sizeBytes ?? null,
91
+ advisories: record.advisories.map(({ id, severity, summary }) => ({ id, severity, summary })),
92
+ },
93
+ ],
94
+ skipDuplicates: true,
95
+ });
96
+ }
47
97
  async allowedExtras(runId, ecosystem, name) {
48
98
  const rows = await this.db.registryAllowance.findMany({
49
99
  where: { runId, ecosystem, name: { startsWith: `${name}[` } },
@@ -73,18 +123,15 @@ export class PrismaRegistryStore {
73
123
  }
74
124
  async listFetches(runId) {
75
125
  const rows = await this.db.registryFetch.findMany({ where: { runId }, orderBy: { createdAt: "asc" } });
76
- return rows.map((row) => ({
77
- runId: row.runId,
78
- ecosystem: row.ecosystem,
79
- name: row.name,
80
- version: row.version ?? undefined,
81
- filename: row.filename ?? undefined,
82
- integrity: row.integrity ?? undefined,
83
- sizeBytes: row.sizeBytes ?? undefined,
84
- outcome: row.outcome,
85
- reason: row.reason ?? undefined,
86
- createdAt: row.createdAt,
87
- }));
126
+ return rows.map(fetchRecordOf);
127
+ }
128
+ async listRecentRefusals(runId, since, limit) {
129
+ const rows = await this.db.registryFetch.findMany({
130
+ where: { runId, outcome: "refused", createdAt: { gte: since } },
131
+ orderBy: { createdAt: "desc" },
132
+ take: limit,
133
+ });
134
+ return rows.map(fetchRecordOf);
88
135
  }
89
136
  async getVersionFacts(ecosystem, versions) {
90
137
  const facts = [];
@@ -117,7 +164,13 @@ export class PrismaRegistryStore {
117
164
  publishedAt: fact.publishedAt,
118
165
  integrity: fact.integrity,
119
166
  downloadUrl: fact.downloadUrl,
120
- dependencies: fact.dependencies.map(({ key, name, range }) => ({ key, name, range })),
167
+ dependencies: fact.dependencies.map(({ key, name, range, extras, when }) => ({
168
+ key,
169
+ name,
170
+ range,
171
+ ...(extras ? { extras: [...extras] } : {}),
172
+ ...(when ? { when: [...when] } : {}),
173
+ })),
121
174
  })),
122
175
  skipDuplicates: true,
123
176
  });
@@ -126,14 +179,32 @@ export class PrismaRegistryStore {
126
179
  if (versions.length === 0)
127
180
  return;
128
181
  await this.db.registryApprovedVersion.createMany({
129
- data: versions.map(({ name, version, integrity }) => ({ runId, ecosystem, name, version, integrity })),
182
+ data: versions.map(({ name, version, integrity, acceptedAdvisories, audit }) => ({
183
+ runId,
184
+ ecosystem,
185
+ name,
186
+ version,
187
+ integrity,
188
+ acceptedAdvisories: [...(acceptedAdvisories ?? [])],
189
+ ...(audit
190
+ ? {
191
+ audit: {
192
+ relation: audit.relation,
193
+ ...(audit.via ? { via: audit.via } : {}),
194
+ ...(audit.advisories?.length
195
+ ? { advisories: audit.advisories.map(({ id, severity, summary }) => ({ id, severity, summary })) }
196
+ : {}),
197
+ },
198
+ }
199
+ : {}),
200
+ })),
130
201
  skipDuplicates: true,
131
202
  });
132
203
  }
133
204
  async findApprovedVersion(runId, ecosystem, name, version) {
134
205
  const approval = await this.db.registryApprovedVersion.findUnique({
135
206
  where: { runId_ecosystem_name_version: { runId, ecosystem, name, version } },
136
- select: { integrity: true },
207
+ select: { integrity: true, acceptedAdvisories: true, audit: true },
137
208
  });
138
209
  if (!approval)
139
210
  return null;
@@ -141,7 +212,15 @@ export class PrismaRegistryStore {
141
212
  where: { ecosystem_name_version: { ecosystem, name, version } },
142
213
  select: { downloadUrl: true },
143
214
  });
144
- return fact ? { integrity: approval.integrity, downloadUrl: fact.downloadUrl } : null;
215
+ const audit = parsePackageAuditVerdict(approval.audit);
216
+ return fact
217
+ ? {
218
+ integrity: approval.integrity,
219
+ downloadUrl: fact.downloadUrl,
220
+ acceptedAdvisories: approval.acceptedAdvisories,
221
+ ...(audit ? { audit } : {}),
222
+ }
223
+ : null;
145
224
  }
146
225
  async refusePlanVersions(runId, ecosystem, versions) {
147
226
  if (versions.length === 0)
@@ -165,4 +244,28 @@ export class PrismaRegistryStore {
165
244
  select: { code: true, reason: true, publishedAt: true },
166
245
  });
167
246
  }
247
+ async recordDependencyCacheLockHash(runId, lockHash, max) {
248
+ // One statement, so a concurrent seal or plan can never slip past a check.
249
+ await this.db.$executeRaw `
250
+ UPDATE "CodingProxySession"
251
+ SET "dependencyCacheLockHashes" = array_append("dependencyCacheLockHashes", ${lockHash})
252
+ WHERE "runId" = ${runId}
253
+ AND "dependencyCacheSealedAt" IS NULL
254
+ AND NOT (${lockHash} = ANY("dependencyCacheLockHashes"))
255
+ AND cardinality("dependencyCacheLockHashes") < ${max}`;
256
+ }
257
+ }
258
+ function fetchRecordOf(row) {
259
+ return {
260
+ runId: row.runId,
261
+ ecosystem: row.ecosystem,
262
+ name: row.name,
263
+ version: row.version ?? undefined,
264
+ filename: row.filename ?? undefined,
265
+ integrity: row.integrity ?? undefined,
266
+ sizeBytes: row.sizeBytes ?? undefined,
267
+ outcome: row.outcome,
268
+ reason: row.reason ?? undefined,
269
+ createdAt: row.createdAt,
270
+ };
168
271
  }