curtain/Scripts/install.sh
Aric Camarata 8c19e960d2 Detection root-cause fix + audit batch: netstat path, UDP activator, settings coherence, refactor, docs
Detection: netstat lives at /usr/sbin/netstat, not /usr/bin — the hardcoded wrong
path silently killed the ESTABLISHED-TCP activator (root cause of the failed live
test). Fixed and live-verified. Added peered-UDP activator (5900-5902) for
High-Performance sessions, per-signal transition logging, unconditional error
logging for dead probe helpers, and probe v2 with full CGSession dictionary
diffing. 7 new parser tests (32 total).

Fixes from a full audit + adversarial review: idle source setting honored
(default now Remote session activity), cover scope reduced to a coherent
two-mode model with legacy migration (per-display toggle was inverted in
onlyMarked and dead in all), curtain test no longer schedules a teardown over a
live session, specific-display password box placement gets a real picker,
refuse-to-arm enforced, activation notification posts a real banner, menu
password gate bypassed when the event tap is dead, shared single-decoder aerial
player with stale-task guard and async playability check, password buffer zeroed
on successful unlock and Esc, XPC interruption/invalidation handlers, modern
Accessibility settings URL, launchPath modernized, codesign failures now abort
release.sh, monotonic CFBundleVersion, install.sh temp cleanup, dead
armDisarmHotkey setting removed.

Refactor: Curtain.swift and PreferencesWindow.swift split into focused files
(largest now 479 lines). Wiki, README, and contributing docs updated to match.
Build clean at 0 warnings, 32/32 tests pass.
2026-06-09 20:36:30 -04:00

45 lines
1.7 KiB
Bash
Executable file

#!/bin/bash
# Curtain local installer (developer convenience — end users drag the .app
# from the .dmg instead). Builds a release Curtain.app and drops it in
# /Applications, ad-hoc signed.
#
# Login-at-login and the optional Screen Sharing disconnect helper are now
# managed from inside the app via SMAppService — this script no longer writes
# a LaunchAgent, a /usr/local/bin helper, or a sudoers rule.
set -euo pipefail
REPO="$(cd "$(dirname "$0")/.." && pwd)"
APP="/Applications/Curtain.app"
# Prefer the full release pipeline (icon, daemon plist, dmg) when present.
if [ -x "$REPO/Scripts/release.sh" ]; then
echo "==> Building via release pipeline…"
"$REPO/Scripts/release.sh"
SRC="$REPO/dist/Curtain.app"
else
echo "==> Building (release)…"
cd "$REPO"
swift build -c release
TMP_PARENT="$(mktemp -d)"
trap 'rm -rf "$TMP_PARENT"' EXIT
SRC="$TMP_PARENT/Curtain.app"
mkdir -p "$SRC/Contents/MacOS"
cp "$REPO/.build/release/Curtain" "$SRC/Contents/MacOS/Curtain"
cp "$REPO/.build/release/CurtainHelper" "$SRC/Contents/MacOS/CurtainHelper"
codesign --force --options runtime --sign - "$SRC" 2>/dev/null || true
fi
echo "==> Installing $APP"
rm -rf "$APP"
cp -R "$SRC" "$APP"
echo
echo "✅ Curtain installed to $APP"
echo
echo "Manual step (required so Curtain can block desk input):"
echo " System Settings → Privacy & Security → Accessibility → enable \"Curtain\"."
echo
echo "Open Curtain, then in its settings:"
echo " • Open at Login and the optional disconnect daemon are registered from"
echo " inside the app (SMAppService) — no terminal commands needed."
echo " • Set a desk password, and mark DisplayLink monitors if you use them."