@wardby/cli 0.5.2 → 0.6.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 (411) hide show
  1. package/.env.example +33 -0
  2. package/README.md +25 -14
  3. package/dist/claude-coding-worker/context.d.ts +22 -0
  4. package/dist/claude-coding-worker/context.js +92 -0
  5. package/dist/claude-coding-worker/driver.d.ts +7 -1
  6. package/dist/claude-coding-worker/driver.js +38 -5
  7. package/dist/claude-coding-worker/sdk.js +13 -4
  8. package/dist/cli-help.d.ts +1 -1
  9. package/dist/cli-help.js +5 -2
  10. package/dist/cli-native-mode.d.ts +9 -0
  11. package/dist/cli-native-mode.js +20 -0
  12. package/dist/cli.d.ts +3 -1
  13. package/dist/cli.js +141 -5
  14. package/dist/coding/claude-context.d.ts +45 -0
  15. package/dist/coding/claude-context.js +434 -0
  16. package/dist/coding/local-git.js +9 -1
  17. package/dist/coding/profile.d.ts +12 -0
  18. package/dist/coding/profile.js +6 -0
  19. package/dist/coding/protocol.d.ts +104 -0
  20. package/dist/coding/protocol.js +87 -3
  21. package/dist/coding/registry/pypi.d.ts +25 -1
  22. package/dist/coding/registry/pypi.js +140 -16
  23. package/dist/coding/registry/types.d.ts +17 -3
  24. package/dist/coding-worker/artifact.d.ts +8 -0
  25. package/dist/coding-worker/artifact.js +2 -2
  26. package/dist/coding-worker/driver.js +2 -0
  27. package/dist/coding-worker/sdk.d.ts +6 -0
  28. package/dist/coding-worker/sdk.js +1 -0
  29. package/dist/coding-worker/skills.d.ts +23 -0
  30. package/dist/coding-worker/skills.js +117 -0
  31. package/dist/coding-worker/types.d.ts +2 -0
  32. package/dist/config/github-allowed-accounts.d.ts +15 -0
  33. package/dist/config/github-allowed-accounts.js +36 -0
  34. package/dist/config/low-power.d.ts +12 -0
  35. package/dist/config/low-power.js +18 -0
  36. package/dist/config/mobile.d.ts +12 -0
  37. package/dist/config/mobile.js +18 -0
  38. package/dist/config/providers.d.ts +56 -2
  39. package/dist/config/providers.js +92 -6
  40. package/dist/core/db.d.ts +16 -6
  41. package/dist/core/db.js +12 -10
  42. package/dist/core/dispatch.d.ts +11 -0
  43. package/dist/core/dispatch.js +36 -1
  44. package/dist/core/engine-native.js +9 -5
  45. package/dist/core/host-events.d.ts +49 -3
  46. package/dist/core/host-events.js +289 -15
  47. package/dist/core/http-runtime.js +13 -6
  48. package/dist/core/issue-bridge.js +42 -2
  49. package/dist/core/issue-events.js +12 -1
  50. package/dist/core/issue-status.js +14 -3
  51. package/dist/core/merge-order-check.d.ts +129 -0
  52. package/dist/core/merge-order-check.js +336 -0
  53. package/dist/core/notification-dispatcher.d.ts +70 -0
  54. package/dist/core/notification-dispatcher.js +368 -0
  55. package/dist/core/notification-templates.d.ts +25 -0
  56. package/dist/core/notification-templates.js +105 -0
  57. package/dist/core/notifications.d.ts +10 -0
  58. package/dist/core/notifications.js +38 -0
  59. package/dist/core/pg-auth.d.ts +22 -0
  60. package/dist/core/pg-auth.js +152 -0
  61. package/dist/core/power-composition.d.ts +16 -0
  62. package/dist/core/power-composition.js +37 -0
  63. package/dist/core/power-idle.d.ts +14 -0
  64. package/dist/core/power-idle.js +30 -0
  65. package/dist/core/power.d.ts +71 -0
  66. package/dist/core/power.js +202 -0
  67. package/dist/core/reconciler.d.ts +4 -2
  68. package/dist/core/reconciler.js +29 -5
  69. package/dist/core/related-pull-requests.d.ts +48 -4
  70. package/dist/core/related-pull-requests.js +113 -11
  71. package/dist/core/repo-access.d.ts +15 -0
  72. package/dist/core/repo-access.js +66 -0
  73. package/dist/core/review-fix.d.ts +37 -0
  74. package/dist/core/review-fix.js +207 -6
  75. package/dist/core/review-host-tools.d.ts +20 -0
  76. package/dist/core/review-host-tools.js +58 -2
  77. package/dist/core/runner.d.ts +336 -3
  78. package/dist/core/runner.js +894 -317
  79. package/dist/core/secret-broker-config.d.ts +103 -0
  80. package/dist/core/secret-broker-config.js +112 -0
  81. package/dist/core/secrets.d.ts +39 -4
  82. package/dist/core/secrets.js +148 -40
  83. package/dist/core/workflow-event-recorder.d.ts +14 -0
  84. package/dist/core/workflow-event-recorder.js +120 -0
  85. package/dist/core/workflow-events.d.ts +82 -0
  86. package/dist/core/workflow-events.js +44 -0
  87. package/dist/core/workflow-run-events.d.ts +16 -0
  88. package/dist/core/workflow-run-events.js +40 -0
  89. package/dist/generated/prisma/browser.d.ts +58 -0
  90. package/dist/generated/prisma/client.d.ts +58 -0
  91. package/dist/generated/prisma/commonInputTypes.d.ts +150 -0
  92. package/dist/generated/prisma/enums.d.ts +27 -0
  93. package/dist/generated/prisma/enums.js +23 -0
  94. package/dist/generated/prisma/internal/class.d.ts +88 -0
  95. package/dist/generated/prisma/internal/class.js +4 -4
  96. package/dist/generated/prisma/internal/prismaNamespace.d.ts +772 -1
  97. package/dist/generated/prisma/internal/prismaNamespace.js +135 -4
  98. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +139 -0
  99. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +135 -4
  100. package/dist/generated/prisma/models/Agent.d.ts +360 -1
  101. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +73 -1
  102. package/dist/generated/prisma/models/CodingRun.d.ts +205 -1
  103. package/dist/generated/prisma/models/DeferredReview.d.ts +78 -1
  104. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +1675 -0
  105. package/dist/generated/prisma/models/NativeGatewayCall.js +1 -0
  106. package/dist/generated/prisma/models/NativeGatewaySession.d.ts +1517 -0
  107. package/dist/generated/prisma/models/NativeGatewaySession.js +1 -0
  108. package/dist/generated/prisma/models/NativeWarmWorker.d.ts +1296 -0
  109. package/dist/generated/prisma/models/NativeWarmWorker.js +1 -0
  110. package/dist/generated/prisma/models/NotificationChannel.d.ts +1543 -0
  111. package/dist/generated/prisma/models/NotificationChannel.js +1 -0
  112. package/dist/generated/prisma/models/NotificationDelivery.d.ts +1502 -0
  113. package/dist/generated/prisma/models/NotificationDelivery.js +1 -0
  114. package/dist/generated/prisma/models/NotificationThread.d.ts +1090 -0
  115. package/dist/generated/prisma/models/NotificationThread.js +1 -0
  116. package/dist/generated/prisma/models/Run.d.ts +826 -1
  117. package/dist/generated/prisma/models/RunHostCheck.d.ts +36 -1
  118. package/dist/generated/prisma/models/Secret.d.ts +37 -1
  119. package/dist/generated/prisma/models/SecretBrokerChange.d.ts +1101 -0
  120. package/dist/generated/prisma/models/SecretBrokerChange.js +1 -0
  121. package/dist/generated/prisma/models/WorkflowEvent.d.ts +1422 -0
  122. package/dist/generated/prisma/models/WorkflowEvent.js +1 -0
  123. package/dist/generated/prisma/models.d.ts +8 -0
  124. package/dist/help/build.js +4 -2
  125. package/dist/help/catalog.d.ts +1 -1
  126. package/dist/help/catalog.js +31 -6
  127. package/dist/help-index.json +1492 -113
  128. package/dist/import/create.js +17 -0
  129. package/dist/import/neutral-schema.d.ts +6 -2
  130. package/dist/import/neutral-schema.js +2 -0
  131. package/dist/mcp/auth/access.d.ts +1 -0
  132. package/dist/mcp/auth/ownership.d.ts +1 -1
  133. package/dist/mcp/auth/repo-authorization.js +14 -0
  134. package/dist/mcp/auth/resource-server.d.ts +2 -1
  135. package/dist/mcp/auth/resource-server.js +7 -2
  136. package/dist/mcp/auth/self-hosted/browser.d.ts +1 -1
  137. package/dist/mcp/auth/self-hosted/browser.js +19 -6
  138. package/dist/mcp/context.d.ts +6 -0
  139. package/dist/mcp/host-events/github-ingress.d.ts +23 -1
  140. package/dist/mcp/host-events/github-ingress.js +68 -0
  141. package/dist/mcp/index.d.ts +13 -0
  142. package/dist/mcp/index.js +59 -10
  143. package/dist/mcp/tools/agents.js +83 -12
  144. package/dist/mcp/tools/notification-channels.d.ts +2 -0
  145. package/dist/mcp/tools/notification-channels.js +293 -0
  146. package/dist/mcp/tools/power.d.ts +2 -0
  147. package/dist/mcp/tools/power.js +77 -0
  148. package/dist/mcp/tools/runs.d.ts +0 -6
  149. package/dist/mcp/tools/runs.js +7 -2
  150. package/dist/mcp/tools/secret-broker-compat.d.ts +12 -0
  151. package/dist/mcp/tools/secret-broker-compat.js +23 -0
  152. package/dist/mcp/tools/secret-elicitation-form.d.ts +22 -2
  153. package/dist/mcp/tools/secret-elicitation-form.js +200 -10
  154. package/dist/mcp/tools/secret-elicitation-server.js +8 -1
  155. package/dist/mcp/tools/secret-elicitation.d.ts +38 -3
  156. package/dist/mcp/tools/secret-elicitation.js +110 -12
  157. package/dist/mcp/tools/secrets.js +184 -7
  158. package/dist/mcp/tools/tools.d.ts +1 -1
  159. package/dist/mcp/tools/tools.js +22 -2
  160. package/dist/native-worker/composition.d.ts +23 -0
  161. package/dist/native-worker/composition.js +77 -0
  162. package/dist/native-worker/docker-isolation.d.ts +65 -0
  163. package/dist/native-worker/docker-isolation.js +183 -0
  164. package/dist/native-worker/docker-launcher.d.ts +74 -0
  165. package/dist/native-worker/docker-launcher.js +237 -0
  166. package/dist/native-worker/gateway-server.d.ts +39 -0
  167. package/dist/native-worker/gateway-server.js +315 -0
  168. package/dist/native-worker/gateway.d.ts +44 -0
  169. package/dist/native-worker/gateway.js +197 -0
  170. package/dist/native-worker/http-server.d.ts +22 -0
  171. package/dist/native-worker/http-server.js +109 -0
  172. package/dist/native-worker/http-transport.d.ts +17 -0
  173. package/dist/native-worker/http-transport.js +88 -0
  174. package/dist/native-worker/kubernetes-isolation.d.ts +90 -0
  175. package/dist/native-worker/kubernetes-isolation.js +218 -0
  176. package/dist/native-worker/kubernetes-launcher.d.ts +102 -0
  177. package/dist/native-worker/kubernetes-launcher.js +335 -0
  178. package/dist/native-worker/launch.d.ts +45 -0
  179. package/dist/native-worker/launch.js +44 -0
  180. package/dist/native-worker/ledger.d.ts +109 -0
  181. package/dist/native-worker/ledger.js +192 -0
  182. package/dist/native-worker/loopback.d.ts +12 -0
  183. package/dist/native-worker/loopback.js +49 -0
  184. package/dist/native-worker/main.d.ts +7 -0
  185. package/dist/native-worker/main.js +74 -0
  186. package/dist/native-worker/protocol.d.ts +744 -0
  187. package/dist/native-worker/protocol.js +200 -0
  188. package/dist/native-worker/sandbox-executor.d.ts +68 -0
  189. package/dist/native-worker/sandbox-executor.js +210 -0
  190. package/dist/native-worker/stdio.d.ts +29 -0
  191. package/dist/native-worker/stdio.js +188 -0
  192. package/dist/native-worker/warm-delivery.d.ts +16 -0
  193. package/dist/native-worker/warm-delivery.js +33 -0
  194. package/dist/native-worker/warm-pool-ledger.d.ts +39 -0
  195. package/dist/native-worker/warm-pool-ledger.js +73 -0
  196. package/dist/native-worker/warm-pool.d.ts +107 -0
  197. package/dist/native-worker/warm-pool.js +283 -0
  198. package/dist/native-worker/worker.d.ts +17 -0
  199. package/dist/native-worker/worker.js +115 -0
  200. package/dist/providers/auth/authorization-server.d.ts +3 -0
  201. package/dist/providers/auth/index.js +2 -0
  202. package/dist/providers/auth/self-hosted.d.ts +13 -1
  203. package/dist/providers/auth/self-hosted.js +54 -4
  204. package/dist/providers/chat/fake.d.ts +46 -0
  205. package/dist/providers/chat/fake.js +39 -0
  206. package/dist/providers/chat/index.d.ts +4 -0
  207. package/dist/providers/chat/index.js +8 -0
  208. package/dist/providers/chat/slack.d.ts +37 -0
  209. package/dist/providers/chat/slack.js +105 -0
  210. package/dist/providers/chat/types.d.ts +42 -0
  211. package/dist/providers/chat/types.js +19 -0
  212. package/dist/providers/coding-proxy/mock-upstream.d.ts +33 -0
  213. package/dist/providers/coding-proxy/mock-upstream.js +116 -0
  214. package/dist/providers/coding-proxy/registry/prisma-store.d.ts +3 -0
  215. package/dist/providers/coding-proxy/registry/prisma-store.js +17 -0
  216. package/dist/providers/coding-proxy/registry/service.d.ts +4 -0
  217. package/dist/providers/coding-proxy/registry/service.js +20 -3
  218. package/dist/providers/coding-proxy/registry/store.d.ts +18 -1
  219. package/dist/providers/coding-proxy/registry/store.js +33 -0
  220. package/dist/providers/coding-proxy/runtime.js +12 -1
  221. package/dist/providers/coding-proxy/types.d.ts +2 -0
  222. package/dist/providers/engine/types.d.ts +19 -0
  223. package/dist/providers/engine/types.js +22 -0
  224. package/dist/providers/executor/composition.d.ts +24 -1
  225. package/dist/providers/executor/composition.js +39 -6
  226. package/dist/providers/executor/container.d.ts +24 -1
  227. package/dist/providers/executor/container.js +101 -11
  228. package/dist/providers/executor/dbos.d.ts +42 -0
  229. package/dist/providers/executor/dbos.js +118 -12
  230. package/dist/providers/executor/deferred.d.ts +56 -0
  231. package/dist/providers/executor/deferred.js +119 -0
  232. package/dist/providers/executor/routing.d.ts +37 -10
  233. package/dist/providers/executor/routing.js +73 -32
  234. package/dist/providers/executor/types.d.ts +12 -0
  235. package/dist/providers/jobs/docker.js +3 -3
  236. package/dist/providers/jobs/fake-kubernetes-api.d.ts +21 -2
  237. package/dist/providers/jobs/fake-kubernetes-api.js +42 -1
  238. package/dist/providers/jobs/kubernetes-api.d.ts +17 -1
  239. package/dist/providers/jobs/kubernetes-api.js +7 -0
  240. package/dist/providers/jobs/kubernetes-client.d.ts +10 -1
  241. package/dist/providers/jobs/kubernetes-client.js +52 -3
  242. package/dist/providers/jobs/kubernetes-dry-run-fixture.d.ts +6 -1
  243. package/dist/providers/jobs/kubernetes-dry-run-fixture.js +6 -3
  244. package/dist/providers/jobs/kubernetes-isolation.d.ts +16 -1
  245. package/dist/providers/jobs/kubernetes-isolation.js +58 -5
  246. package/dist/providers/jobs/kubernetes-platform.d.ts +4 -1
  247. package/dist/providers/jobs/kubernetes-platform.js +38 -1
  248. package/dist/providers/jobs/kubernetes-preflight.d.ts +2 -1
  249. package/dist/providers/jobs/kubernetes-preflight.js +4 -2
  250. package/dist/providers/jobs/kubernetes.d.ts +56 -7
  251. package/dist/providers/jobs/kubernetes.js +117 -36
  252. package/dist/providers/jobs/metadata-probes.d.ts +11 -0
  253. package/dist/providers/jobs/metadata-probes.js +13 -0
  254. package/dist/providers/jobs/types.d.ts +9 -0
  255. package/dist/providers/llm/openai.js +0 -1
  256. package/dist/providers/review-host/github.d.ts +11 -1
  257. package/dist/providers/review-host/github.js +50 -0
  258. package/dist/providers/review-host/types.d.ts +23 -0
  259. package/dist/providers/vcs/github.d.ts +32 -6
  260. package/dist/providers/vcs/github.js +74 -16
  261. package/dist/quickstart/coding-db.js +14 -2
  262. package/dist/quickstart/coding-doctor.d.ts +3 -0
  263. package/dist/quickstart/coding-doctor.js +3 -0
  264. package/dist/quickstart/coding-images.d.ts +9 -0
  265. package/dist/quickstart/coding-images.js +39 -0
  266. package/dist/quickstart/coding-seed.d.ts +20 -1
  267. package/dist/quickstart/coding-seed.js +96 -7
  268. package/dist/quickstart/coding.d.ts +2 -0
  269. package/dist/quickstart/coding.js +75 -3
  270. package/dist/quickstart/config.d.ts +2 -0
  271. package/dist/quickstart/config.js +4 -0
  272. package/dist/quickstart/images.d.ts +13 -0
  273. package/dist/quickstart/images.js +80 -12
  274. package/dist/quickstart/index.d.ts +0 -2
  275. package/dist/quickstart/index.js +10 -14
  276. package/dist/quickstart/manifests.d.ts +56 -0
  277. package/dist/quickstart/manifests.js +523 -0
  278. package/dist/quickstart/python-detect.d.ts +10 -0
  279. package/dist/quickstart/python-detect.js +32 -0
  280. package/dist/quickstart/repo-packages.d.ts +10 -0
  281. package/dist/quickstart/repo-packages.js +132 -0
  282. package/dist/quickstart/reviewer-prompt.d.ts +12 -0
  283. package/dist/quickstart/reviewer-prompt.js +84 -0
  284. package/dist/quickstart/scenarios.d.ts +19 -0
  285. package/dist/quickstart/scenarios.js +28 -0
  286. package/dist/quickstart/sync-reviewer-prompt.d.ts +1 -0
  287. package/dist/quickstart/sync-reviewer-prompt.js +10 -0
  288. package/dist/quickstart-images.json +1 -1
  289. package/dist/sandbox/brokered-fetch.d.ts +23 -0
  290. package/dist/sandbox/brokered-fetch.js +37 -0
  291. package/dist/sandbox/host-functions.d.ts +34 -0
  292. package/dist/sandbox/host-functions.js +144 -80
  293. package/dist/sandbox/prelude.js +7 -1
  294. package/dist/sandbox/run-in-sandbox.d.ts +19 -0
  295. package/dist/sandbox/run-in-sandbox.js +28 -10
  296. package/dist/sandbox/safe-fetch.d.ts +2 -0
  297. package/dist/sandbox/safe-fetch.js +3 -1
  298. package/dist/sandbox/secret-broker-sigv4.d.ts +2 -0
  299. package/dist/sandbox/secret-broker-sigv4.js +49 -0
  300. package/dist/sandbox/secret-broker.d.ts +34 -0
  301. package/dist/sandbox/secret-broker.js +162 -0
  302. package/dist/sandbox/user-tool.d.ts +14 -0
  303. package/dist/sandbox/user-tool.js +32 -0
  304. package/dist/serve.js +18 -0
  305. package/dist/viewer/api-schema.d.ts +214 -18
  306. package/dist/viewer/api-schema.js +22 -0
  307. package/dist/viewer/build-schemas.js +4 -1
  308. package/dist/viewer/event-bus.d.ts +6 -0
  309. package/dist/viewer/event-bus.js +16 -7
  310. package/dist/viewer/graph.d.ts +5 -2
  311. package/dist/viewer/graph.js +7 -2
  312. package/dist/viewer/http.d.ts +0 -1
  313. package/dist/viewer/http.js +2 -2
  314. package/dist/viewer/infra.js +25 -2
  315. package/dist/viewer/limits.d.ts +4 -0
  316. package/dist/viewer/limits.js +4 -0
  317. package/dist/viewer/openapi.d.ts +15 -0
  318. package/dist/viewer/openapi.js +172 -0
  319. package/docs/README.md +7 -0
  320. package/docs/agent-recipes.md +57 -8
  321. package/docs/architecture-runtime.md +16 -1
  322. package/docs/code-review-agents.md +139 -5
  323. package/docs/coding-agent-setup.md +127 -2
  324. package/docs/coding-packages.md +105 -5
  325. package/docs/coding-services.md +3 -1
  326. package/docs/coding-worker-byo-images.md +239 -2
  327. package/docs/coding-worker-isolation.md +88 -23
  328. package/docs/getting-started-gke.md +225 -9
  329. package/docs/getting-started-identity-provider.md +21 -10
  330. package/docs/getting-started.md +140 -11
  331. package/docs/jira-agents.md +5 -1
  332. package/docs/knowledge.md +11 -0
  333. package/docs/native-sandbox.md +635 -0
  334. package/docs/release-verification.md +9 -0
  335. package/docs/security-deployment.md +113 -12
  336. package/docs/slack-notifications.md +252 -0
  337. package/docs/tool-secrets.md +252 -0
  338. package/docs/viewer-api.md +46 -5
  339. package/docs/viewer-api.openapi.yml +1404 -0
  340. package/help/admin-viewer.md +6 -2
  341. package/help/agent-recipes.md +27 -0
  342. package/help/architecture-agent.md +136 -0
  343. package/help/brokered-secrets.md +79 -0
  344. package/help/build-claude-code-image.md +131 -0
  345. package/help/build-worker-image.md +195 -0
  346. package/help/code-review-agents.md +68 -6
  347. package/help/coding-packages.md +31 -2
  348. package/help/creating-agents.md +14 -0
  349. package/help/deploy-gke.md +37 -6
  350. package/help/deployment-targets.md +24 -13
  351. package/help/errors/coding-provider-not-configured.md +2 -2
  352. package/help/errors/database-auth-invalid.md +28 -0
  353. package/help/errors/github-account-not-allowed.md +25 -0
  354. package/help/errors/low-power-disabled.md +29 -0
  355. package/help/errors/low-power-scale-forbidden.md +35 -0
  356. package/help/errors/low-power-wake-timeout.md +30 -0
  357. package/help/errors/mobile-disabled.md +31 -0
  358. package/help/errors/native-sandbox-capacity.md +22 -0
  359. package/help/errors/native-sandbox-deadline-exceeded.md +19 -0
  360. package/help/errors/native-sandbox-docker-failed.md +20 -0
  361. package/help/errors/native-sandbox-gateway-unavailable.md +21 -0
  362. package/help/errors/native-sandbox-image-not-pinned.md +19 -0
  363. package/help/errors/native-sandbox-isolation-mismatch.md +20 -0
  364. package/help/errors/native-sandbox-network-unenforced.md +22 -0
  365. package/help/errors/native-sandbox-requires-catalog.md +31 -0
  366. package/help/errors/native-sandbox-unavailable.md +19 -0
  367. package/help/errors/native-sandbox-warm-delivery-failed.md +21 -0
  368. package/help/errors/native-sandbox-worker-exited.md +20 -0
  369. package/help/errors/native-sandbox-worker-lost.md +20 -0
  370. package/help/errors/native-sandbox-worker-unready.md +22 -0
  371. package/help/errors/secret-broker-body-invalid.md +26 -0
  372. package/help/errors/secret-broker-changed.md +20 -0
  373. package/help/errors/secret-broker-config-invalid.md +30 -0
  374. package/help/errors/secret-broker-conflict.md +27 -0
  375. package/help/errors/secret-broker-destination-denied.md +28 -0
  376. package/help/errors/secret-broker-value-invalid.md +28 -0
  377. package/help/errors/secret-brokered.md +24 -0
  378. package/help/errors/secret-not-brokered.md +25 -0
  379. package/help/errors/slack-auth-failed.md +48 -0
  380. package/help/errors/slack-channel-unreachable.md +39 -0
  381. package/help/errors/slack-not-configured.md +33 -0
  382. package/help/getting-started.md +18 -0
  383. package/help/github.md +18 -1
  384. package/help/identity-and-access.md +5 -1
  385. package/help/local-repositories.md +35 -5
  386. package/help/low-power-mode.md +125 -0
  387. package/help/merge-order-check.md +117 -0
  388. package/help/mobile-app.md +54 -0
  389. package/help/native-sandbox.md +136 -0
  390. package/help/observability.md +8 -0
  391. package/help/related-pull-requests.md +70 -9
  392. package/help/repo-instructions-and-skills.md +91 -0
  393. package/help/review-fix-rounds.md +10 -0
  394. package/help/slack-notifications.md +62 -0
  395. package/help/troubleshooting/coding-workers.md +21 -0
  396. package/package.json +13 -5
  397. package/prisma/migrations/20261009000003_native_execution_mode/migration.sql +12 -0
  398. package/prisma/migrations/20261009000004_native_gateway_ledger/migration.sql +65 -0
  399. package/prisma/migrations/20261009000005_native_gateway_call_child_agent/migration.sql +5 -0
  400. package/prisma/migrations/20261009000006_run_deferred_start_stop/migration.sql +14 -0
  401. package/prisma/migrations/20261009000007_native_gateway_network_ready/migration.sql +5 -0
  402. package/prisma/migrations/20261010000001_workflow_notifications/migration.sql +99 -0
  403. package/prisma/migrations/20261011000001_native_gateway_session_status_index/migration.sql +2 -0
  404. package/prisma/migrations/20261012000001_native_warm_worker/migration.sql +32 -0
  405. package/prisma/migrations/20261013000001_coding_run_merge_order/migration.sql +2 -0
  406. package/prisma/migrations/20261013000001_secret_broker/migration.sql +17 -0
  407. package/prisma/migrations/20261013000002_deferred_review_request/migration.sql +4 -0
  408. package/prisma/migrations/20261014000000_repo_skills/migration.sql +15 -0
  409. package/prisma/migrations/20261015000001_coding_run_merge_order_index/migration.sql +2 -0
  410. package/prisma/migrations/20261015000002_no_change_rereview/migration.sql +2 -0
  411. package/prisma/schema.prisma +362 -91
