Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI reference

Commands work as a Cargo subcommand (cargo ferry ...) or direct binary (cargo-ferry ...). Run --help on the installed revision for exact parsing.

Global flags

  • --verbose: external-command/discovery detail in human mode; conflicts with --quiet, --json, and --json-stream; secrets must be redacted.
  • --quiet: suppress successful human output; conflicts with --verbose, --json, and --json-stream.
  • --json: schema-versioned JSON without terminal styling; conflicts with human verbosity flags and --json-stream. Current output schema is version 1.
  • --json-stream: protocol-v1 NDJSON for ide operations, devices, live application logs, and jobs logs; conflicts with human verbosity flags and --json. Other commands reject it and use --json instead.
  • --dry-run: validate and show intended mutations where the command supports planning.

Commands

CommandCurrent contract
new <name>Atomic generation; --display-name, --id, --template, --platform, runtime source controls, --no-git, --no-check, --parent
add <capability>Preserve TOML formatting, enable config/Cargo feature, create a missing example module, support dry-run
remove <capability>Disable config/Cargo feature; preserve example source
checkValidate config, then run ordinary cargo check
doctor [--all]Read-only host/toolchain inventory
doctor --fix --dry-runPrint fixes; automatic mutation is not implemented
build androidBuild-only Android request; platform readiness and validation level are in STATUS
build ios --simulatorBuild-only Simulator request; no automatic boot/install/launch
build ios --device --team <id>Implemented official arm64/Xcode development-signing build; provisioning updates remain explicit; no identity, Team, profile, or signed artifact was available for artifact validation, and no device was available for device validation
build ios --deviceUses GitHub automatically on Linux/Windows; remains local by default on macOS; an explicit --remote always wins
build iphone --unsignedRemote-only alias; defaults to GitHub when --remote is omitted, submits an exact source revision, then rehashes, inspects, and atomically publishes the downloaded unsigned physical-device archive
build iphone --remote github --snapshot --unsignedExplicit public GitSnapshot of the canonical current project; dry-run is zero-write, interactive execution asks [y/N], and JSON/non-interactive execution requires --yes
build iphone --team <id>Defaults to protected GitHub Apple Development signing when --remote is omitted; implemented and synthetically tested, but no real signed IPA acceptance has run
remote setup githubValidate source/execution Git remote identities, generate the trusted workflow, and persist ignored provider metadata; signing requires a distinct private execution repository
remote doctor githubRead-only provider, repository, and workflow health; use signing doctor --remote github for protected-signing readiness
remote add ssh-mac <name>Persist a create-only named endpoint after validating an exact dedicated known_hosts entry, pinned host-key fingerprint, and optional private-key path reference
remote doctor <name>Run the fixed-command SSH worker handshake and host doctor; readiness requires snapshot/unsigned/XCArchive/events/cancellation/download/cleanup and retention zero, but is not live-build evidence
build iphone --remote <name> --unsignedCreate a deterministic snapshot, use fixed SSH session v1, stream ordered events, independently verify and create-only publish the unsigned XCArchive, acknowledge it, then require non-retaining cleanup
remote bundle inspectPrint the deterministic snapshot manifest, path dependencies, rejected-symlink set, excluded sensitive roots, sizes, executable bits, and SHA-256 digests
remote bundle createCreate a no-clobber deterministic source ZIP and separate versioned descriptor; global --dry-run writes neither
remote bundle verifyTreat ZIP and descriptor as untrusted, perform bounded extraction, and require exact manifest/archive integrity
jobs list [--limit <1..1000>]List bounded newest private project-bound durable jobs
jobs show <job-id> / jobs artifacts <job-id>Show one secret-free durable job or its recorded artifact metadata
jobs logs <job-id>Refresh and read bounded sanitized durable lifecycle/worker events; --follow, --since, --phase, and create-new --output are supported
jobs cancel <job-id>Persist exact owned cancellation intent before at most one provider request, then reconcile terminal state and cleanup across restarts
jobs retry <job-id>Create/resume one exact-source child; retrying a fully evidenced successful parent requires --force; current-source recapture requires --use-current-source --yes
jobs prune --before <unix-ms>Plan or, with --yes, remove complete terminal retry lineages only after local artifact removal and retained-source release authorization
artifact list|show|inspect|verify|reveal|removeManage durable local artifact evidence; bare IDs must resolve uniquely, exact removal is Windows-only and requires --yes, and local removal never means remote Actions deletion
devices [--platform all|android|ios]Typed ADB/simctl/devicectl inventory; --watch --json-stream emits the initial snapshot followed by polling deltas until cancelled
install android|iosBuild, independently validate, select an exact compatible device, then install
run android|iosBuild → validate → install → launch; --logs adds one bounded filtered snapshot where standalone logging is supported
logs android|iosFinite application-filtered history by default; --json-stream runs the live protocol stream until cancellation or platform-tool exit
signing teamsRead-only Apple Development identity/Team inventory
signing doctor --remote githubMetadata-only signing readiness; non-ready returns github_signing_not_ready without reading secret values
signing setup manualValidate one PKCS#12 plus one profile per application/extension target outside Git, check protected GitHub Environment policy, and upload secrets only after dry-run review and confirmation
assets check|generateValidate release sources; generate fingerprinted Android densities and an iOS asset catalog
clean [android|ios|generated]Remove only selected generated output below target/ferry/
clean --allRemove cargo-ferry output below target/ferry/, not application source/signing inputs
config validateStrict parse and semantic validation
config show --resolvedPrint resolved defaults
config schemaPrint JSON Schema
config migrateAtomically upgrade a supported older schema; use global --dry-run to inspect first
capabilitiesList known runtime/platform state and current enablement when inside a project
examplesList bundled template choices and generation commands
docs [topic]Show the source-tree page when available; otherwise print packaged embedded content
completions <shell>Generate shell completion definitions
ide <operation>Direct protocol-v1 JSON/NDJSON for editor integrations, including durable jobs/log pages/cancel/retry/artifacts, snapshot preview/submit, and signing readiness

