#!/bin/bash # ============================================================================ # ProofLab macOS Setup Script # # USAGE: # Mount share (Finder Cmd+K): smb://192.170.1.10/Prooflab # Double-click setup_prooflab.command from macos/ folder # Or: bash /Volumes/Prooflab/ProofLab/macos/setup_prooflab.command # # WHAT THIS DOES: # 1. Installs Hammerspoon (free hotkey manager) # 2. Configures ProofLab hotkeys # 3. Adds SMB share to login items (optional) # # REQUIREMENTS: # - macOS 10.15+ (Catalina or later) # - Admin password # - Network access to ProofLab SMB share # # ============================================================================ set -e # Exit on error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color echo "" echo "======================================" echo " ProofLab macOS Setup" echo "======================================" echo "" # ───────────────────────────────────────────────────────────────────────────── # CONFIGURATION - Auto-detect share path from script location # ───────────────────────────────────────────────────────────────────────────── # Resolve script location SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PARENT_DIR="$(dirname "$SCRIPT_DIR")" # Support both layouts: # A) .../ProofLab/macos/setup_prooflab.command # B) .../ProofLab/Tools/macos/setup_prooflab.command if [ -d "$PARENT_DIR/src" ]; then PROOFLAB_ROOT="$PARENT_DIR" elif [ -d "$PARENT_DIR/../src" ]; then PROOFLAB_ROOT="$(cd "$PARENT_DIR/.." && pwd)" else # Fallback: keep parent as root and let runtime checks report missing files. PROOFLAB_ROOT="$PARENT_DIR" fi # SMB share URL (for Connect to Server) SMB_URL="smb://192.170.1.10/Prooflab" # Path to ProofLab source on the share PROOFLAB_SRC="$PROOFLAB_ROOT/src" # Path to Hammerspoon config file (same folder as this setup script) HAMMERSPOON_CONFIG_SRC="$SCRIPT_DIR/prooflab_hotkeys.lua" # Local hidden runtime root for ProofLab core (launcher target on macOS) LOCAL_CORE_ROOT="$HOME/Library/Application Support/ProofLab/core" # ───────────────────────────────────────────────────────────────────────────── # STEP 1: Check if SMB share is mounted # ───────────────────────────────────────────────────────────────────────────── echo -e "${YELLOW}Step 1: Checking SMB share...${NC}" if [ ! -d "$PROOFLAB_ROOT" ]; then echo -e "${RED}ERROR: ProofLab share not mounted at $PROOFLAB_ROOT${NC}" echo "" echo "Please mount the share first:" echo " 1. Open Finder" echo " 2. Press Cmd+K" echo " 3. Enter: $SMB_URL" echo " 4. Click Connect and enter credentials" echo " 5. Run this script again" echo "" read -p "Press Enter to exit..." exit 1 fi echo -e "${GREEN}✓ SMB share is mounted${NC}" # ───────────────────────────────────────────────────────────────────────────── # STEP 1B: Sync local hidden ProofLab runtime # ───────────────────────────────────────────────────────────────────────────── echo "" echo -e "${YELLOW}Step 1B: Syncing local hidden ProofLab runtime...${NC}" mkdir -p "$LOCAL_CORE_ROOT/src" mkdir -p "$LOCAL_CORE_ROOT/macos" if command -v rsync >/dev/null 2>&1; then rsync -a --delete "$PROOFLAB_SRC/" "$LOCAL_CORE_ROOT/src/" else rm -rf "$LOCAL_CORE_ROOT/src" mkdir -p "$LOCAL_CORE_ROOT/src" cp -R "$PROOFLAB_SRC"/. "$LOCAL_CORE_ROOT/src/" fi cp "$HAMMERSPOON_CONFIG_SRC" "$LOCAL_CORE_ROOT/macos/prooflab_hotkeys.lua" echo "$PROOFLAB_ROOT" > "$LOCAL_CORE_ROOT/.prooflab-core-source-path" echo -e "${GREEN}✓ Local runtime ready at $LOCAL_CORE_ROOT${NC}" # ───────────────────────────────────────────────────────────────────────────── # STEP 2: Install Hammerspoon # ───────────────────────────────────────────────────────────────────────────── echo "" echo -e "${YELLOW}Step 2: Installing Hammerspoon...${NC}" if [ -d "/Applications/Hammerspoon.app" ]; then echo -e "${GREEN}✓ Hammerspoon already installed${NC}" else echo "Downloading Hammerspoon..." TEMP_DIR=$(mktemp -d) ZIP_FILE="$TEMP_DIR/Hammerspoon.zip" # Use direct release URL (0.9.100) - "latest" redirect can fail on some networks HAMMERSPOON_URL="https://github.com/Hammerspoon/hammerspoon/releases/download/0.9.100/Hammerspoon-0.9.100.zip" if ! curl -L -f -o "$ZIP_FILE" "$HAMMERSPOON_URL" 2>/dev/null; then echo "" echo -e "${YELLOW}Download failed. Try installing via Homebrew instead:${NC}" echo " brew install --cask hammerspoon" echo "" echo "Then run this script again." rm -rf "$TEMP_DIR" read -p "Press Enter to close..." exit 1 fi if [ ! -s "$ZIP_FILE" ] || ! unzip -t "$ZIP_FILE" >/dev/null 2>&1; then echo -e "${RED}Downloaded file is invalid (not a zip). Try: brew install --cask hammerspoon${NC}" rm -rf "$TEMP_DIR" read -p "Press Enter to close..." exit 1 fi echo "Extracting..." unzip -q "$ZIP_FILE" -d "$TEMP_DIR" echo "Installing to /Applications (admin password required)..." sudo mv "$TEMP_DIR/Hammerspoon.app" /Applications/ rm -rf "$TEMP_DIR" echo -e "${GREEN}✓ Hammerspoon installed${NC}" fi # ───────────────────────────────────────────────────────────────────────────── # STEP 3: Configure Hammerspoon # ───────────────────────────────────────────────────────────────────────────── echo "" echo -e "${YELLOW}Step 3: Configuring Hammerspoon hotkeys...${NC}" # Create Hammerspoon config directory HAMMERSPOON_DIR="$HOME/.hammerspoon" mkdir -p "$HAMMERSPOON_DIR" # Create init.lua that loads ProofLab config from SMB share (uses detected path) cat > "$HAMMERSPOON_DIR/init.lua" << EOF -- Hammerspoon Configuration for ProofLab -- Local-first runtime with SMB fallback local localCoreRoot = "$LOCAL_CORE_ROOT" local localConfigPath = localCoreRoot .. "/macos/prooflab_hotkeys.lua" local shareRootPath = "$PROOFLAB_ROOT" local shareConfigPath = "$HAMMERSPOON_CONFIG_SRC" local function pathExists(path, expectedMode) local attrs = hs.fs and hs.fs.attributes(path) if not attrs then return false end if expectedMode then return attrs.mode == expectedMode end return true end local function isLocalReady() return pathExists(localCoreRoot .. "/src", "directory") and pathExists(localConfigPath, "file") end local function isShareReady() return pathExists(shareRootPath, "directory") and pathExists(shareConfigPath, "file") end local function resolveConfigPath() if isLocalReady() then return localConfigPath, "local" end if isShareReady() then return shareConfigPath, "share" end return nil, "missing" end -- Load ProofLab hotkeys local function loadProofLabConfig() local configPath, mode = resolveConfigPath() if not configPath then hs.notify.show("ProofLab", "Warning", "No local/share runtime found. Hotkeys disabled.") print("ProofLab runtime missing. Checked local and share locations.") return end _G._PROOFLAB_SHARE_PATH = shareRootPath _G._PROOFLAB_LOCAL_CORE_PATH = localCoreRoot local chunk, err = loadfile(configPath) if chunk then chunk() hs.notify.show("ProofLab", "Hotkeys Loaded", "Source: " .. mode) print("Loaded ProofLab config (" .. mode .. "): " .. configPath) else hs.notify.show("ProofLab", "Error", "Failed to load config: " .. (err or "unknown")) print("Failed to load ProofLab config: " .. (err or "unknown")) end end -- Load on startup loadProofLabConfig() -- Provide a way to reload (Cmd+Ctrl+R) hs.hotkey.bind({"cmd", "ctrl"}, "R", function() hs.reload() end) -- Watch for share mount/unmount and reload when available. if pathExists(shareRootPath, "directory") then local watcher = hs.pathwatcher.new(shareRootPath, function(_) loadProofLabConfig() end) watcher:start() end EOF echo -e "${GREEN}✓ Hammerspoon configured${NC}" # ───────────────────────────────────────────────────────────────────────────── # STEP 4: Add Hammerspoon to Login Items # ───────────────────────────────────────────────────────────────────────────── echo "" echo -e "${YELLOW}Step 4: Adding Hammerspoon to login items...${NC}" osascript << 'EOF' tell application "System Events" make login item at end with properties {path:"/Applications/Hammerspoon.app", hidden:false} end tell EOF echo -e "${GREEN}✓ Hammerspoon will start automatically on login${NC}" # ───────────────────────────────────────────────────────────────────────────── # STEP 5: Start Hammerspoon # ───────────────────────────────────────────────────────────────────────────── echo "" echo -e "${YELLOW}Step 5: Starting Hammerspoon...${NC}" open -a Hammerspoon echo -e "${GREEN}✓ Hammerspoon started${NC}" # ───────────────────────────────────────────────────────────────────────────── # DONE # ───────────────────────────────────────────────────────────────────────────── echo "" echo "======================================" echo -e "${GREEN} ProofLab Setup Complete!${NC}" echo "======================================" echo "" echo "IMPORTANT: Hammerspoon needs Accessibility permissions" echo " 1. A prompt should appear - click 'Open System Preferences'" echo " 2. Click the lock icon and enter your password" echo " 3. Check the box next to 'Hammerspoon'" echo "" echo "HOTKEYS (when Illustrator is active):" echo " Cmd+Ctrl+N - Laboratory (Auto-fix + ProofLab)" echo " Cmd+Ctrl+0 - Swatch Panel" echo " Ctrl+Option+S - Setup Artboard Variables" echo " Ctrl+Shift+P - PDB Garment Picker (browser)" echo " Ctrl+Shift+G - Place Garment" echo " Ctrl+Option+L - ProofLab Control Panel" echo " Cmd+Ctrl+R - Reload hotkeys" echo "" echo "PDB GARMENT PICKER (optional):" echo " One-time: Open server/ folder, run setup-pdb-bridge.command" echo " Daily: Run start-pdb-bridge.command in server/ when using the picker" echo "" echo "If the share disconnects, hotkeys will auto-reload when reconnected." echo "" read -p "Press Enter to close..."