@wardby/cli 0.5.3 → 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 (763) hide show
  1. package/.env.example +33 -0
  2. package/README.md +25 -14
  3. package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
  4. package/dist/claude-coding-worker/context.d.ts +22 -0
  5. package/dist/claude-coding-worker/context.js +92 -0
  6. package/dist/claude-coding-worker/driver.d.ts +27 -3
  7. package/dist/claude-coding-worker/driver.js +161 -20
  8. package/dist/claude-coding-worker/main.js +34 -6
  9. package/dist/claude-coding-worker/sdk.js +25 -5
  10. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  11. package/dist/claude-coding-worker/tool-socket.js +111 -0
  12. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  13. package/dist/claude-coding-worker/transcript.js +77 -0
  14. package/dist/cli-help.d.ts +1 -1
  15. package/dist/cli-help.js +6 -2
  16. package/dist/cli-native-mode.d.ts +9 -0
  17. package/dist/cli-native-mode.js +20 -0
  18. package/dist/cli.d.ts +3 -1
  19. package/dist/cli.js +161 -11
  20. package/dist/coding/claude-context.d.ts +45 -0
  21. package/dist/coding/claude-context.js +434 -0
  22. package/dist/coding/continuation-wording.d.ts +35 -0
  23. package/dist/coding/continuation-wording.js +73 -0
  24. package/dist/coding/linked-issue-note.d.ts +23 -0
  25. package/dist/coding/linked-issue-note.js +47 -0
  26. package/dist/coding/merge-wording.d.ts +28 -0
  27. package/dist/coding/merge-wording.js +78 -0
  28. package/dist/coding/pr-description-note.d.ts +9 -0
  29. package/dist/coding/pr-description-note.js +32 -0
  30. package/dist/coding/profile.d.ts +50 -118
  31. package/dist/coding/profile.js +51 -4
  32. package/dist/coding/protected-path-wording.d.ts +8 -0
  33. package/dist/coding/protected-path-wording.js +1 -1
  34. package/dist/coding/protocol.d.ts +292 -270
  35. package/dist/coding/protocol.js +322 -15
  36. package/dist/coding/redact.d.ts +3 -0
  37. package/dist/coding/redact.js +12 -0
  38. package/dist/coding/registry/allowlist.d.ts +12 -0
  39. package/dist/coding/registry/allowlist.js +14 -1
  40. package/dist/coding/registry/audit-mode.d.ts +153 -0
  41. package/dist/coding/registry/audit-mode.js +304 -0
  42. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  43. package/dist/coding/registry/lockfile-shared.js +128 -0
  44. package/dist/coding/registry/lockfiles.js +1 -1
  45. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  46. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  47. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  48. package/dist/coding/registry/npm-lockfile.js +4 -6
  49. package/dist/coding/registry/npm.js +78 -8
  50. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  51. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  52. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  53. package/dist/coding/registry/pypi-plan.js +406 -0
  54. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  55. package/dist/coding/registry/pypi-requirements.js +155 -0
  56. package/dist/coding/registry/pypi.d.ts +3 -27
  57. package/dist/coding/registry/pypi.js +40 -154
  58. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  59. package/dist/coding/registry/refusal-hints.js +61 -0
  60. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  61. package/dist/coding/registry/refusal-wording.js +56 -0
  62. package/dist/coding/registry/report.d.ts +70 -8
  63. package/dist/coding/registry/report.js +112 -5
  64. package/dist/coding/registry/types.d.ts +58 -8
  65. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  66. package/dist/coding/registry/yarn-lockfile.js +367 -0
  67. package/dist/coding/services/catalog.d.ts +37 -351
  68. package/dist/coding/transcript/claude-code.d.ts +13 -0
  69. package/dist/coding/transcript/claude-code.js +273 -0
  70. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  71. package/dist/coding/transcript/download-protocol.js +18 -0
  72. package/dist/coding/transcript/format.d.ts +20 -0
  73. package/dist/coding/transcript/format.js +32 -0
  74. package/dist/coding/transcript/recorder.d.ts +51 -0
  75. package/dist/coding/transcript/recorder.js +225 -0
  76. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  77. package/dist/coding/transcript/resume/checkout.js +203 -0
  78. package/dist/coding/transcript/resume/command.d.ts +17 -0
  79. package/dist/coding/transcript/resume/command.js +176 -0
  80. package/dist/coding/transcript/resume/download.d.ts +20 -0
  81. package/dist/coding/transcript/resume/download.js +153 -0
  82. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  83. package/dist/coding/transcript/resume/launch.js +128 -0
  84. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  85. package/dist/coding/transcript/resume/session-file.js +79 -0
  86. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  87. package/dist/coding/transcript/resume/stand-in.js +49 -0
  88. package/dist/coding-worker/artifact.d.ts +16 -3
  89. package/dist/coding-worker/artifact.js +5 -3
  90. package/dist/coding-worker/debug-trace.d.ts +6 -5
  91. package/dist/coding-worker/debug-trace.js +13 -18
  92. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  93. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  94. package/dist/coding-worker/driver.d.ts +4 -3
  95. package/dist/coding-worker/driver.js +118 -38
  96. package/dist/coding-worker/errors.d.ts +1 -0
  97. package/dist/coding-worker/errors.js +32 -0
  98. package/dist/coding-worker/sdk.d.ts +6 -0
  99. package/dist/coding-worker/sdk.js +1 -0
  100. package/dist/coding-worker/skills.d.ts +23 -0
  101. package/dist/coding-worker/skills.js +117 -0
  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 +13 -0
  105. package/dist/config/dependency-cache.d.ts +23 -0
  106. package/dist/config/dependency-cache.js +32 -0
  107. package/dist/config/github-allowed-accounts.d.ts +15 -0
  108. package/dist/config/github-allowed-accounts.js +36 -0
  109. package/dist/config/low-power.d.ts +12 -0
  110. package/dist/config/low-power.js +18 -0
  111. package/dist/config/mobile.d.ts +12 -0
  112. package/dist/config/mobile.js +18 -0
  113. package/dist/config/providers.d.ts +65 -3
  114. package/dist/config/providers.js +147 -11
  115. package/dist/config/test-simulators.d.ts +82 -0
  116. package/dist/config/test-simulators.js +305 -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-queue.d.ts +2 -1
  130. package/dist/core/coding-queue.js +7 -0
  131. package/dist/core/cron.d.ts +19 -1
  132. package/dist/core/cron.js +17 -0
  133. package/dist/core/datastores.js +1 -1
  134. package/dist/core/db.d.ts +16 -6
  135. package/dist/core/db.js +12 -10
  136. package/dist/core/deferred-coding.d.ts +14 -0
  137. package/dist/core/deferred-coding.js +62 -0
  138. package/dist/core/delegation-child.d.ts +25 -0
  139. package/dist/core/delegation-child.js +37 -0
  140. package/dist/core/dispatch.d.ts +53 -0
  141. package/dist/core/dispatch.js +167 -57
  142. package/dist/core/engine-native.js +10 -6
  143. package/dist/core/error-code.d.ts +38 -0
  144. package/dist/core/error-code.js +168 -0
  145. package/dist/core/grants.d.ts +19 -6
  146. package/dist/core/grants.js +55 -6
  147. package/dist/core/host-events.d.ts +67 -5
  148. package/dist/core/host-events.js +571 -37
  149. package/dist/core/host-status.d.ts +85 -3
  150. package/dist/core/host-status.js +298 -20
  151. package/dist/core/issue-bridge.d.ts +50 -6
  152. package/dist/core/issue-bridge.js +151 -20
  153. package/dist/core/issue-events.d.ts +1 -1
  154. package/dist/core/issue-events.js +16 -11
  155. package/dist/core/issue-status.d.ts +1 -1
  156. package/dist/core/issue-status.js +68 -29
  157. package/dist/core/logger.d.ts +5 -0
  158. package/dist/core/logger.js +14 -1
  159. package/dist/core/lost-run-children.d.ts +6 -0
  160. package/dist/core/lost-run-children.js +32 -0
  161. package/dist/core/mark-ready.d.ts +34 -0
  162. package/dist/core/mark-ready.js +152 -0
  163. package/dist/core/markdown-code.d.ts +8 -0
  164. package/dist/core/markdown-code.js +107 -0
  165. package/dist/core/memory-tools.js +7 -0
  166. package/dist/core/merge-order-check.d.ts +130 -0
  167. package/dist/core/merge-order-check.js +343 -0
  168. package/dist/core/notification-dispatcher.d.ts +70 -0
  169. package/dist/core/notification-dispatcher.js +368 -0
  170. package/dist/core/notification-templates.d.ts +19 -0
  171. package/dist/core/notification-templates.js +139 -0
  172. package/dist/core/notifications.d.ts +10 -0
  173. package/dist/core/notifications.js +38 -0
  174. package/dist/core/pg-auth.d.ts +22 -0
  175. package/dist/core/pg-auth.js +152 -0
  176. package/dist/core/power-composition.d.ts +16 -0
  177. package/dist/core/power-composition.js +37 -0
  178. package/dist/core/power-idle.d.ts +14 -0
  179. package/dist/core/power-idle.js +30 -0
  180. package/dist/core/power.d.ts +71 -0
  181. package/dist/core/power.js +202 -0
  182. package/dist/core/pull-request-state-sync.js +2 -2
  183. package/dist/core/reconciler.d.ts +8 -5
  184. package/dist/core/reconciler.js +37 -6
  185. package/dist/core/related-pull-requests.d.ts +59 -7
  186. package/dist/core/related-pull-requests.js +140 -25
  187. package/dist/core/reply-parts.d.ts +21 -0
  188. package/dist/core/reply-parts.js +73 -0
  189. package/dist/core/repo-access.d.ts +15 -0
  190. package/dist/core/repo-access.js +66 -0
  191. package/dist/core/review-fix.d.ts +38 -1
  192. package/dist/core/review-fix.js +209 -7
  193. package/dist/core/review-host-checks.d.ts +1 -1
  194. package/dist/core/review-host-tools.d.ts +23 -0
  195. package/dist/core/review-host-tools.js +156 -14
  196. package/dist/core/review-reads.d.ts +55 -0
  197. package/dist/core/review-reads.js +233 -0
  198. package/dist/core/run-status.d.ts +12 -0
  199. package/dist/core/run-status.js +12 -0
  200. package/dist/core/runner.d.ts +384 -5
  201. package/dist/core/runner.js +1244 -372
  202. package/dist/core/schedule-start.d.ts +12 -0
  203. package/dist/core/schedule-start.js +14 -0
  204. package/dist/core/secret-broker-config.d.ts +39 -0
  205. package/dist/core/secret-broker-config.js +112 -0
  206. package/dist/core/secret-guard.d.ts +46 -0
  207. package/dist/core/secret-guard.js +104 -0
  208. package/dist/core/secret-guarded-stores.d.ts +12 -0
  209. package/dist/core/secret-guarded-stores.js +41 -0
  210. package/dist/core/secret-spans.d.ts +50 -0
  211. package/dist/core/secret-spans.js +94 -0
  212. package/dist/core/secrets.d.ts +39 -4
  213. package/dist/core/secrets.js +148 -40
  214. package/dist/core/stop-run.d.ts +46 -0
  215. package/dist/core/stop-run.js +61 -0
  216. package/dist/core/workflow-event-recorder.d.ts +14 -0
  217. package/dist/core/workflow-event-recorder.js +120 -0
  218. package/dist/core/workflow-events.d.ts +94 -0
  219. package/dist/core/workflow-events.js +48 -0
  220. package/dist/core/workflow-run-events.d.ts +18 -0
  221. package/dist/core/workflow-run-events.js +75 -0
  222. package/dist/core/zod-json-schema.d.ts +4 -0
  223. package/dist/core/zod-json-schema.js +39 -0
  224. package/dist/core/zod3-window.d.ts +35 -0
  225. package/dist/core/zod3-window.js +124 -0
  226. package/dist/generated/prisma/browser.d.ts +92 -3
  227. package/dist/generated/prisma/client.d.ts +92 -3
  228. package/dist/generated/prisma/commonInputTypes.d.ts +364 -54
  229. package/dist/generated/prisma/enums.d.ts +37 -0
  230. package/dist/generated/prisma/enums.js +31 -0
  231. package/dist/generated/prisma/internal/class.d.ts +132 -0
  232. package/dist/generated/prisma/internal/class.js +4 -4
  233. package/dist/generated/prisma/internal/prismaNamespace.d.ts +1332 -142
  234. package/dist/generated/prisma/internal/prismaNamespace.js +227 -5
  235. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +234 -0
  236. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +227 -5
  237. package/dist/generated/prisma/models/Agent.d.ts +464 -7
  238. package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
  239. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +301 -1
  240. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  241. package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
  242. package/dist/generated/prisma/models/CodingRun.d.ts +1841 -1
  243. package/dist/generated/prisma/models/DeferredReview.d.ts +78 -1
  244. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  245. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  246. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  247. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  248. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +1713 -0
  249. package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
  250. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1551 -0
  251. package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
  252. package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
  253. package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
  254. package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
  255. package/dist/generated/prisma/models/NotificationChannel.js +1 -0
  256. package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
  257. package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
  258. package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
  259. package/dist/generated/prisma/models/NotificationThread.js +1 -0
  260. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  261. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  262. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  263. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  264. package/dist/generated/prisma/models/Run.d.ts +1619 -58
  265. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  266. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  267. package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
  268. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  269. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  270. package/dist/generated/prisma/models/Secret.d.ts +37 -1
  271. package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
  272. package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
  273. package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
  274. package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
  275. package/dist/generated/prisma/models.d.ts +12 -0
  276. package/dist/help/build.js +4 -2
  277. package/dist/help/catalog.d.ts +1 -1
  278. package/dist/help/catalog.js +31 -6
  279. package/dist/help-index.json +2584 -146
  280. package/dist/import/create.js +49 -3
  281. package/dist/import/neutral-schema.d.ts +50 -277
  282. package/dist/import/neutral-schema.js +7 -4
  283. package/dist/knowledge/check.d.ts +1 -1
  284. package/dist/knowledge/cli.d.ts +11 -1
  285. package/dist/knowledge/cli.js +37 -4
  286. package/dist/knowledge/concept.d.ts +3 -19
  287. package/dist/knowledge/location.d.ts +31 -0
  288. package/dist/knowledge/location.js +78 -0
  289. package/dist/mcp/auth/access.d.ts +11 -2
  290. package/dist/mcp/auth/access.js +15 -1
  291. package/dist/mcp/auth/ownership.d.ts +7 -7
  292. package/dist/mcp/auth/repo-authorization.js +14 -0
  293. package/dist/mcp/auth/resource-server.d.ts +2 -1
  294. package/dist/mcp/auth/resource-server.js +7 -2
  295. package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
  296. package/dist/mcp/auth/self-hosted/browser.js +19 -6
  297. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  298. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  299. package/dist/mcp/context.d.ts +6 -0
  300. package/dist/mcp/host-events/github-ingress.d.ts +25 -1
  301. package/dist/mcp/host-events/github-ingress.js +70 -1
  302. package/dist/mcp/index.d.ts +19 -0
  303. package/dist/mcp/index.js +117 -20
  304. package/dist/mcp/server.d.ts +13 -0
  305. package/dist/mcp/server.js +33 -14
  306. package/dist/mcp/tools/agents.d.ts +4 -0
  307. package/dist/mcp/tools/agents.js +277 -24
  308. package/dist/mcp/tools/datastore.js +17 -8
  309. package/dist/mcp/tools/grants.js +9 -3
  310. package/dist/mcp/tools/memory.js +11 -1
  311. package/dist/mcp/tools/notification-channels.d.ts +2 -0
  312. package/dist/mcp/tools/notification-channels.js +293 -0
  313. package/dist/mcp/tools/packages.d.ts +2 -0
  314. package/dist/mcp/tools/packages.js +195 -0
  315. package/dist/mcp/tools/power.d.ts +2 -0
  316. package/dist/mcp/tools/power.js +77 -0
  317. package/dist/mcp/tools/repositories.js +18 -5
  318. package/dist/mcp/tools/run-access.d.ts +16 -0
  319. package/dist/mcp/tools/run-access.js +25 -0
  320. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  321. package/dist/mcp/tools/run-transcript-download.js +129 -0
  322. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  323. package/dist/mcp/tools/run-transcript.js +70 -0
  324. package/dist/mcp/tools/runs.d.ts +0 -6
  325. package/dist/mcp/tools/runs.js +41 -14
  326. package/dist/mcp/tools/scheduling.js +3 -1
  327. package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
  328. package/dist/mcp/tools/secret-broker-compat.js +23 -0
  329. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
  330. package/dist/mcp/tools/secret-elicitation-form.js +205 -10
  331. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  332. package/dist/mcp/tools/secret-elicitation-server.js +10 -54
  333. package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
  334. package/dist/mcp/tools/secret-elicitation.js +110 -12
  335. package/dist/mcp/tools/secrets.js +186 -9
  336. package/dist/mcp/tools/stop-run.d.ts +2 -0
  337. package/dist/mcp/tools/stop-run.js +82 -0
  338. package/dist/mcp/tools/subagents.js +2 -2
  339. package/dist/mcp/tools/tools.d.ts +2 -2
  340. package/dist/mcp/tools/tools.js +47 -11
  341. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  342. package/dist/mcp/transport/stdio-link-host.js +67 -0
  343. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  344. package/dist/mcp/transport/streamable-http.js +41 -1
  345. package/dist/native-worker/composition.d.ts +23 -0
  346. package/dist/native-worker/composition.js +77 -0
  347. package/dist/native-worker/docker-isolation.d.ts +65 -0
  348. package/dist/native-worker/docker-isolation.js +183 -0
  349. package/dist/native-worker/docker-launcher.d.ts +110 -0
  350. package/dist/native-worker/docker-launcher.js +297 -0
  351. package/dist/native-worker/gateway-server.d.ts +77 -0
  352. package/dist/native-worker/gateway-server.js +412 -0
  353. package/dist/native-worker/gateway.d.ts +70 -0
  354. package/dist/native-worker/gateway.js +263 -0
  355. package/dist/native-worker/http-server.d.ts +24 -0
  356. package/dist/native-worker/http-server.js +113 -0
  357. package/dist/native-worker/http-transport.d.ts +17 -0
  358. package/dist/native-worker/http-transport.js +88 -0
  359. package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
  360. package/dist/native-worker/kubernetes-isolation.js +218 -0
  361. package/dist/native-worker/kubernetes-launcher.d.ts +106 -0
  362. package/dist/native-worker/kubernetes-launcher.js +375 -0
  363. package/dist/native-worker/launch.d.ts +62 -0
  364. package/dist/native-worker/launch.js +49 -0
  365. package/dist/native-worker/ledger.d.ts +125 -0
  366. package/dist/native-worker/ledger.js +245 -0
  367. package/dist/native-worker/loopback.d.ts +12 -0
  368. package/dist/native-worker/loopback.js +44 -0
  369. package/dist/native-worker/main.d.ts +8 -0
  370. package/dist/native-worker/main.js +85 -0
  371. package/dist/native-worker/protocol.d.ts +296 -0
  372. package/dist/native-worker/protocol.js +246 -0
  373. package/dist/native-worker/sandbox-executor.d.ts +83 -0
  374. package/dist/native-worker/sandbox-executor.js +284 -0
  375. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  376. package/dist/native-worker/stderr-redaction.js +237 -0
  377. package/dist/native-worker/stdio.d.ts +29 -0
  378. package/dist/native-worker/stdio.js +189 -0
  379. package/dist/native-worker/warm-delivery.d.ts +16 -0
  380. package/dist/native-worker/warm-delivery.js +33 -0
  381. package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
  382. package/dist/native-worker/warm-pool-ledger.js +73 -0
  383. package/dist/native-worker/warm-pool.d.ts +107 -0
  384. package/dist/native-worker/warm-pool.js +283 -0
  385. package/dist/native-worker/worker.d.ts +17 -0
  386. package/dist/native-worker/worker.js +141 -0
  387. package/dist/observability/metrics.js +6 -1
  388. package/dist/providers/auth/authorization-server.d.ts +3 -0
  389. package/dist/providers/auth/index.js +2 -0
  390. package/dist/providers/auth/self-hosted.d.ts +14 -2
  391. package/dist/providers/auth/self-hosted.js +54 -4
  392. package/dist/providers/chat/fake.d.ts +46 -0
  393. package/dist/providers/chat/fake.js +39 -0
  394. package/dist/providers/chat/index.d.ts +4 -0
  395. package/dist/providers/chat/index.js +8 -0
  396. package/dist/providers/chat/slack.d.ts +37 -0
  397. package/dist/providers/chat/slack.js +105 -0
  398. package/dist/providers/chat/types.d.ts +42 -0
  399. package/dist/providers/chat/types.js +19 -0
  400. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  401. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  402. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  403. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  404. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  405. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  406. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  407. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  408. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  409. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  410. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  411. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  412. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  413. package/dist/providers/coding-proxy/hold.js +86 -0
  414. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  415. package/dist/providers/coding-proxy/interrupted.js +104 -0
  416. package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
  417. package/dist/providers/coding-proxy/memory-ledger.js +84 -8
  418. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  419. package/dist/providers/coding-proxy/metering.js +27 -4
  420. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
  421. package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
  422. package/dist/providers/coding-proxy/proxy.d.ts +14 -1
  423. package/dist/providers/coding-proxy/proxy.js +166 -14
  424. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  425. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  426. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  427. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  428. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  429. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  430. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  431. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  432. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  433. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  434. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  435. package/dist/providers/coding-proxy/registry/service.js +579 -112
  436. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  437. package/dist/providers/coding-proxy/registry/store.js +54 -1
  438. package/dist/providers/coding-proxy/runtime.d.ts +4 -0
  439. package/dist/providers/coding-proxy/runtime.js +78 -16
  440. package/dist/providers/coding-proxy/server.d.ts +6 -1
  441. package/dist/providers/coding-proxy/server.js +45 -1
  442. package/dist/providers/coding-proxy/types.d.ts +65 -1
  443. package/dist/providers/datastore/types.d.ts +5 -0
  444. package/dist/providers/engine/types.d.ts +36 -2
  445. package/dist/providers/engine/types.js +39 -0
  446. package/dist/providers/executor/composition.d.ts +31 -1
  447. package/dist/providers/executor/composition.js +81 -8
  448. package/dist/providers/executor/container.d.ts +385 -9
  449. package/dist/providers/executor/container.js +1234 -99
  450. package/dist/providers/executor/dbos-status.d.ts +31 -0
  451. package/dist/providers/executor/dbos-status.js +64 -0
  452. package/dist/providers/executor/dbos.d.ts +91 -0
  453. package/dist/providers/executor/dbos.js +319 -26
  454. package/dist/providers/executor/deferred.d.ts +44 -0
  455. package/dist/providers/executor/deferred.js +100 -0
  456. package/dist/providers/executor/in-process.d.ts +9 -1
  457. package/dist/providers/executor/in-process.js +14 -4
  458. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  459. package/dist/providers/executor/linked-issue-reader.js +30 -0
  460. package/dist/providers/executor/routing.d.ts +39 -10
  461. package/dist/providers/executor/routing.js +77 -32
  462. package/dist/providers/executor/types.d.ts +25 -0
  463. package/dist/providers/index.d.ts +2 -1
  464. package/dist/providers/issue-tracker/types.d.ts +17 -0
  465. package/dist/providers/issue-tracker/types.js +39 -1
  466. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  467. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  468. package/dist/providers/jobs/docker-isolation.d.ts +8 -0
  469. package/dist/providers/jobs/docker-isolation.js +17 -0
  470. package/dist/providers/jobs/docker.d.ts +1 -0
  471. package/dist/providers/jobs/docker.js +29 -4
  472. package/dist/providers/jobs/fake-kubernetes-api.d.ts +23 -2
  473. package/dist/providers/jobs/fake-kubernetes-api.js +45 -1
  474. package/dist/providers/jobs/kubernetes-api.d.ts +25 -1
  475. package/dist/providers/jobs/kubernetes-api.js +17 -0
  476. package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
  477. package/dist/providers/jobs/kubernetes-client.js +61 -3
  478. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
  479. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
  480. package/dist/providers/jobs/kubernetes-isolation.d.ts +5 -1
  481. package/dist/providers/jobs/kubernetes-isolation.js +23 -1
  482. package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
  483. package/dist/providers/jobs/kubernetes-platform.js +38 -1
  484. package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
  485. package/dist/providers/jobs/kubernetes-preflight.js +4 -2
  486. package/dist/providers/jobs/kubernetes.d.ts +42 -2
  487. package/dist/providers/jobs/kubernetes.js +178 -19
  488. package/dist/providers/jobs/metadata-probes.d.ts +11 -0
  489. package/dist/providers/jobs/metadata-probes.js +13 -0
  490. package/dist/providers/jobs/types.d.ts +42 -0
  491. package/dist/providers/jobs/types.js +13 -1
  492. package/dist/providers/llm/anthropic.js +5 -1
  493. package/dist/providers/llm/bedrock.d.ts +0 -12
  494. package/dist/providers/llm/bedrock.js +4 -0
  495. package/dist/providers/llm/claude-messages.d.ts +3 -1
  496. package/dist/providers/llm/claude-messages.js +4 -1
  497. package/dist/providers/llm/claude-provider.d.ts +2 -2
  498. package/dist/providers/llm/claude-provider.js +2 -2
  499. package/dist/providers/llm/openai.d.ts +2 -2
  500. package/dist/providers/llm/openai.js +6 -2
  501. package/dist/providers/llm/routing.d.ts +2 -2
  502. package/dist/providers/llm/routing.js +2 -2
  503. package/dist/providers/llm/types.d.ts +12 -2
  504. package/dist/providers/review-host/github-events.d.ts +9 -1
  505. package/dist/providers/review-host/github-events.js +34 -12
  506. package/dist/providers/review-host/github.d.ts +39 -2
  507. package/dist/providers/review-host/github.js +274 -29
  508. package/dist/providers/review-host/local.d.ts +8 -4
  509. package/dist/providers/review-host/local.js +49 -31
  510. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  511. package/dist/providers/review-host/patch-pages.js +176 -0
  512. package/dist/providers/review-host/review-format.d.ts +19 -1
  513. package/dist/providers/review-host/review-format.js +38 -7
  514. package/dist/providers/review-host/types.d.ts +157 -2
  515. package/dist/providers/review-host/types.js +8 -0
  516. package/dist/providers/storage/gcs.d.ts +63 -0
  517. package/dist/providers/storage/gcs.js +69 -0
  518. package/dist/providers/storage/index.d.ts +15 -0
  519. package/dist/providers/storage/index.js +14 -0
  520. package/dist/providers/storage/local.d.ts +24 -0
  521. package/dist/providers/storage/local.js +92 -0
  522. package/dist/providers/storage/meter.d.ts +14 -0
  523. package/dist/providers/storage/meter.js +34 -0
  524. package/dist/providers/storage/s3.d.ts +41 -0
  525. package/dist/providers/storage/s3.js +107 -0
  526. package/dist/providers/storage/types.d.ts +37 -3
  527. package/dist/providers/storage/types.js +21 -4
  528. package/dist/providers/vcs/git.d.ts +33 -2
  529. package/dist/providers/vcs/git.js +324 -22
  530. package/dist/providers/vcs/github-remote.d.ts +26 -3
  531. package/dist/providers/vcs/github-remote.js +124 -14
  532. package/dist/providers/vcs/github.d.ts +246 -12
  533. package/dist/providers/vcs/github.js +521 -61
  534. package/dist/providers/vcs/index.js +8 -1
  535. package/dist/providers/vcs/pr-description.d.ts +127 -0
  536. package/dist/providers/vcs/pr-description.js +270 -0
  537. package/dist/providers/vcs/remote.d.ts +33 -1
  538. package/dist/providers/vcs/routing.d.ts +4 -2
  539. package/dist/providers/vcs/routing.js +6 -0
  540. package/dist/providers/vcs/types.d.ts +80 -3
  541. package/dist/quickstart/coding-seed.d.ts +21 -3
  542. package/dist/quickstart/coding-seed.js +283 -3
  543. package/dist/quickstart/images.d.ts +2 -0
  544. package/dist/quickstart/images.js +7 -1
  545. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  546. package/dist/quickstart/reviewer-prompt.js +6 -6
  547. package/dist/quickstart-images.json +1 -1
  548. package/dist/sandbox/brokered-fetch.d.ts +23 -0
  549. package/dist/sandbox/brokered-fetch.js +37 -0
  550. package/dist/sandbox/generated/zod.bundle.js +62 -1
  551. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  552. package/dist/sandbox/host-functions.d.ts +35 -0
  553. package/dist/sandbox/host-functions.js +150 -91
  554. package/dist/sandbox/prelude.js +7 -1
  555. package/dist/sandbox/run-in-sandbox.d.ts +19 -0
  556. package/dist/sandbox/run-in-sandbox.js +28 -10
  557. package/dist/sandbox/safe-fetch.d.ts +2 -0
  558. package/dist/sandbox/safe-fetch.js +3 -1
  559. package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
  560. package/dist/sandbox/secret-broker-sigv4.js +49 -0
  561. package/dist/sandbox/secret-broker.d.ts +34 -0
  562. package/dist/sandbox/secret-broker.js +161 -0
  563. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  564. package/dist/sandbox/user-tool.d.ts +14 -0
  565. package/dist/sandbox/user-tool.js +32 -0
  566. package/dist/sandbox/zod-params.d.ts +37 -5
  567. package/dist/sandbox/zod-params.js +181 -26
  568. package/dist/serve.js +25 -0
  569. package/dist/viewer/api-schema.d.ts +372 -2454
  570. package/dist/viewer/api-schema.js +29 -0
  571. package/dist/viewer/build-schemas.js +10 -3
  572. package/dist/viewer/event-bus.d.ts +6 -0
  573. package/dist/viewer/event-bus.js +16 -7
  574. package/dist/viewer/graph.d.ts +5 -2
  575. package/dist/viewer/graph.js +7 -2
  576. package/dist/viewer/http.d.ts +0 -1
  577. package/dist/viewer/http.js +2 -2
  578. package/dist/viewer/infra.js +25 -2
  579. package/dist/viewer/limits.d.ts +4 -0
  580. package/dist/viewer/limits.js +4 -0
  581. package/dist/viewer/openapi.d.ts +15 -0
  582. package/dist/viewer/openapi.js +170 -0
  583. package/dist/wardby-bin.js +10 -0
  584. package/docs/README.md +7 -0
  585. package/docs/agent-recipes.md +114 -27
  586. package/docs/architecture-runtime.md +16 -1
  587. package/docs/code-review-agents.md +689 -45
  588. package/docs/coding-agent-setup.md +602 -12
  589. package/docs/coding-packages.md +1037 -92
  590. package/docs/coding-services.md +30 -13
  591. package/docs/coding-worker-byo-images.md +218 -6
  592. package/docs/coding-worker-isolation.md +173 -44
  593. package/docs/getting-started-gke.md +332 -129
  594. package/docs/getting-started-identity-provider.md +31 -11
  595. package/docs/getting-started.md +14 -4
  596. package/docs/jira-agents.md +22 -9
  597. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  598. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  599. package/docs/knowledge/delegation-admission-slots.md +52 -0
  600. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  601. package/docs/knowledge/import-rename-target.md +52 -0
  602. package/docs/knowledge/index.md +57 -0
  603. package/docs/knowledge/log.md +9 -0
  604. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  605. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  606. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  607. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  608. package/docs/knowledge/overview-cli.md +74 -0
  609. package/docs/knowledge/overview-coding-proxy.md +72 -0
  610. package/docs/knowledge/overview-coding.md +72 -0
  611. package/docs/knowledge/overview-config.md +60 -0
  612. package/docs/knowledge/overview-core.md +72 -0
  613. package/docs/knowledge/overview-deploy.md +83 -0
  614. package/docs/knowledge/overview-mcp.md +61 -0
  615. package/docs/knowledge/overview-prisma.md +72 -0
  616. package/docs/knowledge/overview-providers.md +89 -0
  617. package/docs/knowledge/overview-sandbox.md +83 -0
  618. package/docs/knowledge/overview-surfaces.md +83 -0
  619. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  620. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  621. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  622. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  623. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  624. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  625. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  626. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  627. package/docs/knowledge/warm-input-publication.md +30 -0
  628. package/docs/knowledge/workspace-staging-failure.md +54 -0
  629. package/docs/knowledge.md +54 -14
  630. package/docs/native-sandbox.md +731 -0
  631. package/docs/observability.md +4 -0
  632. package/docs/release-verification.md +9 -0
  633. package/docs/security-deployment.md +146 -14
  634. package/docs/slack-notifications.md +268 -0
  635. package/docs/tool-secrets.md +284 -0
  636. package/docs/viewer-api.md +46 -5
  637. package/docs/viewer-api.openapi.yml +1404 -0
  638. package/help/admin-viewer.md +29 -3
  639. package/help/agent-recipes.md +27 -0
  640. package/help/architecture-agent.md +11 -6
  641. package/help/brokered-secrets.md +79 -0
  642. package/help/build-claude-code-image.md +131 -0
  643. package/help/build-worker-image.md +6 -7
  644. package/help/builder-agent.md +19 -6
  645. package/help/code-review-agents.md +243 -10
  646. package/help/coding-packages.md +156 -6
  647. package/help/cost-attribution.md +9 -5
  648. package/help/creating-agents.md +14 -1
  649. package/help/dependency-cache.md +143 -0
  650. package/help/deploy-gke.md +23 -9
  651. package/help/deployment-targets.md +25 -14
  652. package/help/errors/budget-exhausted.md +187 -0
  653. package/help/errors/budget-group-exhausted.md +5 -1
  654. package/help/errors/coding-provider-not-configured.md +2 -2
  655. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  656. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  657. package/help/errors/continuation-closed.md +9 -12
  658. package/help/errors/database-auth-invalid.md +28 -0
  659. package/help/errors/delegation-conflict.md +24 -0
  660. package/help/errors/file-list-truncated.md +45 -0
  661. package/help/errors/full-read-required.md +49 -0
  662. package/help/errors/github-account-not-allowed.md +29 -0
  663. package/help/errors/graph-incomplete.md +43 -0
  664. package/help/errors/graph-limit.md +43 -0
  665. package/help/errors/low-power-disabled.md +29 -0
  666. package/help/errors/low-power-scale-forbidden.md +35 -0
  667. package/help/errors/low-power-wake-timeout.md +30 -0
  668. package/help/errors/merge-conflict.md +49 -0
  669. package/help/errors/mobile-disabled.md +31 -0
  670. package/help/errors/native-sandbox-capacity.md +22 -0
  671. package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
  672. package/help/errors/native-sandbox-docker-failed.md +20 -0
  673. package/help/errors/native-sandbox-gateway-error.md +20 -0
  674. package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
  675. package/help/errors/native-sandbox-image-not-pinned.md +19 -0
  676. package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
  677. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  678. package/help/errors/native-sandbox-network-unenforced.md +22 -0
  679. package/help/errors/native-sandbox-requires-catalog.md +31 -0
  680. package/help/errors/native-sandbox-unavailable.md +19 -0
  681. package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
  682. package/help/errors/native-sandbox-worker-exited.md +21 -0
  683. package/help/errors/native-sandbox-worker-lost.md +20 -0
  684. package/help/errors/native-sandbox-worker-unready.md +22 -0
  685. package/help/errors/package-not-allowed-pending.md +52 -0
  686. package/help/errors/package-not-allowed.md +51 -0
  687. package/help/errors/package-refusals.md +43 -0
  688. package/help/errors/patch-cursor-malformed.md +31 -0
  689. package/help/errors/run-lost.md +39 -0
  690. package/help/errors/run-transcript-download.md +44 -0
  691. package/help/errors/secret-broker-body-invalid.md +26 -0
  692. package/help/errors/secret-broker-changed.md +20 -0
  693. package/help/errors/secret-broker-config-invalid.md +30 -0
  694. package/help/errors/secret-broker-conflict.md +27 -0
  695. package/help/errors/secret-broker-destination-denied.md +28 -0
  696. package/help/errors/secret-broker-value-invalid.md +28 -0
  697. package/help/errors/secret-brokered.md +24 -0
  698. package/help/errors/secret-in-value.md +69 -0
  699. package/help/errors/secret-not-brokered.md +25 -0
  700. package/help/errors/slack-auth-failed.md +48 -0
  701. package/help/errors/slack-channel-unreachable.md +39 -0
  702. package/help/errors/slack-not-configured.md +33 -0
  703. package/help/errors/target-merge.md +40 -0
  704. package/help/fix-merge-conflicts.md +73 -0
  705. package/help/getting-started.md +4 -5
  706. package/help/github-app-setup.md +132 -0
  707. package/help/github.md +40 -1
  708. package/help/identity-and-access.md +7 -1
  709. package/help/jira.md +23 -6
  710. package/help/knowledge.md +16 -7
  711. package/help/local-repositories.md +3 -4
  712. package/help/low-power-mode.md +131 -0
  713. package/help/merge-order-check.md +122 -0
  714. package/help/mobile-app.md +54 -0
  715. package/help/native-capabilities.md +29 -1
  716. package/help/native-sandbox.md +150 -0
  717. package/help/observability.md +8 -0
  718. package/help/operating-agents.md +5 -0
  719. package/help/package-audit-mode.md +91 -0
  720. package/help/related-pull-requests.md +80 -16
  721. package/help/repo-instructions-and-skills.md +91 -0
  722. package/help/resume-runs-locally.md +131 -0
  723. package/help/review-fix-rounds.md +43 -1
  724. package/help/sharing-agents.md +59 -0
  725. package/help/slack-notifications.md +76 -0
  726. package/help/status-comments.md +31 -0
  727. package/help/stop-run.md +58 -0
  728. package/help/troubleshooting/budgets.md +28 -0
  729. package/help/troubleshooting/coding-workers.md +99 -7
  730. package/package.json +27 -13
  731. package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
  732. package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
  733. package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
  734. package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
  735. package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
  736. package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
  737. package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
  738. package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
  739. package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
  740. package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
  741. package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
  742. package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
  743. package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
  744. package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
  745. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  746. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  747. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  748. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  749. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  750. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  751. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  752. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  753. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  754. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  755. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  756. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  757. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  758. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  759. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  760. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  761. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  762. package/prisma/schema.prisma +631 -146
  763. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -12,6 +12,16 @@ export declare const HOST_ACCOUNT_PROVIDERS: readonly ReviewHostProvider[];
