Files
status-indicators/install.sh
T
christianandClaude Opus 5.5 246500f965 Add the Companion status page and its watchdog for NA Ingest.
status_panel.py runs on NA Ingest as a LaunchAgent. Every second it reads
Companion's connection statuses and module variables, adds what Companion
cannot see (network MIDI peers, Bonjour sessions, pings, launchd services,
disk, Resi cloud, the Bible TV app), and writes one JSON custom variable that
page 19 renders. Buttons acknowledge alarms, mute them, and restart a stuck
Companion connection on a two second hold. If the watchdog stops, the page
turns purple instead of freezing on stale green.

make_page.py builds the page export from config.json; tests/ runs offline
against a fake Companion and a CoreMIDI loopback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:00:56 -04:00

60 lines
2.2 KiB
Bash

#!/bin/zsh
# Install or update the status panel watchdog on this Mac (NA Ingest) as a LaunchAgent.
# Re-run after changing status_panel.py, coremidi.py or config.json in this folder.
#
# zsh install.sh install / update and (re)start
# zsh install.sh --remove stop it and remove the LaunchAgent (files stay)
set -e
SRC=${0:A:h}
LABEL=org.waterschurch.status-panel
# App Support, not ~/Documents: launchd-run python3 cannot read ~/Documents.
DEST="$HOME/Library/Application Support/status-panel"
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
DOMAIN="gui/$(id -u)"
if [[ "$1" == "--remove" ]]; then
launchctl bootout "$DOMAIN/$LABEL" 2>/dev/null || true
rm -f "$PLIST"
echo "removed $LABEL (files left in $DEST)"
exit 0
fi
/usr/bin/python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$SRC/config.json"
mkdir -p "$DEST"
if [[ -f "$DEST/config.json" ]] && ! cmp -s "$SRC/config.json" "$DEST/config.json"; then
cp "$DEST/config.json" "$DEST/config.json.bak-$(date +%Y%m%d-%H%M%S)"
fi
cp "$SRC/status_panel.py" "$SRC/coremidi.py" "$SRC/config.json" "$DEST/"
cat > "$PLIST" <<EOF
<?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>/usr/bin/python3</string>
<string>$DEST/status_panel.py</string>
<string>--data-dir</string>
<string>$DEST</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>ThrottleInterval</key><integer>10</integer>
<key>StandardErrorPath</key><string>$HOME/Library/Logs/status-panel.err.log</string>
</dict>
</plist>
EOF
launchctl bootout "$DOMAIN/$LABEL" 2>/dev/null || true
# bootout returns before the old job is gone; bootstrapping too early fails with "5: Input/output error".
for i in {1..50}; do launchctl print "$DOMAIN/$LABEL" >/dev/null 2>&1 || break; sleep 0.2; done
for attempt in 1 2 3; do
launchctl bootstrap "$DOMAIN" "$PLIST" && break
[[ $attempt == 3 ]] && { echo "launchctl bootstrap failed" >&2; exit 1; }
sleep 1
done
echo "installed $LABEL -> $DEST"
echo "log: ~/Library/Logs/status-panel.log"