122 lines
3.9 KiB
Bash
Executable File
122 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# resume_session.sh — resume a stopped session
|
|
set -euo pipefail
|
|
|
|
source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh"
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 --workspace <path> --agent <claude|agy|hermes|cline> --session <name> [--dry-run]
|
|
|
|
Options:
|
|
--dry-run Simulates resume flow (resolves binary, environment) without writing
|
|
any updates to YAML or DB. Safe to execute inside active write transactions.
|
|
EOF
|
|
}
|
|
|
|
WORKSPACE=""
|
|
AGENT=""
|
|
SESSION_NAME=""
|
|
|
|
DRY_RUN=0
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--workspace) WORKSPACE="$2"; shift 2 ;;
|
|
--agent) AGENT="$2"; shift 2 ;;
|
|
--session) SESSION_NAME="$2"; shift 2 ;;
|
|
--dry-run) DRY_RUN=1; shift ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) echo "ERROR: unknown arg: $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
[ -n "$WORKSPACE" ] || { echo "ERROR: --workspace required" >&2; exit 2; }
|
|
[ -n "$AGENT" ] || { echo "ERROR: --agent required" >&2; exit 2; }
|
|
[ -n "$SESSION_NAME" ] || { echo "ERROR: --session required" >&2; exit 2; }
|
|
|
|
# 1. Resolve the session id
|
|
UUID=$(bash "$(dirname "${BASH_SOURCE[0]}")/resolve_session_id.sh" \
|
|
--workspace "$WORKSPACE" --agent "$AGENT" --session "$SESSION_NAME")
|
|
|
|
if [ -z "$UUID" ]; then
|
|
echo "ERROR: No saved session for $WORKSPACE ($AGENT). Use multi-agent-mux-create first." >&2
|
|
exit 1
|
|
fi
|
|
|
|
HERDR_SERVER_NAME="$(resolve_herdr_workspace "$SESSION_NAME")"
|
|
export HERDR_SERVER_NAME
|
|
|
|
# 2. If herdr is alive, print warning or attach.
|
|
if herdr has-session -t "$SESSION_NAME" 2>/dev/null; then
|
|
if [ "${DRY_RUN:-0}" = "1" ]; then
|
|
echo "[dry-run] herdr '$SESSION_NAME' already running — nothing to validate"
|
|
exit 0
|
|
fi
|
|
echo "herdr '$SESSION_NAME' already running."
|
|
# Just update YAML to make sure it's set to running
|
|
bash "$(dirname "${BASH_SOURCE[0]}")/update_yaml_resumed.sh" \
|
|
--session "$SESSION_NAME" --uuid "$UUID" --agent "$AGENT" --workspace "$WORKSPACE"
|
|
exit 0
|
|
fi
|
|
|
|
# Resolve absolute path of the agent command to prevent herdr PATH inheritance issues (especially on macOS)
|
|
RESOLVED_BIN="$AGENT"
|
|
if [ "$AGENT" = "cline" ]; then
|
|
if command -v cline >/dev/null 2>&1; then
|
|
RESOLVED_BIN="$(command -v cline)"
|
|
fi
|
|
else
|
|
if command -v "$AGENT" >/dev/null 2>&1; then
|
|
RESOLVED_BIN="$(command -v "$AGENT")"
|
|
fi
|
|
fi
|
|
|
|
# On macOS, clear quarantine attribute for the agent binary to prevent Gatekeeper hangs
|
|
if [ "$(uname)" = "Darwin" ] && [ -f "$RESOLVED_BIN" ]; then
|
|
xattr -d com.apple.quarantine "$RESOLVED_BIN" 2>/dev/null || true
|
|
fi
|
|
|
|
# Determine CMD_FULL
|
|
case "$AGENT" in
|
|
claude) CMD_FULL="${RESOLVED_BIN} --dangerously-skip-permissions -r $UUID" ;;
|
|
agy) CMD_FULL="${RESOLVED_BIN} --dangerously-skip-permissions --conversation $UUID" ;;
|
|
hermes) CMD_FULL="${RESOLVED_BIN} --resume $UUID" ;;
|
|
cline) CMD_FULL="${RESOLVED_BIN} -i --id $UUID" ;;
|
|
*) echo "ERROR: unsupported agent: $AGENT" >&2; exit 2 ;;
|
|
esac
|
|
|
|
# Validate binary exists and is executable
|
|
if [ -f "$RESOLVED_BIN" ] || [[ "$RESOLVED_BIN" == /* ]] || [[ "$RESOLVED_BIN" == ~/* ]]; then
|
|
if [ ! -x "$RESOLVED_BIN" ]; then
|
|
echo "ERROR: Agent binary is not executable: $RESOLVED_BIN" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
if ! command -v "$RESOLVED_BIN" >/dev/null 2>&1; then
|
|
echo "ERROR: Agent binary not found in PATH: $RESOLVED_BIN" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ "${DRY_RUN:-0}" = "1" ]; then
|
|
echo "[dry-run] would spawn: $CMD_FULL"
|
|
exit 0
|
|
fi
|
|
|
|
# 4. Spawn new agent session (delegates to herdr translation shim)
|
|
_herdr new-session -d -s "$SESSION_NAME" -c "$WORKSPACE" "$CMD_FULL"
|
|
if [ "$AGENT" = "claude" ]; then
|
|
# auto-handle trust / bypass dialogs
|
|
handle_startup_dialogs "$SESSION_NAME" 20
|
|
fi
|
|
|
|
# Wait for TUI readiness or let it settle
|
|
sleep 2
|
|
|
|
# 5. Update agent-sessions.yaml: status running, last_visible_status
|
|
bash "$(dirname "${BASH_SOURCE[0]}")/update_yaml_resumed.sh" \
|
|
--session "$SESSION_NAME" --uuid "$UUID" --agent "$AGENT" --workspace "$WORKSPACE"
|
|
|
|
echo "Successfully resumed $SESSION_NAME ($AGENT)"
|