@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
@@ -7,6 +7,7 @@ import { GitHubRemote } from "./github-remote.js";
7
7
  import { LocalRemote } from "./local-remote.js";
8
8
  import { RoutingVcsProvider } from "./routing.js";
9
9
  import { logger } from "../../core/logger.js";
10
+ import { testSimulatorBase } from "../../config/test-simulators.js";
10
11
  const vcsLog = logger.child({ module: "vcs" });
11
12
  export * from "./types.js";
12
13
  export { GitHubAppClient } from "./github.js";
@@ -33,7 +34,13 @@ export function buildVcsProvider(providerConfig, config, env = process.env, opti
33
34
  privateKey: config.privateKey,
34
35
  apiVersion: config.apiVersion,
35
36
  });
36
- github = new GitVcsProvider({ rootDir, remote: new GitHubRemote({ github: client }), ...limits });
37
+ // WARDBY_TEST_SIMULATORS (test only): clone from and push to the simulator's git server.
38
+ const simulatorGit = testSimulatorBase("github-git", env);
39
+ const remote = new GitHubRemote({
40
+ github: client,
41
+ ...(simulatorGit ? { cloneUrlForRepository: (repository) => `${simulatorGit}/${repository}.git` } : {}),
42
+ });
43
+ github = new GitVcsProvider({ rootDir, remote, ...limits });
37
44
  }
38
45
  let local = null;
