Architecture

Peekaboo daemon

Peekaboo daemon

Peekaboo's reusable daemon keeps automation services, snapshots, window tracking, and browser MCP state warm across separate CLI invocations. It runs from the same peekaboo binary and is managed with:

peekaboo daemon start
peekaboo daemon status
peekaboo daemon stop

#Runtime ownership

Each long-lived host has one distinct role and socket:

RuntimeSocketLifecycle
Reusable CLI daemon~/Library/Application Support/Peekaboo/daemon.sockAuto-started with idle exit, or manual until stopped.
Peekaboo.app Bridge~/Library/Application Support/Peekaboo/bridge.sockOwned by the GUI app and its TCC grants.
MCP serverstdioOwned by the MCP client; no Bridge listener or published socket.

Normal automation commands prefer the reusable daemon when it is healthy. If it is unavailable, they use a healthy Peekaboo.app host with the required capability before auto-starting a daemon. If no remote host is usable, the command falls back to process-local services when that operation permits it.

If another build owns daemon.sock but lacks a required capability, the current universal binary reuses a deterministic daemon-<build>.sock fallback shared by native and Rosetta invocations. Daemon status prefers the compatible host and warns when another daemon also exists; explicit daemon start safely promotes a compatible auto fallback to manual mode. After executable upgrades, implicit routing rediscovers compatible same-user fallback sockets and validates their daemon identity before reuse. Explicit Bridge paths and custom daemon paths do not scan sibling sockets.

Explicit --bridge-socket or PEEKABOO_BRIDGE_SOCKET selects only that Bridge path and disables daemon auto-start. PEEKABOO_DAEMON_SOCKET changes the reusable daemon path without becoming an explicit Bridge override. --no-remote or PEEKABOO_NO_REMOTE forces local execution.

#Lifecycle modes

  • Auto: launched on demand by a CLI command; exits after inactivity (default 300 seconds).
  • Manual: launched by peekaboo daemon start; remains running until peekaboo daemon stop.

PEEKABOO_DAEMON_IDLE_TIMEOUT_SECONDS changes the auto idle timeout. Accepted requests count as activity, and shutdown waits for accepted connections and operational services to drain.

Standalone mcp daemon mode is intentionally unavailable. peekaboo mcp owns its stdio lifecycle and uses only process-local support such as window tracking.

#Socket ownership

Bridge listeners hold an exclusive lease beside their socket for the listener's full lifetime. Publication is atomic: a host binds and secures a private temporary socket, then publishes it without replacing an owned path. Stale recovery requires proof that no same-user process has the exact UNIX path open; a failed connection alone is not enough.

Shutdown removes a socket only when its filesystem identity still matches the listener that created it. Client connect, read, and write operations are nonblocking and deadline-bound so abandoned connections cannot exhaust the host.

#Legacy migration

Older daemons may still occupy Peekaboo.app's bridge.sock. Current daemon control detects the host kind before acting:

  • Peekaboo.app is never mistaken for a daemon.
  • Auto and manual daemons that advertise conditional stop migrate to daemon.sock while preserving lifecycle mode,
  • polling interval, and idle timeout.

  • Migration defers while requests are active.
  • Older daemons without conditional stop remain on the legacy socket until they exit or are explicitly stopped.

#Status

peekaboo daemon status --json reports:

  • PID, start time, lifecycle mode, and socket path
  • Bridge protocol version, host kind, and advertised operations
  • active requests, last activity, idle timeout, and idle deadline
  • Screen Recording, Accessibility, and Automation permissions
  • snapshot count and last access
  • tracked windows, AX observers, and poll interval
  • browser MCP connection, tool count, and detected browsers

See peekaboo daemon for command flags and Bridge host for transport and security details.