feat(mac): manage node service in remote mode
This commit is contained in:
@@ -5,9 +5,7 @@ read_when:
|
||||
---
|
||||
# Clawdbot macOS IPC architecture
|
||||
|
||||
**Current model:** there is **no local control socket** and no `clawdbot-mac` CLI. All agent actions go through the Gateway WebSocket and `node.invoke`. UI automation still uses PeekabooBridge.
|
||||
|
||||
**Planned model:** add a local Unix socket between the **node service** and the **macOS app**. The app owns `system.run` (UI/TCC context); the node service forwards exec requests over IPC.
|
||||
**Current model:** a local Unix socket connects the **node service** to the **macOS app** for exec approvals + `system.run`. There is no `clawdbot-mac` CLI; agent actions still flow through the Gateway WebSocket and `node.invoke`. UI automation uses PeekabooBridge.
|
||||
|
||||
## Goals
|
||||
- Single GUI app instance that owns all TCC-facing work (notifications, screen recording, mic, speech, AppleScript).
|
||||
@@ -15,11 +13,11 @@ read_when:
|
||||
- Predictable permissions: always the same signed bundle ID, launched by launchd, so TCC grants stick.
|
||||
|
||||
## How it works
|
||||
### Gateway + node bridge (current)
|
||||
### Gateway + node bridge
|
||||
- The app runs the Gateway (local mode) and connects to it as a node.
|
||||
- Agent actions are performed via `node.invoke` (e.g. `system.run`, `system.notify`, `canvas.*`).
|
||||
|
||||
### Node service + app IPC (planned)
|
||||
### Node service + app IPC
|
||||
- A headless node service connects to the Gateway bridge.
|
||||
- `system.run` requests are forwarded to the macOS app over a local Unix socket.
|
||||
- The app performs the exec in UI context, prompts if needed, and returns output.
|
||||
@@ -38,10 +36,6 @@ Agent -> Gateway -> Bridge -> Node Service (TS)
|
||||
- Security: bridge hosts require an allowed TeamID; DEBUG-only same-UID escape hatch is guarded by `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1` (Peekaboo convention).
|
||||
- See: [PeekabooBridge usage](/platforms/mac/peekaboo) for details.
|
||||
|
||||
### Mach/XPC
|
||||
- Not required for automation; `node.invoke` + PeekabooBridge cover current needs.
|
||||
- Planned IPC keeps Unix sockets (no XPC helper).
|
||||
|
||||
## Operational flows
|
||||
- Restart/rebuild: `SIGN_IDENTITY="Apple Development: <Developer Name> (<TEAMID>)" scripts/restart-mac.sh`
|
||||
- Kills existing instances
|
||||
@@ -54,4 +48,4 @@ Agent -> Gateway -> Bridge -> Node Service (TS)
|
||||
- PeekabooBridge: `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1` (DEBUG-only) may allow same-UID callers for local development.
|
||||
- All communication remains local-only; no network sockets are exposed.
|
||||
- TCC prompts originate only from the GUI app bundle; keep the signed bundle ID stable across rebuilds.
|
||||
- Planned IPC hardening: socket mode `0600`, token, peer-UID checks, HMAC challenge/response, short TTL.
|
||||
- IPC hardening: socket mode `0600`, token, peer-UID checks, HMAC challenge/response, short TTL.
|
||||
|
||||
@@ -17,19 +17,17 @@ capabilities to the agent as a node.
|
||||
Speech Recognition, Automation/AppleScript).
|
||||
- Runs or connects to the Gateway (local or remote).
|
||||
- Exposes macOS‑only tools (Canvas, Camera, Screen Recording, `system.run`).
|
||||
- Starts the local node host service in **remote** mode (launchd), and stops it in **local** mode.
|
||||
- Optionally hosts **PeekabooBridge** for UI automation.
|
||||
- Installs the global CLI (`clawdbot`) via npm/pnpm on request (bun not recommended for the Gateway runtime).
|
||||
|
||||
Planned:
|
||||
- Run a headless **node service** locally (launchd).
|
||||
- Keep `system.run` in the app (UI/TCC context), with the node service forwarding via IPC.
|
||||
|
||||
## Local vs remote mode
|
||||
|
||||
- **Local** (default): the app attaches to a running local Gateway if present;
|
||||
otherwise it enables the launchd service via `clawdbot daemon`.
|
||||
- **Remote**: the app connects to a Gateway over SSH/Tailscale and never starts
|
||||
a local process.
|
||||
The app starts the local **node host service** so the remote Gateway can reach this Mac.
|
||||
The app does not spawn the Gateway as a child process.
|
||||
|
||||
## Launchd control
|
||||
@@ -58,9 +56,9 @@ The macOS app presents itself as a node. Common commands:
|
||||
|
||||
The node reports a `permissions` map so agents can decide what’s allowed.
|
||||
|
||||
Planned split:
|
||||
- Node service advertises the node surface to the Gateway.
|
||||
- macOS app performs `system.run` in UI context over IPC.
|
||||
Node service + app IPC:
|
||||
- When the headless node service is running (remote mode), it connects to the Gateway bridge.
|
||||
- `system.run` executes in the macOS app (UI/TCC context) over a local Unix socket; prompts + output stay in-app.
|
||||
|
||||
Diagram (SCI):
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user