#!/bin/bash # # DSS - Design System Server # # Portable single-server launcher. One command, one port, everything included. # # Usage: # ./dss start Start DSS (UI + API on port 3456) # ./dss dev Development mode with auto-reload # ./dss stop Stop DSS server # ./dss status Check service status # ./dss config Show current configuration # ./dss help Show this help # set -e DSS_ROOT="$(cd "$(dirname "$0")/.." && pwd)" API_DIR="$DSS_ROOT/apps/api" UI_DIR="$DSS_ROOT/admin-ui" VENV_DIR="$DSS_ROOT/.venv" PID_FILE="$DSS_ROOT/.dss/dss.pid" LOG_FILE="$DSS_ROOT/.dss/dss.log" PORT="${DSS_PORT:-3456}" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Ensure .dss directory exists mkdir -p "$DSS_ROOT/.dss" log() { echo -e "${BLUE}[DSS]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" >&2 } success() { echo -e "${GREEN}[OK]${NC} $1" } warn() { echo -e "${YELLOW}[WARN]${NC} $1" } # Check Python and dependencies check_deps() { if ! command -v python3 &> /dev/null; then error "Python 3 is required but not installed" exit 1 fi # Check if venv exists if [ ! -d "$VENV_DIR" ]; then log "Creating virtual environment..." python3 -m venv "$VENV_DIR" fi # Activate venv source "$VENV_DIR/bin/activate" # Check if dependencies installed if ! python3 -c "import fastapi" 2>/dev/null; then log "Installing dependencies..." pip install -q -r "$DSS_ROOT/requirements.txt" fi } # Start server start_server() { local dev_mode="$1" check_deps if [ -f "$PID_FILE" ]; then if kill -0 $(cat "$PID_FILE") 2>/dev/null; then warn "DSS is already running (PID: $(cat $PID_FILE))" return 0 else rm -f "$PID_FILE" fi fi cd "$API_DIR" # Build command - single server serves UI + API local cmd="python3 -m uvicorn server:app --host 0.0.0.0 --port $PORT" if [ "$dev_mode" = "true" ]; then cmd="$cmd --reload" log "Starting DSS in development mode..." else log "Starting DSS server..." fi # Export Python path (project root for dss package) export PYTHONPATH="$DSS_ROOT:$PYTHONPATH" export PORT="$PORT" if [ "$dev_mode" = "true" ]; then # Run in foreground for dev $cmd else # Run in background nohup $cmd > "$LOG_FILE" 2>&1 & echo $! > "$PID_FILE" sleep 2 if kill -0 $(cat "$PID_FILE") 2>/dev/null; then success "DSS started (PID: $(cat $PID_FILE))" echo "" log "Dashboard: http://localhost:$PORT" log "API: http://localhost:$PORT/api" log "Docs: http://localhost:$PORT/docs" log "Logs: $LOG_FILE" else error "Failed to start DSS. Check $LOG_FILE" exit 1 fi fi } # Stop server stop_server() { if [ ! -f "$PID_FILE" ]; then warn "DSS is not running" return 0 fi local pid=$(cat "$PID_FILE") if kill -0 $pid 2>/dev/null; then log "Stopping DSS (PID: $pid)..." kill $pid rm -f "$PID_FILE" success "DSS stopped" else rm -f "$PID_FILE" warn "DSS was not running" fi } # Check status check_status() { echo "" echo "╔═══════════════════════════════════════════════════════════════╗" echo "║ Design System Server (DSS) - Status ║" echo "╚═══════════════════════════════════════════════════════════════╝" echo "" # Check if running if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then success "Server: Running (PID: $(cat $PID_FILE))" else warn "Server: Not running" fi # Check API health if curl -s http://localhost:$PORT/health > /dev/null 2>&1; then local health=$(curl -s http://localhost:$PORT/health) success "API: Healthy on port $PORT" echo " Mode: $(echo $health | python3 -c "import sys,json; print(json.load(sys.stdin).get('figma_mode','unknown'))" 2>/dev/null || echo 'unknown')" else warn "API: Not responding on port $PORT" fi # Check Admin UI if curl -s http://localhost:$PORT/ > /dev/null 2>&1; then success "UI: Served at http://localhost:$PORT" fi # Check companion services echo "" log "Companion services:" for svc_port in 6006 5173; do if nc -z localhost $svc_port 2>/dev/null; then case $svc_port in 6006) success " Storybook: Running on :$svc_port" ;; 5173) success " Vite: Running on :$svc_port" ;; esac fi done echo "" } # Show configuration show_config() { check_deps echo "" echo "═══════════════════════════════════════════════════" echo " DSS Configuration" echo "═══════════════════════════════════════════════════" echo "" if curl -s http://localhost:3456/api/config > /dev/null 2>&1; then curl -s http://localhost:3456/api/config | python3 -m json.tool else warn "DSS not running. Showing file-based config..." if [ -f "$DSS_ROOT/.dss/runtime-config.json" ]; then cat "$DSS_ROOT/.dss/runtime-config.json" | python3 -m json.tool else log "No configuration file found" fi fi echo "" } # Show help show_help() { echo "" echo "╔═══════════════════════════════════════════════════════════════╗" echo "║ Design System Server (DSS) ║" echo "║ Portable design system companion & server ║" echo "╚═══════════════════════════════════════════════════════════════╝" echo "" echo "Usage: ./dss " echo "" echo "Commands:" echo " start Start DSS (UI + API on single port)" echo " stop Stop DSS server" echo " restart Restart DSS server" echo " dev Development mode (foreground, auto-reload)" echo " status Check service status" echo " config Show current configuration" echo " logs Tail server logs" echo " help Show this help" echo "" echo "Environment:" echo " DSS_PORT Override default port (default: 3456)" echo "" echo "Examples:" echo " ./dss start # Start on port 3456" echo " DSS_PORT=8080 ./dss start # Start on port 8080" echo " ./dss dev # Dev mode with auto-reload" echo "" echo "Once running, open http://localhost:3456 for:" echo " / Dashboard (Admin UI)" echo " /api/* REST API endpoints" echo " /docs Swagger documentation" echo " /api/config Runtime configuration" echo "" } # Tail logs tail_logs() { if [ -f "$LOG_FILE" ]; then tail -f "$LOG_FILE" else error "No log file found at $LOG_FILE" fi } # Main case "${1:-help}" in start) start_server "false" ;; stop) stop_server ;; restart) stop_server sleep 1 start_server "false" ;; dev) start_server "true" ;; status) check_status ;; config) show_config ;; logs) tail_logs ;; help|--help|-h) show_help ;; *) error "Unknown command: $1" show_help exit 1 ;; esac