./run install now also builds the Prospector.app menu-bar tray (~/Applications: ❖ Open/Stop/Quit, AppleScript-ObjC + sips/iconutil, no Swift/deps) and registers the prospector MCP in Claude (Desktop + global, non-invasive). New ./run stop and ./run tray; SKIP_DB/SKIP_TRAY/SKIP_MCP escape hatches. app.sh: --detach (background, for the tray), reuse an already-running instance instead of colliding, fail loudly if a process we started dies, pidfile in .run/. Fix the local front door: a prod build calls /prospector/* (api.ts API_BASE), so vite preview now proxies /prospector (passthrough) while dev keeps /api (rewrite), both injecting the bearer token. find_psql handles keg-only postgresql@N. Verified end-to-end: ./run install (deps/env/DB+5 migrations/build/tray/MCP), ./run app serves markets through the token proxy (200; 401 without token), tray launches resident, web tsc + 160 backend tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
95 lines
3.7 KiB
Bash
Executable file
95 lines
3.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Build (and install) the Prospector menu-bar tray app: a macOS .app bundle that
|
|
# shows a status-bar icon with Open / Stop / Quit, launching the local app via
|
|
# ./run. No Swift, no deps — AppleScript-ObjC + built-in icon tooling.
|
|
#
|
|
# scripts/make-tray.sh build into ~/Applications/Prospector.app
|
|
# TRAY_DEST=/path/Prospector.app override install location
|
|
# ./run tray (preferred entrypoint)
|
|
set -euo pipefail
|
|
|
|
. "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
|
|
DEST="${TRAY_DEST:-$HOME/Applications/Prospector.app}"
|
|
SVG="$REPO_ROOT/web/public/icon.svg"
|
|
[[ -f "$SVG" ]] || die "icon not found at $SVG"
|
|
|
|
NODE_BIN="$(dirname "$(command -v node)")"
|
|
[[ -n "$NODE_BIN" ]] || die "node not found on PATH"
|
|
|
|
WORK="$(mktemp -d)"
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
|
|
# 1. Rasterize the SVG (qlmanage renders crisply at 1024; sips is the fallback).
|
|
BASE="$WORK/base.png"
|
|
if qlmanage -t -s 1024 -o "$WORK" "$SVG" >/dev/null 2>&1 && [[ -f "$WORK/icon.svg.png" ]]; then
|
|
mv "$WORK/icon.svg.png" "$BASE"
|
|
else
|
|
sips -s format png "$SVG" --out "$BASE" >/dev/null
|
|
fi
|
|
|
|
# 2. Assemble the bundle skeleton.
|
|
info "building $DEST"
|
|
rm -rf "$DEST"
|
|
mkdir -p "$DEST/Contents/MacOS" "$DEST/Contents/Resources"
|
|
RES="$DEST/Contents/Resources"
|
|
|
|
# 3. AppIcon.icns (full iconset) + tray.png (menu-bar size).
|
|
ICONSET="$WORK/AppIcon.iconset"; mkdir -p "$ICONSET"
|
|
for s in 16 32 128 256 512; do
|
|
sips -z "$s" "$s" "$BASE" --out "$ICONSET/icon_${s}x${s}.png" >/dev/null
|
|
d=$(( s * 2 )); sips -z "$d" "$d" "$BASE" --out "$ICONSET/icon_${s}x${s}@2x.png" >/dev/null
|
|
done
|
|
iconutil -c icns "$ICONSET" -o "$RES/AppIcon.icns"
|
|
sips -z 36 36 "$BASE" --out "$RES/tray.png" >/dev/null
|
|
|
|
# 4. Info.plist (LSUIElement = menu-bar only, no Dock icon).
|
|
cat > "$DEST/Contents/Info.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>CFBundleName</key><string>Prospector</string>
|
|
<key>CFBundleDisplayName</key><string>Prospector</string>
|
|
<key>CFBundleIdentifier</key><string>com.transquinnftw.prospector.tray</string>
|
|
<key>CFBundleVersion</key><string>0.1.0</string>
|
|
<key>CFBundleShortVersionString</key><string>0.1.0</string>
|
|
<key>CFBundlePackageType</key><string>APPL</string>
|
|
<key>CFBundleExecutable</key><string>Prospector</string>
|
|
<key>CFBundleIconFile</key><string>AppIcon</string>
|
|
<key>LSUIElement</key><true/>
|
|
<key>LSMinimumSystemVersion</key><string>10.15</string>
|
|
</dict>
|
|
</plist>
|
|
PLIST
|
|
|
|
# 5. Executable stub — runs the tray AppleScript, passing it its Resources dir.
|
|
cat > "$DEST/Contents/MacOS/Prospector" <<'STUB'
|
|
#!/bin/bash
|
|
RES="$(cd "$(dirname "$0")/../Resources" && pwd)"
|
|
exec /usr/bin/osascript "$RES/tray.applescript" "$RES"
|
|
STUB
|
|
chmod +x "$DEST/Contents/MacOS/Prospector"
|
|
|
|
# 6. Tray script + the menu's launch/stop helpers (node bin baked onto PATH, since
|
|
# `do shell script` runs with a minimal PATH that lacks Homebrew node).
|
|
cp "$REPO_ROOT/scripts/tray.applescript" "$RES/tray.applescript"
|
|
cat > "$RES/launch.sh" <<SH
|
|
#!/usr/bin/env bash
|
|
export PATH="$NODE_BIN:\$PATH"
|
|
exec "$REPO_ROOT/run" app --detach
|
|
SH
|
|
cat > "$RES/stop.sh" <<SH
|
|
#!/usr/bin/env bash
|
|
export PATH="$NODE_BIN:\$PATH"
|
|
exec "$REPO_ROOT/run" stop
|
|
SH
|
|
chmod +x "$RES/launch.sh" "$RES/stop.sh"
|
|
|
|
# 7. Validate before declaring success.
|
|
plutil -lint "$DEST/Contents/Info.plist" >/dev/null || die "Info.plist failed validation"
|
|
osacompile -o "$WORK/syntax-check.scpt" "$RES/tray.applescript" >/dev/null || die "tray.applescript failed to compile"
|
|
|
|
ok "tray app built → $DEST"
|
|
echo " Open it once (double-click in ~/Applications or 'open \"$DEST\"') to put the"
|
|
echo " ❖ icon in your menu bar. It survives logout via Login Items if you add it."
|