#!/usr/bin/env bash
set -euo pipefail
LABEL="dev.cmux.iphone-install-queue"
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
QUEUE_DIR="${CMUX_IPHONE_QUEUE_DIR:-$HOME/Library/Application Support/cmux-dev/iphone-install-queue}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
GUI_DOMAIN="gui/$(id -u)"
usage() { sed -n '2,27p' "$0"; }
cmd_status() {
if launchctl print "$GUI_DOMAIN/$LABEL" >/dev/null 2>&1; then
echo "LaunchAgent $LABEL is loaded ($PLIST)"
launchctl print "$GUI_DOMAIN/$LABEL" 2>/dev/null | grep -E 'state|last exit code|program ' || true
else
echo "LaunchAgent $LABEL is NOT loaded"
return 1
fi
}
cmd_uninstall() {
launchctl bootout "$GUI_DOMAIN/$LABEL" 2>/dev/null || true
rm -f "$PLIST"
echo "uninstalled $LABEL"
}
cmd_install() {
local checkout="$REPO_ROOT"
while [[ $# -gt 0 ]]; do
case "$1" in
--checkout) checkout="${2:-}"; shift 2 ;;
*) echo "install: unknown argument: $1" >&2; usage >&2; exit 2 ;;
esac
done
[[ -x "$checkout/scripts/mobile-dev-launch.sh" ]] \
|| { echo "error: --checkout $checkout has no scripts/mobile-dev-launch.sh" >&2; exit 1; }
mkdir -p "$QUEUE_DIR/bin" "$QUEUE_DIR/logs" "$QUEUE_DIR/pending" \
"$HOME/Library/LaunchAgents"
install -m 0755 "$SCRIPT_DIR/iphone-install-queue.sh" "$QUEUE_DIR/bin/iphone-install-queue.sh"
cat > "$PLIST" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>$LABEL</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>$QUEUE_DIR/bin/iphone-install-queue.sh</string>
<string>drain</string>
<string>--wait</string>
<string>600</string>
<string>--interval</string>
<string>10</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin:$HOME/.local/bin</string>
<key>CMUX_IPHONE_QUEUE_DIR</key>
<string>$QUEUE_DIR</string>
<key>CMUX_IPHONE_QUEUE_CHECKOUT</key>
<string>$checkout</string>
</dict>
<key>LaunchEvents</key>
<dict>
<key>com.apple.iokit.matching</key>
<dict>
<key>dev.cmux.iphone.usb-attach</key>
<dict>
<key>IOProviderClass</key><string>IOUSBHostDevice</string>
<key>idVendor</key><integer>1452</integer>
<key>IOMatchLaunchStream</key><true/>
</dict>
</dict>
</dict>
<key>WatchPaths</key>
<array>
<string>$QUEUE_DIR/pending</string>
</array>
<key>StartInterval</key><integer>30</integer>
<key>RunAtLoad</key><true/>
<key>ProcessType</key><string>Background</string>
<key>StandardOutPath</key><string>$QUEUE_DIR/logs/agent.log</string>
<key>StandardErrorPath</key><string>$QUEUE_DIR/logs/agent.log</string>
</dict>
</plist>
PLIST
launchctl bootout "$GUI_DOMAIN/$LABEL" 2>/dev/null || true
launchctl bootstrap "$GUI_DOMAIN" "$PLIST"
launchctl enable "$GUI_DOMAIN/$LABEL" 2>/dev/null || true
echo "installed $LABEL"
echo " plist: $PLIST"
echo " script: $QUEUE_DIR/bin/iphone-install-queue.sh"
echo " checkout: $checkout"
cmd_status || true
}
verb="${1:-install}"
case "$verb" in
install) shift || true; cmd_install "$@" ;;
uninstall) cmd_uninstall ;;
status) cmd_status ;;
-h|--help|help) usage ;;
*)
# Bare flags mean install (e.g. `install-iphone-queue-agent.sh --checkout X`).
case "$verb" in
--*) cmd_install "$@" ;;
*) echo "unknown verb: $verb" >&2; usage >&2; exit 2 ;;
esac
;;
esac