▍ humdrum codex / ticktock v0.0.2
license AGPL-3.0
2.9 KB raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env bash
# Repoint the com.humdrum.ticktock.autotrack launchd agent at `tt autotrack`.
#
# Rollback: the Python daemon in ticktock-old is untouched — re-run
#   ~/Developer/Home/ticktock-old/daemon/install-daemon.sh
# (note: it installs under the old com.ticktock.autotrack label; bootout the
# com.humdrum one first) or hand-edit the plist back to autotrack.py.
set -euo pipefail
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TT="$REPO/bin/tt"
LABEL="com.humdrum.ticktock.autotrack"
PLIST="${HOME}/Library/LaunchAgents/${LABEL}.plist"

[ -x "$TT" ] || { echo "missing $TT — run: make build helpers" >&2; exit 1; }
mkdir -p "${HOME}/.local/share/ticktock" "${HOME}/Library/LaunchAgents"

# Prove the new binary actually runs before we touch the live agent. If this
# fails we bail out here, with the Python daemon still installed and running.
echo "smoke-testing ${TT} autotrack --once ..."
if ! "$TT" autotrack --once >/dev/null 2>&1; then
  echo "✗ ${TT} autotrack --once failed — aborting, Python daemon left running" >&2
  exit 1
fi

sed -e "s#@TT@#${TT}#g" -e "s#@HOME@#${HOME}#g" \
  "$REPO/deploy/autotrack.plist.template" > "$PLIST"

launchctl bootout "gui/$(id -u)/${LABEL}" 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" "$PLIST"

# bootout/bootstrap can race: bootout can return before the old job is fully
# torn down, making bootstrap report success while the new job never reaches
# "running". Give it a moment, then confirm and force a (re)start if needed
# rather than silently leaving no daemon in place.
sleep 1
state="$(launchctl print "gui/$(id -u)/${LABEL}" 2>/dev/null | awk '/state = /{print $3; exit}')"
if [ "$state" != "running" ]; then
  echo "  ${LABEL} not running yet (state: ${state:-unknown}) — kickstarting..." >&2
  launchctl kickstart -k "gui/$(id -u)/${LABEL}" 2>/dev/null || true
  sleep 1
  state="$(launchctl print "gui/$(id -u)/${LABEL}" 2>/dev/null | awk '/state = /{print $3; exit}')"
fi
if [ "$state" != "running" ]; then
  echo "✗ ${LABEL} did not reach 'running' state (state: ${state:-unknown})." >&2
  echo "  Check: launchctl print gui/$(id -u)/${LABEL}" >&2
  echo "  Rollback: see the header of this script." >&2
  exit 1
fi

echo "✓ ${LABEL}${TT} autotrack  (${PLIST})"
echo "  verify: launchctl print gui/$(id -u)/${LABEL} | grep -E 'state|program'"
echo "  logs:   tail -f ~/.local/share/ticktock/autotrack.err"
echo
echo "IMPORTANT — macOS permissions do NOT carry over from the old daemon:"
echo "  ${TT} is a new binary, so Accessibility, Automation (System Events /"
echo "  browser control), and Calendar access must be re-granted in System"
echo "  Settings → Privacy & Security for ${TT} (and its winctx helper)."
echo "  Until granted, autotrack degrades silently instead of erroring."
echo "  Trigger the permission prompts now from Terminal:"
echo "    \"$TT\" autotrack --once"
echo "    \"$TT\" autotrack --list-calendars"