Referencia de scripting
Verbos CLI, selectores, métodos JSON-RPC, frames de eventos, claves de configuración, specs de workspace, specs de flow, herramientas MCP, hooks y códigos de salida para automatización Paneflow.
Esta es la referencia compacta de Scripting y automatización. Nombra la superficie pública que un script humano o un LLM puede citar con precisión.
Verbos CLI
El binario paneflow intercepta estos verbos y sale antes de iniciar
la GUI. Los verbos desconocidos salen con código de uso 2 en vez de
lanzar la app silenciosamente.
| Verbo | Método principal o motor | ¿Escribe en paneles? | Uso |
|---|---|---|---|
ls [--human] | surface.list | No | Lista paneles en el espacio de trabajo activo |
read <target> | surface.read | No | Lee el scrollback de un panel |
search <target> <pattern> | surface.search | No | Busca en el scrollback de un panel |
ps [--json] | fleet.list | No | Lista agentes detectados entre espacios de trabajo |
status <target> [--json] | surface.status | No | Lee el estado de agente de un panel |
new | workspace.create | No | Crea un espacio de trabajo |
select <index> | workspace.select | No | Selecciona un espacio de trabajo |
split <h|v> | surface.split | No | Divide un panel |
focus <target> | surface.focus | No | Enfoca un panel y su espacio de trabajo |
send <target> <text> | surface.send_text | Gate | Prepara o envía texto |
key <target> <keystroke> | surface.send_keystroke | Gate | Envía una tecla que no somete |
wait --match <sel> | surface.read, events.subscribe | No | Bloquea hasta pattern, idle o ambos |
watch [--surface <sel>] [--type <event>] | events.subscribe | No | Emite eventos de ciclo de vida y superficie |
up <file> | Motor de spec workspace | Solo prellenado | Crea un workspace declarativo |
flow run <file> | Motor flow | Gate para pasos que envían | Ejecuta un DAG multiagente local |
Alias aceptados por la CLI: list_panes apunta a ls, read_pane a
read y search_pane a search.
Selectores
| Selector | Ejemplo | Notas |
|---|---|---|
| Id numérico | paneflow read 42 | Coincide exactamente con surface_id |
| Nombre | paneflow status backend | Mejor selector para scripts duraderos |
cmdline:<substr> | paneflow read cmdline:vite | argv foreground completo en Linux, nombre de ejecutable en macOS y Windows |
cwd:<path> | paneflow read cwd:/home/me/api | Coincide con el directorio de trabajo del panel |
Un selector que no coincide con nada o coincide con varios paneles sale
con código 3, salvo comandos que aceptan explícitamente múltiples
coincidencias como send --broadcast, wait --any y wait --all.
Códigos de salida
| Código | Significado |
|---|---|
0 | Éxito |
1 | Fallo runtime: instancia inaccesible, panel cerrado, gate rechazado o error de handler |
2 | Error de uso CLI |
3 | Objetivo no encontrado o ambiguo |
4 | Timeout de wait o timeout de ready en flow |
Gates de escritura
La lectura está permitida por defecto. Las escrituras se separan por capacidad:
| Operación | Gate |
|---|---|
send sin --submit | PANEFLOW_IPC_SCRIPTING=1 o ai_unrestricted |
send --submit | PANEFLOW_IPC_SCRIPTING=1 o ai_unrestricted |
key | PANEFLOW_IPC_SCRIPTING=1 |
Paso flow con submit = true | Capacidad scripting reportada por system.capabilities |
send no añade carriage return salvo que --submit esté presente.
key rechaza teclas que someten como enter, ctrl-m y ctrl-j. Un
payload único de surface.send_text está limitado a 64 KiB.
Claves de configuración relevantes:
| Clave | Valor por defecto | Significado |
|---|---|---|
ai_unrestricted | false | Permite a automatizaciones de IA confiables enviar texto sin el gate de entorno |
ai_injection_fence | true | Envuelve el texto de surface.read en una envoltura de terminal no confiable |
submit_paste_delay_ms | 70 | Retardo base entre bracketed paste y el carriage return de envío |
terminal.env | ninguno | Variables de entorno inyectadas en nuevos terminales |
Campos de lectura
paneflow read <target> --json y surface.read crudo devuelven:
| Campo | Significado |
|---|---|
text | Texto de scrollback, fenced por defecto |
lines | Número de líneas devueltas |
total_lines | Total de líneas retenidas |
eof | Si la lectura llegó a la línea retenida más antigua |
output_generation | Contador monótono avanzado por la salida del panel |
Valores por defecto y límites: lines vale 200 por defecto y se
limita a 1-4000. offset parte del final del buffer. Un offset fuera
de rango es un error invalid-params.
El parámetro JSON-RPC fenced usa ai_injection_fence por defecto.
El flag CLI --raw pasa fenced: false.
Campos de estado de agente
paneflow ps --json devuelve {"agents":[...]}. paneflow status <target> --json devuelve un objeto de estado.
| Campo | Significado |
|---|---|
pid | Id de proceso del agente, si se conoce |
tool | Familia de agente como claude, codex, opencode o gemini |
state | thinking, waiting_for_input, finished, errored, stalled, idle o unknown_running |
hooked | Si los eventos de hook de ciclo de vida están conectados |
reason | Razón de detección, incluido no_hook |
surface_id | Id del panel |
surface_name | Nombre del panel |
workspace | Índice del espacio de trabajo |
active_tool_name | Herramienta que se está ejecutando dentro del agente |
message | Prompt o texto de permiso en espera |
last_result | Resumen del último turno, si está disponible |
waiting_ms | Tiempo pasado esperando input |
idle_ms | Tiempo desde la última actividad observada |
output_generation | Contador de salida del panel, en status |
Una flota vacía es {"agents":[]} con código de salida 0. Un panel
sin agente rastreado devuelve estado idle, no un error.
Spec workspace
paneflow up <file> lee una spec workspace TOML.
| Campo top-level | Tipo | Valor por defecto | Notas |
|---|---|---|---|
name | string | "Workspace" | Título del espacio de trabajo |
layout | string | "even_h" | even_h, even_v, main_vertical o tiled |
port_base | integer | 3000 | Base para la asignación ${port_offset} |
[[panes]] | array | requerido | Una entrada por panel |
| Campo de panel | Tipo | Valor por defecto | Notas |
|---|---|---|---|
cwd | string | ninguno | Debe existir tras expansión y canonicalization |
agent | string | ninguno | Nombre de launcher de agente, mutuamente exclusivo con command |
command | string | ninguno | Comando crudo, mutuamente exclusivo con agent |
prompt | string | ninguno | Prellenado en la entrada de un agente, nunca enviado por up |
focus | bool | false | Da foco inicial a este panel |
env | table | ninguno | Se fusiona sobre terminal.env; soporta ${port_offset} |
name | string | ninguno | Nombre selector estable |
worktree | string | ninguno | Nombre de rama para un worktree gestionado bajo <repo>.worktrees/ |
copy_env | bool | true | Copia archivos .env* ignorados por git al worktree |
setup | string | ninguno | Comando ejecutado antes del lanzamiento |
setup_timeout_secs | integer | 300 | Timeout de setup |
worktree_teardown | string | "auto" | auto elimina worktrees limpios al cerrar; keep los conserva |
${port_offset} solo se sustituye dentro de valores env. Las claves
desconocidas son errores. La creación de workspace valida rutas antes
de crear paneles.
Spec flow
paneflow flow run <file> lee una spec flow TOML y la ejecuta contra
la instancia Paneflow actual.
| Campo | Tipo | Notas |
|---|---|---|
id | string | Id de paso requerido y único |
needs | array | Dependencias; en foreach, espera todas las instancias |
foreach | array | Fan-out, una instancia por item |
pane | inline table | Crea un panel usando campos de panel workspace |
send | inline table | { target, text, submit? }; requiere una dependencia |
ready | table | { pattern, timeout_secs? }; barrera regex |
capture | table | { var, lines }; captura 1-500 líneas después de ready |
submit | bool | Envía el prompt de un panel creado; requiere acceso scripting |
Variables:
| Variable | Alcance |
|---|---|
${item} | Pasos foreach: cwd, name, worktree, env, send.target, ready.pattern, prompts y textos |
${var} | Valores capturados dentro de send.text y pane.prompt que se envía |
${var.<item>} | Capturas de un grupo foreach |
El runner valida claves desconocidas, dependencias faltantes, ciclos de
dependencias, regex inválidas, capturas indefinidas, presupuesto de
paneles y timeouts faltantes antes de ejecutar. Ctrl-C detiene el
bucle de orquestación; los paneles creados permanecen en Paneflow.
Conexión JSON-RPC
| Propiedad | Valor |
|---|---|
| Endpoint Linux | $XDG_RUNTIME_DIR/paneflow/paneflow.sock |
| Endpoint macOS | Directorio runtime del usuario, mismo nombre de socket Paneflow |
| Endpoint Windows | \\.\pipe\paneflow |
| Framing | JSON-RPC 2.0 delimitado por líneas |
| Modelo de petición | Una petición por conexión, salvo events.subscribe |
| Confianza local | Mismo usuario únicamente; sin listener de red, sin token, sin TLS |
| Backpressure | Límite de conexiones y colas de eventos acotadas devuelven errores estructurados o frames dropped |
Sondea capacidades en runtime:
printf '%s\n' '{"jsonrpc":"2.0","method":"system.capabilities","params":{},"id":1}' \
| nc -U "$PANEFLOW_SOCKET_PATH"Métodos JSON-RPC
| Método | Params | Retorno o notas |
|---|---|---|
system.ping | - | Check de vida |
system.capabilities | - | {scripting, methods[]} |
system.identify | - | {name, version, protocol} |
workspace.list | - | Espacios de trabajo con índices y títulos |
workspace.current | - | Espacio de trabajo activo |
workspace.create | name?, cwd?, layout? | Crea un espacio de trabajo |
workspace.select | index | Cambia de espacio de trabajo |
workspace.close | index? | Cierra un espacio de trabajo |
workspace.up | name, layout, panes[] | Spawn declarativo usado por up y raíces flow |
workspace.restore_layout | layout | Aplica un árbol layout |
surface.list | - | {surfaces:[{surface_id,name,title,cwd,cmd,workspace}]} |
surface.read | surface_id, lines?, offset?, fenced? | Scrollback y output_generation |
surface.search | surface_id, pattern, max_matches? | Coincidencias substring case-insensitive |
surface.rename | surface_id, name | Renombra o borra el nombre de un panel |
surface.focus | surface_id | Enfoca panel y espacio de trabajo |
surface.status | surface_id | Estado de agente para un panel |
surface.send_text | surface_id, text, submit?, paste? | Escritura de texto PTY con gate |
surface.send_keystroke | surface_id, keystroke | Tecla no submit gated por env |
surface.split | direction, surface_id?, cwd?, command?, prompt?, env?, name?, managed_worktree? | Divide un panel |
fleet.list | - | Snapshot read-only de la flota |
events.subscribe | surfaces?, types? | Stream persistente de eventos delimitado por líneas |
ai.session_start | payload hook | Telemetría de ciclo de vida |
ai.prompt_submit | payload hook | Telemetría de ciclo de vida |
ai.tool_use | payload hook | Telemetría de ciclo de vida |
ai.notification | payload hook | Telemetría de ciclo de vida |
ai.stop | payload hook | Telemetría de ciclo de vida |
ai.exit | payload hook | Telemetría de ciclo de vida |
ai.session_end | payload hook | Telemetría de ciclo de vida |
Los fallos estructurados usan envolturas JSON-RPC error: -32602
invalid params, -32601 gated method, -32001 permission y -32000
backpressure. Algunos errores de validación legacy aún llegan como
{"error":"..."} dentro de result; los clientes deben tratar ambas
formas como fallos.
Eventos
paneflow watch y events.subscribe crudo emiten JSON delimitado por
líneas. El primer frame confirma la suscripción.
| Tipo de evento | Significado |
|---|---|
subscribed | Suscripción confirmada |
ai.session_start | La sesión de agente empieza |
ai.prompt_submit | Se envía un prompt |
ai.tool_use | El agente reporta uso de herramienta |
ai.notification | El agente pide input o permiso |
ai.stop | El turno del agente se detiene |
ai.exit | El proceso del agente sale |
ai.session_end | La sesión de agente se cierra |
surface_changed | El output_generation del panel avanzó |
heartbeat | Keepalive idle |
dropped | El subscriber se retrasó y se descartaron eventos |
Después de un frame dropped, resincroniza con paneflow ps --json o
paneflow status <target> --json.
Puente MCP
paneflow-mcp es un servidor MCP stdio read-only sobre el mismo socket
Paneflow.
| Herramienta | Params | Retorno |
|---|---|---|
list_panes | - | Paneles con surface_id, name, title, cwd, cmd, workspace |
read_pane | target, lines?, offset? | Texto de scrollback |
search_pane | target, pattern, max_matches? | Líneas coincidentes |
No tiene herramienta para escribir, enviar, enfocar o dividir paneles. La salida de terminal devuelta está fenced como datos no confiables.
Hooks de ciclo de vida
paneflow-ai-hook lee JSON de evento en stdin, publica un frame
JSON-RPC ai.* y sale con 0 para que una instancia Paneflow detenida
no rompa el agente. La superficie de hooks alimenta estado,
notificaciones, ps, status y watch.
paneflow hooks setup persistente está limitado a Claude Code. Codex
usa hooks de shim por lanzamiento. Los agentes sin superficie de hooks
siguen ejecutándose, pero su estado puede limitarse a detección de
proceso.