From a1105dc4c55ad82ddf4095b06413a37d5f9c9288 Mon Sep 17 00:00:00 2001 From: agent Date: Sun, 21 Jun 2026 21:50:32 +0200 Subject: [PATCH] feat(infra): spawn_fleet_agent auto-detecta socket/session de $TMUX --socket/--session ahora opcionales: si no se pasan, se auto-detectan del contexto tmux ($TMUX) via detect_fleet_context. Los explicitos siguen primando. Aborta (exit 2) solo si tras auto-detectar siguen vacios (no hay tmux). Elimina el bug de caer a kitty cuando $FLEET_SOCKET viene vacia pese a estar en la flota. Bump v1.2.0 + growth log. --- bash/functions/infra/spawn_fleet_agent.md | 21 ++++++++++++++----- bash/functions/infra/spawn_fleet_agent.sh | 25 +++++++++++++++++++++-- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/bash/functions/infra/spawn_fleet_agent.md b/bash/functions/infra/spawn_fleet_agent.md index 6cd7c2b8..0278bc7c 100644 --- a/bash/functions/infra/spawn_fleet_agent.md +++ b/bash/functions/infra/spawn_fleet_agent.md @@ -3,23 +3,24 @@ name: spawn_fleet_agent kind: function lang: bash domain: infra -version: 1.1.0 +version: 1.2.0 purity: impure -signature: "spawn_fleet_agent --socket --session --cwd [--prompt-file | --skill ] [--role orchestrator|executor] [--parent ] [--title ]" -description: "Lanza un Claude como window nueva dentro de la sesion tmux de un perfil FleetView (socket aislado), opcionalmente en modo orquestador (skill embebida como primer prompt), marcado con un role en su goal.json y atribuido a su orquestador padre. Es la forma de que un ejecutor o el propio orquestador VIVAN en la flota tmux (visibles en la TUI fleetview, conmutables con /fleet focus) en vez de en kitties sueltas. Reemplaza a launch_claude_agent_kitty cuando se opera dentro de un perfil fleet ya montado. Con --parent escribe parent_orchestrator en el goal.json del nuevo Claude (via mark_claude_parent) para que el watcher de fleetview rutee sus avisos al orquestador que lo lanzo. Imprime el window_id creado." +signature: "spawn_fleet_agent [--socket ] [--session ] [--cwd ] [--prompt-file | --skill ] [--role orchestrator|executor] [--parent ] [--title ]" +description: "Lanza un Claude como window nueva dentro de la sesion tmux de un perfil FleetView (socket aislado), opcionalmente en modo orquestador (skill embebida como primer prompt), marcado con un role en su goal.json y atribuido a su orquestador padre. --socket/--session son opcionales: si no se pasan se auto-detectan del contexto tmux ($TMUX) via detect_fleet_context (los explicitos tienen prioridad), evitando caer a kitty cuando $FLEET_SOCKET viene vacia. Es la forma de que un ejecutor o el propio orquestador VIVAN en la flota tmux (visibles en la TUI fleetview, conmutables con /fleet focus) en vez de en kitties sueltas. Reemplaza a launch_claude_agent_kitty cuando se opera dentro de un perfil fleet ya montado. Con --parent escribe parent_orchestrator en el goal.json del nuevo Claude (via mark_claude_parent) para que el watcher de fleetview rutee sus avisos al orquestador que lo lanzo. Imprime el window_id creado." tags: [fleet, claude-fleet, orchestration, tmux, infra] uses_functions: - mark_claude_role_py_infra - mark_claude_parent_py_infra + - detect_fleet_context_bash_infra uses_types: [] error_type: error_go_core file_path: "bash/functions/infra/spawn_fleet_agent.sh" tested: false params: - name: --socket - desc: "Socket tmux del perfil FleetView (ej. fleet, fleet2). El perfil debe estar ya montado (sesion viva)." + desc: "Socket tmux del perfil FleetView (ej. fleet, fleet2). Opcional: se auto-detecta de $TMUX via detect_fleet_context si no se pasa. El perfil debe estar ya montado (sesion viva)." - name: --session - desc: "Nombre de la sesion tmux dentro del socket (normalmente igual al socket)." + desc: "Nombre de la sesion tmux dentro del socket (normalmente igual al socket). Opcional: se auto-detecta de $TMUX si no se pasa." - name: --cwd desc: "Directorio de trabajo del nuevo Claude. Default: PWD." - name: --prompt-file @@ -54,6 +55,11 @@ Lanza un Claude dentro de un perfil FleetView (sesion tmux de un socket aislado) ./fn run spawn_fleet_agent --socket fleet2 --session fleet2 --cwd "$HOME/fn_registry" \ --prompt-file /tmp/orq_health.md --title "kanban-health" \ --parent 32945650-a4e1-472b-90c9-5b38ef60a463 + +# Sin --socket/--session: auto-detecta el socket de la flota actual ($TMUX). +# Forma preferida desde dentro de la flota — no hace falta saber el socket: +./fn run spawn_fleet_agent --cwd "$HOME/fn_registry" \ + --prompt-file /tmp/orq_health.md --title "kanban-health" ``` ## Cuando usarla @@ -62,9 +68,14 @@ Cuando el orquestador (o el launcher) necesita arrancar un Claude que debe vivir ## Gotchas +- **Auto-deteccion de socket/session**: si no pasas `--socket`/`--session`, se derivan de `$TMUX` via `detect_fleet_context`. Los explicitos tienen prioridad. Solo aborta (exit 2) si tras auto-detectar siguen vacios (de verdad no hay tmux). No dependas de `$FLEET_SOCKET`: a veces viene vacia en un claude resumido/relanzado aunque viva en la flota — `$TMUX` es la senal fiable. - El perfil (socket+session) debe estar **ya montado** (`launch_fleetclaude` primero); si la sesion no existe, falla con exit 1. - El `--role` se aplica en **background**: el `sessionId` del nuevo Claude no existe hasta que Claude escribe `~/.claude/sessions/.json` (unos segundos). `mark_claude_role` espera ese archivo. Si el arranque es muy lento, el role puede tardar en aparecer; es no-fatal (el agente simplemente no se pinea/identifica hasta entonces). - El `--parent` se aplica igual en **background** via `mark_claude_parent` (misma espera del `sessions/.json`). Cuando se pasan `--role` y `--parent` juntos se encadenan **secuencialmente** en el mismo subshell (primero role, luego parent) para que la segunda escritura lea el goal ya con la primera clave puesta — sin carrera de lectura-modificacion-escritura. Es no-fatal: si el sessions JSON no aparece a tiempo, el `parent_orchestrator` simplemente no se escribe. - `--skill` envia `/` como primer prompt: depende de que Claude Code interprete el primer argumento como invocacion de slash command (verificado con `/orquestador`). - El nuevo Claude hereda `FLEET_SOCKET`/`FLEET_SESSION` del entorno del server tmux (que `launch_fleetclaude` fija con `set-environment`), asi apunta al perfil correcto. - `--dangerously-skip-permissions` siempre (los agentes de la flota trabajan desatendidos); riesgo asumido como en el resto del modo orquestador. + +## Capability growth log + +- v1.2.0 (2026-06-21) — `--socket`/`--session` ahora son opcionales: se auto-detectan del contexto tmux (`$TMUX`) via `detect_fleet_context` cuando no se pasan. Elimina el gotcha de caer a kitty cuando `$FLEET_SOCKET` viene vacia pese a estar en la flota. Los valores explicitos siguen primando. diff --git a/bash/functions/infra/spawn_fleet_agent.sh b/bash/functions/infra/spawn_fleet_agent.sh index 7da67cbe..28b93ee7 100644 --- a/bash/functions/infra/spawn_fleet_agent.sh +++ b/bash/functions/infra/spawn_fleet_agent.sh @@ -29,11 +29,15 @@ spawn_fleet_agent() { --title) shift; title="${1:-claude}" ;; -h|--help) cat <<'USAGE' -Uso: spawn_fleet_agent --socket --session --cwd [opciones] +Uso: spawn_fleet_agent [--socket ] [--session ] [--cwd ] [opciones] Lanza un Claude como window nueva en la sesion tmux del socket (un perfil FleetView ya montado). Imprime el window_id creado. +--socket/--session son OPCIONALES: si no se pasan, se auto-detectan del contexto +tmux actual ($TMUX) via detect_fleet_context. Los valores explicitos tienen +prioridad. Aborta solo si tras auto-detectar siguen vacios (no hay tmux). + Opciones: --prompt-file Primer prompt del Claude = contenido del archivo (prompt autocontenido del ejecutor). El cat lo hace el shell del @@ -66,8 +70,25 @@ USAGE shift done + # Auto-detectar socket/session del contexto tmux ($TMUX) cuando no se pasan + # explicitos. Los --socket/--session explicitos SIEMPRE tienen prioridad. + # Esto evita el bug de caer a kitty cuando $FLEET_SOCKET viene vacia pese a + # estar dentro de una window de la flota (ver detect_fleet_context). + if [[ -z "$socket" || -z "$session" ]]; then + local _detector ctx det_socket="" det_session="" + _detector="$(dirname "${BASH_SOURCE[0]}")/detect_fleet_context.sh" + if [[ -f "$_detector" ]]; then + ctx="$(bash "$_detector" 2>/dev/null || true)" + # Parseo minimo sin depender de jq: extraer "socket":"..." / "session":"...". + det_socket="$(printf '%s' "$ctx" | sed -n 's/.*"socket":"\([^"]*\)".*/\1/p')" + det_session="$(printf '%s' "$ctx" | sed -n 's/.*"session":"\([^"]*\)".*/\1/p')" + [[ -z "$socket" ]] && socket="$det_socket" + [[ -z "$session" ]] && session="$det_session" + fi + fi + [[ -z "$socket" || -z "$session" ]] && { - echo "spawn_fleet_agent: --socket y --session son obligatorios" >&2 + echo "spawn_fleet_agent: no se detecto contexto tmux (\$TMUX vacia) y no se pasaron --socket/--session. Lanza desde dentro de la flota o pasa el socket/session explicito." >&2 return 2 } [[ -z "$cwd" ]] && cwd="$PWD"