Skip to content

Commit 7a65c9d

Browse files
Klausc06claude
andcommitted
fix: harden launcher process lifecycle and PATH bootstrap
- Use nohup (bash) / Start-Process (PowerShell) so the proxy survives terminal close — previously background processes were killed when the parent shell exited - Add bootstrap_path() to ensure brew and ~/.local/bin are in PATH when launched from non-login shells - Consolidate PID file path into a single variable - Add trap to clean up PID file on script exit - Declare local variables consistently (choice, pids) - Extend proxy startup wait from 10s to 15s for slower machines Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c46023d commit 7a65c9d

2 files changed

Lines changed: 38 additions & 30 deletions

File tree

fcc

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ PORT="${FCC_PORT:-8082}"
1717
BASE_URL="http://localhost:$PORT"
1818
AUTH_TOKEN="${ANTHROPIC_AUTH_TOKEN:-freecc}"
1919
LOG_FILE="/tmp/fcc-proxy.log"
20+
PID_FILE="/tmp/fcc-proxy.pid"
21+
22+
bootstrap_path() {
23+
if [[ -f /opt/homebrew/bin/brew ]]; then
24+
eval "$(/opt/homebrew/bin/brew shellenv)"
25+
elif [[ -f /usr/local/bin/brew ]]; then
26+
eval "$(/usr/local/bin/brew shellenv)"
27+
fi
28+
[[ -d "$HOME/.local/bin" ]] && export PATH="$HOME/.local/bin:$PATH"
29+
}
2030

