#!/bin/bash set -euo pipefail # ═══════════════════════════════════════════════════════════ # GooseFactory — First Boot Script # Sets up the complete development environment from scratch. # ═══════════════════════════════════════════════════════════ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" cd "$PROJECT_ROOT" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # No Color print_header() { echo -e "\n${CYAN}═══════════════════════════════════════${NC}"; echo -e "${CYAN} $1${NC}"; echo -e "${CYAN}═══════════════════════════════════════${NC}\n"; } print_step() { echo -e " ${BLUE}→${NC} $1"; } print_ok() { echo -e " ${GREEN}✅${NC} $1"; } print_warn() { echo -e " ${YELLOW}⚠️${NC} $1"; } print_fail() { echo -e " ${RED}❌${NC} $1"; } # ─── Step 1: Check Prerequisites ─── print_header "Step 1: Checking Prerequisites" MISSING=0 # Node.js if command -v node &> /dev/null; then NODE_VERSION=$(node --version) print_ok "Node.js $NODE_VERSION" NODE_MAJOR=$(echo "$NODE_VERSION" | sed 's/v//' | cut -d. -f1) if [ "$NODE_MAJOR" -lt 20 ]; then print_warn "Node.js 20+ recommended (found $NODE_VERSION)" fi else print_fail "Node.js not found — install from https://nodejs.org" MISSING=1 fi # npm if command -v npm &> /dev/null; then print_ok "npm $(npm --version)" else print_fail "npm not found" MISSING=1 fi # Docker if command -v docker &> /dev/null; then print_ok "Docker $(docker --version | awk '{print $3}' | tr -d ',')" else print_warn "Docker not found — needed for PostgreSQL and Redis" print_step "Install from https://www.docker.com/products/docker-desktop/" print_step "Or install PostgreSQL/Redis natively" fi # Docker Compose if command -v docker &> /dev/null && docker compose version &> /dev/null; then print_ok "Docker Compose $(docker compose version --short 2>/dev/null || echo 'available')" elif command -v docker-compose &> /dev/null; then print_ok "Docker Compose (legacy) $(docker-compose --version | awk '{print $4}' | tr -d ',')" else print_warn "Docker Compose not found — needed for dev infrastructure" fi # Rust (optional, for desktop build) if command -v rustc &> /dev/null; then print_ok "Rust $(rustc --version | awk '{print $2}')" else print_warn "Rust not found — needed only for desktop app build" print_step "Install from https://rustup.rs" fi if [ "$MISSING" -eq 1 ]; then print_fail "Missing required prerequisites. Please install them and re-run." exit 1 fi # ─── Step 2: Environment Setup ─── print_header "Step 2: Environment Setup" if [ ! -f .env ]; then cp .env.example .env print_ok "Created .env from .env.example" print_warn "Edit .env to set your JWT_SECRET and other values" else print_ok ".env already exists" fi # Create feedback storage directories mkdir -p ~/.config/goose/factory/feedback mkdir -p ~/.config/goose/factory/memory print_ok "Created feedback storage directories" # ─── Step 3: Install Dependencies ─── print_header "Step 3: Installing Dependencies" print_step "Running npm install (this may take a minute)..." npm install --workspaces --include-workspace-root print_ok "Dependencies installed" # ─── Step 4: Build Shared Package ─── print_header "Step 4: Building Shared Package" npm -w @goosefactory/shared run build print_ok "@goosefactory/shared built" # ─── Step 5: Start Docker Services ─── print_header "Step 5: Starting Infrastructure" if command -v docker &> /dev/null; then print_step "Starting PostgreSQL and Redis..." docker compose -f infra/docker/docker-compose.yml up -d # Wait for PostgreSQL to be ready print_step "Waiting for PostgreSQL..." RETRIES=30 until docker exec goosefactory-postgres pg_isready -U goosefactory -d goosefactory &>/dev/null || [ $RETRIES -eq 0 ]; do RETRIES=$((RETRIES - 1)) sleep 1 done if [ $RETRIES -gt 0 ]; then print_ok "PostgreSQL ready" else print_warn "PostgreSQL may not be ready yet — check 'docker logs goosefactory-postgres'" fi # Wait for Redis to be ready print_step "Waiting for Redis..." RETRIES=10 until docker exec goosefactory-redis redis-cli ping &>/dev/null || [ $RETRIES -eq 0 ]; do RETRIES=$((RETRIES - 1)) sleep 1 done if [ $RETRIES -gt 0 ]; then print_ok "Redis ready" else print_warn "Redis may not be ready — check 'docker logs goosefactory-redis'" fi else print_warn "Docker not available — skipping infrastructure startup" print_step "Make sure PostgreSQL and Redis are running manually" fi # ─── Step 6: Run Database Migrations ─── print_header "Step 6: Database Setup" if command -v docker &> /dev/null && docker exec goosefactory-postgres pg_isready -U goosefactory -d goosefactory &>/dev/null; then print_step "Database schema initialized via init.sql (Docker entrypoint)" print_ok "Database ready" # Seed data from factory if available if [ -f "$SCRIPT_DIR/seed-from-factory.ts" ]; then print_step "Seeding data from MCP factory state..." npx tsx "$SCRIPT_DIR/seed-from-factory.ts" || print_warn "Seed script had issues (non-fatal)" print_ok "Seed data imported" fi else print_warn "Database not accessible — skipping migrations and seeding" fi # ─── Step 7: Verification ─── print_header "Step 7: Verification" # Typecheck shared print_step "Typechecking shared package..." npm -w @goosefactory/shared run typecheck 2>/dev/null && print_ok "Shared types valid" || print_warn "Typecheck had warnings" # ─── Summary ─── print_header "🏭 GooseFactory is Ready!" echo -e " ${GREEN}Start development:${NC}" echo -e " ${BLUE}npm run dev:api${NC} — Start API server (port 4000)" echo -e " ${BLUE}npm run dev:mcp${NC} — Start MCP server" echo -e " ${BLUE}npm run dev:learning${NC} — Start learning pipeline" echo -e " ${BLUE}npm run dev${NC} — Start all services" echo -e "" echo -e " ${GREEN}Infrastructure:${NC}" echo -e " ${BLUE}PostgreSQL${NC} → localhost:5432 (user: goosefactory)" echo -e " ${BLUE}Redis${NC} → localhost:6379" echo -e " ${BLUE}API${NC} → http://localhost:4000" echo -e " ${BLUE}API Health${NC} → http://localhost:4000/health" echo -e "" echo -e " ${GREEN}Useful commands:${NC}" echo -e " ${BLUE}npm run build${NC} — Build all packages" echo -e " ${BLUE}npm run typecheck${NC} — Check types across monorepo" echo -e " ${BLUE}npm run dev:infra:stop${NC} — Stop Docker services" echo -e ""