@@ -16,6 +16,7 @@
16
16
  import pg from "pg";
17
17
  import { poolSettings } from "../core/db.js";
18
18
  import { logger } from "../core/logger.js";
19
+ import { databaseAuthFromEnv, pgConnectionConfig } from "../core/pg-auth.js";
19
20
  import { ViewerEventSchema } from "./api-schema.js";
20
21
  export const VIEWER_CHANNEL = "wardby_viewer";
21
22
  const DEFAULT_RECONNECT_DELAYS_MS = [500, 1000, 2000, 5000, 10_000];
@@ -25,17 +26,25 @@ const DEFAULT_HEALTH_CHECK_INTERVAL_MS = 60_000;
25
26
  const DEFAULT_HEALTH_CHECK_TIMEOUT_MS = 10_000;
26
27
  /** Upper bound on waiting for a graceful disconnect (a half-open socket never answers). */
27
28
  const END_TIMEOUT_MS = 2_000;
29
+ /** The LISTEN client's config: auth (pg-auth.ts) plus keepAlive and the pool's connect timeout. */
30
+ export function eventBusClientConfig(connectionString, auth, pgAuth) {
31
+ return {
32
+ ...pgConnectionConfig(connectionString, auth, pgAuth),
33
+ keepAlive: true,
34
+ keepAliveInitialDelayMillis: KEEPALIVE_INITIAL_DELAY_MS,
35
+ connectionTimeoutMillis: poolSettings(connectionString).connectionTimeoutMillis,
36
+ };
37
+ }
28
38
  export function createViewerEventBus(options) {
29
39
  const healthIntervalMs = options.healthCheckIntervalMs ?? DEFAULT_HEALTH_CHECK_INTERVAL_MS;
30
40
  const healthTimeoutMs = options.healthCheckTimeoutMs ?? DEFAULT_HEALTH_CHECK_TIMEOUT_MS;
31
41
  const delays = options.reconnectDelaysMs?.length ? options.reconnectDelaysMs : DEFAULT_RECONNECT_DELAYS_MS;
32
- const makeClient = options.connect ??
33
- ((connectionString) => new pg.Client({
34
- connectionString,
35
- keepAlive: true,
36
- keepAliveInitialDelayMillis: KEEPALIVE_INITIAL_DELAY_MS,
37
- connectionTimeoutMillis: poolSettings(connectionString).connectionTimeoutMillis,
38
- }));
42
+ // Built once, up front: a misconfigured DATABASE_AUTH fails here rather than on every reconnect,
43
+ // and under rds-iam every reconnect shares one token cache.
44
+ const clientConfig = options.connect
45
+ ? undefined
46
+ : eventBusClientConfig(options.connectionString, options.auth ?? databaseAuthFromEnv(), options.pgAuth);
47
+ const makeClient = options.connect ?? (() => new pg.Client({ ...clientConfig }));
39
48
  const listeners = new Set();
40
49
  const stateListeners = new Set();
41
50
  let client = null; // the current attempt/connection
@@ -1,8 +1,6 @@
1
1
  /** The graph snapshot read model behind GET /admin/api/graph (docs/viewer-api.md). */
2
2
  import type { Prisma, PrismaClient } from "#prisma";
3
3
  import type { GraphRun, GraphSnapshot } from "./api-schema.js";
4
- export declare const DEFAULT_GRAPH_LIMIT = 500;
5
- export declare const MAX_GRAPH_LIMIT = 2000;
6
4
  /** Accepts "15m" | "1h" | "6h" | "24h" | "7d" or an ISO-8601 timestamp; null defaults to 1h. Throws otherwise. */
7
5
  export declare function parseSince(value: string | null, now: Date): Date;
8
6
  declare const runInclude: {
@@ -23,6 +21,11 @@ declare const runInclude: {
23
21
  createdAt: "asc";
24
22
  };
25
23
  };
24
+ nativeWarmWorker: {
25
+ select: {
26
+ name: true;
27
+ };
28
+ };
26
29
  };
