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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
#!/bin/bash
# launch.command — double-click to start the Personal Dashboard and open it.
# Builds on first run (or after updates), starts the local server on :4317,
# waits until it's healthy, then opens the browser. Safe to run repeatedly.
set -euo pipefail
# Finder-launched scripts get a minimal PATH — add Homebrew + common bins.
# node@22 must come first: better-sqlite3's prebuilt binary won't build under
# the default Homebrew node (v26), so pin the build/run to node@22.
export PATH="/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
PORT=4317
URL="http://localhost:${PORT}"
# Repo = parent of this script's dir, regardless of where it's launched from.
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO"
echo "Personal Dashboard → $REPO"
# This repo lives under ~/Documents, which iCloud syncs. iCloud churns and
# evicts the rapidly-rewritten build cache (.next) and can corrupt the open
# SQLite DB. Redirect those local artifacts to *.nosync dirs (iCloud ignores
# any path ending in .nosync) via symlinks, so the paths stay the same.
for d in .next data editions; do
if [ ! -L "$d" ]; then
[ -d "$d" ] && mv "$d" "$d.nosync" # preserve existing contents (e.g. the DB)
mkdir -p "$d.nosync"
ln -snf "$d.nosync" "$d"
fi
done
# Already running? Just open it.
if curl -sf "${URL}/api/health" >/dev/null 2>&1; then
echo "Already running. Opening $URL"
open "$URL"
exit 0
fi
# Ensure dependencies.
if [ ! -d node_modules ]; then
echo "Installing dependencies…"
pnpm install
fi
# Ensure the local database exists.
if [ ! -f data/dashboard.db ]; then
echo "Setting up database…"
pnpm db:push
pnpm db:seed
fi
# Build if there's no production build yet (pass --rebuild to force).
if [ "${1:-}" = "--rebuild" ] || [ ! -f .next/BUILD_ID ]; then
echo "Building (first run / --rebuild)…"
pnpm build
fi
echo "Starting server on :${PORT}…"
pnpm start &
SERVER_PID=$!
# Wait for health, then open the browser.
for _ in $(seq 1 60); do
if curl -sf "${URL}/api/health" >/dev/null 2>&1; then
echo "Ready. Opening $URL"
open "$URL"
break
fi
sleep 1
done
# Keep the server in the foreground so closing this window stops it.
wait "$SERVER_PID"
|