Files
openclaw/docs/mac/peekaboo.md

171 lines
8.2 KiB
Markdown
Raw Normal View History

---
2026-01-04 14:32:47 +00:00
summary: "Plan for integrating Peekaboo automation into Clawdbot via PeekabooBridge (socket-based TCC broker)"
read_when:
2026-01-04 14:32:47 +00:00
- Hosting PeekabooBridge in Clawdbot.app
- Integrating Peekaboo as a submodule
2025-12-13 23:02:04 +00:00
- Changing PeekabooBridge protocol/paths
---
2026-01-04 14:32:47 +00:00
# Peekaboo Bridge in Clawdbot (macOS UI automation broker)
2025-12-13 16:55:41 +00:00
## TL;DR
- **Peekaboo removed its XPC helper** and now exposes privileged automation via a **UNIX domain socket bridge** (`PeekabooBridge` / `PeekabooBridgeHost`, socket name `bridge.sock`).
2026-01-04 14:32:47 +00:00
- Clawdbot integrates by **optionally hosting the same bridge** inside **Clawdbot.app** (user-toggleable). The primary client is the **`peekaboo` CLI** (installed via npm); Clawdbot does not need its own `ui …` CLI surface.
- For **visualizations**, we keep them in **Peekaboo.app** (best UX); Clawdbot stays a thin broker host. No visualizer toggle in Clawdbot.
Non-goals:
2025-12-13 16:55:41 +00:00
- No auto-launching Peekaboo.app.
2026-01-04 14:32:47 +00:00
- No onboarding deep links from the automation endpoint (Clawdbot onboarding already handles permissions).
- No AI provider/agent runtime dependencies in Clawdbot (avoid pulling Tachikoma/MCP into the Clawdbot app/CLI).
2025-12-13 16:55:41 +00:00
## Big refactor (Dec 2025): XPC → Bridge
2026-01-04 14:32:47 +00:00
Peekaboos privileged execution moved from “CLI → XPC helper” to “CLI → socket bridge host”. For Clawdbot this is a win:
2025-12-13 16:55:41 +00:00
- It matches the existing “local socket + codesign checks” approach.
2026-01-04 14:32:47 +00:00
- It lets us piggyback on **either** Peekaboo.apps permissions **or** Clawdbot.apps permissions (whichever is running).
2025-12-13 16:55:41 +00:00
- It avoids “two apps with two TCC bubbles” unless needed.
2026-01-05 21:30:19 +01:00
Reference (Peekaboo submodule): `Peekaboo/docs/bridge-host.md`.
2025-12-13 16:55:41 +00:00
## Architecture
### Processes
- **Bridge hosts** (provide TCC-backed automation):
- **Peekaboo.app** (preferred; also provides visualizations + controls)
2025-12-21 15:56:42 +01:00
- **Claude.app** (secondary; lets `peekaboo` reuse Claude Desktops granted permissions)
2026-01-04 14:32:47 +00:00
- **Clawdbot.app** (secondary; “thin host” only)
2025-12-13 16:55:41 +00:00
- **Bridge clients** (trigger single actions):
2025-12-13 23:02:04 +00:00
- `peekaboo …` (preferred; humans + agents)
2026-01-04 14:32:47 +00:00
- Optional: Clawdbot/Node shells out to `peekaboo` when it needs UI automation/capture
2025-12-13 16:55:41 +00:00
### Host discovery (client-side)
Order is deliberate:
1. Peekaboo.app host (full UX)
2025-12-21 15:56:42 +01:00
2. Claude.app host (piggyback on Claude Desktop permissions)
2026-01-04 14:32:47 +00:00
3. Clawdbot.app host (piggyback on Clawdbot permissions)
2025-12-13 16:55:41 +00:00
Socket paths (convention; exact paths must match Peekaboo):
- Peekaboo: `~/Library/Application Support/Peekaboo/bridge.sock`
2025-12-21 15:56:42 +01:00
- Claude: `~/Library/Application Support/Claude/bridge.sock`
2026-01-04 14:32:47 +00:00
- Clawdbot: `~/Library/Application Support/clawdbot/bridge.sock`
2025-12-13 16:55:41 +00:00
2026-01-04 14:32:47 +00:00
No auto-launch: if a host isnt reachable, the command fails with a clear error (start Peekaboo.app, Claude.app, or Clawdbot.app).
2025-12-13 16:55:41 +00:00
Override (debugging): set `PEEKABOO_BRIDGE_SOCKET=/path/to/bridge.sock`.
### Protocol shape
- **Single request per connection**: connect → write one JSON request → half-close → read one JSON response → close.
- **Timeout**: 10 seconds end-to-end per action (client enforced; host should also enforce per-operation).
- **Errors**: human-readable string by default; structured envelope in `--json`.
## Dependency strategy (submodule)
Integrate Peekaboo via git submodule (nested submodules are OK).
2026-01-04 14:32:47 +00:00
Path in Clawdbot repo:
2025-12-13 16:55:41 +00:00
- `./Peekaboo` (Swabble-style; keep stable so SwiftPM path deps dont churn).
2026-01-04 14:32:47 +00:00
What Clawdbot should use:
2025-12-13 16:55:41 +00:00
- **Client side**: `PeekabooBridge` (socket client + protocol models).
2026-01-04 14:32:47 +00:00
- **Host side (Clawdbot.app)**: `PeekabooBridgeHost` + the minimal Peekaboo services needed to implement operations.
2025-12-13 16:55:41 +00:00
2026-01-04 14:32:47 +00:00
What Clawdbot should *not* embed:
2025-12-13 16:55:41 +00:00
- **Visualizer UI**: keep it in Peekaboo.app for now (toggle + controls live there).
- **XPC**: dont reintroduce helper targets; use the bridge.
## IPC / CLI surface
2026-01-04 14:32:47 +00:00
### No `clawdbot ui …`
We avoid a parallel “Clawdbot UI automation CLI”. Instead:
2025-12-13 23:02:04 +00:00
- `peekaboo` is the user/agent-facing CLI surface for automation and capture.
2026-01-04 14:32:47 +00:00
- Clawdbot.app can host PeekabooBridge as a **thin TCC broker** so Peekaboo can piggyback on Clawdbot permissions when Peekaboo.app isnt running.
2025-12-13 16:55:41 +00:00
2025-12-13 23:02:04 +00:00
### Diagnostics
Use Peekaboos built-in diagnostics to see which host would be used:
- `peekaboo bridge status`
- `peekaboo bridge status --verbose`
- `peekaboo bridge status --json`
### Output format
2025-12-13 23:02:04 +00:00
Peekaboo commands default to human text output. Add `--json` for a structured envelope.
### Timeouts
2025-12-13 23:02:04 +00:00
Default timeout for UI actions: **10 seconds** end-to-end (client enforced; host should also enforce per-operation).
## Coordinate model (multi-display)
Requirement: coordinates are **per screen**, not global.
2025-12-13 16:55:41 +00:00
Standardize for the CLI (agent-friendly): **top-left origin per screen**.
Proposed request shape:
- Requests accept `screenIndex` + `{x, y}` in that screens local coordinate space.
2026-01-04 14:32:47 +00:00
- Clawdbot.app converts to global CG coordinates using `NSScreen.screens[screenIndex].frame.origin`.
- Responses should echo both:
- The resolved `screenIndex`
- The local `{x, y}` and bounds
- Optionally the global `{x, y}` for debugging
Ordering: use `NSScreen.screens` ordering consistently (documented in the CLI help + JSON schema).
## Targeting (per app/window)
2025-12-13 16:55:41 +00:00
Expose window/app targeting in the UI surface (align with Peekaboo targeting):
- frontmost
- by app name / bundle id
- by window title substring
- by (app, index)
2025-12-13 16:55:41 +00:00
2025-12-13 23:02:04 +00:00
Peekaboo CLI targeting (agent-friendly):
2025-12-13 16:55:41 +00:00
- `--bundle-id <id>` for app targeting
2025-12-13 23:02:04 +00:00
- `--window-index <n>` (0-based) for disambiguating within an app when capturing
All “see/click/type/scroll/wait” requests should accept a target (default: frontmost).
## “See” + click packs (Playwright-style)
2025-12-13 16:55:41 +00:00
Behavior stays aligned with Peekaboo:
2025-12-13 23:02:04 +00:00
- `peekaboo see` returns element IDs (e.g. `B1`, `T3`) with bounds/labels.
2025-12-13 16:55:41 +00:00
- Follow-up actions reference those IDs without re-scanning.
2025-12-13 23:02:04 +00:00
`peekaboo see` should:
- capture (optionally targeted) window/screen
2025-12-13 16:55:41 +00:00
- return a screenshot **file path** (default: temp directory)
- return a list of elements (text or JSON)
Snapshot lifecycle requirement:
2025-12-13 16:55:41 +00:00
- Host apps are long-lived, so snapshot state should be **in-memory by default**.
- Snapshot scoping: “implicit snapshot” is **per target bundle id** (reuse last snapshot for that app when snapshot id is omitted).
2025-12-13 16:55:41 +00:00
Practical flow (agent-friendly):
2025-12-13 23:02:04 +00:00
- `peekaboo list apps` / `peekaboo list windows` provide bundle-id context for targeting.
- `peekaboo see --bundle-id X` updates the implicit snapshot for `X`.
- `peekaboo click --bundle-id X --on B1` reuses the most recent snapshot for `X` when `--snapshot-id` is omitted.
2025-12-13 16:55:41 +00:00
## Visualizer integration
Keep visualizations in **Peekaboo.app** for now.
2026-01-04 14:32:47 +00:00
- Clawdbot hosts the bridge, but does not render overlays.
2025-12-13 16:55:41 +00:00
- Any “visualizer enabled/disabled” setting is controlled in Peekaboo.app.
## Screenshots (legacy → Peekaboo takeover)
2026-01-04 14:32:47 +00:00
Clawdbot should not grow a separate screenshot CLI surface.
Migration plan:
2025-12-13 23:02:04 +00:00
- Use `peekaboo capture …` / `peekaboo see …` (returns a file path, default temp directory).
2026-01-04 14:32:47 +00:00
- Once Clawdbot legacy screenshot plumbing is replaced, remove it cleanly (no aliases).
## Permissions behavior
If required permissions are missing:
- return `ok=false` with a short human error message (e.g., “Accessibility permission missing”)
- do not try to open System Settings from the automation endpoint
## Security (socket auth)
2025-12-13 16:55:41 +00:00
Both hosts must enforce:
- filesystem perms on the socket path (owner read/write only)
2025-12-13 16:55:41 +00:00
- server-side caller validation:
- require the callers code signature TeamID to be `Y5PE65HELJ`
- optional bundle-id allowlist for tighter scoping
Debug-only escape hatch (development convenience):
- “allow same-UID callers” means: *skip codesign checks for clients running under the same Unix user*.
- This must be **opt-in**, **DEBUG-only**, and guarded by an env var (Peekaboo uses `PEEKABOO_ALLOW_UNSIGNED_SOCKET_CLIENTS=1`).
## Next integration steps (after this doc)
2025-12-13 16:55:41 +00:00
1. Add Peekaboo as a git submodule (nested submodules OK).
2026-01-04 14:32:47 +00:00
2. Host `PeekabooBridgeHost` inside Clawdbot.app behind a single setting (“Enable Peekaboo Bridge”, default on).
3. Ensure Clawdbot hosts the bridge at `~/Library/Application Support/clawdbot/bridge.sock` and speaks the PeekabooBridge JSON protocol.
4. Validate with `peekaboo bridge status --verbose` that Peekaboo can select Clawdbot as the fallback host (no auto-launch).
2025-12-13 16:55:41 +00:00
5. Keep all protocol decisions aligned with Peekaboo (coordinate system, element IDs, snapshot scoping, error envelopes).