Developer Guide · 13

Cross-platform Launcher (launcher.py)

13.1 Features

  • Old instance detection: detects running JellyfishBot processes via port scan (lsof / netstat)
  • User-confirmed kill: lists processes occupying ports, SIGTERM → SIGKILL
  • Auto port discovery: default 8000 (backend) + 3000 (frontend), auto-increments if occupied
  • Dual-process management: starts uvicorn + Express, cleans up all processes on subprocess crash
  • Clean exit: Ctrl+C / SIGTERM graceful termination (SIGKILL after 5s timeout)

13.2 Log Tee (2026-04-20)

All subprocess stdout+stderr launched by launcher simultaneously writes to:

  • {project_dir}/logs/{name}-YYYYMMDD.log (daily rotation + append + session header)
  • Original stdout

Implementation: _spawn_with_log(cmd, cwd, env, log_name) replaces bare Popen; subprocess stdout/stderr merged to PIPE, then _tee_pipe_to(fh, src) background daemon thread writes line-by-line to disk.

⚠️ Do not revert to subprocess.PIPE + communicate() — long-running processes will block wait(); current daemon thread + bufsize=0 implementation is a validated non-blocking solution.

13.3 Port Configuration

FileConfiguration
launcher.py--port / --frontend-port command line args
server.jsFRONTEND_PORT / API_TARGET environment variables
start.sh (Docker)BACKEND_PORT / FRONTEND_PORT environment variables

13.4 Usage

bash
python launcher.py                    # Production mode
python launcher.py --dev              # Dev mode (uvicorn --reload + vite dev)
python launcher.py --port 9000        # Custom backend port
python launcher.py --backend-only     # Backend only
python launcher.py --skip-check       # Skip old instance detection