@wardby/cli 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (576) hide show
  1. package/deploy/local/docker-compose.quickstart-coding.yml +13 -0
  2. package/dist/claude-coding-worker/driver.d.ts +21 -3
  3. package/dist/claude-coding-worker/driver.js +125 -17
  4. package/dist/claude-coding-worker/main.js +34 -6
  5. package/dist/claude-coding-worker/sdk.js +12 -1
  6. package/dist/claude-coding-worker/tool-socket.d.ts +27 -0
  7. package/dist/claude-coding-worker/tool-socket.js +111 -0
  8. package/dist/claude-coding-worker/transcript.d.ts +18 -0
  9. package/dist/claude-coding-worker/transcript.js +77 -0
  10. package/dist/cli-help.d.ts +1 -1
  11. package/dist/cli-help.js +1 -0
  12. package/dist/cli.js +24 -10
  13. package/dist/coding/continuation-wording.d.ts +35 -0
  14. package/dist/coding/continuation-wording.js +73 -0
  15. package/dist/coding/linked-issue-note.d.ts +23 -0
  16. package/dist/coding/linked-issue-note.js +47 -0
  17. package/dist/coding/merge-wording.d.ts +28 -0
  18. package/dist/coding/merge-wording.js +78 -0
  19. package/dist/coding/pr-description-note.d.ts +9 -0
  20. package/dist/coding/pr-description-note.js +32 -0
  21. package/dist/coding/profile.d.ts +46 -126
  22. package/dist/coding/profile.js +45 -4
  23. package/dist/coding/protected-path-wording.d.ts +8 -0
  24. package/dist/coding/protected-path-wording.js +1 -1
  25. package/dist/coding/protocol.d.ts +264 -346
  26. package/dist/coding/protocol.js +235 -12
  27. package/dist/coding/redact.d.ts +3 -0
  28. package/dist/coding/redact.js +12 -0
  29. package/dist/coding/registry/allowlist.d.ts +12 -0
  30. package/dist/coding/registry/allowlist.js +14 -1
  31. package/dist/coding/registry/audit-mode.d.ts +153 -0
  32. package/dist/coding/registry/audit-mode.js +304 -0
  33. package/dist/coding/registry/lockfile-shared.d.ts +36 -0
  34. package/dist/coding/registry/lockfile-shared.js +128 -0
  35. package/dist/coding/registry/lockfiles.js +1 -1
  36. package/dist/coding/registry/npm-lockfile-formats.d.ts +11 -0
  37. package/dist/coding/registry/npm-lockfile-formats.js +41 -0
  38. package/dist/coding/registry/npm-lockfile.d.ts +8 -4
  39. package/dist/coding/registry/npm-lockfile.js +4 -6
  40. package/dist/coding/registry/npm.js +78 -8
  41. package/dist/coding/registry/pnpm-lockfile.d.ts +17 -0
  42. package/dist/coding/registry/pnpm-lockfile.js +189 -0
  43. package/dist/coding/registry/pypi-plan.d.ts +50 -0
  44. package/dist/coding/registry/pypi-plan.js +406 -0
  45. package/dist/coding/registry/pypi-requirements.d.ts +58 -0
  46. package/dist/coding/registry/pypi-requirements.js +155 -0
  47. package/dist/coding/registry/pypi.d.ts +3 -27
  48. package/dist/coding/registry/pypi.js +40 -154
  49. package/dist/coding/registry/refusal-hints.d.ts +20 -0
  50. package/dist/coding/registry/refusal-hints.js +61 -0
  51. package/dist/coding/registry/refusal-wording.d.ts +11 -0
  52. package/dist/coding/registry/refusal-wording.js +56 -0
  53. package/dist/coding/registry/report.d.ts +70 -8
  54. package/dist/coding/registry/report.js +112 -5
  55. package/dist/coding/registry/types.d.ts +58 -8
  56. package/dist/coding/registry/yarn-lockfile.d.ts +30 -0
  57. package/dist/coding/registry/yarn-lockfile.js +367 -0
  58. package/dist/coding/services/catalog.d.ts +37 -351
  59. package/dist/coding/transcript/claude-code.d.ts +13 -0
  60. package/dist/coding/transcript/claude-code.js +273 -0
  61. package/dist/coding/transcript/download-protocol.d.ts +30 -0
  62. package/dist/coding/transcript/download-protocol.js +18 -0
  63. package/dist/coding/transcript/format.d.ts +20 -0
  64. package/dist/coding/transcript/format.js +32 -0
  65. package/dist/coding/transcript/recorder.d.ts +51 -0
  66. package/dist/coding/transcript/recorder.js +225 -0
  67. package/dist/coding/transcript/resume/checkout.d.ts +31 -0
  68. package/dist/coding/transcript/resume/checkout.js +203 -0
  69. package/dist/coding/transcript/resume/command.d.ts +17 -0
  70. package/dist/coding/transcript/resume/command.js +176 -0
  71. package/dist/coding/transcript/resume/download.d.ts +20 -0
  72. package/dist/coding/transcript/resume/download.js +153 -0
  73. package/dist/coding/transcript/resume/launch.d.ts +38 -0
  74. package/dist/coding/transcript/resume/launch.js +128 -0
  75. package/dist/coding/transcript/resume/session-file.d.ts +13 -0
  76. package/dist/coding/transcript/resume/session-file.js +79 -0
  77. package/dist/coding/transcript/resume/stand-in.d.ts +11 -0
  78. package/dist/coding/transcript/resume/stand-in.js +49 -0
  79. package/dist/coding-worker/artifact.d.ts +8 -3
  80. package/dist/coding-worker/artifact.js +3 -1
  81. package/dist/coding-worker/debug-trace.d.ts +6 -5
  82. package/dist/coding-worker/debug-trace.js +13 -18
  83. package/dist/coding-worker/dependency-cache.d.mts +229 -0
  84. package/dist/coding-worker/dependency-cache.mjs +2123 -0
  85. package/dist/coding-worker/driver.d.ts +4 -3
  86. package/dist/coding-worker/driver.js +116 -38
  87. package/dist/coding-worker/errors.d.ts +1 -0
  88. package/dist/coding-worker/errors.js +32 -0
  89. package/dist/coding-worker/task-note.d.ts +11 -0
  90. package/dist/coding-worker/task-note.js +13 -0
  91. package/dist/coding-worker/types.d.ts +11 -0
  92. package/dist/config/dependency-cache.d.ts +23 -0
  93. package/dist/config/dependency-cache.js +32 -0
  94. package/dist/config/providers.d.ts +12 -3
  95. package/dist/config/providers.js +55 -5
  96. package/dist/config/test-simulators.d.ts +82 -0
  97. package/dist/config/test-simulators.js +305 -0
  98. package/dist/core/async-context.d.ts +2 -0
  99. package/dist/core/async-context.js +12 -0
  100. package/dist/core/budget-events.d.ts +108 -0
  101. package/dist/core/budget-events.js +346 -0
  102. package/dist/core/budget-groups.d.ts +50 -1
  103. package/dist/core/budget-groups.js +236 -27
  104. package/dist/core/budget-stopped-head.d.ts +46 -0
  105. package/dist/core/budget-stopped-head.js +81 -0
  106. package/dist/core/budget-topup.d.ts +51 -0
  107. package/dist/core/budget-topup.js +156 -0
  108. package/dist/core/budget-wording.d.ts +16 -2
  109. package/dist/core/budget-wording.js +40 -2
  110. package/dist/core/coding-queue.d.ts +2 -1
  111. package/dist/core/coding-queue.js +7 -0
  112. package/dist/core/cron.d.ts +19 -1
  113. package/dist/core/cron.js +17 -0
  114. package/dist/core/datastores.js +1 -1
  115. package/dist/core/deferred-coding.d.ts +14 -0
  116. package/dist/core/deferred-coding.js +62 -0
  117. package/dist/core/delegation-child.d.ts +25 -0
  118. package/dist/core/delegation-child.js +37 -0
  119. package/dist/core/dispatch.d.ts +42 -0
  120. package/dist/core/dispatch.js +131 -56
  121. package/dist/core/engine-native.js +1 -1
  122. package/dist/core/error-code.d.ts +38 -0
  123. package/dist/core/error-code.js +168 -0
  124. package/dist/core/grants.d.ts +19 -6
  125. package/dist/core/grants.js +55 -6
  126. package/dist/core/host-events.d.ts +18 -2
  127. package/dist/core/host-events.js +284 -24
  128. package/dist/core/host-status.d.ts +85 -3
  129. package/dist/core/host-status.js +298 -20
  130. package/dist/core/issue-bridge.d.ts +50 -6
  131. package/dist/core/issue-bridge.js +124 -33
  132. package/dist/core/issue-events.d.ts +1 -1
  133. package/dist/core/issue-events.js +4 -10
  134. package/dist/core/issue-status.d.ts +1 -1
  135. package/dist/core/issue-status.js +54 -26
  136. package/dist/core/logger.d.ts +5 -0
  137. package/dist/core/logger.js +14 -1
  138. package/dist/core/lost-run-children.d.ts +6 -0
  139. package/dist/core/lost-run-children.js +32 -0
  140. package/dist/core/mark-ready.d.ts +34 -0
  141. package/dist/core/mark-ready.js +152 -0
  142. package/dist/core/markdown-code.d.ts +8 -0
  143. package/dist/core/markdown-code.js +107 -0
  144. package/dist/core/memory-tools.js +7 -0
  145. package/dist/core/merge-order-check.d.ts +2 -1
  146. package/dist/core/merge-order-check.js +8 -1
  147. package/dist/core/notification-templates.d.ts +1 -7
  148. package/dist/core/notification-templates.js +36 -2
  149. package/dist/core/pull-request-state-sync.js +2 -2
  150. package/dist/core/reconciler.d.ts +4 -3
  151. package/dist/core/reconciler.js +8 -1
  152. package/dist/core/related-pull-requests.d.ts +11 -3
  153. package/dist/core/related-pull-requests.js +27 -14
  154. package/dist/core/reply-parts.d.ts +21 -0
  155. package/dist/core/reply-parts.js +73 -0
  156. package/dist/core/review-fix.d.ts +1 -1
  157. package/dist/core/review-fix.js +2 -1
  158. package/dist/core/review-host-checks.d.ts +1 -1
  159. package/dist/core/review-host-tools.d.ts +3 -0
  160. package/dist/core/review-host-tools.js +99 -13
  161. package/dist/core/review-reads.d.ts +55 -0
  162. package/dist/core/review-reads.js +233 -0
  163. package/dist/core/run-status.d.ts +12 -0
  164. package/dist/core/run-status.js +12 -0
  165. package/dist/core/runner.d.ts +80 -34
  166. package/dist/core/runner.js +439 -144
  167. package/dist/core/schedule-start.d.ts +12 -0
  168. package/dist/core/schedule-start.js +14 -0
  169. package/dist/core/secret-broker-config.d.ts +10 -74
  170. package/dist/core/secret-guard.d.ts +46 -0
  171. package/dist/core/secret-guard.js +104 -0
  172. package/dist/core/secret-guarded-stores.d.ts +12 -0
  173. package/dist/core/secret-guarded-stores.js +41 -0
  174. package/dist/core/secret-spans.d.ts +50 -0
  175. package/dist/core/secret-spans.js +94 -0
  176. package/dist/core/stop-run.d.ts +46 -0
  177. package/dist/core/stop-run.js +61 -0
  178. package/dist/core/workflow-events.d.ts +14 -2
  179. package/dist/core/workflow-events.js +4 -0
  180. package/dist/core/workflow-run-events.d.ts +5 -3
  181. package/dist/core/workflow-run-events.js +43 -8
  182. package/dist/core/zod-json-schema.d.ts +4 -0
  183. package/dist/core/zod-json-schema.js +39 -0
  184. package/dist/core/zod3-window.d.ts +35 -0
  185. package/dist/core/zod3-window.js +124 -0
  186. package/dist/generated/prisma/browser.d.ts +34 -3
  187. package/dist/generated/prisma/client.d.ts +34 -3
  188. package/dist/generated/prisma/commonInputTypes.d.ts +220 -60
  189. package/dist/generated/prisma/enums.d.ts +10 -0
  190. package/dist/generated/prisma/enums.js +8 -0
  191. package/dist/generated/prisma/internal/class.d.ts +44 -0
  192. package/dist/generated/prisma/internal/class.js +4 -4
  193. package/dist/generated/prisma/internal/prismaNamespace.d.ts +428 -9
  194. package/dist/generated/prisma/internal/prismaNamespace.js +92 -1
  195. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +95 -0
  196. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +92 -1
  197. package/dist/generated/prisma/models/Agent.d.ts +106 -8
  198. package/dist/generated/prisma/models/AgentRepository.d.ts +42 -1
  199. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +229 -1
  200. package/dist/generated/prisma/models/CodingProxyRequest.d.ts +207 -3
  201. package/dist/generated/prisma/models/CodingProxySession.d.ts +114 -1
  202. package/dist/generated/prisma/models/CodingRun.d.ts +1637 -1
  203. package/dist/generated/prisma/models/DependencySnapshot.d.ts +1668 -0
  204. package/dist/generated/prisma/models/DependencySnapshot.js +1 -0
  205. package/dist/generated/prisma/models/IssuePullRequest.d.ts +6 -2
  206. package/dist/generated/prisma/models/LocalReview.d.ts +40 -1
  207. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
  208. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +35 -1
  209. package/dist/generated/prisma/models/RegistryAllowance.d.ts +41 -1
  210. package/dist/generated/prisma/models/RegistryApprovedVersion.d.ts +75 -1
  211. package/dist/generated/prisma/models/RegistryAuditRecord.d.ts +1364 -0
  212. package/dist/generated/prisma/models/RegistryAuditRecord.js +1 -0
  213. package/dist/generated/prisma/models/Run.d.ts +738 -2
  214. package/dist/generated/prisma/models/RunBudgetEvent.d.ts +1211 -0
  215. package/dist/generated/prisma/models/RunBudgetEvent.js +1 -0
  216. package/dist/generated/prisma/models/RunTranscript.d.ts +1339 -0
  217. package/dist/generated/prisma/models/RunTranscript.js +1 -0
  218. package/dist/generated/prisma/models.d.ts +4 -0
  219. package/dist/help-index.json +1320 -69
  220. package/dist/import/create.js +32 -3
  221. package/dist/import/neutral-schema.d.ts +50 -281
  222. package/dist/import/neutral-schema.js +5 -4
  223. package/dist/knowledge/check.d.ts +1 -1
  224. package/dist/knowledge/cli.d.ts +11 -1
  225. package/dist/knowledge/cli.js +37 -4
  226. package/dist/knowledge/concept.d.ts +3 -19
  227. package/dist/knowledge/location.d.ts +31 -0
  228. package/dist/knowledge/location.js +78 -0
  229. package/dist/mcp/auth/access.d.ts +10 -2
  230. package/dist/mcp/auth/access.js +15 -1
  231. package/dist/mcp/auth/ownership.d.ts +7 -7
  232. package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
  233. package/dist/mcp/auth/self-hosted/session.d.ts +2 -2
  234. package/dist/mcp/host-events/github-ingress.d.ts +2 -0
  235. package/dist/mcp/host-events/github-ingress.js +2 -1
  236. package/dist/mcp/index.d.ts +6 -0
  237. package/dist/mcp/index.js +58 -10
  238. package/dist/mcp/server.d.ts +13 -0
  239. package/dist/mcp/server.js +33 -14
  240. package/dist/mcp/tools/agents.d.ts +4 -0
  241. package/dist/mcp/tools/agents.js +198 -16
  242. package/dist/mcp/tools/datastore.js +17 -8
  243. package/dist/mcp/tools/grants.js +9 -3
  244. package/dist/mcp/tools/memory.js +11 -1
  245. package/dist/mcp/tools/notification-channels.js +2 -2
  246. package/dist/mcp/tools/packages.d.ts +2 -0
  247. package/dist/mcp/tools/packages.js +195 -0
  248. package/dist/mcp/tools/repositories.js +18 -5
  249. package/dist/mcp/tools/run-access.d.ts +16 -0
  250. package/dist/mcp/tools/run-access.js +25 -0
  251. package/dist/mcp/tools/run-transcript-download.d.ts +30 -0
  252. package/dist/mcp/tools/run-transcript-download.js +129 -0
  253. package/dist/mcp/tools/run-transcript.d.ts +19 -0
  254. package/dist/mcp/tools/run-transcript.js +70 -0
  255. package/dist/mcp/tools/runs.js +34 -12
  256. package/dist/mcp/tools/scheduling.js +3 -1
  257. package/dist/mcp/tools/secret-elicitation-form.js +5 -0
  258. package/dist/mcp/tools/secret-elicitation-server.d.ts +6 -0
  259. package/dist/mcp/tools/secret-elicitation-server.js +10 -61
  260. package/dist/mcp/tools/secrets.js +2 -2
  261. package/dist/mcp/tools/stop-run.d.ts +2 -0
  262. package/dist/mcp/tools/stop-run.js +82 -0
  263. package/dist/mcp/tools/subagents.js +2 -2
  264. package/dist/mcp/tools/tools.d.ts +1 -1
  265. package/dist/mcp/tools/tools.js +25 -9
  266. package/dist/mcp/transport/stdio-link-host.d.ts +20 -0
  267. package/dist/mcp/transport/stdio-link-host.js +67 -0
  268. package/dist/mcp/transport/streamable-http.d.ts +13 -0
  269. package/dist/mcp/transport/streamable-http.js +41 -1
  270. package/dist/native-worker/docker-launcher.d.ts +38 -2
  271. package/dist/native-worker/docker-launcher.js +65 -5
  272. package/dist/native-worker/gateway-server.d.ts +41 -3
  273. package/dist/native-worker/gateway-server.js +124 -27
  274. package/dist/native-worker/gateway.d.ts +27 -1
  275. package/dist/native-worker/gateway.js +70 -4
  276. package/dist/native-worker/http-server.d.ts +3 -1
  277. package/dist/native-worker/http-server.js +11 -7
  278. package/dist/native-worker/http-transport.js +1 -1
  279. package/dist/native-worker/kubernetes-launcher.d.ts +7 -3
  280. package/dist/native-worker/kubernetes-launcher.js +43 -3
  281. package/dist/native-worker/launch.d.ts +18 -1
  282. package/dist/native-worker/launch.js +6 -1
  283. package/dist/native-worker/ledger.d.ts +18 -2
  284. package/dist/native-worker/ledger.js +57 -4
  285. package/dist/native-worker/loopback.js +3 -8
  286. package/dist/native-worker/main.d.ts +2 -1
  287. package/dist/native-worker/main.js +14 -3
  288. package/dist/native-worker/protocol.d.ts +129 -577
  289. package/dist/native-worker/protocol.js +47 -1
  290. package/dist/native-worker/sandbox-executor.d.ts +17 -2
  291. package/dist/native-worker/sandbox-executor.js +78 -4
  292. package/dist/native-worker/stderr-redaction.d.ts +77 -0
  293. package/dist/native-worker/stderr-redaction.js +237 -0
  294. package/dist/native-worker/stdio.d.ts +1 -1
  295. package/dist/native-worker/stdio.js +6 -5
  296. package/dist/native-worker/warm-pool.d.ts +2 -2
  297. package/dist/native-worker/warm-pool.js +4 -4
  298. package/dist/native-worker/worker.js +28 -2
  299. package/dist/observability/metrics.js +6 -1
  300. package/dist/providers/auth/self-hosted.d.ts +1 -1
  301. package/dist/providers/coding-proxy/dependency-cache/eviction.d.ts +29 -0
  302. package/dist/providers/coding-proxy/dependency-cache/eviction.js +87 -0
  303. package/dist/providers/coding-proxy/dependency-cache/key.d.ts +33 -0
  304. package/dist/providers/coding-proxy/dependency-cache/key.js +86 -0
  305. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.d.ts +18 -0
  306. package/dist/providers/coding-proxy/dependency-cache/model-request-seal.js +40 -0
  307. package/dist/providers/coding-proxy/dependency-cache/prisma-store.d.ts +25 -0
  308. package/dist/providers/coding-proxy/dependency-cache/prisma-store.js +131 -0
  309. package/dist/providers/coding-proxy/dependency-cache/service.d.ts +70 -0
  310. package/dist/providers/coding-proxy/dependency-cache/service.js +409 -0
  311. package/dist/providers/coding-proxy/dependency-cache/store.d.ts +85 -0
  312. package/dist/providers/coding-proxy/dependency-cache/store.js +95 -0
  313. package/dist/providers/coding-proxy/hold.d.ts +32 -0
  314. package/dist/providers/coding-proxy/hold.js +86 -0
  315. package/dist/providers/coding-proxy/interrupted.d.ts +70 -0
  316. package/dist/providers/coding-proxy/interrupted.js +104 -0
  317. package/dist/providers/coding-proxy/memory-ledger.d.ts +15 -2
  318. package/dist/providers/coding-proxy/memory-ledger.js +84 -8
  319. package/dist/providers/coding-proxy/metering.d.ts +16 -0
  320. package/dist/providers/coding-proxy/metering.js +27 -4
  321. package/dist/providers/coding-proxy/prisma-ledger.d.ts +15 -2
  322. package/dist/providers/coding-proxy/prisma-ledger.js +179 -67
  323. package/dist/providers/coding-proxy/proxy.d.ts +14 -1
  324. package/dist/providers/coding-proxy/proxy.js +166 -14
  325. package/dist/providers/coding-proxy/registry/audit.d.ts +53 -10
  326. package/dist/providers/coding-proxy/registry/audit.js +94 -17
  327. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.d.ts +36 -0
  328. package/dist/providers/coding-proxy/registry/lockfile-parse-worker.js +67 -0
  329. package/dist/providers/coding-proxy/registry/lockfile-parse.d.ts +16 -0
  330. package/dist/providers/coding-proxy/registry/lockfile-parse.js +110 -0
  331. package/dist/providers/coding-proxy/registry/plan.d.ts +9 -0
  332. package/dist/providers/coding-proxy/registry/plan.js +201 -48
  333. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +11 -5
  334. package/dist/providers/coding-proxy/registry/prisma-store.js +120 -17
  335. package/dist/providers/coding-proxy/registry/service.d.ts +97 -16
  336. package/dist/providers/coding-proxy/registry/service.js +579 -112
  337. package/dist/providers/coding-proxy/registry/store.d.ts +84 -9
  338. package/dist/providers/coding-proxy/registry/store.js +54 -1
  339. package/dist/providers/coding-proxy/runtime.d.ts +4 -0
  340. package/dist/providers/coding-proxy/runtime.js +78 -16
  341. package/dist/providers/coding-proxy/server.d.ts +6 -1
  342. package/dist/providers/coding-proxy/server.js +45 -1
  343. package/dist/providers/coding-proxy/types.d.ts +65 -1
  344. package/dist/providers/datastore/types.d.ts +5 -0
  345. package/dist/providers/engine/types.d.ts +17 -2
  346. package/dist/providers/engine/types.js +17 -0
  347. package/dist/providers/executor/composition.d.ts +10 -3
  348. package/dist/providers/executor/composition.js +47 -7
  349. package/dist/providers/executor/container.d.ts +361 -8
  350. package/dist/providers/executor/container.js +1136 -91
  351. package/dist/providers/executor/dbos-status.d.ts +31 -0
  352. package/dist/providers/executor/dbos-status.js +64 -0
  353. package/dist/providers/executor/dbos.d.ts +50 -1
  354. package/dist/providers/executor/dbos.js +207 -20
  355. package/dist/providers/executor/deferred.d.ts +12 -24
  356. package/dist/providers/executor/deferred.js +10 -29
  357. package/dist/providers/executor/in-process.d.ts +9 -1
  358. package/dist/providers/executor/in-process.js +14 -4
  359. package/dist/providers/executor/linked-issue-reader.d.ts +16 -0
  360. package/dist/providers/executor/linked-issue-reader.js +30 -0
  361. package/dist/providers/executor/routing.d.ts +2 -0
  362. package/dist/providers/executor/routing.js +4 -0
  363. package/dist/providers/executor/types.d.ts +13 -0
  364. package/dist/providers/index.d.ts +2 -1
  365. package/dist/providers/issue-tracker/types.d.ts +17 -0
  366. package/dist/providers/issue-tracker/types.js +39 -1
  367. package/dist/providers/jobs/claude-tool-setup.d.ts +4 -0
  368. package/dist/providers/jobs/claude-tool-setup.js +5 -2
  369. package/dist/providers/jobs/docker-isolation.d.ts +8 -0
  370. package/dist/providers/jobs/docker-isolation.js +17 -0
  371. package/dist/providers/jobs/docker.d.ts +1 -0
  372. package/dist/providers/jobs/docker.js +27 -2
  373. package/dist/providers/jobs/fake-kubernetes-api.d.ts +2 -0
  374. package/dist/providers/jobs/fake-kubernetes-api.js +3 -0
  375. package/dist/providers/jobs/kubernetes-api.d.ts +8 -0
  376. package/dist/providers/jobs/kubernetes-api.js +10 -0
  377. package/dist/providers/jobs/kubernetes-client.js +10 -1
  378. package/dist/providers/jobs/kubernetes-isolation.d.ts +2 -0
  379. package/dist/providers/jobs/kubernetes-isolation.js +17 -1
  380. package/dist/providers/jobs/kubernetes.d.ts +6 -1
  381. package/dist/providers/jobs/kubernetes.js +105 -16
  382. package/dist/providers/jobs/types.d.ts +33 -0
  383. package/dist/providers/jobs/types.js +13 -1
  384. package/dist/providers/llm/anthropic.js +5 -1
  385. package/dist/providers/llm/bedrock.d.ts +0 -12
  386. package/dist/providers/llm/bedrock.js +4 -0
  387. package/dist/providers/llm/claude-messages.d.ts +3 -1
  388. package/dist/providers/llm/claude-messages.js +4 -1
  389. package/dist/providers/llm/claude-provider.d.ts +2 -2
  390. package/dist/providers/llm/claude-provider.js +2 -2
  391. package/dist/providers/llm/openai.d.ts +2 -2
  392. package/dist/providers/llm/openai.js +6 -2
  393. package/dist/providers/llm/routing.d.ts +2 -2
  394. package/dist/providers/llm/routing.js +2 -2
  395. package/dist/providers/llm/types.d.ts +12 -2
  396. package/dist/providers/review-host/github-events.d.ts +9 -1
  397. package/dist/providers/review-host/github-events.js +34 -12
  398. package/dist/providers/review-host/github.d.ts +29 -2
  399. package/dist/providers/review-host/github.js +224 -29
  400. package/dist/providers/review-host/local.d.ts +8 -4
  401. package/dist/providers/review-host/local.js +49 -31
  402. package/dist/providers/review-host/patch-pages.d.ts +41 -0
  403. package/dist/providers/review-host/patch-pages.js +176 -0
  404. package/dist/providers/review-host/review-format.d.ts +19 -1
  405. package/dist/providers/review-host/review-format.js +38 -7
  406. package/dist/providers/review-host/types.d.ts +134 -2
  407. package/dist/providers/review-host/types.js +8 -0
  408. package/dist/providers/storage/gcs.d.ts +63 -0
  409. package/dist/providers/storage/gcs.js +69 -0
  410. package/dist/providers/storage/index.d.ts +15 -0
  411. package/dist/providers/storage/index.js +14 -0
  412. package/dist/providers/storage/local.d.ts +24 -0
  413. package/dist/providers/storage/local.js +92 -0
  414. package/dist/providers/storage/meter.d.ts +14 -0
  415. package/dist/providers/storage/meter.js +34 -0
  416. package/dist/providers/storage/s3.d.ts +41 -0
  417. package/dist/providers/storage/s3.js +107 -0
  418. package/dist/providers/storage/types.d.ts +37 -3
  419. package/dist/providers/storage/types.js +21 -4
  420. package/dist/providers/vcs/git.d.ts +33 -2
  421. package/dist/providers/vcs/git.js +324 -22
  422. package/dist/providers/vcs/github-remote.d.ts +26 -3
  423. package/dist/providers/vcs/github-remote.js +124 -14
  424. package/dist/providers/vcs/github.d.ts +214 -6
  425. package/dist/providers/vcs/github.js +447 -45
  426. package/dist/providers/vcs/index.js +8 -1
  427. package/dist/providers/vcs/pr-description.d.ts +127 -0
  428. package/dist/providers/vcs/pr-description.js +270 -0
  429. package/dist/providers/vcs/remote.d.ts +33 -1
  430. package/dist/providers/vcs/routing.d.ts +4 -2
  431. package/dist/providers/vcs/routing.js +6 -0
  432. package/dist/providers/vcs/types.d.ts +80 -3
  433. package/dist/quickstart/coding-seed.d.ts +14 -3
  434. package/dist/quickstart/coding-seed.js +213 -4
  435. package/dist/quickstart/reviewer-prompt.d.ts +1 -1
  436. package/dist/quickstart/reviewer-prompt.js +6 -6
  437. package/dist/quickstart-images.json +1 -1
  438. package/dist/sandbox/generated/zod.bundle.js +62 -1
  439. package/dist/sandbox/generated/zod3.bundle.js +5 -0
  440. package/dist/sandbox/host-functions.d.ts +1 -0
  441. package/dist/sandbox/host-functions.js +6 -11
  442. package/dist/sandbox/secret-broker.js +3 -4
  443. package/dist/sandbox/tool-capabilities.d.ts +10 -30
  444. package/dist/sandbox/zod-params.d.ts +37 -5
  445. package/dist/sandbox/zod-params.js +181 -26
  446. package/dist/serve.js +8 -1
  447. package/dist/viewer/api-schema.d.ts +349 -2627
  448. package/dist/viewer/api-schema.js +7 -0
  449. package/dist/viewer/build-schemas.js +6 -2
  450. package/dist/viewer/openapi.js +2 -4
  451. package/dist/wardby-bin.js +10 -0
  452. package/docs/agent-recipes.md +58 -20
  453. package/docs/code-review-agents.md +551 -41
  454. package/docs/coding-agent-setup.md +489 -7
  455. package/docs/coding-packages.md +1033 -90
  456. package/docs/coding-services.md +27 -12
  457. package/docs/coding-worker-byo-images.md +20 -0
  458. package/docs/coding-worker-isolation.md +105 -30
  459. package/docs/getting-started-gke.md +124 -137
  460. package/docs/getting-started-identity-provider.md +10 -1
  461. package/docs/getting-started.md +9 -0
  462. package/docs/jira-agents.md +17 -8
  463. package/docs/knowledge/blob-not-found-semantics.md +41 -0
  464. package/docs/knowledge/bounded-file-descriptor.md +52 -0
  465. package/docs/knowledge/delegation-admission-slots.md +52 -0
  466. package/docs/knowledge/http-dispatcher-bootstrap.md +61 -0
  467. package/docs/knowledge/import-rename-target.md +52 -0
  468. package/docs/knowledge/index.md +57 -0
  469. package/docs/knowledge/log.md +9 -0
  470. package/docs/knowledge/mcp-cancelled-task-precedence.md +41 -0
  471. package/docs/knowledge/mcp-http-prompt-discovery.md +41 -0
  472. package/docs/knowledge/mcp-schema-module-boundary.md +41 -0
  473. package/docs/knowledge/nullable-tool-uniqueness.md +52 -0
  474. package/docs/knowledge/overview-cli.md +74 -0
  475. package/docs/knowledge/overview-coding-proxy.md +72 -0
  476. package/docs/knowledge/overview-coding.md +72 -0
  477. package/docs/knowledge/overview-config.md +60 -0
  478. package/docs/knowledge/overview-core.md +72 -0
  479. package/docs/knowledge/overview-deploy.md +83 -0
  480. package/docs/knowledge/overview-mcp.md +61 -0
  481. package/docs/knowledge/overview-prisma.md +72 -0
  482. package/docs/knowledge/overview-providers.md +89 -0
  483. package/docs/knowledge/overview-sandbox.md +83 -0
  484. package/docs/knowledge/overview-surfaces.md +83 -0
  485. package/docs/knowledge/private-datastore-shared-boundary.md +54 -0
  486. package/docs/knowledge/proxy-settlement-projections.md +41 -0
  487. package/docs/knowledge/run-pricing-first-writer.md +43 -0
  488. package/docs/knowledge/schedule-claim-transaction.md +41 -0
  489. package/docs/knowledge/secret-entry-replica-contract.md +52 -0
  490. package/docs/knowledge/terminal-run-first-writer.md +41 -0
  491. package/docs/knowledge/transactional-agent-authorization.md +52 -0
  492. package/docs/knowledge/viewer-notify-write-isolation.md +30 -0
  493. package/docs/knowledge/warm-input-publication.md +30 -0
  494. package/docs/knowledge/workspace-staging-failure.md +54 -0
  495. package/docs/knowledge.md +54 -14
  496. package/docs/native-sandbox.md +119 -23
  497. package/docs/observability.md +4 -0
  498. package/docs/security-deployment.md +33 -2
  499. package/docs/slack-notifications.md +35 -19
  500. package/docs/tool-secrets.md +42 -10
  501. package/docs/viewer-api.openapi.yml +1 -1
  502. package/help/admin-viewer.md +24 -2
  503. package/help/architecture-agent.md +11 -6
  504. package/help/build-worker-image.md +3 -1
  505. package/help/builder-agent.md +19 -6
  506. package/help/code-review-agents.md +177 -6
  507. package/help/coding-packages.md +156 -6
  508. package/help/cost-attribution.md +9 -5
  509. package/help/creating-agents.md +14 -1
  510. package/help/dependency-cache.md +143 -0
  511. package/help/deploy-gke.md +15 -8
  512. package/help/errors/budget-exhausted.md +187 -0
  513. package/help/errors/budget-group-exhausted.md +5 -1
  514. package/help/errors/coding-stream-quota-exceeded.md +33 -0
  515. package/help/errors/coding-workspace-disk-exceeds-limit.md +39 -0
  516. package/help/errors/continuation-closed.md +9 -12
  517. package/help/errors/delegation-conflict.md +24 -0
  518. package/help/errors/file-list-truncated.md +45 -0
  519. package/help/errors/full-read-required.md +49 -0
  520. package/help/errors/github-account-not-allowed.md +4 -0
  521. package/help/errors/graph-incomplete.md +43 -0
  522. package/help/errors/graph-limit.md +43 -0
  523. package/help/errors/merge-conflict.md +49 -0
  524. package/help/errors/native-sandbox-gateway-error.md +20 -0
  525. package/help/errors/native-sandbox-launch-abandoned.md +21 -0
  526. package/help/errors/native-sandbox-worker-exited.md +3 -2
  527. package/help/errors/package-not-allowed-pending.md +52 -0
  528. package/help/errors/package-not-allowed.md +51 -0
  529. package/help/errors/package-refusals.md +43 -0
  530. package/help/errors/patch-cursor-malformed.md +31 -0
  531. package/help/errors/run-lost.md +39 -0
  532. package/help/errors/run-transcript-download.md +44 -0
  533. package/help/errors/secret-in-value.md +69 -0
  534. package/help/errors/target-merge.md +40 -0
  535. package/help/fix-merge-conflicts.md +73 -0
  536. package/help/github-app-setup.md +132 -0
  537. package/help/github.md +22 -0
  538. package/help/identity-and-access.md +2 -0
  539. package/help/jira.md +23 -6
  540. package/help/knowledge.md +16 -7
  541. package/help/local-repositories.md +1 -1
  542. package/help/low-power-mode.md +7 -1
  543. package/help/merge-order-check.md +5 -0
  544. package/help/native-capabilities.md +29 -1
  545. package/help/native-sandbox.md +15 -1
  546. package/help/operating-agents.md +5 -0
  547. package/help/package-audit-mode.md +91 -0
  548. package/help/related-pull-requests.md +10 -7
  549. package/help/resume-runs-locally.md +131 -0
  550. package/help/review-fix-rounds.md +33 -1
  551. package/help/sharing-agents.md +59 -0
  552. package/help/slack-notifications.md +19 -5
  553. package/help/status-comments.md +31 -0
  554. package/help/stop-run.md +58 -0
  555. package/help/troubleshooting/budgets.md +28 -0
  556. package/help/troubleshooting/coding-workers.md +78 -7
  557. package/package.json +17 -10
  558. package/prisma/migrations/20261016000000_registry_approved_accepted_advisories/migration.sql +3 -0
  559. package/prisma/migrations/20261016000001_mark_ready_when_passing/migration.sql +3 -0
  560. package/prisma/migrations/20261017000000_debug_trace_max_mb/migration.sql +4 -0
  561. package/prisma/migrations/20261018000000_dependency_cache/migration.sql +53 -0
  562. package/prisma/migrations/20261019000000_claude_max_output_tokens/migration.sql +5 -0
  563. package/prisma/migrations/20261021000000_pr_description_hash/migration.sql +4 -0
  564. package/prisma/migrations/20261022000000_dependency_snapshot_validation_metadata/migration.sql +4 -0
  565. package/prisma/migrations/20261023000000_package_audit_mode/migration.sql +27 -0
  566. package/prisma/migrations/20261024000000_budget_events/migration.sql +26 -0
  567. package/prisma/migrations/20261025000000_cache_aware_holds/migration.sql +9 -0
  568. package/prisma/migrations/20261026000000_budget_overrun/migration.sql +4 -0
  569. package/prisma/migrations/20261027000000_coding_run_request/migration.sql +1 -0
  570. package/prisma/migrations/20261028000000_native_gateway_review_reads/migration.sql +6 -0
  571. package/prisma/migrations/20261029000000_lead_survives_deploy/migration.sql +6 -0
  572. package/prisma/migrations/20261030000000_local_review_covered_sha/migration.sql +2 -0
  573. package/prisma/migrations/20261031000000_coding_run_budget_limit/migration.sql +9 -0
  574. package/prisma/migrations/20261101000000_run_transcripts/migration.sql +22 -0
  575. package/prisma/schema.prisma +311 -97
  576. package/dist/sandbox/generated/zod-to-json-schema.bundle.js +0 -5
