docs: fold terminal reattach into the hardened terminal docs (opt-in default)

This commit is contained in:
Peter Steinberger
2026-07-04 14:03:04 -07:00
parent 619fee1b4f
commit e57bcbca50
3 changed files with 7 additions and 29 deletions
+1 -20
View File
@@ -616,6 +616,7 @@ See [Inferred commitments](/concepts/commitments).
- `controlUi.dangerouslyAllowHostHeaderOriginFallback`: dangerous mode that enables Host-header origin fallback for deployments that intentionally rely on Host-header origin policy.
- `terminal.enabled`: opt in to the admin-scoped operator terminal. Default: `false`. The terminal starts a host PTY in the selected agent workspace, inherits the Gateway process environment, and is refused for agents with `sandbox.mode: "all"`. Enable it only for trusted operator deployments; changing it restarts the Gateway and updates the Control UI content security policy.
- `terminal.shell`: optional shell executable. When unset, OpenClaw uses `$SHELL` on Unix and `%ComSpec%` on Windows.
- `terminal.detachedSessionTimeoutSeconds`: how long a terminal session survives after its connection drops (page reload, laptop sleep), staying reattachable via `terminal.attach` with its recent output replayed. Default: `300`. Set `0` to kill sessions the moment their connection drops. Detached sessions keep running their commands, so shorten this on shared or exposed hosts.
- `remote.transport`: `ssh` (default) or `direct` (ws/wss). For `direct`, `remote.url` must be `wss://` for public hosts; plaintext `ws://` is accepted only for loopback, LAN, link-local, `.local`, `.ts.net`, and Tailscale CGNAT hosts.
- `remote.remotePort`: gateway port on the remote SSH host. Defaults to `18789`; use this when the local tunnel port differs from the remote gateway port.
- `remote.sshHostKeyPolicy`: macOS SSH tunnel host-key policy. `strict` is the default and requires an already trusted key. `openssh` is an explicit opt-in to the effective OpenSSH configuration for managed aliases; review matching user and system SSH settings before using it. The macOS app and `configure-remote` reset this policy to `strict` when changing targets unless explicitly opted in again.
@@ -717,26 +718,6 @@ See [Multiple Gateways](/gateway/multiple-gateways).
- `debounceMs`: debounce window in ms before config changes are applied (non-negative integer).
- `deferralTimeoutMs`: optional maximum time in ms to wait for in-flight operations before forcing a restart or channel hot reload. Omit it to use the default bounded wait (`300000`); set `0` to wait indefinitely and log periodic still-pending warnings.
### `gateway.terminal`
```json5
{
gateway: {
terminal: {
enabled: true,
shell: "/bin/zsh",
detachedSessionTimeoutSeconds: 300,
},
},
}
```
Operator terminal served to the Control UI and mobile clients: a PTY-backed shell on the gateway host, restricted to admin-scope operator sessions. Changing any `gateway.terminal.*` key restarts the gateway.
- `enabled`: master switch for the terminal surface (default: `true`). Disabling removes the browser/mobile shell entirely.
- `shell`: shell executable to launch. Unset uses the host login shell (`$SHELL` on Unix, `%ComSpec%` on Windows).
- `detachedSessionTimeoutSeconds`: how long a session survives after its connection drops (page reload, laptop sleep), staying reattachable with its recent output replayed (default: `300`). Set `0` to kill sessions the moment their connection drops. Detached sessions keep running their commands, so shorten this on shared or exposed hosts.
---
## Hooks
+4 -2
View File
@@ -382,8 +382,10 @@ enumeration of `src/gateway/server-methods/*.ts`.
<Accordion title="Operator terminal">
- `terminal.open` starts a host PTY for an explicit `agentId` or the default agent and returns the resolved agent, working directory, shell, and confinement state.
- `terminal.input`, `terminal.resize`, and `terminal.close` operate only on sessions owned by the calling connection.
- `terminal.data` and `terminal.exit` events stream only to the connection that opened the session.
- Every terminal method requires `operator.admin`; `gateway.terminal.enabled` must be explicitly true. Fully sandboxed agents are refused, and an agent policy change closes existing and in-flight PTYs.
- `terminal.data` and `terminal.exit` events stream only to the connection that owns the session.
- Sessions whose connection drops are detached, not killed: they stay reattachable for `gateway.terminal.detachedSessionTimeoutSeconds` (default 300; `0` restores kill-on-disconnect) while recent output accumulates in a bounded server-side buffer.
- `terminal.list` returns attachable sessions; `terminal.attach` rebinds a live-or-detached session to the calling connection and returns the replay buffer (tmux-style take-over — a previous live owner receives `terminal.exit` with reason `detached`); `terminal.text` reads the buffer as plain text without attaching.
- Every terminal method requires `operator.admin`; `gateway.terminal.enabled` must be explicitly true. Fully sandboxed agents are refused, and an agent policy change closes existing and in-flight PTYs, detached ones included.
</Accordion>
+2 -7
View File
@@ -164,13 +164,6 @@ Imported themes are stored only in the current browser profile. They are not wri
- Raw JSON editor "Reset to saved" preserves the raw-authored shape (formatting, comments, `$include` layout) instead of re-rendering a flattened snapshot, so external edits survive a reset when the snapshot can safely round-trip.
- Structured SecretRef object values are rendered read-only in form text inputs to prevent accidental object-to-string corruption.
</Accordion>
<Accordion title="Operator terminal">
- Dockable PTY shell on the gateway host (`terminal.*` RPCs), restricted to admin-scope operator sessions; hidden unless the gateway advertises it (`gateway.terminal.enabled`).
- Sessions start in the target agent's workspace; fully sandboxed agents (`sandbox.mode: "all"`) are refused fail-closed.
- Dropped connections (page reload, laptop sleep) detach sessions instead of killing them; on reconnect the same browser tab reattaches its sessions and replays recent output. Detached sessions are killed after `gateway.terminal.detachedSessionTimeoutSeconds` (default 300; `0` restores kill-on-disconnect).
- `terminal.list` shows attachable sessions, `terminal.attach` adopts one (tmux-style take-over), and `terminal.text` reads a session's recent output as plain text without attaching — an agent/tooling affordance.
</Accordion>
<Accordion title="Debug, logs, update">
- Debug: status/health/models snapshots + event log + manual RPC calls (`status`, `health`, `models.list`).
@@ -224,6 +217,8 @@ The terminal is an unconfined host shell and inherits the Gateway process enviro
Use **Ctrl + backtick** to toggle the dock. The layout supports bottom and right docking, resizes with the browser viewport, and keeps multiple shell tabs. See [Gateway configuration](/gateway/configuration-reference#gateway) for `gateway.terminal.enabled` and the optional `gateway.terminal.shell` override.
Sessions survive disconnects: a page reload, laptop sleep, or network blip detaches the session on the Gateway instead of killing it, and the same browser tab reattaches on reconnect with recent output replayed. Detached sessions are killed after `gateway.terminal.detachedSessionTimeoutSeconds` (default 300 seconds; `0` restores kill-on-disconnect). `terminal.list` shows attachable sessions, `terminal.attach` adopts one (tmux-style take-over), and `terminal.text` reads a session's recent output as plain text without attaching — an agent/tooling affordance.
## Chat behavior
<AccordionGroup>