---
name: pymobiledevice3-device-operator
description: Operate iOS and iPadOS devices with pymobiledevice3, from a local checkout or straight from PyPI via uvx on a fresh workstation. Use when an agent needs to inspect a connected device, collect logs or crash data, browse or copy files, manage apps, profiles, or backups, use developer services such as DDI/DVT/tunnels/sysmon/screenshots/simulated location, automate Safari or WebViews through WebInspector or WDA, write Python scripts against the pymobiledevice3 library, or add a thin repo-native device command on top of existing services. Prefer existing CLI and service modules, choose USB vs --rsd/--tunnel correctly, and require explicit user intent before state-changing or destructive actions.
---

# PyMobileDevice3 Device Operator

## Overview

Use this skill to translate a user goal into the smallest correct `pymobiledevice3` action, then execute it — from a local checkout when one is present, or via the PyPI release (`uvx pymobiledevice3`) on a fresh workstation — or extend the repo with a thin CLI wrapper when the capability already exists in services.

## Default Operating Pattern

Inside a pymobiledevice3 checkout, run commands from the repository root with `uvx --from . pymobiledevice3 ...` so the local checkout is used. On a workstation **without** a checkout, run `uvx pymobiledevice3 ...` instead — `uvx` fetches the released package from PyPI on first use, so nothing needs to be installed beforehand except `uv` itself (`uv tool install pymobiledevice3` gives a persistent install). Everywhere this skill's references show `uvx --from . pymobiledevice3 ...`, drop the `--from .` when there is no checkout. Fall back to `python3 -m pymobiledevice3 ...` only if `uvx` is unavailable or the user explicitly wants the current interpreter environment.

If `uv` itself is missing, bootstrap one of the two paths first (neither needs root):

- Install uv: `curl -LsSf https://astral.sh/uv/install.sh | sh` (macOS/Linux) or
  `powershell -c "irm https://astral.sh/uv/install.ps1 | iex"` (Windows), then use `uvx` as above.
- Or skip uv entirely: `python3 -m pip install -U pymobiledevice3`, then run
  `python3 -m pymobiledevice3 ...` everywhere the references show `uvx ... pymobiledevice3 ...`.
  If pip refuses with `externally-managed-environment` (PEP 668 — Debian/Ubuntu, Homebrew
  Python, Fedora), create a venv instead of forcing it:
  `python3 -m venv ~/.pmd3-venv && ~/.pmd3-venv/bin/pip install -U pymobiledevice3`, then use
  `~/.pmd3-venv/bin/pymobiledevice3 ...`. Never use `--break-system-packages`.

Start with the least invasive command that proves connectivity or surfaces missing prerequisites:

```shell
uvx --from . pymobiledevice3 usbmux list
uvx --from . pymobiledevice3 lockdown info
```

Prefer existing CLI commands first. Prefer reading local docs and CLI source over invoking `--help`. Only write code when the library already exposes the underlying service but lacks the exact CLI/API path needed.

## Workflow

1. Classify the request as one of: inspect, collect, modify, automate, developer-instrument, or extend-the-repo.
2. Confirm transport before doing anything expensive. USB is the default. For iOS 17+ developer services, read `references/transport-and-safety.md`.
3. Discover the narrowest command by checking `docs/guides/cli-recipes.md`, `pymobiledevice3/__main__.py`, and the relevant CLI module under `pymobiledevice3/cli/`. Use `rg` to locate command names, options, and transport flags quickly. Without a checkout, use `--help` discovery and the published docs (<https://doronz88.github.io/pymobiledevice3/>) instead.
4. Use `uvx --from . pymobiledevice3 <group> --help` only as a fallback when code and docs are ambiguous, or as a final verification step before suggesting an exact command to the user.
5. Execute a reversible or read-only step first, then escalate to state-changing actions only if the user asked for them.
6. For long-lived streams or interactive shells, keep the process attached instead of replacing it with one-shot polling.
7. If the CLI is missing a path that clearly exists in services, add a thin command using `ServiceProviderDep`, `@async_command`, and a service class under `pymobiledevice3/services/` — commands live on an `InjectingTyper` app (from `typer_injector`). Read `docs/guides/writing-commands-with-service-provider.md`.

## Parsing Command Output

Prefer machine-readable output over scraping human text — the contract is documented in
`docs/guides/machine-readable-output.md` (published on the docs site):

- Data goes to stdout; logging and diagnostics go to stderr. Parse stdout only.
- Most query commands print JSON unconditionally. Binary values appear as single-key
  `{"$hex": "..."}` objects (decode with `bytes.fromhex`); timestamps are ISO 8601.
- Streaming commands emit NDJSON (one JSON object per line): dict-record streams
  (`dvt energy`/`notifications`/`graphics`, `diagnostics battery monitor`,
  `notification observe`/`observe-all`) always; human-rendered streams (`syslog live`,
  `dvt oslog`, `dvt netstat`, `accessibility notifications`, `crash watch`) with
  `--format json`.

## Safety Rules

Require explicit user intent before any command that changes device state, including:

- restore, erase, recovery, reboot, restart, unpair, pair-supervised
- app install or uninstall
- file push, rm, or app container mutation
- profile or provisioning changes
- developer mode toggles, mounting, simulated location, signals, kill/pkill, or automation that taps/types/swipes

Do not invent prerequisites. If a developer service fails, inspect developer-mode, DDI, and tunnel requirements before changing code.

Do not expose or commit pair records, crash artifacts, backups, or other device-identifying material.

## Task Routing

Read `references/quick-recipes.md` for the exact invocation of the most common tasks
(screenshot, syslog search, crash pull, file copy, app listing) and for the
syslog-first troubleshooting technique.

Read `references/python-scripting.md` before writing Python code against the library —
the API went async incrementally over many releases, so memorized/older API shapes are
usually stale.

Read `references/task-map.md` when you need to map a user goal to a command group or service module.

Read `references/transport-and-safety.md` when the task touches iOS 17+ developer services, tunnels, `--rsd`, `--tunnel`, or destructive operations.

## Source Files To Prefer

These paths are relative to a pymobiledevice3 checkout; without one, use the published
docs site (<https://doronz88.github.io/pymobiledevice3/>) and `--help` output instead.

- `docs/guides/cli-recipes.md` for common end-user commands
- `docs/guides/ios17-tunnels.md` for tunnel setup and `--rsd` usage
- `docs/guides/writing-commands-with-service-provider.md` for repo-native command additions
- `pymobiledevice3/__main__.py` for top-level CLI groups
- `pymobiledevice3/cli/cli_common.py` for transport resolution and dependency injection

## Typical Triggers

- "Pull crash logs from the connected iPhone."
- "List installed apps and copy an app container file."
- "Take a screenshot with developer services."
- "Start a tunnel and run DVT sysmon on an iOS 17 device."
- "Open Safari automation and inspect tabs."
- "Add a new CLI command for an existing service."