@@ -13,5 +13,13 @@ export declare class InProcessExecutor implements Executor {
13
13
  private readonly heartbeatIntervalMs;
14
14
  constructor(providers: NativeRunProviders, db?: RunnerDb, heartbeatIntervalMs?: number);
15
15
  start(runId: string): Promise<void>;
16
- stop(_runId: string, _reason?: string): Promise<void>;
16
+ /**
17
+ * Records the run cancelled (only while it is still pending or running: the first terminal write
18
+ * wins) and settles it like any finished run (its review check, status comments, notifications).
19
+ * The engine itself is stopped cooperatively: executeRun's inline step runner reads the run's row
20
+ * before every step (stopAwareStep), so the process executing it, this one or another, stops it
21
+ * at the next step boundary, and a run that has not started yet never does. A step already in
22
+ * flight (one model turn or tool call) finishes first; its spend is still recorded.
23
+ */
24
+ stop(runId: string, reason?: string): Promise<void>;
17
25
  }
@@ -5,7 +5,7 @@
5
5
  * heartbeat and recovers the run to `lost` rather than leaving it stuck
6
6
  * `running` forever.
7
7
  */
8
- import { executeRun } from "../../core/runner.js";
8
+ import { executeRun, failNativeRun, nativeRunIntegrations, RunCancelledError, } from "../../core/runner.js";
9
9
  import { prisma as defaultDb } from "../../core/db.js";
