204 lines
6.9 KiB
Bash
Executable File
204 lines
6.9 KiB
Bash
Executable File
#!/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 ""
|