Last active
October 7, 2025 03:07
-
-
Save michaelneale/a3b192f8889a5f6b4b49830c1aa9b409 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -e | |
| # Configuration | |
| PORT=62996 | |
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| # Check for goosed binary in multiple locations | |
| if command -v goosed &> /dev/null; then | |
| # goosed is on PATH | |
| GOOSED_BINARY="goosed" | |
| elif [ -f "/Applications/Goose.app/Contents/Resources/bin/goosed" ]; then | |
| # Check in macOS app bundle | |
| GOOSED_BINARY="/Applications/Goose.app/Contents/Resources/bin/goosed" | |
| elif [ -f "${SCRIPT_DIR}/target/release/goosed" ]; then | |
| # Check in local build directory | |
| GOOSED_BINARY="${SCRIPT_DIR}/target/release/goosed" | |
| else | |
| GOOSED_BINARY="" | |
| fi | |
| # Color codes for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Generate a random secret (32 character alphanumeric) | |
| SECRET=$(openssl rand -base64 24 | tr -d "=+/" | cut -c1-32) | |
| echo -e "${BLUE}╔════════════════════════════════════════════════════════════════════╗${NC}" | |
| echo -e "${BLUE}║ Goose Remote Access Setup ║${NC}" | |
| echo -e "${BLUE}╚════════════════════════════════════════════════════════════════════╝${NC}" | |
| echo "" | |
| # Check if goosed binary exists | |
| if [ -z "$GOOSED_BINARY" ] || [ ! -f "$GOOSED_BINARY" ]; then | |
| echo -e "${RED}Error: goosed binary not found${NC}" | |
| echo -e "${YELLOW}Checked locations:${NC}" | |
| echo -e " - goosed on PATH" | |
| echo -e " - /Applications/Goose.app/Contents/Resources/bin/goosed" | |
| echo -e " - ${SCRIPT_DIR}/target/release/goosed" | |
| echo -e "${YELLOW}Please build it first with: cargo build --release --bin goosed${NC}" | |
| exit 1 | |
| fi | |
| # Check if qrencode is available for QR code generation | |
| QRENCODE_AVAILABLE=false | |
| if command -v qrencode &> /dev/null; then | |
| QRENCODE_AVAILABLE=true | |
| else | |
| echo -e "${YELLOW}Warning: qrencode is not installed - QR codes will not be available${NC}" | |
| echo -e "${YELLOW}Install it with: brew install qrencode${NC}" | |
| fi | |
| # Check if cloudflared is available | |
| CLOUDFLARED_AVAILABLE=false | |
| if command -v cloudflared &> /dev/null; then | |
| CLOUDFLARED_AVAILABLE=true | |
| else | |
| echo -e "${YELLOW}Warning: cloudflared is not installed - tunnel will not be available${NC}" | |
| echo -e "${YELLOW}Install it with: brew install cloudflared${NC}" | |
| fi | |
| # Cleanup function | |
| cleanup() { | |
| echo -e "\n${YELLOW}Shutting down...${NC}" | |
| if [ ! -z "$GOOSED_PID" ]; then | |
| echo "Stopping goosed (PID: $GOOSED_PID)" | |
| kill $GOOSED_PID 2>/dev/null || true | |
| fi | |
| if [ ! -z "$TUNNEL_PID" ]; then | |
| echo "Stopping tunnel (PID: $TUNNEL_PID)" | |
| kill $TUNNEL_PID 2>/dev/null || true | |
| fi | |
| exit 0 | |
| } | |
| trap cleanup SIGINT SIGTERM EXIT | |
| # Start goosed in the background | |
| echo -e "${GREEN}Starting goosed on port ${PORT}...${NC}" | |
| export GOOSE_PORT=$PORT | |
| export GOOSE_SERVER__SECRET_KEY="$SECRET" | |
| "$GOOSED_BINARY" agent > /dev/null 2>&1 & | |
| GOOSED_PID=$! | |
| # Wait for goosed to be ready | |
| echo "Waiting for goosed to start..." | |
| for i in {1..30}; do | |
| if curl -s "http://localhost:${PORT}/health" > /dev/null 2>&1; then | |
| echo -e "${GREEN}✓ Goosed is running (PID: $GOOSED_PID)${NC}" | |
| break | |
| fi | |
| if [ $i -eq 30 ]; then | |
| echo -e "${RED}Error: goosed failed to start${NC}" | |
| exit 1 | |
| fi | |
| sleep 0.5 | |
| done | |
| # Try to create Cloudflare tunnel if available | |
| TUNNEL_URL="" | |
| CONNECT_URL="" | |
| APP_URL="" | |
| if [ "$CLOUDFLARED_AVAILABLE" = true ]; then | |
| echo -e "${GREEN}Creating Cloudflare tunnel...${NC}" | |
| TUNNEL_LOG=$(mktemp) | |
| cloudflared tunnel --url "http://localhost:${PORT}" > "$TUNNEL_LOG" 2>&1 & | |
| TUNNEL_PID=$! | |
| # Wait for tunnel URL to appear in the log | |
| echo "Waiting for tunnel URL..." | |
| for i in {1..30}; do | |
| # Look for lines like: "https://randomly-generated-name.trycloudflare.com" | |
| if grep -q "https://.*\.trycloudflare\.com" "$TUNNEL_LOG" 2>/dev/null; then | |
| TUNNEL_URL=$(grep -o "https://[a-z0-9-]*\.trycloudflare\.com" "$TUNNEL_LOG" | head -1) | |
| break | |
| fi | |
| if [ $i -eq 30 ]; then | |
| echo -e "${YELLOW}Warning: Failed to get tunnel URL${NC}" | |
| CLOUDFLARED_AVAILABLE=false | |
| break | |
| fi | |
| sleep 0.5 | |
| done | |
| rm -f "$TUNNEL_LOG" | |
| if [ -n "$TUNNEL_URL" ]; then | |
| echo -e "${GREEN}✓ Cloudflare tunnel established (PID: $TUNNEL_PID)${NC}" | |
| # Format the connection URL (remove https:// and add :443) | |
| CONNECT_URL="${TUNNEL_URL#https://}:443" | |
| # Create the configuration JSON for the QR code | |
| CONFIG_JSON="{\"url\":\"${CONNECT_URL}\",\"secret\":\"${SECRET}\"}" | |
| # URL encode the config JSON | |
| URL_ENCODED_CONFIG=$(printf %s "$CONFIG_JSON" | jq -sRr @uri) | |
| # Create the app URL for deep linking (matching tunnel.ts format) | |
| APP_URL="goosechat://configure?data=${URL_ENCODED_CONFIG}" | |
| else | |
| CLOUDFLARED_AVAILABLE=false | |
| fi | |
| fi | |
| echo "" | |
| echo -e "${BLUE}╔════════════════════════════════════════════════════════════════════╗${NC}" | |
| echo -e "${BLUE}║ Connection Information ║${NC}" | |
| echo -e "${BLUE}╚════════════════════════════════════════════════════════════════════╝${NC}" | |
| echo "" | |
| if [ "$CLOUDFLARED_AVAILABLE" = true ] && [ -n "$TUNNEL_URL" ]; then | |
| echo -e "${GREEN}Tunnel URL:${NC} $TUNNEL_URL" | |
| echo -e "${GREEN}Connect URL:${NC} $CONNECT_URL" | |
| echo -e "${GREEN}Secret Key:${NC} $SECRET" | |
| echo -e "${GREEN}Local Port:${NC} $PORT" | |
| echo "" | |
| if [ "$QRENCODE_AVAILABLE" = true ]; then | |
| echo -e "${BLUE}╔════════════════════════════════════════════════════════════════════╗${NC}" | |
| echo -e "${BLUE}║ QR Code (Scan Me!) ║${NC}" | |
| echo -e "${BLUE}╚════════════════════════════════════════════════════════════════════╝${NC}" | |
| echo "" | |
| # Generate and display QR code in terminal | |
| qrencode -t ANSIUTF8 "$APP_URL" | |
| echo "" | |
| echo -e "${BLUE}────────────────────────────────────────────────────────────────────${NC}" | |
| echo -e "${YELLOW}App URL:${NC} $APP_URL" | |
| echo -e "${BLUE}────────────────────────────────────────────────────────────────────${NC}" | |
| echo "" | |
| fi | |
| echo -e "${GREEN}✓ Everything is running!${NC}" | |
| echo -e "${YELLOW}Press Ctrl+C to stop the server and tunnel${NC}" | |
| else | |
| echo -e "${YELLOW}⚠ Unable to launch cloudflare tunnel${NC}" | |
| echo "" | |
| echo -e "${GREEN}Local URL:${NC} http://localhost:${PORT}" | |
| echo -e "${GREEN}Secret Key:${NC} $SECRET" | |
| echo "" | |
| echo -e "${YELLOW}Note: Server is only accessible locally without tunnel${NC}" | |
| echo -e "${GREEN}✓ Goosed is running locally!${NC}" | |
| echo -e "${YELLOW}Press Ctrl+C to stop the server${NC}" | |
| fi | |
| echo "" | |
| # Keep the script running | |
| wait |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment