skills/xcode-sync/SKILL.md
Xcode fleet sync: signed archives, compatibility, install, selection, first launch.
npx skillsauth add steipete/agent-scripts xcode-syncInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Synchronize exact Xcode builds across Peter's supported Macs. Use $remote-mac for fleet topology and SSH rules.
~/Projects/manager/computers.yaml; use live tailscale status --json for reachability/IPs.hostname, user, macOS, architecture, and hardware UUID before writes.scripts/xcode-host-inventory.sh locally or remotely:skills/xcode-sync/scripts/xcode-host-inventory.sh
ssh -o RequestTTY=no -o RemoteCommand=none HOST 'bash -s' \
< skills/xcode-sync/scripts/xcode-host-inventory.sh
Treat unreachable hosts as pending, not synchronized. Try live Tailscale IP, Tailscale SSH, then mDNS/LAN only when network topology permits.
Every fleet Mac must pass the simulator-hygiene audit, including worker Macs where the correct result is not-applicable because Xcode and simctl are absent. Apple CoreSimulator's own classifications are authoritative: remove runtime images reported by simctl runtime delete --outdated --dry-run or --unusable --dry-run, plus simulator devices attached to unavailable runtimes. Do not classify a runtime as stale from its version number alone; stable and beta Xcodes can legitimately need different runtime generations on the same Mac.
Run the dependency-light audit locally or stream it to a remote Mac:
skills/xcode-sync/scripts/xcode-simulator-hygiene.sh
ssh -o RequestTTY=no -o RemoteCommand=none HOST 'bash -s' \
< skills/xcode-sync/scripts/xcode-simulator-hygiene.sh
The audit exits 1 for drift. After verifying the host identity and current Xcode work, repair with --repair; the action deletes unavailable devices and Apple's outdated/unusable runtime candidates, then re-audits. It refuses repair while a simulator device is booted. Do not use age-based runtime deletion, --notUsedSinceDays, or all for routine fleet maintenance.
Prefer the user's downloaded .xip; do not redownload it.
pkgutil --check-signature "$archive"
shasum -a 256 "$archive"
stage=$(mktemp -d /tmp/xcode.XXXXXX)
cleanup() { rm -rf "$stage"; }
trap cleanup EXIT
(cd "$stage" && xip --expand "$archive")
set -- "$stage"/Xcode*.app
[[ $# == 1 && -d "$1" ]]
app=$1
plutil -extract CFBundleShortVersionString raw -o - "$app/Contents/Info.plist"
plutil -extract ProductBuildVersion raw -o - "$app/Contents/version.plist"
plutil -extract LSMinimumSystemVersion raw -o - "$app/Contents/Info.plist"
DEVELOPER_DIR="$app/Contents/Developer" xcodebuild -version
cleanup
trap - EXIT
Require Apple Software signature. Compare ProductBuildVersion, not version label alone: two archives named Xcode 26.6 may contain different builds. Do not use DTXcodeBuild as the sync key; it can differ from the build reported by xcodebuild -version.
LSMinimumSystemVersion.Never change a host OS to make an Xcode build eligible unless explicitly requested.
rsync -a --partial --progress -e 'ssh -o RequestTTY=no -o RemoteCommand=none' \
"$archive" HOST:Downloads/
ssh HOST 'bash -s'; never let the local shell expand remote $variables or $(commands)./Applications/Xcode.app/Applications/Xcode-beta.app/Applications/Xcode-previous.app, only for three months after a new stable major ships unless the user sets another windowXcode-previous.app to a temporary rollback path, move the former stable to Xcode-previous.app, install and verify the new stable, then delete the older rollback copy. Restore both channel paths on failure. Record the new previous-major removal date in the task report.xcode-select unless the user requests a switch. Replacing the app at the already-selected path preserves selection.Use writable /Applications directly. Otherwise use passwordless sudo -n; if admin approval is required, show a local macOS authorization prompt or report the exact pending step. Do not bypass receipts or license state.
For every installed app:
DEVELOPER_DIR="$app/Contents/Developer" xcodebuild -version
codesign --verify --deep --strict "$app"
DEVELOPER_DIR="$app/Contents/Developer" xcodebuild -checkFirstLaunchStatus
If first-launch status is nonzero:
sudo env DEVELOPER_DIR="$app/Contents/Developer" xcodebuild -license accept
sudo env DEVELOPER_DIR="$app/Contents/Developer" xcodebuild -runFirstLaunch
Recheck until status 0. If sudo/admin UI is unavailable, the app is installed but not ready; report that distinction.
Finish with a host matrix: macOS, desired version/build, installed path, selected path, signature, first-launch state, simulator-hygiene state, previous-major removal date, and skip/failure reason. Keep source archives unless deletion is explicitly requested.
tools
npm registry ops: login, whoami, names, publish; 1Password tmux.
development
Mac fleet inventory and upkeep with full/worker profiles: collect installed apps and packages, compare desired versus observed state, audit local-account escrow references, update Homebrew/global packages, safely sync repos and Xcode, and report disk, service, backup, update, and security health.
tools
Claude Code work routing: delegate implementation, fixing, exploratory subagents, rebasing, and PR merging/landing to Codex CLI while the parent specifies, decides, reviews, and verifies. Load a private codex-next policy first when available; otherwise use the native-Claude model gate. Codex-backed autoreview is always allowed and preferred.
tools
macOS screen capture, accessibility inspection, and background-first app/window/UI automation with Peekaboo v4.