@wardby/cli 0.7.0 → 0.8.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 (304) hide show
  1. package/.env.example +5 -5
  2. package/README.md +6 -1
  3. package/deploy/local/docker-compose.quickstart-coding.yml +6 -0
  4. package/dist/claude-coding-worker/driver.d.ts +12 -0
  5. package/dist/claude-coding-worker/driver.js +29 -7
  6. package/dist/claude-coding-worker/main.js +5 -1
  7. package/dist/claude-coding-worker/sdk.js +17 -1
  8. package/dist/claude-plugin/command.d.ts +61 -0
  9. package/dist/claude-plugin/command.js +376 -0
  10. package/dist/cli-help.d.ts +1 -1
  11. package/dist/cli-help.js +2 -1
  12. package/dist/cli.js +47 -3
  13. package/dist/coding/code-host.d.ts +16 -0
  14. package/dist/coding/code-host.js +60 -0
  15. package/dist/coding/mcp-token.d.ts +12 -0
  16. package/dist/coding/mcp-token.js +26 -0
  17. package/dist/coding/protocol.js +2 -0
  18. package/dist/coding/redact.js +6 -1
  19. package/dist/coding/transcript/recorder.d.ts +5 -4
  20. package/dist/coding/transcript/recorder.js +1 -1
  21. package/dist/coding-worker/debug-trace.d.ts +3 -1
  22. package/dist/coding-worker/debug-trace.js +4 -2
  23. package/dist/coding-worker/driver.js +8 -1
  24. package/dist/coding-worker/main.js +5 -1
  25. package/dist/coding-worker/mcp-config.d.ts +27 -0
  26. package/dist/coding-worker/mcp-config.js +32 -0
  27. package/dist/coding-worker/sdk.d.ts +36 -0
  28. package/dist/coding-worker/sdk.js +28 -1
  29. package/dist/coding-worker/types.d.ts +4 -0
  30. package/dist/config/mcp-call-limit.d.ts +8 -0
  31. package/dist/config/mcp-call-limit.js +18 -0
  32. package/dist/config/mcp-servers.d.ts +8 -0
  33. package/dist/config/mcp-servers.js +12 -0
  34. package/dist/config/test-simulators.d.ts +10 -0
  35. package/dist/config/test-simulators.js +28 -0
  36. package/dist/config/tool-timeout.d.ts +1 -0
  37. package/dist/config/tool-timeout.js +18 -0
  38. package/dist/core/coding-mcp.d.ts +36 -0
  39. package/dist/core/coding-mcp.js +253 -0
  40. package/dist/core/coding-repository.d.ts +46 -0
  41. package/dist/core/coding-repository.js +92 -0
  42. package/dist/core/delegation-slots.d.ts +27 -0
  43. package/dist/core/delegation-slots.js +44 -0
  44. package/dist/core/dispatch.d.ts +6 -2
  45. package/dist/core/dispatch.js +36 -11
  46. package/dist/core/error-code.js +1 -0
  47. package/dist/core/grants.d.ts +28 -3
  48. package/dist/core/grants.js +46 -4
  49. package/dist/core/host-events.js +7 -3
  50. package/dist/core/host-status.js +2 -2
  51. package/dist/core/issue-status.js +4 -3
  52. package/dist/core/mark-ready.d.ts +1 -1
  53. package/dist/core/mark-ready.js +1 -1
  54. package/dist/core/mcp-client/client.d.ts +47 -0
  55. package/dist/core/mcp-client/client.js +141 -0
  56. package/dist/core/mcp-client/jsonrpc.d.ts +15 -0
  57. package/dist/core/mcp-client/jsonrpc.js +54 -0
  58. package/dist/core/mcp-client/results.d.ts +13 -0
  59. package/dist/core/mcp-client/results.js +42 -0
  60. package/dist/core/mcp-servers.d.ts +90 -0
  61. package/dist/core/mcp-servers.js +230 -0
  62. package/dist/core/mcp-tools.d.ts +108 -0
  63. package/dist/core/mcp-tools.js +287 -0
  64. package/dist/core/merge-order-check.js +38 -19
  65. package/dist/core/notification-dispatcher.js +2 -1
  66. package/dist/core/related-pull-requests.js +26 -10
  67. package/dist/core/review-fix.js +2 -2
  68. package/dist/core/review-host-tools.js +3 -1
  69. package/dist/core/runner.d.ts +66 -16
  70. package/dist/core/runner.js +281 -73
  71. package/dist/core/secret-broker-config.d.ts +2 -0
  72. package/dist/core/secret-broker-config.js +1 -1
  73. package/dist/core/secret-guard.d.ts +5 -2
  74. package/dist/core/secret-guard.js +22 -7
  75. package/dist/core/secrets.d.ts +11 -1
  76. package/dist/core/secrets.js +27 -1
  77. package/dist/core/serializable-retry.d.ts +18 -0
  78. package/dist/core/serializable-retry.js +43 -0
  79. package/dist/core/tool-admin.d.ts +5 -1
  80. package/dist/core/tool-admin.js +7 -2
  81. package/dist/core/tool-names.d.ts +13 -0
  82. package/dist/core/tool-names.js +20 -0
  83. package/dist/core/webhooks.d.ts +4 -0
  84. package/dist/core/webhooks.js +68 -49
  85. package/dist/core/workflow-run-events.js +2 -1
  86. package/dist/generated/prisma/browser.d.ts +31 -0
  87. package/dist/generated/prisma/client.d.ts +31 -0
  88. package/dist/generated/prisma/commonInputTypes.d.ts +50 -50
  89. package/dist/generated/prisma/internal/class.d.ts +66 -0
  90. package/dist/generated/prisma/internal/class.js +4 -4
  91. package/dist/generated/prisma/internal/prismaNamespace.d.ts +530 -1
  92. package/dist/generated/prisma/internal/prismaNamespace.js +75 -2
  93. package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +79 -0
  94. package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +75 -2
  95. package/dist/generated/prisma/models/Agent.d.ts +271 -0
  96. package/dist/generated/prisma/models/AgentMcpServer.d.ts +1412 -0
  97. package/dist/generated/prisma/models/AgentMcpServer.js +1 -0
  98. package/dist/generated/prisma/models/AgentRepository.d.ts +40 -1
  99. package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
  100. package/dist/generated/prisma/models/CodingAgentProfile.d.ts +0 -7
  101. package/dist/generated/prisma/models/CodingProxySession.d.ts +119 -2
  102. package/dist/generated/prisma/models/CodingRun.d.ts +76 -1
  103. package/dist/generated/prisma/models/HostProvider.d.ts +2176 -0
  104. package/dist/generated/prisma/models/HostProvider.js +1 -0
  105. package/dist/generated/prisma/models/HostProviderCredential.d.ts +1285 -0
  106. package/dist/generated/prisma/models/HostProviderCredential.js +1 -0
  107. package/dist/generated/prisma/models/HostProviderOperation.d.ts +1470 -0
  108. package/dist/generated/prisma/models/HostProviderOperation.js +1 -0
  109. package/dist/generated/prisma/models/HostProviderTrustedAccount.d.ts +1145 -0
  110. package/dist/generated/prisma/models/HostProviderTrustedAccount.js +1 -0
  111. package/dist/generated/prisma/models/McpServer.d.ts +1500 -0
  112. package/dist/generated/prisma/models/McpServer.js +1 -0
  113. package/dist/generated/prisma/models/NativeGatewayCall.d.ts +39 -1
  114. package/dist/generated/prisma/models/Principal.d.ts +167 -0
  115. package/dist/generated/prisma/models/ResourceGrant.d.ts +1 -1
  116. package/dist/generated/prisma/models/Secret.d.ts +387 -0
  117. package/dist/generated/prisma/models/Tool.d.ts +223 -1
  118. package/dist/generated/prisma/models.d.ts +6 -0
  119. package/dist/help/search.js +12 -3
  120. package/dist/help-index.json +719 -47
  121. package/dist/import/create.js +16 -1
  122. package/dist/import/neutral-schema.d.ts +1 -0
  123. package/dist/import/neutral-schema.js +2 -0
  124. package/dist/mcp/auth/grants-cli.d.ts +6 -4
  125. package/dist/mcp/auth/grants-cli.js +42 -3
  126. package/dist/mcp/auth/resource-server.d.ts +3 -1
  127. package/dist/mcp/auth/resource-server.js +17 -2
  128. package/dist/mcp/context.d.ts +3 -0
  129. package/dist/mcp/index.js +11 -0
  130. package/dist/mcp/tools/agents.js +100 -15
  131. package/dist/mcp/tools/grants.js +66 -28
  132. package/dist/mcp/tools/host-providers.d.ts +2 -0
  133. package/dist/mcp/tools/host-providers.js +215 -0
  134. package/dist/mcp/tools/mcp-servers.d.ts +26 -0
  135. package/dist/mcp/tools/mcp-servers.js +481 -0
  136. package/dist/mcp/tools/repositories.js +50 -10
  137. package/dist/mcp/tools/runs.js +178 -18
  138. package/dist/mcp/tools/secret-elicitation.d.ts +2 -0
  139. package/dist/mcp/tools/secret-elicitation.js +25 -2
  140. package/dist/mcp/tools/secrets.js +38 -4
  141. package/dist/mcp/tools/tools.d.ts +6 -4
  142. package/dist/mcp/tools/tools.js +40 -8
  143. package/dist/mcp/tools/trigger.js +28 -6
  144. package/dist/mcp/transport/http-limits.d.ts +2 -0
  145. package/dist/mcp/transport/http-limits.js +6 -2
  146. package/dist/mcp/webhooks/ingress.js +10 -0
  147. package/dist/native-worker/gateway-server.d.ts +14 -0
  148. package/dist/native-worker/gateway-server.js +28 -7
  149. package/dist/native-worker/gateway.d.ts +2 -0
  150. package/dist/native-worker/gateway.js +5 -1
  151. package/dist/native-worker/http-server.d.ts +4 -0
  152. package/dist/native-worker/http-server.js +51 -0
  153. package/dist/native-worker/ledger.d.ts +6 -2
  154. package/dist/native-worker/ledger.js +5 -4
  155. package/dist/native-worker/protocol.d.ts +1 -0
  156. package/dist/native-worker/protocol.js +4 -1
  157. package/dist/providers/coding-proxy/capability-hash.d.ts +2 -0
  158. package/dist/providers/coding-proxy/capability-hash.js +5 -0
  159. package/dist/providers/coding-proxy/mcp-route.d.ts +34 -0
  160. package/dist/providers/coding-proxy/mcp-route.js +166 -0
  161. package/dist/providers/coding-proxy/memory-ledger.d.ts +2 -0
  162. package/dist/providers/coding-proxy/memory-ledger.js +15 -0
  163. package/dist/providers/coding-proxy/prisma-ledger.d.ts +1 -0
  164. package/dist/providers/coding-proxy/prisma-ledger.js +30 -2
  165. package/dist/providers/coding-proxy/proxy.d.ts +7 -1
  166. package/dist/providers/coding-proxy/proxy.js +134 -34
  167. package/dist/providers/coding-proxy/runtime.d.ts +6 -0
  168. package/dist/providers/coding-proxy/runtime.js +32 -1
  169. package/dist/providers/coding-proxy/server.d.ts +3 -0
  170. package/dist/providers/coding-proxy/server.js +10 -0
  171. package/dist/providers/coding-proxy/types.d.ts +13 -0
  172. package/dist/providers/executor/composition.js +5 -0
  173. package/dist/providers/executor/container.d.ts +33 -1
  174. package/dist/providers/executor/container.js +76 -7
  175. package/dist/providers/host-tools/invoke.d.ts +37 -0
  176. package/dist/providers/host-tools/invoke.js +117 -0
  177. package/dist/providers/host-tools/operations.d.ts +65 -0
  178. package/dist/providers/host-tools/operations.js +149 -0
  179. package/dist/providers/host-tools/registry.d.ts +79 -0
  180. package/dist/providers/host-tools/registry.js +362 -0
  181. package/dist/providers/host-tools/request-guard.d.ts +17 -0
  182. package/dist/providers/host-tools/request-guard.js +99 -0
  183. package/dist/providers/host-tools/self-test.d.ts +64 -0
  184. package/dist/providers/host-tools/self-test.js +142 -0
  185. package/dist/providers/jobs/docker-isolation.d.ts +2 -2
  186. package/dist/providers/jobs/docker-isolation.js +30 -8
  187. package/dist/providers/jobs/docker.d.ts +8 -0
  188. package/dist/providers/jobs/docker.js +33 -9
  189. package/dist/providers/jobs/kubernetes-isolation.d.ts +3 -1
  190. package/dist/providers/jobs/kubernetes-isolation.js +15 -2
  191. package/dist/providers/jobs/kubernetes.d.ts +5 -0
  192. package/dist/providers/jobs/kubernetes.js +6 -1
  193. package/dist/providers/jobs/types.d.ts +6 -0
  194. package/dist/providers/review-host/types.d.ts +6 -4
  195. package/dist/providers/review-host/types.js +1 -1
  196. package/dist/providers/vcs/git.d.ts +6 -2
  197. package/dist/providers/vcs/git.js +15 -4
  198. package/dist/providers/vcs/github.d.ts +2 -71
  199. package/dist/providers/vcs/github.js +8 -11
  200. package/dist/providers/vcs/index.d.ts +1 -1
  201. package/dist/providers/vcs/index.js +1 -1
  202. package/dist/providers/vcs/remote.d.ts +4 -0
  203. package/dist/providers/vcs/remote.js +7 -1
  204. package/dist/providers/vcs/routing.d.ts +12 -6
  205. package/dist/providers/vcs/routing.js +21 -6
  206. package/dist/providers/vcs/types.d.ts +71 -3
  207. package/dist/quickstart/index.d.ts +5 -0
  208. package/dist/quickstart/index.js +21 -0
  209. package/dist/quickstart-images.json +1 -1
  210. package/dist/sandbox/eval-core.d.ts +12 -2
  211. package/dist/sandbox/eval-core.js +20 -4
  212. package/dist/sandbox/host-functions.d.ts +4 -0
  213. package/dist/sandbox/host-functions.js +7 -2
  214. package/dist/sandbox/limits.d.ts +4 -1
  215. package/dist/sandbox/limits.js +4 -1
  216. package/dist/sandbox/run-in-sandbox.d.ts +6 -0
  217. package/dist/sandbox/run-in-sandbox.js +14 -2
  218. package/dist/sandbox/safe-fetch.d.ts +2 -0
  219. package/dist/sandbox/safe-fetch.js +1 -1
  220. package/dist/sandbox/secret-broker.d.ts +1 -0
  221. package/dist/sandbox/secret-broker.js +1 -1
  222. package/dist/sandbox/tool-timeout.d.ts +32 -0
  223. package/dist/sandbox/tool-timeout.js +52 -0
  224. package/dist/sandbox/user-tool.d.ts +8 -1
  225. package/dist/sandbox/user-tool.js +9 -3
  226. package/dist/viewer/graph.js +2 -1
  227. package/dist/wardby-bin.js +5 -0
  228. package/docs/README.md +11 -1
  229. package/docs/agent-recipes.md +37 -4
  230. package/docs/architecture-runtime.md +1 -1
  231. package/docs/claude-code-plugin.md +164 -0
  232. package/docs/code-review-agents.md +6 -0
  233. package/docs/coding-agent-setup.md +77 -1
  234. package/docs/coding-worker-byo-images.md +4 -2
  235. package/docs/coding-worker-isolation.md +78 -7
  236. package/docs/debugging-agent-runs.md +242 -0
  237. package/docs/getting-started-gke.md +5 -4
  238. package/docs/getting-started-identity-provider.md +43 -37
  239. package/docs/getting-started.md +8 -0
  240. package/docs/host-providers.md +294 -0
  241. package/docs/mcp-servers.md +254 -0
  242. package/docs/native-sandbox.md +25 -9
  243. package/docs/security-deployment.md +110 -31
  244. package/docs/tool-secrets.md +3 -0
  245. package/docs/viewer-api.md +6 -0
  246. package/docs/viewer-api.openapi.yml +1 -1
  247. package/help/admin-viewer.md +4 -0
  248. package/help/agent-recipes.md +33 -2
  249. package/help/brokered-secrets.md +3 -0
  250. package/help/build-claude-code-image.md +1 -1
  251. package/help/claude-code-run-pane.md +40 -0
  252. package/help/errors/coding-mcp-pins-unavailable.md +35 -0
  253. package/help/errors/database-auth-invalid.md +1 -1
  254. package/help/errors/host-provider-error.md +40 -0
  255. package/help/errors/host-tool-failed.md +36 -0
  256. package/help/errors/mcp-call-limit.md +22 -0
  257. package/help/errors/mcp-call-timeout.md +22 -0
  258. package/help/errors/mcp-server-auth-failed.md +22 -0
  259. package/help/errors/mcp-server-credentials-unavailable.md +45 -0
  260. package/help/errors/mcp-server-error.md +28 -0
  261. package/help/errors/mcp-server-unreachable.md +22 -0
  262. package/help/errors/mcp-servers-off.md +21 -0
  263. package/help/errors/mcp-tool-not-allowed.md +26 -0
  264. package/help/errors/mcp-tool-removed.md +22 -0
  265. package/help/errors/mcp-unavailable.md +25 -0
  266. package/help/errors/native-sandbox-capacity.md +1 -1
  267. package/help/errors/native-sandbox-deadline-exceeded.md +1 -1
  268. package/help/errors/native-sandbox-docker-failed.md +1 -1
  269. package/help/errors/native-sandbox-gateway-error.md +1 -1
  270. package/help/errors/native-sandbox-gateway-unavailable.md +1 -1
  271. package/help/errors/native-sandbox-image-not-pinned.md +1 -1
  272. package/help/errors/native-sandbox-isolation-mismatch.md +1 -1
  273. package/help/errors/native-sandbox-network-unenforced.md +1 -1
  274. package/help/errors/native-sandbox-requires-catalog.md +1 -1
  275. package/help/errors/native-sandbox-unavailable.md +1 -1
  276. package/help/errors/native-sandbox-warm-delivery-failed.md +1 -1
  277. package/help/errors/native-sandbox-worker-exited.md +1 -1
  278. package/help/errors/native-sandbox-worker-lost.md +1 -1
  279. package/help/errors/native-sandbox-worker-unready.md +1 -1
  280. package/help/errors/repository-not-listed.md +36 -0
  281. package/help/errors/repository-required.md +36 -0
  282. package/help/errors/tool-timeout.md +38 -0
  283. package/help/host-providers.md +40 -0
  284. package/help/identity-and-access.md +4 -1
  285. package/help/mcp-servers.md +73 -0
  286. package/help/mcp.md +7 -2
  287. package/help/native-capabilities.md +27 -1
  288. package/help/native-sandbox.md +1 -1
  289. package/help/operating-agents.md +16 -0
  290. package/help/related-pull-requests.md +7 -3
  291. package/help/repo-instructions-and-skills.md +3 -1
  292. package/help/resume-runs-locally.md +3 -0
  293. package/help/stop-run.md +1 -1
  294. package/help/troubleshooting/coding-workers.md +9 -1
  295. package/help/troubleshooting/debugging-agent-runs.md +29 -0
  296. package/package.json +2 -1
  297. package/prisma/migrations/20261102000000_host_providers/migration.sql +56 -0
  298. package/prisma/migrations/20261104000000_coding_agent_repository_list/migration.sql +5 -0
  299. package/prisma/migrations/20261106000000_tool_timeout/migration.sql +4 -0
  300. package/prisma/migrations/20261107000000_mcp_servers/migration.sql +33 -0
  301. package/prisma/migrations/20261108000000_coding_mcp/migration.sql +5 -0
  302. package/prisma/migrations/20261109000000_task_run_index/migration.sql +3 -0
  303. package/prisma/schema.prisma +159 -14
  304. package/scripts/git-askpass.sh +1 -1
