Peekaboo
Use Peekaboo for native macOS capture, UI inspection, and automation. Prefer its
native app, window, Accessibility, and input commands over AppleScript or
osascript whenever Peekaboo exposes the operation.
Binary
- Prefer
~/bin/peekaboo when present; it is Peter's signed local release copy.
- Otherwise use
peekaboo from PATH.
- Check the selected binary before relying on syntax or installed state.
PB="${PEEKABOO_BIN:-$HOME/bin/peekaboo}"
[ -x "$PB" ] || PB="$(command -v peekaboo)"
"$PB" --version
Runtime host and permissions
- Launch
Peekaboo.app without taking focus when a GUI Bridge host is needed:
open -gj -a Peekaboo.
- The app owns its TCC grants and serves
~/Library/Application Support/Peekaboo/bridge.sock. The reusable daemon has
separate permissions and serves daemon.sock; daemon start is not an app
launch.
- Ordinary runtime selection prefers a healthy reusable daemon, then the GUI
host, before starting a daemon. Implicit screen-capture observation, AX-tree
inspection, browser, and snapshot-state commands instead prefer and may
auto-start the current CLI build's exact build-scoped daemon before the GUI
host. Use
bridge status --verbose --json to inspect candidates, but remember
that operation requirements can change their order. When app-held TCC is
required, pass
--bridge-socket "$HOME/Library/Application Support/Peekaboo/bridge.sock"
and verify hostKind: gui instead of assuming the app was selected.
- Check
permissions status --all-sources --json. Grant Screen Recording,
Accessibility, and Event Synthesizing to the process reported as the selected
source, not merely to the invoking terminal.
- Prefer Bridge capture from SSH, LaunchAgent, Codex, and other background
sessions.
--no-remote --capture-engine cg is a local-debug override and can
return wallpaper-only pixels outside the active Aqua session.
- Never run an unsigned or ad-hoc build against saved TCC or Keychain state.
Background-first safety
- Keep the user's foreground app, keyboard focus, and physical cursor untouched
by default. Supply an exact
--app, --pid, --window-id, or fresh snapshot
target and use Peekaboo's background delivery.
- Never add
--foreground merely to make a command work speculatively. Add it
only when the user authorized foreground interaction or the target demonstrably
rejects background delivery.
- Shared-cursor and targetless global input must use explicit foreground mode.
This includes
move, drag, targetless/smooth scroll, and targetless keyboard
input; click --long-press is foreground-only. Foreground mode can interrupt
the user.
- Background type and paste need a resolvable app/PID, a complete inventory with
at most one eligible window, and Event Synthesizing permission. Raw
press
additionally requires an exact window selector or fresh exact-window snapshot;
app/PID-only chords require explicit foreground mode.
- Do not click, type, paste, quit, or otherwise mutate UI unless the user asked
or the target is a controlled test. Re-observe after mutations; never replay
an indeterminate input blindly.
v4 command names
- Inventory:
app list, window list, and screen list; there is no top-level
list command.
- Screenshots and UI inspection:
see --no-elements for pixels, or
see --tree --no-screenshot for AX-only text; do not use the removed image
or inspect-ui CLI commands.
- Keyboard chords:
press; do not use the removed hotkey command.
- Named Accessibility actions:
action; do not use perform-action.
- Coordinate clicks:
click --at x,y; do not use --coords.
Common commands
"$PB" permissions status --all-sources --json
open -gj -a Peekaboo
"$PB" bridge status --verbose --json
"$PB" screen list --json
"$PB" app list --include-hidden --include-background --json
"$PB" window list --app Safari --json
# Screenshot only; observation does not activate the target app.
"$PB" see --no-elements --mode screen --path /tmp/screen.png --json
# Interactive map plus a directly accessible image artifact.
"$PB" see --app Safari --annotate --path /tmp/safari-see.png --json
# AX-only inspection, with no pixel capture or screenshot artifact.
"$PB" see --app Safari --tree --no-screenshot --json
# Use IDs and the snapshot returned by a fresh `see`.
"$PB" click --on "$ELEMENT_ID" --snapshot "$SNAPSHOT_ID" --json
# Generic `action AXPress` requires explicit foreground consent; use the
# dedicated exact-target `click` route above for background button activation.
# Process-targeted background keyboard delivery.
"$PB" type "text" --app TextEdit --json
"$PB" press Return --app TextEdit --window-id 1234 --json
"$PB" paste "text" --app TextEdit --json
"$PB" tools --json
"$PB" tools describe click --json
Click coordinates safely
Screenshot pixels are not automatically click coordinates. click --at uses
logical points. With target flags, coordinates are relative to the resolved
window; without them they are global screen coordinates. Add --global to make
targeted coordinates use the global logical space. Use screen list --json for
display bounds and scale factors when converting Retina pixels.
A background coordinate click requires an explicit snapshot from a fresh
exact-window observation. First resolve the canonical window ID, then observe
that exact window and use both its window ID and returned snapshot ID:
"$PB" window list --app Safari --json
"$PB" see --app Safari --window-id 12345 --path /tmp/safari.png --json
"$PB" click --window-id 12345 --at 20,40 --snapshot "$SNAPSHOT_ID" --json
Peekaboo revalidates the captured PID, process generation, window ID, and bounds
before dispatch. If the exact receipt cannot be established, background input
must fail instead of guessing. Use --foreground only when visible shared-pointer
interaction is intentional. Background right/double click can be dispatched to
an exact route but remains effect-unverifiable; run a fresh see before retrying.
For element work, prefer IDs from a fresh see and pass the snapshot explicitly.
Queries and the implicit latest snapshot are convenient but less deterministic.
After an action changes UI, capture a new snapshot rather than reusing stale IDs.
Workflow
- Resolve
PB, confirm its version, and launch the signed GUI host in the
background when app-held TCC is needed.
- Verify the selected Bridge host and compare permissions across sources.
- Resolve the target with
app list or window list; prefer PID/window ID over
a broad name or title when cleanup or mutation must be exact.
- Observe without focus theft: use
see --no-elements for a screenshot,
ordinary see for element IDs, or see --tree --no-screenshot for AX-only
inspection. Pass --path when the caller needs the image file.
- Interact in the background with an exact target and fresh snapshot. Prefer
action or an element click over coordinate input.
- Verify every mutation with a new
see or a purpose-built read-only command.
- Escalate to explicit
--foreground only for authorized shared cursor/global
input or a confirmed application limitation; never silently promote modes.
- Use
capture live for change-aware capture, capture video for video frame
sampling, tools describe <name> for MCP schemas, and <command> --help for
current CLI syntax.
- Verify image artifacts with
sips -g pixelWidth -g pixelHeight <path> or view
them locally.
Source of truth: ~/Projects/peekaboo/docs/commands/ and the selected binary's
--help output.
1---2name: peekaboo3description: macOS screen capture, accessibility inspection, and background-first app/window/UI automation with Peekaboo v4.4---5
6# Peekaboo
7
8Use Peekaboo for native macOS capture, UI inspection, and automation. Prefer its
9native app, window, Accessibility, and input commands over AppleScript or
10`osascript` whenever Peekaboo exposes the operation.
11
12## Binary
13
14- Prefer `~/bin/peekaboo` when present; it is Peter's signed local release copy.
15- Otherwise use `peekaboo` from `PATH`.
16- Check the selected binary before relying on syntax or installed state.
17
18```bash
19PB="${PEEKABOO_BIN:-$HOME/bin/peekaboo}"
20[ -x "$PB" ] || PB="$(command -v peekaboo)"
21"$PB" --version
22```
23
24## Runtime host and permissions
25
26- Launch `Peekaboo.app` without taking focus when a GUI Bridge host is needed:
27 `open -gj -a Peekaboo`.
28- The app owns its TCC grants and serves
29 `~/Library/Application Support/Peekaboo/bridge.sock`. The reusable daemon has
30 separate permissions and serves `daemon.sock`; `daemon start` is not an app
31 launch.
32- Ordinary runtime selection prefers a healthy reusable daemon, then the GUI
33 host, before starting a daemon. Implicit screen-capture observation, AX-tree
34 inspection, browser, and snapshot-state commands instead prefer and may
35 auto-start the current CLI build's exact build-scoped daemon before the GUI
36 host. Use `bridge status --verbose --json` to inspect candidates, but remember
37 that operation requirements can change their order. When app-held TCC is
38 required, pass
39 `--bridge-socket "$HOME/Library/Application Support/Peekaboo/bridge.sock"`
40 and verify `hostKind: gui` instead of assuming the app was selected.
41- Check `permissions status --all-sources --json`. Grant Screen Recording,
42 Accessibility, and Event Synthesizing to the process reported as the selected
43 source, not merely to the invoking terminal.
44- Prefer Bridge capture from SSH, LaunchAgent, Codex, and other background
45 sessions. `--no-remote --capture-engine cg` is a local-debug override and can
46 return wallpaper-only pixels outside the active Aqua session.
47- Never run an unsigned or ad-hoc build against saved TCC or Keychain state.
48
49## Background-first safety
50
51- Keep the user's foreground app, keyboard focus, and physical cursor untouched
52 by default. Supply an exact `--app`, `--pid`, `--window-id`, or fresh snapshot
53 target and use Peekaboo's background delivery.
54- Never add `--foreground` merely to make a command work speculatively. Add it
55 only when the user authorized foreground interaction or the target demonstrably
56 rejects background delivery.
57- Shared-cursor and targetless global input must use explicit foreground mode.
58 This includes `move`, `drag`, targetless/smooth scroll, and targetless keyboard
59 input; `click --long-press` is foreground-only. Foreground mode can interrupt
60 the user.
61- Background type and paste need a resolvable app/PID, a complete inventory with
62 at most one eligible window, and Event Synthesizing permission. Raw `press`
63 additionally requires an exact window selector or fresh exact-window snapshot;
64 app/PID-only chords require explicit foreground mode.
65- Do not click, type, paste, quit, or otherwise mutate UI unless the user asked
66 or the target is a controlled test. Re-observe after mutations; never replay
67 an indeterminate input blindly.
68
69## v4 command names
70
71- Inventory: `app list`, `window list`, and `screen list`; there is no top-level
72 `list` command.
73- Screenshots and UI inspection: `see --no-elements` for pixels, or
74 `see --tree --no-screenshot` for AX-only text; do not use the removed `image`
75 or `inspect-ui` CLI commands.
76- Keyboard chords: `press`; do not use the removed `hotkey` command.
77- Named Accessibility actions: `action`; do not use `perform-action`.
78- Coordinate clicks: `click --at x,y`; do not use `--coords`.
79
80## Common commands
81
82```bash
83"$PB" permissions status --all-sources --json
84open -gj -a Peekaboo
85"$PB" bridge status --verbose --json
86
87"$PB" screen list --json
88"$PB" app list --include-hidden --include-background --json
89"$PB" window list --app Safari --json
90
91# Screenshot only; observation does not activate the target app.
92"$PB" see --no-elements --mode screen --path /tmp/screen.png --json
93
94# Interactive map plus a directly accessible image artifact.
95"$PB" see --app Safari --annotate --path /tmp/safari-see.png --json
96
97# AX-only inspection, with no pixel capture or screenshot artifact.
98"$PB" see --app Safari --tree --no-screenshot --json
99
100# Use IDs and the snapshot returned by a fresh `see`.
101"$PB" click --on "$ELEMENT_ID" --snapshot "$SNAPSHOT_ID" --json
102# Generic `action AXPress` requires explicit foreground consent; use the
103# dedicated exact-target `click` route above for background button activation.
104
105# Process-targeted background keyboard delivery.
106"$PB" type "text" --app TextEdit --json
107"$PB" press Return --app TextEdit --window-id 1234 --json
108"$PB" paste "text" --app TextEdit --json
109
110"$PB" tools --json
111"$PB" tools describe click --json
112```
113
114## Click coordinates safely
115
116Screenshot pixels are not automatically click coordinates. `click --at` uses
117logical points. With target flags, coordinates are relative to the resolved
118window; without them they are global screen coordinates. Add `--global` to make
119targeted coordinates use the global logical space. Use `screen list --json` for
120display bounds and scale factors when converting Retina pixels.
121
122A background coordinate click requires an explicit snapshot from a fresh
123exact-window observation. First resolve the canonical window ID, then observe
124that exact window and use both its window ID and returned snapshot ID:
125
126```bash
127"$PB" window list --app Safari --json
128"$PB" see --app Safari --window-id 12345 --path /tmp/safari.png --json
129"$PB" click --window-id 12345 --at 20,40 --snapshot "$SNAPSHOT_ID" --json
130```
131
132Peekaboo revalidates the captured PID, process generation, window ID, and bounds
133before dispatch. If the exact receipt cannot be established, background input
134must fail instead of guessing. Use `--foreground` only when visible shared-pointer
135interaction is intentional. Background right/double click can be dispatched to
136an exact route but remains effect-unverifiable; run a fresh `see` before retrying.
137
138For element work, prefer IDs from a fresh `see` and pass the snapshot explicitly.
139Queries and the implicit latest snapshot are convenient but less deterministic.
140After an action changes UI, capture a new snapshot rather than reusing stale IDs.
141
142## Workflow
143
1441. Resolve `PB`, confirm its version, and launch the signed GUI host in the
145 background when app-held TCC is needed.
1462. Verify the selected Bridge host and compare permissions across sources.
1473. Resolve the target with `app list` or `window list`; prefer PID/window ID over
148 a broad name or title when cleanup or mutation must be exact.
1494. Observe without focus theft: use `see --no-elements` for a screenshot,
150 ordinary `see` for element IDs, or `see --tree --no-screenshot` for AX-only
151 inspection. Pass `--path` when the caller needs the image file.
1525. Interact in the background with an exact target and fresh snapshot. Prefer
153 `action` or an element click over coordinate input.
1546. Verify every mutation with a new `see` or a purpose-built read-only command.
1557. Escalate to explicit `--foreground` only for authorized shared cursor/global
156 input or a confirmed application limitation; never silently promote modes.
1578. Use `capture live` for change-aware capture, `capture video` for video frame
158 sampling, `tools describe <name>` for MCP schemas, and `<command> --help` for
159 current CLI syntax.
1609. Verify image artifacts with `sips -g pixelWidth -g pixelHeight <path>` or view
161 them locally.
162
163Source of truth: `~/Projects/peekaboo/docs/commands/` and the selected binary's
164`--help` output.