diff --git a/docs/concepts/architecture.md b/docs/concepts/architecture.md index 722f3b4a8..9e9309b2c 100644 --- a/docs/concepts/architecture.md +++ b/docs/concepts/architecture.md @@ -5,7 +5,7 @@ read_when: --- # Gateway architecture -Last updated: 2026-01-19 +Last updated: 2026-01-22 ## Overview @@ -34,7 +34,8 @@ Last updated: 2026-01-19 ### Nodes (macOS / iOS / Android / headless) - Connect to the **same WS server** with `role: node`. -- Pair with the Gateway to receive a token. +- Provide a device identity in `connect`; pairing is **device‑based** (role `node`) and + approval lives in the device pairing store. - Expose commands like `canvas.*`, `camera.*`, `screen.record`, `location.get`. Protocol details: diff --git a/docs/concepts/presence.md b/docs/concepts/presence.md index a9c6e2003..4a1694657 100644 --- a/docs/concepts/presence.md +++ b/docs/concepts/presence.md @@ -52,10 +52,10 @@ Instances list, `client.mode === "cli"` is **not** turned into a presence entry. Clients can send richer periodic beacons via the `system-event` method. The mac app uses this to report host name, IP, and `lastInputSeconds`. -### 4) Node bridge beacons +### 4) Node connects (role: node) -When a node bridge connection authenticates, the Gateway emits a presence entry -for that node and refreshes it periodically so it doesn’t expire. +When a node connects over the Gateway WebSocket with `role: node`, the Gateway +upserts a presence entry for that node (same flow as other WS clients). ## Merge + dedupe rules (why `instanceId` matters) diff --git a/docs/gateway/pairing.md b/docs/gateway/pairing.md index 8acfc4846..2d9626418 100644 --- a/docs/gateway/pairing.md +++ b/docs/gateway/pairing.md @@ -11,6 +11,10 @@ In Gateway-owned pairing, the **Gateway** is the source of truth for which nodes are allowed to join. UIs (macOS app, future clients) are just frontends that approve or reject pending requests. +**Important:** WS nodes use **device pairing** (role `node`) during `connect`. +`node.pair.*` is a separate pairing store and does **not** gate the WS handshake. +Only clients that explicitly call `node.pair.*` use this flow. + ## Concepts - **Pending request**: a node asked to join; requires approval. diff --git a/docs/nodes/index.md b/docs/nodes/index.md index 6bb48a3e9..80e1015fc 100644 --- a/docs/nodes/index.md +++ b/docs/nodes/index.md @@ -8,9 +8,11 @@ read_when: # Nodes -A **node** is a companion device (iOS/Android today) that connects to the Gateway over the **Bridge** and exposes a command surface (e.g. `canvas.*`, `camera.*`, `system.*`) via `node.invoke`. Bridge protocol details: [Bridge protocol](/gateway/bridge-protocol). +A **node** is a companion device (macOS/iOS/Android/headless) that connects to the Gateway **WebSocket** (same port as operators) with `role: "node"` and exposes a command surface (e.g. `canvas.*`, `camera.*`, `system.*`) via `node.invoke`. Protocol details: [Gateway protocol](/gateway/protocol). -macOS can also run in **node mode**: the menubar app connects to the Gateway’s bridge and exposes its local canvas/camera commands as a node (so `clawdbot nodes …` works against this Mac). +Legacy transport: [Bridge protocol](/gateway/bridge-protocol) (TCP JSONL; for older node clients only). + +macOS can also run in **node mode**: the menubar app connects to the Gateway’s WS server and exposes its local canvas/camera commands as a node (so `clawdbot nodes …` works against this Mac). Notes: - Nodes are **peripherals**, not gateways. They don’t run the gateway service. @@ -18,21 +20,23 @@ Notes: ## Pairing + status -Pairing is gateway-owned and approval-based. See [Gateway pairing](/gateway/pairing) for the full flow. +**WS nodes use device pairing.** Nodes present a device identity during `connect`; the Gateway +creates a device pairing request for `role: node`. Approve via the devices CLI (or UI). Quick CLI: ```bash -clawdbot nodes pending -clawdbot nodes approve -clawdbot nodes reject +clawdbot devices list +clawdbot devices approve +clawdbot devices reject clawdbot nodes status clawdbot nodes describe --node -clawdbot nodes rename --node --name "Kitchen iPad" ``` Notes: -- `nodes rename` stores a display name override in the gateway pairing store. +- `nodes status` marks a node as **paired** when its device pairing role includes `node`. +- `node.pair.*` (CLI: `clawdbot nodes pending/approve/reject`) is a separate gateway-owned + node pairing store; it does **not** gate the WS `connect` handshake. ## Remote node host (system.run) @@ -275,7 +279,7 @@ Nodes may include a `permissions` map in `node.list` / `node.describe`, keyed by ## Headless node host (cross-platform) Clawdbot can run a **headless node host** (no UI) that connects to the Gateway -bridge and exposes `system.run` / `system.which`. This is useful on Linux/Windows +WebSocket and exposes `system.run` / `system.which`. This is useful on Linux/Windows or for running a minimal node alongside a server. Start it: @@ -292,9 +296,9 @@ Notes: - On macOS, the headless node host prefers the companion app exec host when reachable and falls back to local execution if the app is unavailable. Set `CLAWDBOT_NODE_EXEC_HOST=app` to require the app, or `CLAWDBOT_NODE_EXEC_FALLBACK=0` to disable fallback. -- Add `--tls` / `--tls-fingerprint` when the bridge requires TLS. +- Add `--tls` / `--tls-fingerprint` when the Gateway WS uses TLS. ## Mac node mode -- The macOS menubar app connects to the Gateway bridge as a node (so `clawdbot nodes …` works against this Mac). -- In remote mode, the app opens an SSH tunnel for the bridge port and connects to `localhost`. +- The macOS menubar app connects to the Gateway WS server as a node (so `clawdbot nodes …` works against this Mac). +- In remote mode, the app opens an SSH tunnel for the Gateway port and connects to `localhost`. diff --git a/docs/start/pairing.md b/docs/start/pairing.md index 4c811d580..ce5bf23f2 100644 --- a/docs/start/pairing.md +++ b/docs/start/pairing.md @@ -45,27 +45,29 @@ Stored under `~/.clawdbot/credentials/`: Treat these as sensitive (they gate access to your assistant). -## 2) Node pairing (iOS/Android nodes joining the gateway) +## 2) Node device pairing (iOS/Android/macOS/headless nodes) -Nodes (iOS/Android, future hardware, etc.) connect to the Gateway and request to join. -The Gateway keeps an authoritative allowlist; new nodes require explicit approve/reject. +Nodes connect to the Gateway as **devices** with `role: node`. The Gateway +creates a device pairing request that must be approved. -### Approve a node +### Approve a node device ```bash -clawdbot nodes pending -clawdbot nodes approve +clawdbot devices list +clawdbot devices approve +clawdbot devices reject ``` ### Where the state lives -Stored under `~/.clawdbot/nodes/`: +Stored under `~/.clawdbot/devices/`: - `pending.json` (short-lived; pending requests expire) -- `paired.json` (paired nodes + tokens) +- `paired.json` (paired devices + tokens) -### Details +### Notes -Full protocol + design notes: [Gateway pairing](/gateway/pairing) +- The legacy `node.pair.*` API (CLI: `clawdbot nodes pending/approve`) is a + separate gateway-owned pairing store. WS nodes still require device pairing. ## Related docs