12
12
  export type ReviewVerdict = "APPROVE" | "CHANGES_REQUESTED" | "COMMENT";
13
13
  export type CheckConclusion = "success" | "failure" | "neutral";
14
14
  export type CommentSide = "LEFT" | "RIGHT";
15
+ /**
16
+ * Where a file's patch is in a repo_pr_read result:
17
+ * - complete: the whole patch is in this result;
18
+ * - partial: one part, starting at patchOffset; the rest comes with nextPatchCursor;
19
+ * - later_page: not in this result; call again with nextPatchCursor;
20
+ * - earlier_page: delivered by an earlier call of the same cursor chain;
21
+ * - unavailable: the host has no patch for it (too large, binary): read it with repo_read_file;
22
+ * - empty: nothing to show (no line changes, a pure rename).
23
+ */
24
+ export type PatchStatus = "complete" | "partial" | "later_page" | "earlier_page" | "unavailable" | "empty";
15
25
  export interface PullRequestFileView {
16
26
  filename: string;
17
27
  status: string;
@@ -19,7 +29,18 @@ export interface PullRequestFileView {
19
29
  deletions: number;
20
30
  previousFilename?: string;
21
31
  patch: string;
32
+ /** True for later_page, unavailable, and a partial part that the next page continues. */
22
33
  patchTruncated: boolean;
34
+ patchStatus: PatchStatus;
35
+ /** Where this part starts in the file's patch; only on partial. */
36
+ patchOffset?: number;
37
+ /** Only on partial: true when the next page continues this file, false when this part is its last. */
38
+ patchContinues?: boolean;
39
+ }
40
+ /** A patchCursor that is not one this deployment issued, or one for a head or compare that has moved on. */
41
+ export declare class PatchCursorError extends Error {
42
+ readonly reason: "malformed" | "stale";
43
+ constructor(reason: "malformed" | "stale");
23
44
  }
24
45
  /** One of this agent's own review threads that is still unresolved. */
25
46
  export interface ReviewThreadView {
@@ -71,6 +92,12 @@ export interface PullRequestView {
71
92
  htmlUrl: string;
72
93
  /** Head sha recorded in this agent's summary comment, if it reviewed before. */
73
94
  lastReviewedSha: string | null;
95
+ /**
96
+ * The latest head this agent reviewed after reading every file (a whole, uncut list of the
97
+ * pull request or a delta from an earlier covered head, every source/test/config file read),
98
+ * whatever the verdict. The only safe sinceSha for a re-review that may APPROVE.
99
+ */
100
+ lastCoveredSha: string | null;
74
101
  /** Set when `files` is the compare of `comparedFrom...headSha` rather than the whole PR. */
75
102
  comparedFrom: string | null;
76
103
  /**
@@ -80,10 +107,26 @@ export interface PullRequestView {
80
107
  */
81
108
  baseMergedSince: boolean;
82
109
  files: PullRequestFileView[];
110
+ /**
111
+ * False when `files` is cut: the host's listing stopped at its upper bound before every
112
+ * changed file (on GitHub, also a compare at its 300-file limit). repo_publish_review then
113
+ * refuses an APPROVE of this head with file_list_truncated.
114
+ */
115
+ fileListComplete: boolean;
116
+ /** No patch is left to page through and none is unavailable: with earlier pages, every patch was delivered. */
117
+ patchesComplete: boolean;
118
+ /** Files whose patch is not (fully) delivered yet: later_page, unavailable, or a partial part the next page continues; in review order. */
119
+ truncatedFiles: string[];
120
+ /** Pass as repo_pr_read's patchCursor for the next page; null when nothing is left to page. */
121
+ nextPatchCursor: string | null;
122
+ /** Estimate of files with patch content still to come after this page (a partial file counts once); a later_page file may turn out empty or unavailable once loaded. */
123
+ remainingPatchFiles: number;
83
124
  /** This agent's own unresolved review threads on the PR (the first 100 threads are searched). */
84
125
  openThreads: ReviewThreadView[];
85
126
  /** CI on headSha (check runs and commit statuses, minus wardby's own); absent on hosts that can't read CI. */
86
127
  ci?: CiView;
128
+ /** Only on a wardby pull request with a pending proposal in its description comment. */
129
+ descriptionProposal?: DescriptionProposalView;
87
130
  }
88
131
  export interface PullRequestHead {
89
132
  headSha: string;
@@ -120,6 +163,59 @@ export type FileReadResult = {
120
163
  kind: "not_found";
121
164
  path: string;
122
165
  };
166
+ /** One issue comment; author-written text, untrusted. */
167
+ export interface IssueCommentView {
168
+ author: string | null;
169
+ body: string;
170
+ createdAt: string;
171
+ /** The body was cut at the per-comment cap. */
172
+ truncated: boolean;
173
+ }
174
+ /** An issue as repo_issue_read shows it. Title, body, labels, and comments are untrusted text. */
175
+ export interface IssueView {
176
+ number: number;
177
+ title: string;
178
+ state: "open" | "closed";
179
+ body: string;
180
+ bodyTruncated: boolean;
181
+ labels: string[];
182
+ author: string | null;
183
+ url: string;
184
+ createdAt: string;
185
+ updatedAt: string;
186
+ /** The most recent comments, oldest first. */
187
+ comments: IssueCommentView[];
188
+ /** All comments on the issue, including any left out. */
189
+ totalComments: number;
190
+ /** Anything was cut: the body, a comment, or older comments left out. */
191
+ truncated: boolean;
192
+ }
193
+ /**
194
+ * wardby's proposed description on a pull request whose description wardby
195
+ * couldn't confirm as its own (from its description comment). `current`: the
196
+ * proposal is for the head being read; `not_for_this_head`: it isn't yet;
197
+ * `unavailable`: the comments couldn't be read.
198
+ */
199
+ export type DescriptionProposalView = {
200
+ state: "current";
201
+ forHead: string;
202
+ runId?: string;
203
+ text: string;
204
+ truncated: boolean;
205
+ note: string;
206
+ } | {
207
+ state: "not_for_this_head" | "unavailable";
208
+ note: string;
209
+ };
210
+ export type IssueReadResult = ({
211
+ kind: "issue";
212
+ } & IssueView) | {
213
+ kind: "pull_request";
214
+ number: number;
215
+ } | {
216
+ kind: "not_found";
217
+ number: number;
218
+ };
123
219
  export interface FileListView {
124
220
  ref: string;
125
221
  count: number;
@@ -157,6 +253,11 @@ export interface PublishReviewInput {
157
253
  * unresolved threads on this PR are resolved; any other id is skipped.
158
254
  */
159
255
  resolveThreadIds?: string[];
256
+ /**
257
+ * headSha when this review read every file of it (see PullRequestView.lastCoveredSha); null or
258
+ * absent otherwise, and the host keeps the earlier covered head.
259
+ */
260
+ coveredSha?: string | null;
160
261
  }
161
262
  export type PublishReviewResult = {
162
263
  published: true;
@@ -207,12 +308,25 @@ export interface CompleteCheckInput {
207
308
  text?: string;
208
309
  detailsUrl?: string;
209
310
  }
311
+ export type UpsertNamedCheckInput = {
312
+ headSha: string;
313
+ /** The check's fixed name, e.g. MERGE_ORDER_CHECK_NAME ("wardby merge order"); identifies which run to update. */
314
+ name: string;
315
+ title: string;
316
+ summary: string;
317
+ } & ({
318
+ status: "in_progress";
319
+ } | {
320
+ status: "completed";
321
+ conclusion: "success" | "failure";
322
+ });
210
323
  /**
211
324
  * A user's effective permission on one repository, host-neutral and ranked
212
325
  * none < read < triage < write < maintain < admin. GitHub maps its
213
326
  * collaborator permission onto these directly; GitLab would map reporter ->
214
327
  * read, developer -> write, maintainer -> maintain, owner -> admin.
215
328
  */
329
+ export type AcknowledgeOutcome = "picked_up" | "refused";
216
330
  export type HostPermission = "none" | "read" | "triage" | "write" | "maintain" | "admin";
217
331
  export declare const HOST_PERMISSION_RANK: Readonly<Record<HostPermission, number>>;
218
332
  /** A host user, by its immutable numeric id (as text) and its current login. */
@@ -222,6 +336,8 @@ export interface HostUser {
222
336
  }
223
337
  export interface CodeReviewHost {
224
338
  readonly provider: ReviewHostProvider;
339
+ /** The GitHub App's owner account (always served; see WARDBY_GITHUB_ALLOWED_ACCOUNTS). Hosts without an App omit it. */
340
+ appOwnerLogin?(): Promise<string>;
225
341
  /**
226
342
  * The user's effective permission on `repository`, asked with the App's own
227
343
  * installation credential (never a user token). Answers only for the user
@@ -236,6 +352,7 @@ export interface CodeReviewHost {
236
352
  sinceSha?: string;
237
353
  maxPatchChars: number;
238
354
  agentMarker: string;
355
+ patchCursor?: string;
239
356
  }): Promise<PullRequestView>;
240
357
  pullRequestHead(repository: string, prNumber: number): Promise<PullRequestHead>;
241
358
  /** CI on one commit, excluding wardby's own checks. Never throws. Hosts that can't say leave it out. */
@@ -260,6 +377,11 @@ export interface CodeReviewHost {
260
377
  maxLines: number;
261
378
  }): Promise<FileReadResult>;
262
379
  listFiles(repository: string, ref: string | undefined, pathPrefix?: string): Promise<FileListView>;
380
+ /** An issue and its most recent comments, read-only. Hosts without issues (a local repository) leave it out. */
381
+ /** `comments: false` reads the issue alone (title, body, labels), without its comments. */
382
+ readIssue?(repository: string, number: number, opts?: {
383
+ comments?: boolean;
384
+ }): Promise<IssueReadResult>;
263
385
  publishReview(repository: string, input: PublishReviewInput): Promise<PublishReviewResult>;
264
386
  /** `id` identifies the new comment for editComment; a reply is an "inline" comment, anything else "conversation". */
265
387
  comment(repository: string, input: CommentInput): Promise<{
@@ -268,12 +390,41 @@ export interface CodeReviewHost {
268
390
  }>;
269
391
  /** Replaces the body of a comment the App wrote. */
270
392
  editComment(repository: string, input: EditCommentInput): Promise<void>;
271
- /** Marks a comment as picked up (GitHub: a 👀 reaction); a host without reactions may do nothing. */
272
- acknowledge(repository: string, target: CommentRef): Promise<void>;
393
+ /**
394
+ * Marks a comment as picked up (GitHub: a 👀 reaction), or as refused (😕)
395
+ * when its author can see the repository but lacks the access to start a
396
+ * run. A host without reactions may do nothing.
397
+ */
398
+ acknowledge(repository: string, target: CommentRef, outcome?: AcknowledgeOutcome): Promise<void>;
273
399
  startCheck(repository: string, input: StartCheckInput): Promise<{
274
400
  checkId: string;
275
401
  }>;
276
402
  completeCheck(repository: string, input: CompleteCheckInput): Promise<void>;
403
+ /**
404
+ * Creates or updates, by fixed name, a check run on one commit that isn't
405
+ * tied to a run's own startCheck/completeCheck lifecycle (e.g. the
406
+ * `wardby merge order` check, recomputed fresh and reposted on demand).
407
+ * Finds the one this App owns among the commit's check runs with that
408
+ * name and patches it; creates one when none exists. Hosts that can't
409
+ * post checks (e.g. a local repository) leave this out.
410
+ */
411
+ upsertNamedCheck?(repository: string, input: UpsertNamedCheckInput): Promise<void>;
412
+ /**
413
+ * This App's newest check run per name on one commit (names not found are absent).
414
+ * At most 10 names. Hosts that can't say leave it out.
415
+ */
416
+ readOwnChecks?(repository: string, headSha: string, names: string[]): Promise<Map<string, OwnCheckView>>;
417
+ /**
418
+ * Marks a draft pull request this App authored ready for review, only while it is
419
+ * open, a draft, at `expectedHeadSha`, and carrying `expectedMarkerRunId` in its
420
+ * description's run marker (mirrors replaceRelatedSection's expectedMarkerRunId).
421
+ * "skipped" covers every refusal.
422
+ */
423
+ markReadyForReview?(repository: string, prNumber: number, expectedHeadSha: string, expectedMarkerRunId: string): Promise<"marked" | "skipped">;
424
+ }
425
+ export interface OwnCheckView {
426
+ status: string;
427
+ conclusion: string | null;
277
428
  }
278
429
  export type ReviewHostErrorCode = "host_not_installed" | "host_permission_missing" | "host_api_error" | "host_invalid_response";
279
430
  export declare class ReviewHostError extends Error {
@@ -361,6 +512,10 @@ export type HostEvent = {
361
512
  author: string;
362
513
  /** The author's immutable numeric host user id, as text; their permission is checked by it. */
363
514
  authorId: string;
515
+ /** GitHub's `author_association` for the author; a hint only, never a permission. */
516
+ authorAssociation?: string;
517
+ /** Whether the repository is private, when the payload says. */
518
+ repositoryPrivate?: boolean;
364
519
  /** The issue or PR the mention is on, when the payload carries it. */
365
520
  subject?: {
366
521
  title: string;
@@ -8,6 +8,14 @@
8
8
  export const REVIEW_HOST_PROVIDERS = ["github", "local"];
9
9
  /** Providers with host user accounts to link (link_host_account); a local repository has none. */
10
10
  export const HOST_ACCOUNT_PROVIDERS = ["github"];
11
+ /** A patchCursor that is not one this deployment issued, or one for a head or compare that has moved on. */
12
+ export class PatchCursorError extends Error {
13
+ reason;
14
+ constructor(reason) {
15
+ super(reason === "stale" ? "patch_cursor_stale" : "patch_cursor_malformed");
16
+ this.reason = reason;
17
+ }
18
+ }
11
19
  export const HOST_PERMISSION_RANK = {
12
20
  none: 0,
13
21
  read: 1,
@@ -0,0 +1,63 @@
1
+ import type { Readable, Writable } from "node:stream";
2
+ import { type BlobInfo, type BlobStore } from "./types.js";
3
+ /** The slice of a GCS File the adapter uses (the real `File` satisfies it; tests supply an in-memory fake). */
4
+ export interface GcsFileLike {
5
+ createWriteStream(options?: {
6
+ resumable?: boolean;
7
+ contentType?: string;
8
+ }): Writable;
9
+ createReadStream(): Readable;
10
+ getMetadata(): Promise<[
11
+ {
12
+ size?: string | number;
13
+ updated?: string;
14
+ metadata?: Record<string, unknown>;
15
+ },
16
+ ...unknown[]
17
+ ]>;
18
+ save(data: Buffer, options?: {
19
+ resumable?: boolean;
20
+ contentType?: string;
21
+ }): Promise<unknown>;
22
+ delete(options?: {
23
+ ignoreNotFound?: boolean;
24
+ }): Promise<unknown>;
25
+ getSignedUrl(config: {
26
+ version: "v4";
27
+ action: "read" | "write";
28
+ expires: number;
29
+ }): Promise<[string]>;
30
+ }
31
+ export interface GcsBucketLike {
32
+ file(name: string): GcsFileLike;
33
+ }
34
+ /**
35
+ * Google Cloud Storage blob store. Credentials come from Application Default Credentials (Workload Identity on
36
+ * GKE); no key files. Uploads are single-request (non-resumable), so an upload that is destroyed before it
37
+ * finishes never creates or replaces an object.
38
+ */
39
+ export declare class GcsBlobStore implements BlobStore {
40
+ private readonly bucket;
41
+ constructor(bucket: GcsBucketLike);
42
+ /** Build a store over `bucketName` using Application Default Credentials. */
43
+ static forBucket(bucketName: string): GcsBlobStore;
44
+ private file;
45
+ put(key: string, body: Buffer, opts?: {
46
+ contentType?: string;
47
+ }): Promise<void>;
48
+ get(key: string): Promise<Buffer>;
49
+ delete(key: string): Promise<void>;
50
+ signedUrl(key: string, opts: {
51
+ expiresSec: number;
52
+ method: "GET" | "PUT";
53
+ }): Promise<string>;
54
+ putStream(key: string, body: NodeJS.ReadableStream, opts?: {
55
+ contentType?: string;
56
+ maxBytes?: number;
57
+ }): Promise<{
58
+ sizeBytes: number;
59
+ sha256: string;
60
+ }>;
61
+ getStream(key: string): Promise<NodeJS.ReadableStream>;
62
+ head(key: string): Promise<BlobInfo | null>;
63
+ }
@@ -0,0 +1,69 @@
1
+ import { pipeline } from "node:stream/promises";
2
+ import { Storage } from "@google-cloud/storage";
3
+ import { collectStream, createByteMeter } from "./meter.js";
4
+ import { assertValidBlobKey, BlobStoreError } from "./types.js";
5
+ function isNotFound(error) {
6
+ return error?.code === 404;
7
+ }
8
+ /**
9
+ * Google Cloud Storage blob store. Credentials come from Application Default Credentials (Workload Identity on
10
+ * GKE); no key files. Uploads are single-request (non-resumable), so an upload that is destroyed before it
11
+ * finishes never creates or replaces an object.
12
+ */
13
+ export class GcsBlobStore {
14
+ bucket;
15
+ constructor(bucket) {
16
+ this.bucket = bucket;
17
+ }
18
+ /** Build a store over `bucketName` using Application Default Credentials. */
19
+ static forBucket(bucketName) {
20
+ return new GcsBlobStore(new Storage().bucket(bucketName));
21
+ }
22
+ file(key) {
23
+ assertValidBlobKey(key);
24
+ return this.bucket.file(key);
25
+ }
26
+ async put(key, body, opts) {
27
+ await this.file(key).save(body, { resumable: false, contentType: opts?.contentType });
28
+ }
29
+ async get(key) {
30
+ return collectStream(await this.getStream(key));
31
+ }
32
+ async delete(key) {
33
+ await this.file(key).delete({ ignoreNotFound: true });
34
+ }
35
+ async signedUrl(key, opts) {
36
+ const [url] = await this.file(key).getSignedUrl({
37
+ version: "v4",
38
+ action: opts.method === "GET" ? "read" : "write",
39
+ expires: Date.now() + opts.expiresSec * 1000,
40
+ });
41
+ return url;
42
+ }
43
+ async putStream(key, body, opts) {
44
+ const file = this.file(key);
45
+ const meter = createByteMeter(opts?.maxBytes);
46
+ // pipeline destroys every stream (including the GCS write stream) on failure, which aborts the HTTP request
47
+ // before the object is finalized.
48
+ await pipeline(body, meter.stream, file.createWriteStream({ resumable: false, contentType: opts?.contentType }));
49
+ return { sizeBytes: meter.size(), sha256: meter.digest() };
50
+ }
51
+ async getStream(key) {
52
+ const file = this.file(key);
53
+ // createReadStream reports a missing object asynchronously; look first so callers get a typed not_found.
54
+ if ((await this.head(key)) === null)
55
+ throw new BlobStoreError("not_found");
56
+ return file.createReadStream();
57
+ }
58
+ async head(key) {
59
+ try {
60
+ const [metadata] = await this.file(key).getMetadata();
61
+ return { sizeBytes: Number(metadata.size ?? 0), updatedAt: new Date(metadata.updated ?? 0) };
62
+ }
63
+ catch (error) {
64
+ if (isNotFound(error))
65
+ return null;
66
+ throw error;
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,15 @@
1
+ import type { BlobStore } from "./types.js";
2
+ export type BlobStoreConfig = {
3
+ kind: "local";
4
+ localDir: string;
5
+ } | {
6
+ kind: "gcs";
7
+ bucket: string;
8
+ } | {
9
+ kind: "s3";
10
+ bucket: string;
11
+ region: string;
12
+ endpoint?: string;
13
+ };
14
+ /** Build the configured blob store. Cloud adapters take credentials from the environment's default chain. */
15
+ export declare function createBlobStore(config: BlobStoreConfig): BlobStore;
@@ -0,0 +1,14 @@
1
+ import { GcsBlobStore } from "./gcs.js";
2
+ import { LocalBlobStore } from "./local.js";
3
+ import { S3BlobStore } from "./s3.js";
4
+ /** Build the configured blob store. Cloud adapters take credentials from the environment's default chain. */
5
+ export function createBlobStore(config) {
6
+ switch (config.kind) {
7
+ case "local":
8
+ return new LocalBlobStore(config.localDir);
9
+ case "gcs":
10
+ return GcsBlobStore.forBucket(config.bucket);
11
+ case "s3":
12
+ return S3BlobStore.forBucket(config);
13
+ }
14
+ }
@@ -0,0 +1,24 @@
1
+ import { type BlobInfo, type BlobStore } from "./types.js";
2
+ /** Filesystem blob store rooted at one directory. Writes go to a temp file in the target directory, then rename (atomic). */
3
+ export declare class LocalBlobStore implements BlobStore {
4
+ private readonly root;
5
+ constructor(root: string);
6
+ private pathFor;
7
+ private tempPathFor;
8
+ put(key: string, body: Buffer): Promise<void>;
9
+ get(key: string): Promise<Buffer>;
10
+ delete(key: string): Promise<void>;
11
+ signedUrl(key: string, _opts: {
12
+ expiresSec: number;
13
+ method: "GET" | "PUT";
14
+ }): Promise<string>;
15
+ putStream(key: string, body: NodeJS.ReadableStream, opts?: {
16
+ contentType?: string;
17
+ maxBytes?: number;
18
+ }): Promise<{
19
+ sizeBytes: number;
20
+ sha256: string;
21
+ }>;
22
+ getStream(key: string): Promise<NodeJS.ReadableStream>;
23
+ head(key: string): Promise<BlobInfo | null>;
24
+ }
@@ -0,0 +1,92 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { createReadStream, createWriteStream } from "node:fs";
3
+ import { mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
4
+ import { dirname, join } from "node:path";
5
+ import { pipeline } from "node:stream/promises";
6
+ import { createByteMeter } from "./meter.js";
7
+ import { assertValidBlobKey, BlobStoreError } from "./types.js";
8
+ function isNotFound(error) {
9
+ return error?.code === "ENOENT";
10
+ }
11
+ /** Filesystem blob store rooted at one directory. Writes go to a temp file in the target directory, then rename (atomic). */
12
+ export class LocalBlobStore {
13
+ root;
14
+ constructor(root) {
15
+ this.root = root;
16
+ }
17
+ pathFor(key) {
18
+ assertValidBlobKey(key);
19
+ return join(this.root, key);
20
+ }
21
+ tempPathFor(path) {
22
+ return join(dirname(path), `.tmp-${randomUUID()}`);
23
+ }
24
+ async put(key, body) {
25
+ const path = this.pathFor(key);
26
+ await mkdir(dirname(path), { recursive: true });
27
+ const temp = this.tempPathFor(path);
28
+ try {
29
+ await writeFile(temp, body);
30
+ await rename(temp, path);
31
+ }
32
+ catch (error) {
33
+ await rm(temp, { force: true });
34
+ throw error;
35
+ }
36
+ }
37
+ async get(key) {
38
+ try {
39
+ return await readFile(this.pathFor(key));
40
+ }
41
+ catch (error) {
42
+ if (isNotFound(error))
43
+ throw new BlobStoreError("not_found", "not_found", { cause: error });
44
+ throw error;
45
+ }
46
+ }
47
+ async delete(key) {
48
+ await rm(this.pathFor(key), { force: true });
49
+ }
50
+ async signedUrl(key, _opts) {
51
+ assertValidBlobKey(key);
52
+ throw new BlobStoreError("not_supported", "not_supported: the local blob store has no signed URLs");
53
+ }
54
+ async putStream(key, body, opts) {
55
+ const path = this.pathFor(key);
56
+ await mkdir(dirname(path), { recursive: true });
57
+ const temp = this.tempPathFor(path);
58
+ const meter = createByteMeter(opts?.maxBytes);
59
+ try {
60
+ await pipeline(body, meter.stream, createWriteStream(temp));
61
+ await rename(temp, path);
62
+ }
63
+ catch (error) {
64
+ await rm(temp, { force: true });
65
+ throw error;
66
+ }
67
+ return { sizeBytes: meter.size(), sha256: meter.digest() };
68
+ }
69
+ async getStream(key) {
70
+ const path = this.pathFor(key);
71
+ try {
72
+ await stat(path);
73
+ }
74
+ catch (error) {
75
+ if (isNotFound(error))
76
+ throw new BlobStoreError("not_found", "not_found", { cause: error });
77
+ throw error;
78
+ }
79
+ return createReadStream(path);
80
+ }
81
+ async head(key) {
82
+ try {
83
+ const info = await stat(this.pathFor(key));
84
+ return { sizeBytes: info.size, updatedAt: info.mtime };
85
+ }
86
+ catch (error) {
87
+ if (isNotFound(error))
88
+ return null;
89
+ throw error;
90
+ }
91
+ }
92
+ }
@@ -0,0 +1,14 @@
1
+ import { Transform } from "node:stream";
2
+ import { BlobStoreError } from "./types.js";
3
+ export interface ByteMeter {
4
+ stream: Transform;
5
+ /** Bytes seen so far. */
6
+ size(): number;
7
+ /** The blob_too_large error, once the limit tripped. */
8
+ limitError(): BlobStoreError | undefined;
9
+ /** Finish the hash; call once, after the body has ended. */
10
+ digest(): string;
11
+ }
12
+ /** A passthrough that counts bytes (normalizing string chunks), hashes them, and fails with blob_too_large past `maxBytes`. */
13
+ export declare function createByteMeter(maxBytes: number | undefined): ByteMeter;
14
+ export declare function collectStream(stream: NodeJS.ReadableStream): Promise<Buffer>;
@@ -0,0 +1,34 @@
1
+ import { createHash } from "node:crypto";
2
+ import { Transform } from "node:stream";
3
+ import { BlobStoreError } from "./types.js";
4
+ /** A passthrough that counts bytes (normalizing string chunks), hashes them, and fails with blob_too_large past `maxBytes`. */
5
+ export function createByteMeter(maxBytes) {
6
+ const hash = createHash("sha256");
7
+ let sizeBytes = 0;
8
+ let tooLarge;
9
+ const stream = new Transform({
10
+ transform(chunk, encoding, callback) {
11
+ // Only a string is converted; a Buffer (or any byte view) passes through without a copy.
12
+ const bytes = typeof chunk === "string"
13
+ ? Buffer.from(chunk, encoding)
14
+ : Buffer.isBuffer(chunk)
15
+ ? chunk
16
+ : Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
17
+ sizeBytes += bytes.length;
18
+ if (maxBytes !== undefined && sizeBytes > maxBytes) {
19
+ tooLarge = new BlobStoreError("blob_too_large", `blob_too_large: more than ${maxBytes} bytes`);
20
+ callback(tooLarge);
21
+ return;
22
+ }
23
+ hash.update(bytes);
24
+ callback(null, bytes);
25
+ },
26
+ });
27
+ return { stream, size: () => sizeBytes, limitError: () => tooLarge, digest: () => hash.digest("hex") };
28
+ }
29
+ export async function collectStream(stream) {
30
+ const chunks = [];
31
+ for await (const chunk of stream)
32
+ chunks.push(Buffer.from(chunk));
33
+ return Buffer.concat(chunks);
34
+ }
@@ -0,0 +1,41 @@
1
+ import { type BlobInfo, type BlobStore } from "./types.js";
2
+ /** The slice of S3Client the adapter uses (the real client satisfies it; tests supply an in-memory fake). */
3
+ export interface S3ClientLike {
4
+ send(command: object): Promise<unknown>;
5
+ readonly config: unknown;
6
+ }
7
+ /**
8
+ * S3-compatible blob store (AWS S3, MinIO via `endpoint`). Credentials come from the default AWS credential
9
+ * chain (Pod Identity on EKS). Streamed uploads use multipart for large bodies; S3 only exposes an object once the
10
+ * upload completes, so an aborted upload never replaces the previous object.
11
+ */
12
+ export declare class S3BlobStore implements BlobStore {
13
+ private readonly client;
14
+ private readonly bucket;
15
+ constructor(client: S3ClientLike, bucket: string);
16
+ /** Build a store using the default credential chain. A custom `endpoint` (MinIO) switches to path-style addressing. */
17
+ static forBucket(settings: {
18
+ bucket: string;
19
+ region: string;
20
+ endpoint?: string;
21
+ }): S3BlobStore;
22
+ private keyed;
23
+ put(key: string, body: Buffer, opts?: {
24
+ contentType?: string;
25
+ }): Promise<void>;
26
+ get(key: string): Promise<Buffer>;
27
+ delete(key: string): Promise<void>;
28
+ signedUrl(key: string, opts: {
29
+ expiresSec: number;
30
+ method: "GET" | "PUT";
31
+ }): Promise<string>;
32
+ putStream(key: string, body: NodeJS.ReadableStream, opts?: {
33
+ contentType?: string;
34
+ maxBytes?: number;
35
+ }): Promise<{
36
+ sizeBytes: number;
37
+ sha256: string;
38
+ }>;
39
+ getStream(key: string): Promise<NodeJS.ReadableStream>;
40
+ head(key: string): Promise<BlobInfo | null>;
41
+ }