@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
@@ -0,0 +1,152 @@
1
+ import { lastPusher } from "./budget-stopped-head.js";
2
+ import { pullRequestOutcome } from "./host-status.js";
3
+ import { MERGE_ORDER_CHECK_NAME } from "./merge-order-check.js";
4
+ const CI_GREEN = new Set(["passing", "none"]);
5
+ /** How far up the run tree (Run.parentRunId) the opt-in may come from. */
6
+ const MAX_ANCESTOR_HOPS = 10;
7
+ const CODING_RUN_SELECT = {
8
+ runId: true,
9
+ repository: true,
10
+ rootCodingRunId: true,
11
+ markedReadyAt: true,
12
+ result: true,
13
+ run: { select: { agentId: true, parentRunId: true, status: true } },
14
+ };
15
+ const passed = (c) => c !== undefined && c.status === "completed" && c.conclusion === "success";
16
+ export async function maybeMarkReady(deps, repository, prNumber, provider = "github") {
17
+ try {
18
+ const host = deps.hosts?.[provider];
19
+ if (!host?.pullRequestOrigin || !host.readOwnChecks || !host.readCi || !host.markReadyForReview)
20
+ return "off";
21
+ const links = await deps.db.agentRepository.findMany({
22
+ where: { provider, repository },
23
+ select: {
24
+ agentId: true,
25
+ access: true,
26
+ triggers: true,
27
+ checkName: true,
28
+ markReadyWhenPassing: true,
29
+ authorizedVia: true,
30
+ },
31
+ });
32
+ const optedIn = new Set(links
33
+ .filter((l) => l.access === "write" && l.authorizedVia !== null && l.markReadyWhenPassing)
34
+ .map((l) => l.agentId));
35
+ if (optedIn.size === 0)
36
+ return "off";
37
+ const reviewChecks = links
38
+ .filter((l) => l.access === "write" && l.authorizedVia !== null && l.triggers.includes("pull_request") && l.checkName)
39
+ .map((l) => l.checkName);
40
+ if (reviewChecks.length === 0)
41
+ return "not_ready";
42
+ // readOwnChecks reads at most 10 names; MERGE_ORDER_CHECK_NAME plus the reviewer
43
+ // check names must fit, or the merge-order check would silently be read as absent.
44
+ if (reviewChecks.length > 9)
45
+ return "not_ready";
46
+ const origin = await host.pullRequestOrigin(repository, prNumber);
47
+ if (origin.state !== "open" || origin.draft !== true || origin.isFork || !origin.markerRunId)
48
+ return "not_ready";
49
+ const marked = await deps.db.codingRun.findUnique({
50
+ where: { runId: origin.markerRunId },
51
+ select: CODING_RUN_SELECT,
52
+ });
53
+ if (!marked)
54
+ return "not_ready";
55
+ const root = marked.rootCodingRunId
56
+ ? await deps.db.codingRun.findUnique({ where: { runId: marked.rootCodingRunId }, select: CODING_RUN_SELECT })
57
+ : marked;
58
+ if (!root || root.repository.toLowerCase() !== repository.toLowerCase())
59
+ return "not_ready";
60
+ if (pullRequestOutcome(root.result)?.pullRequestNumber !== prNumber)
61
+ return "not_ready";
62
+ if (!(await optedInInRunTree(deps.db, root.run, optedIn)))
63
+ return "not_ready";
64
+ if (root.markedReadyAt)
65
+ return "skipped";
66
+ if (await lastPushStoppedAtBudget(deps.db, root, prNumber))
67
+ return "not_ready";
68
+ const checks = await host.readOwnChecks(repository, origin.headSha, [MERGE_ORDER_CHECK_NAME, ...reviewChecks]);
69
+ if (!reviewChecks.every((name) => passed(checks.get(name))))
70
+ return "not_ready";
71
+ const order = checks.get(MERGE_ORDER_CHECK_NAME);
72
+ if (order !== undefined && !passed(order))
73
+ return "not_ready";
74
+ const ci = await host.readCi(repository, origin.headSha);
75
+ if (!CI_GREEN.has(ci.state) || ci.truncated)
76
+ return "not_ready";
77
+ const claimedAt = new Date();
78
+ // CodingRun.updatedAt is @updatedAt, so this claim (and a release below) bumps it, which
79
+ // feeds the merge-order sweep's ordering. Harmless: the sweep re-derives state from the
80
+ // host each time, it doesn't rely on updatedAt being untouched by mark-ready.
81
+ const claim = await deps.db.codingRun.updateMany({
82
+ where: { runId: root.runId, markedReadyAt: null },
83
+ data: { markedReadyAt: claimedAt },
84
+ });
85
+ if (claim.count === 0)
86
+ return "skipped";
87
+ const release = () => deps.db.codingRun
88
+ .updateMany({ where: { runId: root.runId, markedReadyAt: claimedAt }, data: { markedReadyAt: null } })
89
+ .catch((err) => deps.log?.warn({ err, repository, prNumber }, "could not release the mark-ready claim"));
90
+ try {
91
+ const result = await host.markReadyForReview(repository, prNumber, origin.headSha, origin.markerRunId);
92
+ if (result === "marked") {
93
+ deps.log?.info({ repository, prNumber }, "marked the pull request ready for review");
94
+ return "marked";
95
+ }
96
+ await release();
97
+ return "skipped";
98
+ }
99
+ catch (err) {
100
+ await release();
101
+ throw err;
102
+ }
103
+ }
104
+ catch (err) {
105
+ deps.log?.warn({ err, repository, prNumber }, "could not mark the pull request ready for review");
106
+ return "failed";
107
+ }
108
+ }
109
+ /**
110
+ * Whether the last run that pushed to the pull request (the root, or a later continuation of it)
111
+ * stopped at its budget: its pushed changes are unfinished work, so the draft stays a draft. A
112
+ * continuation that finished the work makes it eligible again.
113
+ */
114
+ async function lastPushStoppedAtBudget(db, root, prNumber) {
115
+ return (await lastPusher(db, root, prNumber)).status === "budget_exhausted";
116
+ }
117
+ /**
118
+ * True when the opener's agent, or an agent up its run tree (bounded, cycle-safe), is opted in.
119
+ * A coding run's parentRunId is set when a lead delegated to it.
120
+ */
121
+ async function optedInInRunTree(db, opener, optedIn) {
122
+ if (optedIn.has(opener.agentId))
123
+ return true;
124
+ const seen = new Set();
125
+ let next = opener.parentRunId ?? null;
126
+ for (let hop = 0; next && hop < MAX_ANCESTOR_HOPS && !seen.has(next); hop++) {
127
+ seen.add(next);
128
+ const run = await db.run.findUnique({ where: { id: next }, select: { agentId: true, parentRunId: true } });
129
+ if (!run)
130
+ return false;
131
+ if (optedIn.has(run.agentId))
132
+ return true;
133
+ next = run.parentRunId;
134
+ }
135
+ return false;
136
+ }
137
+ /** After a reviewer run ends: evaluate the pull request it reviewed. Null when it reviewed none. */
138
+ export async function markReadyAfterRun(deps, runId) {
139
+ try {
140
+ const row = await deps.db.runHostCheck.findUnique({
141
+ where: { runId },
142
+ select: { provider: true, repository: true, prNumber: true, verdict: true },
143
+ });
144
+ if (!row || row.prNumber === null || !row.verdict)
145
+ return null;
146
+ return await maybeMarkReady(deps, row.repository, row.prNumber, row.provider);
147
+ }
148
+ catch (err) {
149
+ deps.log?.warn({ err, runId }, "could not evaluate mark-ready after the run");
150
+ return "failed";
151
+ }
152
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * GitHub-flavoured Markdown with its code removed, so a mention quoted in code
3
+ * (`` `@app` ``, a fenced or indented block) is documentation, not a request.
4
+ * Close to CommonMark, not a full parser: when in doubt it keeps text, so a
5
+ * real mention is never lost to an odd construct.
6
+ */
7
+ /** `markdown` without its code blocks and inline code spans. */
8
+ export declare function withoutMarkdownCode(markdown: string): string;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * GitHub-flavoured Markdown with its code removed, so a mention quoted in code
3
+ * (`` `@app` ``, a fenced or indented block) is documentation, not a request.
4
+ * Close to CommonMark, not a full parser: when in doubt it keeps text, so a
5
+ * real mention is never lost to an odd construct.
6
+ */
7
+ const FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})/;
8
+ const INDENTED = /^(?: {4}|\t)/;
9
+ const LIST_ITEM = /^ {0,3}(?:[-*+]|\d{1,9}[.)])(?:\s|$)/;
10
+ const BLANK = /^\s*$/;
11
+ /** Up to three spaces, at least the opening run of the fence's character, then only whitespace. */
12
+ function closesFence(line, fence) {
13
+ let index = 0;
14
+ while (index < 3 && line[index] === " ")
15
+ index += 1;
16
+ const start = index;
17
+ while (line[index] === fence.char)
18
+ index += 1;
19
+ return index - start >= fence.length && line.slice(index).trim() === "";
20
+ }
21
+ /** Fenced and indented code blocks blanked out, line count kept. */
22
+ function withoutCodeBlocks(markdown) {
23
+ const out = [];
24
+ let fence = null;
25
+ // Indented code needs a blank line before it, and indented text under a
26
+ // list item is the item's paragraph, not code.
27
+ let previousBlank = true;
28
+ let inIndentedCode = false;
29
+ let inList = false;
30
+ for (const line of markdown.split(/\r?\n/)) {
31
+ if (fence) {
32
+ if (closesFence(line, fence))
33
+ fence = null;
34
+ out.push("");
35
+ continue;
36
+ }
37
+ const open = FENCE_OPEN.exec(line);
38
+ // A backtick fence's info string cannot contain a backtick (CommonMark).
39
+ if (open && !(open[1][0] === "`" && line.slice(line.indexOf(open[1]) + open[1].length).includes("`"))) {
40
+ fence = { char: open[1][0], length: open[1].length };
41
+ inIndentedCode = false;
42
+ previousBlank = false;
43
+ out.push("");
44
+ continue;
45
+ }
46
+ if (BLANK.test(line)) {
47
+ previousBlank = true;
48
+ out.push(line);
49
+ continue;
50
+ }
51
+ if (INDENTED.test(line) && !inList && (previousBlank || inIndentedCode)) {
52
+ inIndentedCode = true;
53
+ previousBlank = false;
54
+ out.push("");
55
+ continue;
56
+ }
57
+ inIndentedCode = false;
58
+ if (LIST_ITEM.test(line))
59
+ inList = true;
60
+ else if (!INDENTED.test(line) && previousBlank)
61
+ inList = false;
62
+ previousBlank = false;
63
+ out.push(line);
64
+ }
65
+ return out;
66
+ }
67
+ /** Inline code spans in one paragraph replaced by a space; an unmatched run of backticks is literal. */
68
+ function withoutCodeSpans(paragraph) {
69
+ const runs = [];
70
+ for (let index = 0; index < paragraph.length;) {
71
+ if (paragraph[index] !== "`") {
72
+ index += 1;
73
+ continue;
74
+ }
75
+ const start = index;
76
+ while (paragraph[index] === "`")
77
+ index += 1;
78
+ runs.push({ start, end: index });
79
+ }
80
+ // A span closes at the next run of exactly the opening run's length.
81
+ const closer = new Array(runs.length).fill(-1);
82
+ const nextOfLength = new Map();
83
+ for (let i = runs.length - 1; i >= 0; i--) {
84
+ const length = runs[i].end - runs[i].start;
85
+ closer[i] = nextOfLength.get(length) ?? -1;
86
+ nextOfLength.set(length, i);
87
+ }
88
+ let result = "";
89
+ let copied = 0;
90
+ for (let i = 0; i < runs.length; i++) {
91
+ const close = closer[i];
92
+ if (close === -1)
93
+ continue;
94
+ result += `${paragraph.slice(copied, runs[i].start)} `;
95
+ copied = runs[close].end;
96
+ i = close;
97
+ }
98
+ return result + paragraph.slice(copied);
99
+ }
100
+ /** `markdown` without its code blocks and inline code spans. */
101
+ export function withoutMarkdownCode(markdown) {
102
+ return withoutCodeBlocks(markdown)
103
+ .join("\n")
104
+ .split(/(\n[ \t]*\n)/)
105
+ .map((part, i) => (i % 2 === 1 ? part : withoutCodeSpans(part)))
106
+ .join("");
107
+ }
@@ -10,6 +10,7 @@
10
10
  * agents' data.