27
30
  type RunRow = Prisma.RunGetPayload<{
28
31
  include: typeof runInclude;
@@ -1,7 +1,5 @@
1
1
  import { periodStart } from "../core/budget-groups.js";
2
2
  import { publicCodingRunResult } from "../coding/protocol.js";
3
- export const DEFAULT_GRAPH_LIMIT = 500;
4
- export const MAX_GRAPH_LIMIT = 2000;
5
3
  const DEFAULT_SINCE_MS = 60 * 60 * 1000;
6
4
  const RELATIVE_SINCE_MS = {
7
5
  "15m": 15 * 60 * 1000,
@@ -30,6 +28,7 @@ const runInclude = {
30
28
  hostStatus: true,
31
29
  issueStatus: true,
32
30
  serviceStatuses: { orderBy: { createdAt: "asc" } },
31
+ nativeWarmWorker: { select: { name: true } },
33
32
  };
34
33
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
35
34
  /** Name and version of each service in a coding run's resolved services snapshot. */
@@ -151,6 +150,12 @@ export function toGraphRun(row, pullRequests, sites = {}) {
151
150
  agentKind: row.agent.kind,
152
151
  model: row.codingRun?.model ?? row.agent.model,
153
152
  codingProvider: row.codingRun?.provider ?? null,
153
+ nativeExecutionMode: row.nativeExecutionMode === "sandbox"
154
+ ? "sandbox"
155
+ : row.nativeExecutionMode === "control_plane"
156
+ ? "control-plane"
157
+ : null,
158
+ warmWorkerName: row.nativeWarmWorker?.name ?? null,
154
159
  status: row.status,
155
160
  trigger: triggerFor(row, sites),
156
161
  turns: row.turns,
@@ -12,7 +12,6 @@ import type { InfraInfo } from "./api-schema.js";
12
12
  import { type IssueSites } from "./graph.js";
13
13
  import type { ViewerEventBus } from "./event-bus.js";
14
14
  export declare const VIEWER_API_PREFIX = "/admin/api/";
15
- export declare const SSE_HEARTBEAT_MS = 15000;
16
15
  /** A stream whose unsent backlog exceeds this is ended; the client reconnects and resyncs. */
17
16
  export declare const SSE_MAX_BUFFERED_BYTES: number;
18
17
  export interface ViewerApiDeps {
@@ -1,9 +1,9 @@
1
1
  import { requireScope } from "../mcp/auth/resource-server.js";
2
2
  import { sendJson } from "../mcp/transport/streamable-http.js";
3
- import { DEFAULT_GRAPH_LIMIT, MAX_GRAPH_LIMIT, loadGraph, parseSince } from "./graph.js";
3
+ import { loadGraph, parseSince } from "./graph.js";
4
+ import { DEFAULT_GRAPH_LIMIT, MAX_GRAPH_LIMIT, SSE_HEARTBEAT_MS } from "./limits.js";
4
5
  import { loadRunDetail } from "./run-detail.js";
5
6
  export const VIEWER_API_PREFIX = "/admin/api/";
6
- export const SSE_HEARTBEAT_MS = 15_000;
7
7
  /** A stream whose unsent backlog exceeds this is ended; the client reconnects and resyncs. */
8
8
  export const SSE_MAX_BUFFERED_BYTES = 1024 * 1024;
9
9
  const RUN_ID = /^[A-Za-z0-9_-]{1,64}$/;
@@ -1,14 +1,17 @@
1
1
  /** The read model behind GET /admin/api/infra (docs/viewer-api.md): built once at startup, no cluster reads. */
2
- import { loadKubernetesJobConfig, loadProviderConfig } from "../config/providers.js";
2
+ import { loadKubernetesJobConfig, loadNativeSandboxConfig, loadProviderConfig } from "../config/providers.js";
3
+ import { NATIVE_RUN_COMPONENT_LABEL, NATIVE_RUN_SHA_LABEL, NATIVE_WARM_POOL_LABEL, NATIVE_WARM_TOKEN_LABEL, } from "../native-worker/kubernetes-isolation.js";
3
4
  import { RUN_COMPONENT_LABEL, RUN_MANAGED_BY_LABEL, RUN_SHA_CHARS, RUN_SHA_LABEL, } from "../providers/jobs/kubernetes-isolation.js";
4
5
  export function buildInfraInfo(env = process.env) {
5
6
  const raw = loadProviderConfig(env).jobs;
6
7
  const launcher = raw === "docker" || raw === "kubernetes" ? raw : "local";
8
+ const native = buildNativeInfo(env);
7
9
  if (launcher !== "kubernetes")
8
- return { launcher, kubernetes: null };
10
+ return { launcher, kubernetes: null, native };
9
11
  const k8s = loadKubernetesJobConfig(env);
10
12
  return {
11
13
  launcher,
14
+ native,
12
15
  kubernetes: {
13
16
  namespace: k8s.namespace,
14
17
  platform: k8s.platform,
@@ -21,3 +24,23 @@ export function buildInfraInfo(env = process.env) {
21
24
  },
22
25
  };
23
26
  }
27
+ /** Where sandbox-mode native agents run (NATIVE_SANDBOX_*); null when no sandbox launcher is configured. */
28
+ function buildNativeInfo(env) {
29
+ const config = loadNativeSandboxConfig(env);
30
+ if (!config)
31
+ return null;
32
+ return {
33
+ launcher: config.launcher,
34
+ warmPoolSize: config.warmPoolSize,
35
+ kubernetes: config.launcher === "kubernetes"
36
+ ? {
37
+ namespace: config.namespace,
38
+ runtimeClass: config.runtimeClassName ?? null,
39
+ runLabel: NATIVE_RUN_SHA_LABEL,
40
+ componentLabel: { ...NATIVE_RUN_COMPONENT_LABEL },
41
+ warmPoolLabel: { ...NATIVE_WARM_POOL_LABEL },
42
+ warmWorkerLabel: NATIVE_WARM_TOKEN_LABEL,
43
+ }
44
+ : null,
45
+ };
46
+ }
@@ -0,0 +1,4 @@
1
+ /** Viewer API constants shared by the server and the OpenAPI generator (no runtime imports). */
2
+ export declare const DEFAULT_GRAPH_LIMIT = 500;
3
+ export declare const MAX_GRAPH_LIMIT = 2000;
4
+ export declare const SSE_HEARTBEAT_MS = 15000;
@@ -0,0 +1,4 @@
1
+ /** Viewer API constants shared by the server and the OpenAPI generator (no runtime imports). */
2
+ export const DEFAULT_GRAPH_LIMIT = 500;
3
+ export const MAX_GRAPH_LIMIT = 2000;
4
+ export const SSE_HEARTBEAT_MS = 15_000;
@@ -0,0 +1,15 @@
1
+ export declare const OPENAPI_PATH: string;
2
+ type Json = Record<string, unknown>;
3
+ export interface ViewerRoute {
4
+ path: string;
5
+ operationId: string;
6
+ summary: string;
7
+ description: string;
8
+ parameters?: readonly Json[];
9
+ responses: Readonly<Record<string, Json>>;
10
+ }
11
+ export declare const VIEWER_ROUTES: readonly ViewerRoute[];
12
+ export declare function buildViewerOpenApi(version: string): Json;
13
+ export declare const HEADER = "# Generated by npm run build:viewer-schemas from src/viewer/api-schema.ts and src/viewer/openapi.ts. Do not edit.";
14
+ export declare function renderViewerOpenApi(version: string): string;
15
+ export {};
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Builds the published OpenAPI 3.1 document for the admin viewer API
3
+ * (docs/viewer-api.openapi.yml) from the zod schemas and a route table.
4
+ * Generated by `npm run build:viewer-schemas`; never edit the YAML by hand.
5
+ */
6
+ import { dirname, join } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { stringify } from "yaml";
9
+ import { zodToJsonSchema } from "zod-to-json-schema";
10
+ import { VIEWER_SCHEMAS } from "./api-schema.js";
11
+ import { DEFAULT_GRAPH_LIMIT, MAX_GRAPH_LIMIT, SSE_HEARTBEAT_MS } from "./limits.js";
12
+ export const OPENAPI_PATH = join(dirname(fileURLToPath(import.meta.url)), "../../docs/viewer-api.openapi.yml");
13
+ const AUTH_NOTE = "Requires a bearer token with the `admin:view` scope, held by a caller with the admin role.";
14
+ const ref = (name) => ({ $ref: `#/components/schemas/${name}` });
15
+ const errorBody = (codes, description) => {
16
+ const list = codes.split(", ");
17
+ return {
18
+ description,
19
+ content: {
20
+ "application/json": {
21
+ schema: { allOf: [ref("ViewerError"), { properties: { error: { enum: list } } }] },
22
+ },
23
+ },
24
+ "x-error-codes": list,
25
+ };
26
+ };
27
+ const wwwAuthenticate = { "WWW-Authenticate": { $ref: "#/components/headers/WWWAuthenticate" } };
28
+ export const VIEWER_ROUTES = [
29
+ {
30
+ path: "/admin/api/graph",
31
+ operationId: "getGraph",
32
+ summary: "Graph snapshot",
33
+ description: "Agents, runs, coding-run services and outcomes for a time window, as a graph.",
34
+ parameters: [
35
+ {
36
+ name: "since",
37
+ in: "query",
38
+ required: false,
39
+ description: "Window start: `15m`, `1h`, `6h`, `24h`, `7d`, or an ISO-8601 timestamp. Default `1h`.",
40
+ schema: { type: "string", default: "1h" },
41
+ },
42
+ {
43
+ name: "limit",
44
+ in: "query",
45
+ required: false,
46
+ description: `Maximum number of runs, 1 to ${MAX_GRAPH_LIMIT}. Default ${DEFAULT_GRAPH_LIMIT}.`,
47
+ schema: { type: "integer", minimum: 1, maximum: MAX_GRAPH_LIMIT, default: DEFAULT_GRAPH_LIMIT },
48
+ },
49
+ ],
50
+ responses: {
51
+ "200": {
52
+ description: "The graph snapshot.",
53
+ content: { "application/json": { schema: ref("graph-snapshot") } },
54
+ },
55
+ "400": errorBody("invalid_since, invalid_limit", "A query parameter is invalid."),
56
+ },
57
+ },
58
+ {
59
+ path: "/admin/api/runs/{id}",
60
+ operationId: "getRun",
61
+ summary: "Run detail",
62
+ description: "Full detail for one run, including final text.",
63
+ parameters: [{ name: "id", in: "path", required: true, description: "Run id.", schema: { type: "string" } }],
64
+ responses: {
65
+ "200": { description: "The run.", content: { "application/json": { schema: ref("run-detail") } } },
66
+ "404": errorBody("not_found", "No run with that id."),
67
+ },
68
+ },
69
+ {
70
+ path: "/admin/api/infra",
71
+ operationId: "getInfra",
72
+ summary: "Infrastructure info",
73
+ description: "Where and how this wardby deployment runs its workloads.",
74
+ responses: {
75
+ "200": { description: "Infrastructure info.", content: { "application/json": { schema: ref("infra-info") } } },
76
+ },
77
+ },
78
+ {
79
+ path: "/admin/api/events",
80
+ operationId: "getEvents",
81
+ summary: "Live event stream",
82
+ description: [
83
+ "A Server-Sent Events stream (`text/event-stream`) of live changes. Frames:",
84
+ "",
85
+ "- `retry: 3000`: suggested client reconnect delay in milliseconds.",
86
+ '- `event: hello`: sent first. Data is `{"connected": <bool>}`, whether the server\'s live-event connection is up.',
87
+ "- `event: run`, `event: service`, `event: outcome`: a run, coding-run service, or outcome changed. Each carries an `id:` line. Payloads match the `viewer-event` schema (see `x-event-schema`).",
88
+ '- `event: status`: the server\'s live-event connection changed. Data is `{"connected": <bool>}`.',
89
+ "- `event: resync`: the live-event connection is up (again). Events may have been missed: refetch the graph.",
90
+ `- \`: ping\`: comment sent every ${SSE_HEARTBEAT_MS / 1000} seconds to keep the connection open.`,
91
+ "",
92
+ "There is no replay. Open the event stream first, then load `/admin/api/graph` and apply events on top of it. Refetch the graph on every `resync` and after every reconnect rather than trying to resume.",
93
+ ].join("\n"),
94
+ responses: {
95
+ "200": {
96
+ description: "The event stream.",
97
+ content: { "text/event-stream": { schema: { type: "string" } } },
98
+ "x-event-schema": ref("viewer-event"),
99
+ },
100
+ },
101
+ },
102
+ ];
103
+ function componentSchemas() {
104
+ const schemas = {};
105
+ for (const [name, schema] of Object.entries(VIEWER_SCHEMAS)) {
106
+ const json = zodToJsonSchema(schema, { target: "jsonSchema2019-09", $refStrategy: "none" });
107
+ delete json.$schema;
108
+ schemas[name] = json;
109
+ }
110
+ schemas.ViewerError = {
111
+ type: "object",
112
+ required: ["error"],
113
+ properties: { error: { type: "string" } },
114
+ additionalProperties: false,
115
+ };
116
+ schemas.ViewerInternalError = {
117
+ type: "object",
118
+ required: ["error", "id"],
119
+ properties: { error: { type: "string", enum: ["internal_error"] }, id: { type: "string" } },
120
+ additionalProperties: false,
121
+ };
122
+ return schemas;
123
+ }
124
+ function operation(route) {
125
+ return {
126
+ operationId: route.operationId,
127
+ summary: route.summary,
128
+ description: `${route.description}\n\n${AUTH_NOTE}`,
129
+ security: [{ bearer: [] }],
130
+ ...(route.parameters ? { parameters: route.parameters } : {}),
131
+ responses: {
132
+ ...route.responses,
133
+ "401": { ...errorBody("invalid_token", "No valid bearer token."), headers: wwwAuthenticate },
134
+ "403": {
135
+ ...errorBody("invalid_token", "Token lacks the `admin:view` scope (the `WWW-Authenticate` header is present), or the caller lacks the admin role (no `WWW-Authenticate` header)."),
136
+ headers: wwwAuthenticate,
137
+ },
138
+ "405": {
139
+ ...errorBody("method_not_allowed", "Only GET is allowed."),
140
+ headers: { Allow: { description: "Allowed methods: GET.", schema: { type: "string", enum: ["GET"] } } },
141
+ },
142
+ default: {
143
+ description: "Unexpected server error (HTTP 500). `id` identifies the failure in the server log.",
144
+ content: { "application/json": { schema: ref("ViewerInternalError") } },
145
+ },
146
+ },
147
+ };
148
+ }
149
+ export function buildViewerOpenApi(version) {
150
+ const paths = {};
151
+ for (const route of VIEWER_ROUTES)
152
+ paths[route.path] = { get: operation(route) };
153
+ return {
154
+ openapi: "3.1.0",
155
+ info: {
156
+ title: "wardby admin viewer API",
157
+ version,
158
+ description: "Read-only admin API behind the wardby viewer: graph, run detail, infrastructure info and a live event stream. Response objects may gain new fields in later releases; clients should ignore unknown fields. See docs/viewer-api.md for the prose contract.",
159
+ },
160
+ servers: [{ url: "https://{host}", variables: { host: { default: "wardby.example.com" } } }],
161
+ paths,
162
+ components: {
163
+ securitySchemes: { bearer: { type: "http", scheme: "bearer" } },
164
+ headers: { WWWAuthenticate: { description: "Bearer challenge.", schema: { type: "string" } } },
165
+ schemas: componentSchemas(),
166
+ },
167
+ };
168
+ }
169
+ export const HEADER = "# Generated by npm run build:viewer-schemas from src/viewer/api-schema.ts and src/viewer/openapi.ts. Do not edit.";
170
+ export function renderViewerOpenApi(version) {
171
+ return `${HEADER}\n${stringify(buildViewerOpenApi(version), { lineWidth: 0, aliasDuplicateObjects: false })}`;
172
+ }
package/docs/README.md CHANGED
@@ -18,6 +18,11 @@
18
18
  - [Architecture knowledge bundles](knowledge.md) covers `docs/knowledge/`: the
19
19
  concept format, how coding runs and reviewers use it, `wardby knowledge check`,
20
20
  and the scheduled architecture agent.
21
+ - [Native sandbox](native-sandbox.md) (0.5.4+) runs a native agent's turn loop and user
22
+ tools in a single-use, credential-free container behind a native gateway.
23
+ - [Secrets and tools](tool-secrets.md) covers readable and brokered secrets
24
+ (brokered secrets require 0.6.0+):
25
+ attaching secrets to tools, `set_secret_broker`, placements, and errors.
21
26
  - [Coding-worker isolation](coding-worker-isolation.md) documents the threat
22
27
  model and enforced worker boundary.
23
28
  - [Bring-your-own worker images](coding-worker-byo-images.md) explains how to
@@ -29,6 +34,8 @@
29
34
  the catalog, per-agent permission, variables, and errors.
30
35
  - [Jira agents](jira-agents.md) connects wardby to Jira Cloud with a service
31
36
  account and webhook, and links agents to projects.
37
+ - [Send workflow updates to Slack](slack-notifications.md) (0.6.0+) links a Slack
38
+ channel to a Jira project or an agent to follow cards from pickup to merge.
32
39
  - [Observability](observability.md) covers Prometheus metrics, Grafana, cloud
33
40
  collectors, retention, and production ownership.
34
41
  - [Release verification](release-verification.md) lists the automated and live
@@ -336,7 +336,9 @@ toolchain, build your own image on Wardby's driver base image and point the
336
336
  agent at it with `workerImageRef`, a digest-pinned reference (a mutable tag is
337
337
  rejected). Setting it needs the `agents:admin` scope and the admin role. The
338
338
  Dockerfile shape, the driver image, and what Wardby does and does not verify are
339
- in [Bring-your-own worker images](coding-worker-byo-images.md).
339
+ in [Bring-your-own worker images](coding-worker-byo-images.md). For a Claude
340
+ Code agent, build the image on the release's tool runner image instead; see
341
+ [Codex and Claude Code](coding-worker-byo-images.md#codex-and-claude-code).
340
342
 
341
343
  ```json
342
344
  {
@@ -423,14 +425,61 @@ the lead's `maxDelegationsPerRun` (1 to 20) with `create_agent` or
423
425
  - Wardby adds a **Related pull requests** section to each pull request the
424
426
  builders open, listing the others with links, states (open, draft, merged,
425
427
  closed) and the originating issue. With a Jira issue, the list covers every
426
- pull request recorded for that issue in any run. Open ones are numbered as a
428
+ pull request recorded for that issue in any run. When no pull request in the
429
+ set carries a `mergeOrder` (see below), open ones are numbered as a
427
430
  **Suggested merge order** — the order the lead delegated in, not a
428
- guarantee; merged and closed ones are listed separately as context. A pull
429
- request lists the ones opened before it as soon as it is opened; when the
430
- lead run finishes, and whenever a later run pushes to one of them, every
431
- open one is rewritten with the full list. Text you add inside the section is
432
- replaced; the rest of the description is not touched. Only pull requests the
433
- App opened and that are still open are edited.
431
+ guarantee. When any pull request in the set carries one (open, merged or
432
+ closed), the open ones that have a `mergeOrder` are numbered under
433
+ **Merge order (set by the delegating agent; equal steps can merge in either
434
+ order)** and labelled "step k of n" (equal values share a step), and any
435
+ open pull request without one is listed after under **Not ordered**. If
436
+ only merged or closed pull requests carry a `mergeOrder`, the open ones are
437
+ all listed under **Not ordered**, with no **Merge order** heading. Steps
438
+ are counted over the whole set, merged and closed pull requests included,
439
+ so a label stays the same as earlier steps merge. Merged and closed pull
440
+ requests are always listed separately as context, with their step label
441
+ when they have one. A pull request lists the ones opened before it as
442
+ soon as it is opened; when the lead run finishes, and whenever a later run
443
+ pushes to one of them, every open one is rewritten with the full list. Text
444
+ you add inside the section is replaced; the rest of the description is not
445
+ touched. Only pull requests the App opened and that are still open are
446
+ edited. With Wardby 0.6.0 or later, a reviewer linked to one of these repositories
447
+ also holds its review of such a pull request until the lead run finishes,
448
+ however it ends, so every pull request of the request is open by the time
449
+ any of them is reviewed. When the lead finishes normally the section above
450
+ has been rewritten by then; when it is ended another way (for example,
451
+ cancelled), reviews start without that rewrite, and reviewers use
452
+ `repo_pr_read`'s `relatedPullRequests` either way — see
453
+ [Reviewing a pull request a delegated run
454
+ opened](code-review-agents.md#reviewing-a-pull-request-a-delegated-run-opened).
455
+ - Each `delegate_to_<name>` call to a coding sub-agent can carry a
456
+ `mergeOrder`: an integer from 1 to 99, where 1 merges first. Give a
457
+ repository that other repositories' changes depend on a lower number than
458
+ the ones that call it — for example a service `1`, the API in front of it
459
+ `2`, the client `3` — and give two changes the same number when there is no
460
+ order between them. Set it whenever one change spans several repositories
461
+ and the pull requests must land in a particular sequence; leave it unset
462
+ and the set keeps the delegation-order "Suggested merge order" above. A
463
+ native sub-agent has no pull request to order, so it ignores `mergeOrder`
464
+ and the tool result notes that it did. Each pull request shows the value
465
+ most recently set for it, by the run that opened it or a later
466
+ continuation of it: a `continuePriorRun` call that omits `mergeOrder`
467
+ keeps that value, and one that sets `mergeOrder` replaces it. A
468
+ bad value (not an integer, or outside 1-99) is refused as a tool error
469
+ rather than silently ignored.
470
+ - With Wardby 0.6.0 or later, once a set has more than one distinct
471
+ `mergeOrder`, each open or draft pull request Wardby opened in it also
472
+ gets a check run named exactly `wardby merge order`: `in_progress` while
473
+ an earlier step hasn't merged, `success` once every earlier step has
474
+ (or there is none), and `failure` if an earlier step was closed without
475
+ merging. Above the set's lowest step, a would-be `success` stays
476
+ `in_progress` ("waiting for the delegating run to finish") while the
477
+ delegating (lead) agent's run is still running — it may still add or
478
+ reorder steps. A coding run that continues one of the pull requests on
479
+ its own (a review fix round, an `@` mention) never holds it. Posting it never
480
+ blocks a merge by itself: add `wardby merge order` as a required status
481
+ check in branch protection to gate on it. See
482
+ [The wardby merge order check](../help/merge-order-check.md).
434
483
  - The section, and the follow-up hints below, list every pull request in the
435
484
  set by repository name and number. A request that spans repositories of
436
485
  different visibility can therefore show a private repository's name in a
@@ -73,10 +73,14 @@ credentials, still reaches only the proxy, and the proxy still owns the ledger.
73
73
 
74
74
  | `JOB_LAUNCHER` | Worker runs in | Isolation |
75
75
  | -------------- | -------------------------------- | ---------------------------------------------------- |
76
- | `local` | a child process on this host | development only, no isolation |
76
+ | `local` | nowhere: no coding launcher | native agents only; coding runs fail before starting |
77
77
  | `docker` | a container on a per-run network | the diagram above |
78
78
  | `kubernetes` | a pod in a namespace | per-run NetworkPolicy, attested pod, optional gVisor |
79
79
 
80
+ `local` is the default. It composes no coding launcher, so a coding run ends
81
+ with "Coding agents need a container executor"; set `docker` or `kubernetes`
82
+ to run coding agents.
83
+
80
84
  Under `kubernetes` the shape is the same with different nouns: the per-run
81
85
  Docker network becomes a NetworkPolicy, the keeper and worker share a pod
82
86
  instead of a volume, and the proxy is a Service rather than a container name.
@@ -88,3 +92,14 @@ or not anything enforces it. See
88
92
  [coding-worker-isolation.md](coding-worker-isolation.md) for the mechanics and
89
93
  the [Kubernetes deployment guide](../deploy/kind-coding/README.md) for the local
90
94
  and GKE Autopilot overlays.
95
+
96
+ ### Native agents in a sandbox
97
+
98
+ Native sandbox requires Wardby 0.5.4 or later.
99
+
100
+ Native agents run in the server process by default. A native agent set to
101
+ `nativeExecutionMode=sandbox` instead runs its turn loop and user tools in a
102
+ single-use credential-free container whose only path out is a separate native
103
+ gateway, enabled with `NATIVE_SANDBOX_LAUNCHER=docker` or `kubernetes` (a pod
104
+ per run, including on GKE Autopilot under gVisor; independent of
105
+ `JOB_LAUNCHER`). See [native-sandbox.md](native-sandbox.md).