Pippin (Simulator Driver) is a command-line interface designed to bridge the gap between Large Language Models (LLMs) and the iOS Simulator.
- Token Efficiency (The "Narrow Context" Principle): Pippin’s primary output is a simplified, text-based JSON representation of the UI. This allows LLMs to "see" the screen using minimal tokens, avoiding the high cost and latency of processing raw screenshots.
- Stateless Atomic Actions: Each command is independent. Pippin does not maintain a complex session, making it easier for an Agent to reason about the state at any given step.
- Native Wrapper: Under the hood, Pippin orchestrates
xcrun simctl(for system tasks) andidb(for deep accessibility inspection).
- Interface:
pippin [command] [subcommand] [flags] - Output Format: Standard JSON (for machine parsing) or human-readable text.
- Error Handling: Returns strictly formatted error codes and descriptive messages to help the LLM self-correct (e.g.,
ERR_ELEMENT_NOT_FOUND,ERR_APP_CRASHED).
These commands generate the context for the LLM to understand the current state.
Returns a simplified JSON tree of the current screen's accessibility hierarchy.
- Flag:
--interactive-only(Default:true). Filters out structural containers (Window,Other) and keeps actionable elements (Button,TextField,Cell,Switch,StaticText). - Flag:
--depth [n]. Limits the hierarchy depth to save tokens. - Output Schema:
{ "app": "com.example.myapp", "screen_id": "LoginView", "elements": [ { "id": "email_field", "label": "Email Address", "type": "TextField", "frame": "20,100,300,40", "value": "" }, { "id": "login_btn", "label": "Log In", "type": "Button", "enabled": false } ] }
Captures the visual state for verification or multimodal fallback.
- Args:
[filename] - Flag:
--mask-text(Optional). Redacts text for privacy/security before saving.
Direct manipulation of the app UI.
Taps a UI element.
- Targeting Logic: Accepts a string query.
- Exact Match: Accessibility Identifier.
- Fuzzy Match: Label text (e.g., "Login" matches "Log In").
- Coordinate Fallback:
--x [num] --y [num].
- Example:
pippin tap "Sign Up"
Inputs text into the currently focused field.
- Args:
[text_string] - Flag:
--submit(Default:false). Hits "Return/Enter" on the keyboard after typing. - Example:
pippin type "user@example.com" --submit
- Args:
[direction](up,down,left,right). - Flag:
--until-visible [element_label]. A specialized loop that scrolls until a specific element appears in theinspecttree.
- Swipe:
pippin gesture swipe [start_x],[start_y] [end_x],[end_y] - Pinch:
pippin gesture pinch [in|out]
Developers need to test how the app behaves under different system conditions.
- Args:
[bundle_id] - Flag:
--clean. Wipes the app container (simulates a fresh install). - Flag:
--args "[key]=[value]". Passes Launch Arguments (e.g.,-TakingScreenshots YES). - Flag:
--locale [code]. Launches the app in a specific language (e.g.,es-MX).
Opens a URL scheme or Universal Link to test routing.
- Args:
[url] - Example:
pippin open "myapp://settings/profile?edit=true"
Manages TCC (Privacy) permissions to test "Happy Path" vs. "Denied Path".
- Args:
[service] [status] - Services:
camera,photos,location,microphone,contacts,calendar. - Status:
grant,deny,reset. - Example:
pippin permission camera deny
Simulates GPS coordinates.
- Args:
[lat] [lon] - Example:
pippin location 37.7749 -122.4194(San Francisco)
- Args:
[condition] - Options:
wifi,cellular,offline.
Tools for the LLM to verify success or diagnose failure.
Quick boolean check for LLM usage.
- Args:
[element_query] [state] - States:
exists,visible,hidden,text=[value]. - Output:
PASSorFAIL: Element found but text was 'Cancel', expected 'Submit'.
Fetches the tail of the system log for the target app.
- Flag:
--crash-report. Checks if a crash log was generated in the last session and outputs the stack trace. - Use Case: "The app closed unexpectedly. Why?"
Lists files in the app's sandbox.
- Args:
[directory](documents,caches,tmp). - Use Case: Verifying that a file download or database export actually occurred.
Objective: "Verify that the app handles denied Camera permissions gracefully."
pippin launch com.myapp.beta --cleanpippin inspect-> Finds "Start Scan" button.pippin permission camera deny(Pre-emptively deny permission).pippin tap "Start Scan"pippin inspect- Agent Logic: Looks for an alert with text "Camera Permission Needed" or "Open Settings".
- If found:
pippin assert "Open Settings" visible-> ReturnsPASS. - If not found: Agent marks test as
FAILED(App likely stalled or crashed).