2131
ensure_uv() {
2232
if command -v uv >/dev/null 2>&1; then
@@ -41,6 +51,7 @@ ensure_uv() {
4151
}
4252

4353
start_proxy() {
54+
bootstrap_path
4455
ensure_uv || return 1
4556

4657
echo "🔧 Cleaning up port $PORT..."
@@ -56,11 +67,14 @@ start_proxy() {
5667

5768
echo "🚀 Starting proxy server → $BASE_URL"
5869
cd "$SCRIPT_DIR"
59-
uv run uvicorn server:app --host 0.0.0.0 --port "$PORT" > "$LOG_FILE" 2>&1 &
60-
echo $! > /tmp/fcc-proxy.pid
70+
nohup uv run uvicorn server:app --host 0.0.0.0 --port "$PORT" > "$LOG_FILE" 2>&1 < /dev/null &
71+
echo $! > "$PID_FILE"
72+
73+
# Clean up PID file on script exit
74+
trap 'rm -f "$PID_FILE"' EXIT
6175

6276
# Wait for proxy to be ready
63-
for _ in $(seq 1 10); do
77+
for _ in $(seq 1 15); do
6478
if curl -s -o /dev/null "$BASE_URL" 2>/dev/null; then
6579
echo "✅ Proxy is ready"
6680
return 0
@@ -69,53 +83,44 @@ start_proxy() {
6983
done
7084

7185
echo "❌ Proxy failed to start, check log: $LOG_FILE" >&2
72-
# Clean up orphaned background process
73-
if [[ -f /tmp/fcc-proxy.pid ]]; then
86+
if [[ -f "$PID_FILE" ]]; then
7487
local failed_pid
75-
failed_pid="$(cat /tmp/fcc-proxy.pid 2>/dev/null || true)"
88+
failed_pid="$(cat "$PID_FILE" 2>/dev/null || true)"
7689
if [[ -n "$failed_pid" ]] && kill -0 "$failed_pid" 2>/dev/null; then
7790
kill "$failed_pid" 2>/dev/null || true
78-
rm -f /tmp/fcc-proxy.pid
7991
fi
92+
rm -f "$PID_FILE"
8093
fi
8194
return 1
8295
}
8396

8497
stop_proxy() {
85-
local pids
86-
local pid_file="/tmp/fcc-proxy.pid"
98+
local saved_pid=""
8799

88100
# Try PID file first for targeted kill
89-
if [[ -f "$pid_file" ]]; then
90-
local saved_pid
91-
saved_pid="$(cat "$pid_file" 2>/dev/null || true)"
101+
if [[ -f "$PID_FILE" ]]; then
102+
saved_pid="$(cat "$PID_FILE" 2>/dev/null || true)"
92103
if [[ -n "$saved_pid" ]] && kill -0 "$saved_pid" 2>/dev/null; then
93104
echo "🛑 Stopping proxy (PID: $saved_pid)..."
94105
kill "$saved_pid" 2>/dev/null || true
95106
sleep 2
96-
if kill -0 "$saved_pid" 2>/dev/null; then
97-
kill -9 "$saved_pid" 2>/dev/null || true
98-
sleep 1
99-
fi
100-
rm -f "$pid_file"
107+
kill -0 "$saved_pid" 2>/dev/null && kill -9 "$saved_pid" 2>/dev/null || true
108+
rm -f "$PID_FILE"
101109
echo "✅ Stopped"
102110
return 0
103-
else
104-
rm -f "$pid_file"
105111
fi
112+
rm -f "$PID_FILE"
106113
fi
107114

108115
# Fall back to port-based lookup
116+
local pids
109117
pids="$(lsof -ti ":$PORT" 2>/dev/null || true)"
110118
if [[ -n "$pids" ]]; then
111119
echo "🛑 Stopping proxy (PID: $(echo "$pids" | tr '\n' ' '))..."
112120
echo "$pids" | xargs kill 2>/dev/null || true
113121
sleep 2
114122
pids="$(lsof -ti ":$PORT" 2>/dev/null || true)"
115-
if [[ -n "$pids" ]]; then
116-
echo "$pids" | xargs kill -9 2>/dev/null || true
117-
sleep 1
118-
fi
123+
[[ -n "$pids" ]] && echo "$pids" | xargs kill -9 2>/dev/null || true
119124
echo "✅ Stopped"
120125
else
121126
echo "ℹ️ Proxy is not running"
@@ -297,6 +302,7 @@ shortcut_menu() {
297302
echo " 2) Proxy + Claude Code — double-click to start all"
298303
echo " 3) Create both"
299304
echo ""
305+
local choice
300306
read -r -p "Enter option [1/2/3]: " choice
301307

302308
case "$choice" in
@@ -322,6 +328,7 @@ case "${1:-proxy}" in
322328
start_proxy
323329
;;
324330
claude)
331+
bootstrap_path
325332
if ! command -v claude >/dev/null 2>&1; then
326333
echo "❌ claude command not found, please install Claude Code" >&2
327334
exit 1

fcc.ps1

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,16 @@ function Start-Proxy {
6868

6969
Write-Host "🚀 Starting proxy server → $BaseUrl"
7070
Set-Location $ScriptDir
71-
Remove-Job -Name "FCCProxy" -ErrorAction SilentlyContinue
72-
$job = Start-Job -Name "FCCProxy" -ScriptBlock {
73-
param($dir, $port, $log)
74-
Set-Location $dir
75-
uv run uvicorn server:app --host 0.0.0.0 --port $port *>"$log"
76-
} -ArgumentList $ScriptDir, $Port, $LogFile
71+
$proc = Start-Process -FilePath "uv" `
72+
-ArgumentList "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "$Port" `
73+
-NoNewWindow `
74+
-RedirectStandardOutput $LogFile `
75+
-RedirectStandardError $LogFile `
76+
-PassThru
77+
$proc.Id | Out-File -FilePath "$env:TEMP\fcc-proxy.pid"
7778

7879
# Wait for proxy to be ready
79-
for ($i = 0; $i -lt 10; $i++) {
80+
for ($i = 0; $i -lt 15; $i++) {
8081
try {
8182
$null = Invoke-WebRequest -Uri "$BaseUrl" -UseBasicParsing -TimeoutSec 1 -ErrorAction Stop
8283
Write-Host "✅ Proxy is ready"

0 commit comments

Comments
 (0)