-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstart.sh
More file actions
executable file
·232 lines (205 loc) · 7.9 KB
/
start.sh
File metadata and controls
executable file
·232 lines (205 loc) · 7.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#!/bin/bash
# ==================================================================
# Fred - Start All Services
# Temporal server, Fred worker, Signal server, Frontend
# ==================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ Fred Development Server ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo ""
# Check if frontend dependencies are installed
if [ ! -d "frontend/node_modules" ]; then
echo "📦 Installing frontend dependencies..."
cd frontend && pnpm install && cd ..
fi
# Function to cleanup on exit
cleanup() {
echo ""
echo "Shutting down all services..."
kill $(jobs -p) 2>/dev/null
exit 0
}
trap cleanup SIGINT SIGTERM
# Health check function
wait_for_service() {
local url=$1
local name=$2
local max_attempts=${3:-30}
local attempt=1
while [ $attempt -le $max_attempts ]; do
if curl -s "$url" > /dev/null 2>&1; then
echo " $name is ready"
return 0
fi
sleep 1
attempt=$((attempt + 1))
done
echo " WARNING: $name did not respond after ${max_attempts}s"
return 1
}
# 1. Start Temporal server
echo "⏱️ Starting Temporal server..."
temporal server start-dev --ui-port 8233 > /dev/null 2>&1 &
TEMPORAL_PID=$!
echo " Waiting for Temporal to be ready..."
wait_for_service "http://localhost:8233" "Temporal UI"
# Wait for gRPC port (7233) to be ready - this is what workers connect to
echo " Waiting for Temporal gRPC (port 7233)..."
for i in {1..30}; do
if nc -z localhost 7233 2>/dev/null; then
echo " Temporal gRPC is ready"
break
fi
sleep 1
done
sleep 2 # Extra buffer for Temporal to fully initialize
# Ensure default namespace exists
echo " Ensuring default namespace exists..."
temporal operator namespace describe default >/dev/null 2>&1 || \
temporal operator namespace create default 2>/dev/null || true
# 2. Start Fred worker
echo "🤖 Starting Fred worker (fred-queue)..."
cd "$SCRIPT_DIR/backend"
PYTHONPATH=. python -m temporal.fred_worker > /tmp/fred_worker.log 2>&1 &
WORKER_PID=$!
sleep 3 # Give worker time to register with Temporal
# Verify worker started successfully
if ! kill -0 $WORKER_PID 2>/dev/null; then
echo " ❌ Worker failed to start. Check /tmp/fred_worker.log for details"
echo " Last 10 lines of log:"
tail -10 /tmp/fred_worker.log 2>/dev/null || echo " (no log available)"
else
echo " ✓ Worker started (PID: $WORKER_PID)"
fi
# 3. Start Signal server (API)
echo "🚀 Starting Signal server on http://localhost:4000"
cd "$SCRIPT_DIR/backend"
PYTHONPATH=. uvicorn temporal.api.signal_server:app --port 4000 --reload > /dev/null 2>&1 &
BACKEND_PID=$!
echo " Waiting for API to be ready..."
wait_for_service "http://localhost:4000/health" "Signal server"
# 4. Start frontend
echo "🎨 Starting frontend on http://localhost:4001"
cd "$SCRIPT_DIR/frontend"
pnpm dev > /dev/null 2>&1 &
FRONTEND_PID=$!
echo " Waiting for frontend to be ready..."
wait_for_service "http://localhost:4001" "Frontend"
# 5. Set repo root (can be passed as env var or read from config)
CONFIG_FILE="$SCRIPT_DIR/backend/temporal/api/interceptor_config.json"
if [ -n "$FRED_REPO_ROOT" ]; then
# User passed repo root via env var - persist it to config
echo "📁 Setting repo root: $FRED_REPO_ROOT"
mkdir -p "$(dirname "$CONFIG_FILE")"
if [ -f "$CONFIG_FILE" ]; then
python3 -c "
import json
with open('$CONFIG_FILE', 'r') as f:
data = json.load(f)
data['repo_root'] = '$FRED_REPO_ROOT'
with open('$CONFIG_FILE', 'w') as f:
json.dump(data, f, indent=2)
" 2>/dev/null
else
echo '{"repo_root": "'"$FRED_REPO_ROOT"'", "workflow_configs": {}}' > "$CONFIG_FILE"
fi
elif [ -f "$CONFIG_FILE" ]; then
# Read from config if exists
FRED_REPO_ROOT=$(python3 -c "import json; print(json.load(open('$CONFIG_FILE')).get('repo_root', ''))" 2>/dev/null)
fi
# Interactive prompt if still no repo root configured
if [ -z "$FRED_REPO_ROOT" ]; then
echo ""
echo "📁 No target repository configured."
echo " Enter the path to your project (or press Enter for current directory):"
read -p " > " USER_REPO_PATH
if [ -z "$USER_REPO_PATH" ]; then
FRED_REPO_ROOT="$(pwd)"
else
# Expand ~ to home directory
USER_REPO_PATH="${USER_REPO_PATH/#\~/$HOME}"
FRED_REPO_ROOT="$USER_REPO_PATH"
fi
# Validate path exists
if [ ! -d "$FRED_REPO_ROOT" ]; then
echo " ⚠️ Directory not found: $FRED_REPO_ROOT"
echo " Using current directory instead."
FRED_REPO_ROOT="$(pwd)"
fi
# Persist to config
echo " Saving: $FRED_REPO_ROOT"
mkdir -p "$(dirname "$CONFIG_FILE")"
if [ -f "$CONFIG_FILE" ]; then
python3 -c "
import json
with open('$CONFIG_FILE', 'r') as f:
data = json.load(f)
data['repo_root'] = '$FRED_REPO_ROOT'
with open('$CONFIG_FILE', 'w') as f:
json.dump(data, f, indent=2)
" 2>/dev/null
else
echo '{"repo_root": "'"$FRED_REPO_ROOT"'", "workflow_configs": {}}' > "$CONFIG_FILE"
fi
fi
export FRED_REPO_ROOT
# 6. Start n8n (optional - for workflow automation)
if [ "${FRED_N8N_ENABLED:-false}" = "true" ]; then
echo "🔧 Starting n8n on http://localhost:5678"
if ! command -v n8n &> /dev/null; then
echo " ⚠️ n8n not found. Install with: npm install -g n8n"
else
n8n start > /tmp/n8n.log 2>&1 &
N8N_PID=$!
wait_for_service "http://localhost:5678/healthz" "n8n" 15 || true
fi
fi
# 7. Start MCP bridge (optional - for contract enrichment)
if [ "${FRED_MCP_ENABLED:-false}" = "true" ]; then
echo "🔌 Starting MCP bridge on http://localhost:3100"
cd "$SCRIPT_DIR/backend"
if [ -z "$FRED_REPO_ROOT" ]; then
echo " ⚠️ No repo_root set. Use: FRED_REPO_ROOT=/path/to/repo ./start.sh"
else
echo " 📁 Git context: $FRED_REPO_ROOT"
fi
# Check if mcp-server-git is available
if ! command -v mcp-server-git &> /dev/null; then
echo " ⚠️ mcp-server-git not found. Install with: pip install mcp-server-git"
else
npx @anthropic/mcp-bridge --port 3100 --config mcp-config.json > /tmp/mcp_bridge.log 2>&1 &
MCP_PID=$!
wait_for_service "http://localhost:3100/health" "MCP bridge" 10 || true
fi
fi
echo ""
echo "════════════════════════════════════════════════════════════"
echo " Temporal: http://localhost:8233 (Temporal UI)"
echo " Backend: http://localhost:4000 (Signal server + API)"
echo " Frontend: http://localhost:4001 (React dashboard)"
if [ "${FRED_N8N_ENABLED:-false}" = "true" ]; then
echo " n8n: http://localhost:5678 (Workflow automation)"
fi
if [ "${FRED_MCP_ENABLED:-false}" = "true" ]; then
echo " MCP Bridge: http://localhost:3100 (Git context: $FRED_REPO_ROOT)"
fi
echo "════════════════════════════════════════════════════════════"
echo ""
echo " Worker: fred-queue (Fred workflows)"
echo ""
echo "Quick start with your repo:"
echo " FRED_REPO_ROOT=/path/to/your/project ./start.sh"
echo ""
echo "With MCP git enrichment:"
echo " FRED_REPO_ROOT=/path/to/project FRED_MCP_ENABLED=true ./start.sh"
echo ""
echo "With n8n automation:"
echo " FRED_N8N_ENABLED=true ./start.sh"
echo ""
echo "Press Ctrl+C to stop all services"
echo ""
# Wait for processes
wait