Files
agent 697c523604 feat: scaffold claude_extract — captura headless de TUI via PTY
App CLI que automatiza una TUI interactiva a traves de un pseudo-terminal y
captura su texto. Pensada para la CLI claude (solo interactiva con TTY real),
generica para cualquier TUI.

- Modo screen: reconstruye layout 2D con vt_render_go_tui (emulador VT100).
- Modo stream: limpia ANSI de output secuencial con strip_ansi_go_core.
- Modo raw: bytes del PTY intactos.
- --exec pipea el texto a otro proceso; --cwd salta el dialogo MCP de claude.

Captura via pty_capture_idle_go_infra. Validada end-to-end contra claude
(prompt enviado, respuesta capturada) y con 5 e2e_checks POSIX deterministas.
2026-06-03 22:28:06 +02:00

6.8 KiB

name, lang, domain, version, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, icon, e2e_checks
name lang domain version description tags uses_functions uses_types framework entry_point dir_path icon e2e_checks
claude_extract go infra 0.1.0 CLI que automatiza una TUI interactiva a traves de un pseudo-terminal (PTY) headless y captura su texto. Pensada para la CLI 'claude' (solo entra en modo interactivo con un TTY real) pero sirve para cualquier TUI. Reconstruye el layout 2D con un emulador VT, o limpia ANSI de output secuencial, y permite pipear el resultado a otro proceso.
cli
terminal
pty
tui
automation
capture
pty_capture_idle_go_infra
vt_render_go_tui
strip_ansi_go_core
main.go apps/claude_extract
phosphor accent
terminal-window #7c3aed
id cmd timeout_s
build CGO_ENABLED=1 go build -tags fts5 -o claude_extract . 120
id cmd expect_stdout_contains timeout_s
smoke_capture ./claude_extract --cmd bash --arg -lc --arg 'echo CAPTURA_OK' --warmup 200ms --idle 400ms --max 5s CAPTURA_OK 15
id cmd expect_stdout_contains timeout_s
smoke_screen_layout ./claude_extract --cmd bash --arg -lc --arg $'printf "foo\033[10Gbar\n"' --mode screen --warmup 200ms --idle 400ms --max 5s foo 15
id cmd expect_stdout_contains timeout_s
smoke_stream_strip ./claude_extract --cmd bash --arg -lc --arg $'printf "\033[31mROJO\033[0m\n"' --mode stream --warmup 200ms --idle 400ms --max 5s ROJO 15
id cmd expect_stdout_contains timeout_s
smoke_exec_pipe ./claude_extract --cmd bash --arg -lc --arg 'echo pipe ok' --warmup 200ms --idle 400ms --max 5s --exec 'tr a-z A-Z' PIPE OK 15

claude_extract

Que hace

Automatiza una CLI interactiva (TUI) y captura su texto, de forma headless, a traves de un pseudo-terminal (PTY). Nunca abre una ventana de terminal: el PTY es virtual, en memoria.

Existe porque algunas CLIs — sobre todo la CLI claude — solo entran en su modo interactivo rico cuando detectan un TTY real. Un pipe normal las degrada a modo "print". claude_extract le da al proceso hijo un PTY real, lo dirige con input scripteado (teclea el prompt, espera, y pulsa Enter como pasos separados), espera a que el render se estabilice, y devuelve el texto.

Por defecto el texto se imprime limpio a stdout. Con --exec se pipea a otro proceso por stdin. Con --mode raw se obtienen los bytes del terminal sin tocar.

Arquitectura

La app es solo orquestacion + superficie de linea de comandos + defaults amables con claude. Toda la logica reutilizable vive en el registry:

Pieza Funcion del registry Rol
Captura PTY pty_capture_idle_go_infra Lanza el comando en un PTY, inyecta input, corta por inactividad o timeout, devuelve bytes crudos.
Render de pantalla vt_render_go_tui Emula un terminal VT100 y reconstruye el layout 2D (espacios entre columnas que en el stream eran movimientos de cursor). Modo screen.
Limpieza de stream strip_ansi_go_core Quita secuencias ANSI de output secuencial tipo log. Modo stream.

