- fără agent implicit: ambele pane-uri sunt shell în sandbox, agentul se pornește manual; argumentul 3 rămâne pentru lansare explicită - al doilea pane intră în sandbox cu 4s întârziere (SBT_PANE_DELAY): două `sbx exec` simultane se calcă pe lock-ul de refresh Docker Hub și scot "could not acquire docker hub refresh lock" Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
129 lines
3.9 KiB
Bash
Executable File
129 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# sbt — sesiune tmux cu shell/agent în Docker Sandbox (sbx).
|
|
#
|
|
# tmux rulează pe HOST (LXC 102, userul work); fiecare pane intră în sandbox
|
|
# prin `sbx exec -it`. În sandbox nu există tmux, deci sesiunea supraviețuiește
|
|
# oricărei reporniri a agentului.
|
|
#
|
|
# NU lansează niciun agent — deschide shell-uri în sandbox, agentul îl pornești tu.
|
|
#
|
|
# sbt sesiune 1, shell în /home/workspace
|
|
# sbt 2 proiect-a sesiune 2, shell în /home/workspace/proiect-a
|
|
# sbt 1 proiect-a opencode opțional: lansează explicit un agent în pane-ul stâng
|
|
# sbt list listează sesiunile tmux
|
|
# sbt kill [N] omoară sesiunea N
|
|
# sbt detach [N] detașează clienții de la sesiunea N
|
|
#
|
|
# Variabile: SANDBOX (implicit claude-workspace), SBT_PANE_DELAY (implicit 4s)
|
|
set -euo pipefail
|
|
|
|
SANDBOX="${SANDBOX:-claude-workspace}"
|
|
ROOT="/home/workspace"
|
|
BOOTSTRAP="$ROOT/.agent/bootstrap-statusline.sh"
|
|
|
|
usage() {
|
|
sed -n '2,/^set -/p' "$0" | grep '^#' | sed 's/^# \{0,1\}//'
|
|
exit "${1:-0}"
|
|
}
|
|
|
|
session_name() {
|
|
case "$1" in
|
|
1|2|3) echo "sbx$1" ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
# ---- Parsare argumente ----
|
|
ACTION="start"; NUM="1"; PROJ=""; AGENT="shell"
|
|
|
|
case "${1:-}" in
|
|
list)
|
|
tmux ls 2>/dev/null || echo "Nicio sesiune tmux activă."
|
|
exit 0
|
|
;;
|
|
kill|detach)
|
|
ACTION="$1"; NUM="${2:-1}"
|
|
;;
|
|
-h|--help|help)
|
|
usage
|
|
;;
|
|
1|2|3)
|
|
NUM="$1"; PROJ="${2:-}"; AGENT="${3:-shell}"
|
|
;;
|
|
"")
|
|
: # implicite
|
|
;;
|
|
*)
|
|
echo "Argument necunoscut: $1" >&2
|
|
usage 1
|
|
;;
|
|
esac
|
|
|
|
SESSION=$(session_name "$NUM") || { echo "Sesiune invalidă: $NUM (1, 2 sau 3)" >&2; exit 1; }
|
|
|
|
if [ "$ACTION" = "kill" ]; then
|
|
if tmux has-session -t "$SESSION" 2>/dev/null; then
|
|
tmux kill-session -t "$SESSION"; echo "Sesiune oprită: $SESSION"
|
|
else
|
|
echo "Sesiunea nu există: $SESSION"
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$ACTION" = "detach" ]; then
|
|
if tmux has-session -t "$SESSION" 2>/dev/null; then
|
|
tmux detach-client -s "$SESSION"; echo "Clienți detașați de la: $SESSION"
|
|
else
|
|
echo "Sesiunea nu există: $SESSION"
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
# ---- Atașare dacă sesiunea există deja ----
|
|
TMUX_SOCK="/tmp/tmux-$(id -u)/default"
|
|
[ -e "$TMUX_SOCK" ] && ! tmux ls &>/dev/null && rm -f "$TMUX_SOCK"
|
|
|
|
if tmux has-session -t "$SESSION" 2>/dev/null; then
|
|
echo "Mă atașez la sesiunea existentă: $SESSION"
|
|
exec tmux attach-session -t "$SESSION"
|
|
fi
|
|
|
|
# ---- Sandbox pornit + keepalive (idempotent) ----
|
|
if command -v agents >/dev/null 2>&1; then
|
|
SANDBOX="$SANDBOX" agents up
|
|
else
|
|
sbx ls >/dev/null 2>&1 || true
|
|
sbx exec "$SANDBOX" true >/dev/null
|
|
fi
|
|
|
|
DIR="$ROOT${PROJ:+/$PROJ}"
|
|
[ -n "$PROJ" ] && mkdir -p "$DIR"
|
|
|
|
# ---- Comanda rulată în fiecare pane ----
|
|
# bootstrap-ul reinstalează statusline-ul în settings.json din sandbox
|
|
# (settings.json stă pe overlay-ul efemer, deci se pierde la recreare).
|
|
sandbox_pane() {
|
|
local inner="$1"
|
|
printf 'sbx exec -it -w %q %q bash -lc %q' "$DIR" "$SANDBOX" \
|
|
"[ -r '$BOOTSTRAP' ] && . '$BOOTSTRAP'; $inner exec bash -l"
|
|
}
|
|
|
|
case "$AGENT" in
|
|
shell|none|"") INNER="" ;;
|
|
claude) INNER="claude;" ;;
|
|
*) INNER="$AGENT;" ;;
|
|
esac
|
|
|
|
echo "Sesiune nouă: $SESSION (sandbox=$SANDBOX dir=$DIR agent=${AGENT:-shell})"
|
|
|
|
tmux new-session -d -s "$SESSION" -c "$ROOT" "$(sandbox_pane "$INNER")"
|
|
tmux set-option -t "$SESSION" -g mouse on
|
|
|
|
# Al doilea pane intră în sandbox cu întârziere: două `sbx exec` pornite simultan
|
|
# se calcă pe lock-ul de refresh Docker Hub al lui sbx și scot
|
|
# „could not acquire docker hub refresh lock". Warning inofensiv, dar zgomotos.
|
|
tmux split-window -h -t "$SESSION:0" -c "$ROOT" \
|
|
"sh -c $(printf '%q' "sleep ${SBT_PANE_DELAY:-4}; exec $(sandbox_pane "")")"
|
|
tmux select-pane -t "$SESSION:0.0"
|
|
exec tmux attach-session -t "$SESSION"
|