11
11
  */
12
12
  import { z } from "zod";
13
+ import { SecretInValueError, SecretCheckUnavailableError } from "./secret-guard.js";
13
14
  import { MEMORY_CONTENT_MAX_BYTES, MEMORY_KEY_MAX_BYTES, MEMORY_MAX_KEYS_PER_AGENT, MEMORY_SEARCH_MAX_LIMIT, } from "../providers/memory/types.js";
14
15
  export const MEMORY_TOOL_NAMES = new Set([
15
16
  "memory_get",
@@ -116,6 +117,12 @@ export async function handleMemoryTool(name, argsJson, agentId, memory) {
116
117
  message: err.issues.map((issue) => `${issue.path.join(".") || "input"}: ${issue.message}`).join("; "),
117
118
  });
118
119
  }
120
+ if (err instanceof SecretInValueError) {
121
+ return JSON.stringify({ error: err.code, message: err.message, secretNames: err.secretNames });
122
+ }
123
+ if (err instanceof SecretCheckUnavailableError) {
124
+ return JSON.stringify({ error: err.code, message: err.message });
125
+ }
119
126
  const code = err instanceof Error ? err.message : "memory_error";
120
127
  return JSON.stringify({ error: code, message: MEMORY_ERROR_MESSAGES[code] ?? code });
