diff --git a/scripts/servidor/claude-caja.sh b/scripts/servidor/claude-caja.sh index 8bbf9aa1..96d8602e 100755 --- a/scripts/servidor/claude-caja.sh +++ b/scripts/servidor/claude-caja.sh @@ -54,8 +54,35 @@ set -eu # ln -sf /opt/takana/scripts/servidor/claude-caja.sh /usr/bin/claude _yo="$(id -un)" _hogar="${HOME:-/root}" -_inst="claude" -[ "$_yo" != "root" ] && _inst="claude-$_yo" +_base="claude" +[ "$_yo" != "root" ] && _base="claude-$_yo" + +# ── VARIAS SESIONES A LA VEZ ──────────────────────────────────────────────────────────────────── +# El kernel niega DOS overlays sobre el mismo `upper` —la capa mutable se corrompería— y eso no se +# discute. Pero «un solo Claude» era empaquetado nuestro, no del kernel: instancias distintas tienen +# `upper` distintos y conviven. Así que si la de siempre está ocupada, se usa la siguiente. +# +# ⚠ La instancia nueva NO se aprovisiona: se CLONA la capa ya hecha. Con un mapa de un solo id +# —lo que hay hoy, ver §6.55— `pacman` no puede chownear su descarga y el `provision` muere en +# «failed to chown temporary download directory». Copiar el `upper` cuesta ~1 s y 169 M y no depende +# de eso. Cuando el mapeo por rango funcione, `takana qorpa provision` vuelve a ser el camino. +BASEDIR=${BASEDIR:-/var/lib/hammer/qorpa/instances} +_libre() { ! pgrep -f "[q]orpa run $1 " >/dev/null 2>&1; } + +_inst="$_base"; _n=2 +while ! _libre "$_inst"; do + _inst="$_base-$_n"; _n=$((_n+1)) + [ "$_n" -gt 9 ] && { echo "claude: hay 8 sesiones abiertas de $_base — cerrá alguna" >&2; exit 1; } +done +if [ ! -d "$BASEDIR/$_inst" ]; then + echo "claude: abro una sesión más ($_inst) — clonando la capa, ~1 s" >&2 + _sha=$(sed -n 's/^base = "sha256:\(.*\)"//p' "$BASEDIR/$_base/instance.toml") + takana qorpa create "$_inst" --base "$_sha" >/dev/null || { echo "claude: no pude crear $_inst" >&2; exit 1; } + cp "$BASEDIR/$_base/instance.toml" "$BASEDIR/$_inst/instance.toml" + rm -rf "$BASEDIR/$_inst/upper" + cp -a "$BASEDIR/$_base/upper" "$BASEDIR/$_inst/upper" + mkdir -p "$BASEDIR/$_inst/work" +fi # El `cd` no es comodidad: la memoria del agente se indexa POR RUTA DE TRABAJO. Desde `/` —que es # donde `qorpa run` deja el shell— la sesión usa el proyecto `-` y el agente empieza sin saber nada