diff --git a/ui/goose2/justfile b/ui/goose2/justfile index ae5832f43b..afcbf4fe10 100644 --- a/ui/goose2/justfile +++ b/ui/goose2/justfile @@ -1,6 +1,6 @@ -# Derive a stable port from the working directory so the same worktree -# always gets the same port. -vite_port := `python3 -c "import hashlib,os; h=int(hashlib.sha256(os.getcwd().encode()).hexdigest(),16); print(10000 + h % 55000)"` +# Derive a stable default port from the working directory so the same worktree +# usually gets the same port. Set VITE_PORT to override it. +default_vite_port := `python3 -c "import hashlib,os; h=int(hashlib.sha256(os.getcwd().encode()).hexdigest(),16); print(10000 + h % 55000)"` # Default recipe default: @@ -83,7 +83,8 @@ dev: setup #!/usr/bin/env bash set -euo pipefail - VITE_PORT={{ vite_port }} + DEFAULT_VITE_PORT={{ default_vite_port }} + VITE_PORT="${VITE_PORT:-$DEFAULT_VITE_PORT}" export VITE_PORT # Enable perf logs in the child `goose serve` process by default. # Override with e.g. RUST_LOG=info just dev to disable. @@ -103,7 +104,7 @@ dev: setup else unset GOOSE_BIN fi - EXTRA_CONFIG_ARGS=(--config "{\"build\":{\"devUrl\":\"http://localhost:${VITE_PORT}\",\"beforeDevCommand\":{\"script\":\"cd ${PROJECT_DIR} && exec pnpm exec vite --port ${VITE_PORT} --strictPort\",\"cwd\":\".\",\"wait\":false}}}") + EXTRA_CONFIG_ARGS=(--config "{\"build\":{\"devUrl\":\"http://localhost:${VITE_PORT}\",\"beforeDevCommand\":{\"script\":\"exec ./scripts/start-dev-vite.sh ${VITE_PORT}\",\"cwd\":\"${PROJECT_DIR}\",\"wait\":false}}}") if [[ -n "${GOOSE_BIN:-}" ]]; then echo "Using local goose binary: ${GOOSE_BIN}" @@ -140,11 +141,13 @@ dev-debug: setup #!/usr/bin/env bash set -euo pipefail - VITE_PORT={{ vite_port }} + DEFAULT_VITE_PORT={{ default_vite_port }} + VITE_PORT="${VITE_PORT:-$DEFAULT_VITE_PORT}" export VITE_PORT # Enable perf logs in the child `goose serve` process by default. # Override with e.g. RUST_LOG=info just dev-debug to disable. export RUST_LOG="${RUST_LOG:-perf=debug,info}" + PROJECT_DIR=$(pwd) REPO_ROOT=$(cd ../.. && pwd) DISTRO_DIR="$(pwd)/distro" if [[ -z "${GOOSE_DISTRO_DIR:-}" && -d "${DISTRO_DIR}" ]]; then @@ -159,7 +162,7 @@ dev-debug: setup else unset GOOSE_BIN fi - EXTRA_CONFIG_ARGS=(--config "{\"build\":{\"devUrl\":\"http://localhost:${VITE_PORT}\",\"beforeDevCommand\":{\"script\":\"exec ./node_modules/.bin/vite --port ${VITE_PORT} --strictPort\",\"cwd\":\"..\",\"wait\":false}}}") + EXTRA_CONFIG_ARGS=(--config "{\"build\":{\"devUrl\":\"http://localhost:${VITE_PORT}\",\"beforeDevCommand\":{\"script\":\"exec ./scripts/start-dev-vite.sh ${VITE_PORT}\",\"cwd\":\"${PROJECT_DIR}\",\"wait\":false}}}") if [[ -n "${GOOSE_BIN:-}" ]]; then echo "Using local goose binary: ${GOOSE_BIN}" @@ -231,7 +234,8 @@ kill branch="": TARGET_DIR="$WORKTREE_PATH/ui/goose2" VITE_PORT=$(python3 -c '{{ _port_cmd }}' "$TARGET_DIR") else - VITE_PORT={{ vite_port }} + DEFAULT_VITE_PORT={{ default_vite_port }} + VITE_PORT="${VITE_PORT:-$DEFAULT_VITE_PORT}" fi PID=$(lsof -ti :"$VITE_PORT" 2>/dev/null | head -1) || true diff --git a/ui/goose2/scripts/start-dev-vite.sh b/ui/goose2/scripts/start-dev-vite.sh new file mode 100755 index 0000000000..a28e1c0586 --- /dev/null +++ b/ui/goose2/scripts/start-dev-vite.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -euo pipefail + +VITE_PORT="${1:-${VITE_PORT:-}}" +if [[ -z "${VITE_PORT}" ]]; then + echo "VITE_PORT is required" >&2 + exit 1 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" + +PID=$(lsof -ti :"${VITE_PORT}" 2>/dev/null | head -1 || true) +if [[ -n "${PID}" ]]; then + PROC_ARGS="$(ps -p "${PID}" -o args= 2>/dev/null || true)" + PROC_CWD="$(lsof -a -p "${PID}" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p' | head -1)" + if [[ "${PROC_CWD}" == "${PROJECT_DIR}" && "${PROC_ARGS}" == *"--port ${VITE_PORT} --strictPort"* ]]; then + echo "Reusing existing Goose2 Vite dev server on port ${VITE_PORT} (PID ${PID})" + exit 0 + fi + + PROC_NAME="$(ps -p "${PID}" -o comm= 2>/dev/null || true)" + echo "Port ${VITE_PORT} is already in use by '${PROC_NAME}' (PID ${PID})." >&2 + echo "Run 'just goose2 kill' if it is a stale Goose2 dev server, or rerun with VITE_PORT= just goose2 dev." >&2 + exit 1 +fi + +cd "${PROJECT_DIR}" +exec pnpm exec vite --port "${VITE_PORT}" --strictPort