121
128
  }
@@ -21,6 +21,7 @@
21
21
  import type { Run } from "#prisma";
22
22
  import type { PullRequestOrigin, ReviewHostRegistry, UpsertNamedCheckInput } from "../providers/review-host/types.js";
23
23
  import { type Logger } from "./logger.js";
24
+ import { type MarkReadyDb } from "./mark-ready.js";
24
25
  import { type RelatedPullRequestsDb } from "./related-pull-requests.js";
25
26
  export declare const MERGE_ORDER_CHECK_NAME = "wardby merge order";
26
27
  export interface MergeOrderMember {
@@ -49,7 +50,7 @@ export type MergeOrderVerdict = {
49
50
  * as its entry in `set`; only `mergeOrder` is read from it.
50
51
  */
51
52
  export declare function mergeOrderVerdict(self: MergeOrderMember, set: readonly MergeOrderMember[]): MergeOrderVerdict;
52
- export type MergeOrderDb = RelatedPullRequestsDb;
53
+ export type MergeOrderDb = RelatedPullRequestsDb & MarkReadyDb;
53
54
  export interface MergeOrderSyncDeps {
54
55
  db: MergeOrderDb;
55
56
  hosts: ReviewHostRegistry | undefined;
@@ -1,5 +1,6 @@
1
1
  import { CODING_CODE_PROVIDER, normalizeGitHubRepository } from "../coding/protocol.js";
2
2
  import { logger } from "./logger.js";
3
+ import { maybeMarkReady } from "./mark-ready.js";
3
4
  import { collectRelatedPullRequests, runTreeRoot } from "./related-pull-requests.js";
4
5
  const moduleLog = logger.child({ module: "merge-order-check" });
5
6
  export const MERGE_ORDER_CHECK_NAME = "wardby merge order";
@@ -185,12 +186,18 @@ export async function syncMergeOrderChecks(deps, seedRunId, opts = {}) {
185
186
  const verdict = mergeOrderVerdict(self, set);
186
187
  if (verdict.status === "skip")
187
188
  continue;
189
+ const input = mergeOrderCheckInput(self, verdict, steps, target.headSha, leadRunning);
188
190
  try {
189
- await host.upsertNamedCheck(self.repository, mergeOrderCheckInput(self, verdict, steps, target.headSha, leadRunning));
191
+ await host.upsertNamedCheck(self.repository, input);
190
192
  log.info({ seedRunId, repository: self.repository, number: self.number, status: verdict.status }, "merge order check posted");
191
193
  }
192
194
  catch (err) {
193
195
  log.warn({ err, seedRunId, repository: self.repository, number: self.number }, "could not post the merge order check");
196
+ continue;
197
+ }
198
+ if (input.status === "completed" && input.conclusion === "success") {
199
+ // The last earlier step merged: the pull request may now be ready for review (#287).
200
+ await maybeMarkReady({ db: deps.db, hosts: deps.hosts, log: deps.log }, self.repository, self.number);
194
201
  }
195
202
  }
196
203
  }
@@ -1,11 +1,5 @@
1
- /**
2
- * Deterministic Slack text for workflow notifications. Pure functions: no
3
- * I/O, no model output. Every string that came from a person or a model
4
- * (titles, agent names, reasons) is escaped so it cannot become a link or a
5
- * mention; only canonical tracker/host URLs are formatted as links.
6
- */
7
1
  import type { ThreadSubject, WorkflowPayload } from "./workflow-events.js";
8
- export type ThreadStatus = "picked up" | "PR open" | "changes requested" | "fixing" | "fix rounds exhausted" | "approved" | "merged ✅" | "closed" | "failed ❌";
2
+ export type ThreadStatus = "picked up" | "PR open" | "changes requested" | "fixing" | "fix rounds exhausted" | "approved" | "merged ✅" | "closed" | "failed ❌" | "blocked ⛔";
9
3
  export declare function escapeMrkdwn(s: string): string;
10
4
  export declare function nextStatus(prev: ThreadStatus | null, p: WorkflowPayload): ThreadStatus;
11
5
  export declare function renderParent(subject: ThreadSubject, status: ThreadStatus): {
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Deterministic Slack text for workflow notifications. Pure functions: no
3
+ * I/O, no model output. Every string that came from a person or a model
4
+ * (titles, agent names, reasons) is escaped so it cannot become a link or a
5
+ * mention; only canonical tracker/host URLs are formatted as links.
6
+ */
7
+ import { packageAuditStatusText } from "../coding/registry/audit-mode.js";
8
+ import { packageRefusalWording } from "../coding/registry/refusal-wording.js";
1
9
  const TERMINAL = new Set(["merged ✅", "closed"]);
2
10
  /** Events that start a new attempt (a new pickup, a new PR) and so reopen a merged/closed thread. */
3
11
  const REOPENS = new Set(["issue_picked_up", "pr_opened"]);
@@ -28,8 +36,13 @@ export function nextStatus(prev, p) {
28
36
  return p.state === "started" ? "fixing" : "fix rounds exhausted";
29
37
  case "pr_closed":
30
38
  return p.merged ? "merged ✅" : "closed";
39
+ case "run_blocked":
40
+ return "blocked ⛔";
31
41
  case "run_failed":
32
42
  return "failed ❌";
43
+ case "packages_audited":
44
+ // A report about the run, not a step in its workflow.
45
+ return prev ?? "picked up";
33
46
  }
34
47
  }
35
48
  const section = (text) => ({ type: "section", text: { type: "mrkdwn", text } });
@@ -38,6 +51,19 @@ export function renderParent(subject, status) {
38
51
  const text = `${head} — *${status}*`;
39
52
  return { text, blocks: [section(text)] };
40
53
  }
54
+ /** Refusal lists can exceed Slack's 3,000-character section limit. Keep each line intact. */
55
+ function refusalSections(text) {
56
+ const parts = [""];
57
+ for (const line of text.split("\n")) {
58
+ const last = parts.length - 1;
59
+ const joined = parts[last] ? parts[last] + "\n" + line : line;
60
+ if (joined.length > 3000)
61
+ parts.push(line);
62
+ else
63
+ parts[last] = joined;
64
+ }
65
+ return parts.map(section);
66
+ }
41
67
  export function renderEvent(p, spend) {
42
68
  let line;
43
69
  switch (p.kind) {
@@ -69,6 +95,12 @@ export function renderEvent(p, spend) {
69
95
  ? `🎉 ${link(p.prUrl, p.prLabel)} merged${p.movedTo ? ` — moved to ${escapeMrkdwn(p.movedTo)}` : ""}`
70
96
  : `⚪ ${link(p.prUrl, p.prLabel)} closed without merging`;
71
97
  break;
98
+ case "run_blocked":
99
+ line = packageRefusalWording(p.packageRefusals, { slack: true });
100
+ break;
101
+ case "packages_audited":
102
+ line = packageAuditStatusText(p.mode, p, true);
103
+ break;
72
104
  case "run_failed": {
73
105
  const who = `*${escapeMrkdwn(p.agentName)}*`;
74
106
  line =
@@ -83,7 +115,7 @@ export function renderEvent(p, spend) {
83
115
  }
84
116
  }
85
117
  const text = spend ? `${line}\n_${escapeMrkdwn(spend)}_` : line;
86
- return { text, blocks: [section(text)] };
118
+ return { text, blocks: p.kind === "run_blocked" ? refusalSections(text) : [section(text)] };
87
119
  }
88
120
  /**
89
121
  * The Slack display name for a message about this event: the agent's name
@@ -93,13 +125,15 @@ export function renderEvent(p, spend) {
93
125
  export function senderName(p) {
94
126
  switch (p.kind) {
95
127
  case "issue_picked_up":
128
+ case "run_blocked":
96
129
  case "run_failed":
97
130
  case "review_posted":
131
+ case "packages_audited":
98
132
  return p.agentName;
99
133
  default:
100
134
  return "wardby";
101
135
  }
102
136
  }
103
137
  export function broadcasts(p) {
104
- return (p.kind === "pr_closed" && p.merged) || p.kind === "run_failed";
138
+ return (p.kind === "pr_closed" && p.merged) || p.kind === "run_failed" || p.kind === "run_blocked";
105
139
  }
@@ -6,8 +6,8 @@ export const PR_STATE_SYNC_BATCH = 10;
6
6
  /** A row is re-checked at most this often. */
7
7
  export const PR_STATE_SYNC_MIN_AGE_MS = 10 * 60_000;
8
8
  export async function syncOpenPullRequestStates(db, hosts, trackers, now = new Date()) {
9
- // handlePullRequestClosed needs trackers; without them no IssuePullRequest rows are written anyway.
10
- if (!hosts || !trackers)
9
+ // Without trackers the rows (a GitHub issue's, say) are still settled; only tracker actions are skipped.
10
+ if (!hosts)
11
11
  return 0;
12
12
  let settled = 0;
13
13
  try {
@@ -45,8 +45,9 @@ import type { PrismaClient } from "#prisma";
45
45
  import type { Executor } from "../providers/executor/types.js";
46
46
  import type { ReviewHostRegistry } from "../providers/review-host/types.js";
47
47
  import type { IssueTrackerRegistry } from "../providers/issue-tracker/types.js";
48
+ import { type HostStatusDb } from "./host-status.js";
48
49
  import { type ReviewStartDeps } from "./host-events.js";
49
- export type ReconcilerDb = Pick<PrismaClient, "run" | "runHostCheck" | "runHostStatus" | "runIssueStatus" | "agentIssueProject" | "issuePullRequest" | "codingRun" | "agent" | "$transaction" | "$queryRaw">;
50
+ export type ReconcilerDb = Pick<PrismaClient, "run" | "runHostCheck" | "runBudgetEvent" | "runHostStatus" | "runIssueStatus" | "agentIssueProject" | "issuePullRequest" | "codingRun" | "registryFetch" | "registryAuditRecord" | "agent" | "agentRepository" | "$transaction" | "$queryRaw">;
50
51
  /**
51
52
  * How long after a run finishes before its still-open check counts as
52
53
  * orphaned: long enough that the sweep never races `executeRun`'s own
@@ -66,14 +67,14 @@ export declare const ORPHANED_CHECK_MAX_AGE_MS: number;
66
67
  * than retried forever; its Re-run button still works. Never queries when
67
68
  * no host is configured. `closeOpenHostCheck` is best-effort and never throws.
68
69
  */
69
- export declare function closeOrphanedHostChecks(db: Pick<PrismaClient, "runHostCheck" | "run">, hosts: ReviewHostRegistry | undefined, now?: Date): Promise<void>;
70
+ export declare function closeOrphanedHostChecks(db: Pick<PrismaClient, "runHostCheck" | "run" | "runBudgetEvent">, hosts: ReviewHostRegistry | undefined, now?: Date): Promise<void>;
70
71
  /**
71
72
  * Completes open mention status comments on the same terms as
72
73
  * closeOrphanedHostChecks: the run ended between ORPHANED_CHECK_GRACE_MS and
73
74
  * ORPHANED_CHECK_MAX_AGE_MS ago, newest first, at most ORPHANED_CHECK_BATCH per
74
75
  * pass. `completeHostStatus` is best-effort and never throws.
75
76
  */
76
- export declare function closeOrphanedHostStatuses(db: Pick<PrismaClient, "runHostStatus" | "run">, hosts: ReviewHostRegistry | undefined, now?: Date): Promise<void>;
77
+ export declare function closeOrphanedHostStatuses(db: HostStatusDb, hosts: ReviewHostRegistry | undefined, now?: Date): Promise<void>;
77
78
  /** Runs one reconciliation pass. Returns the number of runs marked `lost`. */
78
79
  export declare function reconcileOnce(db: ReconcilerDb, now?: Date, heartbeatTimeoutMs?: number, executor?: Executor, reviewHosts?: ReviewHostRegistry, issueTrackers?: IssueTrackerRegistry,
79
80
  /** What starting a deferred review needs; absent = no deferred-review sweep. */
@@ -44,6 +44,7 @@
44
44
  import { HEARTBEAT_TIMEOUT_MS, RECONCILE_INTERVAL_MS } from "./timing.js";
45
45
  import { prisma as defaultDb } from "./db.js";
46
46
  import { logger } from "./logger.js";
47
+ import { stopChildrenOfLostRun } from "./lost-run-children.js";
47
48
  import { closeOpenHostCheck } from "./review-host-checks.js";
48
49
  import { completeHostStatus } from "./host-status.js";
49
50
  import { closeOrphanedIssueStatuses } from "./issue-status.js";
@@ -210,7 +211,11 @@ deferredReviews) {
210
211
  continue;
211
212
  let recovered;
212
213
  try {
213
- recovered = await executor.recover({ runId: run.id, backend: run.executionBackend, id: run.id });
214
+ recovered = await executor.recover({
215
+ runId: run.id,
216
+ backend: run.executionBackend,
217
+ id: run.executionWorkflowId ?? run.id,
218
+ });
214
219
  }
215
220
  catch (err) {
216
221
  reconcilerLog.error({ err, runId: run.id }, "durable run recovery failed");
@@ -225,6 +230,7 @@ deferredReviews) {
225
230
  });
226
231
  lost += result.count;
227
232
  if (result.count > 0) {
233
+ await stopChildrenOfLostRun(db, executor, run.id);
228
234
  await fileSelfDefect(db, issueTrackers, { ...run, status: "lost", error: reason, finishedAt: now }, SELF_DEFECT_WAIT);
229
235
  await emitRunFinishedEvents(db, {
230
236
  id: run.id,
@@ -243,6 +249,7 @@ deferredReviews) {
243
249
  lost += result.count;
244
250
  // Only after this pass made the row lost (not when another instance won the race); bounded, never throws.
245
251
  if (result.count > 0) {
252
+ await stopChildrenOfLostRun(db, executor, run.id);
246
253
  await fileSelfDefect(db, issueTrackers, { ...run, status: "lost", error: reason, finishedAt: now }, SELF_DEFECT_WAIT);
247
254
  await emitRunFinishedEvents(db, {
248
255
  id: run.id,
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * The pull requests that came from the same request as a run: every pull
3
3
  * request opened by a coding run in the same top-level run tree (a lead that
4
- * fanned out to several repositories), plus any recorded for the same tracker
5
- * issue (IssuePullRequest). Control-plane rows only.
4
+ * fanned out to several repositories), plus any recorded for the same Jira or
5
+ * GitHub issue (IssuePullRequest). Control-plane rows only.
6
6
  * Ordered by the delegating agent's declared merge order when any entry has
7
7
  * one (CodingRun.mergeOrder; nulls last), then by when each pull request's
8
8
  * coding run was dispatched: the lead's delegation order (for a lead with
@@ -47,7 +47,7 @@ export interface RelatedPullRequest {
47
47
  }
48
48
  export interface RelatedPullRequestGroup {
49
49
  pullRequests: RelatedPullRequest[];
50
- /** The first well-formed issue seen on the group's coding runs. */
50
+ /** The first well-formed issue (a Jira or GitHub issue) seen on the group's coding runs. */
51
51
  issue?: {
52
52
  provider: string;
53
53
  key: string;
@@ -111,6 +111,14 @@ export interface OpenSibling {
111
111
  number: number;
112
112
  openedByRunId: string;
113
113
  }
114
+ /**
115
+ * The continuation hint for a ticket (a GitHub or Jira issue) that already has
116
+ * open wardby pull requests: one sentence per pull request (up to
117
+ * MAX_SIBLING_HINTS), then SIBLING_GUIDANCE once, as paragraphs. Built from
118
+ * stored rows only, with the run id, repository and number re-validated and the
119
+ * link built here, never taken from issue text. Empty when nothing is hintable.
120
+ */
121
+ export declare function openPullRequestHints(prs: readonly OpenSibling[]): string;
114
122
  /**
115
123
  * The group's pull requests a follow-up may continue: stored state "open", or
116
124
  * no stored state yet (a same-tree sibling not recorded for an issue), minus
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * The pull requests that came from the same request as a run: every pull
3
3
  * request opened by a coding run in the same top-level run tree (a lead that
4
- * fanned out to several repositories), plus any recorded for the same tracker
5
- * issue (IssuePullRequest). Control-plane rows only.
4
+ * fanned out to several repositories), plus any recorded for the same Jira or
5
+ * GitHub issue (IssuePullRequest). Control-plane rows only.
6
6
  * Ordered by the delegating agent's declared merge order when any entry has
7
7
  * one (CodingRun.mergeOrder; nulls last), then by when each pull request's
8
8
  * coding run was dispatched: the lead's delegation order (for a lead with
@@ -24,7 +24,7 @@
24
24
  */
25
25
  import { Prisma } from "#prisma";
26
26
  import { CODING_CODE_PROVIDER, normalizeGitHubRepository } from "../coding/protocol.js";
27
- import { ISSUE_KEY, ISSUE_TRACKER_NAMES, } from "../providers/issue-tracker/types.js";
27
+ import { issueReference, } from "../providers/issue-tracker/types.js";
28
28
  import { renderRelatedSection } from "../providers/vcs/github.js";
29
29
  import { pullRequestOutcome } from "./host-status.js";
30
30
  import { logger } from "./logger.js";
@@ -162,7 +162,8 @@ onlyIssueKey) {
162
162
  let issue;
163
163
  const issues = new Map();
164
164
  for (const r of rows) {
165
- if (r.issueProvider && r.issueKey && ISSUE_KEY.test(r.issueKey)) {
165
+ // A Jira issue and a GitHub issue join the same way: by provider and key, each key re-validated.
166
+ if (r.issueProvider && r.issueKey && issueReference(r.issueProvider, r.issueKey)) {
166
167
  const found = { provider: r.issueProvider, key: r.issueKey };
167
168
  issue ??= found;
168
169
  issues.set(`${found.provider}\0${found.key}`, found);
@@ -271,16 +272,8 @@ onlyIssueKey) {
271
272
  function issueFor(group, trackers) {
272
273
  if (!group.issue)
273
274
  return undefined;
274
- const provider = group.issue.provider;
275
- let url;
276
- try {
277
- url = trackers?.[provider]?.issueUrl(group.issue.key);
278
- }
279
- catch {
280
- url = undefined;
281
- }
282
- const trackerName = Object.hasOwn(ISSUE_TRACKER_NAMES, provider) ? ISSUE_TRACKER_NAMES[provider] : undefined;
283
- return { key: group.issue.key, ...(url ? { url } : {}), ...(trackerName ? { trackerName } : {}) };
275
+ const tracker = trackers?.[group.issue.provider];
276
+ return issueReference(group.issue.provider, group.issue.key, tracker ? (key) => tracker.issueUrl(key) : undefined);
284
277
  }
285
278
  /**
286
279
  * After a native run ends, rewrites the Related pull requests section on
@@ -388,6 +381,26 @@ const SAFE_RUN_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
388
381
  export const SIBLING_GUIDANCE = "Continue the pull request you were asked about, and a listed open one only when the change requires it. " +
389
382
  "Never open a new pull request in a repository that already has an open pull request listed here. Merged or " +
390
383
  "closed pull requests are not listed: a change there needs a new pull request.";
384
+ const HINT_REPOSITORY = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
385
+ /**
386
+ * The continuation hint for a ticket (a GitHub or Jira issue) that already has
387
+ * open wardby pull requests: one sentence per pull request (up to
388
+ * MAX_SIBLING_HINTS), then SIBLING_GUIDANCE once, as paragraphs. Built from
389
+ * stored rows only, with the run id, repository and number re-validated and the
390
+ * link built here, never taken from issue text. Empty when nothing is hintable.
391
+ */
392
+ export function openPullRequestHints(prs) {
393
+ const lines = prs
394
+ .filter((p) => SAFE_RUN_ID.test(p.openedByRunId) &&
395
+ HINT_REPOSITORY.test(p.repository) &&
396
+ Number.isSafeInteger(p.number) &&
397
+ p.number > 0)
398
+ .slice(0, MAX_SIBLING_HINTS)
399
+ .map((p) => `This issue already has an open pull request wardby opened: ${p.repository}#${p.number} ` +
400
+ `(https://github.com/${p.repository}/pull/${p.number}). ` +
401
+ `To revise it, delegate with continuePriorRun set to exactly "${p.openedByRunId}".`);
402
+ return lines.length > 0 ? [...lines, SIBLING_GUIDANCE].join("\n\n") : "";
403
+ }
391
404
  /**
392
405
  * The group's pull requests a follow-up may continue: stored state "open", or
393
406
  * no stored state yet (a same-tree sibling not recorded for an issue), minus
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Splits an agent's reply into comment-sized parts, so a long reply (a plan
3
+ * posted to an issue, say) can go out in full as numbered follow-up comments
4
+ * instead of being cut. Pure: numbering, headers and the cut note are the
5
+ * caller's job; each part is a raw slice of the defused text.
6
+ */
7
+ export interface ReplyParts {
8
+ parts: string[];
9
+ truncated: boolean;
10
+ }
11
+ /** "@" + U+200B before a word character, so a quoted reply pings nobody. */
12
+ export declare function defuseMentions(text: string): string;
13
+ /**
14
+ * Splits `text` into at most `maxParts` parts of at most `maxChars` each, preferring Markdown heading
15
+ * boundaries, then blank lines (paragraphs), then single newlines, then a hard cut. Defuses @-mentions.
16
+ * Never splits inside a fenced code block unless one block alone exceeds maxChars (then hard-cut it).
17
+ */
18
+ export declare function splitReply(text: string, opts: {
19
+ maxChars: number;
20
+ maxParts: number;
21
+ }): ReplyParts;