feat: scaffold claude_wire — respuesta de claude interceptando el SSE de la red

Obtiene el texto del modelo interceptando el stream SSE de api.anthropic.com
/v1/messages con un mitmproxy, en vez de parsear el render de la terminal.
Dirige la TUI interactiva real (NUNCA claude -p) por el proxy con claude_pipe,
y emite el texto exacto token a token como NDJSON.

Compone tee_anthropic_sse_py_cybersecurity (addon mitmproxy). Corta por
message_stop (sin idle ciego): ~9s vs ~15s de parsear la TUI, y texto exacto
sin artefactos. Validado end-to-end contra claude real.
This commit is contained in:
agent
2026-06-04 00:25:25 +02:00
commit 9c7d9705fd
5 changed files with 366 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
---
name: claude_wire
lang: go
domain: infra
version: 0.1.0
description: "Obtiene la respuesta de claude interceptando el stream SSE del modelo en la red (api.anthropic.com /v1/messages) en vez de parsear el render de la terminal. Dirige la TUI interactiva real (NUNCA claude -p) a traves de un mitmproxy que teea el SSE, y emite el texto exacto del modelo token a token como NDJSON. Mas rapido que parsear la TUI (corta por message_stop, sin idle ciego) y exacto (sin artefactos del render)."
tags: [cli, claude, mitmproxy, sse, streaming, wire, web-proxy]
uses_functions:
- tee_anthropic_sse_py_cybersecurity
uses_types: []
framework: ""
entry_point: "main.go"
dir_path: "apps/claude_wire"
icon:
phosphor: "wifi-high"
accent: "#10b981"
e2e_checks:
- id: build
cmd: "go build -o claude_wire ."
timeout_s: 60
- id: needs_prompt
cmd: "./claude_wire 2>&1 || true"
expect_stdout_contains: "no prompt"
timeout_s: 10
---
# claude_wire
## Que hace
Devuelve la respuesta de `claude` **interceptando el stream del modelo en la red**, no parseando
el render de la terminal. Dirige la TUI interactiva real de `claude` (jamas `claude -p`) a traves
de un mitmproxy que captura el SSE de `POST api.anthropic.com/v1/messages`, y emite el texto
exacto del modelo, token a token, como NDJSON.
Es la culminacion de la exploracion: parsear el render (`claude_pipe`) es heuristico y lento
(warmup + idle ciegos, artefactos del spinner, truncacion por scroll). Interceptar la red da el
texto **exacto** del modelo, en **streaming real**, y sabe **exactamente** cuando termina
(`message_stop`), eliminando el idle ciego.
## Como funciona
```
mitmdump + tee_anthropic_sse ── captura el SSE de /v1/messages → NDJSON
claude_pipe (PTY, dirige la TUI) ── lanza claude interactivo y teclea el prompt
claude_wire (este runner) ── lee el NDJSON del proxy, emite text_delta + result,
mata todo en cuanto llega message_stop
```
1. Arranca `mitmdump` con el addon `tee_anthropic_sse_py_cybersecurity` (`FN_WIRE_ONLY_TOOLS=1`
para aislar la respuesta principal de las llamadas auxiliares de titulo/clasificador).
2. Dirige la TUI interactiva con `claude_pipe` por el proxy (`HTTPS_PROXY` + `NODE_EXTRA_CA_CERTS`
apuntando a la CA de mitmproxy). El output parseado de `claude_pipe` se ignora — solo se usa
para lanzar claude y teclear el prompt.
3. Lee el NDJSON que emite el addon, sigue el primer stream con `has_tools`, emite cada
`text_delta`, y al `message_stop` emite el `result` y mata mitmdump + claude_pipe.
El texto sale **del cable**, no de la pantalla.
## Prerrequisitos
- `mitmproxy` instalado (`mitmdump` en el PATH): `uv tool install mitmproxy`.
- La CA de mitmproxy generada y confiada: arrancar `mitmdump` una vez crea
`~/.mitmproxy/mitmproxy-ca-cert.pem`. claude la acepta via `NODE_EXTRA_CA_CERTS`.
- El binario `claude_pipe` compilado (driver de la TUI): `apps/claude_pipe/claude_pipe`.
## Ejemplo
```bash
cd apps/claude_wire
go build -o claude_wire .
./claude_wire --prompt "di tres palabras: uno dos tres" --cwd /home/enmanuel/fn_registry
# {"type":"text_delta","text":"T"}
# {"type":"text_delta","text":"res palabras: uno dos tres."}
# {"type":"result","subtype":"success","result":"Tres palabras: uno dos tres."}
```
## Flags
| Flag | Default | Que hace |
|---|---|---|
| `--prompt` | — | Prompt a enviar (o arg posicional al final). |
| `--cwd` | `~/fn_registry` | Directorio donde corre claude (MCP aprobados → sin dialogo de arranque). |
| `--port` | `8901` | Puerto del mitmproxy. |
| `--root` | `~/fn_registry` | Raiz del registry (para localizar el addon por defecto). |
| `--addon` | `<root>/python/functions/cybersecurity/tee_anthropic_sse.py` | Addon mitmproxy. |
| `--ca` | `~/.mitmproxy/mitmproxy-ca-cert.pem` | CA de mitmproxy para `NODE_EXTRA_CA_CERTS`. |
| `--pipe` | `apps/claude_pipe/claude_pipe` | Binario que dirige la TUI. |
| `--warmup` | `5s` | Espera de `claude_pipe` para que cargue la TUI antes de teclear. |
| `--max` | `120s` | Timeout duro. |
## Comparativa (por que existe)
| | `claude_pipe` (parsear TUI) | `claude_wire` (interceptar red) |
|---|---|---|
| Texto | heuristico, artefactos | **exacto, byte a byte** |
| Streaming | snapshots ~150ms | **token real (content_block_delta)** |
| Fin de respuesta | idle ciego (4s) | **message_stop exacto** |
| Latencia medida | ~15s | **~9s** |
| Robustez | fragil (UI cambia) | **protocolo API estable** |
## Cuando usarla
- Cuando quieras el texto exacto del modelo desde la TUI interactiva, en streaming real, sin
parsear el render ni pagar el idle ciego.
- Como backend de un chat: emite el mismo NDJSON que `claude_pipe --stream`, mas rapido y exacto.
## Gotchas
- **Requiere mitmproxy + CA confiada** (`NODE_EXTRA_CA_CERTS`). Si claude empezara a hacer TLS
pinning, dejaria de funcionar (hoy no lo hace).
- **Depende de `claude_pipe`** como driver de la TUI (el PTY). No reimplementa el pilotaje.
- **Sigue heredando el warmup** de `claude_pipe` (esperar a que la TUI cargue antes de teclear);
ahi esta el grueso de la latencia restante. Una deteccion de "TUI lista" lo reduciria mas.
- **Una interaccion dispara varias /v1/messages** (respuesta + titulo/clasificador en haiku); el
addon filtra por `has_tools` para seguir solo la principal.
- **Es trafico de tu propia cuenta y maquina** — observabilidad local, no acceso remoto.
- **Linux/Unix** (PTY POSIX heredado de `claude_pipe`).