10
10
  import { HEARTBEAT_INTERVAL_MS } from "../../core/timing.js";
11
11
  export class InProcessExecutor {
@@ -31,8 +31,18 @@ export class InProcessExecutor {
31
31
  clearInterval(timer);
32
32
  }
33
33
  }
34
- async stop(_runId, _reason) {
35
- // Native engine cancellation remains cooperative until Engine accepts an
36
- // AbortSignal. The task state still records the caller's request.
34
+ /**
35
+ * Records the run cancelled (only while it is still pending or running: the first terminal write
36
+ * wins) and settles it like any finished run (its review check, status comments, notifications).
37
+ * The engine itself is stopped cooperatively: executeRun's inline step runner reads the run's row
38
+ * before every step (stopAwareStep), so the process executing it, this one or another, stops it
39
+ * at the next step boundary, and a run that has not started yet never does. A step already in
40
+ * flight (one model turn or tool call) finishes first; its spend is still recorded.
41
+ */
42
+ async stop(runId, reason) {
43
+ const run = await this.db.run.findUnique({ where: { id: runId }, select: { status: true } });
44
+ if (!run || (run.status !== "pending" && run.status !== "running"))
45
+ return;
46
+ await failNativeRun({ runId, db: this.db, providers: this.providers, ...nativeRunIntegrations(this.providers, this.db) }, new RunCancelledError(reason ?? "The run was cancelled."));
37
47
  }
38
48
  }
