diff --git a/sh/digitalocean/hermes.sh b/sh/digitalocean/hermes.sh index 7f300269..2478c8af 100755 --- a/sh/digitalocean/hermes.sh +++ b/sh/digitalocean/hermes.sh @@ -15,6 +15,11 @@ _ensure_bun() { command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } } +# Run command in the foreground so bun gets full terminal access (raw mode, +# arrow keys for interactive prompts). The old pattern backgrounded the child +# with & + wait so a SIGTERM trap could forward the signal, but that removed +# bun from the foreground process group and broke @clack/prompts multiselect. +# Now SIGTERM is detected from exit code 143 (128 + 15) after the child exits. _run_with_restart() { local attempt=0 local backoff=2 @@ -24,10 +29,12 @@ _run_with_restart() { "$@" local exit_code=$? + # Normal exit if [ "$exit_code" -eq 0 ]; then return 0 fi + # SIGTERM (143) or SIGKILL (137) — attempt restart if [ "$exit_code" -eq 143 ] || [ "$exit_code" -eq 137 ]; then printf '\033[0;33m[spawn/%s] Agent process terminated (exit %s). The droplet is likely still running.\033[0m\n' \ "$_AGENT_NAME" "$exit_code" >&2 @@ -46,6 +53,7 @@ _run_with_restart() { fi fi + # Other failure — exit with the original code return "$exit_code" done } diff --git a/sh/hetzner/hermes.sh b/sh/hetzner/hermes.sh index 2aa12782..914d8851 100755 --- a/sh/hetzner/hermes.sh +++ b/sh/hetzner/hermes.sh @@ -1,6 +1,8 @@ #!/bin/bash set -eo pipefail +# Thin shim: ensures bun is available, runs bundled hetzner.js (local or from GitHub release) + _ensure_bun() { if command -v bun &>/dev/null; then return 0; fi printf '\033[0;36mInstalling bun...\033[0m\n' >&2 @@ -8,6 +10,7 @@ _ensure_bun() { export PATH="$HOME/.bun/bin:$PATH" command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; } } + _ensure_bun SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)" @@ -17,10 +20,12 @@ if [[ -n "${SPAWN_CLI_DIR:-}" && -f "$SPAWN_CLI_DIR/packages/cli/src/hetzner/mai exec bun run "$SPAWN_CLI_DIR/packages/cli/src/hetzner/main.ts" hermes "$@" fi +# Local checkout — run from source if [[ -n "$SCRIPT_DIR" && -f "$SCRIPT_DIR/../../packages/cli/src/hetzner/main.ts" ]]; then exec bun run "$SCRIPT_DIR/../../packages/cli/src/hetzner/main.ts" hermes "$@" fi +# Remote — download and run compiled TypeScript bundle HETZNER_JS=$(mktemp) trap 'rm -f "$HETZNER_JS"' EXIT curl -fsSL "https://github.com/OpenRouterTeam/spawn/releases/download/hetzner-latest/hetzner.js" -o "$HETZNER_JS"