Launchpad command line
vphone-launchpad-cli drives the running Launchpad from Terminal or a script: install bundles, create, start and stop machines, and talk to the guest. Use it when you want Launchpad's behavior without clicking through the window.
Set it up
The CLI ships in vphone-launchpad.app/Contents/MacOS. Link it onto your PATH:
It starts Launchpad when Launchpad is not running. A Launchpad the CLI starts opens hidden and does not take focus from the app in front; click its Dock icon, or Open Launchpad in the menu bar, to show the window. Pass --foreground (before the command, or among the options of any command but exec) to start it with its window in front instead. Neither changes a Launchpad that is already running.
Output and exit status
- Progress lines go to stderr as they arrive.
- The result is one JSON document on stdout.
- The exit status is 0 on success and 1 on failure, with the reason on stderr.
- Interrupting the CLI cancels a command that can be cancelled (
exec, waits, CFW install). A bundle install or a machine creation belongs to the window and keeps running.
Every command also appears in Launchpad's window and command history.
Commands
Machine commands take --root <library> when two libraries hold a machine with the same name.
Status and bundles
To install a local build, move a machine to it, or compare two builds, see Core Bundles and local builds.
Machines
Notes:
- In
vm list, only a VM process holding the disk (vphone-vm, or Virtualization's VM service) makes a machinerunning. Any other process that has the disk open (tail, Spotlight, a backup tool) is listed indiskOpenIn(for example12925 tail) and leaves the machinestopped. vm start, likevphone-cli vm launch, is not refused by a process that only has the disk open; it prints a note naming that process.vm start --waitandvm waitalso take--timeout.vm set-bundle --update-environmentalso redeploys that version's guest environment and needs a stopped machine. A disk another process has open refuses it, naming that process, before the binding changes. If the update itself fails, the machine stays bound to the new version andvm liststill shows the oldguestEnvironmentBundle; runcfw update-environmentto finish.
CFW
These run through Launchpad's helper on a stopped machine, with the machine's own bundle. Each refuses a disk another process has open, naming it (12925 tail).
Guest
guest commands and --wait go through the machine's vphone.sock, which every launch serves. Bundles up to 2.0.9 serve it only for machines launched with a window.
Run vphone-cli
Create a machine
vm create runs the New Machine pipeline, bound to --bundle <version> or to the default bundle. The machine is cloned from a template, which is built first when missing (2.9), or restored on its own with --no-template.
The parser also accepts --iphone-source, --cloudos-source, --cpu, --memory, --disk-size, --network, --keep-artifacts and --no-wait; see vphone-launchpad-cli help.
The result names the template, whether this creation built it, and the patches it used.
Other devices
Two more cases run steps as root through the helper:
--preset minimal(Minimal: a stock boot chain, kernel and TXM, with the system customized before the restore) is also restored on its own without slimming, and itsfw patchruns as root through the helper. Its Userspace debugging box (userspace-debuggingunder Features invphone-cli fw patches) is an--allowfor each patch it lists.- For a machine whose cloudOS has no vphone600 components (its release's own cloudOS, a watch, an iOS 18 guest), the kernelcache mix is staged with
fw kernelcacheand linked by the helper as root.
Patch overrides
--block <patch> and --allow <patch> take the identifiers that vphone-cli fw patches lists, once per patch:
Launchpad reads that catalog from the creation's bundle, refuses an identifier no patch set declares or one both blocked and allowed, and keeps only what differs from the preset, as fw set-patches does. It then splits them the way New Machine does:
- Boot-chain patches (AVPBooter, iBSS, iBEC, LLB, TXM, kernelcache, DeviceTree …) are part of the template's key. Find Template looks for a template built with them, and a template build records them with
fw set-patchesbeforefw patch. - Guest patches stay out of the template. The clone records them with
fw set-patches, and the Apply Guest Patches step writes them withcfw update-environmentthrough the helper before the first boot. A guest override alone therefore reuses the plain template.
The result's patches object holds the preset, the blocked and allowed overrides, and the guest ones applied to the clone. With --no-template every override goes into the machine's own restore. --from refuses --block and --allow: a retry keeps the creation's patches.
Bundle fields in results
When guestEnvironmentBundle differs from bundle, host and guest come from different builds; cfw update-environment brings the guest in line.
Touch coordinates and display geometry
Touch coordinates for guest send refer to the full upright screenshot that t:screenshot returns: after a quarter turn its width and height swap. The host converts that point into fixed-panel HID coordinates for both GUI and headless launches. A swipe keeps the geometry sampled at its start. If the geometry changes across a screenshot, you get an error rather than an image with ambiguous input coordinates.
To diagnose rotated coordinate mismatches, read the geometry:
It returns the host's configured and captured pixel dimensions plus the live display-view bounds, rotation, aspect-fit drawing rect, and pointer/touch path, and changes no input or display state. capture_pixels is the raw host frame; screenshot_pixels and input_orientation describe input coordinates. Compare it with device.screen, display.orientation and the events the guest actually receives.
How it connects
The CLI talks to the running Launchpad over a Unix socket at ~/Library/Application Support/vphone-launchpad/control.sock (mode 0600, served only to the same user). It has no privileges and no state of its own: bundles are installed through Launchpad's helper, and each machine runs through the vphone-cli of its own Core Bundle. Nothing listens on the network; to use it from another machine, connect over ssh.