39
46
  if (loadLocalRepoRoots(env).roots.length > 0) {
@@ -0,0 +1,127 @@
1
+ /**
2
+ * The pull request description wardby writes, as pure functions: the hash it
3
+ * records, whether a fix round's final message is good enough to replace it,
4
+ * whether a person has edited it since, and the comment that carries a
5
+ * proposed description when wardby must not overwrite one.
6
+ *
7
+ * Depends on nothing else in providers/vcs, so github.ts can import it.
8
+ */
9
+ /** Marks the Related pull requests section; replaced in place by later runs. */
10
+ export declare const RELATED_SECTION_START = "<!-- wardby-related:start -->";
11
+ export declare const RELATED_SECTION_END = "<!-- wardby-related:end -->";
12
+ /** The last line of a description a fix round rewrote: `<!-- wardby-latest:<runId> -->`. */
13
+ export declare const LATEST_RUN_MARKER_PREFIX = "<!-- wardby-latest:";
14
+ /**
15
+ * The first line of the one description comment per pull request (edited in
16
+ * place on later runs). Pull-request level, never per run. A proposal is
17
+ * stamped with the head commit it describes: `<!-- wardby-description head=<sha> -->`.
18
+ */
19
+ export declare const DESCRIPTION_COMMENT_MARKER = "<!-- wardby-description -->";
20
+ /** The second line of the description comment once a later run applied its description directly. */
21
+ export declare const DESCRIPTION_COMMENT_APPLIED_MARKER = "<!-- wardby-description-applied -->";
22
+ /** The first line of a duplicate description comment, rewritten to point at the one in use. */
23
+ export declare const DESCRIPTION_COMMENT_SUPERSEDED_MARKER = "<!-- wardby-description-superseded -->";
24
+ /** The description comment is searched for on at most this many pages of 100 comments. */
25
+ export declare const MAX_DESCRIPTION_COMMENT_PAGES = 10;
26
+ /** A final message with fewer non-whitespace characters can't replace the description. */
27
+ export declare const MIN_PR_BODY_CHARS = 80;
28
+ /** The fallback comment stays under this many characters (GitHub's limit is 65,536). */
29
+ export declare const MAX_DESCRIPTION_COMMENT_CHARS = 60000;
30
+ /** The marked Related block, START through END inclusive; undefined when absent or malformed (missing, reversed, repeated). */
31
+ export declare function extractRelatedBlock(body: string): string | undefined;
32
+ /**
33
+ * The body as hashed: LF line endings, the Related block removed (it is
34
+ * rewritten as other runs finish, which is not an edit), trailing whitespace
35
+ * trimmed per line and at the end, and runs of blank lines collapsed to one.
36
+ */
37
+ export declare function normalizeDescriptionForHash(body: string): string;
38
+ /** SHA-256 of the normalized body, lowercase hex. */
39
+ export declare function descriptionSha256(body: string): string;
40
+ /** Whether the text contains a GitHub closing keyword and issue reference (`Fixes #3`, `resolves owner/repo#3`). */
41
+ export declare function hasClosingKeyword(text: string): boolean;
42
+ /**
43
+ * The issue number of the first closing keyword in `text` that points at an
44
+ * issue in `repository` (`Resolves #12`, `fixes owner/repo#12` naming this
45
+ * repository, case-insensitively); undefined when there is none.
46
+ */
47
+ export declare function closingIssueNumber(text: string | undefined, repository: string): number | undefined;
48
+ export type FinalMessageVerdict = {
49
+ ok: true;
50
+ } | {
51
+ ok: false;
52
+ reason: "empty" | "too_short" | "missing_closing_keyword";
53
+ };
54
+ /**
55
+ * Whether `next` (a fix round's final message) can replace the description
56
+ * whose agent-written text was `previous`: not empty, at least
57
+ * MIN_PR_BODY_CHARS non-whitespace characters, and keeping a closing keyword
58
+ * when the previous text had one.
59
+ */
60
+ export declare function assessFinalMessage(next: string | undefined, previous: string | undefined): FinalMessageVerdict;
61
+ /**
62
+ * Whether the PR description is still what wardby last wrote. It must start
63
+ * with the root run's marker, and its normalized hash must match the recorded
64
+ * one. Without a recorded hash (a description written before hashes were
65
+ * recorded), it must match `legacySha256`, the hash of the body wardby would
66
+ * have written for the root run, rebuilt from stored records; without that
67
+ * either it counts as edited, so a person's text is never overwritten.
68
+ * `previousAgentText` does not decide edit status; it is carried for callers.
69
+ */
70
+ export declare function isUneditedDescription(input: {
71
+ currentBody: string;
72
+ rootRunId: string;
73
+ recordedSha256: string | null;
74
+ legacySha256?: string;
75
+ previousAgentText?: string | undefined;
76
+ }): boolean;
77
+ export interface ParsedDescriptionComment {
78
+ /** The head commit the proposal describes; absent on an unstamped or applied comment. */
79
+ headSha?: string;
80
+ /** A later run applied its description directly: no proposal is pending. */
81
+ applied: boolean;
82
+ /** The run that proposed it, when named. */
83
+ runId?: string;
84
+ /** The proposed description; absent when the comment holds none. */
85
+ proposed?: string;
86
+ }
87
+ /**
88
+ * wardby's description comment, parsed; undefined for any other comment.
89
+ * Only the first line (the marker) and second line (the applied marker) are
90
+ * structural, so text inside a proposal can't change its state.
91
+ */
92
+ export declare function parseDescriptionComment(body: string): ParsedDescriptionComment | undefined;
93
+ export interface DescriptionCommentRecord {
94
+ id: number;
95
+ body: string;
96
+ url?: string;
97
+ parsed: ParsedDescriptionComment;
98
+ }
99
+ /**
100
+ * wardby's description comments on a pull request, read the same way by the
101
+ * writer and the reviewer: up to MAX_DESCRIPTION_COMMENT_PAGES pages of 100
102
+ * (oldest first), only comments `isOurs` accepts that start with the
103
+ * pull-request-level marker. `newest` is the one in use; `older` are
104
+ * duplicates (oldest first).
105
+ */
106
+ export declare function findDescriptionComments(fetchPage: (page: number) => Promise<unknown[]>, isOurs: (comment: Record<string, unknown>) => boolean): Promise<{
107
+ newest: DescriptionCommentRecord | null;
108
+ older: DescriptionCommentRecord[];
109
+ }>;
110
+ /** What a duplicate description comment becomes: a pointer to the one in use. */
111
+ export declare function supersededDescriptionComment(url: string | undefined): string;
112
+ /**
113
+ * The pull request's description comment, carrying the description wardby's
114
+ * latest run proposed when it could not apply it (it couldn't confirm the
115
+ * description is still its own text). There is one per pull request,
116
+ * edited in place by later runs, its marker stamped with `headSha`, the head
117
+ * commit the proposal describes. Holds the body in a collapsed fenced block,
118
+ * and stays under MAX_DESCRIPTION_COMMENT_CHARS (a long body is truncated).
119
+ * Throws on a run id or head that isn't safe to quote.
120
+ */
121
+ export declare function descriptionFallbackComment(runId: string, proposedBody: string, headSha?: string): string;
122
+ /**
123
+ * What the description comment becomes once a later run applied its
124
+ * description directly: no proposal is pending, so nobody (a person or a
125
+ * reviewer) acts on a stale one.
126
+ */
127
+ export declare function descriptionAppliedComment(runId: string): string;
@@ -0,0 +1,270 @@
1
+ import { createHash } from "node:crypto";
2
+ /**
3
+ * The pull request description wardby writes, as pure functions: the hash it
4
+ * records, whether a fix round's final message is good enough to replace it,
5
+ * whether a person has edited it since, and the comment that carries a
6
+ * proposed description when wardby must not overwrite one.
7
+ *
8
+ * Depends on nothing else in providers/vcs, so github.ts can import it.
9
+ */
10
+ /** Marks the Related pull requests section; replaced in place by later runs. */
11
+ export const RELATED_SECTION_START = "<!-- wardby-related:start -->";
12
+ export const RELATED_SECTION_END = "<!-- wardby-related:end -->";
13
+ /** The last line of a description a fix round rewrote: `<!-- wardby-latest:<runId> -->`. */
14
+ export const LATEST_RUN_MARKER_PREFIX = "<!-- wardby-latest:";
15
+ /**
16
+ * The first line of the one description comment per pull request (edited in
17
+ * place on later runs). Pull-request level, never per run. A proposal is
18
+ * stamped with the head commit it describes: `<!-- wardby-description head=<sha> -->`.
19
+ */
20
+ export const DESCRIPTION_COMMENT_MARKER = "<!-- wardby-description -->";
21
+ /** The marker line, plain or stamped with a head; anchored to the whole first line. */
22
+ const DESCRIPTION_COMMENT_MARKER_LINE = /^<!-- wardby-description(?: head=([0-9a-f]{40}))? -->$/;
23
+ /** The second line of the description comment once a later run applied its description directly. */
24
+ export const DESCRIPTION_COMMENT_APPLIED_MARKER = "<!-- wardby-description-applied -->";
25
+ /** The first line of a duplicate description comment, rewritten to point at the one in use. */
26
+ export const DESCRIPTION_COMMENT_SUPERSEDED_MARKER = "<!-- wardby-description-superseded -->";
27
+ /** The description comment is searched for on at most this many pages of 100 comments. */
28
+ export const MAX_DESCRIPTION_COMMENT_PAGES = 10;
29
+ const HEAD_SHA = /^[0-9a-f]{40}$/;
30
+ const PROPOSAL_SUMMARY = "<details><summary>Proposed description</summary>";
31
+ /** A final message with fewer non-whitespace characters can't replace the description. */
32
+ export const MIN_PR_BODY_CHARS = 80;
33
+ /** The fallback comment stays under this many characters (GitHub's limit is 65,536). */
34
+ export const MAX_DESCRIPTION_COMMENT_CHARS = 60_000;
35
+ const RUN_MARKER_PREFIX = "<!-- wardby:";
36
+ /** Mirrors the runId shape validated in github.ts and coding/protocol.ts. */
37
+ const SAFE_RUN_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
38
+ /** GitHub's closing keywords, then `#N` or `owner/repo#N`. */
39
+ const CLOSING_KEYWORD = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\b:?\s+(?:[\w.-]+\/[\w.-]+)?#\d+\b/i;
40
+ /** The marked Related block, START through END inclusive; undefined when absent or malformed (missing, reversed, repeated). */
41
+ export function extractRelatedBlock(body) {
42
+ const start = body.indexOf(RELATED_SECTION_START);
43
+ const end = body.indexOf(RELATED_SECTION_END);
44
+ if (start === -1 || end === -1 || end < start)
45
+ return undefined;
46
+ if (body.indexOf(RELATED_SECTION_START, start + 1) !== -1 || body.indexOf(RELATED_SECTION_END, end + 1) !== -1) {
47
+ return undefined;
48
+ }
49
+ return body.slice(start, end + RELATED_SECTION_END.length);
50
+ }
51
+ /**
52
+ * The body as hashed: LF line endings, the Related block removed (it is
53
+ * rewritten as other runs finish, which is not an edit), trailing whitespace
54
+ * trimmed per line and at the end, and runs of blank lines collapsed to one.
55
+ */
56
+ export function normalizeDescriptionForHash(body) {
57
+ let text = body.replace(/\r\n/g, "\n");
58
+ const related = extractRelatedBlock(text);
59
+ if (related)
60
+ text = text.replace(related, "");
61
+ return text
62
+ .split("\n")
63
+ .map((line) => line.trimEnd())
64
+ .join("\n")
65
+ .replace(/\n{3,}/g, "\n\n")
66
+ .trimEnd();
67
+ }
68
+ /** SHA-256 of the normalized body, lowercase hex. */
69
+ export function descriptionSha256(body) {
70
+ return createHash("sha256").update(normalizeDescriptionForHash(body), "utf8").digest("hex");
71
+ }
72
+ /** Whether the text contains a GitHub closing keyword and issue reference (`Fixes #3`, `resolves owner/repo#3`). */
73
+ export function hasClosingKeyword(text) {
74
+ return CLOSING_KEYWORD.test(text);
75
+ }
76
+ const CLOSING_REFERENCES = /\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\b:?\s+(?:([\w.-]+\/[\w.-]+))?#(\d+)\b/gi;
77
+ /**
78
+ * The issue number of the first closing keyword in `text` that points at an
79
+ * issue in `repository` (`Resolves #12`, `fixes owner/repo#12` naming this
80
+ * repository, case-insensitively); undefined when there is none.
81
+ */
82
+ export function closingIssueNumber(text, repository) {
83
+ if (!text)
84
+ return undefined;
85
+ for (const match of text.matchAll(CLOSING_REFERENCES)) {
86
+ if (match[1] && match[1].toLowerCase() !== repository.toLowerCase())
87
+ continue;
88
+ const number = Number(match[2]);
89
+ if (Number.isSafeInteger(number) && number > 0)
90
+ return number;
91
+ }
92
+ return undefined;
93
+ }
94
+ /**
95
+ * Whether `next` (a fix round's final message) can replace the description
96
+ * whose agent-written text was `previous`: not empty, at least
97
+ * MIN_PR_BODY_CHARS non-whitespace characters, and keeping a closing keyword
98
+ * when the previous text had one.
99
+ */
100
+ export function assessFinalMessage(next, previous) {
101
+ const text = next?.trim() ?? "";
102
+ if (!text)
103
+ return { ok: false, reason: "empty" };
104
+ if (text.replace(/\s/g, "").length < MIN_PR_BODY_CHARS)
105
+ return { ok: false, reason: "too_short" };
106
+ if (previous && hasClosingKeyword(previous) && !hasClosingKeyword(text)) {
107
+ return { ok: false, reason: "missing_closing_keyword" };
108
+ }
109
+ return { ok: true };
110
+ }
111
+ /**
112
+ * Whether the PR description is still what wardby last wrote. It must start
113
+ * with the root run's marker, and its normalized hash must match the recorded
114
+ * one. Without a recorded hash (a description written before hashes were
115
+ * recorded), it must match `legacySha256`, the hash of the body wardby would
116
+ * have written for the root run, rebuilt from stored records; without that
117
+ * either it counts as edited, so a person's text is never overwritten.
118
+ * `previousAgentText` does not decide edit status; it is carried for callers.
119
+ */
120
+ export function isUneditedDescription(input) {
121
+ const body = input.currentBody.replace(/\r\n/g, "\n");
122
+ if (!body.startsWith(`${RUN_MARKER_PREFIX}${input.rootRunId} -->`))
123
+ return false;
124
+ const expected = input.recordedSha256 ?? input.legacySha256;
125
+ if (!expected)
126
+ return false;
127
+ return descriptionSha256(body) === expected;
128
+ }
129
+ /** A backtick fence one longer than the longest backtick run in `text` (at least three). */
130
+ function fenceFor(text) {
131
+ const longest = Math.max(0, ...Array.from(text.matchAll(/`+/g), (m) => m[0].length));
132
+ return "`".repeat(Math.max(3, longest + 1));
133
+ }
134
+ /**
135
+ * wardby's description comment, parsed; undefined for any other comment.
136
+ * Only the first line (the marker) and second line (the applied marker) are
137
+ * structural, so text inside a proposal can't change its state.
138
+ */
139
+ export function parseDescriptionComment(body) {
140
+ const text = body.replace(/\r\n/g, "\n");
141
+ const lines = text.split("\n");
142
+ const marker = DESCRIPTION_COMMENT_MARKER_LINE.exec(lines[0] ?? "");
143
+ if (!marker)
144
+ return undefined;
145
+ if (lines[1] === DESCRIPTION_COMMENT_APPLIED_MARKER)
146
+ return { applied: true };
147
+ const proposed = proposalOf(text);
148
+ const runId = proposed === undefined ? undefined : proposingRunId(text);
149
+ return {
150
+ ...(marker[1] ? { headSha: marker[1] } : {}),
151
+ applied: false,
152
+ ...(runId ? { runId } : {}),
153
+ ...(proposed !== undefined ? { proposed } : {}),
154
+ };
155
+ }
156
+ /** The fenced block under "Proposed description"; undefined when absent. */
157
+ function proposalOf(text) {
158
+ const at = text.indexOf(PROPOSAL_SUMMARY);
159
+ if (at === -1)
160
+ return undefined;
161
+ const open = /\n(`{3,})markdown\n/.exec(text.slice(at));
162
+ if (!open)
163
+ return undefined;
164
+ const start = at + open.index + open[0].length;
165
+ const close = text.indexOf(`\n${open[1]}\n`, start - 1);
166
+ const end = close === -1 ? text.indexOf(`\n${open[1]}`, start - 1) : close;
167
+ if (end < start - 1)
168
+ return undefined;
169
+ const proposal = text.slice(start, Math.max(start, end)).trimEnd();
170
+ return proposal || undefined;
171
+ }
172
+ /** The run a fallback comment names as its proposer (in its header, before the proposal). */
173
+ function proposingRunId(text) {
174
+ const header = text.slice(0, Math.max(0, text.indexOf(PROPOSAL_SUMMARY)));
175
+ const named = /latest run \(`([^`\n]+)`\)/.exec(header)?.[1];
176
+ return named && SAFE_RUN_ID.test(named) ? named : undefined;
177
+ }
178
+ /**
179
+ * wardby's description comments on a pull request, read the same way by the
180
+ * writer and the reviewer: up to MAX_DESCRIPTION_COMMENT_PAGES pages of 100
181
+ * (oldest first), only comments `isOurs` accepts that start with the
182
+ * pull-request-level marker. `newest` is the one in use; `older` are
183
+ * duplicates (oldest first).
184
+ */
185
+ export async function findDescriptionComments(fetchPage, isOurs) {
186
+ const found = [];
187
+ for (let page = 1; page <= MAX_DESCRIPTION_COMMENT_PAGES; page++) {
188
+ const comments = await fetchPage(page);
189
+ for (const item of comments) {
190
+ if (!item || typeof item !== "object")
191
+ continue;
192
+ const comment = item;
193
+ if (typeof comment.body !== "string" || typeof comment.id !== "number")
194
+ continue;
195
+ const parsed = parseDescriptionComment(comment.body);
196
+ if (!parsed || !isOurs(comment))
197
+ continue;
198
+ found.push({
199
+ id: comment.id,
200
+ body: comment.body,
201
+ ...(typeof comment.html_url === "string" ? { url: comment.html_url } : {}),
202
+ parsed,
203
+ });
204
+ }
205
+ if (comments.length < 100)
206
+ break;
207
+ }
208
+ return { newest: found.at(-1) ?? null, older: found.slice(0, -1) };
209
+ }
210
+ /** What a duplicate description comment becomes: a pointer to the one in use. */
211
+ export function supersededDescriptionComment(url) {
212
+ const link = url && /^https:\/\/[^\s)]+$/.test(url) ? `[the current one](${url})` : "a newer comment";
213
+ return `${DESCRIPTION_COMMENT_SUPERSEDED_MARKER}\n\nSuperseded by ${link}.`;
214
+ }
215
+ /**
216
+ * The pull request's description comment, carrying the description wardby's
217
+ * latest run proposed when it could not apply it (it couldn't confirm the
218
+ * description is still its own text). There is one per pull request,
219
+ * edited in place by later runs, its marker stamped with `headSha`, the head
220
+ * commit the proposal describes. Holds the body in a collapsed fenced block,
221
+ * and stays under MAX_DESCRIPTION_COMMENT_CHARS (a long body is truncated).
222
+ * Throws on a run id or head that isn't safe to quote.
223
+ */
224
+ export function descriptionFallbackComment(runId, proposedBody, headSha) {
225
+ if (!SAFE_RUN_ID.test(runId))
226
+ throw new Error("description_comment_run_id_invalid");
227
+ if (headSha !== undefined && !HEAD_SHA.test(headSha))
228
+ throw new Error("description_comment_head_invalid");
229
+ const head = [
230
+ headSha ? `<!-- wardby-description head=${headSha} -->` : DESCRIPTION_COMMENT_MARKER,
231
+ "",
232
+ `This is the current description proposed by wardby's latest run (\`${runId}\`)${headSha ? ` for commit ${headSha.slice(0, 12)}` : ""}. ` +
233
+ "It was not applied because wardby couldn't confirm the description is unchanged since it wrote it (for example, a person edited it), and wardby never overwrites a person's edits. " +
234
+ "The pull request author can copy it into the description; wardby then keeps it up to date again. Later runs update this comment.",
235
+ "",
236
+ PROPOSAL_SUMMARY,
237
+ "",
238
+ ].join("\n");
239
+ const truncatedNote = "\n\n_The proposed description was truncated to fit in a comment._";
240
+ let body = proposedBody.replace(/\r\n/g, "\n").trimEnd();
241
+ let note = "";
242
+ const render = () => {
243
+ const fence = fenceFor(body);
244
+ return `${head}${fence}markdown\n${body}\n${fence}${note}\n\n</details>`;
245
+ };
246
+ let comment = render();
247
+ if (comment.length >= MAX_DESCRIPTION_COMMENT_CHARS) {
248
+ note = truncatedNote;
249
+ // Headroom for the fence growing if the cut leaves a longer backtick run (it can't), plus the note.
250
+ const overhead = comment.length - body.length + note.length + 64;
251
+ body = body.slice(0, Math.max(0, MAX_DESCRIPTION_COMMENT_CHARS - overhead)).trimEnd();
252
+ comment = render();
253
+ }
254
+ return comment;
255
+ }
256
+ /**
257
+ * What the description comment becomes once a later run applied its
258
+ * description directly: no proposal is pending, so nobody (a person or a
259
+ * reviewer) acts on a stale one.
260
+ */
261
+ export function descriptionAppliedComment(runId) {
262
+ if (!SAFE_RUN_ID.test(runId))
263
+ throw new Error("description_comment_run_id_invalid");
264
+ return [
265
+ DESCRIPTION_COMMENT_MARKER,
266
+ DESCRIPTION_COMMENT_APPLIED_MARKER,
267
+ "",
268
+ `wardby's latest run (\`${runId}\`) updated the pull request description directly, so it is current. No proposed description is pending here.`,
269
+ ].join("\n");
270
+ }
@@ -1,4 +1,4 @@
1
- import type { FinalizeChangesDetails, PreparedWorkspace, VcsProvider } from "./types.js";
1
+ import type { DescriptionWriteOutcome, FinalizeChangesDetails, PreparedWorkspace, VcsProvider } from "./types.js";
2
2
  /** What a remote needs to publish a pushed commit (GitHub: open or find the draft PR). */
3
3
  export interface PublishInput {
4
4
  /** The validated workspace whose headRef was just pushed. */
@@ -6,11 +6,14 @@ export interface PublishInput {
6
6
  details?: FinalizeChangesDetails;
7
7
  /** Every path the commit changes relative to baseCommit (already validated). */
8
8
  changedPaths: readonly string[];
9
+ /** The commit just pushed (the pull request's new head). */
10
+ commitSha?: string;
9
11
  }
10
12
  export type PublishResult = {
11
13
  kind: "pull_request";
12
14
  number: number;
13
15
  url: string;
16
+ description?: DescriptionWriteOutcome;
14
17
  } | {
15
18
  kind: "branch";
16
19
  branch: string;
@@ -52,7 +55,36 @@ export interface GitRemote {
52
55
  assertPushRef?(headRef: string): void;
53
56
  /** When set, called inside withAccess right before the push; throws to refuse it (GitHub: unset). */
54
57
  beforePush?(repository: string, headRef: string): Promise<void>;
58
+ /**
59
+ * Optional: the branch a continuation's pull request currently targets, which
60
+ * prepareWorkspace merges into the workspace before the agent starts (GitHub:
61
+ * the open PR's base; local: unset, so no merge). Null when there is nothing to
62
+ * merge from: not a continuation, the PR is a fork's, or the lookup failed.
63
+ * Never throws.
64
+ */
65
+ pullRequestBase?(input: {
66
+ runId: string;
67
+ repository: string;
68
+ baseRef: string;
69
+ headRef: string;
70
+ continuation?: {
71
+ rootRunId: string;
72
+ };
73
+ }): Promise<{
74
+ ref: string;
75
+ } | null>;
55
76
  notifyContinuationStarted?: VcsProvider["notifyContinuationStarted"];
77
+ continuationPullRequestDraft?: VcsProvider["continuationPullRequestDraft"];
56
78
  notifyContinuationFinished?: VcsProvider["notifyContinuationFinished"];
57
79
  readRepositoryFile?: VcsProvider["readRepositoryFile"];
80
+ /**
81
+ * Optional: called after the commit and before the push, with the commit
82
+ * about to become the head. GitHub writes a continuation's description
83
+ * comment here, so it exists before the push starts a review. Never throws.
84
+ */
85
+ proposeDescriptionBeforePush?(input: PublishInput & {
86
+ commitSha: string;
87
+ }): Promise<void>;
88
+ /** Optional: re-derive a continuation's PR description without a push (GitHub only). Never throws. */
89
+ refreshDescription?: VcsProvider["refreshPullRequestDescription"];
58
90
  }
@@ -1,5 +1,5 @@
1
1
  import type { RepositoryFileInput } from "./github.js";
2
- import type { ContinuationFinishedDetails, ContinuationOutcome, FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
2
+ import type { ContinuationFinishedDetails, ContinuationOutcome, ContinuationTarget, DescriptionWriteOutcome, FinalizeChangesDetails, FinalizeChangesResult, PreparedWorkspace, VcsPrepareInput, VcsProvider } from "./types.js";
3
3
  /** Keeps the `vcs_github_not_configured` code prefix that error matching and categorization key on. */
4
4
  export declare const VCS_GITHUB_NOT_CONFIGURED_ERROR = "vcs_github_not_configured: set GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY to run coding agents on GitHub repositories";
5
5
  export interface RoutingVcsOptions {
@@ -28,6 +28,8 @@ export declare class RoutingVcsProvider implements VcsProvider {
28
28
  notifyContinuationStarted(workspace: PreparedWorkspace, details?: {
29
29
  agentName?: string;
30
30
  }): Promise<void>;
31
- notifyContinuationFinished(workspace: PreparedWorkspace, outcome: ContinuationOutcome, details?: ContinuationFinishedDetails): Promise<void>;
31
+ notifyContinuationFinished(workspace: ContinuationTarget, outcome: ContinuationOutcome, details?: ContinuationFinishedDetails): Promise<void>;
32
+ refreshPullRequestDescription(workspace: ContinuationTarget, details: FinalizeChangesDetails): Promise<DescriptionWriteOutcome | undefined>;
33
+ continuationPullRequestDraft(workspace: PreparedWorkspace): Promise<boolean | undefined>;
32
34
  readRepositoryFile(input: RepositoryFileInput): Promise<string | null>;
33
35
  }
@@ -46,6 +46,12 @@ export class RoutingVcsProvider {
46
46
  async notifyContinuationFinished(workspace, outcome, details) {
47
47
  await this.optionalTarget(workspace.repository)?.notifyContinuationFinished?.(workspace, outcome, details);
48
48
  }
49
+ async refreshPullRequestDescription(workspace, details) {
50
+ return this.optionalTarget(workspace.repository)?.refreshPullRequestDescription?.(workspace, details);
51
+ }
52
+ async continuationPullRequestDraft(workspace) {
53
+ return this.optionalTarget(workspace.repository)?.continuationPullRequestDraft?.(workspace);
54
+ }
49
55
  async readRepositoryFile(input) {
50
56
  return (await this.optionalTarget(input.repository)?.readRepositoryFile?.(input)) ?? null;
51
57
  }
@@ -1,4 +1,10 @@
1
- import type { RelatedPullRequestsInput, RepositoryFileInput } from "./github.js";
1
+ import type { PackageAuditReport } from "../../coding/registry/audit-mode.js";
2
+ import type { DescriptionBaseline, DescriptionUpdateResult, RelatedPullRequestsInput, RepositoryFileInput } from "./github.js";
3
+ /** What happened to a pull request description: wardby just wrote it (a new PR) or updated a fix round's. */
4
+ export type DescriptionWriteOutcome = {
5
+ kind: "written";
6
+ sha256: string;
7
+ } | DescriptionUpdateResult;
2
8
  export interface VcsPrepareInput {
3
9
  runId: string;
4
10
  repository: string;
@@ -45,7 +51,30 @@ export interface PreparedWorkspace {
45
51
  continuation?: {
46
52
  rootRunId: string;
47
53
  };
54
+ /**
55
+ * Set when prepareWorkspace merged the pull request's current target branch
56
+ * into a continuation's workspace (it was behind): the target branch, the
57
+ * commit merged, and the paths the merge left conflicted (markers in the
58
+ * workspace). Read back from the workspace's git metadata on recovery, never
59
+ * from worker output.
60
+ */
61
+ targetMerge?: TargetMerge;
48
62
  }
63
+ export interface TargetMerge {
64
+ ref: string;
65
+ targetCommit: string;
66
+ conflictedPaths: string[];
67
+ }
68
+ /**
69
+ * The pull request a continuation run works on, without its local workspace:
70
+ * what the host-side finish signals and the no-push description refresh need.
71
+ * A run finished by another control-plane process (a deploy moved it) has no
72
+ * workspace to recover, so the executor builds this from the run record, and
73
+ * `baseCommit` is then unknown.
74
+ */
75
+ export type ContinuationTarget = Pick<PreparedWorkspace, "runId" | "repository" | "baseRef" | "headRef" | "continuation"> & {
76
+ baseCommit?: string;
77
+ };
49
78
  /** Already-validated/redacted agent-authored fields (coding/protocol.ts) surfaced in the opened PR, if any. */
50
79
  export interface FinalizeChangesDetails {
51
80
  summary?: string;
@@ -59,20 +88,33 @@ export interface FinalizeChangesDetails {
59
88
  ecosystem: string;
60
89
  name: string;
61
90
  version: string;
91
+ /** Blocking advisories the run's accepted set waived to serve it. */
92
+ acceptedAdvisories?: readonly string[];
62
93
  }[];
63
94
  packageRefusals?: readonly {
64
95
  ecosystem: string;
65
96
  name: string;
66
97
  reason: string;
67
98
  }[];
99
+ /** Package audit mode (control-plane records): the mode the run(s) had and what the registry served only
100
+ * because of it, for the PR body's caution banner. Absent when the mode was off. */
101
+ packageAudit?: PackageAuditReport;
102
+ /** Folders whose node_modules the run's dependency cache restored from a snapshot ("." for the root), for the PR body. */
103
+ restoredDependencies?: readonly string[];
68
104
  /** Originating issue (control-plane data): named in the PR title and body. Provider-neutral. */
69
105
  issue?: {
70
106
  key: string;
71
107
  url?: string;
72
108
  trackerName?: string;
73
109
  };
110
+ /** The same-repository issue the run came from (a mention on a GitHub issue): the body's `From issue #N` line (a link; it never closes the issue). */
111
+ issueNumber?: number;
74
112
  /** The request's other pull requests (control-plane rows): the PR body's Related pull requests section. */
75
113
  related?: RelatedPullRequestsInput;
114
+ /** Fix rounds: the control plane's record of the description wardby last wrote; enables the description update. */
115
+ description?: {
116
+ baseline: DescriptionBaseline;
117
+ };
76
118
  }
77
119
  export type FinalizeChangesResult = {
78
120
  outcome: "no_changes";
@@ -88,6 +130,7 @@ export type FinalizeChangesResult = {
88
130
  commitSha: string;
89
131
  pullRequestNumber: number;
90
132
  pullRequestUrl: string;
133
+ description?: DescriptionWriteOutcome;
91
134
  } | {
92
135
  /** Revision-in-place: pushed a new commit onto an existing open PR's
93
136
  * branch instead of opening a new one. */
@@ -99,6 +142,13 @@ export type FinalizeChangesResult = {
99
142
  commitSha: string;
100
143
  pullRequestNumber: number;
101
144
  pullRequestUrl: string;
145
+ description?: DescriptionWriteOutcome;
146
+ /** The pushed head is a merge of the PR's target branch (see PreparedWorkspace.targetMerge). */
147
+ targetMerge?: {
148
+ ref: string;
149
+ targetCommit: string;
150
+ conflicts: number;
151
+ };
102
152
  } | {
103
153
  /** Pushed the run's branch to a remote with no pull requests (a local
104
154
  * repository): headRef now points at commitSha there. */
@@ -143,12 +193,13 @@ export interface VcsProvider {
143
193
  * `FinalizeChangesDetails.summary`) so the "done" status reflects what
144
194
  * actually happened instead of a caller having to go find out.
145
195
  * `budget_exhausted` is a failure that ran out of budget;
146
- * `details.budgetSentence` then says how (see core/budget-wording.ts).
196
+ * `details.budgetSentence` then says how (see core/budget-wording.ts), and
197
+ * `details.changesPushed` says its changes so far were pushed anyway.
147
198
  * A `failed` run the model provider refused carries `details.providerSentence`.
148
199
  * A `failed` run whose changes touched a protected path carries
149
200
  * `details.protectedPathSentence` (see coding/protected-path-wording.ts).
150
201
  */
151
- notifyContinuationFinished?(workspace: PreparedWorkspace, outcome: ContinuationOutcome, details?: ContinuationFinishedDetails): Promise<void>;
202
+ notifyContinuationFinished?(workspace: ContinuationTarget, outcome: ContinuationOutcome, details?: ContinuationFinishedDetails): Promise<void>;
152
203
  /**
153
204
  * The raw text of one repository file at a ref, read through the host's API
154
205
  * without a clone, or null when it does not exist. Dispatch reads a coding
@@ -157,6 +208,19 @@ export interface VcsProvider {
157
208
  * provider (or test double) without it gives runs no services.
158
209
  */
159
210
  readRepositoryFile?(input: RepositoryFileInput): Promise<string | null>;
211
+ /**
212
+ * Re-derive a continuation's pull request description without pushing (a fix
213
+ * round that made no changes). Undefined when there is nothing to refresh
214
+ * (no description details, or a remote without pull requests). Never throws.
215
+ */
216
+ refreshPullRequestDescription?(workspace: ContinuationTarget, details: FinalizeChangesDetails): Promise<DescriptionWriteOutcome | undefined>;
217
+ /**
218
+ * Whether the pull request a continuation pushes to is still a draft, per
219
+ * the host: true or false, or undefined when unknown (a fresh run, a remote
220
+ * without pull requests, a pull request no longer open, or a failed
221
+ * lookup). Optional; never throws.
222
+ */
223
+ continuationPullRequestDraft?(workspace: PreparedWorkspace): Promise<boolean | undefined>;
160
224
  }
161
225
  export type ContinuationOutcome = "succeeded" | "failed" | "budget_exhausted";
162
226
  export interface ContinuationFinishedDetails {
@@ -164,10 +228,23 @@ export interface ContinuationFinishedDetails {
164
228
  agentName?: string;
165
229
  /** Host-safe sentence naming the run's budget; used with `budget_exhausted`. */
166
230
  budgetSentence?: string;
231
+ /** Host-safe sentence for a run that finished over its base budget (core/budget-wording.ts); used with `succeeded`. */
232
+ overrunSentence?: string;
167
233
  /** Host-safe sentence naming a model-provider refusal (see core/provider-wording.ts); used with `failed`. */
168
234
  providerSentence?: string;
169
235
  /** Host-safe sentence naming a coding-run service that never became ready (coding/services/wording.ts); used with `failed`. */
170
236
  serviceSentence?: string;
171
237
  /** Host-safe sentence naming a protected path the run's changes touched (coding/protected-path-wording.ts); used with `failed`. */
172
238
  protectedPathSentence?: string;
239
+ /** Host-safe sentence naming what was merged from the target branch (coding/merge-wording.ts); used with `succeeded`. */
240
+ mergeSentence?: string;
241
+ /** Host-safe sentence naming a file still holding conflict markers (coding/merge-wording.ts); used with `failed`. */
242
+ conflictMarkersSentence?: string;
243
+ /**
244
+ * Set with `budget_exhausted` when the run's changes so far were pushed anyway
245
+ * (the pull request it opened or continued, or a branch with no number).
246
+ */
247
+ changesPushed?: {
248
+ pullRequestNumber?: number;
249
+ };
173
250
  }