Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add commands/openclaw/peekaboo/appgit clone --depth 1 https://github.com/openclaw/PeekabooWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.02528 |
| Opus 5 | $0.00000 | $0.01264 |
| Sonnet 5 | $0.00000 | $0.00506 |
| Haiku 4.5 | $0.00000 | $0.00253 |
Grade A, and why
app scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 86 lines — stays where its author put it; the contents beside it link to each section on GitHub.
peekaboo app
app bundles every app-management primitive Peekaboo exposes: launching, quitting, hiding, relaunching, switching/focusing, and listing processes. Commands run through the selected Peekaboo runtime host so they share its macOS session, LaunchServices, and AX view instead of the caller's sandbox.
Subcommands
| Name | Purpose | Key flags |
|---|---|---|
launch |
Verify an exact running app in the background, or explicitly start/open it in the foreground. | --bundle-id, `--open <path |
quit |
Quit one app or all regular apps (with optional exclusions). | Positional <app> or --app, --pid, --expected-process-start-identity, --all, --except "Finder,Terminal", --force. |
relaunch |
Quit + relaunch the same app with explicit foreground consent. | Positional <app> or --app, or --pid; --wait, --force, --wait-until-ready, --foreground (required). |
hide / unhide |
Hide an app, or unhide and activate it with explicit consent. | Positional <app> or --app, or --pid; unhide requires --activate. |
switch |
Activate a specific app or cycle Cmd+Tab style with explicit foreground consent. | Exactly one positional <app>/--to or --cycle; --verify only with an app target; --foreground required. |
focus |
Activate and focus an app through the same service path as the MCP app tool. | Positional <app> or --app, or --pid; --foreground required. |
list |
App-management view of running apps, filtering hidden/background apps by default. | --include-hidden, --include-background. |
Implementation notes
- App mutations accept only an exact case-insensitive application name, exact bundle ID, or explicit
PID:<n>/--pid. Partial-name matching remains available to read-only discovery, but a mutation such as--app Safis refused before any lifecycle action is dispatched. - Launch resolves explicit paths, bundle IDs, PID selectors, and friendly names on the selected runtime host. Without
--foreground, it may only return an exact already-running app as a verified no-op; it may resolve the application URL but never dispatches a LaunchServices open/start. Cold launch,--open,--new-instance, and relaunch refuse before dispatch because macOS does not provide a trustworthy nonactivation guarantee. These refusals reportINTERACTION_FAILED,effect: refused,retry_safe: true, andmutation_dispatched: false, with explicit foreground guidance. Background launch also requires a host that advertises this exact no-op contract, so a rolling upgrade cannot delegate to an older host that would cold-launch. The deprecated--no-focusflag remains a no-op compatibility alias. - Background no-op
launch --wait-readyand--wait-for-windowretain the selected PID/process-generation receipt throughout their read-only waits. A readiness failure remains explicitly retry-safe withmutation_dispatched: false. APID:selector stays pinned to that exact process generation for both the no-op and a plain foreground activation; it cannot be combined with--openor--new-instance. Foreground launch keeps the full existing LaunchServices behavior for path/name/bundle selectors: it can start windowless/accessory apps, deliver documents/URLs, create a distinct process, and wait up to 10 seconds for a real WindowServer window.relaunchretains its single--wait-until-readyspelling and requires--foregroundbefore the target is resolved or quit. - JSON launch output returns the launch-bound numeric compatibility field
process_start_identityplus the lossless authoritative stringprocess_start_identity_decimalbesidepid, along with refreshedwindow_count,window_ready, andwindow_ids. Relaunch usesnew_process_start_identityand authoritativenew_process_start_identity_decimal. JSON-number consumers must not use the numeric forms for exact comparison because values above 2^53 can lose precision. A current native host captures that process generation from the exact process selected by LaunchServices and refuses the result if the PID is recycled before return. Older runtime hosts may omit the process identity for foreground launch, but background launch fails closed unless the host advertises the safe no-op contract; cleanup callers must never probe a returned PID to manufacture a new receipt.window_identityisexactwhen the window IDs came from WindowServer andunknownfor an older runtime host that cannot provide that metadata. - MCP app lifecycle and focus results expose the same generation through
target_identity.kind: processandtarget_identity.process_start_identity_decimal. Agents must chain that target identity; the generic numericprocess_start_identitymetadata is compatibility-only and is intentionally not exported as authoritative safety metadata. - Quit mode supports
--allplus--except, automatically ignoring core system processes (Finder,Dock,SystemUIServer,WindowServer). Bulk quit targets only generation-pinned applications whose bounded metadata explicitly classifies them as regular; accessory, prohibited, and incomplete rows are never treated as regular by default. Controlled cleanup can pair--pidwith the lossless unsigned-decimal--expected-process-start-identity(including the full UInt64 range); Peekaboo atomically rejects a recycled PID instead of terminating its replacement. Each JSON result publishes the frozen target plan aspidplus authoritativeprocess_start_identity_decimal. When quits fail, the command prints hints about unsaved changes and suggests--force. - Hide remains background-capable. Unhide requires
--activatebefore runtime-host resolution and carries the selected PID/process-generation receipt through verified activation because showing an application's windows can move them in front. Hosts that cannot enforce the receipt are rejected, and the legacy identifier-only Bridge unhide operation is refused. switch --cyclesynthesizes Cmd+Tab events usingCGEventso it behaves like the real keyboard shortcut;switch --toactivates the exact PID resolved via AX. Both switch forms andapp focusrequire--foregroundbefore application lookup or global input dispatch. Switch accepts exactly one app target or--cycle; it never ignores a target in favor of a global cycle.- App activation is successful only after the exact resolved PID reports active and Workspace-frontmost. When the
target owns visible ordinary windows, the frontmost WindowServer window must also belong to that PID. Peekaboo
first uses native application activation, then falls back to the application's AX frontmost attribute when macOS
accepts the request without completing it. Multi-window apps activate all of their windows; use
window focuswhen one specific window must become key. - CLI and MCP focus/switch/unhide operations never reduce a selected application to a bare PID or name before activation; the runtime host rechecks the original process-generation receipt immediately before and after native activation.
switch --verifyperforms an additional command-level confirmation after the shared verified activation path (not supported with--cycle).- Supply one selector shape. Launch rejects a positional app combined with
--bundle-id; app lifecycle commands reject a textual--appcombined with--pid. A redundant--app PID:123 --pid 123pair is accepted only when both PIDs match. - With
--foreground,relaunchsends the initially selected PID/process-generation receipt, quit, termination polling (up to 5 s), the requested delay, and launch as one daemon-held transaction, so even a short daemon idle timeout cannot strand the app closed. The host rejects PID reuse before quit, refuses to relaunch its own daemon, launches via bundle ID or bundle path, can wait forisFinishedLaunching, and returns authoritativeprevious_process_start_identity_decimalandnew_process_start_identity_decimalgenerations for race-free follow-up cleanup. app listfilters hidden/background apps unless--include-hiddenor--include-backgroundis passed and emits its establisheddata.appspayload. Inventory snapshots WindowServer once and schedules up to eight concurrent metadata waits, with a 250 ms per-process caller timeout and a one-second enrichment scheduling budget. Synchronous inventory seed collection (including running processes and WindowServer) and final generation validation are not hard-bound by that budget.- Detached LaunchServices metadata has a separate process-wide limit of eight retained operations shared by all application services and process generations. Admission reserves capacity through native return/throw and autorelease cleanup, even after the caller times out or cancels. There is no waiting backlog or result coalescing: duplicate
(PID, process generation)requests and requests beyond capacity are rejected immediately. Dispatched wrappers that expire before starting retain their reservation until they drain without invoking the getter. Permanently blocked getters permanently consume capacity. This limit covers detached application metadata per host process, not all AX work, threads, or the machine. Exact-target AX window, focus, and typing readback use independent lanes, including for the same PID and generation. - An overloaded, timed-out, or deadline-skipped inventory row retains its stable PID/generation/window IDs, carries
metadata_warnings, and omitsis_hiddenrather than guessing; use both inclusive flags to retain rows whose hidden state and activation policy are unknown. Overload returns partial rows, never a fabricated empty inventory. Changed generations are still omitted, cancellation still propagates, and incomplete rows remain ineligible for bulk quit. Top-levelwarningsmakes a partial result visible in JSON and text output; row warnings also survive Bridge transport. Each current native process generation is available asprocess_start_identityplus the lossless canonical stringprocess_start_identity_decimal; shell/JSON-number consumers must use the decimal string for exact comparison and treat missing values from older hosts as unknown. The result'sschema_capabilitiesarray advertisesprocessStartIdentityDecimaleven whenappsis empty, so installers can require the lossless receipt contract without inferring CLI capability from ambient processes.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- yesterday Changed · +2 lines e2b73f31d754
- 2d ago First seen · 84 lines · 0 tokens per session scan A a7f83eac9ad2
app is a command published in the GitHub repository openclaw/Peekaboo (5,098 stars, last pushed yesterday), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 2,528 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other commands, from other repositories
upload
Archive, upload, and submit to external TestFlight (full loop with monitor).
release
Create a new Remarc release using the automated GitHub Actions workflow.
imark-review
Open a markdown document in Imark for review and wait for the reviewer's notes.
imark-notes
Read the Imark comments out of a markdown file.
archive
Create xcarchive for TestFlight.
build
Build debug and launch HomeClaw.