Build, install, and launch an iOS app on a physical iPhone or iPad entirely from the command line (no Xcode GUI), using xcodebuild + devicectl. Use when the user wants to run, test, or screenshot their app on a real device without opening Xcode.
npx skills add https://github.com/rshankras/claude-code-apple-skills --skill run-device
Builds, signs, installs, and launches an app on a connected physical device
straight from the terminal — no Xcode Run button. The companion run-simulator
skill covers the Simulator; this is the hardware path, which uses a different
toolchain: devicectl (not simctl), real code signing, and an external tool
for screenshots.
Building proves the code typechecks and signs; launching proves it installs and
runs on real hardware. A crash on launch or a failed install is a failure.
Use when the user wants to:
Not for the Simulator (use run-simulator) and not for xcodebuild test.
Mode → on → restart. There is no CLI to enable this.
on the device — tap Trust. devicectl pairs once trusted.
CODE_SIGN_STYLE = Automaticand a DEVELOPMENT_TEAM, and the signing Apple ID must already be logged into
Xcode (Settings → Accounts) so -allowProvisioningUpdates can mint profiles.
A free personal team works but apps expire after 7 days.
Confirm reachability before building:
xcrun devicectl list devices
The Identifier column is a CoreDevice UUID (e.g. A1B2C3D4-…). It is used by
devicectl for install/launch. It is NOT the value xcodebuild wants — see
the trap in step 2. Pick a row whose State is available (paired) /
connected.
xcrun devicectl list devices # grab the Identifier (CoreDevice UUID) of the paired device
Store it: DEV=<identifier-from-the-Identifier-column>.
Trap: xcodebuild matches on the *hardware* UDID, not the devicectl
identifier. Passing -destination 'platform=iOS,id=<devicectl-id>' fails with
*"Unable to find a device matching the provided destination specifier."* Build
for a generic device instead — it produces the same signed .app:
xcodebuild build \
-project MyApp.xcodeproj -scheme MyApp \
-destination 'generic/platform=iOS' \
-allowProvisioningUpdates 2>&1 | tail -5
(Use -workspace MyApp.xcworkspace instead of -project if the project has one.)
Look for BUILD SUCCEEDED . -allowProvisioningUpdates lets xcodebuild
register the device and create/refresh the provisioning profile automatically.
Common failures:
DEVELOPMENT_TEAM=XXXXXXXXXX onthe command line, or fix it in project settings.
-allowProvisioningUpdates (above), andmake sure the signing Apple ID is logged into Xcode.
.app (device build → Debug-iphoneos)Don't guess DerivedData — read it from build settings. Note the directory is
Debug-iphoneos for device builds (vs Debug-iphonesimulator for the Simulator):
eval $(xcodebuild -project MyApp.xcodeproj -scheme MyApp \
-destination 'generic/platform=iOS' -showBuildSettings 2>/dev/null \
| awk -F' = ' '/ TARGET_BUILD_DIR =/{print "DIR=\""$2"\""} / FULL_PRODUCT_NAME =/{print "NAME=\""$2"\""}')
APP="$DIR/$NAME" # .../Debug-iphoneos/MyApp.app
BID=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$APP/Info.plist")
xcrun devicectl device install app --device "$DEV" "$APP"
Prints App installed: with the bundleID and installationURL on success.
xcrun devicectl device process launch --device "$DEV" "$BID"
Prints Launched application with <bundle id> ….
Known quirk: adding --terminate-existing (to relaunch a running app)
sometimes returns `CoreDeviceError 10004 — "process identifier … could not be
determined"` even though the app launched. If you see it, run the plain
launch above and verify it's actually running:
xcrun devicectl device info processes --device "$DEV" | grep -i MyApp.app
A matching pid /…/MyApp.app line confirms it's live.
devicectl has no screenshot command, so device screenshots require
brew install libimobiledevice # one-time
idevicescreenshot /tmp/device-shot.png # captures the foreground screen
Then Read /tmp/device-shot.png and verify the change renders.
Caveats:
idevicescreenshot needs the Developer Disk Image mounted. Running the app viadevicectl (steps 4–5) mounts it, so screenshot *after* launching.
idevicescreenshot -u <hardware-udid> …(idevice_id -l lists hardware UDIDs — again, distinct from the devicectl id).
manual screenshot on the device.
Report:
BUILD SUCCEEDED or the error: lines, then stop)Trust, log the Apple ID into Xcode)
xcodebuild → "Unable to find a device matching thedestination." Build generic/platform=iOS; use the devicectl id only for
install/launch (step 2 trap).
-quiet hides success → it suppresses BUILD SUCCEEDED ; drop it forthe confirming run or grep error:.
10004 on launch → usually a false alarm from --terminate-existing; plainlaunch + device info processes confirms (step 5).
with a pairing/trust error, have the user complete it on-device once.
devicectl works over the network once paired; the devicemust be awake and on the same network.
xcrun devicectl device uninstall app --device "$DEV" "$BID".
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take rshankras/run-device from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference brew.
Without those the skill loads but fails at the first command.