@@ -0,0 +1,16 @@
1
+ import type { IssueTrackerRegistry } from "../issue-tracker/types.js";
2
+ import type { ReviewHostRegistry } from "../review-host/types.js";
3
+ import type { LinkedIssueRef } from "./container.js";
4
+ /**
5
+ * The executor's readLinkedIssue: a GitHub issue through the review host's
6
+ * issue read (the App's installation token for the run's repository), a Jira
7
+ * issue through the configured tracker. Null when the number is a pull
8
+ * request, the issue is missing, or no host or tracker is configured.
9
+ */
10
+ export declare function linkedIssueReader(deps: {
11
+ hosts: ReviewHostRegistry;
12
+ issueTrackers: IssueTrackerRegistry;
13
+ }): (ref: LinkedIssueRef) => Promise<{
14
+ title: string;
15
+ body: string;
16
+ } | null>;
@@ -0,0 +1,30 @@
1
+ /** A tracker read for a continuation's task must not hold up its launch. */
2
+ const TRACKER_READ_TIMEOUT_MS = 10_000;
3
+ /**
4
+ * The executor's readLinkedIssue: a GitHub issue through the review host's
5
+ * issue read (the App's installation token for the run's repository), a Jira
6
+ * issue through the configured tracker. Null when the number is a pull
7
+ * request, the issue is missing, or no host or tracker is configured.
8
+ */
9
+ export function linkedIssueReader(deps) {
10
+ return async (ref) => {
11
+ if (ref.provider === "github") {
12
+ const host = deps.hosts.github;
13
+ if (!host?.readIssue)
14
+ return null;
15
+ // Title and body only: the task carries the ticket, not its discussion.
16
+ const result = await host.readIssue(ref.repository, ref.number, { comments: false });
17
+ return result.kind === "issue" ? { title: result.title, body: result.body } : null;
18
+ }
19
+ const tracker = deps.issueTrackers.jira;
20
+ if (!tracker)
21
+ return null;
22
+ const view = await tracker.getIssue(ref.key, {
23
+ maxComments: 0,
24
+ agentMarker: "",
25
+ timeoutMs: TRACKER_READ_TIMEOUT_MS,
26
+ retryOn429: false,
27
+ });
28
+ return { title: view.summary, body: view.description };
29
+ };
30
+ }
@@ -37,6 +37,8 @@ export declare class RoutingExecutor implements Executor {
37
37
  * backend name.
38
38
  */
39
39
  recover(handle: PersistedExecutionHandle): Promise<ExecutionRecoveryResult>;
40
+ /** Only coding runs wait in the coding queue, so only the coding executor is asked. */
41
+ cleanupQueueTimeout(runId: string): Promise<void>;
40
42
  /** Each distinct executor once, in a fixed order: native, coding, sandbox. */
41
43
  private distinct;
42
44
  /** Lifecycle fans out to every distinct executor; each hook is optional on the seam. */
@@ -63,6 +63,10 @@ export class RoutingExecutor {
63
63
  }
64
64
  return executor.recover(handle);
65
65
  }
