@wardby/cli 0.8.0 → 0.9.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.
- package/deploy/local/docker-compose.quickstart-coding.yml +5 -0
- package/dist/claude-plugin/command.d.ts +4 -1
- package/dist/claude-plugin/command.js +7 -4
- package/dist/cli.js +24 -0
- package/dist/coding/transcript/recorder.js +2 -8
- package/dist/core/dispatch.js +3 -0
- package/dist/core/engine-native.d.ts +2 -0
- package/dist/core/engine-native.js +13 -0
- package/dist/core/error-code.js +1 -0
- package/dist/core/listen-address.d.ts +10 -0
- package/dist/core/listen-address.js +14 -0
- package/dist/core/power-idle.d.ts +8 -2
- package/dist/core/power-idle.js +17 -3
- package/dist/core/power.d.ts +5 -0
- package/dist/core/power.js +5 -0
- package/dist/core/retention-days.d.ts +5 -0
- package/dist/core/retention-days.js +14 -0
- package/dist/core/run-steps/config.d.ts +25 -0
- package/dist/core/run-steps/config.js +40 -0
- package/dist/core/run-steps/control-chars.d.ts +16 -0
- package/dist/core/run-steps/control-chars.js +26 -0
- package/dist/core/run-steps/detail.d.ts +32 -0
- package/dist/core/run-steps/detail.js +240 -0
- package/dist/core/run-steps/extract.d.ts +52 -0
- package/dist/core/run-steps/extract.js +467 -0
- package/dist/core/run-steps/ingress.d.ts +51 -0
- package/dist/core/run-steps/ingress.js +160 -0
- package/dist/core/run-steps/last-step.d.ts +15 -0
- package/dist/core/run-steps/last-step.js +35 -0
- package/dist/core/run-steps/native.d.ts +48 -0
- package/dist/core/run-steps/native.js +164 -0
- package/dist/core/run-steps/seen.d.ts +16 -0
- package/dist/core/run-steps/seen.js +35 -0
- package/dist/core/run-steps/summarize.d.ts +57 -0
- package/dist/core/run-steps/summarize.js +304 -0
- package/dist/core/run-steps/sweep.d.ts +21 -0
- package/dist/core/run-steps/sweep.js +41 -0
- package/dist/core/run-steps/types.d.ts +89 -0
- package/dist/core/run-steps/types.js +39 -0
- package/dist/core/run-steps/wire.d.ts +35 -0
- package/dist/core/run-steps/wire.js +47 -0
- package/dist/core/run-steps/writer.d.ts +49 -0
- package/dist/core/run-steps/writer.js +279 -0
- package/dist/core/runner.d.ts +4 -0
- package/dist/core/runner.js +15 -1
- package/dist/generated/prisma/browser.d.ts +8 -0
- package/dist/generated/prisma/client.d.ts +8 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +30 -0
- package/dist/generated/prisma/enums.d.ts +6 -0
- package/dist/generated/prisma/enums.js +5 -0
- package/dist/generated/prisma/internal/class.d.ts +11 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +103 -1
- package/dist/generated/prisma/internal/prismaNamespace.js +19 -1
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +19 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +19 -1
- package/dist/generated/prisma/models/Agent.d.ts +101 -1
- package/dist/generated/prisma/models/CodingProxySession.d.ts +41 -1
- package/dist/generated/prisma/models/Run.d.ts +503 -1
- package/dist/generated/prisma/models/RunStep.d.ts +1453 -0
- package/dist/generated/prisma/models/RunStep.js +1 -0
- package/dist/generated/prisma/models.d.ts +1 -0
- package/dist/help-index.json +102 -14
- package/dist/mcp/auth/access.d.ts +1 -0
- package/dist/mcp/context.d.ts +3 -0
- package/dist/mcp/index.js +10 -0
- package/dist/mcp/tools/agents.js +37 -7
- package/dist/mcp/tools/power.js +2 -2
- package/dist/mcp/tools/run-access.d.ts +7 -0
- package/dist/mcp/tools/run-access.js +14 -0
- package/dist/mcp/tools/run-steps.d.ts +16 -0
- package/dist/mcp/tools/run-steps.js +85 -0
- package/dist/mcp/tools/runs.js +10 -2
- package/dist/native-worker/gateway-server.d.ts +4 -1
- package/dist/native-worker/gateway-server.js +10 -2
- package/dist/native-worker/gateway.d.ts +3 -0
- package/dist/native-worker/gateway.js +8 -0
- package/dist/native-worker/http-server.d.ts +2 -4
- package/dist/native-worker/http-server.js +2 -8
- package/dist/providers/coding-proxy/memory-ledger.js +1 -0
- package/dist/providers/coding-proxy/prisma-ledger.js +9 -3
- package/dist/providers/coding-proxy/proxy.d.ts +26 -0
- package/dist/providers/coding-proxy/proxy.js +133 -42
- package/dist/providers/coding-proxy/run-step-forwarder.d.ts +42 -0
- package/dist/providers/coding-proxy/run-step-forwarder.js +206 -0
- package/dist/providers/coding-proxy/runtime.d.ts +7 -0
- package/dist/providers/coding-proxy/runtime.js +55 -3
- package/dist/providers/coding-proxy/types.d.ts +5 -0
- package/dist/providers/engine/types.d.ts +26 -0
- package/dist/providers/executor/container.d.ts +14 -0
- package/dist/providers/executor/container.js +8 -1
- package/dist/providers/jobs/kubernetes.d.ts +8 -0
- package/dist/providers/jobs/kubernetes.js +22 -4
- package/dist/quickstart-images.json +1 -1
- package/dist/serve.js +26 -18
- package/dist/viewer/api-schema.d.ts +66 -0
- package/dist/viewer/api-schema.js +31 -0
- package/dist/viewer/openapi.js +2 -1
- package/dist/viewer/run-detail.d.ts +2 -0
- package/dist/viewer/run-detail.js +26 -1
- package/docs/claude-code-plugin.md +57 -13
- package/docs/coding-agent-setup.md +17 -0
- package/docs/coding-worker-isolation.md +16 -0
- package/docs/debugging-agent-runs.md +112 -0
- package/docs/getting-started-gke.md +28 -7
- package/docs/mcp-servers.md +9 -0
- package/docs/native-sandbox.md +6 -0
- package/docs/security-deployment.md +51 -0
- package/docs/viewer-api.md +21 -12
- package/docs/viewer-api.openapi.yml +78 -2
- package/help/admin-viewer.md +1 -0
- package/help/claude-code-run-pane.md +27 -4
- package/help/deploy-gke.md +5 -0
- package/help/errors/coding-mcp-gateway-unavailable.md +46 -0
- package/help/low-power-mode.md +19 -8
- package/help/mcp.md +2 -0
- package/help/resume-runs-locally.md +4 -0
- package/help/run-steps.md +140 -0
- package/package.json +1 -1
- package/prisma/migrations/20261110000000_run_steps/migration.sql +26 -0
- package/prisma/migrations/20261111000000_run_steps_viewer_notify/migration.sql +59 -0
- package/prisma/migrations/20261112000000_run_steps_detail/migration.sql +9 -0
- package/prisma/schema.prisma +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,6 +11,7 @@ export type * from './models/Run.js';
|
|
|
11
11
|
export type * from './models/CodingAgentProfile.js';
|
|
12
12
|
export type * from './models/CodingRun.js';
|
|
13
13
|
export type * from './models/RunTranscript.js';
|
|
14
|
+
export type * from './models/RunStep.js';
|
|
14
15
|
export type * from './models/CodingService.js';
|
|
15
16
|
export type * from './models/CodingRunServiceStatus.js';
|
|
16
17
|
export type * from './models/RunBudgetEvent.js';
|
package/dist/help-index.json
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
],
|
|
22
22
|
"appliesTo": ">=0.4.0",
|
|
23
23
|
"sourcePath": "admin-viewer.md",
|
|
24
|
-
"markdown": "\n# Watch live runs with the admin viewer API\n\nThe admin viewer API is a read-only HTTP API for dashboards and desktop\nviewers. It shows every owner's runs across the deployment: sub-agent trees,\nwhat triggered each run, its outcomes (pull requests, comments, checks), and\ncoding-run services, with a live event stream.\n\nIt requires the Wardby `admin` role and the `admin:view` scope, which only the\n`admin` role grants. In delegating mode, define `admin:view` in your identity\nprovider and map it like `agents:admin`. See\n[Configure identity and privileged access](identity-and-access.md).\n\nFrom an MCP client, an admin gets the same deployment-wide listing with\n`list_agents` and `list_runs` and `all: true` (Wardby 0.8.0 and later; also\n`admin:view`). Without the role the call is refused.\n\nEndpoints, all `GET`:\n\n- `/admin/api/graph?since=1h&limit=500`: a snapshot of runs in a time window.\n- `/admin/api/runs/<id>`: one run in full, including its final text and error.\n- `/admin/api/infra`: how this deployment runs coding jobs (launcher, Kubernetes namespace, platform, run labels).\n- `/admin/api/events`: a Server-Sent Events stream of live changes.\n\nThe stream has no replay: open the event stream first, then load the graph,\nand refetch the graph on every `resync` event and after any reconnect. `hello`\nand `status` events report whether live events are flowing. Proxies and load balancers in front of Wardby\nmust allow long-lived responses and not buffer `text/event-stream`.\n\nA desktop viewer for macOS is included in the source tree (`apps/viewer`). Add\nyour server's canonical URI, sign in with an `admin` user in the browser, and it\nshows the live graph. Each GitHub release has an unsigned macOS build of the viewer attached (see the README for opening it past Gatekeeper). Its README covers setup, and what an external identity\nprovider client needs when the server runs in delegating mode.\n\n## Viewer sign-in with an external identity provider\n\nIn delegating mode, the viewer signs in through your identity provider's\npublic (native) client. That client must:\n\n- register the exact redirect URI `http://127.0.0.1:8585/callback`. The viewer\n always listens on port 8585, and some providers (Okta, for example) match a\n loopback redirect by its exact port, so a port-less or wildcard loopback\n entry may not match;\n- allow the `admin:view` scope for the Wardby resource;\n- enable the refresh-token grant and allow the `offline_access` scope. The\n viewer requests it so the provider returns a refresh token, and sign-in\n fails with \"server issued no refresh token\" without one.\n\nThe viewer prints its callback URL to stderr at startup. If sign-in reports\nthat it could not open the local callback listener on `127.0.0.1:8585`,\nanother program is using that port: close it and sign in again. In\nself-hosted mode the viewer registers itself, so there is no client to set up.\n\nFrom Wardby 0.6.0, admins can also sign in to a mobile app for the same read-only live view; see the help article `mobile-app`.\n\nThe Infrastructure tab shows the Kubernetes pods where your deployment runs\ncoding jobs, read-only. It uses your kubeconfig (switchable per server) and\nrequires a minimal read-only Kubernetes role. See the Infrastructure view\nsection of the [viewer README](../apps/viewer/README.md#infrastructure-view) for\nsetup. Its Map shows the request path (entry, protection layer such as Cloud\nArmor, routes), each NetworkPolicy with a plain-English summary, and on GKE a\nlink from each pod to the Google Cloud console. In low-power mode the sleeping\ncoding proxy and native gateway show as asleep (with when they last woke), and\na failed old replica next to a healthy one is greyed out rather than shown as a\nfailure. The run graph's zoom controls\ninclude **Fit width**, which fills the canvas with the graph's width.\n\nFrom Wardby 0.6.0 the API is also published as OpenAPI 3.1 (`docs/viewer-api.openapi.yml` in the package), an API contract you can feed to client generators such as `openapi-typescript`.\n\nFor parameters, status codes, frame formats and schemas, follow\n[`docs/viewer-api.md`](../docs/viewer-api.md).\n",
|
|
25
|
-
"plainText": "Watch live runs with the admin viewer API The admin viewer API is a read-only HTTP API for dashboards and desktop viewers. It shows every owner's runs across the deployment: sub-agent trees, what triggered each run, its outcomes (pull requests, comments, checks), and coding-run services, with a live event stream. It requires the Wardby admin role and the admin:view scope, which only the admin role grants. In delegating mode, define admin:view in your identity provider and map it like agents:admin. See Configure identity and privileged access. From an MCP client, an admin gets the same deployment-wide listing with listagents and listruns and all: true (Wardby 0.8.0 and later; also admin:view). Without the role the call is refused. Endpoints, all GET: /admin/api/graph?since=1h&limit=500: a snapshot of runs in a time window. /admin/api/runs/<id: one run in full, including its final text and error. /admin/api/infra: how this deployment runs coding jobs (launcher, Kubernetes namespace, platform, run labels). /admin/api/events: a Server-Sent Events stream of live changes. The stream has no replay: open the event stream first, then load the graph, and refetch the graph on every resync event and after any reconnect. hello and status events report whether live events are flowing. Proxies and load balancers in front of Wardby must allow long-lived responses and not buffer text/event-stream. A desktop viewer for macOS is included in the source tree (apps/viewer). Add your server's canonical URI, sign in with an admin user in the browser, and it shows the live graph. Each GitHub release has an unsigned macOS build of the viewer attached (see the README for opening it past Gatekeeper). Its README covers setup, and what an external identity provider client needs when the server runs in delegating mode. Viewer sign-in with an external identity provider In delegating mode, the viewer signs in through your identity provider's public (native) client. That client must: register the exact redirect URI http://127.0.0.1:8585/callback. The viewer always listens on port 8585, and some providers (Okta, for example) match a loopback redirect by its exact port, so a port-less or wildcard loopback entry may not match; allow the admin:view scope for the Wardby resource; enable the refresh-token grant and allow the offlineaccess scope. The viewer requests it so the provider returns a refresh token, and sign-in fails with \"server issued no refresh token\" without one. The viewer prints its callback URL to stderr at startup. If sign-in reports that it could not open the local callback listener on 127.0.0.1:8585, another program is using that port: close it and sign in again. In self-hosted mode the viewer registers itself, so there is no client to set up. From Wardby 0.6.0, admins can also sign in to a mobile app for the same read-only live view; see the help article mobile-app. The Infrastructure tab shows the Kubernetes pods where your deployment runs coding jobs, read-only. It uses your kubeconfig (switchable per server) and requires a minimal read-only Kubernetes role. See the Infrastructure view section of the viewer README for setup. Its Map shows the request path (entry, protection layer such as Cloud Armor, routes), each NetworkPolicy with a plain-English summary, and on GKE a link from each pod to the Google Cloud console. In low-power mode the sleeping coding proxy and native gateway show as asleep (with when they last woke), and a failed old replica next to a healthy one is greyed out rather than shown as a failure. The run graph's zoom controls include Fit width, which fills the canvas with the graph's width. From Wardby 0.6.0 the API is also published as OpenAPI 3.1 (docs/viewer-api.openapi.yml in the package), an API contract you can feed to client generators such as openapi-typescript. For parameters, status codes, frame formats and schemas, follow docs/viewer-api.md.",
|
|
24
|
+
"markdown": "\n# Watch live runs with the admin viewer API\n\nThe admin viewer API is a read-only HTTP API for dashboards and desktop\nviewers. It shows every owner's runs across the deployment: sub-agent trees,\nwhat triggered each run, its outcomes (pull requests, comments, checks), and\ncoding-run services, with a live event stream.\n\nIt requires the Wardby `admin` role and the `admin:view` scope, which only the\n`admin` role grants. In delegating mode, define `admin:view` in your identity\nprovider and map it like `agents:admin`. See\n[Configure identity and privileged access](identity-and-access.md).\n\nFrom an MCP client, an admin gets the same deployment-wide listing with\n`list_agents` and `list_runs` and `all: true` (Wardby 0.8.0 and later; also\n`admin:view`). Without the role the call is refused.\n\nEndpoints, all `GET`:\n\n- `/admin/api/graph?since=1h&limit=500`: a snapshot of runs in a time window.\n- `/admin/api/runs/<id>`: one run in full, including its final text and error.\n From Wardby 0.9.0 it also lists the run's newest 200 steps (see `run-steps`).\n- `/admin/api/infra`: how this deployment runs coding jobs (launcher, Kubernetes namespace, platform, run labels).\n- `/admin/api/events`: a Server-Sent Events stream of live changes.\n\nThe stream has no replay: open the event stream first, then load the graph,\nand refetch the graph on every `resync` event and after any reconnect. `hello`\nand `status` events report whether live events are flowing. Proxies and load balancers in front of Wardby\nmust allow long-lived responses and not buffer `text/event-stream`.\n\nA desktop viewer for macOS is included in the source tree (`apps/viewer`). Add\nyour server's canonical URI, sign in with an `admin` user in the browser, and it\nshows the live graph. Each GitHub release has an unsigned macOS build of the viewer attached (see the README for opening it past Gatekeeper). Its README covers setup, and what an external identity\nprovider client needs when the server runs in delegating mode.\n\n## Viewer sign-in with an external identity provider\n\nIn delegating mode, the viewer signs in through your identity provider's\npublic (native) client. That client must:\n\n- register the exact redirect URI `http://127.0.0.1:8585/callback`. The viewer\n always listens on port 8585, and some providers (Okta, for example) match a\n loopback redirect by its exact port, so a port-less or wildcard loopback\n entry may not match;\n- allow the `admin:view` scope for the Wardby resource;\n- enable the refresh-token grant and allow the `offline_access` scope. The\n viewer requests it so the provider returns a refresh token, and sign-in\n fails with \"server issued no refresh token\" without one.\n\nThe viewer prints its callback URL to stderr at startup. If sign-in reports\nthat it could not open the local callback listener on `127.0.0.1:8585`,\nanother program is using that port: close it and sign in again. In\nself-hosted mode the viewer registers itself, so there is no client to set up.\n\nFrom Wardby 0.6.0, admins can also sign in to a mobile app for the same read-only live view; see the help article `mobile-app`.\n\nThe Infrastructure tab shows the Kubernetes pods where your deployment runs\ncoding jobs, read-only. It uses your kubeconfig (switchable per server) and\nrequires a minimal read-only Kubernetes role. See the Infrastructure view\nsection of the [viewer README](../apps/viewer/README.md#infrastructure-view) for\nsetup. Its Map shows the request path (entry, protection layer such as Cloud\nArmor, routes), each NetworkPolicy with a plain-English summary, and on GKE a\nlink from each pod to the Google Cloud console. In low-power mode the sleeping\ncoding proxy and native gateway show as asleep (with when they last woke), and\na failed old replica next to a healthy one is greyed out rather than shown as a\nfailure. The run graph's zoom controls\ninclude **Fit width**, which fills the canvas with the graph's width.\n\nFrom Wardby 0.6.0 the API is also published as OpenAPI 3.1 (`docs/viewer-api.openapi.yml` in the package), an API contract you can feed to client generators such as `openapi-typescript`.\n\nFor parameters, status codes, frame formats and schemas, follow\n[`docs/viewer-api.md`](../docs/viewer-api.md).\n",
|
|
25
|
+
"plainText": "Watch live runs with the admin viewer API The admin viewer API is a read-only HTTP API for dashboards and desktop viewers. It shows every owner's runs across the deployment: sub-agent trees, what triggered each run, its outcomes (pull requests, comments, checks), and coding-run services, with a live event stream. It requires the Wardby admin role and the admin:view scope, which only the admin role grants. In delegating mode, define admin:view in your identity provider and map it like agents:admin. See Configure identity and privileged access. From an MCP client, an admin gets the same deployment-wide listing with listagents and listruns and all: true (Wardby 0.8.0 and later; also admin:view). Without the role the call is refused. Endpoints, all GET: /admin/api/graph?since=1h&limit=500: a snapshot of runs in a time window. /admin/api/runs/<id: one run in full, including its final text and error. From Wardby 0.9.0 it also lists the run's newest 200 steps (see run-steps). /admin/api/infra: how this deployment runs coding jobs (launcher, Kubernetes namespace, platform, run labels). /admin/api/events: a Server-Sent Events stream of live changes. The stream has no replay: open the event stream first, then load the graph, and refetch the graph on every resync event and after any reconnect. hello and status events report whether live events are flowing. Proxies and load balancers in front of Wardby must allow long-lived responses and not buffer text/event-stream. A desktop viewer for macOS is included in the source tree (apps/viewer). Add your server's canonical URI, sign in with an admin user in the browser, and it shows the live graph. Each GitHub release has an unsigned macOS build of the viewer attached (see the README for opening it past Gatekeeper). Its README covers setup, and what an external identity provider client needs when the server runs in delegating mode. Viewer sign-in with an external identity provider In delegating mode, the viewer signs in through your identity provider's public (native) client. That client must: register the exact redirect URI http://127.0.0.1:8585/callback. The viewer always listens on port 8585, and some providers (Okta, for example) match a loopback redirect by its exact port, so a port-less or wildcard loopback entry may not match; allow the admin:view scope for the Wardby resource; enable the refresh-token grant and allow the offlineaccess scope. The viewer requests it so the provider returns a refresh token, and sign-in fails with \"server issued no refresh token\" without one. The viewer prints its callback URL to stderr at startup. If sign-in reports that it could not open the local callback listener on 127.0.0.1:8585, another program is using that port: close it and sign in again. In self-hosted mode the viewer registers itself, so there is no client to set up. From Wardby 0.6.0, admins can also sign in to a mobile app for the same read-only live view; see the help article mobile-app. The Infrastructure tab shows the Kubernetes pods where your deployment runs coding jobs, read-only. It uses your kubeconfig (switchable per server) and requires a minimal read-only Kubernetes role. See the Infrastructure view section of the viewer README for setup. Its Map shows the request path (entry, protection layer such as Cloud Armor, routes), each NetworkPolicy with a plain-English summary, and on GKE a link from each pod to the Google Cloud console. In low-power mode the sleeping coding proxy and native gateway show as asleep (with when they last woke), and a failed old replica next to a healthy one is greyed out rather than shown as a failure. The run graph's zoom controls include Fit width, which fills the canvas with the graph's width. From Wardby 0.6.0 the API is also published as OpenAPI 3.1 (docs/viewer-api.openapi.yml in the package), an API contract you can feed to client generators such as openapi-typescript. For parameters, status codes, frame formats and schemas, follow docs/viewer-api.md.",
|
|
26
26
|
"headings": [
|
|
27
27
|
{
|
|
28
28
|
"level": 1,
|
|
@@ -469,20 +469,21 @@
|
|
|
469
469
|
"summary": "Install the wardby-runs Claude Code plugin to see your runs beside the chat, grouped by pull request, with run details and Continue locally.",
|
|
470
470
|
"audience": "operator",
|
|
471
471
|
"tags": [
|
|
472
|
+
"run steps",
|
|
473
|
+
"get_run_steps",
|
|
472
474
|
"claude code",
|
|
473
475
|
"plugin",
|
|
474
476
|
"wardby-runs",
|
|
475
477
|
"pane",
|
|
476
478
|
"claude-plugin",
|
|
477
479
|
"runs",
|
|
478
|
-
"desktop",
|
|
479
480
|
"auto mode",
|
|
480
481
|
"permissions"
|
|
481
482
|
],
|
|
482
483
|
"appliesTo": ">=0.8.0",
|
|
483
484
|
"sourcePath": "claude-code-run-pane.md",
|
|
484
|
-
"markdown": "\n# See your runs in Claude Code\n\nThe `wardby-runs` plugin opens a pane in Claude Code that lists your wardby\nruns, grouped by pull request, and shows each run's details. It uses the\n`wardby` MCP server your session already has and only reads.\n\nInstall it, and allow its read-only tools for auto mode, with:\n\n```sh\nnpx @wardby/cli@latest claude-plugin install\n```\n\nAdd `--server-url https://<your wardby host>/mcp` if Claude Code has no MCP\nserver named `wardby` yet. Or install it yourself with\n`/plugin install wardby-runs --marketplace wardby/wardby`. Then run\n`/wardby-runs`.\n\nIf the pane says auto mode refused a call, allow `mcp__wardby__list_runs`,\n`mcp__wardby__list_agents`, `mcp__wardby__get_run` and\n`
|
|
485
|
-
"plainText": "See your runs in Claude Code The wardby-runs plugin opens a pane in Claude Code that lists your wardby runs, grouped by pull request, and shows each run's details. It uses the wardby MCP server your session already has and only reads. Install it, and allow its read-only tools for auto mode, with: npx @wardby/cli@latest claude-plugin install Add --server-url https://<your wardby host/mcp if Claude Code has no MCP server named wardby yet. Or install it yourself with /plugin install wardby-runs --marketplace wardby/wardby. Then run /wardby-runs. If the pane says auto mode refused a call, allow mcpwardbylistruns, mcpwardbylistagents, mcpwardbygetrun and
|
|
485
|
+
"markdown": "\n# See your runs in Claude Code\n\nThe `wardby-runs` plugin opens a pane in Claude Code that lists your wardby\nruns, grouped by pull request, and shows each run's details. It uses the\n`wardby` MCP server your session already has and only reads.\n\nInstall it, and allow its read-only tools for auto mode, with:\n\n```sh\nnpx @wardby/cli@latest claude-plugin install\n```\n\nAdd `--server-url https://<your wardby host>/mcp` if Claude Code has no MCP\nserver named `wardby` yet. Or install it yourself with\n`/plugin install wardby-runs --marketplace wardby/wardby`. Then run\n`/wardby-runs`.\n\nIf the pane says auto mode refused a call, allow `mcp__wardby__list_runs`,\n`mcp__wardby__list_agents`, `mcp__wardby__get_run`,\n`mcp__wardby__get_run_transcript` and `mcp__wardby__get_run_steps` in\n`/permissions`. Run `wardby claude-plugin install` again to add a rule a newer\npane needs.\n\nIn the terminal, the pane takes clicks and sits beside the chat only in Claude\nCode's fullscreen view (`\"tui\": \"fullscreen\"`); otherwise use ctrl+x tab and the\nkeys it shows. The desktop app needs no setting.\n\n`wardby quickstart` offers the pane when it connects Claude Code, and\n`wardby doctor` and `wardby claude-plugin status` check the setup; `wardby claude-plugin\nuninstall` removes the plugin and the rules install added. To continue a run\nfrom the pane, see `resume-runs-locally`.\n\nA running run's detail shows its **Recent steps** (the last 8 tool calls and\nmessages: a ✓ or the exit code of a failed command, then the tool and its\ncommand; what the model said wraps to about two lines); a finished run's shows all its\n**Steps**, 200 at a time. In the list, a running or failed run shows its newest\nstep under its name. Against a server without `get_run_steps` the pane shows no\nsteps and checks again every few refreshes; with run steps off it says \"Steps\nare off on this server.\" See `run-steps`. Steps need Wardby 0.9.0 or later\non the server. From 0.9.0, a step with detail, or a longer message, has a ▸ at\nits right that opens it; in the terminal, `j`/`k` also move between such steps\nand `e` shows or hides one. An open command shows \"$ command\", its exit status\nand its output, without Codex's framing lines. Detail appears only for the\nagent's owner and the run's starter (and the stdio operator), on a server at\nthe detail level. An open detail shows its last 40 lines, with a count of the\nlines above them.\n\nEach section of a run's detail is a card, coloured by its kind (a bar on the\ndesktop, the border in the terminal). On the desktop each card, an error and an\nopen step's detail have a **Copy** button that copies the full text as the\nserver sent it, an open step's detail included in full; in the terminal, **Copy section** (`y`) copies the open\nstep's detail.\n\nThe full guide is [Claude Code plugin](../docs/claude-code-plugin.md).\n",
|
|
486
|
+
"plainText": "See your runs in Claude Code The wardby-runs plugin opens a pane in Claude Code that lists your wardby runs, grouped by pull request, and shows each run's details. It uses the wardby MCP server your session already has and only reads. Install it, and allow its read-only tools for auto mode, with: npx @wardby/cli@latest claude-plugin install Add --server-url https://<your wardby host/mcp if Claude Code has no MCP server named wardby yet. Or install it yourself with /plugin install wardby-runs --marketplace wardby/wardby. Then run /wardby-runs. If the pane says auto mode refused a call, allow mcpwardbylistruns, mcpwardbylistagents, mcpwardbygetrun, mcpwardbygetruntranscript and mcpwardbygetrunsteps in /permissions. Run wardby claude-plugin install again to add a rule a newer pane needs. In the terminal, the pane takes clicks and sits beside the chat only in Claude Code's fullscreen view (\"tui\": \"fullscreen\"); otherwise use ctrl+x tab and the keys it shows. The desktop app needs no setting. wardby quickstart offers the pane when it connects Claude Code, and wardby doctor and wardby claude-plugin status check the setup; wardby claude-plugin uninstall removes the plugin and the rules install added. To continue a run from the pane, see resume-runs-locally. A running run's detail shows its Recent steps (the last 8 tool calls and messages: a ✓ or the exit code of a failed command, then the tool and its command; what the model said wraps to about two lines); a finished run's shows all its Steps, 200 at a time. In the list, a running or failed run shows its newest step under its name. Against a server without getrunsteps the pane shows no steps and checks again every few refreshes; with run steps off it says \"Steps are off on this server.\" See run-steps. Steps need Wardby 0.9.0 or later on the server. From 0.9.0, a step with detail, or a longer message, has a ▸ at its right that opens it; in the terminal, j/k also move between such steps and e shows or hides one. An open command shows \"$ command\", its exit status and its output, without Codex's framing lines. Detail appears only for the agent's owner and the run's starter (and the stdio operator), on a server at the detail level. An open detail shows its last 40 lines, with a count of the lines above them. Each section of a run's detail is a card, coloured by its kind (a bar on the desktop, the border in the terminal). On the desktop each card, an error and an open step's detail have a Copy button that copies the full text as the server sent it, an open step's detail included in full; in the terminal, Copy section (y) copies the open step's detail. The full guide is Claude Code plugin.",
|
|
486
487
|
"headings": [
|
|
487
488
|
{
|
|
488
489
|
"level": 1,
|
|
@@ -861,8 +862,8 @@
|
|
|
861
862
|
],
|
|
862
863
|
"appliesTo": ">=0.2.1",
|
|
863
864
|
"sourcePath": "deploy-gke.md",
|
|
864
|
-
"markdown": "\n# Deploy Wardby on GKE Autopilot\n\nThe supported Google Cloud deployment creates a GKE Autopilot cluster, private\nCloud SQL for PostgreSQL, Artifact Registry, HTTPS Gateway, Google Secret\nManager synchronization, and isolated gVisor-backed coding-worker pods for\nCodex and Claude Code. It also applies namespace RBAC and default-deny network\npolicies.\n\nUse a dedicated billed project, a hostname you control, remote Terraform state,\nand a GitHub App installed only on repositories that agents need. Review\nTerraform's plan and set cloud budgets before applying it: the deployment\ncreates billable resources.\n\nThe deployment process is:\n\n1. Install `gcloud`, Terraform, Docker with `linux/amd64` support, `kubectl`,\n Helm, Node.js 24, and authenticate to the target project.\n2. Configure `deploy/gke/terraform.tfvars`, apply Terraform, and prepare the\n Gateway's address, certificate map, Cloud Armor policy, and DNS record. On\n a brand-new project, run `deploy/gke/bootstrap-database-iam.sh` once after\n `terraform apply`, so the migrator has its database grants before the\n first migration.\n3. Put first-time values in an untracked `.env.local`; `deploy/gke/up.sh`\n seeds Secret Manager without overwriting existing production values.\n Jira settings are optional there, all or none; see [Jira](jira.md).\n4. Run `WARDBY_HOSTNAME=wardby.example.com deploy/gke/up.sh`, then verify DNS,\n certificate issuance, and service health.\n Use `WARDBY_HOSTNAME`, not `HOSTNAME` (shells set that to the machine name);\n the script refuses local names such as `*.lan` or `*.local`, and asks you\n to confirm (or set `WARDBY_HOSTNAME_CHANGE=<new hostname>`) before moving\n a deployment to a different hostname.\n\nTo upgrade, re-run `deploy/gke/up.sh` from the new release. It applies the\nmigrations, then the database grants (`deploy/gke/database-grants.sql`), and\nonly then rolls out the new pods, so a release that adds tables or columns the\ncoding proxy uses (such as per-model usage for\n[cost attribution](cost-attribution.md)) needs no manual grants step. If the\ngrants fail, `up.sh` stops before the rollout with a non-zero exit;\n`deploy/gke/bootstrap-database-iam.sh --check` shows the refused statement\nwithout changing anything. See\n[Upgrading an existing deployment](../docs/getting-started-gke.md#upgrading-an-existing-deployment).\n\nThe Kubernetes launcher runs Codex and Claude Code coding workers; a Claude\nCode pod adds a tool-runner sidecar with its own image. Configure an identity\nprovider and GitHub App before allowing people to use the public endpoint.\n\nTo lower the idle cost of a lightly used deployment, see\n[Low-power mode](../docs/getting-started-gke.md#low-power-mode) (Wardby 0.6.0 and later).\n\n## Plan it with your assistant\n\nIf you are an assistant connected to Wardby over MCP and the user asked to plan\na GKE deployment, produce a written plan; do not create cloud resources. Read\n[Choose a deployment target](deployment-targets.md) first and confirm GKE is\nthe right target. Then ask for, one at a time, and record:\n\n1. The Google Cloud project (dedicated, with billing) and region, and who\n holds the IAM roles to apply Terraform.\n2. The public hostname and who controls its DNS.\n3. The identity provider for people signing in (see\n [Configure identity and privileged access](identity-and-access.md)).\n4. The GitHub App: which repositories it is installed on (see\n [Connect GitHub repositories](github.md)).\n5. Which coding providers the agents use (Codex, Claude Code or both), and\n which provider keys and worker images that needs.\n6. Where Terraform state lives, and the monthly cloud budget and alerts.\n7. Optional: Jira.\n\nThe plan lists those answers, the ordered steps above with the values filled\nin, the commands the user will run themselves, and the open questions. Point\nthe user to the full guide below for every step.\n\nFollow the complete, ordered guide at\n[`docs/getting-started-gke.md`](../docs/getting-started-gke.md). It includes\nthe precise IAM, DNS, bootstrap, upgrades, and teardown steps.\n",
|
|
865
|
-
"plainText": "Deploy Wardby on GKE Autopilot The supported Google Cloud deployment creates a GKE Autopilot cluster, private Cloud SQL for PostgreSQL, Artifact Registry, HTTPS Gateway, Google Secret Manager synchronization, and isolated gVisor-backed coding-worker pods for Codex and Claude Code. It also applies namespace RBAC and default-deny network policies. Use a dedicated billed project, a hostname you control, remote Terraform state, and a GitHub App installed only on repositories that agents need. Review Terraform's plan and set cloud budgets before applying it: the deployment creates billable resources. The deployment process is: Install gcloud, Terraform, Docker with linux/amd64 support, kubectl, Helm, Node.js 24, and authenticate to the target project. Configure deploy/gke/terraform.tfvars, apply Terraform, and prepare the Gateway's address, certificate map, Cloud Armor policy, and DNS record. On a brand-new project, run deploy/gke/bootstrap-database-iam.sh once after terraform apply, so the migrator has its database grants before the first migration. Put first-time values in an untracked .env.local; deploy/gke/up.sh seeds Secret Manager without overwriting existing production values. Jira settings are optional there, all or none; see Jira. Run WARDBYHOSTNAME=wardby.example.com deploy/gke/up.sh, then verify DNS, certificate issuance, and service health. Use WARDBYHOSTNAME, not HOSTNAME (shells set that to the machine name); the script refuses local names such as .lan or .local, and asks you to confirm (or set WARDBYHOSTNAMECHANGE=<new hostname) before moving a deployment to a different hostname. To upgrade, re-run deploy/gke/up.sh from the new release. It applies the migrations, then the database grants (deploy/gke/database-grants.sql), and only then rolls out the new pods, so a release that adds tables or columns the coding proxy uses (such as per-model usage for cost attribution) needs no manual grants step. If the grants fail, up.sh stops before the rollout with a non-zero exit; deploy/gke/bootstrap-database-iam.sh --check shows the refused statement without changing anything. See Upgrading an existing deployment. The Kubernetes launcher runs Codex and Claude Code coding workers; a Claude Code pod adds a tool-runner sidecar with its own image. Configure an identity provider and GitHub App before allowing people to use the public endpoint. To lower the idle cost of a lightly used deployment, see Low-power mode (Wardby 0.6.0 and later). Plan it with your assistant If you are an assistant connected to Wardby over MCP and the user asked to plan a GKE deployment, produce a written plan; do not create cloud resources. Read Choose a deployment target first and confirm GKE is the right target. Then ask for, one at a time, and record: The Google Cloud project (dedicated, with billing) and region, and who holds the IAM roles to apply Terraform. The public hostname and who controls its DNS. The identity provider for people signing in (see Configure identity and privileged access). The GitHub App: which repositories it is installed on (see Connect GitHub repositories). Which coding providers the agents use (Codex, Claude Code or both), and which provider keys and worker images that needs. Where Terraform state lives, and the monthly cloud budget and alerts. Optional: Jira. The plan lists those answers, the ordered steps above with the values filled in, the commands the user will run themselves, and the open questions. Point the user to the full guide below for every step. Follow the complete, ordered guide at docs/getting-started-gke.md. It includes the precise IAM, DNS, bootstrap, upgrades, and teardown steps.",
|
|
865
|
+
"markdown": "\n# Deploy Wardby on GKE Autopilot\n\nThe supported Google Cloud deployment creates a GKE Autopilot cluster, private\nCloud SQL for PostgreSQL, Artifact Registry, HTTPS Gateway, Google Secret\nManager synchronization, and isolated gVisor-backed coding-worker pods for\nCodex and Claude Code. It also applies namespace RBAC and default-deny network\npolicies.\n\nUse a dedicated billed project, a hostname you control, remote Terraform state,\nand a GitHub App installed only on repositories that agents need. Review\nTerraform's plan and set cloud budgets before applying it: the deployment\ncreates billable resources.\n\nThe deployment process is:\n\n1. Install `gcloud`, Terraform, Docker with `linux/amd64` support, `kubectl`,\n Helm, Node.js 24, and authenticate to the target project.\n2. Configure `deploy/gke/terraform.tfvars`, apply Terraform, and prepare the\n Gateway's address, certificate map, Cloud Armor policy, and DNS record. On\n a brand-new project, run `deploy/gke/bootstrap-database-iam.sh` once after\n `terraform apply`, so the migrator has its database grants before the\n first migration.\n3. Put first-time values in an untracked `.env.local`; `deploy/gke/up.sh`\n seeds Secret Manager without overwriting existing production values.\n Jira settings are optional there, all or none; see [Jira](jira.md).\n4. Run `WARDBY_HOSTNAME=wardby.example.com deploy/gke/up.sh`, then verify DNS,\n certificate issuance, and service health.\n Use `WARDBY_HOSTNAME`, not `HOSTNAME` (shells set that to the machine name);\n the script refuses local names such as `*.lan` or `*.local`, and asks you\n to confirm (or set `WARDBY_HOSTNAME_CHANGE=<new hostname>`) before moving\n a deployment to a different hostname.\n\nTo upgrade, re-run `deploy/gke/up.sh` from the new release. It applies the\nmigrations, then the database grants (`deploy/gke/database-grants.sql`), and\nonly then rolls out the new pods, so a release that adds tables or columns the\ncoding proxy uses (such as per-model usage for\n[cost attribution](cost-attribution.md)) needs no manual grants step. If the\ngrants fail, `up.sh` stops before the rollout with a non-zero exit;\n`deploy/gke/bootstrap-database-iam.sh --check` shows the refused statement\nwithout changing anything. See\n[Upgrading an existing deployment](../docs/getting-started-gke.md#upgrading-an-existing-deployment).\n\n`up.sh` works from its own one-cluster copy of the cluster's\nkubeconfig context, so switching contexts in another terminal mid-deploy can't\nsend a step to another cluster. Run one deploy of a cluster at a time: a second\nstops with `another operation (install/upgrade/rollback) is in progress`.\n\nThe Kubernetes launcher runs Codex and Claude Code coding workers; a Claude\nCode pod adds a tool-runner sidecar with its own image. Configure an identity\nprovider and GitHub App before allowing people to use the public endpoint.\n\nTo lower the idle cost of a lightly used deployment, see\n[Low-power mode](../docs/getting-started-gke.md#low-power-mode) (Wardby 0.6.0 and later).\n\n## Plan it with your assistant\n\nIf you are an assistant connected to Wardby over MCP and the user asked to plan\na GKE deployment, produce a written plan; do not create cloud resources. Read\n[Choose a deployment target](deployment-targets.md) first and confirm GKE is\nthe right target. Then ask for, one at a time, and record:\n\n1. The Google Cloud project (dedicated, with billing) and region, and who\n holds the IAM roles to apply Terraform.\n2. The public hostname and who controls its DNS.\n3. The identity provider for people signing in (see\n [Configure identity and privileged access](identity-and-access.md)).\n4. The GitHub App: which repositories it is installed on (see\n [Connect GitHub repositories](github.md)).\n5. Which coding providers the agents use (Codex, Claude Code or both), and\n which provider keys and worker images that needs.\n6. Where Terraform state lives, and the monthly cloud budget and alerts.\n7. Optional: Jira.\n\nThe plan lists those answers, the ordered steps above with the values filled\nin, the commands the user will run themselves, and the open questions. Point\nthe user to the full guide below for every step.\n\nFollow the complete, ordered guide at\n[`docs/getting-started-gke.md`](../docs/getting-started-gke.md). It includes\nthe precise IAM, DNS, bootstrap, upgrades, and teardown steps.\n",
|
|
866
|
+
"plainText": "Deploy Wardby on GKE Autopilot The supported Google Cloud deployment creates a GKE Autopilot cluster, private Cloud SQL for PostgreSQL, Artifact Registry, HTTPS Gateway, Google Secret Manager synchronization, and isolated gVisor-backed coding-worker pods for Codex and Claude Code. It also applies namespace RBAC and default-deny network policies. Use a dedicated billed project, a hostname you control, remote Terraform state, and a GitHub App installed only on repositories that agents need. Review Terraform's plan and set cloud budgets before applying it: the deployment creates billable resources. The deployment process is: Install gcloud, Terraform, Docker with linux/amd64 support, kubectl, Helm, Node.js 24, and authenticate to the target project. Configure deploy/gke/terraform.tfvars, apply Terraform, and prepare the Gateway's address, certificate map, Cloud Armor policy, and DNS record. On a brand-new project, run deploy/gke/bootstrap-database-iam.sh once after terraform apply, so the migrator has its database grants before the first migration. Put first-time values in an untracked .env.local; deploy/gke/up.sh seeds Secret Manager without overwriting existing production values. Jira settings are optional there, all or none; see Jira. Run WARDBYHOSTNAME=wardby.example.com deploy/gke/up.sh, then verify DNS, certificate issuance, and service health. Use WARDBYHOSTNAME, not HOSTNAME (shells set that to the machine name); the script refuses local names such as .lan or .local, and asks you to confirm (or set WARDBYHOSTNAMECHANGE=<new hostname) before moving a deployment to a different hostname. To upgrade, re-run deploy/gke/up.sh from the new release. It applies the migrations, then the database grants (deploy/gke/database-grants.sql), and only then rolls out the new pods, so a release that adds tables or columns the coding proxy uses (such as per-model usage for cost attribution) needs no manual grants step. If the grants fail, up.sh stops before the rollout with a non-zero exit; deploy/gke/bootstrap-database-iam.sh --check shows the refused statement without changing anything. See Upgrading an existing deployment. up.sh works from its own one-cluster copy of the cluster's kubeconfig context, so switching contexts in another terminal mid-deploy can't send a step to another cluster. Run one deploy of a cluster at a time: a second stops with another operation (install/upgrade/rollback) is in progress. The Kubernetes launcher runs Codex and Claude Code coding workers; a Claude Code pod adds a tool-runner sidecar with its own image. Configure an identity provider and GitHub App before allowing people to use the public endpoint. To lower the idle cost of a lightly used deployment, see Low-power mode (Wardby 0.6.0 and later). Plan it with your assistant If you are an assistant connected to Wardby over MCP and the user asked to plan a GKE deployment, produce a written plan; do not create cloud resources. Read Choose a deployment target first and confirm GKE is the right target. Then ask for, one at a time, and record: The Google Cloud project (dedicated, with billing) and region, and who holds the IAM roles to apply Terraform. The public hostname and who controls its DNS. The identity provider for people signing in (see Configure identity and privileged access). The GitHub App: which repositories it is installed on (see Connect GitHub repositories). Which coding providers the agents use (Codex, Claude Code or both), and which provider keys and worker images that needs. Where Terraform state lives, and the monthly cloud budget and alerts. Optional: Jira. The plan lists those answers, the ordered steps above with the values filled in, the commands the user will run themselves, and the open questions. Point the user to the full guide below for every step. Follow the complete, ordered guide at docs/getting-started-gke.md. It includes the precise IAM, DNS, bootstrap, upgrades, and teardown steps.",
|
|
866
867
|
"headings": [
|
|
867
868
|
{
|
|
868
869
|
"level": 1,
|
|
@@ -993,6 +994,41 @@
|
|
|
993
994
|
}
|
|
994
995
|
]
|
|
995
996
|
},
|
|
997
|
+
{
|
|
998
|
+
"id": "errors/coding-mcp-gateway-unavailable",
|
|
999
|
+
"title": "A coding run failed before launch because the native gateway did not wake",
|
|
1000
|
+
"summary": "In low-power mode, the run failed with coding_failure_mcp_gateway_unavailable because the native gateway that serves its MCP tools did not wake in time.",
|
|
1001
|
+
"audience": "operator",
|
|
1002
|
+
"tags": [
|
|
1003
|
+
"error",
|
|
1004
|
+
"mcp",
|
|
1005
|
+
"coding-agents",
|
|
1006
|
+
"low-power",
|
|
1007
|
+
"coding_failure_mcp_gateway_unavailable",
|
|
1008
|
+
"coding_mcp_gateway_unavailable"
|
|
1009
|
+
],
|
|
1010
|
+
"appliesTo": ">=0.8.0",
|
|
1011
|
+
"sourcePath": "errors/coding-mcp-gateway-unavailable.md",
|
|
1012
|
+
"markdown": "\n# A coding run failed before launch because the native gateway did not wake\n\n## What happened\n\nThe run's error starts with `coding_failure_mcp_gateway_unavailable`, followed\nby a diagnostic id. It happens only in [low-power mode](../low-power-mode.md).\n\nA coding run with MCP tools sends every MCP call through the coding proxy to\nthe native gateway (`wardby-native-gateway`). In low-power mode the gateway\nmay be scaled to zero, so before such a run launches, wardby wakes the gateway\ntogether with the proxy and waits for a ready endpoint. The gateway did not\nbecome ready in time, so wardby failed the run rather than start it without\nits MCP tools. Nothing was launched, so the run made no changes.\n\nThe run's error contains only the code and the diagnostic id. The control\nplane log has the cause at `warn`, under the same diagnostic id, with the\ninternal code `coding_mcp_gateway_unavailable` and the underlying wake error,\nusually [`low_power_wake_timeout`](low-power-wake-timeout.md) or\n[`low_power_scale_forbidden`](low-power-scale-forbidden.md).\n\n## What to do\n\n1. Search the control plane log for the diagnostic id and read the wake error.\n2. For `low_power_wake_timeout`, check why the gateway pod did not become\n ready: `kubectl -n <namespace> describe deployment wardby-native-gateway`\n and the events of its pod. A cold Autopilot node can take a few minutes.\n The wait is at least 5 minutes; for coding runs a\n `KUBERNETES_READY_TIMEOUT_MS` above that, set on the control-plane\n Deployment, raises it.\n3. For `low_power_scale_forbidden`, re-run `up.sh` with `WARDBY_LOW_POWER=1` to\n apply the `wardby-power` Role.\n4. Trigger the agent again once the gateway is ready.\n\nRuns without MCP tools do not wake the gateway and never fail this way.\n\nSee [Remote MCP servers for coding agents](../../docs/mcp-servers.md#coding-agents)\nand [Low-power mode](../low-power-mode.md).\n",
|
|
1013
|
+
"plainText": "A coding run failed before launch because the native gateway did not wake What happened The run's error starts with codingfailuremcpgatewayunavailable, followed by a diagnostic id. It happens only in low-power mode. A coding run with MCP tools sends every MCP call through the coding proxy to the native gateway (wardby-native-gateway). In low-power mode the gateway may be scaled to zero, so before such a run launches, wardby wakes the gateway together with the proxy and waits for a ready endpoint. The gateway did not become ready in time, so wardby failed the run rather than start it without its MCP tools. Nothing was launched, so the run made no changes. The run's error contains only the code and the diagnostic id. The control plane log has the cause at warn, under the same diagnostic id, with the internal code codingmcpgatewayunavailable and the underlying wake error, usually lowpowerwaketimeout or lowpowerscaleforbidden. What to do Search the control plane log for the diagnostic id and read the wake error. For lowpowerwaketimeout, check why the gateway pod did not become ready: kubectl -n <namespace describe deployment wardby-native-gateway and the events of its pod. A cold Autopilot node can take a few minutes. The wait is at least 5 minutes; for coding runs a KUBERNETESREADYTIMEOUTMS above that, set on the control-plane Deployment, raises it. For lowpowerscaleforbidden, re-run up.sh with WARDBYLOWPOWER=1 to apply the wardby-power Role. Trigger the agent again once the gateway is ready. Runs without MCP tools do not wake the gateway and never fail this way. See Remote MCP servers for coding agents and Low-power mode.",
|
|
1014
|
+
"headings": [
|
|
1015
|
+
{
|
|
1016
|
+
"level": 1,
|
|
1017
|
+
"text": "A coding run failed before launch because the native gateway did not wake",
|
|
1018
|
+
"slug": "a-coding-run-failed-before-launch-because-the-native-gateway-did-not-wake"
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
"level": 2,
|
|
1022
|
+
"text": "What happened",
|
|
1023
|
+
"slug": "what-happened"
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
"level": 2,
|
|
1027
|
+
"text": "What to do",
|
|
1028
|
+
"slug": "what-to-do"
|
|
1029
|
+
}
|
|
1030
|
+
]
|
|
1031
|
+
},
|
|
996
1032
|
{
|
|
997
1033
|
"id": "errors/coding-mcp-pins-unavailable",
|
|
998
1034
|
"title": "A coding run failed before launch because its MCP tools could not be read",
|
|
@@ -3776,12 +3812,14 @@
|
|
|
3776
3812
|
"power_sleep",
|
|
3777
3813
|
"power_status",
|
|
3778
3814
|
"sleep now",
|
|
3779
|
-
"power:manage"
|
|
3815
|
+
"power:manage",
|
|
3816
|
+
"mcp",
|
|
3817
|
+
"coding-agents"
|
|
3780
3818
|
],
|
|
3781
3819
|
"appliesTo": ">=0.6.0",
|
|
3782
3820
|
"sourcePath": "low-power-mode.md",
|
|
3783
|
-
"markdown": "\n# Low-power mode on GKE\n\nLow-power mode reduces the cost of a GKE Autopilot deployment that runs agents\nonly occasionally. When it is on, the coding proxy and the native gateway scale\nto zero replicas after an idle window and wake when a run needs them. The\nheadroom placeholder is off, and the control plane runs 1 copy that scales to 2\nunder load.\n\nIt needs `JOB_LAUNCHER=kubernetes`. Without it Wardby logs `low_power_ignored`\nand the mode does nothing.\n\n## Turn it on or off\n\n```sh\nWARDBY_HOSTNAME=wardby.example.com WARDBY_LOW_POWER=1 deploy/gke/up.sh\n```\n\nRe-running `up.sh` without `WARDBY_LOW_POWER=1` turns it off: it removes the\nautoscaler `wardby-control-plane` and the Role and RoleBinding `wardby-power`\nand restores proxy 1, gateway 2, headroom 1, control plane 1.\n\n`WARDBY_LOW_POWER` accepts only unset, `0` or `1`; anything else fails `up.sh`\nand stops the control plane at start-up. `LOW_POWER_IDLE_MINUTES` is an integer\nfrom 5 to 1440 (default 30) set on the control-plane Deployment; it is read\nonly when `WARDBY_LOW_POWER=1`.\n\n## How it behaves\n\n- **Sleep.** Every minute the scheduler leader scales the coding proxy\n (`wardby-coding-proxy`) or native gateway (`wardby-native-gateway`) to 0 when\n nothing is pending or running for it and nothing finished within the idle\n window.
|
|
3784
|
-
"plainText": "Low-power mode on GKE Low-power mode reduces the cost of a GKE Autopilot deployment that runs agents only occasionally. When it is on, the coding proxy and the native gateway scale to zero replicas after an idle window and wake when a run needs them. The headroom placeholder is off, and the control plane runs 1 copy that scales to 2 under load. It needs JOBLAUNCHER=kubernetes. Without it Wardby logs lowpowerignored and the mode does nothing. Turn it on or off WARDBYHOSTNAME=wardby.example.com WARDBYLOWPOWER=1 deploy/gke/up.sh Re-running up.sh without WARDBYLOWPOWER=1 turns it off: it removes the autoscaler wardby-control-plane and the Role and RoleBinding wardby-power and restores proxy 1, gateway 2, headroom 1, control plane 1. WARDBYLOWPOWER accepts only unset, 0 or 1; anything else fails up.sh and stops the control plane at start-up. LOWPOWERIDLEMINUTES is an integer from 5 to 1440 (default 30) set on the control-plane Deployment; it is read only when WARDBYLOWPOWER=1. How it behaves Sleep. Every minute the scheduler leader scales the coding proxy (wardby-coding-proxy) or native gateway (wardby-native-gateway) to 0 when nothing is pending or running for it and nothing finished within the idle window.
|
|
3821
|
+
"markdown": "\n# Low-power mode on GKE\n\nLow-power mode reduces the cost of a GKE Autopilot deployment that runs agents\nonly occasionally. When it is on, the coding proxy and the native gateway scale\nto zero replicas after an idle window and wake when a run needs them. The\nheadroom placeholder is off, and the control plane runs 1 copy that scales to 2\nunder load.\n\nIt needs `JOB_LAUNCHER=kubernetes`. Without it Wardby logs `low_power_ignored`\nand the mode does nothing.\n\n## Turn it on or off\n\n```sh\nWARDBY_HOSTNAME=wardby.example.com WARDBY_LOW_POWER=1 deploy/gke/up.sh\n```\n\nRe-running `up.sh` without `WARDBY_LOW_POWER=1` turns it off: it removes the\nautoscaler `wardby-control-plane` and the Role and RoleBinding `wardby-power`\nand restores proxy 1, gateway 2, headroom 1, control plane 1.\n\n`WARDBY_LOW_POWER` accepts only unset, `0` or `1`; anything else fails `up.sh`\nand stops the control plane at start-up. `LOW_POWER_IDLE_MINUTES` is an integer\nfrom 5 to 1440 (default 30) set on the control-plane Deployment; it is read\nonly when `WARDBY_LOW_POWER=1`.\n\n## How it behaves\n\n- **Sleep.** Every minute the scheduler leader scales the coding proxy\n (`wardby-coding-proxy`) or native gateway (`wardby-native-gateway`) to 0 when\n nothing is pending or running for it and nothing finished within the idle\n window. For the gateway that means sandbox runs and coding runs with MCP\n tools, and it also needs no active session. Either target sleeps only\n once at least one idle window has passed since it was last woken (annotation\n `wardby.io/power-woke-at`) and since the control plane started, whichever is\n later. The check repeats just before scaling. Log: `power: proxy slept (idle 30m)`.\n- **Wake.** A coding run scales the proxy to 1 and waits for a ready endpoint;\n a sandbox run does the same for the gateway. A coding run with MCP tools\n wakes both at once, because its MCP calls go through the gateway; if the\n gateway does not wake it fails before launch with\n [`coding_failure_mcp_gateway_unavailable`](errors/coding-mcp-gateway-unavailable.md).\n The wait is at least 5 minutes.\n A `KUBERNETES_READY_TIMEOUT_MS` (the proxy, and the gateway wake of a coding\n run) or `NATIVE_SANDBOX_READY_TIMEOUT_MS` (the gateway wake of a sandbox run)\n above that, set on the control-plane Deployment, raises it. Expect\n about 1 to 2 minutes extra on a cold node. Log: `power: proxy woke`. A\n sandbox run woken this way may then wait for a gVisor node for its worker\n pod, so its first model call can come several minutes after it started. From\n 0.7.0 it shows as running the whole time and is not reaped as orphaned; only\n the wake and pod-start limits above can fail it.\n- **Preflight.** The first coding run after a control-plane restart also runs\n the cluster preflight canary, because start-up preflight is deferred while the\n proxy sleeps (`kubernetes_preflight_deferred`).\n- **Deploys.** Every `up.sh` run, including one that turns the mode off, marks\n the proxy and gateway as just woken before it brings them back up, so the\n control plane being replaced cannot scale them down mid-deploy. With the mode\n on they stay up through the deploy (its database checks need them) and sleep\n one idle window later.\n- **Control plane.** It scales 1 to 2 on CPU (20% target, scale down\n after 10 minutes). A run executes on the copy that started it, so scheduled\n runs stay on the scheduler leader; webhook and MCP-started runs spread. The\n autoscaler owns the replica count while the mode is on.\n\n## Sleep now\n\nTo skip the idle window, for example right after a test, call `power_sleep`.\nPass `target: \"proxy\"` or `target: \"gateway\"` to sleep one; omit it for both.\n\n- It scales the target to 0 at once, ignoring the idle window and the woke-at\n grace.\n- It never stops a run. A target with a pending or running run (for the\n gateway, a sandbox run or a coding run with MCP tools), or for the gateway an\n active gateway session, stays up, and its run ids are returned:\n `{ \"slept\": [\"proxy\"], \"blocked\": [{ \"target\": \"gateway\", \"runIds\": [\"...\"] }] }`.\n Recently finished runs do not block it.\n- The next run wakes the target as usual.\n- Each call is logged with `event: \"power.sleep\"` and the caller's principal.\n\n`power_status` returns, for each target, `replicas`, `ready`, `wokeAt` and\n`blockers` (the run ids keeping it busy; for the gateway these include\npending or running coding runs with MCP tools).\n\nBoth tools need the `power:manage` scope, which only the `admin` role grants\n(see [Identity and access](identity-and-access.md)). With the mode off,\n`power_sleep` fails with\n[`409 low_power_disabled`](errors/low-power-disabled.md) and `power_status`\nreturns `{ \"enabled\": false }`.\n\n## Trade-offs and requirements\n\n- With headroom off, the control plane has less protection against preemption.\n- The gateway runs 1 replica instead of 2 while awake: no redundancy.\n- `NATIVE_SANDBOX_WARM_POOL_SIZE` must be 0, or the control plane refuses to\n start.\n- The gateway must be in the same namespace as `KUBERNETES_NAMESPACE`.\n\n## Cost\n\nAutopilot bills Pod requests while a Pod exists. At us-central1 list prices\n($0.0445 per vCPU-hour, $0.0049225 per GiB-hour, 730 hours a month; use your\nregion's rates), always-on cost per workload is: control plane (1.1 vCPU / 2.125\nGiB) $43.37, coding proxy (1.1 / 3.125) $46.96, native gateway (0.35 / 0.625 per\nreplica, two replicas) $27.23, headroom (0.25 / 0.5) $9.92. In low-power mode\nthe proxy costs $0.0643 an hour and a gateway replica $0.0187 an hour only\nwhile awake, and headroom costs nothing. See\n[Getting started on GKE](../docs/getting-started-gke.md#low-power-mode) for the\nfull table.\n\n## Errors and log lines\n\n- [`low_power_wake_timeout`](errors/low-power-wake-timeout.md): the target did\n not become ready in time, or its Deployment does not exist.\n- [`coding_failure_mcp_gateway_unavailable`](errors/coding-mcp-gateway-unavailable.md):\n a coding run with MCP tools failed before launch because the gateway did not\n wake.\n- `native_sandbox_launch_abandoned` (0.7.0 and later): a sandbox run was\n stopped while the gateway woke, so no worker pod was made.\n- [`low_power_disabled`](errors/low-power-disabled.md): `power_sleep` was\n called while the mode is off.\n- [`low_power_scale_forbidden`](errors/low-power-scale-forbidden.md): the\n control plane may not read or scale a Deployment or read its Endpoints\n (Role `wardby-power` missing or out of date).\n- Also: `power_sleep_failed`, `low_power_access_check_failed`,\n `low_power_ignored`.\n\n## Local kind\n\n`WARDBY_LOW_POWER=1 deploy/kind-coding/up.sh` applies the Role. The kind control\nplane runs on your host, so set `WARDBY_LOW_POWER=1` (and optionally\n`LOW_POWER_IDLE_MINUTES`) in the environment of `wardby serve` too.\n\nRelated: [Deploy Wardby on GKE Autopilot](deploy-gke.md),\n[Run native agents in a sandbox](native-sandbox.md).\n",
|
|
3822
|
+
"plainText": "Low-power mode on GKE Low-power mode reduces the cost of a GKE Autopilot deployment that runs agents only occasionally. When it is on, the coding proxy and the native gateway scale to zero replicas after an idle window and wake when a run needs them. The headroom placeholder is off, and the control plane runs 1 copy that scales to 2 under load. It needs JOBLAUNCHER=kubernetes. Without it Wardby logs lowpowerignored and the mode does nothing. Turn it on or off WARDBYHOSTNAME=wardby.example.com WARDBYLOWPOWER=1 deploy/gke/up.sh Re-running up.sh without WARDBYLOWPOWER=1 turns it off: it removes the autoscaler wardby-control-plane and the Role and RoleBinding wardby-power and restores proxy 1, gateway 2, headroom 1, control plane 1. WARDBYLOWPOWER accepts only unset, 0 or 1; anything else fails up.sh and stops the control plane at start-up. LOWPOWERIDLEMINUTES is an integer from 5 to 1440 (default 30) set on the control-plane Deployment; it is read only when WARDBYLOWPOWER=1. How it behaves Sleep. Every minute the scheduler leader scales the coding proxy (wardby-coding-proxy) or native gateway (wardby-native-gateway) to 0 when nothing is pending or running for it and nothing finished within the idle window. For the gateway that means sandbox runs and coding runs with MCP tools, and it also needs no active session. Either target sleeps only once at least one idle window has passed since it was last woken (annotation wardby.io/power-woke-at) and since the control plane started, whichever is later. The check repeats just before scaling. Log: power: proxy slept (idle 30m). Wake. A coding run scales the proxy to 1 and waits for a ready endpoint; a sandbox run does the same for the gateway. A coding run with MCP tools wakes both at once, because its MCP calls go through the gateway; if the gateway does not wake it fails before launch with codingfailuremcpgatewayunavailable. The wait is at least 5 minutes. A KUBERNETESREADYTIMEOUTMS (the proxy, and the gateway wake of a coding run) or NATIVESANDBOXREADYTIMEOUTMS (the gateway wake of a sandbox run) above that, set on the control-plane Deployment, raises it. Expect about 1 to 2 minutes extra on a cold node. Log: power: proxy woke. A sandbox run woken this way may then wait for a gVisor node for its worker pod, so its first model call can come several minutes after it started. From 0.7.0 it shows as running the whole time and is not reaped as orphaned; only the wake and pod-start limits above can fail it. Preflight. The first coding run after a control-plane restart also runs the cluster preflight canary, because start-up preflight is deferred while the proxy sleeps (kubernetespreflightdeferred). Deploys. Every up.sh run, including one that turns the mode off, marks the proxy and gateway as just woken before it brings them back up, so the control plane being replaced cannot scale them down mid-deploy. With the mode on they stay up through the deploy (its database checks need them) and sleep one idle window later. Control plane. It scales 1 to 2 on CPU (20% target, scale down after 10 minutes). A run executes on the copy that started it, so scheduled runs stay on the scheduler leader; webhook and MCP-started runs spread. The autoscaler owns the replica count while the mode is on. Sleep now To skip the idle window, for example right after a test, call powersleep. Pass target: \"proxy\" or target: \"gateway\" to sleep one; omit it for both. It scales the target to 0 at once, ignoring the idle window and the woke-at grace. It never stops a run. A target with a pending or running run (for the gateway, a sandbox run or a coding run with MCP tools), or for the gateway an active gateway session, stays up, and its run ids are returned: { \"slept\": [\"proxy\"], \"blocked\": [{ \"target\": \"gateway\", \"runIds\": [\"...\"] }] }. Recently finished runs do not block it. The next run wakes the target as usual. Each call is logged with event: \"power.sleep\" and the caller's principal. powerstatus returns, for each target, replicas, ready, wokeAt and blockers (the run ids keeping it busy; for the gateway these include pending or running coding runs with MCP tools). Both tools need the power:manage scope, which only the admin role grants (see Identity and access). With the mode off, powersleep fails with 409 lowpowerdisabled and powerstatus returns { \"enabled\": false }. Trade-offs and requirements With headroom off, the control plane has less protection against preemption. The gateway runs 1 replica instead of 2 while awake: no redundancy. NATIVESANDBOXWARMPOOLSIZE must be 0, or the control plane refuses to start. The gateway must be in the same namespace as KUBERNETESNAMESPACE. Cost Autopilot bills Pod requests while a Pod exists. At us-central1 list prices ($0.0445 per vCPU-hour, $0.0049225 per GiB-hour, 730 hours a month; use your region's rates), always-on cost per workload is: control plane (1.1 vCPU / 2.125 GiB) $43.37, coding proxy (1.1 / 3.125) $46.96, native gateway (0.35 / 0.625 per replica, two replicas) $27.23, headroom (0.25 / 0.5) $9.92. In low-power mode the proxy costs $0.0643 an hour and a gateway replica $0.0187 an hour only while awake, and headroom costs nothing. See Getting started on GKE for the full table. Errors and log lines lowpowerwaketimeout: the target did not become ready in time, or its Deployment does not exist. codingfailuremcpgatewayunavailable: a coding run with MCP tools failed before launch because the gateway did not wake. nativesandboxlaunchabandoned (0.7.0 and later): a sandbox run was stopped while the gateway woke, so no worker pod was made. lowpowerdisabled: powersleep was called while the mode is off. lowpowerscaleforbidden: the control plane may not read or scale a Deployment or read its Endpoints (Role wardby-power missing or out of date). Also: powersleepfailed, lowpoweraccesscheckfailed, lowpowerignored. Local kind WARDBYLOWPOWER=1 deploy/kind-coding/up.sh applies the Role. The kind control plane runs on your host, so set WARDBYLOWPOWER=1 (and optionally LOWPOWERIDLEMINUTES) in the environment of wardby serve too. Related: Deploy Wardby on GKE Autopilot, Run native agents in a sandbox.",
|
|
3785
3823
|
"headings": [
|
|
3786
3824
|
{
|
|
3787
3825
|
"level": 1,
|
|
@@ -3838,8 +3876,8 @@
|
|
|
3838
3876
|
],
|
|
3839
3877
|
"appliesTo": ">=0.2.1",
|
|
3840
3878
|
"sourcePath": "mcp.md",
|
|
3841
|
-
"markdown": "\n# Connect a client to Wardby\n\nFor local use, `wardby quickstart` can register the local stdio MCP server with\nCodex or Claude Code. Local stdio trusts the local operator.\n\nFor remote access, Wardby exposes an OAuth 2.1-protected HTTP resource server.\nRun the service with `MCP_TRANSPORT=http`, set a canonical public URI, and use\nthe instance's configured identity-provider mode. Keep the MCP endpoint behind\nyour intended ingress and authentication boundary.\n\nMCP clients use Wardby to manage agents, budgets, tools, schedules, secrets,\ndatastores, and runs. They do not receive the provider or GitHub App\ncredentials held by Wardby's trusted components.\n\nWith the existing `agents:read` scope, clients can also use `search_help` to\nfind bundled self-hosted guidance with fuzzy matching and `get_help_article`\nto read a complete article by id. These tools use the same release-bundled,\noffline catalog as `wardby help`; they expose no instance data or credentials.\n\nSee [`docs/getting-started-identity-provider.md`](../docs/getting-started-identity-provider.md)\nfor the supported self-hosted and delegated identity-provider setup.\n\nFrom Wardby 0.8.0, Claude Code can show your runs in a pane beside the chat\nthrough the `wardby-runs` plugin: run `wardby claude-plugin install`, then\n`/wardby-runs`. Search help for \"claude code plugin\" (article\n`claude-code-run-pane`, Wardby 0.8.0 and later).\n",
|
|
3842
|
-
"plainText": "Connect a client to Wardby For local use, wardby quickstart can register the local stdio MCP server with Codex or Claude Code. Local stdio trusts the local operator. For remote access, Wardby exposes an OAuth 2.1-protected HTTP resource server. Run the service with MCPTRANSPORT=http, set a canonical public URI, and use the instance's configured identity-provider mode. Keep the MCP endpoint behind your intended ingress and authentication boundary. MCP clients use Wardby to manage agents, budgets, tools, schedules, secrets, datastores, and runs. They do not receive the provider or GitHub App credentials held by Wardby's trusted components. With the existing agents:read scope, clients can also use searchhelp to find bundled self-hosted guidance with fuzzy matching and gethelparticle to read a complete article by id. These tools use the same release-bundled, offline catalog as wardby help; they expose no instance data or credentials. See docs/getting-started-identity-provider.md for the supported self-hosted and delegated identity-provider setup. From Wardby 0.8.0, Claude Code can show your runs in a pane beside the chat through the wardby-runs plugin: run wardby claude-plugin install, then /wardby-runs. Search help for \"claude code plugin\" (article claude-code-run-pane, Wardby 0.8.0 and later).",
|
|
3879
|
+
"markdown": "\n# Connect a client to Wardby\n\nFor local use, `wardby quickstart` can register the local stdio MCP server with\nCodex or Claude Code. Local stdio trusts the local operator.\n\nFor remote access, Wardby exposes an OAuth 2.1-protected HTTP resource server.\nRun the service with `MCP_TRANSPORT=http`, set a canonical public URI, and use\nthe instance's configured identity-provider mode. Keep the MCP endpoint behind\nyour intended ingress and authentication boundary.\n\nMCP clients use Wardby to manage agents, budgets, tools, schedules, secrets,\ndatastores, and runs. They do not receive the provider or GitHub App\ncredentials held by Wardby's trusted components.\n\nWith the existing `agents:read` scope, clients can also use `search_help` to\nfind bundled self-hosted guidance with fuzzy matching and `get_help_article`\nto read a complete article by id. These tools use the same release-bundled,\noffline catalog as `wardby help`; they expose no instance data or credentials.\n\nSee [`docs/getting-started-identity-provider.md`](../docs/getting-started-identity-provider.md)\nfor the supported self-hosted and delegated identity-provider setup.\n\nFrom Wardby 0.8.0, Claude Code can show your runs in a pane beside the chat\nthrough the `wardby-runs` plugin: run `wardby claude-plugin install`, then\n`/wardby-runs`. Search help for \"claude code plugin\" (article\n`claude-code-run-pane`, Wardby 0.8.0 and later).\n\nTo follow what a run is doing, call `get_run_steps` (article `run-steps`).\n",
|
|
3880
|
+
"plainText": "Connect a client to Wardby For local use, wardby quickstart can register the local stdio MCP server with Codex or Claude Code. Local stdio trusts the local operator. For remote access, Wardby exposes an OAuth 2.1-protected HTTP resource server. Run the service with MCPTRANSPORT=http, set a canonical public URI, and use the instance's configured identity-provider mode. Keep the MCP endpoint behind your intended ingress and authentication boundary. MCP clients use Wardby to manage agents, budgets, tools, schedules, secrets, datastores, and runs. They do not receive the provider or GitHub App credentials held by Wardby's trusted components. With the existing agents:read scope, clients can also use searchhelp to find bundled self-hosted guidance with fuzzy matching and gethelparticle to read a complete article by id. These tools use the same release-bundled, offline catalog as wardby help; they expose no instance data or credentials. See docs/getting-started-identity-provider.md for the supported self-hosted and delegated identity-provider setup. From Wardby 0.8.0, Claude Code can show your runs in a pane beside the chat through the wardby-runs plugin: run wardby claude-plugin install, then /wardby-runs. Search help for \"claude code plugin\" (article claude-code-run-pane, Wardby 0.8.0 and later). To follow what a run is doing, call getrunsteps (article run-steps).",
|
|
3843
3881
|
"headings": [
|
|
3844
3882
|
{
|
|
3845
3883
|
"level": 1,
|
|
@@ -4328,8 +4366,8 @@
|
|
|
4328
4366
|
],
|
|
4329
4367
|
"appliesTo": ">=0.7.0",
|
|
4330
4368
|
"sourcePath": "resume-runs-locally.md",
|
|
4331
|
-
"markdown": "\n# Resume Claude Code runs locally\n\n`sessionResume` makes a Claude Code agent keep a redacted copy of each run's\nconversation, so the session can be continued locally in Claude Code with\n`get_run_transcript` and `npx @wardby/cli@latest resume`. It is off by default and is not\navailable for Codex agents. It needs Claude Code worker images from Wardby\n0.7.0 or later.\n\n## Turn it on\n\n```json\n{ \"id\": \"<coding agent id>\", \"codingProfile\": { \"sessionResume\": true } }\n```\n\nUse `update_agent` or `create_agent`. The server needs a blob store\n(`BLOB_STORE`, with `BLOB_STORE_LOCAL_DIR`, `BLOB_STORE_GCS_BUCKET`, or\n`BLOB_STORE_S3_BUCKET` and `BLOB_STORE_S3_REGION`, plus the optional\n`BLOB_STORE_S3_ENDPOINT` for an S3-compatible store) set on the **server\nprocess** that launches coding runs, not only on the coding proxy. Without a\nblob store nothing is stored, and `update_agent` warns you.\n\n## What is stored\n\n- The conversation as Claude Code recorded it: user and assistant messages,\n tool calls and their results, compaction summaries, files and skills the\n agent loaded, and a session title (`wardby run <id>: <task>` when Claude\n Code made none).\n- Removed: thinking blocks, the system prompt, the worker's environment, date\n and budget reminders, account and organisation details, and billing\n records.\n- Redacted: the values of the agent's attached secrets, plus the run's\n capability and registry token by their token shape. If the agent's secrets\n cannot be loaded, nothing is stored.\n- Stored for runs that finish, stop at their budget, or fail. Not stored for\n runs stopped with `stop_run` or ended by their timeout.\n- Stored gzip-compressed under the `run-transcripts/` prefix. When the run's\n context was compacted, only what a resume loads is kept: the last\n compaction's summary, the messages it kept, and everything after it.\n- At most `RUN_TRANSCRIPT_MAX_BYTES` per run, measured before compression\n (default 10 MiB, at most 64 MiB). Each run records a status (`stored`,\n `too_large`, `not_captured` or `failed`) with a reason code.\n\n## Who can read it\n\nTranscripts are stored from the first run with `sessionResume` on. Anyone\nwho can read a run (its triggerer and the agent's owner, as for `get_run`)\ncan download its transcript, which includes\nwhat the agent saw in the repository and in command output. Redaction removes secret\nvalues, not other sensitive text. Turn this on only for agents whose runs you\nare comfortable sharing with everyone who can read them.\n\n## Continue a run on your machine\n\n1. Ask your MCP client to call `get_run_transcript` with the run id (same\n access as `get_run`). For a stored transcript it returns a download link\n that works for 10 minutes and the command to run; otherwise the status\n (`none`, `too_large`, `not_captured`, `failed`, `expired`, `unavailable`,\n `unsupported`) and what it means.\n2. Run the command in a terminal, `npx @wardby/cli@latest resume -`, and paste the link\n when it asks. (A link given as an argument stays in shell history and the\n process list.) For a GitHub repository, run it inside a clone of that\n repository. A `local:` repository is used only when the link comes from\n this machine (a stdio MCP server); otherwise pass `--here` or `--dir`.\n\nIt verifies the download's SHA-256, writes the session to\n`~/.wardby/sessions/<run id>/<session id>.jsonl` (mode 0600, never into\nClaude Code's own config directory), adds a detached git worktree of the\nrun's branch next to the repository (the base commit, with a warning, when\nthe branch is gone), and starts `claude --resume` there. A stand-in\n`wardby_tools` server shows the run's `run_command` calls but runs nothing,\nand a note tells the model `/workspace` is now the worktree.\n\nOptions: `--dir <path>` (worktree location), `--here` (no checkout),\n`--force` (replace a different imported session file), `--print` (print the\n`claude` command instead of starting it). The command passes\n`--system-prompt-snapshot off` so the move note applies; remove it for a\nClaude Code older than 2.1.257 when the version could not be read. Under\n`npx`, the MCP config points into the npx cache: run `wardby resume` again if\nthe cache was cleaned.\n\nThe link is a credential until it expires: do not share it. Over stdio it\npoints at a local port the MCP server opens, so keep your MCP client\nconnected until the download finishes. The token is in the link's query\nstring: keep `/run-transcripts/download` out of load-balancer and ingress\naccess logs. Refusals:\n[Run transcript download refused](errors/run-transcript-download.md).\n\n## Retention\n\n`RUN_TRANSCRIPT_RETENTION_DAYS` is a whole number from 1 to 3650 (default 30).\nExpired transcripts are pruned when new ones are stored. On GCS or S3 also add\na bucket lifecycle rule on the `run-transcripts/` prefix.\n\n## Set it up per deployment\n\nGive transcripts a bucket of their own, not the dependency cache bucket, that\nonly the control plane can use.\n\n- GKE: `session_transcripts_enabled` and `session_transcripts_bucket_name` in\n Terraform (optionally `session_transcripts_retention_days`), then\n `WARDBY_SESSION_TRANSCRIPTS=true deploy/gke/up.sh`. Terraform adds the\n lifecycle rule; `up.sh` passes the same retention to the control plane.\n- AWS: the same Terraform variables, then give the control plane `BLOB_STORE=s3`,\n the `session_transcripts_bucket` output as `BLOB_STORE_S3_BUCKET`,\n `BLOB_STORE_S3_REGION`, and the `session_transcripts_retention_days` output as\n `RUN_TRANSCRIPT_RETENTION_DAYS`.\n- kind harness and Docker quickstart: the server runs on your host. Set\n `BLOB_STORE=local` and `BLOB_STORE_LOCAL_DIR` in its environment (for the\n quickstart, in `.wardby/.env`).\n\n## Startup and custom images\n\nWith `JOB_LAUNCHER` set to `docker` or `kubernetes`, a half-set `BLOB_STORE`\nor an invalid `RUN_TRANSCRIPT_RETENTION_DAYS` or `RUN_TRANSCRIPT_MAX_BYTES` stops\nthe server at startup,\nnaming the variable. An agent with its own `workerImageRef` image must rebuild\nit from a release that includes session resume (see\n[Build a tool runner image for a Claude Code agent](help://build-claude-code-image)),\nor its runs fail at input with `worker_input_failed`.\n\nFull setup: [Resume a run locally](../docs/coding-agent-setup.md#resume-a-run-locally).\nSee also [Choose a native or coding agent](help://creating-agents).\n\nThe `wardby-runs` Claude Code plugin can start the import from a run's detail\n(**Continue locally**); see `claude-code-run-pane` (Wardby 0.8.0 and later).\n",
|
|
4332
|
-
"plainText": "Resume Claude Code runs locally sessionResume makes a Claude Code agent keep a redacted copy of each run's conversation, so the session can be continued locally in Claude Code with getruntranscript and npx @wardby/cli@latest resume. It is off by default and is not available for Codex agents. It needs Claude Code worker images from Wardby 0.7.0 or later. Turn it on { \"id\": \"<coding agent id\", \"codingProfile\": { \"sessionResume\": true } } Use updateagent or createagent. The server needs a blob store (BLOBSTORE, with BLOBSTORELOCALDIR, BLOBSTOREGCSBUCKET, or BLOBSTORES3BUCKET and BLOBSTORES3REGION, plus the optional BLOBSTORES3ENDPOINT for an S3-compatible store) set on the server process that launches coding runs, not only on the coding proxy. Without a blob store nothing is stored, and updateagent warns you. What is stored The conversation as Claude Code recorded it: user and assistant messages, tool calls and their results, compaction summaries, files and skills the agent loaded, and a session title (wardby run <id: <task when Claude Code made none). Removed: thinking blocks, the system prompt, the worker's environment, date and budget reminders, account and organisation details, and billing records. Redacted: the values of the agent's attached secrets, plus the run's capability and registry token by their token shape. If the agent's secrets cannot be loaded, nothing is stored. Stored for runs that finish, stop at their budget, or fail. Not stored for runs stopped with stoprun or ended by their timeout. Stored gzip-compressed under the run-transcripts/ prefix. When the run's context was compacted, only what a resume loads is kept: the last compaction's summary, the messages it kept, and everything after it. At most RUNTRANSCRIPTMAXBYTES per run, measured before compression (default 10 MiB, at most 64 MiB). Each run records a status (stored, toolarge, notcaptured or failed) with a reason code. Who can read it Transcripts are stored from the first run with sessionResume on. Anyone who can read a run (its triggerer and the agent's owner, as for getrun) can download its transcript, which includes what the agent saw in the repository and in command output. Redaction removes secret values, not other sensitive text. Turn this on only for agents whose runs you are comfortable sharing with everyone who can read them. Continue a run on your machine Ask your MCP client to call getruntranscript with the run id (same access as getrun). For a stored transcript it returns a download link that works for 10 minutes and the command to run; otherwise the status (none, toolarge, notcaptured, failed, expired, unavailable, unsupported) and what it means. Run the command in a terminal, npx @wardby/cli@latest resume -, and paste the link when it asks. (A link given as an argument stays in shell history and the process list.) For a GitHub repository, run it inside a clone of that repository. A local: repository is used only when the link comes from this machine (a stdio MCP server); otherwise pass --here or --dir. It verifies the download's SHA-256, writes the session to ~/.wardby/sessions/<run id/<session id.jsonl (mode 0600, never into Claude Code's own config directory), adds a detached git worktree of the run's branch next to the repository (the base commit, with a warning, when the branch is gone), and starts claude --resume there. A stand-in wardbytools server shows the run's runcommand calls but runs nothing, and a note tells the model /workspace is now the worktree. Options: --dir <path (worktree location), --here (no checkout), --force (replace a different imported session file), --print (print the claude command instead of starting it). The command passes --system-prompt-snapshot off so the move note applies; remove it for a Claude Code older than 2.1.257 when the version could not be read. Under npx, the MCP config points into the npx cache: run wardby resume again if the cache was cleaned. The link is a credential until it expires: do not share it. Over stdio it points at a local port the MCP server opens, so keep your MCP client connected until the download finishes. The token is in the link's query string: keep /run-transcripts/download out of load-balancer and ingress access logs. Refusals: Run transcript download refused. Retention RUNTRANSCRIPTRETENTIONDAYS is a whole number from 1 to 3650 (default 30). Expired transcripts are pruned when new ones are stored. On GCS or S3 also add a bucket lifecycle rule on the run-transcripts/ prefix. Set it up per deployment Give transcripts a bucket of their own, not the dependency cache bucket, that only the control plane can use. GKE: sessiontranscriptsenabled and sessiontranscriptsbucketname in Terraform (optionally sessiontranscriptsretentiondays), then WARDBYSESSIONTRANSCRIPTS=true deploy/gke/up.sh. Terraform adds the lifecycle rule; up.sh passes the same retention to the control plane. AWS: the same Terraform variables, then give the control plane BLOBSTORE=s3, the sessiontranscriptsbucket output as BLOBSTORES3BUCKET, BLOBSTORES3REGION, and the sessiontranscriptsretentiondays output as RUNTRANSCRIPTRETENTIONDAYS. kind harness and Docker quickstart: the server runs on your host. Set BLOBSTORE=local and BLOBSTORELOCALDIR in its environment (for the quickstart, in .wardby/.env). Startup and custom images With JOBLAUNCHER set to docker or kubernetes, a half-set BLOBSTORE or an invalid RUNTRANSCRIPTRETENTIONDAYS or RUNTRANSCRIPTMAXBYTES stops the server at startup, naming the variable. An agent with its own workerImageRef image must rebuild it from a release that includes session resume (see Build a tool runner image for a Claude Code agent), or its runs fail at input with workerinputfailed. Full setup: Resume a run locally. See also Choose a native or coding agent. The wardby-runs Claude Code plugin can start the import from a run's detail (Continue locally); see claude-code-run-pane (Wardby 0.8.0 and later).",
|
|
4369
|
+
"markdown": "\n# Resume Claude Code runs locally\n\n`sessionResume` makes a Claude Code agent keep a redacted copy of each run's\nconversation, so the session can be continued locally in Claude Code with\n`get_run_transcript` and `npx @wardby/cli@latest resume`. It is off by default and is not\navailable for Codex agents. It needs Claude Code worker images from Wardby\n0.7.0 or later.\n\n## Turn it on\n\n```json\n{ \"id\": \"<coding agent id>\", \"codingProfile\": { \"sessionResume\": true } }\n```\n\nUse `update_agent` or `create_agent`. The server needs a blob store\n(`BLOB_STORE`, with `BLOB_STORE_LOCAL_DIR`, `BLOB_STORE_GCS_BUCKET`, or\n`BLOB_STORE_S3_BUCKET` and `BLOB_STORE_S3_REGION`, plus the optional\n`BLOB_STORE_S3_ENDPOINT` for an S3-compatible store) set on the **server\nprocess** that launches coding runs, not only on the coding proxy. Without a\nblob store nothing is stored, and `update_agent` warns you.\n\n## What is stored\n\n- The conversation as Claude Code recorded it: user and assistant messages,\n tool calls and their results, compaction summaries, files and skills the\n agent loaded, and a session title (`wardby run <id>: <task>` when Claude\n Code made none).\n- Removed: thinking blocks, the system prompt, the worker's environment, date\n and budget reminders, account and organisation details, and billing\n records.\n- Redacted: the values of the agent's attached secrets, plus the run's\n capability and registry token by their token shape. If the agent's secrets\n cannot be loaded, nothing is stored.\n- Stored for runs that finish, stop at their budget, or fail. Not stored for\n runs stopped with `stop_run` or ended by their timeout.\n- Stored gzip-compressed under the `run-transcripts/` prefix. When the run's\n context was compacted, only what a resume loads is kept: the last\n compaction's summary, the messages it kept, and everything after it.\n- At most `RUN_TRANSCRIPT_MAX_BYTES` per run, measured before compression\n (default 10 MiB, at most 64 MiB). Each run records a status (`stored`,\n `too_large`, `not_captured` or `failed`) with a reason code.\n\nFor a short line-per-step record of any run, without a blob store and without\ncontinuing it, see `run-steps`; from 0.9.0 its `detail` level is a lighter way to\nsee tool output without a transcript.\n\n## Who can read it\n\nTranscripts are stored from the first run with `sessionResume` on. Anyone\nwho can read a run (its triggerer and the agent's owner, as for `get_run`)\ncan download its transcript, which includes\nwhat the agent saw in the repository and in command output. Redaction removes secret\nvalues, not other sensitive text. Turn this on only for agents whose runs you\nare comfortable sharing with everyone who can read them.\n\n## Continue a run on your machine\n\n1. Ask your MCP client to call `get_run_transcript` with the run id (same\n access as `get_run`). For a stored transcript it returns a download link\n that works for 10 minutes and the command to run; otherwise the status\n (`none`, `too_large`, `not_captured`, `failed`, `expired`, `unavailable`,\n `unsupported`) and what it means.\n2. Run the command in a terminal, `npx @wardby/cli@latest resume -`, and paste the link\n when it asks. (A link given as an argument stays in shell history and the\n process list.) For a GitHub repository, run it inside a clone of that\n repository. A `local:` repository is used only when the link comes from\n this machine (a stdio MCP server); otherwise pass `--here` or `--dir`.\n\nIt verifies the download's SHA-256, writes the session to\n`~/.wardby/sessions/<run id>/<session id>.jsonl` (mode 0600, never into\nClaude Code's own config directory), adds a detached git worktree of the\nrun's branch next to the repository (the base commit, with a warning, when\nthe branch is gone), and starts `claude --resume` there. A stand-in\n`wardby_tools` server shows the run's `run_command` calls but runs nothing,\nand a note tells the model `/workspace` is now the worktree.\n\nOptions: `--dir <path>` (worktree location), `--here` (no checkout),\n`--force` (replace a different imported session file), `--print` (print the\n`claude` command instead of starting it). The command passes\n`--system-prompt-snapshot off` so the move note applies; remove it for a\nClaude Code older than 2.1.257 when the version could not be read. Under\n`npx`, the MCP config points into the npx cache: run `wardby resume` again if\nthe cache was cleaned.\n\nThe link is a credential until it expires: do not share it. Over stdio it\npoints at a local port the MCP server opens, so keep your MCP client\nconnected until the download finishes. The token is in the link's query\nstring: keep `/run-transcripts/download` out of load-balancer and ingress\naccess logs. Refusals:\n[Run transcript download refused](errors/run-transcript-download.md).\n\n## Retention\n\n`RUN_TRANSCRIPT_RETENTION_DAYS` is a whole number from 1 to 3650 (default 30).\nExpired transcripts are pruned when new ones are stored. On GCS or S3 also add\na bucket lifecycle rule on the `run-transcripts/` prefix.\n\n## Set it up per deployment\n\nGive transcripts a bucket of their own, not the dependency cache bucket, that\nonly the control plane can use.\n\n- GKE: `session_transcripts_enabled` and `session_transcripts_bucket_name` in\n Terraform (optionally `session_transcripts_retention_days`), then\n `WARDBY_SESSION_TRANSCRIPTS=true deploy/gke/up.sh`. Terraform adds the\n lifecycle rule; `up.sh` passes the same retention to the control plane.\n- AWS: the same Terraform variables, then give the control plane `BLOB_STORE=s3`,\n the `session_transcripts_bucket` output as `BLOB_STORE_S3_BUCKET`,\n `BLOB_STORE_S3_REGION`, and the `session_transcripts_retention_days` output as\n `RUN_TRANSCRIPT_RETENTION_DAYS`.\n- kind harness and Docker quickstart: the server runs on your host. Set\n `BLOB_STORE=local` and `BLOB_STORE_LOCAL_DIR` in its environment (for the\n quickstart, in `.wardby/.env`).\n\n## Startup and custom images\n\nWith `JOB_LAUNCHER` set to `docker` or `kubernetes`, a half-set `BLOB_STORE`\nor an invalid `RUN_TRANSCRIPT_RETENTION_DAYS` or `RUN_TRANSCRIPT_MAX_BYTES` stops\nthe server at startup,\nnaming the variable. An agent with its own `workerImageRef` image must rebuild\nit from a release that includes session resume (see\n[Build a tool runner image for a Claude Code agent](help://build-claude-code-image)),\nor its runs fail at input with `worker_input_failed`.\n\nFull setup: [Resume a run locally](../docs/coding-agent-setup.md#resume-a-run-locally).\nSee also [Choose a native or coding agent](help://creating-agents).\n\nThe `wardby-runs` Claude Code plugin can start the import from a run's detail\n(**Continue locally**); see `claude-code-run-pane` (Wardby 0.8.0 and later).\n",
|
|
4370
|
+
"plainText": "Resume Claude Code runs locally sessionResume makes a Claude Code agent keep a redacted copy of each run's conversation, so the session can be continued locally in Claude Code with getruntranscript and npx @wardby/cli@latest resume. It is off by default and is not available for Codex agents. It needs Claude Code worker images from Wardby 0.7.0 or later. Turn it on { \"id\": \"<coding agent id\", \"codingProfile\": { \"sessionResume\": true } } Use updateagent or createagent. The server needs a blob store (BLOBSTORE, with BLOBSTORELOCALDIR, BLOBSTOREGCSBUCKET, or BLOBSTORES3BUCKET and BLOBSTORES3REGION, plus the optional BLOBSTORES3ENDPOINT for an S3-compatible store) set on the server process that launches coding runs, not only on the coding proxy. Without a blob store nothing is stored, and updateagent warns you. What is stored The conversation as Claude Code recorded it: user and assistant messages, tool calls and their results, compaction summaries, files and skills the agent loaded, and a session title (wardby run <id: <task when Claude Code made none). Removed: thinking blocks, the system prompt, the worker's environment, date and budget reminders, account and organisation details, and billing records. Redacted: the values of the agent's attached secrets, plus the run's capability and registry token by their token shape. If the agent's secrets cannot be loaded, nothing is stored. Stored for runs that finish, stop at their budget, or fail. Not stored for runs stopped with stoprun or ended by their timeout. Stored gzip-compressed under the run-transcripts/ prefix. When the run's context was compacted, only what a resume loads is kept: the last compaction's summary, the messages it kept, and everything after it. At most RUNTRANSCRIPTMAXBYTES per run, measured before compression (default 10 MiB, at most 64 MiB). Each run records a status (stored, toolarge, notcaptured or failed) with a reason code. For a short line-per-step record of any run, without a blob store and without continuing it, see run-steps; from 0.9.0 its detail level is a lighter way to see tool output without a transcript. Who can read it Transcripts are stored from the first run with sessionResume on. Anyone who can read a run (its triggerer and the agent's owner, as for getrun) can download its transcript, which includes what the agent saw in the repository and in command output. Redaction removes secret values, not other sensitive text. Turn this on only for agents whose runs you are comfortable sharing with everyone who can read them. Continue a run on your machine Ask your MCP client to call getruntranscript with the run id (same access as getrun). For a stored transcript it returns a download link that works for 10 minutes and the command to run; otherwise the status (none, toolarge, notcaptured, failed, expired, unavailable, unsupported) and what it means. Run the command in a terminal, npx @wardby/cli@latest resume -, and paste the link when it asks. (A link given as an argument stays in shell history and the process list.) For a GitHub repository, run it inside a clone of that repository. A local: repository is used only when the link comes from this machine (a stdio MCP server); otherwise pass --here or --dir. It verifies the download's SHA-256, writes the session to ~/.wardby/sessions/<run id/<session id.jsonl (mode 0600, never into Claude Code's own config directory), adds a detached git worktree of the run's branch next to the repository (the base commit, with a warning, when the branch is gone), and starts claude --resume there. A stand-in wardbytools server shows the run's runcommand calls but runs nothing, and a note tells the model /workspace is now the worktree. Options: --dir <path (worktree location), --here (no checkout), --force (replace a different imported session file), --print (print the claude command instead of starting it). The command passes --system-prompt-snapshot off so the move note applies; remove it for a Claude Code older than 2.1.257 when the version could not be read. Under npx, the MCP config points into the npx cache: run wardby resume again if the cache was cleaned. The link is a credential until it expires: do not share it. Over stdio it points at a local port the MCP server opens, so keep your MCP client connected until the download finishes. The token is in the link's query string: keep /run-transcripts/download out of load-balancer and ingress access logs. Refusals: Run transcript download refused. Retention RUNTRANSCRIPTRETENTIONDAYS is a whole number from 1 to 3650 (default 30). Expired transcripts are pruned when new ones are stored. On GCS or S3 also add a bucket lifecycle rule on the run-transcripts/ prefix. Set it up per deployment Give transcripts a bucket of their own, not the dependency cache bucket, that only the control plane can use. GKE: sessiontranscriptsenabled and sessiontranscriptsbucketname in Terraform (optionally sessiontranscriptsretentiondays), then WARDBYSESSIONTRANSCRIPTS=true deploy/gke/up.sh. Terraform adds the lifecycle rule; up.sh passes the same retention to the control plane. AWS: the same Terraform variables, then give the control plane BLOBSTORE=s3, the sessiontranscriptsbucket output as BLOBSTORES3BUCKET, BLOBSTORES3REGION, and the sessiontranscriptsretentiondays output as RUNTRANSCRIPTRETENTIONDAYS. kind harness and Docker quickstart: the server runs on your host. Set BLOBSTORE=local and BLOBSTORELOCALDIR in its environment (for the quickstart, in .wardby/.env). Startup and custom images With JOBLAUNCHER set to docker or kubernetes, a half-set BLOBSTORE or an invalid RUNTRANSCRIPTRETENTIONDAYS or RUNTRANSCRIPTMAXBYTES stops the server at startup, naming the variable. An agent with its own workerImageRef image must rebuild it from a release that includes session resume (see Build a tool runner image for a Claude Code agent), or its runs fail at input with workerinputfailed. Full setup: Resume a run locally. See also Choose a native or coding agent. The wardby-runs Claude Code plugin can start the import from a run's detail (Continue locally); see claude-code-run-pane (Wardby 0.8.0 and later).",
|
|
4333
4371
|
"headings": [
|
|
4334
4372
|
{
|
|
4335
4373
|
"level": 1,
|
|
@@ -4406,6 +4444,56 @@
|
|
|
4406
4444
|
}
|
|
4407
4445
|
]
|
|
4408
4446
|
},
|
|
4447
|
+
{
|
|
4448
|
+
"id": "run-steps",
|
|
4449
|
+
"title": "See what a run is doing (run steps)",
|
|
4450
|
+
"summary": "Wardby records each run's steps, one line per tool call or model message, so you can follow a running run and read what a finished one did with get_run_steps. Run steps detail adds tool output.",
|
|
4451
|
+
"audience": "operator",
|
|
4452
|
+
"tags": [
|
|
4453
|
+
"run steps",
|
|
4454
|
+
"claude code run steps",
|
|
4455
|
+
"get_run_steps",
|
|
4456
|
+
"what is my run doing",
|
|
4457
|
+
"WARDBY_RUN_STEPS",
|
|
4458
|
+
"viewer step event"
|
|
4459
|
+
],
|
|
4460
|
+
"appliesTo": ">=0.9.0",
|
|
4461
|
+
"sourcePath": "run-steps.md",
|
|
4462
|
+
"markdown": "\n# See what a run is doing\n\nWardby records the steps of a run while it runs:\n\n- one line for each **tool call**: the tool, and its command, file or first\n argument, cut to about 100 characters, with its status once the result is\n back (`ok`, `error`, or `exit N` for a command that exited with code N);\n- one line for what the **model said**, cut to about 120 characters.\n\n## Levels\n\n| Level | Tool input | Tool result | Model text |\n| --------- | -------------------- | --------------------------------------- | -------------------- |\n| `off` | - | - | - |\n| `summary` | about 100 characters | status only (`ok`, `error`, `exit N`) | about 120 characters |\n| `detail` | up to about 4 KB | status and the last ~2 KB of its output | up to about 8 KB |\n\nAt `summary`, the default, tool output is never recorded. At `detail` each step\nalso keeps a **detail** text, at most 16 KB. When the output is cut at the\nstart, the partial first line is dropped if it ends within 256 characters;\notherwise only the first 256 characters are dropped, so a long single-line\noutput, such as a JSON result, keeps about its last 1.8 KB. At every level,\nterminal escape sequences (colour codes, links, clipboard writes, title changes)\nand every other control character except line breaks and tabs are removed from\nstep text before it is stored.\n\nA run's level is the lower of two settings, fixed when the run is dispatched (a\nchange reaches later runs only; lowering the ceiling also stops detail for runs\nalready in flight):\n\n- the instance's ceiling, `WARDBY_RUN_STEPS` (default `summary`);\n- the agent's `runSteps` (`off`, `summary` or `detail`), set by the agent's\n owner with `create_agent` or `update_agent`. Unset counts as `summary`. Set\n `null` to clear it.\n\nSo `detail` needs both the operator and the agent's owner. If `runSteps` asks\nfor more than the instance allows, the value is stored, `update_agent` and\n`get_agent` say so in `warnings`, and runs record at the ceiling.\n\n> **Warning: `detail` stores tool output.** Before a step is stored, every\n> secret value the run was given is removed and anything shaped like a token or\n> key is masked. A secret that exists only inside a repository file, or another\n> source the run read, and that matches no known shape, is not known to Wardby\n> and can remain in the detail text. That is why detail is off unless both the\n> operator and the agent's owner ask for it. Turn it on only for agents whose\n> tool output you are prepared to keep for the retention period.\n\nSteps are recorded for native runs (in the control plane and on the native\nsandbox) and for Claude Code and Codex runs. Every agent's shell command shows\nas `Bash`: a native agent's `run_command`, Claude Code's command tool, and\nCodex's `exec_command`, `shell`, `local_shell` and `shell_command`. Another tool\nshows under its own name (for example `apply_patch`), and a remote MCP tool as\n`mcp:<tool>`.\n\nA Claude Code or Codex run's final answer is one `said` step: the start of the\nsummary it returned (the pull request description), or `Finished` with the\noutcome (for example `Finished: changes ready`) when it returned none.\n\nFor Claude Code and Codex runs, the coding proxy reads the steps from the\nmodel's replies after relaying them and posts them to the server, which needs a\nlistener for them: `WARDBY_RUN_STEPS_LISTEN` on `wardby serve` and\n`WARDBY_RUN_STEPS_URL` on the proxy. The reference GKE manifests set both; the\nkind overlay sets only `WARDBY_RUN_STEPS_URL`, so set\n`WARDBY_RUN_STEPS_LISTEN` on the host's `wardby serve`. Without either, coding\nruns record no steps; native runs are not affected. A slow or unreachable listener loses steps; it never slows the run.\n\n## Read the steps\n\n- `get_run_steps` with `runId` lists a run's steps, oldest first, 50 at a time\n (`limit`, at most 200). `next` is what to pass as `after` for the next page.\n To follow a running run, call it again every few seconds with `after` set to\n the last `seq` you have.\n- `get_run` and `list_runs` (without `agentId`) include `lastStep`, the run's\n newest step as one line, for example `Bash: npm test (exit 1)`.\n- The `wardby-runs` Claude Code pane shows a running run's last steps and a\n finished run's steps; see `claude-code-run-pane`.\n- The admin viewer API sends a `step` event on `/admin/api/events` for each\n step and status, and `GET /admin/api/runs/<id>` lists the run's newest 200\n steps (see `admin-viewer`). The Wardby Viewer app shows them in a **Steps**\n section of a run's detail.\n\nAt `detail`, `get_run_steps` also returns each step's `detail` to the agent's\nowner and to the person who started the run (and to the stdio operator); anyone\nelse, including an admin who does not own the agent, gets the lines only. `lastStep`, the admin viewer API\nand its `step` events never include detail.\n\nYou can read a run's steps when you can read the run with `get_run`.\n\nA run records at most 2,000 steps. Later steps are not recorded; `dropped`\ncounts them.\n\n## Secrets\n\nBefore a step is stored, Wardby removes every secret value the run's agent has\n(its attached secrets, readable or brokered, and its MCP servers' secrets), the\nrun's own capability and registry token, and\nanything shaped like a token or key. A command that echoes a secret shows\n`[REDACTED]` in its place.\n\n## Retention\n\nSteps, and their detail, are deleted `RUN_STEP_RETENTION_DAYS` after they are\nrecorded (default 30). A change applies to steps recorded after it. `get_run_steps` reports `expired` when a run finished more than\n`RUN_STEP_RETENTION_DAYS` ago and has no steps left.\n\n## Settings\n\n| Variable | Default | What it does |\n| ------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `WARDBY_RUN_STEPS` | `summary` | `off` records no steps; `summary` the lines above; `detail` allows agents whose `runSteps` is `detail` to record detail. The ceiling for every run. Any other value stops start-up. |\n| `RUN_STEP_RETENTION_DAYS` | `30` | Days to keep a step, a whole number from 1 to 3650. Any other value stops start-up. |\n| `WARDBY_RUN_STEPS_LISTEN` | unset | On `wardby serve` only: `host:port` (or `:port`) of the listener the coding proxy posts coding runs' steps to. Unset: no listener. |\n| `WARDBY_RUN_STEPS_URL` | unset | On the coding proxy: the listener's origin, for example `http://<server host>:8792`, with no credentials or path. Unset: coding runs record no steps. |\n\nSet `WARDBY_RUN_STEPS` (including `detail`) and `RUN_STEP_RETENTION_DAYS` on\nevery process that writes steps: `wardby serve`,\n`wardby scheduler`, `wardby run`, `wardby mcp` and `wardby native-gateway`. The\ncoding proxy reads `WARDBY_RUN_STEPS` too: with `off`, or with\n`WARDBY_RUN_STEPS_URL` unset, no step text leaves the proxy. For a coding\nrun's steps use `wardby serve` (the only process that runs the listener), not\nthe stdio `wardby mcp`.\n\nFor coding runs at `detail`, set `WARDBY_RUN_STEPS=detail` on the coding proxy\ntoo: below `detail`, the proxy never sends any tool output to the server.\n\nThe listener is a second network path into the server, from the coding proxy\nonly; keep it off any load balancer. See\n[Run steps](../docs/security-deployment.md#run-steps) for how to restrict it.\n\nThe full guide is\n[Debugging agent runs](../docs/debugging-agent-runs.md#run-steps).\n",
|
|
4463
|
+
"plainText": "See what a run is doing Wardby records the steps of a run while it runs: one line for each tool call: the tool, and its command, file or first argument, cut to about 100 characters, with its status once the result is back (ok, error, or exit N for a command that exited with code N); one line for what the model said, cut to about 120 characters. Levels | Level | Tool input | Tool result | Model text | | --------- | -------------------- | --------------------------------------- | -------------------- | | off | - | - | - | | summary | about 100 characters | status only (ok, error, exit N) | about 120 characters | | detail | up to about 4 KB | status and the last ~2 KB of its output | up to about 8 KB | At summary, the default, tool output is never recorded. At detail each step also keeps a detail text, at most 16 KB. When the output is cut at the start, the partial first line is dropped if it ends within 256 characters; otherwise only the first 256 characters are dropped, so a long single-line output, such as a JSON result, keeps about its last 1.8 KB. At every level, terminal escape sequences (colour codes, links, clipboard writes, title changes) and every other control character except line breaks and tabs are removed from step text before it is stored. A run's level is the lower of two settings, fixed when the run is dispatched (a change reaches later runs only; lowering the ceiling also stops detail for runs already in flight): the instance's ceiling, WARDBYRUNSTEPS (default summary); the agent's runSteps (off, summary or detail), set by the agent's owner with createagent or updateagent. Unset counts as summary. Set null to clear it. So detail needs both the operator and the agent's owner. If runSteps asks for more than the instance allows, the value is stored, updateagent and getagent say so in warnings, and runs record at the ceiling. Warning: detail stores tool output. Before a step is stored, every secret value the run was given is removed and anything shaped like a token or key is masked. A secret that exists only inside a repository file, or another source the run read, and that matches no known shape, is not known to Wardby and can remain in the detail text. That is why detail is off unless both the operator and the agent's owner ask for it. Turn it on only for agents whose tool output you are prepared to keep for the retention period. Steps are recorded for native runs (in the control plane and on the native sandbox) and for Claude Code and Codex runs. Every agent's shell command shows as Bash: a native agent's runcommand, Claude Code's command tool, and Codex's execcommand, shell, localshell and shellcommand. Another tool shows under its own name (for example applypatch), and a remote MCP tool as mcp:<tool. A Claude Code or Codex run's final answer is one said step: the start of the summary it returned (the pull request description), or Finished with the outcome (for example Finished: changes ready) when it returned none. For Claude Code and Codex runs, the coding proxy reads the steps from the model's replies after relaying them and posts them to the server, which needs a listener for them: WARDBYRUNSTEPSLISTEN on wardby serve and WARDBYRUNSTEPSURL on the proxy. The reference GKE manifests set both; the kind overlay sets only WARDBYRUNSTEPSURL, so set WARDBYRUNSTEPSLISTEN on the host's wardby serve. Without either, coding runs record no steps; native runs are not affected. A slow or unreachable listener loses steps; it never slows the run. Read the steps getrunsteps with runId lists a run's steps, oldest first, 50 at a time (limit, at most 200). next is what to pass as after for the next page. To follow a running run, call it again every few seconds with after set to the last seq you have. getrun and listruns (without agentId) include lastStep, the run's newest step as one line, for example Bash: npm test (exit 1). The wardby-runs Claude Code pane shows a running run's last steps and a finished run's steps; see claude-code-run-pane. The admin viewer API sends a step event on /admin/api/events for each step and status, and GET /admin/api/runs/<id lists the run's newest 200 steps (see admin-viewer). The Wardby Viewer app shows them in a Steps section of a run's detail. At detail, getrunsteps also returns each step's detail to the agent's owner and to the person who started the run (and to the stdio operator); anyone else, including an admin who does not own the agent, gets the lines only. lastStep, the admin viewer API and its step events never include detail. You can read a run's steps when you can read the run with getrun. A run records at most 2,000 steps. Later steps are not recorded; dropped counts them. Secrets Before a step is stored, Wardby removes every secret value the run's agent has (its attached secrets, readable or brokered, and its MCP servers' secrets), the run's own capability and registry token, and anything shaped like a token or key. A command that echoes a secret shows [REDACTED] in its place. Retention Steps, and their detail, are deleted RUNSTEPRETENTIONDAYS after they are recorded (default 30). A change applies to steps recorded after it. getrunsteps reports expired when a run finished more than RUNSTEPRETENTIONDAYS ago and has no steps left. Settings | Variable | Default | What it does | | ------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | WARDBYRUNSTEPS | summary | off records no steps; summary the lines above; detail allows agents whose runSteps is detail to record detail. The ceiling for every run. Any other value stops start-up. | | RUNSTEPRETENTIONDAYS | 30 | Days to keep a step, a whole number from 1 to 3650. Any other value stops start-up. | | WARDBYRUNSTEPSLISTEN | unset | On wardby serve only: host:port (or :port) of the listener the coding proxy posts coding runs' steps to. Unset: no listener. | | WARDBYRUNSTEPSURL | unset | On the coding proxy: the listener's origin, for example http://<server host:8792, with no credentials or path. Unset: coding runs record no steps. | Set WARDBYRUNSTEPS (including detail) and RUNSTEPRETENTIONDAYS on every process that writes steps: wardby serve, wardby scheduler, wardby run, wardby mcp and wardby native-gateway. The coding proxy reads WARDBYRUNSTEPS too: with off, or with WARDBYRUNSTEPSURL unset, no step text leaves the proxy. For a coding run's steps use wardby serve (the only process that runs the listener), not the stdio wardby mcp. For coding runs at detail, set WARDBYRUNSTEPS=detail on the coding proxy too: below detail, the proxy never sends any tool output to the server. The listener is a second network path into the server, from the coding proxy only; keep it off any load balancer. See Run steps for how to restrict it. The full guide is Debugging agent runs.",
|
|
4464
|
+
"headings": [
|
|
4465
|
+
{
|
|
4466
|
+
"level": 1,
|
|
4467
|
+
"text": "See what a run is doing",
|
|
4468
|
+
"slug": "see-what-a-run-is-doing"
|
|
4469
|
+
},
|
|
4470
|
+
{
|
|
4471
|
+
"level": 2,
|
|
4472
|
+
"text": "Levels",
|
|
4473
|
+
"slug": "levels"
|
|
4474
|
+
},
|
|
4475
|
+
{
|
|
4476
|
+
"level": 2,
|
|
4477
|
+
"text": "Read the steps",
|
|
4478
|
+
"slug": "read-the-steps"
|
|
4479
|
+
},
|
|
4480
|
+
{
|
|
4481
|
+
"level": 2,
|
|
4482
|
+
"text": "Secrets",
|
|
4483
|
+
"slug": "secrets"
|
|
4484
|
+
},
|
|
4485
|
+
{
|
|
4486
|
+
"level": 2,
|
|
4487
|
+
"text": "Retention",
|
|
4488
|
+
"slug": "retention"
|
|
4489
|
+
},
|
|
4490
|
+
{
|
|
4491
|
+
"level": 2,
|
|
4492
|
+
"text": "Settings",
|
|
4493
|
+
"slug": "settings"
|
|
4494
|
+
}
|
|
4495
|
+
]
|
|
4496
|
+
},
|
|
4409
4497
|
{
|
|
4410
4498
|
"id": "security-boundaries",
|
|
4411
4499
|
"title": "Understand Wardby security boundaries",
|
package/dist/mcp/context.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { Principal, PrismaClient } from "#prisma";
|
|
|
11
11
|
import type { RequestStateAccessor } from "@modelcontextprotocol/server";
|
|
12
12
|
import type { ProviderRegistry } from "../providers/index.js";
|
|
13
13
|
import type { RepoAccessGate } from "../core/repo-access.js";
|
|
14
|
+
import type { RunStepSink } from "../core/run-steps/types.js";
|
|
14
15
|
import type { IssueTrackerRegistry } from "../providers/issue-tracker/types.js";
|
|
15
16
|
import type { HostUserAuthorizerRegistry, ReviewHostRegistry } from "../providers/review-host/types.js";
|
|
16
17
|
import type { Power } from "../core/power.js";
|
|
@@ -34,6 +35,8 @@ export type McpProviders = Pick<ProviderRegistry, "llm" | "engine" | "datastore"
|
|
|
34
35
|
power?: Power;
|
|
35
36
|
/** Overrides the outbound call to remote MCP servers (register/update/refresh_mcp_server) — tests only. */
|
|
36
37
|
sandboxFetch?: typeof safeFetch;
|
|
38
|
+
/** Records runs' steps; also what the run-steps listener writes through. */
|
|
39
|
+
runSteps?: RunStepSink;
|
|
37
40
|
};
|
|
38
41
|
export interface McpRequestContext {
|
|
39
42
|
principal: Principal;
|
package/dist/mcp/index.js
CHANGED
|
@@ -77,6 +77,9 @@ import { registerSecretsTools } from "./tools/secrets.js";
|
|
|
77
77
|
import { registerWebhookTools } from "./tools/webhooks.js";
|
|
78
78
|
import { STDIO_SECRET_PATH, secretFormRoute } from "./tools/secret-elicitation-server.js";
|
|
79
79
|
import { createStdioLinkHost } from "./transport/stdio-link-host.js";
|
|
80
|
+
import { loadRunStepRetentionDays, loadRunStepsLevel } from "../core/run-steps/config.js";
|
|
81
|
+
import { buildRunStepWriter } from "../core/run-steps/writer.js";
|
|
82
|
+
import { registerRunStepsTool } from "./tools/run-steps.js";
|
|
80
83
|
import { registerRunTranscriptTool } from "./tools/run-transcript.js";
|
|
81
84
|
import { handleRunTranscriptDownload, RUN_TRANSCRIPT_DOWNLOAD_PATH } from "./tools/run-transcript-download.js";
|
|
82
85
|
import { createBlobStore } from "../providers/storage/index.js";
|
|
@@ -139,6 +142,7 @@ export function registerAllTools(mcp, opts) {
|
|
|
139
142
|
blobStoreConfigured: runTranscriptUrl !== undefined && opts.blobStoreConfigured === true,
|
|
140
143
|
audience: opts.runTranscriptAudience ?? "http",
|
|
141
144
|
});
|
|
145
|
+
registerRunStepsTool(mcp, { level: loadRunStepsLevel(), retentionDays: loadRunStepRetentionDays() });
|
|
142
146
|
registerStopRunTool(mcp);
|
|
143
147
|
registerCostReportTools(mcp);
|
|
144
148
|
registerDatastoreTools(mcp);
|
|
@@ -171,6 +175,8 @@ export function buildMcpProviders() {
|
|
|
171
175
|
const secretGuard = createDbSecretWriteGuard(prisma, secrets);
|
|
172
176
|
const datastore = guardDatastore(new PostgresDatastore(prisma, secrets), secretGuard);
|
|
173
177
|
const memory = guardAgentMemory(new PostgresAgentMemory(prisma), secretGuard);
|
|
178
|
+
// The one run-steps writer of this process (WARDBY_RUN_STEPS, RUN_STEP_RETENTION_DAYS; invalid stops start-up).
|
|
179
|
+
const runSteps = buildRunStepWriter(prisma, secrets);
|
|
174
180
|
const reviewHosts = buildReviewHosts(process.env, prisma);
|
|
175
181
|
const issueTrackers = buildIssueTrackers();
|
|
176
182
|
const hostUserAuthorizers = buildHostUserAuthorizers();
|
|
@@ -199,6 +205,7 @@ export function buildMcpProviders() {
|
|
|
199
205
|
reviewHosts,
|
|
200
206
|
issueTrackers,
|
|
201
207
|
repoAccess,
|
|
208
|
+
runSteps,
|
|
202
209
|
};
|
|
203
210
|
// Read again at each tool call; checked here so a bad value stops start-up, not every run.
|
|
204
211
|
loadToolMaxTimeoutMs();
|
|
@@ -232,6 +239,7 @@ export function buildMcpProviders() {
|
|
|
232
239
|
repoAccess,
|
|
233
240
|
chat,
|
|
234
241
|
power,
|
|
242
|
+
runSteps,
|
|
235
243
|
},
|
|
236
244
|
};
|
|
237
245
|
}
|
|
@@ -323,6 +331,7 @@ export async function startMcp(options = {}) {
|
|
|
323
331
|
close: async () => {
|
|
324
332
|
await closeQuietly(stdio.close(), "stdio transport close");
|
|
325
333
|
await closeQuietly(providers.executor.close?.(), "executor close");
|
|
334
|
+
await providers.runSteps?.flush?.();
|
|
326
335
|
modelCatalog.close();
|
|
327
336
|
},
|
|
328
337
|
};
|
|
@@ -460,6 +469,7 @@ export async function startMcp(options = {}) {
|
|
|
460
469
|
// closes under them; a run abandoned here is lost, never resumed.
|
|
461
470
|
await waitForInFlightRuns(drainSeconds * 1000);
|
|
462
471
|
await closeQuietly(providers.executor.close?.(), "executor close");
|
|
472
|
+
await providers.runSteps?.flush?.();
|
|
463
473
|
modelCatalog.close();
|
|
464
474
|
},
|
|
465
475
|
};
|