--- name: parse_claude_tui kind: function lang: go domain: tui version: "1.0.0" purity: pure signature: "func ParseClaudeTUI(screen string) ClaudeTUIParse" description: "Parsea el texto renderizado de la pantalla de la TUI de Claude Code y extrae los turnos de la conversación (user, assistant, tool_use, tool_result) y la respuesta final del asistente. Equivalente a lo que devolvería `claude -p` pero operando sobre el render visual." tags: [terminal-capture, claude, tui, parse, conversation] uses_functions: - vt_render_go_tui uses_types: - claude_turn_go_tui - claude_tui_parse_go_tui returns: - claude_tui_parse_go_tui returns_optional: false error_type: "" imports: [] params: - name: screen desc: "Texto renderizado de la pantalla de la TUI de Claude Code, producido por VTRender(raw, rows, cols). Debe incluir el contenido visible completo: banner opcional, conversación y status bar opcional." output: "ClaudeTUIParse con los turnos visibles en orden (Role, Text, ToolName) y Answer — la concatenación de los bloques assistant que siguen al último turno user, equivalente al output de `claude -p`." tested: true tests: - "golden screen — banner + status bar + single Q&A" - "multiline assistant response" - "tool_use + tool_result + final assistant text" - "multi-turn — answer from last user only" - "no banner no status bar — minimal screen" - "determinism — same input produces same output" test_file_path: "functions/tui/parse_claude_tui_test.go" file_path: "functions/tui/parse_claude_tui.go" --- ## Ejemplo ```go // Pipeline completo: PTY capture → VTRender → ParseClaudeTUI → usar .Answer import ( "fmt" "fn-registry/functions/infra" "fn-registry/functions/tui" ) raw, _ := infra.PtyCaptureIdle("claude", []string{}, 40, 220, 8000) screen := tui.VTRender(raw, 40, 220) result := tui.ParseClaudeTUI(screen) fmt.Println(result.Answer) // imprime la respuesta final del asistente for _, turn := range result.Turns { fmt.Printf("[%s] %s\n", turn.Role, turn.Text) } ``` ## Cuando usarla Cuando captures la TUI de `claude` con `pty_capture_idle_go_infra` + `vt_render_go_tui` y necesites extraer la respuesta como dato estructurado (equivalente a `claude -p`) en vez de procesar el render visual crudo. Úsala para agentes que lanzan `claude` como subproceso TUI y quieren leer la respuesta sin requerir modo headless. ## Gotchas - **Heurístico y dependiente del layout de la TUI de Claude Code**: si Claude cambia los marcadores (`❯`, `●`, `⎿`, `✻`) o el formato del banner/status-bar, el parser puede dejar de funcionar sin aviso. - **Solo ve lo visible en el grid**: `VTRender` reconstruye únicamente lo que cabe en el terminal emulado (rows × cols). Respuestas largas que hacen scroll hacia arriba se truncan por arriba — no hay scrollback. Para respuestas largas, aumentar `rows` en `VTRender` o usar `claude -p` directamente. - **tool_use/tool_result best-effort**: la TUI colapsa algunos bloques de herramientas. Los `ToolName` y textos de `tool_result` pueden quedar incompletos si la TUI los trunca con `…`. - **Answer asume captura post-respuesta**: `PtyCaptureIdle` debe haberse disparado DESPUÉS de que la respuesta terminó de renderizarse (el spinner `✻` desapareció). Si se captura durante el streaming, `Answer` puede estar incompleto.