Application Resolution in Peekaboo
This document explains how Peekaboo resolves applications across commands that accept an application parameter.
#Overview
Peekaboo supports multiple ways to identify and target applications:
- Application Name - Human-readable name (e.g., "Safari", "Google Chrome")
- Bundle ID - Unique application identifier (e.g., "com.apple.Safari")
- Process ID (PID) - Numeric process identifier
- Fuzzy Matching - Partial name matching for convenience
#Command Line Parameters
Most commands that work with applications support two parameters:
--app- Application name, bundle ID, or PID in format "PID:12345"--pid- Direct process ID as a number
#Examples
# By application name
peekaboo see --no-elements --app Safari
# By bundle ID
peekaboo window close --app com.apple.Safari
# By PID using --app parameter
peekaboo menu list --app "PID:12345"
# By PID using --pid parameter
peekaboo app quit --pid 12345
# Both parameters on a legacy window command (when they refer to the same app)
peekaboo window focus --app Safari --pid 12345
#Resolution Methods
#1. Application Name
The most common method - uses the localized application name:
peekaboo see --no-elements --app "Google Chrome"
peekaboo window list --app TextEdit
Features:
- Case-insensitive matching
- Supports spaces in names
- Uses localized names (what you see in the UI)
#2. Bundle Identifier
More precise than names, bundle IDs are unique:
peekaboo app launch --app com.microsoft.VSCode
peekaboo window close --app com.google.Chrome
Features:
- Exact matching only
- Always lowercase
- Guaranteed unique per application
#3. Process ID (PID)
Direct process targeting using numeric IDs:
# Using --pid parameter
peekaboo app quit --pid 67890
# Using --app parameter with PID: prefix
peekaboo window focus --app "PID:67890"
# Finding PIDs
peekaboo app list --include-hidden --include-background # Shows all PIDs
Features:
- Most precise targeting method
- Works even if app name is unknown
- Useful for scripting and automation
#4. Fuzzy Name Matching
Peekaboo supports partial name matching for convenience:
# Matches "Visual Studio Code"
peekaboo see --no-elements --app "visual"
peekaboo see --no-elements --app "code"
peekaboo see --no-elements --app "studio"
# Matches "Google Chrome"
peekaboo window list --app chrome
Algorithm:
- First tries exact match (case-insensitive)
- Then tries "contains" match
- Prioritizes running applications
- Falls back to installed applications
#Selector safety and legacy leniency
V4 interaction and observation commands fail closed: use either --app or --pid, never both. This rule covers see and commands that use the shared interaction target such as action, click, drag, press, set-value, and type. These commands may observe, focus, and mutate through different services, so a redundant-looking pair is unsafe when those services resolve it differently.
Some legacy app/window management commands retain lenient parameter handling as a compatibility contract. For those commands, redundant app/PID information is accepted; a textual app selector remains authoritative because the synchronous resolver cannot reliably cross-check it against the PID.
#Allowed Redundancy
These legacy management forms are valid and equivalent:
# Redundant PID specifications
peekaboo window close --app "PID:12345" --pid 12345
# Legacy compatibility: the textual app selector is authoritative
peekaboo window focus --app Safari --pid 67890
#Conflict Detection
This produces an error:
# Different PIDs
peekaboo window close --app "PID:12345" --pid 67890
A textual app/PID mismatch is not synchronously detectable in the legacy resolver. This is why interaction and observation commands reject the pair instead of choosing one.
#Implementation Details
#ApplicationResolvable Protocol
Commands with application parameters can conform to the ApplicationResolvable protocol:
protocol ApplicationResolvable {
var app: String? { get }
var pid: Int32? { get }
}
Safety-sensitive interaction call sites add stricter selector validation before invoking this resolver.
#Resolution Priority
When a legacy-compatible command accepts both --app and --pid:
- If
--appusesPID:<pid>, validate that it matches--pid - Otherwise, prefer the textual app or bundle identifier for the operation
- Do not infer that an accompanying PID proves the textual app's identity
#Error Messages
Clear error messages help users understand issues:
"No application found with name 'Safarii'"- Typo in name"Application 'Safari' is not running"- App not launched"Process with PID 12345 not found or terminated"- Invalid PID"Application mismatch: --app 'Safari' does not match PID 12345 (Chrome)"- Conflict
#Best Practices
#For Users
- Use names for readability:
--app Safariis clearer than--app "PID:12345" - Use PIDs for precision: When scripting or targeting specific instances
- Use bundle IDs for reliability: When app names might be ambiguous
#For Scripts
# Get PID for scripting
PID=$(peekaboo app list --json --include-hidden --include-background | jq '.data.apps[] | select(.name=="Safari") | .pid')
peekaboo window close --pid $PID
# Or use bundle ID
peekaboo app launch --app com.apple.Safari
#For AI Agents
AI agents should provide exactly one of --app or --pid. Use PID:<pid> in --app only when a schema lacks a separate PID field. Do not send both unless the specific legacy command documents that compatibility form.
#Common Patterns
#Finding Applications
# List all running apps with PIDs
peekaboo app list --include-hidden --include-background
# Find specific app
peekaboo app list --include-hidden --include-background | grep -i safari
#Window Management
# List windows for an app
peekaboo window list --app Safari
# Focus specific window
peekaboo window focus --app Safari --window-title "GitHub"
#Cross-Space Operations
# Move window to current space (finds app by any method)
peekaboo space move-window --app Terminal --to-current
peekaboo space move-window --pid 12345 --to 2
#Troubleshooting
#Application Not Found
Symptoms:
"Application 'X' not found""No running application matches 'X'"
Solutions:
- Check spelling:
peekaboo app list --include-hidden --include-background - Try partial name:
--app chromeinstead of--app "Google Chrome" - Use bundle ID:
--app com.google.Chrome - Use PID directly: Find it with
peekaboo app list --include-hidden --include-background, then use--pid
#PID Issues
Symptoms:
"Process with PID X not found""Invalid PID format"
Solutions:
- Verify PID is current:
peekaboo app list --include-hidden --include-background - Check format:
--app "PID:12345"needs quotes and prefix - Use
--pid 12345for direct numeric PIDs
#Multiple Matches
Symptoms:
- Fuzzy matching finds wrong app
- Multiple apps with similar names
Solutions:
- Use full name:
--app "Visual Studio Code"not--app code - Use bundle ID for precision
- Use PID for exact targeting
#See Also
- Command index - Full command documentation
- Agent chat - Using Peekaboo with AI agents
- Automation guide - Scripting and automation patterns