#!/usr/bin/env bash set -euo pipefail ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)" export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}" export FNOS_SKILL="${FNOS_SKILL:-$CODEX_HOME/skills/fnos-hyzq-deploy}" export FNOS_SSH="${FNOS_SSH:-$FNOS_SKILL/scripts/fnos_ssh.sh}" export FNOS_SCP="${FNOS_SCP:-$FNOS_SKILL/scripts/fnos_scp.sh}" FNOS_HOST="${FNOS_HOST:-192.168.31.188}" FNOS_USER="${FNOS_USER:-krisolo}" REMOTE_ROOT="${STORYFORGE_FNOS_REMOTE_ROOT:-/vol1/docker/hyzq-stack/current/storyforge}" REMOTE_WEB_PARENT="$REMOTE_ROOT/web" REMOTE_WEB_DIR="$REMOTE_WEB_PARENT/storyforge-web-v4" REMOTE_ASSETS_DIR="$REMOTE_WEB_DIR/assets" REMOTE_COMPOSE_DIR="${STORYFORGE_FNOS_COMPOSE_DIR:-/vol1/docker/hyzq-stack/current/deploy/fnos}" REMOTE_COMPOSE_FILE="$REMOTE_COMPOSE_DIR/storyforge-fnos-web-v4.compose.yaml" COLLECTOR_PORT="${STORYFORGE_COLLECTOR_DEV_PORT:-19193}" BACKEND_URL="${STORYFORGE_FNOS_BACKEND_URL:-${STORYFORGE_FNOS_COLLECTOR_URL:-http://$FNOS_HOST:$COLLECTOR_PORT}}" WEB_PORT="${STORYFORGE_WEB_V4_DEV_PORT:-19192}" need_cmd() { if ! command -v "$1" >/dev/null 2>&1; then echo "missing required command: $1" >&2 exit 1 fi } need_cmd python3 if [ -z "${FNOS_PASSWORD:-}" ]; then need_cmd security fi shell_quote() { python3 - "$1" <<'PY' import shlex import sys print(shlex.quote(sys.argv[1])) PY } json_quote() { python3 - "$1" <<'PY' import json import sys print(json.dumps(sys.argv[1], ensure_ascii=False)) PY } resolve_password() { if [ -n "${FNOS_PASSWORD:-}" ]; then printf '%s' "$FNOS_PASSWORD" return 0 fi security find-internet-password -s "$FNOS_HOST" -a "$FNOS_USER" -w } run_remote_sudo() { local password="$1" shift local remote_cmd="$*" local password_quoted password_quoted="$(shell_quote "$password")" "$FNOS_SSH" "$(shell_quote "printf '%s\\n' $password_quoted | sudo -S -p '' sh -lc $(shell_quote "$remote_cmd")")" } PASSWORD="$(resolve_password)" TMPDIR_DEPLOY="$(mktemp -d)" RUNTIME_CONFIG_FILE="$TMPDIR_DEPLOY/storyforge-runtime-config.js" BACKEND_URL_JSON="$(json_quote "$BACKEND_URL")" trap 'rm -rf "$TMPDIR_DEPLOY"' EXIT cat >"$RUNTIME_CONFIG_FILE" </dev/null; then break fi sleep 2 done curl -fsS "http://$FNOS_HOST:$WEB_PORT/" >/dev/null curl -fsS "http://$FNOS_HOST:$WEB_PORT/assets/storyforge-runtime-config.js" | grep -q "$BACKEND_URL" echo "fnOS StoryForge Web V4 ready: http://$FNOS_HOST:$WEB_PORT/"