.PHONY: dev backend frontend test test-backend test-frontend test-setup \ stop-backend stop-frontend stop-ollama reset \ start-ollama start-backend start-frontend up restart \ status logs help help: @# Use color only when output is a TTY. Keep plain output for logs/CI. @is_tty=0; if [ -t 1 ]; then is_tty=1; fi; \ if [ $$is_tty -eq 1 ]; then \ BOLD=$$(printf '\033[1m'); DIM=$$(printf '\033[2m'); RESET=$$(printf '\033[0m'); \ CYAN=$$(printf '\033[36m'); GREEN=$$(printf '\033[32m'); YELLOW=$$(printf '\033[33m'); \ else \ BOLD=""; DIM=""; RESET=""; CYAN=""; GREEN=""; YELLOW=""; \ fi; \ printf "%sLLM Council%s %sMake targets%s\n" "$$BOLD" "$$RESET" "$$DIM" "$$RESET"; \ printf "\n"; \ printf "%sCore%s\n" "$$CYAN" "$$RESET"; \ printf " %smake dev%s Start backend + frontend (foreground, Ctrl+C to stop)\n" "$$GREEN" "$$RESET"; \ printf " %smake up%s Start ollama + backend + frontend (background via nohup)\n" "$$GREEN" "$$RESET"; \ printf " %smake restart%s Reset (stop) then start everything (up)\n" "$$GREEN" "$$RESET"; \ printf "\n"; \ printf "%sStart/Stop%s\n" "$$CYAN" "$$RESET"; \ printf " %smake start-ollama%s Start Ollama (systemd if available, else 'ollama serve' nohup)\n" "$$GREEN" "$$RESET"; \ printf " %smake start-backend%s Start backend (nohup, logs: %s/tmp/llm-council-backend.log%s)\n" "$$GREEN" "$$RESET" "$$DIM" "$$RESET"; \ printf " %smake start-frontend%s Start frontend (nohup, logs: %s/tmp/llm-council-frontend.log%s)\n" "$$GREEN" "$$RESET" "$$DIM" "$$RESET"; \ printf " %smake stop-backend%s Stop backend on port %s8001%s\n" "$$GREEN" "$$RESET" "$$YELLOW" "$$RESET"; \ printf " %smake stop-frontend%s Stop frontend on port %s5173%s\n" "$$GREEN" "$$RESET" "$$YELLOW" "$$RESET"; \ printf " %smake stop-ollama%s Attempt to stop Ollama (systemd if available)\n" "$$GREEN" "$$RESET"; \ printf " %smake reset%s Stop frontend + backend + attempt Ollama stop\n" "$$GREEN" "$$RESET"; \ printf "\n"; \ printf "%sTesting / setup%s\n" "$$CYAN" "$$RESET"; \ printf " %smake test%s Run backend + frontend tests\n" "$$GREEN" "$$RESET"; \ printf " %smake test-backend%s Run backend unit tests\n" "$$GREEN" "$$RESET"; \ printf " %smake test-frontend%s Run frontend tests\n" "$$GREEN" "$$RESET"; \ printf " %smake test-setup%s Create a new conversation, upload TEST_DOCS, prefill TEST_MESSAGE in UI\n" "$$GREEN" "$$RESET"; \ printf " %sEnv:%s TEST_DOCS=path1.md,path2.md TEST_MESSAGE='your msg'\n" "$$DIM" "$$RESET"; \ printf "\n"; \ printf "%sDiagnostics%s\n" "$$CYAN" "$$RESET"; \ printf " %smake status%s Show whether backend/frontend/ollama are up + PIDs + basic info\n" "$$GREEN" "$$RESET"; \ printf " %smake logs%s Tail recent backend/frontend logs (from /tmp)\n" "$$GREEN" "$$RESET"; \ printf "\n"; \ printf "%sHelp%s\n" "$$CYAN" "$$RESET"; \ printf " %smake help%s Show this message\n" "$$GREEN" "$$RESET" backend: uv run python -m backend.main frontend: cd frontend && npm run dev dev: ./start.sh test-backend: uv run python -m unittest discover -s backend/tests -p "test_*.py" -q test-frontend: cd frontend && npm test test: test-backend test-frontend stop-backend: @echo "Stopping backend processes on port 8001..." @if lsof -ti:8001 > /dev/null 2>&1; then \ lsof -ti:8001 | xargs kill -9 2>/dev/null || true; \ echo "✓ Backend stopped"; \ sleep 1; \ else \ echo "✓ No backend process found on port 8001"; \ fi stop-frontend: @echo "Stopping frontend processes on port 5173..." @if lsof -ti:5173 > /dev/null 2>&1; then \ lsof -ti:5173 | xargs kill -9 2>/dev/null || true; \ echo "✓ Frontend stopped"; \ sleep 1; \ else \ echo "✓ No frontend process found on port 5173"; \ fi stop-ollama: @echo "Stopping Ollama..." @# Prefer systemd if available; do not force-kill processes (safer). @if command -v systemctl >/dev/null 2>&1; then \ if systemctl is-active --quiet ollama 2>/dev/null; then \ echo "Stopping systemd service: ollama"; \ systemctl stop ollama 2>/dev/null || true; \ sleep 2; \ else \ echo "Ollama systemd service is not active"; \ fi; \ else \ echo "systemctl not found (not a systemd environment)"; \ fi @PIDS=$$(pgrep -x ollama 2>/dev/null || true); \ if [ -n "$$PIDS" ]; then \ echo "⚠️ Ollama processes still running (PIDs: $$PIDS)"; \ echo " Stop manually with one of:"; \ echo " - systemctl stop ollama (if installed as a service)"; \ echo " - pkill -x ollama"; \ echo " - sudo pkill -x ollama"; \ else \ echo "✓ Ollama is stopped"; \ fi reset: stop-frontend stop-backend stop-ollama @echo "" @echo "✓ Reset complete - Frontend/Backend stopped (Ollama stop attempted)" @echo "" @echo "To start fresh (recommended):" @echo " make up" @echo "" @echo "Or manually:" @echo " 1) make start-ollama" @echo " 2) make start-backend" @echo " 3) make start-frontend" start-ollama: @echo "Starting Ollama..." @if curl -s --max-time 2 http://localhost:11434/api/tags >/dev/null 2>&1; then \ echo "✓ Ollama already responding on http://localhost:11434"; \ exit 0; \ fi @if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files 2>/dev/null | grep -q "^ollama\\.service"; then \ echo "Starting systemd service: ollama"; \ systemctl start ollama 2>/dev/null || true; \ sleep 2; \ else \ echo "systemd service not available; starting 'ollama serve' in background"; \ nohup ollama serve > /tmp/llm-council-ollama.log 2>&1 & \ echo "ollama serve PID: $$!"; \ sleep 2; \ fi @if curl -s --max-time 2 http://localhost:11434/api/tags >/dev/null 2>&1; then \ echo "✓ Ollama is up: http://localhost:11434"; \ else \ echo "⚠️ Ollama did not respond yet. Check: /tmp/llm-council-ollama.log"; \ fi start-backend: @echo "Starting backend..." @if curl -s --max-time 2 http://localhost:8001/ >/dev/null 2>&1; then \ echo "✓ Backend already responding on http://localhost:8001"; \ exit 0; \ fi @nohup uv run python -m backend.main > /tmp/llm-council-backend.log 2>&1 & \ echo "backend PID: $$!"; \ sleep 2; \ if curl -s --max-time 2 http://localhost:8001/ >/dev/null 2>&1; then \ echo "✓ Backend is up: http://localhost:8001"; \ else \ echo "⚠️ Backend did not respond yet. Check: /tmp/llm-council-backend.log"; \ fi start-frontend: @echo "Starting frontend..." @if curl -s --max-time 2 http://localhost:5173/ >/dev/null 2>&1; then \ echo "✓ Frontend already responding on http://localhost:5173"; \ exit 0; \ fi @nohup sh -c "cd frontend && npm run dev" > /tmp/llm-council-frontend.log 2>&1 & \ echo "frontend PID: $$!"; \ sleep 2; \ if curl -s --max-time 2 http://localhost:5173/ >/dev/null 2>&1; then \ echo "✓ Frontend is up: http://localhost:5173"; \ else \ echo "⚠️ Frontend did not respond yet. Check: /tmp/llm-council-frontend.log"; \ fi up: start-ollama start-backend start-frontend @echo "" @echo "✓ All services started (or already running)" @echo "Frontend: http://localhost:5173" @echo "Backend: http://localhost:8001" @echo "Ollama: http://localhost:11434" restart: reset up status: @echo "=== LLM Council status ===" @date @echo "" @echo "-- Backend (8001) --" @if curl -s --max-time 2 http://localhost:8001/ >/dev/null 2>&1; then \ echo "✓ UP: http://localhost:8001"; \ else \ echo "✗ DOWN: http://localhost:8001"; \ fi @echo "PIDs:"; lsof -ti:8001 2>/dev/null | tr '\n' ' ' || true; echo "" @echo "" @echo "-- Frontend (5173) --" @if curl -s --max-time 2 http://localhost:5173/ >/dev/null 2>&1; then \ echo "✓ UP: http://localhost:5173"; \ else \ echo "✗ DOWN: http://localhost:5173"; \ fi @echo "PIDs:"; lsof -ti:5173 2>/dev/null | tr '\n' ' ' || true; echo "" @echo "" @echo "-- Ollama (11434) --" @if curl -s --max-time 2 http://localhost:11434/api/tags >/dev/null 2>&1; then \ echo "✓ UP: http://localhost:11434"; \ else \ echo "✗ DOWN/UNREACHABLE: http://localhost:11434"; \ fi @O_PID=$$(pgrep -x ollama 2>/dev/null || true); \ R_CNT=$$(pgrep -f "ollama runner" 2>/dev/null | wc -l | tr -d ' '); \ if [ -n "$$O_PID" ]; then \ echo "ollama PIDs: $$O_PID"; \ echo "runner count: $$R_CNT"; \ echo ""; \ echo "top ollama processes:"; \ ps -o pid,ppid,pcpu,pmem,etime,command -p $$O_PID 2>/dev/null || true; \ pgrep -f "ollama runner" 2>/dev/null | head -5 | while read pid; do \ ps -o pid,ppid,pcpu,pmem,etime,command -p $$pid 2>/dev/null || true; \ done; \ else \ echo "ollama not running"; \ fi @echo "" @echo "-- Quick health hints --" @echo "Backend log: /tmp/llm-council-backend.log" @echo "Frontend log: /tmp/llm-council-frontend.log" @echo "Run: make logs" logs: @echo "=== Recent logs ===" @echo "" @echo "-- Backend log (/tmp/llm-council-backend.log) --" @tail -n 80 /tmp/llm-council-backend.log 2>/dev/null || echo "(no backend log found)" @echo "" @echo "-- Frontend log (/tmp/llm-council-frontend.log) --" @tail -n 120 /tmp/llm-council-frontend.log 2>/dev/null || echo "(no frontend log found)" test-setup: @echo "Setting up test conversation..." @echo "Usage: TEST_MESSAGE='your message' TEST_DOCS='path1.md,path2.md' make test-setup" @echo "" @echo "⚠️ Safeguard check: Verifying backend is running..." @if ! curl -s http://localhost:8001/ > /dev/null 2>&1; then \ echo "✗ Backend is NOT running on port 8001"; \ echo " Starting backend in background..."; \ uv run python -m backend.main > /tmp/llm-council-backend.log 2>&1 & \ BACKEND_PID=$$!; \ echo " Backend PID: $$BACKEND_PID"; \ sleep 2; \ if ! curl -s http://localhost:8001/ > /dev/null 2>&1; then \ echo "✗ Backend failed to start"; \ exit 1; \ fi; \ echo "✓ Backend started"; \ else \ echo "✓ Backend is already running"; \ fi @echo "" @echo "Running test setup script..." @uv run python scripts/test_setup.py > /tmp/llm-council-test-setup.log 2>&1; \ cat /tmp/llm-council-test-setup.log; \ CONV_ID=$$(grep "CONVERSATION_ID=" /tmp/llm-council-test-setup.log | cut -d'=' -f2 | head -1); \ OPEN_URL=$$(grep "OPEN_URL=" /tmp/llm-council-test-setup.log | cut -d'=' -f2- | head -1); \ echo ""; \ echo "Checking frontend status..."; \ if pgrep -f "vite" > /dev/null 2>&1 || pgrep -f "npm.*dev" > /dev/null 2>&1; then \ echo "✓ Frontend process detected (already running)"; \ elif timeout 2 curl -s http://localhost:5173/ > /dev/null 2>&1; then \ echo "✓ Frontend is responding"; \ else \ echo "Starting frontend in background..."; \ cd frontend && npm run dev > /tmp/llm-council-frontend.log 2>&1 & \ echo "Frontend starting (PID: $$!)"; \ echo "Waiting up to 10 seconds for frontend..."; \ for i in 1 2 3 4 5 6 7 8 9 10; do \ if timeout 1 curl -s http://localhost:5173/ > /dev/null 2>&1; then \ echo "✓ Frontend is ready!"; \ break; \ fi; \ sleep 1; \ done; \ fi; \ echo ""; \ echo "✓ Test setup complete!"; \ echo ""; \ if [ -n "$$OPEN_URL" ]; then \ echo "Opening browser: $$OPEN_URL"; \ xdg-open "$$OPEN_URL" 2>/dev/null || \ open "$$OPEN_URL" 2>/dev/null || \ echo "Open manually: $$OPEN_URL"; \ elif [ -n "$$CONV_ID" ]; then \ echo "Opening browser with new conversation: $$CONV_ID"; \ xdg-open "http://localhost:5173/?conversation=$$CONV_ID" 2>/dev/null || \ open "http://localhost:5173/?conversation=$$CONV_ID" 2>/dev/null || \ echo "Open manually: http://localhost:5173/?conversation=$$CONV_ID"; \ else \ echo "Open: http://localhost:5173"; \ echo "The new conversation should appear in the sidebar"; \ fi; \ echo ""; \ echo "Note: TEST_MESSAGE is NOT sent automatically - check the script output above for the message to paste"