5c253a26e2
Dos funciones bash para la mecanica del modo orquestador (Claudes secundarios interactivos en kitty): - launch_claude_agent_kitty(title, directory, prompt_file): lanza un Claude Code secundario en su propia terminal kitty con un prompt autonomo inyectado y --dangerously-skip-permissions, detached (setsid nohup ... disown) para sobrevivir al cierre de la terminal padre. - list_claude_agents([--json] [--exclude-current]): lista la flota de Claudes vivos cruzando pgrep -x claude con ~/.claude/sessions/<PID>.json (con validacion anti-PID-reciclado por procStart), reportando PID, sessionId, cwd, status, etime y KITTY_PID. Reusa la logica de descubrimiento de reboot_all_claudes_bash_infra. Tag de grupo de capacidad: orchestration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
136 lines
5.6 KiB
Bash
Executable File
136 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# launch_claude_agent_kitty — Lanza un Claude Code secundario interactivo y
|
|
# persistente en su propia terminal kitty, con un prompt autonomo inyectado
|
|
# desde un archivo. Es la mecanica de lanzamiento del "modo orquestador": un
|
|
# Claude principal descompone una tarea y lanza N secundarios, cada uno en su
|
|
# kitty, que el humano ve y puede retomar.
|
|
#
|
|
# Mecanismo:
|
|
# - setsid nohup kitty ... & disown -> la ventana sobrevive al cierre de la
|
|
# terminal padre (igual que reboot_all_claudes con setsid).
|
|
# - zsh -ic 'claude ...; exec zsh' -> al terminar el claude queda una shell
|
|
# interactiva viva para que el humano siga en esa terminal.
|
|
# - --dangerously-skip-permissions -> agente autonomo desatendido (sin
|
|
# confirmaciones). Riesgo asumido a proposito.
|
|
# - El prompt se inyecta con "$(cat <prompt_file>)" para no expandir nada en
|
|
# el shell del orquestador.
|
|
# - Log de arranque en /tmp/orq_<slug>_kitty.log, donde <slug> deriva del
|
|
# title (minusculas, no-alfanumerico -> '_').
|
|
set -euo pipefail
|
|
IFS=$' \t\n'
|
|
|
|
launch_claude_agent_kitty() {
|
|
# -----------------------------------------------------------------------
|
|
# Ayuda / sin argumentos.
|
|
# -----------------------------------------------------------------------
|
|
if [[ $# -eq 0 || "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
cat <<'USAGE'
|
|
Uso: launch_claude_agent_kitty <title> <directory> <prompt_file>
|
|
|
|
Lanza un Claude Code secundario interactivo y persistente en su propia
|
|
terminal kitty, con el prompt del archivo <prompt_file> inyectado y
|
|
--dangerously-skip-permissions (agente autonomo desatendido).
|
|
|
|
Argumentos (los 3 obligatorios):
|
|
title Titulo de la ventana kitty. Ej: "fn_registry · subtarea X".
|
|
directory Directorio de trabajo AISLADO donde arranca el claude
|
|
secundario (worktree git, sub-repo, o dir cualquiera). Debe
|
|
existir. Usa un dir aislado: dos claudes en el mismo working
|
|
tree comparten HEAD y dispersan commits.
|
|
prompt_file Ruta a un archivo .md con el prompt autonomo a inyectar.
|
|
Debe existir y ser legible.
|
|
|
|
Ejemplo:
|
|
launch_claude_agent_kitty "fn_registry · docs" /tmp/orq_docs_wt /tmp/orq_docs.md
|
|
|
|
El log de arranque va a /tmp/orq_<slug>_kitty.log (slug derivado del title).
|
|
USAGE
|
|
return 0
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------
|
|
# Validacion de argumentos.
|
|
# -----------------------------------------------------------------------
|
|
if [[ $# -ne 3 ]]; then
|
|
echo "launch_claude_agent_kitty: se requieren 3 argumentos <title> <directory> <prompt_file> (recibidos: $#). Usa -h." >&2
|
|
return 2
|
|
fi
|
|
|
|
local title="$1"
|
|
local directory="$2"
|
|
local prompt_file="$3"
|
|
|
|
if [[ -z "$title" ]]; then
|
|
echo "launch_claude_agent_kitty: <title> no puede estar vacio." >&2
|
|
return 2
|
|
fi
|
|
|
|
if [[ ! -d "$directory" ]]; then
|
|
echo "launch_claude_agent_kitty: el directorio de trabajo no existe: '$directory'." >&2
|
|
return 2
|
|
fi
|
|
|
|
if [[ ! -f "$prompt_file" ]]; then
|
|
echo "launch_claude_agent_kitty: el prompt_file no existe: '$prompt_file'." >&2
|
|
return 2
|
|
fi
|
|
|
|
if [[ ! -r "$prompt_file" ]]; then
|
|
echo "launch_claude_agent_kitty: el prompt_file no es legible: '$prompt_file'." >&2
|
|
return 2
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------
|
|
# Comprobar que kitty esta instalado.
|
|
# -----------------------------------------------------------------------
|
|
if ! command -v kitty >/dev/null 2>&1; then
|
|
echo "launch_claude_agent_kitty: 'kitty' no esta instalado o no esta en el PATH." >&2
|
|
return 1
|
|
fi
|
|
|
|
# -----------------------------------------------------------------------
|
|
# Derivar el slug del title para el nombre del log.
|
|
# minusculas, todo no-alfanumerico -> '_', colapsar/recortar '_'.
|
|
# -----------------------------------------------------------------------
|
|
local slug
|
|
slug="$(printf '%s' "$title" \
|
|
| tr '[:upper:]' '[:lower:]' \
|
|
| tr -c 'a-z0-9' '_' \
|
|
| sed -E 's/_+/_/g; s/^_//; s/_$//')"
|
|
[[ -z "$slug" ]] && slug="agent"
|
|
|
|
local log="/tmp/orq_${slug}_kitty.log"
|
|
|
|
# -----------------------------------------------------------------------
|
|
# Lanzar la kitty detached. El prompt se inyecta con "$(cat <prompt_file>)"
|
|
# ya escapado para que se evalue DENTRO de la kitty, no aqui.
|
|
# exec zsh deja una shell viva cuando el claude termina.
|
|
# -----------------------------------------------------------------------
|
|
local inner
|
|
inner="claude --dangerously-skip-permissions \"\$(cat $(printf '%q' "$prompt_file"))\"; exec zsh"
|
|
|
|
setsid nohup kitty \
|
|
--title "$title" \
|
|
--directory "$directory" \
|
|
zsh -ic "$inner" \
|
|
>"$log" 2>&1 &
|
|
disown 2>/dev/null || true
|
|
|
|
# -----------------------------------------------------------------------
|
|
# Reportar. Con setsid el $! es el PID de setsid, no el de kitty; basta
|
|
# con confirmar el lanzamiento y apuntar al log donde se ve el arranque.
|
|
# -----------------------------------------------------------------------
|
|
echo "launch_claude_agent_kitty: claude secundario lanzado."
|
|
echo " title: $title"
|
|
echo " directory: $directory"
|
|
echo " prompt_file: $prompt_file"
|
|
echo " log: $log"
|
|
echo " (sigue el arranque con: tail -f $(printf '%q' "$log"))"
|
|
return 0
|
|
}
|
|
|
|
# Permitir ejecutar el archivo directamente (no solo como funcion sourced).
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
launch_claude_agent_kitty "$@"
|
|
fi
|