#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" MODEL_STREAM_HOST="${MODEL_STREAM_HOST:-127.0.0.1}" MODEL_STREAM_PORT="${MODEL_STREAM_PORT:-8011}" MODEL_STREAM_URL="${MODEL_STREAM_URL:-http://${MODEL_STREAM_HOST}:${MODEL_STREAM_PORT}}" WEB_PORT="${WEB_PORT:-3000}" MODEL_STARTED=0 PIDS=() kill_tree() { local pid="$1" local children="" if command -v pgrep >/dev/null 2>&1; then children="$(pgrep -P "$pid" 2>/dev/null || true)" fi for child in $children; do kill_tree "$child" done kill "$pid" 2>/dev/null || true } cleanup() { local exit_code=$? trap - EXIT INT TERM for pid in "${PIDS[@]}"; do kill_tree "$pid" done if [[ "${#PIDS[@]}" -gt 0 ]]; then wait "${PIDS[@]}" 2>/dev/null || true fi exit "$exit_code" } trap cleanup EXIT INT TERM if command -v curl >/dev/null 2>&1 && curl -fsS "${MODEL_STREAM_URL}/health" >/dev/null 2>&1; then echo "[model] using existing service at ${MODEL_STREAM_URL}" else echo "[model] starting ${MODEL_STREAM_URL}" ( cd "$ROOT_DIR" exec env MODEL_STREAM_HOST="$MODEL_STREAM_HOST" MODEL_STREAM_PORT="$MODEL_STREAM_PORT" bash scripts/model-dev.sh ) & PIDS+=("$!") MODEL_STARTED=1 fi echo "[web] starting http://127.0.0.1:${WEB_PORT}" ( cd "$ROOT_DIR/webapp" exec env MODEL_STREAM_URL="$MODEL_STREAM_URL" npm run dev -- -p "$WEB_PORT" ) & PIDS+=("$!") if [[ "$MODEL_STARTED" -eq 1 ]]; then echo "[dev] model + web are attached. Press Ctrl+C to stop both." else echo "[dev] web is attached. Press Ctrl+C to stop it; existing model service is left running." fi wait -n "${PIDS[@]}"