@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
@@ -66,6 +66,18 @@ function isOrderedBefore(run, other) {
66
66
  * returned with a null cap. One query at the widest configured window
67
67
  * (month contains week contains day), bucketed in JS, rather than a
68
68
  * separate DB round trip per period.
69
+ *
70
+ * A delegated run tree is held once, at its root. A sub-run whose tree root
71
+ * is a counted run of this group with a live, counted hold spends inside the
72
+ * root's hold, so it holds nothing (its cost still counts as spent), and the
73
+ * root holds its reservation minus the cost of every run in its tree, or the
74
+ * unspent holds of its tree's live runs when that is more (a coding run's
75
+ * grant can grow past the root's budget through overrun top-ups). A sub-run
76
+ * whose root is in another group, has finished, or whose hold is left out
77
+ * here (excludeReservationRunIds, holdsBefore) holds its own reservation. So
78
+ * does a sub-run in a period its root did not start in (a root that started
79
+ * yesterday, a child today: today's daily cap still holds the child's own
80
+ * reservation, since the root's hold falls in yesterday's bucket).
69
81
  */
70
82
  export async function computeGroupSpend(db, group, members, now = new Date(), options = {}) {
71
83
  const caps = [
@@ -97,33 +109,142 @@ export async function computeGroupSpend(db, group, members, now = new Date(), op
97
109
  costUsd: true,
98
110
  startedAt: true,
99
111
  heartbeatAt: true,
112
+ parentRunId: true,
100
113
  codingRun: { select: { budgetReservedUsd: true, timeoutSec: true } },
101
114
  },
102
115
  });
103
116
  const counted = runs.filter((r) => !dropped.has(r.id));
117
+ const countedById = new Map(counted.map((r) => [r.id, r]));
118
+ const holds = (r) => !excluded.has(r.id) &&
119
+ (options.holdsBefore === undefined || isOrderedBefore(r, options.holdsBefore)) &&
120
+ isHoldLive(r, now, queueTimeoutSec);
121
+ // A coding run holds exactly what dispatch reserved. A native run (or a
122
+ // coding run whose CodingRun row is missing) holds its agent's per-run
123
+ // budget: never less than what it can actually spend.
124
+ const reservationOf = (r) => r.codingRun != null ? Number(r.codingRun.budgetReservedUsd) : (memberBudgets.get(r.agentId) ?? 0);
125
+ // A run inside the tree of a counted, holding root in this group spends
126
+ // inside that root's hold, so it holds nothing of its own.
127
+ const rootOf = await resolveRootRunIds(db, counted);
128
+ const heldRoots = new Set();
129
+ for (const r of counted) {
130
+ const rootId = rootOf.get(r.id);
131
+ if (rootId === undefined || rootId === r.id)
132
+ continue;
133
+ const root = countedById.get(rootId);
134
+ if (root && holds(root))
135
+ heldRoots.add(rootId);
136
+ }
137
+ // Such a root holds its reservation minus the cost of its whole tree, every
138
+ // run in it included (also runs in other groups: they spend the tree too).
139
+ // The runs below it may hold more than that: a coding run's grant takes
140
+ // top-ups from the root agent's overrun, and dispatch sized it beside its live
141
+ // siblings' holds. So the root holds at least the unspent holds of every live run below
142
+ // it, each held as in siblingHoldsUsd.
143
+ const treeHoldByRoot = new Map();
144
+ for (const rootId of heldRoots) {
145
+ const treeRunIds = await collectTreeRunIds(db, rootId);
146
+ const treeRuns = await db.run.findMany({
147
+ where: { id: { in: treeRunIds } },
148
+ select: {
149
+ id: true,
150
+ status: true,
151
+ costUsd: true,
152
+ startedAt: true,
153
+ heartbeatAt: true,
154
+ agent: { select: { budgetUsd: true } },
155
+ codingRun: { select: { budgetReservedUsd: true, timeoutSec: true } },
156
+ },
157
+ });
158
+ const treeCostUsd = treeRuns.reduce((sum, t) => sum + Number(t.costUsd), 0);
159
+ const childHoldsUsd = treeRuns
160
+ .filter((t) => t.id !== rootId && !excluded.has(t.id) && isHoldLive(t, now, queueTimeoutSec))
161
+ .reduce((sum, t) => {
162
+ const reservation = t.codingRun ? Number(t.codingRun.budgetReservedUsd) : Number(t.agent.budgetUsd);
163
+ return sum + Math.max(0, reservation - Number(t.costUsd));
164
+ }, 0);
165
+ const root = countedById.get(rootId);
166
+ treeHoldByRoot.set(rootId, Math.max(reservationOf(root) - treeCostUsd, childHoldsUsd));
167
+ }
104
168
  const accounted = counted.map((r) => {
105
169
  const costUsd = Number(r.costUsd);
106
- let reservedUsd = 0;
107
- const holds = !excluded.has(r.id) &&
108
- (options.holdsBefore === undefined || isOrderedBefore(r, options.holdsBefore)) &&
109
- isHoldLive(r, now, queueTimeoutSec);
110
- if (holds) {
111
- // A coding run holds exactly what dispatch reserved. A native run (or
112
- // a coding run whose CodingRun row is missing) holds its agent's
113
- // per-run budget: never less than what it can actually spend.
114
- const reservation = r.codingRun != null ? Number(r.codingRun.budgetReservedUsd) : (memberBudgets.get(r.agentId) ?? 0);
115
- reservedUsd = Math.max(0, reservation - costUsd);
170
+ const rootId = rootOf.get(r.id);
171
+ let ownReservedUsd = 0;
172
+ if (heldRoots.has(r.id)) {
173
+ ownReservedUsd = Math.max(0, treeHoldByRoot.get(r.id) ?? 0);
174
+ }
175
+ else if (holds(r)) {
176
+ ownReservedUsd = Math.max(0, reservationOf(r) - costUsd);
116
177
  }
117
- return { startedAt: r.startedAt, costUsd, reservedUsd };
178
+ // Set when the run spends inside its root's hold: the root's startedAt.
179
+ const heldRootStartedAt = rootId !== undefined && rootId !== r.id && heldRoots.has(rootId) ? countedById.get(rootId).startedAt : null;
180
+ return { startedAt: r.startedAt, costUsd, ownReservedUsd, heldRootStartedAt };
118
181
  });
119
182
  return configured.map(({ period, capUsd }) => {
120
183
  const start = periodStart(period, now);
121
- const inPeriod = accounted.filter((r) => r.startedAt >= start);
184
+ // A run inside a held tree holds nothing in a period only when its root's
185
+ // hold is counted in that period too (the root started in it); otherwise
186
+ // the period would see the run's spend but no hold for it.
187
+ const inPeriod = accounted
188
+ .filter((r) => r.startedAt >= start)
189
+ .map((r) => ({
190
+ costUsd: r.costUsd,
191
+ reservedUsd: r.heldRootStartedAt !== null && r.heldRootStartedAt >= start ? 0 : r.ownReservedUsd,
192
+ }));
122
193
  const spentUsd = inPeriod.reduce((sum, r) => sum + r.costUsd, 0);
123
194
  const reservedUsd = inPeriod.reduce((sum, r) => sum + r.reservedUsd, 0);
124
- return { period, capUsd, spentUsd, reservedUsd, remainingUsd: Math.max(0, capUsd - spentUsd - reservedUsd) };
195
+ const heldRuns = inPeriod.filter((r) => r.reservedUsd > 0).length;
196
+ return {
197
+ period,
198
+ capUsd,
199
+ spentUsd,
200
+ reservedUsd,
201
+ remainingUsd: Math.max(0, capUsd - spentUsd - reservedUsd),
202
+ heldRuns,
203
+ };
125
204
  });
126
205
  }
206
+ /** Deepest parentRunId chain resolveRootRunIds follows: a guard against a cycle. */
207
+ const MAX_TREE_DEPTH = 32;
208
+ /**
209
+ * Each run's tree root (the ancestor with parentRunId null), walking
210
+ * parentRunId upward in one batched query per level. A run whose chain cannot
211
+ * be resolved (a missing ancestor, or deeper than MAX_TREE_DEPTH) is left out.
212
+ */
213
+ async function resolveRootRunIds(db, runs) {
214
+ const parentOf = new Map(runs.map((r) => [r.id, r.parentRunId ?? null]));
215
+ const missing = new Set();
216
+ for (let level = 0; level < MAX_TREE_DEPTH; level++) {
217
+ const unresolved = new Set();
218
+ for (const parentId of parentOf.values()) {
219
+ if (parentId !== null && !parentOf.has(parentId) && !missing.has(parentId))
220
+ unresolved.add(parentId);
221
+ }
222
+ if (unresolved.size === 0)
223
+ break;
224
+ const parents = await db.run.findMany({
225
+ where: { id: { in: [...unresolved] } },
226
+ select: { id: true, parentRunId: true, agentId: true },
227
+ });
228
+ for (const p of parents)
229
+ parentOf.set(p.id, p.parentRunId ?? null);
230
+ for (const id of unresolved)
231
+ if (!parentOf.has(id))
232
+ missing.add(id);
233
+ }
234
+ const rootOf = new Map();
235
+ for (const r of runs) {
236
+ let id = r.id;
237
+ let parentId = parentOf.get(id);
238
+ for (let depth = 0; parentId != null && depth < MAX_TREE_DEPTH; depth++) {
239
+ id = parentId;
240
+ parentId = parentOf.get(id);
241
+ }
242
+ // parentId undefined: a missing ancestor; non-null: too deep or a cycle.
243
+ if (parentId === null)
244
+ rootOf.set(r.id, id);
245
+ }
246
+ return rootOf;
247
+ }
127
248
  /** Walks parentRunId upward from `runId` to the tree's root (parentRunId null). */
128
249
  async function findRootRun(db, runId) {
129
250
  let current = await db.run.findUniqueOrThrow({
@@ -204,7 +325,13 @@ function siblingHoldsUsd(rows, parentRunId, now, self) {
204
325
  }
205
326
  return total;
206
327
  }
207
- async function runTreeSpend(db, parentRunId, now, self) {
328
+ /**
329
+ * With `withOverrun` (a coding run's top-up, codingTopUpRoom), the tree's
330
+ * ceiling is the root agent's budgetUsd raised by its own
331
+ * allowedOverrunPercent, still capped by the root's budget group; without it
332
+ * (dispatch and native callers), the root's budgetUsd: what the tree holds.
333
+ */
334
+ async function runTreeSpend(db, parentRunId, now, self, withOverrun = false) {
208
335
  const root = await findRootRun(db, parentRunId);
209
336
  const treeRunIds = await collectTreeRunIds(db, root.id);
210
337
  const rows = await db.run.findMany({
@@ -224,15 +351,12 @@ async function runTreeSpend(db, parentRunId, now, self) {
224
351
  const heldUsd = siblingHoldsUsd(rows, parentRunId, now, self);
225
352
  const rootAgent = await db.agent.findUniqueOrThrow({
226
353
  where: { id: root.agentId },
227
- select: { id: true, budgetGroupId: true, budgetUsd: true },
354
+ select: { id: true, budgetGroupId: true, budgetUsd: true, allowedOverrunPercent: true },
228
355
  });
229
356
  const rootOrder = { id: root.id, startedAt: root.startedAt };
230
357
  // Root has no parentRunId of its own, so this terminates in one level —
231
358
  // no unbounded recursion regardless of how deep `parentRunId` itself was.
232
- const rootCeiling = await groupCappedBudget(db, rootAgent, now, {
233
- excludeRunIds: treeRunIds,
234
- holdsBefore: rootOrder,
235
- });
359
+ const rootCeiling = await groupCappedBudget(db, rootAgent, now, { excludeRunIds: treeRunIds, holdsBefore: rootOrder }, undefined, withOverrun ? rootAgent.allowedOverrunPercent : undefined);
236
360
  const capUsd = rootCeiling.effectiveBudgetUsd;
237
361
  return {
238
362
  rootRunId: root.id,
@@ -263,7 +387,7 @@ async function runTreeSpend(db, parentRunId, now, self) {
263
387
  * the tree's included.
264
388
  */
265
389
  export async function effectiveBudgetForRun(db, agent, now = new Date(), parentRunId, options = {}) {
266
- const self = options.self;
390
+ const { self } = options;
267
391
  const ownSpend = { excludeReservationRunIds: self ? [self.id] : [], holdsBefore: self };
268
392
  if (!parentRunId)
269
393
  return groupCappedBudget(db, agent, now, ownSpend);
@@ -272,10 +396,21 @@ export async function effectiveBudgetForRun(db, agent, now = new Date(), parentR
272
396
  const spend = sharesRootGroup
273
397
  ? { excludeReservationRunIds: [...tree.treeRunIds, ...(self ? [self.id] : [])], holdsBefore: tree.root }
274
398
  : ownSpend;
275
- return groupCappedBudget(db, agent, now, spend, { value: tree.remainingUsd, reason: "run-tree" });
399
+ return groupCappedBudget(db, agent, now, spend, {
400
+ value: tree.remainingUsd,
401
+ reason: "run-tree",
402
+ detail: {
403
+ capUsd: tree.capUsd,
404
+ spentUsd: tree.spentUsd,
405
+ heldUsd: tree.capUsd - tree.spentUsd - tree.remainingUsd,
406
+ heldRuns: 0,
407
+ },
408
+ });
276
409
  }
277
- async function groupCappedBudget(db, agent, now, spendOptions, extra) {
410
+ async function groupCappedBudget(db, agent, now, spendOptions, extra, overrunPercent) {
278
411
  const ownBudgetUsd = Number(agent.budgetUsd);
412
+ // The ceiling the candidates tighten: own raised by the overrun, when one is given (a run tree's raised cap).
413
+ const ownLimitUsd = overrunPercent === undefined ? ownBudgetUsd : (ownBudgetUsd * (100 + overrunPercent)) / 100;
279
414
  const candidates = [];
280
415
  if (agent.budgetGroupId) {
281
416
  const group = await db.budgetGroup.findUnique({
@@ -286,7 +421,11 @@ async function groupCappedBudget(db, agent, now, spendOptions, extra) {
286
421
  const spend = await computeGroupSpend(db, group, group.agents, now, spendOptions);
287
422
  const warnThresholdRatio = Number(group.warnThresholdRatio);
288
423
  for (const s of spend) {
289
- candidates.push({ value: s.remainingUsd, reason: s.period });
424
+ candidates.push({
425
+ value: s.remainingUsd,
426
+ reason: s.period,
427
+ detail: { capUsd: s.capUsd, spentUsd: s.spentUsd, heldUsd: s.reservedUsd, heldRuns: s.heldRuns },
428
+ });
290
429
  if (s.spentUsd >= s.capUsd * warnThresholdRatio) {
291
430
  budgetGroupLog.warn({ groupId: group.id, groupName: group.name, period: s.period, capUsd: s.capUsd, spentUsd: s.spentUsd }, `budget group "${group.name}"'s ${s.period} spend ($${s.spentUsd.toFixed(4)}) has reached ` +
292
431
  `${(warnThresholdRatio * 100).toFixed(0)}% of its $${s.capUsd.toFixed(4)} cap`);
@@ -297,10 +436,80 @@ async function groupCappedBudget(db, agent, now, spendOptions, extra) {
297
436
  if (extra)
298
437
  candidates.push(extra);
299
438
  if (candidates.length === 0)
300
- return { effectiveBudgetUsd: ownBudgetUsd, constrainedBy: [] };
301
- const constrainedBy = candidates.filter((c) => c.value < ownBudgetUsd).map((c) => c.reason);
302
- const effectiveBudgetUsd = Math.min(ownBudgetUsd, ...candidates.map((c) => c.value));
439
+ return { effectiveBudgetUsd: ownLimitUsd, constrainedBy: [] };
440
+ const values = candidates.map((c) => c.value);
441
+ const constrainedBy = candidates.filter((c) => c.value < ownLimitUsd).map((c) => c.reason);
442
+ const effectiveBudgetUsd = Math.min(ownLimitUsd, ...values);
303
443
  // Less than the smallest reservable amount is nothing left.
304
444
  const exhausted = candidates.find((c) => c.value < MIN_RESERVATION_USD);
305
- return { effectiveBudgetUsd, constrainedBy, ...(exhausted ? { exhaustedBy: exhausted.reason } : {}) };
445
+ const limiting = effectiveBudgetUsd < ownLimitUsd ? candidates.find((c) => c.value === effectiveBudgetUsd) : undefined;
446
+ return {
447
+ effectiveBudgetUsd,
448
+ constrainedBy,
449
+ ...(limiting ? { limitedBy: limiting.reason } : {}),
450
+ ...(exhausted ? { exhaustedBy: exhausted.reason, exhaustedDetail: exhausted.detail } : {}),
451
+ };
452
+ }
453
+ /**
454
+ * Room for a coding run's overrun top-up (budget-topup.ts): the least of what
455
+ * its budget group, its run tree's root group, and its run tree's
456
+ * overrun-raised ceiling have left right now. Each group is seen whole: every
457
+ * live hold counts, this run's own grant (or its tree's hold) included, with
458
+ * no first-come-first-served ordering, because a top-up is new money that runs
459
+ * started later did not count when they reserved. A grant of at most roomUsd
460
+ * raises each group's and the tree's committed total by at most that much, so
461
+ * caps and ceilings stay hard. Callers hold the group dispatch lock.
462
+ */
463
+ export async function codingTopUpRoom(db, runId, now = new Date()) {
464
+ const run = await db.run.findUniqueOrThrow({
465
+ where: { id: runId },
466
+ select: { parentRunId: true, agent: { select: { budgetGroupId: true } } },
467
+ });
468
+ const candidates = [];
469
+ const groupIds = new Set();
470
+ if (run.agent.budgetGroupId)
471
+ groupIds.add(run.agent.budgetGroupId);
472
+ if (run.parentRunId) {
473
+ // Every live run in the tree off the ancestor chain holds its grant, this run's included.
474
+ const tree = await runTreeSpend(db, run.parentRunId, now, undefined, true);
475
+ candidates.push({
476
+ value: tree.remainingUsd,
477
+ reason: "run-tree",
478
+ detail: {
479
+ capUsd: tree.capUsd,
480
+ spentUsd: tree.spentUsd,
481
+ heldUsd: tree.capUsd - tree.spentUsd - tree.remainingUsd,
482
+ heldRuns: 0,
483
+ },
484
+ });
485
+ // The root's group holds the tree, this run's grant included, wherever this run's own group is.
486
+ if (tree.rootBudgetGroupId)
487
+ groupIds.add(tree.rootBudgetGroupId);
488
+ }
489
+ for (const groupId of groupIds) {
490
+ const group = await db.budgetGroup.findUnique({
491
+ where: { id: groupId },
492
+ include: { agents: { select: { id: true, budgetUsd: true } } },
493
+ });
494
+ if (!group)
495
+ continue;
496
+ for (const s of await computeGroupSpend(db, group, group.agents, now)) {
497
+ candidates.push({
498
+ value: s.remainingUsd,
499
+ reason: s.period,
500
+ detail: { capUsd: s.capUsd, spentUsd: s.spentUsd, heldUsd: s.reservedUsd, heldRuns: s.heldRuns },
501
+ groupName: group.name,
502
+ });
503
+ }
504
+ }
505
+ if (candidates.length === 0)
506
+ return { roomUsd: Infinity };
507
+ const least = candidates.reduce((min, c) => (c.value < min.value ? c : min));
508
+ const { capUsd, spentUsd, heldUsd } = least.detail;
509
+ return {
510
+ roomUsd: Math.max(0, least.value),
511
+ limitedBy: least.reason,
512
+ detail: { capUsd, spentUsd, heldUsd },
513
+ ...(least.groupName !== undefined ? { groupName: least.groupName } : {}),
514
+ };
306
515
  }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Which run last pushed to a pull request a coding run opened, and whether that push was work a
3
+ * run stopped at its budget left unfinished. Mark-ready keeps such a draft a draft; the review
4
+ * check skips it while its head is still that push (a person's later commit is reviewed).
5
+ */
6
+ import type { PrismaClient } from "#prisma";
7
+ export type BudgetStoppedHeadDb = Pick<PrismaClient, "codingRun">;
8
+ /** The run that pushed last: its status and the commit it pushed (result.commitSha). */
9
+ export interface LastPusher {
10
+ status: string | undefined;
11
+ commitSha: string | undefined;
12
+ }
13
+ /**
14
+ * The newest continuation of `root` (by createdAt) whose result names pull request `prNumber`,
15
+ * else the root itself.
16
+ */
17
+ export declare function lastPusher(db: BudgetStoppedHeadDb, root: {
18
+ runId: string;
19
+ result: unknown;
20
+ run: {
21
+ status?: string;
22
+ } | null;
23
+ }, prNumber: number): Promise<LastPusher>;
24
+ /**
25
+ * True when the pull request's head is the push of a run that stopped at its budget: the marker
26
+ * run resolves (through rootCodingRunId) to a root coding run in `repository` recorded as this
27
+ * pull request, and its last pusher stopped at its budget with `headSha` as its commit. Any
28
+ * lookup failure is false, so the pull request is reviewed as usual.
29
+ */
30
+ export declare function headStoppedAtBudget(db: BudgetStoppedHeadDb, input: {
31
+ markerRunId: string | null | undefined;
32
+ repository: string;
33
+ prNumber: number;
34
+ headSha: string;
35
+ }): Promise<boolean>;
36
+ /**
37
+ * The coding run that may be pushing to the pull request right now: the marker's root coding
38
+ * run (in `repository`) while it is pending or running, else its newest continuation that is.
39
+ * Its result, and so whether it stopped at its budget, is recorded only after its push lands,
40
+ * so a review of the head waits for it. Null when none is in flight or the marker resolves to
41
+ * nothing.
42
+ */
43
+ export declare function pushingRunInFlight(db: BudgetStoppedHeadDb, input: {
44
+ markerRunId: string | null | undefined;
45
+ repository: string;
46
+ }): Promise<string | null>;
@@ -0,0 +1,81 @@
1
+ import { pullRequestOutcome } from "./host-status.js";
2
+ const commitShaOf = (result) => {
3
+ if (!result || typeof result !== "object")
4
+ return undefined;
5
+ const sha = result.commitSha;
6
+ return typeof sha === "string" ? sha : undefined;
7
+ };
8
+ /**
9
+ * The newest continuation of `root` (by createdAt) whose result names pull request `prNumber`,
10
+ * else the root itself.
11
+ */
12
+ export async function lastPusher(db, root, prNumber) {
13
+ const continuations = await db.codingRun.findMany({
14
+ where: { rootCodingRunId: root.runId },
15
+ select: { result: true, run: { select: { status: true } } },
16
+ orderBy: { createdAt: "desc" },
17
+ });
18
+ const last = continuations.find((c) => pullRequestOutcome(c.result)?.pullRequestNumber === prNumber) ?? root;
19
+ return { status: last.run?.status, commitSha: commitShaOf(last.result) };
20
+ }
21
+ const ROOT_SELECT = {
22
+ runId: true,
23
+ repository: true,
24
+ rootCodingRunId: true,
25
+ result: true,
26
+ run: { select: { status: true } },
27
+ };
28
+ /** The marker run's root coding run (rootCodingRunId, else itself), only when it is in `repository`. */
29
+ async function markerRoot(db, markerRunId, repository) {
30
+ const marked = await db.codingRun.findUnique({ where: { runId: markerRunId }, select: ROOT_SELECT });
31
+ if (!marked)
32
+ return null;
33
+ const root = marked.rootCodingRunId
34
+ ? await db.codingRun.findUnique({ where: { runId: marked.rootCodingRunId }, select: ROOT_SELECT })
35
+ : marked;
36
+ return root && root.repository.toLowerCase() === repository.toLowerCase() ? root : null;
37
+ }
38
+ /**
39
+ * True when the pull request's head is the push of a run that stopped at its budget: the marker
40
+ * run resolves (through rootCodingRunId) to a root coding run in `repository` recorded as this
41
+ * pull request, and its last pusher stopped at its budget with `headSha` as its commit. Any
42
+ * lookup failure is false, so the pull request is reviewed as usual.
43
+ */
44
+ export async function headStoppedAtBudget(db, input) {
45
+ try {
46
+ if (!input.markerRunId)
47
+ return false;
48
+ const root = await markerRoot(db, input.markerRunId, input.repository);
49
+ if (!root || pullRequestOutcome(root.result)?.pullRequestNumber !== input.prNumber)
50
+ return false;
51
+ const last = await lastPusher(db, root, input.prNumber);
52
+ return last.status === "budget_exhausted" && last.commitSha === input.headSha;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ /** Run statuses of a coding run that may still push (its result is not recorded yet). */
59
+ const IN_FLIGHT = ["pending", "running"];
60
+ /**
61
+ * The coding run that may be pushing to the pull request right now: the marker's root coding
62
+ * run (in `repository`) while it is pending or running, else its newest continuation that is.
63
+ * Its result, and so whether it stopped at its budget, is recorded only after its push lands,
64
+ * so a review of the head waits for it. Null when none is in flight or the marker resolves to
65
+ * nothing.
66
+ */
67
+ export async function pushingRunInFlight(db, input) {
68
+ if (!input.markerRunId)
69
+ return null;
70
+ const root = await markerRoot(db, input.markerRunId, input.repository);
71
+ if (!root)
72
+ return null;
73
+ if (root.run && IN_FLIGHT.includes(root.run.status))
74
+ return root.runId;
75
+ const continuation = await db.codingRun.findFirst({
76
+ where: { rootCodingRunId: root.runId, run: { status: { in: [...IN_FLIGHT] } } },
77
+ select: { runId: true },
78
+ orderBy: { createdAt: "desc" },
79
+ });
80
+ return continuation?.runId ?? null;
81
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Overrun from available room: a coding run reserves only its base budget at
3
+ * dispatch, and may spend past it, up to its limit (CodingRun.budgetLimitUsd,
4
+ * the base raised by the agent's allowedOverrunPercent), only out of room its
5
+ * budget group and run tree still have when it needs it. Overrun is
6
+ * permission, not a reservation.
7
+ *
8
+ * The control plane grants top-ups, never the proxy: the executor's per-run
9
+ * monitor loop calls topUpCodingBudget while the run's job is running. A run
10
+ * close to its grant (spent + held within its headroom of it: two of its
11
+ * largest request holds, or 20% of its base if more) is granted one step, under the same group dispatch lock dispatch takes, by
12
+ * raising CodingRun.budgetReservedUsd (what groups and run trees hold) and
13
+ * CodingProxySession.budgetUsd (what the proxy enforces, re-read on every
14
+ * request) together. When the group or tree has no room left, the run records
15
+ * an overrun_unavailable budget event and never asks again; the proxy then
16
+ * refuses it at its grant as it always has.
17
+ */
18
+ import type { PrismaClient } from "#prisma";
19
+ /**
20
+ * not_needed: the run is not close to its grant yet. granted: one step was
21
+ * added. unavailable: its group or run tree had no room; recorded once, and
22
+ * the run stops asking. closed: nothing more to ask for (no limit, the limit
23
+ * reached, already refused once, or the run or its proxy session is not active).
24
+ */
25
+ export type TopUpOutcome = "not_needed" | "granted" | "unavailable" | "closed";
26
+ export interface TopUpResult {
27
+ outcome: TopUpOutcome;
28
+ /** The run's grant after this call, when it has a limit. */
29
+ grantedUsd?: number;
30
+ /**
31
+ * The run is within twice its headroom of its grant: the caller should ask
32
+ * again soon (the executor polls faster), since a top-up must land while the
33
+ * request before the one that would not fit is still in flight.
34
+ */
35
+ near?: boolean;
36
+ }
37
+ /** Share of the base one step adds, unless one maximum request hold is more. */
38
+ export declare const TOP_UP_STEP_SHARE = 0.1;
39
+ /** Headroom: the share of the base, or this many of the run's largest request holds if more. */
40
+ export declare const TOP_UP_HEADROOM_SHARE = 0.2;
41
+ export declare const TOP_UP_HEADROOM_HOLDS = 2;
42
+ /**
43
+ * Grants the run one overrun step when it is close to its grant and its
44
+ * budget group and run tree have room. Cheap when it is not close: that is
45
+ * read without the lock. One attempt per call, so a poll never blocks on
46
+ * retries: a serialization conflict (or a lock not had in time) answers
47
+ * not_needed and near, and the caller's next poll, soon, asks again.
48
+ */
49
+ export declare function topUpCodingBudget(db: PrismaClient, runId: string, now?: Date): Promise<TopUpResult>;
50
+ /** How long one top-up waits to start its transaction: short, so a poll (and its heartbeat) is never held long. */
51
+ export declare const TOP_UP_TX_MAX_WAIT_MS = 2000;