Modos de salida (--mode)

Modo Que hace Cuando
screen (default) Reconstruye el layout 2D con vt_render. TUIs que posicionan texto con cursor absoluto: claude, htop, dialog. Sin esto las palabras quedan pegadas ("2newMCPservers").
stream Quita ANSI del stream con strip_ansi. Output secuencial: logs, builds, comandos que imprimen linea a linea.
raw Bytes del PTY intactos (ANSI incluido). Cuando quieres procesar los escape codes tu mismo. Atajo: --raw.

Ejemplo

cd apps/claude_extract
CGO_ENABLED=1 go build -tags fts5 -o claude_extract .

# Preguntar a claude y obtener su respuesta como texto con layout (modo screen).
# --cwd apunta a un repo donde los MCP de claude ya estan aprobados, para saltar
# el dialogo de arranque "new MCP servers found".
./claude_extract \
  --prompt "responde unicamente con la palabra PONG" \
  --cwd /home/enmanuel/fn_registry \
  --warmup 4s --step-delay 600ms --idle 4s --max 60s

# Capturar una TUI cualquiera (sin prompt), output secuencial limpio.
./claude_extract --cmd bash --arg -lc --arg 'echo hola' --mode stream

# Pipear el texto capturado a otro proceso por stdin.
./claude_extract --prompt "lista 5 ideas" --cwd /home/enmanuel/fn_registry --exec "tee ideas.txt"

# Leer el prompt de un pipe.
echo "explica este error" | ./claude_extract --cwd /home/enmanuel/fn_registry

Flags

Flag Default Que hace
--cmd claude Comando a lanzar dentro del PTY.
--arg Argumento extra para --cmd (repetible).
--prompt Texto que se teclea primero, seguido de Enter. Si vacio y stdin es un pipe, se lee de stdin.
--send Input crudo extra tras el prompt (repetible). Incluye \r para Enter, ej. --send $'\r'.
--mode screen screen | stream | raw. Ver tabla de modos.
--raw false Atajo de --mode raw.
--warmup 2.5s Espera antes de enviar input, para que la TUI cargue.
--step-delay 300ms Espera entre inputs sucesivos (entre teclear y Enter).
--idle 2.5s Corta la captura tras este silencio (sin bytes nuevos de la TUI).
--max 120s Timeout duro de toda la captura.
--exec Pipea el texto capturado al stdin de este comando (via sh -c).
--out Tambien escribe el texto capturado a este archivo.
--cwd Ejecuta el hijo en este directorio (util para saltar el dialogo MCP de claude).

Cuando usarla

  • Cuando necesites el render real de una CLI interactiva como texto, para auditar, scriptear o alimentar otro proceso.
  • Cuando claude -p (modo print) no te sirva porque quieres exactamente lo que muestra la TUI.

Gotchas

  • Linux/Unix only: el PTY es POSIX (heredado de pty_capture_idle_go_infra).
  • Enter separado: el prompt y el Enter se envian como pasos distintos a proposito; un \r pegado al texto lo trata claude como newline literal en el input, no como submit.
  • Layout pegado en modo stream: para TUIs con posicionamiento absoluto usa --mode screen. --mode stream (strip_ansi) pega las palabras porque los espacios entre columnas eran movimientos de cursor.
  • Spinners y el corte por idle: si la TUI hace render periodico (spinner, reloj), el --idle no se dispara y la captura cae al --max. Para claude, el spinner se detiene al terminar la respuesta, asi que --idle corta poco despues; sube --max si la respuesta es larga.
  • Dialogo de arranque de claude: en un cwd cuyos MCP no estan aprobados, claude muestra "new MCP servers found" y bloquea. Usa --cwd <repo-raiz-aprobado> o despacha el dialogo con --send.
  • Dimensiones fijas 40x120: el PTY y el render usan 40 filas x 120 columnas. Una respuesta mas ancha se envuelve a 120 columnas.
  • Sin color: el modo screen reconstruye texto y layout, no color.