Repository Public
1#!/bin/zsh2# Local manual run of Claude Remote: real runtime + server on http://localhost:8620.3# scripts/dev-up.sh → build, create/migrate the dev database, start both processes4# scripts/dev-down.sh → stop both and kill ONLY the dev tmux server (socket claude-remote-dev)5# Never sets CR_INSTALL_CLAUDE_HOOKS: your ~/.claude/settings.json is not modified (so sessions6# do not report WAITING_FOR_INPUT in this mode unless you install the hook yourself).7set -euo pipefail8cd "$(dirname "$0")/.."9REPO="$PWD"10DB=claude_remote_dev11PORT=862012TMUX_SOCKET=claude-remote-dev1314mkdir -p /tmp/cr-dev-data /tmp/cr-dev-workspace15chmod 700 /tmp/cr-dev-data16# Real paths (/tmp is a symlink on macOS): the runtime compares canonical paths.17DATA="$(cd /tmp/cr-dev-data && pwd -P)"18WS="$(cd /tmp/cr-dev-workspace && pwd -P)"19mkdir -p "$DATA/run" "$DATA/logs"20chmod 700 "$DATA/run"2122alive() { [[ -f "$1" ]] && kill -0 "$(cat "$1")" 2>/dev/null; }23if alive "$DATA/run/runtime.pid" || alive "$DATA/run/server.pid"; then24 echo "Claude Remote dev is already running — stop it first: scripts/dev-down.sh" >&225 exit 126fi2728echo "== build (shared, runtime, server)"29for pkg in shared runtime server; do30 out="$(pnpm --filter "@cr/$pkg" build 2>&1)" || { echo "$out" >&2; echo "build of @cr/$pkg failed" >&2; exit 1; }31done3233echo "== database $DB"34psql -d postgres -tAc "select 1 from pg_database where datname='$DB'" | grep -q 1 || createdb "$DB"35export DATABASE_URL="postgres://localhost/$DB"36node apps/server/dist/migrate.js >/dev/null3738TOKEN_FILE="$DATA/dev-runtime-token"39if [[ ! -s "$TOKEN_FILE" ]]; then (umask 077; openssl rand -hex 32 > "$TOKEN_FILE"); fi4041unset CR_INSTALL_CLAUDE_HOOKS CR_INSTALL_AGENT_HOOKS CLAUDECODE CLAUDE_CODE_ENTRYPOINT TMUX TMUX_PANE42export NODE_ENV=development43export CR_PORT=$PORT CR_HOST=127.0.0.1 CR_PUBLIC_ORIGIN="http://localhost:$PORT"44export CR_DATA_DIR="$DATA" CR_WORKSPACE_ROOTS="workspace=$WS"45export CR_RUNTIME_SOCKET="$DATA/run/runtime.sock" CR_RUNTIME_TOKEN="$(cat "$TOKEN_FILE")"46export CR_TMUX_SOCKET="$TMUX_SOCKET" CR_LOG_LEVEL="${CR_LOG_LEVEL:-info}"47if [[ -f "$REPO/apps/web/out/index.html" ]]; then48 export CR_WEB_DIR="$REPO/apps/web/out"; WEB="apps/web/out"49else50 export CR_WEB_DIR="$DATA/no-web"; WEB="none (API only — build apps/web to get the UI)"51fi5253echo "== runtime"54nohup node apps/runtime/dist/main.js >> "$DATA/logs/runtime.log" 2>&1 &55echo $! > "$DATA/run/runtime.pid"56for i in {1..100}; do57 [[ -S "$CR_RUNTIME_SOCKET" ]] && break58 alive "$DATA/run/runtime.pid" || { echo "runtime failed to start:" >&2; tail -5 "$DATA/logs/runtime.log" >&2; exit 1; }59 sleep 0.160done61[[ -S "$CR_RUNTIME_SOCKET" ]] || { echo "runtime socket did not appear" >&2; exit 1; }6263echo "== server"64nohup node apps/server/dist/main.js >> "$DATA/logs/server.log" 2>&1 &65echo $! > "$DATA/run/server.pid"66ok=067for i in {1..100}; do68 if curl -fsS -o /dev/null "http://127.0.0.1:$PORT/api/v1/health" 2>/dev/null; then ok=1; break; fi69 alive "$DATA/run/server.pid" || break70 sleep 0.171done72if [[ $ok != 1 ]]; then73 echo "server failed to start:" >&2; tail -5 "$DATA/logs/server.log" >&274 "$REPO/scripts/dev-down.sh" >/dev/null 2>&1 || true75 exit 176fi7778echo79echo "Claude Remote dev is up: http://localhost:$PORT"80echo " web app : $WEB"81echo " workspace root : $WS"82echo " data dir : $DATA (logs in $DATA/logs/)"83if [[ -f "$DATA/setup-token" ]]; then84 echo " first run : the one-time setup token is in the file $DATA/setup-token"85else86 echo " administrator already created (no setup token)"87fi88echo " stop : scripts/dev-down.sh"89