Skip to content
Development
Skill

/peekaboo-driver

Use this skill when driving native-UI AX-tree snapshots and screenshots via steipete/peekaboo (MIT, macOS-only). Dispatched by `skills/test-runner/` to capture native-UI AX-tree snapshots + screenshots on macOS 15+ targets, and exits with deterministic JSON output the

From plugin
session-orchestrator
5144 skills14 agents26 commands10 hooks
+1
Install
$ npx -y skills add Kanevry/session-orchestrator --skill peekaboo-driver --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/peekaboo-driver

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use this skill when driving native-UI AX-tree snapshots and screenshots via steipete/peekaboo (MIT, macOS-only). Dispatched by `skills/test-runner/` to capture native-UI AX-tree snapshots + screenshots on macOS 15+ targets, and exits with deterministic JSON output the

SKILL.md

peekaboo-driver.SKILL.md
name: peekaboo-driver
user-invocable: false
tags: [test, driver, macos, peekaboo]
model: haiku
model-preference: sonnet
description: Use this skill when driving native-UI AX-tree snapshots and screenshots via steipete/peekaboo (MIT, macOS-only). Dispatched by `skills/test-runner/` to capture native-UI AX-tree snapshots + screenshots on macOS 15+ targets, and exits with deterministic JSON output the orchestrator can parse.

Peekaboo Driver Skill

Soul

Before anything else, read and internalize `soul.md` in this skill directory. It defines WHO you are — a thin executor, not an orchestrator. Every action in this session should reflect that identity.

Phase 0: Bootstrap Gate

Read `skills/_shared/bootstrap-gate.md` and execute the gate check. If GATE_CLOSED, invoke `skills/bootstrap/SKILL.md` and wait for completion. If GATE_OPEN, continue.

<HARD-GATE> This driver is macOS-only. It wraps the `peekaboo` binary (steipete/peekaboo, MIT). It does NOT use any MCP adapter layer. The platform gate in Phase 1 is mandatory pre-flight. </HARD-GATE>

Package Note — Installation & Binary Name

Both install paths surface the same `peekaboo` binary at the same version:

| Install path | Command | Notes | |---|---|---| | Homebrew (preferred) | `brew install steipete/tap/peekaboo` | Installs to `/opt/homebrew/bin/peekaboo` | | npm / npx (CI-friendly) | `npx -y @steipete/peekaboo` | Requires Node 22+. No global install needed. |

The GitHub repository is `github.com/steipete/peekaboo`. Older links may surface `openclaw/Peekaboo` — both redirect to the same canonical repo and binary.

**Canonical name verification:** Always verify a package name via `brew info` or `npm view` before documenting. The playwright-driver PRD originally referenced `@playwright/cli@0.1.13` (an unrelated stub) instead of canonical `playwright@1.60.0`. Verify `@steipete/peekaboo` against any look-alike before trusting an install path.

Install

brew install steipete/tap/peekaboo    # Option A — Homebrew
npx -y @steipete/peekaboo --version   # Option B — npx (CI)
peekaboo --version                    # Verify: expect 3.1.x

Baseline: **v3.1.0**. Latest at time of writing: **v3.1.2** (May 11 2026).

Phase 1: Platform & Version Gate

**Mandatory pre-flight. Run before any other peekaboo command.**

[ "$(uname -s)" != "Darwin" ] && { echo "peekaboo-driver: non-darwin, skipping." >&2; exit 0; }
MACOS_MAJOR="$(sw_vers -productVersion | cut -d. -f1)"
[ "$MACOS_MAJOR" -lt 15 ] && { echo "peekaboo-driver: requires macOS 15+, skipping." >&2; exit 0; }
command -v peekaboo >/dev/null 2>&1 || { echo "peekaboo-driver: binary not found — install first." >&2; exit 2; }

Exit 0 (non-fatal skip) on non-darwin or macOS < 15.0 (Sequoia). Exit 2 (fatal) only when the binary is missing on an otherwise-compatible system.

Phase 2: Permission Probe

PERMS_JSON="$(peekaboo permissions status --json)"
MISSING="$(echo "$PERMS_JSON" | jq -r '.data.permissions[] | select(.isRequired == true and .isGranted == false) | .name')"
[ -n "$MISSING" ] && echo "peekaboo-driver: missing required permissions: ${MISSING}" >&2

The `permissions status --json` schema (verified 2026-05-14):

{
  "success": true,
  "data": {
    "permissions": [
      { "name": "Screen Recording",   "isRequired": true,  "isGranted": false, "grantInstructions": "System Settings > Privacy & Security > Screen Recording" },
      { "name": "Accessibility",      "isRequired": true,  "isGranted": false, "grantInstructions": "System Settings > Privacy & Security > Accessibility" },
      { "name": "Event Synthesizing", "isRequired": false, "isGranted": false, "grantInstructions": "System Settings > Privacy & Security > Accessibility" }
    ],
    "source": "local"
  }
}

Required: **Screen Recording** (hard), **Accessibility** (hard). Optional: **Event Synthesizing**. Permission failures are never silent. Route to Phase 3 when any required permission is not granted.

Phase 3: Permission Remediation

Surface missing required permissions via AskUserQuestion (per `ask-via-tool.md` AUQ-003). Do not auto-grant — macOS requires manual user action in System Settings.

If `$MISSING` from Phase 2 contains more than one permission, present **one AUQ per missing permission** in the order they appear. The user can grant or skip each independently; the driver re-checks after each grant (one full Phase 2 sweep per round).

The loop executes once per permission in `$MISSING`, exiting after Phase 3 permission re-probe shows all required permissions granted or the user selects Skip for the current permission.

For each `${PERM_NAME}` in `$MISSING`:

AskUserQuestion({
  questions: [{
    question: `${PERM_NAME} is not granted. Enable the terminal entry under System Settings > Privacy & Security, then confirm.`,
    header: "Zugriff",
    options: [
      { label: "Granted — continue (Recommended)", description: "I enabled the terminal entry in that pane — the driver then checks again and carries on if the grant took effect." },
      { label: "Skip this run", description: "Abort peekaboo-driver. Test-runner will record a framework-error finding." }
    ],
    multiSelect: false
  }]
})

After confirmation, re-probe (`$MISSING` Phase 2 sweep). If still not granted or user selects Skip for any permission, exit 2 (fatal). Do NOT attempt any capture without required permissions — the binary will fail ungracefully.

Canonical Usage

The orchestrator (`skills/test-runner/`) dispatches via Bash. Inputs via environment variables: `RUN_ID`, `RUN_DIR`, `TARGET` (app name), `PROFILE`.

# Validate TARGET (app name) — alphanumeric, spaces, dots, hyphens only
# (Prevents shell injection per SEC-PD-MED-1 + path traversal per SEC-PD-LOW-1)
[[ "${TARGET}" =~ ^[A-Za-z0-9\ \.\-]+$ ]] || { echo "peekaboo-driver: invalid TARGET (must match ^[A-Za-z0-9 .-]+$)" >&2; exit 2; }
TARGET_SAFE="${TARGET//[^A-Za-z0-9_.-]/_}"   # filename-safe variant
Read more
Ships withsession-orchestrator

Give your agents a working rhythm. You type three commands: /session reads your repository, your open issues and the last session, proposes what to work on, and waits for your correction.

Get the whole plugin

Other skills on session-orchestrator.