diff --git a/docs/concepts/session-attachment.md b/docs/concepts/session-attachment.md new file mode 100644 index 000000000000..a7df837ae0c1 --- /dev/null +++ b/docs/concepts/session-attachment.md @@ -0,0 +1,190 @@ +--- +doc-schema-version: 1 +summary: "How Gateway-owned sessions continue across the Control UI, terminal, CLI, mobile clients, and coding harnesses" +read_when: + - You want to continue a Control UI session in the terminal + - You want to attach a coding harness to an existing session + - You are troubleshooting session links, remote pairing, or attachment failures +title: "Session synchronization and attachment" +--- + +OpenClaw keeps shared session state on the Gateway. The Control UI, mobile +clients, ACP, `openclaw tui `, and `openclaw attach ` project +that Gateway-owned state instead of keeping independent session copies. This +lets you open one session in several clients without exporting or copying its +transcript. + +Use `openclaw tui` when you want to continue the conversation in a terminal. +Use `openclaw attach` when you want a coding harness beside the session with a +temporary, session-scoped MCP grant. + +Embedded local mode is separate: `openclaw tui --local`, `openclaw chat`, and +`openclaw terminal` use the local agent runtime and cannot accept a session +target. See the [TUI CLI reference](/cli/tui#notes) for local-mode behavior. + +## One Gateway, many clients + +The Gateway owns session rows, transcript history, routing metadata, and active +runs. Clients select a session key and read or update that same state through the +Gateway protocol. A mobile node remains a peripheral connected to the Gateway; +it does not become a second session owner. + +Most agent session keys use this shape: + +```text +agent:: +``` + +The `` portion may be a simple name, several colon-delimited routing +segments, or a value ending in a UUID. A Gateway configured with global session +scope uses the canonical `global` session instead. When an agent-only URL is +opened against a global-scope Gateway, the CLI asks the Gateway for its session +scope and resolves the URL to that canonical global session. + +See [Session management](/concepts/session) for routing, isolation, lifecycle, +and storage details. + +## Session URLs and short links + +Control UI chat and dashboard links share this route grammar: + +```text +/{chat|dashboard}/ +/{chat|dashboard}//- +/{chat|dashboard}// +``` + +A configured Control UI base path prefixes these routes. The agent-only form +opens that agent's main projection. Literal forms encode the colon-delimited +session key after `agent::` as path segments. + +For a key whose rest ends in a UUID, the shareable short form uses 8 to 32 +lowercase hexadecimal characters from the start of that UUID, with UUID dashes +removed. The short ID is authoritative. The display-name slug is decorative +unless two sessions share the same prefix, in which case one exact slug match +breaks the tie. For CLI short-link targets, the agent segment is also decorative: +the Gateway resolves the short ID without constraining it to that URL agent. + +The Gateway method `sessions.resolve` owns resolution for exact keys, raw +session IDs, labels, and short IDs. Discovery selectors are filtered by the +calling client's session visibility. Short-ID ambiguity results contain at most +ten recent candidates, so clients can ask you for a longer prefix without +guessing. See [Control UI URLs](/web/urls) for the complete literal encoding and +stability contract. + +### Current and older Gateways + +Current Gateways resolve short references at the session store owner. The +Control UI and CLI then use the returned canonical key. + +An older Gateway may reject the additive `shortId` selector. The Control UI can +fall back to its older bounded list search, scanning at most five pages. The CLI +does not recreate that paging policy: it tells you to copy the full session key +from that Gateway's Control UI or upgrade the Gateway. + +## Choose how to continue + +The CLI accepts three target syntaxes: + +- A complete Control UI URL, such as + `https://claw.example.com/dashboard/main/deploy-monitor-6db92d48`. +- Gateway shorthand, such as + `claw.example.com/main/deploy-monitor-6db92d48`. +- A bare short reference or full key, such as `deploy-monitor-6db92d48` or + `agent:main:telegram:12345`. Bare references use the configured or default + Gateway. + +Session URLs must not contain credentials. Pass `--token` or `--password` +separately when first pairing with a Gateway origin. + +### Continue in the terminal + +For Gateway-backed continuation, pass the URL or reference to `openclaw tui`: + +```bash +openclaw tui https://claw.example.com/dashboard/main/deploy-monitor-6db92d48 +openclaw tui deploy-monitor-6db92d48 +``` + +You can also paste a complete session URL directly at the CLI root: + +```bash +openclaw https://claw.example.com/dashboard/main/deploy-monitor-6db92d48 +``` + +This opens the TUI on the canonical session key returned by the Gateway. It does +not clone the transcript or create a new session. See [TUI](/cli/tui) for target +conflicts, supported bare-URL options, and examples. + +### Attach a coding harness + +Pass the same URL or reference to `openclaw attach`: + +```bash +openclaw attach https://claw.example.com/dashboard/main/deploy-monitor-6db92d48 +openclaw attach deploy-monitor-6db92d48 +``` + +The Gateway resolves the session first, then mints a temporary grant scoped to +that session and launches the coding harness with a strict MCP configuration. +The bearer token travels in the child environment instead of argv. A normal +launch revokes the grant when the harness exits; `--print-config` leaves it live +until its TTL expires. See [Attach CLI](/cli/attach) for grant lifetime and +launch options. + +## Pair once per Gateway origin + +A URL or gateway shorthand authoritatively selects one normalized Gateway +origin. OpenClaw never reuses configured credentials or a stored device token +from another origin for that target. + +On first contact: + +1. Run the TUI or attach command with `--token` or `--password` once. +2. Open **Settings > Devices** in that Gateway's Control UI and approve the + pending request. On the Gateway host, you can instead preview the newest + request with `openclaw devices approve --latest`, verify it, and run the + printed `openclaw devices approve ` command. +3. Retry the original command. OpenClaw stores the issued operator device token + in SQLite under that exact normalized Gateway origin. +4. Later connections to the same origin can use the stored device token. An + explicit `--token` or `--password` always wins for the entire connection. + +Revoke or remove the device from the same Gateway's **Devices** page when that +client should no longer connect. Tokens do not cross origins. Read-only probes +through an SSH tunnel also suppress stored device auth because the loopback +transport does not identify the remote origin; explicit credentials still work. + +See [Devices](/cli/devices), [Remote access](/gateway/remote), and +[Gateway security](/gateway/security) for approval, rotation, revocation, and +network guidance. + +## Failure taxonomy + +Gateway connection failures use one structured-first classifier. Older +Gateways still work through a bounded text fallback, so health, status, and the +TUI give the same category and recovery guidance. + +| Failure or kind | What it means | What to do | +| ---------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Older Gateway short-link rejection | The Gateway does not accept `shortId` in `sessions.resolve`. | Copy the full session key from that Gateway's Control UI, or upgrade the Gateway. | +| Session missing | The selected Gateway cannot find that key or short ID. | For the configured Gateway, run `openclaw sessions list`. For a URL target, choose the session in that Gateway's Control UI. | +| Session reference ambiguous | More than one visible session shares the prefix and the slug did not select one. | Use one of the longer ID prefixes shown by the CLI, or copy the full key. | +| `pairing-required` | The device is new or an existing device needs a role, scope, or metadata approval. | Approve the pending request in **Settings > Devices**, or preview it with `openclaw devices approve --latest` and run the printed exact-ID command, then retry. | +| `device-identity-required` | The Gateway requires a signed device identity for this connection. | Use a current OpenClaw client, let it create its device identity, and complete pairing. | +| `scope-mismatch` | The stored device token is valid but lacks the requested operator scope. | Review `openclaw devices list`, approve the pending scope upgrade, and reconnect. | +| `auth-rejected` | An explicit shared credential is wrong, or a paired-device token was revoked or rotated. | Verify explicit Gateway auth. For a stale device token, rotate it with `openclaw devices rotate --device --role operator` or pair again. | +| `rate-limited` | Too many failed authentication attempts caused a temporary lockout. | Wait for the lockout to expire, then retry. Do not rotate credentials merely because the Gateway is rate-limited. | +| `gateway-rejected` | The Gateway returned another structured rejection, such as a protocol mismatch. | Follow the error details. For version skew, update the older client or Gateway before retrying. | +| `unreachable` | The selected origin cannot be reached. | Check the Gateway process and route. For a `*.ts.net` host, connect Tailscale and confirm tailnet reachability; for SSH, confirm the tunnel is running. | +| TLS fingerprint mismatch | The presented certificate does not match the configured or explicit pin. | Verify the certificate and expected fingerprint. Change the pin only after confirming the Gateway identity. | + +## Related pages + +- [Session management](/concepts/session) +- [Control UI URLs](/web/urls) +- [TUI](/cli/tui) +- [Attach CLI](/cli/attach) +- [Devices](/cli/devices) +- [Remote access](/gateway/remote) +- [Gateway security](/gateway/security) diff --git a/docs/concepts/session.md b/docs/concepts/session.md index d58f46db9a10..cd10f46bf3b9 100644 --- a/docs/concepts/session.md +++ b/docs/concepts/session.md @@ -11,6 +11,9 @@ OpenClaw routes every inbound message to a **session** based on where it came from: DMs, group chats, cron jobs, etc. All session state is owned by the **gateway**; UI clients query the gateway for session data. +To continue the same Gateway-owned session in the Control UI, terminal, or a +coding harness, see [Session synchronization and attachment](/concepts/session-attachment). + For the personal-agent default — one rolling conversation shared by all your DM channels, with group activity and background work flowing into it — see [The main session](/concepts/main-session). diff --git a/docs/docs.json b/docs/docs.json index 3ce54afb83a4..409f0c9bbccc 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -1247,6 +1247,7 @@ "concepts/main-session", "concepts/multi-user", "concepts/session", + "concepts/session-attachment", "concepts/session-search", "concepts/channel-docking", "concepts/session-pruning", diff --git a/docs/gateway/remote.md b/docs/gateway/remote.md index 4667e96ac4f6..f14cad7f4e4c 100644 --- a/docs/gateway/remote.md +++ b/docs/gateway/remote.md @@ -10,6 +10,9 @@ OpenClaw runs one Gateway (the master) on a host and connects every client to it - **Operators** (you, or the macOS app): direct LAN/Tailnet WebSocket is simplest when the Gateway is reachable; SSH tunneling is the universal fallback. - **Nodes** (iOS/Android and other devices): connect to the Gateway **WebSocket** (LAN/tailnet or SSH tunnel). +Remote clients can continue the same Gateway-owned conversation by URL or short +reference. See [Session synchronization and attachment](/concepts/session-attachment). + ## The core idea The Gateway WebSocket binds to **loopback** by default, on port `18789` (`gateway.port`). For remote use, either expose it through Tailscale Serve / a trusted LAN-Tailnet bind, or forward the loopback port over SSH. diff --git a/docs/web/urls.md b/docs/web/urls.md index 4b1137d2efb0..fbb1879aa8d3 100644 --- a/docs/web/urls.md +++ b/docs/web/urls.md @@ -110,6 +110,9 @@ back to the prior bounded list search, scanning at most five pages of results. It likewise reports an incomplete search instead of guessing when that fallback cannot prove uniqueness. +To continue one of these links in the terminal or attach a coding harness, see +[Session synchronization and attachment](/concepts/session-attachment). + Canonical links do not use `?session=` or `?face=`. Released links such as `/chat?session=` are accepted only at the application boundary as a migration aid and immediately rewritten, without adding browser history, to the