66
+ /** Only coding runs wait in the coding queue, so only the coding executor is asked. */
67
+ async cleanupQueueTimeout(runId) {
68
+ await this.coding.cleanupQueueTimeout?.(runId);
69
+ }
66
70
  /** Each distinct executor once, in a fixed order: native, coding, sandbox. */
67
71
  distinct() {
68
72
  return [this.native, this.coding, this.sandbox].filter((executor, index, all) => executor !== undefined && all.indexOf(executor) === index);
@@ -35,6 +35,14 @@ export interface Executor {
35
35
  * terminal Run persistence completed. Recovery must never relaunch a job.
36
36
  */
37
37
  recover?: (handle: PersistedExecutionHandle) => Promise<ExecutionRecoveryResult>;
38
+ /**
39
+ * Called by drainCodingQueue for each queued coding run it failed with coding_queue_timeout, after
40
+ * that write: releases what an earlier attempt of the run left (a launch the backend refused for
41
+ * capacity), such as a continuation's in-progress host signal and its input artifact. Best effort;
42
+ * a throw is logged by the caller. Optional: an executor that never leaves a queued run anything
43
+ * to release omits it.
44
+ */
45
+ cleanupQueueTimeout?: (runId: string) => Promise<void>;
38
46
  /**
39
47
  * Optional one-time startup. A durable backend connects and re-drives the
40
48
  * workflows it owned before the last restart. Composition roots call it
@@ -97,5 +105,10 @@ export interface Executor {
97
105
  * in). MCP refuses to set an agent to sandbox mode where it cannot (docs/native-sandbox.md).
98
106
  */
99
107
  supportsNativeSandbox?(): boolean;
108
+ /**
109
+ * true: this executor cannot resolve coding inputs; dispatch records the coding run unresolved
110
+ * and the process that starts it resolves them (resolveDeferredCodingRun).
111
+ */
112
+ defersCodingResolution?: boolean;
100
113
  }
101
114
  import type { CodingProvider } from "../../coding/provider.js";
@@ -34,7 +34,8 @@ export interface ProviderRegistry {
34
34
  llm: LlmProvider;
35
35
  secrets: SecretCipher;
36
36
  auth: AuthProvider;
37
- storage: BlobStore;
37
+ /** Absent unless BLOB_STORE is configured. */
38
+ storage?: BlobStore;
38
39
  executor: Executor;
39
40
  datastore: Datastore;
40
41
  memory: AgentMemoryStore;
@@ -264,6 +264,23 @@ export interface IssueEvent {
264
264
  }
265
265
  /** Shared by the ingress and the tools: a Jira issue key, e.g. PROJ-123. */
266
266
  export declare const ISSUE_KEY: RegExp;
267
+ /** A GitHub issue's recorded key (githubIssueKey): "<owner>/<repo>#<number>", the repository normalised to lowercase. */
268
+ export declare const GITHUB_ISSUE_KEY: RegExp;
269
+ /** The product name of each system an issue can be recorded from (CodingRun / IssuePullRequest issueProvider). */
270
+ export declare const ISSUE_SOURCE_NAMES: Readonly<Record<string, string>>;
271
+ /**
272
+ * A recorded issue (CodingRun / IssuePullRequest issueProvider + issueKey) as
273
+ * people see it: the key re-validated for its provider, the system's name and
274
+ * the issue's page. A GitHub issue's page comes from its key; a tracker
275
+ * issue's from `trackerUrl` (the tracker's issueUrl), dropped when it throws
276
+ * or is not https. Undefined for an unknown provider or a malformed key.
277
+ */
278
+ export declare function issueReference(provider: string, key: string, trackerUrl?: (key: string) => string | undefined): {
279
+ key: string;
280
+ url?: string;
281
+ trackerName: string;
282
+ } | undefined;
267
283
  /** A Jira project key. */
268
284
  export declare const PROJECT_KEY: RegExp;
285
+ /** An issue key's project: a Jira key's project key ("PROJ-123" → "PROJ"); a GitHub issue key's repository ("owner/repo#5" → "owner/repo"). */
269
286
  export declare const projectOf: (issueKey: string) => string;
@@ -11,6 +11,44 @@ export class IssueTrackerError extends Error {
11
11
  }
12
12
  /** Shared by the ingress and the tools: a Jira issue key, e.g. PROJ-123. */
13
13
  export const ISSUE_KEY = /^[A-Z][A-Z0-9_]{0,254}-[1-9]\d{0,9}$/;
14
+ /** A GitHub issue's recorded key (githubIssueKey): "<owner>/<repo>#<number>", the repository normalised to lowercase. */
15
+ export const GITHUB_ISSUE_KEY = /^[a-z0-9](?:[a-z0-9-]{0,37}[a-z0-9])?\/[a-z0-9._-]{1,100}#[1-9]\d{0,9}$/;
16
+ /** The product name of each system an issue can be recorded from (CodingRun / IssuePullRequest issueProvider). */
17
+ export const ISSUE_SOURCE_NAMES = { ...ISSUE_TRACKER_NAMES, github: "GitHub" };
18
+ /**
19
+ * A recorded issue (CodingRun / IssuePullRequest issueProvider + issueKey) as
20
+ * people see it: the key re-validated for its provider, the system's name and
21
+ * the issue's page. A GitHub issue's page comes from its key; a tracker
22
+ * issue's from `trackerUrl` (the tracker's issueUrl), dropped when it throws
23
+ * or is not https. Undefined for an unknown provider or a malformed key.
24
+ */
25
+ export function issueReference(provider, key, trackerUrl) {
26
+ let url;
27
+ if (provider === "github") {
28
+ if (!GITHUB_ISSUE_KEY.test(key))
29
+ return undefined;
30
+ const hash = key.lastIndexOf("#");
31
+ url = `https://github.com/${key.slice(0, hash)}/issues/${key.slice(hash + 1)}`;
32
+ }
33
+ else if (provider === "jira") {
34
+ if (!ISSUE_KEY.test(key))
35
+ return undefined;
36
+ try {
37
+ url = trackerUrl?.(key);
38
+ }
39
+ catch {
40
+ url = undefined;
41
+ }
42
+ }
43
+ else {
44
+ return undefined;
45
+ }
46
+ return { key, ...(url?.startsWith("https://") ? { url } : {}), trackerName: ISSUE_SOURCE_NAMES[provider] };
47
+ }
14
48
  /** A Jira project key. */
15
49
  export const PROJECT_KEY = /^[A-Z][A-Z0-9_]{0,254}$/;
16
- export const projectOf = (issueKey) => issueKey.slice(0, issueKey.lastIndexOf("-"));
50
+ /** An issue key's project: a Jira key's project key ("PROJ-123" → "PROJ"); a GitHub issue key's repository ("owner/repo#5" → "owner/repo"). */
51
+ export const projectOf = (issueKey) => {
52
+ const hash = issueKey.lastIndexOf("#");
53
+ return issueKey.slice(0, hash >= 0 ? hash : issueKey.lastIndexOf("-"));
54
+ };
@@ -19,5 +19,9 @@ export interface ClaudeToolSetup {
19
19
  content: string;
20
20
  mode: number;
21
21
  }[];
22
+ /** Present only when the run's dependency cache is on, so older tool runners see an unchanged setup. */
23
+ dependencyCache?: true;
24
+ /** With dependencyCache only: the workspace volume size (limits.diskMb) the cache must stay inside. */
25
+ diskMb?: number;
22
26
  }
23
27
  export declare function claudeToolSetup(spec: JobSpec, capability: string): string;
@@ -2,8 +2,10 @@
2
2
  * What Claude Code's tool runner (the credential-free container that runs commands in the
3
3
  * repository) needs from the trusted launcher: the package-registry settings every Codex shell