Goal 3 IDE-v1 operations are jobs-list, jobs-show, jobs-artifacts, jobs-logs, jobs-logs-page, jobs-cancel, jobs-retry, jobs-artifact-verify, jobs-artifact-reveal, jobs-artifact-remove, remote-build-preview, remote-build-submit, and signing-readiness. Legacy jobs-logs remains a finite timestamp snapshot; the UI uses decimal-cursor jobs-logs-page. Preview and submit are capability-co-gated, and submit accepts one bounded consent object on standard input.

Capabilities accepted by add/remove: network, notifications, storage, haptics, clipboard, deep-links, share, widget, and live-activity.

Manual GitHub signing accepts at most three profiles. An extension-free project may retain the legacy --profile PATH form. A project with Widget or Live Activity targets must pass repeatable, exact --profile TARGET=PATH arguments for the application and every extension; keyed and unkeyed forms cannot be mixed. The profiles must share the selected registered device and match their target bundle identifiers, Team, certificate, validity, and required entitlements. Multi-profile secret input uses RFSIGNV2; the legacy worker frame remains single-application-only.

Templates accepted by new: starter, minimal, counter, network, notifications, widget, live-activity, and kitchen-sink. They share a template engine and feature fragments rather than copied project trees.

Runtime controls are source-specific. --runtime-source registry accepts an optional semantic --runtime-version; --runtime-source workspace accepts neither version nor path; --runtime-source path requires --runtime-path naming an absolute, existing directory containing Cargo.toml. Version/path flags are rejected without an explicit source. With no runtime flag, generation uses the CLI’s registry version unless the contributor-only CARGO_FERRY_RUNTIME_PATH override is set.

Device watch mode requires --json-stream. It emits the current devices and warnings first, then polls at --interval-ms (2,000 ms by default, clamped to 500–60,000 ms) and emits only added, changed, removed, or warning changes. Ctrl+C ends watch mode with cancellation status.

logs without --json-stream collects a finite snapshot using --since-seconds, --max-entries, --max-bytes, and --level. --json-stream selects continuous, application-filtered Android or iOS Simulator logging and emits protocol events incrementally. Standalone physical-iOS logs is currently unsupported; CoreDevice console attachment is not exposed as this command.

build never discovers, boots, installs on, or launches a device. Those side effects exist only behind the explicit deployment commands. Android reinstall/downgrade/permission grant/data clear, Simulator boot, process termination, and Xcode provisioning updates are opt-in.

SSH snapshot v1 is unsigned-only. A signed request or --team fails explicitly; it is never downgraded. Named SSH endpoints are always selected explicitly; omission never falls back from GitHub to a configured SSH endpoint. The returned XCArchive ZIP is not an IPA and is not installable on a stock iPhone. Unsigned remote archives are published at target/ferry/ios/device/<debug|release>/<Product>-unsigned.xcarchive.zip.

GitHub GitSnapshot is also unsigned-only and explicit. Preview binds the invocation, exact source manifest, public repository/ref, retention, and side effects; archive construction occurs only after consent. The caller branch, worktree, index, remotes, and hooks are unchanged. Public Git objects may remain recoverable after RustFerry deletes its temporary ref.

Durable job logs use log_scope=durable_sanitized_job_events. Raw provider payloads and raw worker bytes are never stored. provider_full_logs=true requires an exact completion proof for the current run attempt. Local artifact removal and job pruning do not delete GitHub Actions artifacts.

JSON failures

Failures include schema_version, status, and a stable error object with code, message, optional help, and safe details. Nonzero exit classes distinguish usage/configuration, missing/unsupported prerequisites, external command failure, and filesystem/safety failure.