@@ -0,0 +1,164 @@
1
+ # Claude Code plugin: the wardby runs pane
2
+
3
+ From Wardby 0.8.0, the `wardby-runs` Claude Code plugin shows your wardby agent
4
+ runs in a pane beside the chat. It lists runs grouped by pull request, shows a
5
+ run's request, outcomes, services, errors and final answer, and can continue a
6
+ finished Claude Code run in your own terminal.
7
+
8
+ The plugin lives in this repository under `plugins/claude-code/`, and the
9
+ repository is its marketplace (`.claude-plugin/marketplace.json`). It talks only
10
+ to the wardby MCP server your Claude Code session already has, through
11
+ `list_runs`, `list_agents`, `get_run` and `get_run_transcript`, so it shows
12
+ exactly what those tools show you and needs no token of its own.
13
+
14
+ ## Install
15
+
16
+ ### With the wardby CLI
17
+
18
+ ```sh
19
+ npx @wardby/cli@latest claude-plugin install
20
+ ```
21
+
22
+ This installs the plugin from `wardby/wardby` and offers to allow the pane's
23
+ read-only tools for auto mode (see [Permissions](#permissions)). Options:
24
+
25
+ | Option | What it does |
26
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
27
+ | `--server-url <url>` | Registers the wardby MCP server at this `https` URL (for example `https://wardby.example.com/mcp`) when Claude Code has none named `wardby` |
28
+ | `--server-name <name>` | The MCP server the pane uses, as `/mcp` lists it (default `wardby`); the allow rules it adds follow the name, for example `mcp__wardby-prod__list_runs` |
29
+ | `--marketplace <src>` | Installs from another marketplace: an operator's own repository (`your-org/claude-plugins`) or a local folder |
30
+ | `--allow-tools` | Allows the pane's read-only tools without asking; `--no-allow-tools` leaves permission rules alone |
31
+ | `--fullscreen` | Also switches Claude Code's terminal to its fullscreen view (see [Terminal](#in-the-terminal)); it applies to every session |
32
+ | `--yes` | Answers yes to every question |
33
+
34
+ `wardby quickstart` offers the same install once it has connected Claude Code
35
+ (`--claude-plugin` installs it without asking, `--no-claude-plugin` skips it),
36
+ and `wardby doctor` lists the plugin, the MCP server and the allow rules
37
+ alongside its other checks, without failing when the optional pane is missing.
38
+
39
+ `wardby claude-plugin status` reports whether the plugin, the MCP server and
40
+ the allow rules are in place. `wardby claude-plugin uninstall` removes the
41
+ plugin and only the settings install added: the rules it added and the
42
+ fullscreen view if it switched it on. It leaves the MCP server in place.
43
+
44
+ The CLI writes to the settings file of the Claude Code it finds:
45
+ `$CLAUDE_CONFIG_DIR/settings.json`, else `~/.claude/settings.json`. It refuses a
46
+ settings file that isn't valid JSON instead of overwriting it.
47
+
48
+ ### In Claude Code
49
+
50
+ At the prompt of a terminal session:
51
+
52
+ ```
53
+ /plugin install wardby-runs --marketplace wardby/wardby
54
+ ```
55
+
56
+ In the desktop app, where `/plugin` doesn't run: click **+** next to the prompt
57
+ box, then **Plugins**, **Add marketplace** with `wardby/wardby`, then **Add
58
+ plugin**. A plugin installed from a terminal at user scope also loads in the
59
+ desktop app's local Code sessions that read the same Claude Code configuration.
60
+
61
+ Open the pane with `/wardby-runs`; `/wardby-runs close` closes it and
62
+ `/wardby-runs clear` clears its filters.
63
+
64
+ ### The MCP server
65
+
66
+ The pane needs an MCP server named `wardby` in Claude Code. `wardby quickstart`
67
+ registers one; for a deployed instance, add it with `--server-url` above or:
68
+
69
+ ```sh
70
+ claude mcp add --transport http --scope user wardby https://wardby.example.com/mcp
71
+ ```
72
+
73
+ then sign in with `/mcp`. Another name works too: set the plugin's **wardby MCP
74
+ server** option to it. A server added through the Claude apps' **Connectors**
75
+ settings is not a Claude Code MCP server and the pane doesn't use it. With another
76
+ name, install with `--server-name <name>` so the allow rules match it, and the
77
+ pane's own hints name it too.
78
+
79
+ ## Permissions
80
+
81
+ The pane reads only, with the caller's own access:
82
+
83
+ | Pane feature | MCP tool | Scope | What you see |
84
+ | -------------------- | -------------------- | ------------- | ------------------------------------------------------------------------------ |
85
+ | Run list | `list_runs` | `agents:read` | All runs of agents you own, and the runs you started on agents shared with you |
86
+ | Agent names, budgets | `list_agents` | `agents:read` | Agents you can see (the pane asks for `summary: true`) |
87
+ | Run detail | `get_run` | `agents:read` | Runs you started, or of agents you own |
88
+ | Continue locally | `get_run_transcript` | `agents:read` | Same as `get_run` |
89
+
90
+ Under Claude Code's auto mode, a plugin's MCP calls go through the same safety
91
+ check as any other, and calls the pane makes on its own timer are refused
92
+ unless allowed. Allow these in `/permissions` (or let `wardby claude-plugin
93
+ install` add them): `mcp__wardby__list_runs`, `mcp__wardby__list_agents`,
94
+ `mcp__wardby__get_run` and `mcp__wardby__get_run_transcript`. The pane never
95
+ calls `stop_run` or any other tool that changes something. When a call is
96
+ refused, the pane says which rules to add.
97
+
98
+ Plugins are not sandboxed: they run as you. **Continue locally** runs
99
+ `npx @wardby/cli@latest resume - --print` in the folder you give it, passing the
100
+ transcript's download link on standard input; the link is never drawn, stored
101
+ or logged. The import writes only under `~/.wardby/` and the new worktree.
102
+
103
+ ## Using the pane
104
+
105
+ - **Ledger** (desktop): runs grouped by pull request (or Jira issue), each group
106
+ one row with its state and total cost, folded once every run in it finished.
107
+ A pull request with one run is one line. Runs that touch no pull request are
108
+ under **Other**. Each line names its step (opened, review, fix 1, …), with
109
+ sub-agent runs under their lead.
110
+ - **Strips** (desktop): one card per pull request, its steps drawn as a row of
111
+ dots; click a step's name to see it.
112
+ - **Filters**: show all, active, failed or finished runs, or type to match an
113
+ agent, status, trigger or task.
114
+ - **Run detail**: what started the run and what it produced, its request and
115
+ final answer (as markdown; **Show full text** for all of it), services,
116
+ errors, the run tree, and **Continue locally** for finished Claude Code runs
117
+ with `sessionResume` on (see [Resume Claude Code runs locally](coding-agent-setup.md#resume-a-run-locally)).
118
+
119
+ The pane refreshes every 10 seconds while a run is active and every 60 seconds
120
+ otherwise (the plugin's **pollSeconds** and **idleSeconds** options), asks only
121
+ for what changed since its last refresh, backs off when the server fails, and
122
+ polls only while it is open.
123
+
124
+ ### In the terminal
125
+
126
+ Claude Code's classic terminal view draws a plugin pane as a band above the
127
+ prompt and doesn't pass mouse clicks to plugins: use the keyboard (ctrl+x tab
128
+ focuses the pane, then `1`–`9` open a run, `r` refreshes, `b` goes back, `x` or
129
+ Escape closes). In the fullscreen view the pane is a side bar beside the chat
130
+ and takes clicks. Turn it on with `"tui": "fullscreen"` in your Claude Code
131
+ settings (or `--fullscreen` above, or `CLAUDE_CODE_NO_FLICKER=1`), then restart
132
+ Claude Code. The desktop app needs none of this.
133
+
134
+ ## Add it to your own marketplace
135
+
136
+ The plugin keeps everything it needs in `plugins/claude-code/` and has no
137
+ instance-specific values, so an operator can list it in their organization's
138
+ marketplace. Point an entry at this repository's subfolder, pinned to a
139
+ release:
140
+
141
+ ```json
142
+ {
143
+ "name": "wardby-runs",
144
+ "source": {
145
+ "source": "git-subdir",
146
+ "url": "wardby/wardby",
147
+ "path": "plugins/claude-code",
148
+ "ref": "v0.8.0"
149
+ }
150
+ }
151
+ ```
152
+
153
+ Preset its options for your users in managed settings under
154
+ `pluginConfigs["wardby-runs@<your marketplace>"].options` (for example the MCP
155
+ server's name), and ship the allow rules above in the same managed settings.
156
+ When managed settings set `allowManagedHooksOnly`, a plugin a user installs
157
+ loads no hooks: install it through managed settings instead.
158
+
159
+ ## Limits
160
+
161
+ - Plugins draw in the Claude Code terminal, the desktop app's Code tab and VS
162
+ Code; not in claude.ai/code, `claude -p`, the Agent SDK or WSL.
163
+ - The pane polls; there is no push.
164
+ - A run's live steps and a readable transcript are not shown yet.
@@ -574,6 +574,12 @@ requires more than owning the agent:
574
574
  - **A repository is the owner's binding.** Principals the agent is shared
575
575
  with (`grant_access`) can't link, unlink or change its repository, even at
576
576
  `write`.
577
+ - **A coding agent's extra repositories follow the same rules.** A
578
+ `link_repository` call with `access: "write"` and no triggers on a coding
579
+ agent adds a repository its runs may work in; it needs the same GitHub write
580
+ access or admin approval as the default repository. Unlinking it
581
+ refuses queued runs for that repository when they start, and a run already under way is refused at
582
+ its final push check (`repo_access`), so nothing is pushed.
577
583
 
578
584
  The authorization is stamped on the link (`authorizedVia`: `host_permission`,
579
585
  `admin`, or `grandfathered`) and **checked again every time it is used**: on
@@ -69,6 +69,81 @@ request currently targets, and the agent resolves any conflicts — see
69
69
  Over stdio, the local operator holds every role, so `repositoryAdminOverride`
70
70
  is the way to approve a repository there.
71
71
 
72
+ ## A coding agent's repositories
73
+
74
+ A coding agent works in one repository per run, chosen from its list:
75
+
76
+ - `codingProfile.repository` is the **default** repository.
77
+ - `link_repository` adds more. A link on a coding agent takes
78
+ `access: "write"`, no triggers, no `checkName` and an optional `baseRef`
79
+ (the base branch for runs in that repository; default: the profile's
80
+ `baseRef`). The repository must be on GitHub or a `local:` path. Linking the
81
+ default repository again is refused.
82
+ - `unlink_repository` removes one.
83
+
84
+ ```json
85
+ { "agentId": "<agent id>", "repository": "your-org/other-repo", "access": "write", "baseRef": "main" }
86
+ ```
87
+
88
+ Only the agent's owner (or an admin approving explicitly with `adminOverride`)
89
+ can add a repository, and the same authorization applies as for the default;
90
+ see [Repository authorization](#repository-authorization).
91
+
92
+ The repository is chosen when the run starts and never changes during it:
93
+
94
+ - `trigger_agent` takes an optional `repository`. Leave it out and the run uses
95
+ the default repository. Name one that is not on the list and the call is
96
+ refused with `repository_not_listed`. Only the agent's owner can pass
97
+ `repository`, unless `codingProfile.allowWebhookTaskOverride` is on; anyone
98
+ else is refused with a 403.
99
+ - A webhook body can carry `wardbyRepository` the same way (not `repository`,
100
+ which forwarded payloads already use). A refused value is a 400
101
+ `{ "error": "invalid_repository" }`. A webhook can carry `wardbyRepository`
102
+ only when `codingProfile.allowWebhookTaskOverride` is on, whoever created
103
+ the webhook. With the flag off a well-formed value is refused with 403
104
+ `{ "error": "disabled" }`, before it is compared with the list; a malformed
105
+ one (not a string, empty, or over 300 characters) is a 400 either way.
106
+ - A lead's `delegate_to_<name>` call takes `repository`. When the sub-agent has
107
+ more than its default repository the call must name one, unless
108
+ `continuePriorRun` is given: a follow-up works in the repository of the run
109
+ it continues. Without a choice the call is refused with
110
+ `repository_required`.
111
+
112
+ Everything else about the agent is shared across its repositories: toolchain,
113
+ worker image, services, system prompt, budget, protected paths and the package
114
+ allowlist. If two repositories need different ones, use two agents.
115
+
116
+ Being on the list lets a run work in a repository; it starts nothing there.
117
+ Reviews, mention follow-ups, fix rounds and mark-ready route by repository and
118
+ trigger, so a pull request opened in a linked repository gets none of them by
119
+ itself. For follow-ups, link the lead and the reviewer on each listed GitHub
120
+ repository with the triggers they need.
121
+
122
+ An agent with no repository links works only in its default repository.
123
+ Changing an agent's `kind` is refused while it has write links without
124
+ triggers; unlink them first.
125
+
126
+ Every write link without triggers on a coding agent is on its list, whenever it
127
+ was made. An agent converted from native to coding can hold such links from its
128
+ native configuration: run `list_repositories` on converted agents and unlink any
129
+ repository their runs should not work in.
130
+
131
+ For the refusals, see [Repository required](../help/errors/repository-required.md)
132
+ and [Repository not on the agent's list](../help/errors/repository-not-listed.md).
133
+
134
+ ## See what a run was asked to do
135
+
136
+ `get_run` returns a coding run's `request`: the task it received from
137
+ `trigger_agent`, a webhook or a lead, or the agent's default task. It leaves out
138
+ the agent's standing instructions. On a delegated run, this shows what the lead
139
+ told the coding agent, so you can tell a vague task from a run that missed a
140
+ clear one.
141
+
142
+ The value is masked when it's read: the values of the agent's attached secrets
143
+ and token-shaped values are replaced. If the agent's secrets can't be read,
144
+ `get_run` returns `requestUnavailable: true` instead of the text. Runs from
145
+ before this field have no `request`.
146
+
72
147
  ## Local repositories
73
148
 
74
149
  A coding agent (or a review agent) can work on a git repository on the same
@@ -313,7 +388,8 @@ agents.
313
388
  - **`false`.** Bare mode is off. Claude Code loads `CLAUDE.md` and skills
314
389
  itself, through its native Skill tool, instead of reading them from the
315
390
  system prompt. Repository settings, hooks, MCP configuration, agents, and
316
- commands are still never loaded in either mode; native loading also locks
391
+ commands are still never loaded in either mode (the only MCP tools a coding
392
+ run has are those of [attached MCP servers](mcp-servers.md#coding-agents)); native loading also locks
317
393
  Claude Code's own hooks to wardby's managed set.
318
394
 
319
395
  If the worker can't write the native-mode context to disk for a run, that
@@ -95,8 +95,10 @@ the exact command.
95
95
  On a local quickstart install with the Docker launcher, `workerImageRef` can be
96
96
  the local image ID (`docker image inspect --format '{{.Id}}' <your-tag>`).
97
97
  Otherwise, build it, push it to your own registry, and note the resulting digest —
98
- `docker inspect --format '{{index .RepoDigests 0}}' <your-tag>` after a push,
99
- or read it straight from `docker buildx build --push`'s output.
98
+ `docker inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' <your-tag>`
99
+ after a push lists one digest per registry the image is in: take the one in
100
+ the registry your cluster pulls from, not simply the first. Or read it straight
101
+ from `docker buildx build --push`'s output.
100
102
 
101
103
  ## Pointing an agent at it
102
104
 
@@ -143,7 +143,8 @@ deeply to process is refused with `request_nesting_too_deep`.
143
143
 
144
144
  - **Anthropic Messages** (`parseAnthropicRequest`): a fixed set of keys,
145
145
  text/`tool_use`/`tool_result`/thinking blocks, exactly the two Wardby tool
146
- names, the reviewed beta values, the thinking mode the run's model catalog
146
+ names plus the run's own MCP tool names (see
147
+ [Remote MCP tools](#remote-mcp-tools)), the reviewed beta values, the thinking mode the run's model catalog
147
148
  entry names, and only effort levels that entry lists in `efforts` (top-level,
148
149
  or on an effort-only system message for models that change effort per turn).
149
150
  - **OpenAI Responses** (`parseOpenAiRequest`), built from what the pinned
@@ -157,8 +158,15 @@ deeply to process is refused with `request_nesting_too_deep`.
157
158
  `previous_response_id`, `conversation` and `metadata`, is refused with
158
159
  `openai_request_key_not_allowed:<key>`.
159
160
  - Tools: `function` and `custom` definitions, and `namespace` groups of
160
- them, either in `tools` or in Codex's `additional_tools` input item. Every
161
- other tool type, including all hosted tools (`web_search`, `mcp`,
161
+ them, either in `tools` or in Codex's `additional_tools` input item. A
162
+ `tool_search` tool is accepted only in the top-level `tools`, only with
163
+ `execution: "client"` (Codex runs the search over its own tools) and only
164
+ with `type`, `execution`, `description` and `parameters`; a
165
+ server-executed search is refused with
166
+ `openai_tool_not_allowed:tool_search`. Each tool list holds at most 512
167
+ tools, and a request at most 512 distinct tools in all; a definition
168
+ repeated in replayed tool search results counts once. Every other tool
169
+ type, including all hosted tools (`web_search`, `mcp`,
162
170
  `code_interpreter`, `image_generation`, `file_search`, `local_shell`, and
163
171
  so on), is refused with `openai_tool_not_allowed:<type>`. Tool names are
164
172
  checked for shape (`[A-Za-z0-9_-]{1,128}`) but not against a fixed list:
@@ -169,10 +177,17 @@ deeply to process is refused with `request_nesting_too_deep`.
169
177
  - Input items: `message` (`input_text`/`input_image` for user, developer
170
178
  and system; `output_text` for assistant), `reasoning`, `function_call`,
171
179
  `function_call_output`, `custom_tool_call`, `custom_tool_call_output`,
172
- `agent_message` and `additional_tools`, each with only the keys Codex
173
- sends. Anything else (`input_file`, `input_audio`, `item_reference`,
174
- replayed hosted-tool calls, `compaction`, `local_shell_call`) is refused
175
- with `openai_input_not_allowed:<type>`. An `input_image` must be an inline
180
+ `agent_message`, `additional_tools`, `tool_search_call` and
181
+ `tool_search_output`, each with only the keys Codex sends. The two tool
182
+ search items must say `execution: "client"`. A `tool_search_call` may
183
+ carry only a string `query` and a positive integer `limit` as its
184
+ arguments. Every tool a `tool_search_output` brings into the conversation
185
+ passes the same checks as a top-level tool, except another `tool_search`;
186
+ a `function` there may also carry `defer_loading: true`, which Codex sets
187
+ on the tools it loads through tool search, and nowhere else. Anything
188
+ else (`input_file`, `input_audio`, `item_reference`, replayed hosted-tool
189
+ calls, `compaction`, `local_shell_call`) is refused with
190
+ `openai_input_not_allowed:<type>`. An `input_image` must be an inline
176
191
  `data:image/{png,jpeg,gif,webp};base64,` URL, as Codex's `view_image`
177
192
  produces; a remote URL or a `file_id` is refused with
178
193
  `openai_remote_input_not_allowed`.
@@ -218,6 +233,62 @@ rather than silently widening what reaches OpenAI. Upgrading the pinned
218
233
  then widen `parseOpenAiRequest` only for what that review accepts, and
219
234
  document it in the list above.
220
235
 
236
+ ### Remote MCP tools
237
+
238
+ A coding agent can have [remote MCP server](mcp-servers.md#coding-agents) tools
239
+ attached. The worker still reaches only the proxy:
240
+
241
+ 1. When a run has MCP tools, the control plane mints a per-run MCP token
242
+ (`rmt_` plus 32 random bytes, base64url). Only its SHA-256 hash is stored
243
+ with the run's proxy session; the token reaches the worker only as
244
+ `WARDBY_MCP_TOKEN`, and is never logged. It is valid only on the proxy's
245
+ `/mcp` route, and only while the session is active and before its deadline.
246
+ It is not the run capability, and it is not accepted by the model routes.
247
+ 2. The worker (Claude Code or Codex, over HTTP) calls `POST /mcp` on the proxy
248
+ with `Authorization: Bearer <token>`. The proxy checks the token and
249
+ forwards the request to the native gateway's `/coding-mcp` route
250
+ (`WARDBY_MCP_GATEWAY_URL`). The proxy never sees an MCP server's URL or
251
+ secrets. Without `WARDBY_MCP_GATEWAY_URL`, `/mcp` answers `503`
252
+ `mcp_unavailable`. A bad or expired token gets a `401` without a
253
+ `WWW-Authenticate` header, so a client doesn't start OAuth discovery.
254
+ 3. The gateway checks the token again (the proxy is not trusted), checks the
255
+ live attachment on every call, counts the call against the run's limit
256
+ (`WARDBY_MCP_MAX_CALLS_PER_RUN`, default 100; failed calls count), runs it,
257
+ and removes the server's secret values from the result before it leaves.
258
+ Logs for the route carry the method, status and session id, never bodies,
259
+ arguments, results or the token.
260
+
261
+ The proxy can reach the gateway's HTTP port. It holds no gateway credentials,
262
+ and each route authenticates separately. The Anthropic allowlist accepts the
263
+ run's own MCP tools as plain client tools named
264
+ `mcp__wardby_mcp__<server>__<tool>`, and only those the run pinned.
265
+
266
+ Where the token is exposed:
267
+
268
+ - **Claude Code.** The agent container receives the MCP configuration, its
269
+ bearer header included, on Claude Code's command line. That container runs no
270
+ model commands and shares no PID namespace with the tool runner, so commands
271
+ the model runs can't read it.
272
+ - **Codex.** Shell commands run in the same container as Codex, and can read
273
+ the token through `/proc`. For that reason a Codex agent may use only tools
274
+ the server marks `readOnlyHint: true`: Wardby refuses any other tool when you
275
+ attach, when a run loads its tools, and on every call. `readOnlyHint` is the
276
+ server's own claim, which Wardby can't verify, so the allowlist remains the
277
+ owner's control. A leaked token is limited to this run's allowed tools, the
278
+ call limit and the run's deadline.
279
+
280
+ A repository's own MCP configuration is never loaded. MCP tools need this
281
+ release's Claude worker image and a new Codex driver image; an older image
282
+ ignores the token and gets no MCP tools, and the run does not fail. Codex
283
+ models that use tool search get their MCP tools through `tool_search_output`
284
+ items; the proxy checks every tool in them like a top-level tool (see
285
+ [Model request allowlist](#model-request-allowlist)).
286
+
287
+ The read-only rule follows the provider a run was started with
288
+ (`CodingRun.provider`), at pin time and on every call, not the agent's current
289
+ profile. At attach, a coding agent counts as Codex unless its provider is
290
+ exactly `claude-code`, so an agent without a profile is held to the rule too.
291
+
221
292
  The proxy also binds a second listener, the **deny port** (`8788`,
222
293
  `CODING_PROXY_DENY_PORT`), which serves nothing: it accepts a connection,
223
294
  sends no bytes and closes it immediately
@@ -0,0 +1,242 @@
1
+ # Debugging an agent run
2
+
3
+ You can triage most agent problems yourself with the Wardby MCP and GitHub. Only
4
+ some failures need someone with server logs.
5
+
6
+ ## Start here
7
+
8
+ Find the run with `list_runs`, then read it with `get_run`. Then go to the section
9
+ for what you see.
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ start["Find the run: list_runs, then get_run"]
14
+ start --> none["No run started<br/>Check the repo links and triggers"]
15
+ start --> failed["Failed or refused<br/>Read failureCategory and the final text"]
16
+ start --> nopr["Succeeded, no PR<br/>Read outcome in codingResult"]
17
+ start --> missed["PR, but it missed<br/>Read the diff and the review"]
18
+ none --> nopull["See: No pull request appeared"]
19
+ nopr --> nopull
20
+ failed --> runfailed["See: The run failed"]
21
+ missed --> didntfix["See: The agent didn't fix what you expected"]
22
+ runfailed -- still unexplained --> operator["See: When you need an operator"]
23
+ nopr -- why it decided that --> transcript["See: Run transcripts"]
24
+ missed -- why it decided that --> transcript
25
+ ```
26
+
27
+ ## What you can use without server access
28
+
29
+ These all work through the Wardby MCP or GitHub, and you only see runs you have
30
+ access to.
31
+
32
+ | Tool | What it tells you |
33
+ | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
34
+ | `list_runs` (agent id, optional `status`) | An agent's recent runs: status, trigger, cost, turns, final text, and which run started it |
35
+ | `list_runs` without an agent id (from 0.8.0) | Your runs across every agent, each with `agentName`; no final text. `active: true` or `since` (ISO time) narrow it |
36
+ | `get_run` (run id) | One run in full, adding `failureCategory`, `diagnosticId`, `codingResult.outcome`, `request`, budget events and package refusals |
37
+ | `triggerInfo`, `outcomes`, `serviceReadiness` (from 0.8.0, on `get_run` and on `list_runs` without an agent id) | What started the run (the pull request and whether it was a review or a mention, the issue, the schedule or the lead), what it produced (pull requests opened, comments, checks) and each service's state, in the admin viewer API's shapes. Follow a pull request from the run that opened it through its review and fix rounds by matching one run's outcome to the next run's trigger |
38
+ | `get_agent`, `list_repositories`, `list_subagents` | How the agent is set up: prompt, model, budget, repo links and triggers, sub-agents |
39
+ | `search_help`, `get_help_article` | Help for an error code or failure category |
40
+ | `cost_report` | What runs cost, when spend is the question |
41
+ | `get_run_transcript` | The run's conversation, for Claude Code runs with `sessionResume` on |
42
+ | `stop_run` | Stops a run that's stuck |
43
+ | The PR, issue or Jira ticket | The diff, CI, the review, and the comment the run posted |
44
+
45
+ From Wardby 0.8.0, `list_agents` with `summary: true` returns each agent's id,
46
+ name, kind, model, coding provider, budget, owner and your access, without the
47
+ prompt and coding profile. Admins (the `admin` role, `admin:view` scope) can add
48
+ `all: true` to `list_agents` or `list_runs` to see every agent or run in the
49
+ deployment.
50
+
51
+ Admins can also use the [Wardby Viewer](viewer-api.md), a desktop app showing runs,
52
+ sub-agent trees, triggers and outcomes for every owner.
53
+
54
+ ## The run failed
55
+
56
+ Call `get_run` and read `status`, `error`, `failureCategory` and the final text. A
57
+ failed coding run's `error` looks like
58
+ `coding_failure_repo_access:coding_diag_…`: the middle part is the stage that
59
+ failed, and the ID is what an operator searches for.
60
+
61
+ | What you see | Likely cause | What to do |
62
+ | ------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------- |
63
+ | `repo_access` | The agent's owner lost access, or a repo link was removed | Check `list_repositories` and the owner's GitHub access |
64
+ | `repo_access_unavailable` | GitHub couldn't be reached reliably | Try again later |
65
+ | `workspace` | Often a workspace disk size above the server's limit | Lower `workspaceDiskMb`, or ask an operator to raise the limit |
66
+ | `executor` while running checks | The run may have run out of memory, among other causes | Reduce what the checks run; send the ID to an operator if it repeats |
67
+ | `merge_conflict` | The branch conflicts with its target | Read the `merge-conflict` help article |
68
+ | `service_unready` | A service the run needs, such as Postgres, didn't start | Check `.wardby/services.yaml` and the agent's `services` |
69
+ | `coding_turn_limit` | The run used all its turns | Raise `maxTurns` or narrow the task |
70
+ | `budgetEvents`, or `refused` | The run, run tree or budget group ran out of money | Raise the budget or check spend with `cost_report` |
71
+ | `packageRefusals` | A package isn't allowed or is too new | Add it to `packageAllowlist`, or wait out the release age limit |
72
+
73
+ For anything else, call `search_help` with the code or category. If that doesn't
74
+ explain it, see [When you need an operator](#when-you-need-an-operator).
75
+
76
+ **Prompt for Claude Code:**
77
+
78
+ ```
79
+ Wardby run <run id> failed. Why, and what can I do about it?
80
+ If it needs server logs, give me the diagnosticId.
81
+ ```
82
+
83
+ ## No pull request appeared
84
+
85
+ First find out whether a run started, using `list_runs` on the lead or router,
86
+ then on the coding agent.
87
+
88
+ | What `list_runs` shows | What it means | What to do |
89
+ | -------------------------------- | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
90
+ | No new run | The request never started anything: nothing is linked with that trigger, or the person doesn't have access | Check `list_repositories` on the router. Only one agent per repo can hold the `mention` trigger |
91
+ | Lead ran, no coding run under it | The lead chose not to delegate | Read the lead's final text, which should say why |
92
+ | Coding run failed or was refused | See [The run failed](#the-run-failed) | |
93
+ | Coding run succeeded, with no PR | Check `codingResult.outcome` in `get_run` | See below |
94
+
95
+ | `outcome` | Meaning |
96
+ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
97
+ | `no_changes` | The agent changed nothing. Its final text should say why: the request may be vague or already done. On Claude Code, the transcript shows how it decided |
98
+ | `budget_exhausted` | It ran out of money before finishing. Raise the budget or narrow the task |
99
+ | `branch_pushed` | A local repo: there's a branch, and no PR by design |
100
+
101
+ A mention can also get no reply at all. If a server sets
102
+ `WARDBY_MENTION_EXPLANATIONS=false`, a mention that starts nothing stays silent. An
103
+ operator can look for `mention ignored` or `mention declined` in the server log.
104
+
105
+ **Prompt for Claude Code:**
106
+
107
+ ```
108
+ I asked Wardby agent <agent name> to <request> in <your-org/your-repo>,
109
+ and no pull request appeared. Why?
110
+ ```
111
+
112
+ ## The agent didn't fix what you expected
113
+
114
+ The run succeeded, so most of what you need is on the PR and the run, with no
115
+ server logs involved. Check these in order:
116
+
117
+ 1. **The diff:** what actually changed.
118
+ 2. **The PR description:** the run's final text, including what it says it tested.
119
+ If it says the tests weren't run, trust CI.
120
+ 3. **The review:** whether your review check caught the miss.
121
+ 4. **The request:** whether the issue or mention said what you meant.
122
+ 5. **The task the agent received:** `request` in `get_run` (from Wardby 0.8.0). On a
123
+ delegated run, this shows what the lead told the coding agent.
124
+ 6. **The transcript:** why it decided that. This is only for Claude Code runs with
125
+ `sessionResume` on.
126
+
127
+ The usual causes are a vague request, a lead that dropped something when it rewrote
128
+ the request, a repo rule missing from `AGENTS.md`, or a fix aimed at the symptom it
129
+ was told about.
130
+
131
+ **To fix it,** comment on the PR, mentioning the App, with what's wrong. The
132
+ follow-up pushes to the same branch and PR, so you don't start again. If the same
133
+ miss keeps happening, add the rule to `AGENTS.md` so future runs follow it.
134
+
135
+ **Prompt for Claude Code:**
136
+
137
+ ```
138
+ PR <PR URL> from Wardby didn't do what I expected: <what you expected>.
139
+ Where did it go wrong? Draft a follow-up comment, but don't post it.
140
+ ```
141
+
142
+ ## Run transcripts
143
+
144
+ A transcript is the run's conversation: the messages, the tool calls and their
145
+ results, and the files and skills the agent loaded. You can get it yourself,
146
+ without server access, on Claude Code agents.
147
+
148
+ **To turn it on,** set `codingProfile.sessionResume` to `true` with `update_agent`.
149
+ It's off by default and has to be turned on for each agent. It only applies to runs
150
+ started afterward, so an earlier failure has no transcript. The server also needs a
151
+ blob store, set in the environment of the process that launches coding runs:
152
+ `BLOB_STORE` set to `local`, `gcs` or `s3`, plus `BLOB_STORE_LOCAL_DIR`,
153
+ `BLOB_STORE_GCS_BUCKET`, or `BLOB_STORE_S3_BUCKET` and `BLOB_STORE_S3_REGION`.
154
+ Without `BLOB_STORE`, no transcript is stored.
155
+
156
+ **To read one,** call `get_run_transcript` with the run ID. It returns a download
157
+ link that works for 10 minutes and a command. Run `npx @wardby/cli@latest resume -`
158
+ in a clone of the repo and paste the link, which also lets you continue the session
159
+ on your machine.
160
+
161
+ | Transcripts | |
162
+ | ------------------ | ------------------------------------------------------------------------------ |
163
+ | **Who can read** | Anyone who can read the run: the person who triggered it and the agent's owner |
164
+ | **Stored for** | Runs that finish, fail, or stop at their budget |
165
+ | **Not stored for** | Runs stopped with `stop_run` or ended by their timeout |
166
+ | **Removed** | Thinking blocks, the system prompt, the worker's environment, account details |
167
+ | **Redacted** | The agent's attached secrets and the run's own tokens |
168
+ | **Not available** | On Codex agents |
169
+
170
+ Redaction removes secret values, not other sensitive text, so a transcript includes
171
+ what the agent saw in the repo and in command output. Turn this on only for agents
172
+ whose runs you're comfortable sharing with everyone who can read them.
173
+
174
+ **Prompts for Claude Code:**
175
+
176
+ To turn it on:
177
+
178
+ ```
179
+ Turn on transcripts for Wardby agent <agent name>.
180
+ ```
181
+
182
+ To get one:
183
+
184
+ ```
185
+ Get me the transcript for Wardby run <run id>.
186
+ ```
187
+
188
+ See [Resume Claude Code runs locally](../help/resume-runs-locally.md) for more.
189
+
190
+ ## When you need an operator
191
+
192
+ Ask someone with server access when `get_run` and help don't explain a failure. The
193
+ specific reason for a failed coding run is written only to the server log, under
194
+ its `diagnosticId`.
195
+
196
+ **Send them:** the run ID, the `diagnosticId`, the repo, and what you expected to
197
+ happen.
198
+
199
+ **What the operator can do:**
200
+
201
+ 1. Search the control-plane log for the `diagnosticId`, which holds the real reason.
202
+ 2. If that isn't enough, turn on the
203
+ [debug trace](coding-worker-isolation.md#debug-trace) with `debugTraceMinutes`
204
+ and reproduce the failure.
205
+
206
+ The debug trace won't help you directly. Only admins can turn it on, it only covers
207
+ runs started afterward, and its output goes to the run's worker log, which you can't
208
+ read. It can include prompts and repo content, so it isn't exposed through MCP.
209
+
210
+ **What the trace holds:** the agent's whole stream, the commands it ran with their
211
+ output (Claude Code), final usage and duration, and stream failures in full.
212
+ Token-shaped values are redacted. It stops at 2 MiB per run by default.
213
+
214
+ **What MCP gives you:** the trace itself isn't available through MCP. You can only
215
+ turn it on or off with `update_agent` (admin role), see when it expires with
216
+ `get_agent` (`debugTraceUntil`), and see whether a run was traced with `get_run`
217
+ (`debugTrace: true`).
218
+
219
+ **Prompt to try first.** Paste this into any client connected to the Wardby MCP:
220
+
221
+ ```
222
+ Wardby run <run id> didn't do what I expected. What happened, and what can I do?
223
+ If it needs server logs, give me the diagnosticId.
224
+ ```
225
+
226
+ ## Known gaps
227
+
228
+ Two things can't be answered without server access yet.
229
+
230
+ | Gap | Why it matters | What you can do |
231
+ | --------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------- |
232
+ | The specific reason a coding run failed | You get the stage, such as `executor`, but not why | Send the `diagnosticId` to an operator |
233
+ | Why a mention got no reply | With explanations off, a declined mention leaves no reply and no run | Turn explanations on where that's acceptable: `true` is the default |
234
+
235
+ **To turn explanations on,** an operator removes
236
+ `WARDBY_MENTION_EXPLANATIONS=false` from the server's settings, or sets it to
237
+ `true`, then redeploys. Once on, the GitHub App replies to say why a mention started
238
+ nothing. On a public repo, anyone who can read that comment can see what is or isn't
239
+ linked there.
240
+
241
+ Run transcripts are limited to Claude Code runs with `sessionResume` on, so they
242
+ don't help on Codex agents.