4
4
  * gets, built from the run's registry-only token (deriveRegistryToken, never the capability), and
5
- * the run's service test variables. Delivered as CLAUDE_TOOL_SETUP_ENV: a Kubernetes Secret key, or
6
- * `docker create --env NAME` with the value in the CLI's own environment.
5
+ * the run's service test variables, and whether the run's dependency cache is on. Delivered as the
6
+ * WARDBY_TOOL_SETUP environment variable (CLAUDE_TOOL_SETUP_ENV, docker-isolation.ts; a test keeps it
7
+ * equal to the tool runner's TOOL_SETUP_ENV): a Kubernetes Secret key, or `docker create --env NAME`
8
+ * with the value in the CLI's own environment.
7
9
  */
8
10
  import { serviceEnvironment } from "../../coding-worker/driver.js";
9
11
  import { registryWorkerSetup } from "../../coding/registry/worker-config.js";
@@ -35,6 +37,7 @@ export function claudeToolSetup(spec, capability) {
35
37
  // Same precedence as the Codex driver: the registry's own settings win over a service's.
36
38
  env: { ...serviceEnvironment(spec.services), ...registry.env },
37
39
  files: registry.files,
40
+ ...(spec.dependencyCache ? { dependencyCache: true, diskMb: spec.limits.diskMb } : {}),
38
41
  };
39
42
  const raw = JSON.stringify(setup);
40
43
  const limits = CLAUDE_TOOL_SETUP_LIMITS;
@@ -25,6 +25,14 @@ export declare const CLAUDE_TOOL_SETUP_ENV = "WARDBY_TOOL_SETUP";
25
25
  export declare const CODING_PROXY_DENY_PORT = 8788;
26
26
  export declare const DOCKER_ISOLATION_ERROR = "docker_isolation_unsupported";
27
27
  export declare const WORKER_STOP_GRACE_SECONDS = 10;
28
+ /** The Claude worker's SDK config dir (claude-coding-worker/driver.ts CLAUDE_CONFIG_DIR). */
29
+ export declare const CLAUDE_CONFIG_PATH = "/tmp/claude-config";
30
+ /**
31
+ * Its own memory-backed scratch on a session-resume run: room for a session file up to the largest the
32
+ * control plane reads (coding/protocol.ts MAX_RAW_TRANSCRIPT_BYTES, 64 MiB) plus the SDK's small config
33
+ * files. Past it the SDK's writes there fail with ENOSPC, as /tmp's would; /tmp itself keeps its room.
34
+ */
35
+ export declare const CLAUDE_CONFIG_SCRATCH_MIB = 80;
28
36
  export declare const WORKER_PATHS: {
29
37
  readonly workspace: "/workspace";
30
38
  readonly git: "/workspace/.git";
@@ -28,6 +28,14 @@ export const CLAUDE_TOOL_SETUP_ENV = "WARDBY_TOOL_SETUP";
28
28
  export const CODING_PROXY_DENY_PORT = 8788;
29
29
  export const DOCKER_ISOLATION_ERROR = "docker_isolation_unsupported";
30
30
  export const WORKER_STOP_GRACE_SECONDS = 10;
31
+ /** The Claude worker's SDK config dir (claude-coding-worker/driver.ts CLAUDE_CONFIG_DIR). */
32
+ export const CLAUDE_CONFIG_PATH = "/tmp/claude-config";
33
+ /**
34
+ * Its own memory-backed scratch on a session-resume run: room for a session file up to the largest the
35
+ * control plane reads (coding/protocol.ts MAX_RAW_TRANSCRIPT_BYTES, 64 MiB) plus the SDK's small config
36
+ * files. Past it the SDK's writes there fail with ENOSPC, as /tmp's would; /tmp itself keeps its room.
37
+ */
38
+ export const CLAUDE_CONFIG_SCRATCH_MIB = 80;
31
39
  export const WORKER_PATHS = {
32
40
  workspace: "/workspace",
33
41
  git: "/workspace/.git",
@@ -90,6 +98,9 @@ function validateSpec(spec) {
90
98
  else if (spec.toolImage !== undefined) {
91
99
  throw isolationError();
92
100
  }
101
+ if (spec.sessionResume !== undefined && (spec.sessionResume !== true || spec.provider !== "claude-code")) {
102
+ throw isolationError();
103
+ }
93
104
  if (spec.services !== undefined) {
94
105
  // docker-services.ts re-validates every entry against the catalog schema. Both providers' shells
95
106
  // share the network keeper's namespace: Codex's worker, and Claude Code's tool runner.
@@ -432,6 +443,12 @@ export function buildClaudeAgentCreateArgs(spec, proxyPort = CODING_PROXY_PORT)
432
443
  `/tmp:rw,noexec,nosuid,nodev,size=${scratchMb}m,mode=1777`,
433
444
  "--tmpfs",
434
445
  `/home/wardby:rw,noexec,nosuid,nodev,size=${scratchMb}m,uid=${CODING_WORKER_UID},gid=${CODING_WORKER_GID},mode=0700`,
446
+ ...(spec.sessionResume
447
+ ? [
448
+ "--tmpfs",
449
+ `${CLAUDE_CONFIG_PATH}:rw,noexec,nosuid,nodev,size=${CLAUDE_CONFIG_SCRATCH_MIB}m,uid=${CODING_WORKER_UID},gid=${CODING_WORKER_GID},mode=0700`,
450
+ ]
451
+ : []),
435
452
  "--mount",
436
453
  `type=volume,src=${names.storageVolume},dst=${WORKER_PATHS.input},volume-subpath=input,volume-nocopy,readonly`,
437
454
  "--mount",
@@ -164,6 +164,7 @@ export declare class DockerJobLauncher implements WorkspaceJobLauncher {
164
164
  private removeNetworkIfAttested;
165
165
  private removeVolumeIfAttested;
166
166
  private seedRun;
167
+ readTranscript(handle: JobHandle, maxBytes: number): Promise<string | undefined>;
167
168
  private readResultArtifact;
168
169
  private readWorkerFailureDiagnostic;
169
170
  private keeperName;
@@ -7,7 +7,7 @@ import { dirname, isAbsolute, join, resolve, sep } from "node:path";
7
7
  import { logger } from "../../core/logger.js";
8
8
  import { ensurePrivateDirectory } from "../../core/private-directory.js";
9
9
  import { readBoundedRegularFile } from "../../coding-worker/artifact.js";
10
- import { parseCodingAgentOutputJson, redactAndTruncate, MAX_CODING_ARTIFACT_BYTES, MAX_CODING_INPUT_BYTES, MAX_CODING_OUTPUT_ISSUES, SAFE_CODING_OUTPUT_ISSUE, } from "../../coding/protocol.js";
10
+ import { parseCodingWorkerOutputJson, redactAndTruncate, MAX_CODING_ARTIFACT_BYTES, MAX_CODING_INPUT_BYTES, MAX_CODING_OUTPUT_ISSUES, SAFE_CODING_OUTPUT_ISSUE, } from "../../coding/protocol.js";
11
11
  import { assertDockerHostSupportsIsolation, assertClaudeAgentContainerInspection, assertClaudeToolRunnerContainerInspection, assertIsolationNetworkInspection, assertKeeperContainerInspection, assertNetworkKeeperContainerInspection, assertProxyContainerInspection, assertStorageVolumeInspection, assertWorkerContainerInspection, buildDockerIsolationPlan, CLAUDE_TOOL_SETUP_ENV, dockerSupportsServicesFor, } from "./docker-isolation.js";
12
12
  import { serviceUnreadyError } from "../../coding/services/wording.js";
13
13
  import { assertServiceContainerInspection, buildDockerServicePlan, dockerServiceContainerNames, } from "./docker-services.js";
@@ -1067,13 +1067,38 @@ export class DockerJobLauncher {
1067
1067
  await this.transfer.seedDirectory(resolve(runRoot, "git"), keeper, "/run/wardby/storage/git");
1068
1068
  await this.transfer.seedInput(record.spec.inputArtifact, keeper);
1069
1069
  }
1070
+ async readTranscript(handle, maxBytes) {
1071
+ await this.ready;
1072
+ const record = await this.findRecord(handle);
1073
+ if (!record)
1074
+ return undefined;
1075
+ const staging = await mkdtemp(join(this.stateRoot, ".wardby-transcript-"));
1076
+ const target = join(staging, "session.jsonl");
1077
+ try {
1078
+ try {
1079
+ await this.run([
1080
+ "container",
1081
+ "cp",
1082
+ `${this.keeperName(record)}:/run/wardby/storage/output/session.jsonl`,
1083
+ target,
1084
+ ]);
1085
+ }
1086
+ catch {
1087
+ return undefined;
1088
+ }
1089
+ return await readBoundedRegularFile(target, maxBytes, "transcript_too_large");
1090
+ }
1091
+ finally {
1092
+ await rm(staging, { recursive: true, force: true });
1093
+ }
1094
+ }
1070
1095
  async readResultArtifact(record) {
1071
1096
  const staging = await mkdtemp(join(this.stateRoot, ".wardby-result-"));
1072
1097
  const target = join(staging, "result.json");
1073
1098
  try {
1074
1099
  await this.run(["container", "cp", `${this.keeperName(record)}:/run/wardby/storage/output/result.json`, target]);
1075
1100
  const raw = await readBoundedRegularFile(target, MAX_CODING_ARTIFACT_BYTES, "docker_result_artifact_invalid");
1076
- const output = parseCodingAgentOutputJson(raw);
1101
+ const output = parseCodingWorkerOutputJson(raw);
1077
1102
  if (output.runId !== record.runId)
1078
1103
  throw new Error("docker_result_run_mismatch");
1079
1104
  return JSON.stringify(output);
@@ -31,6 +31,8 @@ export declare class FakeKubernetesApi implements KubernetesApi {
31
31
  onExec: (call: FakeExecCall) => Promise<number>;
32
32
  /** The admission chain a dry-run create runs through. Default: echo the pod back unchanged. */
33
33
  onDryRunCreatePod: (namespace: string, body: V1Pod) => Promise<V1Pod>;
34
+ /** Runs at the start of every pod create; tests throw KubernetesQuotaExceededError (or anything) from it. */
35
+ onCreatePod: (namespace: string, body: V1Pod) => Promise<void>;
34
36
  readonly deploymentPatches: Array<{
35
37
  name: string;
36
38
  replicas?: number;
@@ -13,6 +13,8 @@ export class FakeKubernetesApi {
13
13
  };
14
14
  /** The admission chain a dry-run create runs through. Default: echo the pod back unchanged. */
15
15
  onDryRunCreatePod = async (_namespace, body) => body;
16
+ /** Runs at the start of every pod create; tests throw KubernetesQuotaExceededError (or anything) from it. */
17
+ onCreatePod = async () => { };
16
18
  deploymentPatches = [];
17
19
  /** Deployment names whose patch throws KubernetesForbiddenError. */
18
20
  forbidden = new Set();
@@ -83,6 +85,7 @@ export class FakeKubernetesApi {
83
85
  this.delete("secret", namespace, name);
84
86
  }
85
87
  async createPod(namespace, body) {
88
+ await this.onCreatePod(namespace, body);
86
89
  return this.create("pod", namespace, body);
87
90
  }
88
91
  /**
@@ -12,6 +12,14 @@ export declare class KubernetesNotFoundError extends Error {
12
12
  export declare class KubernetesForbiddenError extends Error {
13
13
  constructor(message?: string, options?: ErrorOptions);
14
14
  }
15
+ /** A create the namespace ResourceQuota refused (HTTP 403 "exceeded quota"). */
16
+ export declare class KubernetesQuotaExceededError extends Error {
17
+ /** The refusing quota's name as the API server worded it; unvalidated, and nothing else of the refusal is kept. */
18
+ readonly quotaName?: string;
19
+ constructor(message?: string, options?: ErrorOptions & {
20
+ quotaName?: string;
21
+ });
22
+ }
15
23
  /** Stale resourceVersion on replace. */
16
24
  export declare class KubernetesConflictError extends Error {
17
25
  constructor(message?: string);
@@ -11,6 +11,16 @@ export class KubernetesForbiddenError extends Error {
11
11
  this.name = "KubernetesForbiddenError";
12
12
  }
13
13
  }
14
+ /** A create the namespace ResourceQuota refused (HTTP 403 "exceeded quota"). */
15
+ export class KubernetesQuotaExceededError extends Error {
16
+ /** The refusing quota's name as the API server worded it; unvalidated, and nothing else of the refusal is kept. */
17
+ quotaName;
18
+ constructor(message, options) {
19
+ super(message, options);
20
+ this.name = "KubernetesQuotaExceededError";
21
+ this.quotaName = options?.quotaName;
22
+ }
23
+ }
14
24
  /** Stale resourceVersion on replace. */
15
25
  export class KubernetesConflictError extends Error {
16
26
  constructor(message) {
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { ApiException, AppsV1Api, AuthorizationV1Api, CoreV1Api, Exec, KubeConfig, NetworkingV1Api, PatchStrategy, setHeaderOptions, VersionApi, } from "@kubernetes/client-node";
7
7
  import { Writable } from "node:stream";
8
- import { KubernetesAlreadyExistsError, KubernetesConflictError, KubernetesForbiddenError, KubernetesNotFoundError, } from "./kubernetes-api.js";
8
+ import { KubernetesAlreadyExistsError, KubernetesConflictError, KubernetesForbiddenError, KubernetesNotFoundError, KubernetesQuotaExceededError, } from "./kubernetes-api.js";
9
9
  function statusCode(error) {
10
10
  return error instanceof ApiException ? error.code : undefined;
11
11
  }
@@ -44,6 +44,11 @@ async function deleteIgnoringMissing(remove) {
44
44
  throw error;
45
45
  }
46
46
  }
47
+ /** The error's message plus its body as text, for matching only; never copied into a thrown message. */
48
+ function bodyText(error) {
49
+ const { body, message } = error;
50
+ return `${message}\n${typeof body === "string" ? body : JSON.stringify(body ?? "")}`;
51
+ }
47
52
  async function create(what, write) {
48
53
  try {
49
54
  return await write();
@@ -54,6 +59,10 @@ async function create(what, write) {
54
59
  throw new KubernetesAlreadyExistsError(what);
55
60
  if (code === 404)
56
61
  throw new KubernetesNotFoundError(what);
62
+ if (code === 403 && /exceeded quota/i.test(bodyText(error))) {
63
+ const quotaName = /exceeded quota: ([^\s,"\\]+)/i.exec(bodyText(error))?.[1];
64
+ throw new KubernetesQuotaExceededError(`exceeded quota: ${what}`, { cause: error, quotaName });
65
+ }
57
66
  throw error;
58
67
  }
59
68
  }
@@ -1,6 +1,7 @@
1
1
  import type { V1Container, V1NetworkPolicy, V1Pod, V1Secret } from "@kubernetes/client-node";
2
2
  import { type ResolvedCodingService } from "../../coding/services/catalog.js";
3
3
  import type { JobSpec } from "./types.js";
4
+ import { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB } from "./docker-isolation.js";
4
5
  import { type KubernetesPlatform } from "./kubernetes-platform.js";
5
6
  export declare const KUBERNETES_ISOLATION_ERROR = "kubernetes_isolation_unsupported";
6
7
  /** Extra seconds past timeoutSec before Kubernetes kills the pod (keeper included). */
@@ -51,6 +52,7 @@ export declare const ENFORCEMENT_PROBE_PROXY_UNREACHABLE = 4;
51
52
  * blocking the path — the port is reachable-but-unserved and witnesses nothing.
52
53
  */
53
54
  export declare const ENFORCEMENT_PROBE_DENY_REFUSED = 5;
55
+ export { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB };
54
56
  export interface KubernetesRunNames {
55
57
  token: string;
56
58
  runSha: string;
@@ -7,7 +7,7 @@
7
7
  import { createHash } from "node:crypto";
8
8
  import { isIP } from "node:net";
9
9
  import { StoredCodingServicesSchema } from "../../coding/services/catalog.js";
10
- import { CLAUDE_TOOL_SETUP_ENV, CODING_PROXY_ALIAS, CODING_PROXY_DENY_PORT, CODING_PROXY_PORT, CODING_WORKER_GID, CODING_WORKER_UID, WORKER_STOP_GRACE_SECONDS, claudeToolLimits, isRepositoryDigest, } from "./docker-isolation.js";
10
+ import { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB, CLAUDE_TOOL_SETUP_ENV, CODING_PROXY_ALIAS, CODING_PROXY_DENY_PORT, CODING_PROXY_PORT, CODING_WORKER_GID, CODING_WORKER_UID, WORKER_STOP_GRACE_SECONDS, claudeToolLimits, isRepositoryDigest, } from "./docker-isolation.js";
11
11
  import { GVISOR_RUNTIME_CLASS, KubernetesPlatformError, STORAGE_INIT_EPHEMERAL_MIB, TOOL_RUNNER_EPHEMERAL_MIB, WORKER_EPHEMERAL_MIB, conformResources, describeMib, normalizePlatformMetadata, platformProfile, podEphemeralStorageMib, } from "./kubernetes-platform.js";
12
12
  export const KUBERNETES_ISOLATION_ERROR = "kubernetes_isolation_unsupported";
13
13
  /** Extra seconds past timeoutSec before Kubernetes kills the pod (keeper included). */
@@ -97,6 +97,9 @@ const STORAGE_DIRECTORIES = ["workspace", "input", "output"];
97
97
  * sandbox (GKE Autopilot annotates it `share: pod`), so the agent's relay can connect.
98
98
  */
99
99
  const TOOL_SOCKET_VOLUME = "tool-socket";
100
+ /** Session resume only: the Claude worker's SDK config dir (docker-isolation.ts CLAUDE_CONFIG_SCRATCH_MIB). */
101
+ const CLAUDE_CONFIG_VOLUME = "claude-config";
102
+ export { CLAUDE_CONFIG_PATH, CLAUDE_CONFIG_SCRATCH_MIB };
100
103
  const TOOL_SOCKET_VOLUME_MIB = 1;
101
104
  /**
102
105
  * `reason` is a short, fixed code naming which check failed (never a value from the spec itself,
@@ -166,6 +169,9 @@ export function validateKubernetesSpec(spec) {
166
169
  else if (spec.toolImage !== undefined) {
167
170
  throw isolationError("tool-image-set");
168
171
  }
172
+ if (spec.sessionResume !== undefined && (spec.sessionResume !== true || spec.provider !== "claude-code")) {
173
+ throw isolationError("session-resume-not-claude");
174
+ }
169
175
  if (!isRegistryDigest(spec.image))
170
176
  throw isolationError("image-not-registry-digest");
171
177
  if (spec.services !== undefined) {
@@ -322,6 +328,8 @@ export function buildRunPod(spec, options) {
322
328
  { name: TOOL_SOCKET_VOLUME, mountPath: "/run/wardby/tool" },
323
329
  { name: "tmp", mountPath: "/tmp" },
324
330
  { name: "home", mountPath: "/home/wardby" },
331
+ // Session resume: the SDK's config dir, where the session file grows, off /tmp's budget.
332
+ ...(spec.sessionResume ? [{ name: CLAUDE_CONFIG_VOLUME, mountPath: CLAUDE_CONFIG_PATH }] : []),
325
333
  ]
326
334
  : [
327
335
  { name: "storage", mountPath: "/workspace", subPath: "workspace" },
@@ -414,6 +422,14 @@ export function buildRunPod(spec, options) {
414
422
  { name: TOOL_SOCKET_VOLUME, emptyDir: { medium: "Memory", sizeLimit: `${TOOL_SOCKET_VOLUME_MIB}Mi` } },
415
423
  { name: "tool-tmp", emptyDir: { medium: "Memory", sizeLimit: `${toolScratchMb}Mi` } },
416
424
  { name: "tool-home", emptyDir: { medium: "Memory", sizeLimit: `${toolScratchMb}Mi` } },
425
+ ...(spec.sessionResume
426
+ ? [
427
+ {
428
+ name: CLAUDE_CONFIG_VOLUME,
429
+ emptyDir: { medium: "Memory", sizeLimit: `${CLAUDE_CONFIG_SCRATCH_MIB}Mi` },
430
+ },
431
+ ]
432
+ : []),
417
433
  ]
418
434
  : []),
419
435
  ...serviceVolumes(services),
@@ -4,7 +4,7 @@ import { type Power } from "../../core/power.js";
4
4
  import { type KubernetesApi } from "./kubernetes-api.js";
5
5
  import { type ServiceStateReporter } from "./service-state.js";
6
6
  import type { CodingProvider } from "../../coding/provider.js";
7
- import type { JobHandle, JobResult, JobSpec, JobStatus, WorkspaceJobLauncher } from "./types.js";
7
+ import { type JobHandle, type JobResult, type JobSpec, type JobStatus, type WorkspaceJobLauncher } from "./types.js";
8
8
  export interface KubernetesClusterInfo {
9
9
  /** The proxy Service's ClusterIP: the enforcement witness's address (8787 reachable, 8788 not). */
10
10
  proxyIp: string;
@@ -165,6 +165,10 @@ export declare class KubernetesJobLauncher implements WorkspaceJobLauncher {
165
165
  * must not open the gate at the initial proof either.
166
166
  */
167
167
  private waitForPolicyEnforcement;
168
+ /** True when `found` is a requeued record for this spec, which launch() replaces with a fresh one. */
169
+ private isRequeued;
170
+ /** Tells the operator once that a quota refused a pod while no quota is configured for the pre-launch check. */
171
+ private hintQuotaUnconfigured;
168
172
  private existingLaunch;
169
173
  private provision;
170
174
  private createIfMissing;
@@ -178,6 +182,7 @@ export declare class KubernetesJobLauncher implements WorkspaceJobLauncher {
178
182
  private refresh;
179
183
  /** Reads only a fixed diagnostic code from a failed worker's bounded log tail; never keeps anything else. */
180
184
  private readWorkerDiagnostic;
185
+ readTranscript(handle: JobHandle, maxBytes: number): Promise<string | undefined>;
181
186
  private readResultArtifact;
182
187
  /**
183
188
  * Streams the keeper's workspace through the strict extractor into `staging`.