Ir al contenido

API de socket

Herdr expone una API de socket local para scripts y agentes que necesiten inspeccionar o controlar una sesión en marcha.

La mayoría de las automatizaciones deberían empezar por los comandos de la CLI. Usa la API de socket en bruto solo cuando necesites control directo de petición y respuesta o suscripciones a eventos de larga duración.

Capa Para qué
Skill de agente Enseñar a un agente de programación a usar Herdr desde dentro de un panel.
Comandos de la CLI Scripts de shell, orquestación sencilla y depuración a mano.
API de socket en bruto Herramientas propias, clientes del protocolo y suscriptores de eventos.

Las tres capas comparten la misma superficie de control.

La CLI instalada puede imprimir el esquema del protocolo de socket incluido en ese binario de Herdr:

Ventana de terminal
herdr api schema
herdr api schema --json
herdr api schema --output herdr-api.schema.json

herdr api schema a secas imprime un resumen breve. --json imprime el documento JSON Schema completo para herramientas, y --output RUTA lo escribe en un fichero. El esquema cubre las peticiones en bruto, las respuestas correctas, las de error, los eventos emitidos y los eventos de suscripción.

La API de socket permite:

  • crear, listar, enfocar, renombrar y cerrar espacios de trabajo
  • crear, listar, enfocar, renombrar y cerrar pestañas
  • listar, inspeccionar, dividir, intercambiar, enfocar, redimensionar, renombrar, leer, cerrar y enviar entrada a paneles
  • listar, inspeccionar, leer, enviar prompts, esperar, renombrar, enfocar, arrancar y conectarse a agentes mediante los comandos de la CLI
  • informar del estado de agentes a medida desde ganchos y plugins
  • suscribirse a eventos y esperar salidas o cambios de estado
  • instalar y desinstalar las integraciones integradas
  • parar el servidor y recargar la configuración

Crear un espacio de trabajo:

Ventana de terminal
herdr workspace create --cwd ~/proyecto --label api

Crear una pestaña:

Ventana de terminal
herdr tab create --label logs

Dividir un panel y ejecutar un comando:

Ventana de terminal
herdr pane split w1:p1 --direction right
herdr pane run w1:p2 "npm test"

Inspeccionar y reorganizar paneles:

Ventana de terminal
herdr pane layout --current
herdr pane neighbor --direction right --current
herdr pane resize --direction right --amount 0.1 --current
herdr pane swap --direction right --current
herdr pane zoom --on --current
herdr pane split w1:p1 --direction right --ratio 0.333

Esperar a un agente:

Ventana de terminal
herdr agent wait w1:p1 --until done

Leer la salida de un panel:

Ventana de terminal
herdr pane read w1:p2 --source recent --lines 50

Los nombres de método usan notación con puntos:

Área Métodos
Servidor ping, server.stop, server.reload_config, server.agent_manifests, server.reload_agent_manifests
Notificación notification.show
Cliente client.window_title.set, client.window_title.clear
Sesión session.snapshot
Espacio de trabajo workspace.create, workspace.list, workspace.get, workspace.focus, workspace.rename, workspace.move, workspace.move_block, workspace.report_metadata, workspace.close
Worktree worktree.list, worktree.create, worktree.open, worktree.remove
Pestaña tab.create, tab.list, tab.get, tab.focus, tab.rename, tab.move, tab.close
Panel pane.split, pane.swap, pane.move, pane.zoom, pane.layout, pane.process_info, pane.neighbor, pane.edges, pane.focus_direction, pane.resize, pane.list, pane.current, pane.get, pane.rename, pane.send_text, pane.send_keys, pane.send_input, pane.read, pane.graphics.info, pane.graphics.set, pane.graphics.clear, pane.graphics.stream, pane.report_agent, pane.report_agent_session, pane.report_metadata, pane.clear_agent_authority, pane.release_agent, pane.close, pane.wait_for_output
Ventana emergente popup.close
Disposición layout.export, layout.apply, layout.set_split_ratio
Agente agent.list, agent.get, agent.read, agent.explain, agent.send_keys, agent.prompt, agent.wait, agent.rename, agent.focus, agent.start, agent.view.set, agent.view.clear
Eventos events.subscribe, events.wait
Integraciones integration.install, integration.uninstall
Plugins plugin.link, plugin.list, plugin.unlink, plugin.enable, plugin.disable, plugin.action.list, plugin.action.invoke, plugin.log.list, plugin.pane.open, plugin.pane.focus, plugin.pane.close

agent.wait lo gestiona el servidor y funciona por eventos. Fija el ocupante resuelto del panel, de modo que un sustituto no puede satisfacer la espera. agent.prompt acepta un objeto wait opcional con until y timeout_ms; así envía el prompt y arranca la espera en una sola petición, evitando una carrera entre dos llamadas separadas. Si el agente resuelto ya está blocked, agent.prompt devuelve agent_blocked sin enviar entrada ni arrancar la espera.

workspace.move_block mueve de forma atómica los workspace_ids ordenados delante de before_workspace_id; omite el ancla para mover el bloque al final. Los ids deben ser únicos y el ancla no puede formar parte del bloque. La respuesta contiene la lista ordenada y autoritativa de espacios de trabajo.

session.snapshot devuelve una instantánea de arranque de un solo uso para clientes que mantienen su propia caché local. La respuesta incluye metadatos de versión y protocolo, los ids del espacio de trabajo, pestaña y panel enfocados, y los registros de espacios de trabajo, pestañas, paneles, instantáneas de disposición de pestañas y agentes. No es una suscripción. Para arrancar o recuperar una caché, suscríbete primero y concilia después mediante lecturas autoritativas, como se describe más abajo en «Suscripciones a eventos». Los eventos invalidan el estado en caché; no se pueden reproducir sin más sobre una instantánea. Vuelve a llamar a session.snapshot tras reconectar o cuando la caché local pueda estar obsoleta. La procedencia de worktree adjunta se incluye en los registros de espacio de trabajo. El descubrimiento completo de worktrees del repositorio sigue siendo worktree.list.

Desde la CLI, herdr api snapshot imprime en JSON la respuesta viva de session.snapshot, para clientes y agentes que quieran un comando de arranque sencillo.

Los métodos de control de paneles usan ids públicos como w1:p1. Los métodos cuyo esquema hace opcional pane_id usan el panel enfocado activo del servidor cuando se omite. pane.move siempre requiere el pane_id de origen.

pane.send_keys y pane.send_input.keys aceptan cadenas de combinación de teclas de Herdr: teclas imprimibles, teclas especiales como enter y esc, combinaciones con modificadores como ctrl+h, control+j, alt+x y shift+tab, teclas de función como f1 y signos con nombre como minus y plus. No aceptan cadenas de atajo con prefix+.

{"id":"req_current","method":"pane.current","params":{"caller_pane_id":"w1:p1"}}
{"id":"req_layout","method":"pane.layout","params":{"pane_id":"w1:p1"}}
{"id":"req_neighbor","method":"pane.neighbor","params":{"pane_id":"w1:p1","direction":"right"}}
{"id":"req_edges","method":"pane.edges","params":{"pane_id":"w1:p1"}}
{"id":"req_focus","method":"pane.focus_direction","params":{"direction":"right"}}
{"id":"req_resize","method":"pane.resize","params":{"pane_id":"w1:p1","direction":"right","amount":0.1}}
{"id":"req_zoom","method":"pane.zoom","params":{"pane_id":"w1:p1","mode":"toggle"}}
{"id":"req_input","method":"pane.input.set","params":{"pane_id":"w1:p1","right_click":"pane"}}
{"id":"req_split","method":"pane.split","params":{"direction":"right","ratio":0.333,"right_click":"pane","env":{"HERDR_ROLE":"tests"}}}
{"id":"req_process","method":"pane.process_info","params":{"pane_id":"w1:p1"}}

pane.current devuelve un único PaneInfo. Con caller_pane_id, Herdr devuelve ese panel. Sin él, devuelve el panel enfocado activo.

pane.input.set fija right_click a herdr o pane para un panel. herdr es el valor por defecto. pane reenvía los gestos de mantener y arrastrar con clic derecho sin modificador cuando la aplicación solicita informes de ratón de la terminal; si no, Herdr recurre a su menú de panel. El clic derecho en el marco del panel siempre abre el menú de Herdr. pane.split acepta el mismo valor opcional right_click para el panel recién creado.

PaneInfo incluye scroll cuando hay métricas de desplazamiento de la terminal:

{
"offset_from_bottom": 12,
"max_offset_from_bottom": 240,
"viewport_rows": 30
}

Los clientes pueden tratar offset_from_bottom == 0 como «al final».

Los gráficos de panel permiten a un plugin colocar datos de imagen sobre un panel. Están disponibles por defecto; cuando el servidor tiene [terminal].kitty_graphics = false, todos los métodos de gráficos devuelven feature_disabled. Cambiar ese ajuste requiere reiniciar el servidor. Llamar a pane.graphics.info activa expresamente el descubrimiento de capacidades y devuelve el tamaño de celda del cliente conectado, las opciones de fotogramas por fichero, el soporte de ratón por píxel, el límite de 16 capas y pane_visible. pane_visible es true solo cuando el destino está en el espacio de trabajo y la pestaña activos y no lo oculta una ampliación. Los modos de interfaz breves no lo cambian.

pane.graphics.set, pane.graphics.clear y pane.graphics.stream aceptan un layer_id opcional (primary por defecto). Set y stream aceptan también z_index; las capas se colocan en orden estable (z_index, layer_id). Cada flujo es dueño exclusivo de su capa, y cerrarlo elimina esa capa. Los fotogramas en línea aceptan png, rgb, rgba o bgra; BGRA se normaliza una vez a RGBA propio. Herdr avanza la caché del host una transacción de imagen por pasada de pintado, así que conjuntos arbitrarios de capas progresan sin un fotograma agregado. El transporte del cliente mantiene cada transacción dentro de su límite de 32 MiB en el cable.

{"id":"graphics_info","method":"pane.graphics.info","params":{"pane_id":"w1:p1"}}
{"id":"graphics_set","method":"pane.graphics.set","params":{"pane_id":"w1:p1","format":"png","image_width":800,"image_height":600,"data_base64":"...","placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}}
{"id":"graphics_clear","method":"pane.graphics.clear","params":{"pane_id":"w1:p1"}}

Para fotogramas repetidos, abre un socket dedicado con pane.graphics.stream. Cuando Herdr responda ok, envía una cabecera JSON y después exactamente data_length bytes en bruto por cada fotograma en línea. Las operaciones concurrentes sobre esa capa devuelven stream_conflict.

{"id":"graphics_stream","method":"pane.graphics.stream","params":{"pane_id":"w1:p1","z_index":0}}
{"format":"png","image_width":800,"image_height":600,"data_length":12345,"placement":{"viewport_col":0,"viewport_row":0,"grid_cols":80,"grid_rows":30}}

Cuando pane.graphics.info anuncia file_frame_transport: "direct-kitty", un cliente local de Ghostty, kitty o WezTerm que cumpla los requisitos puede enviar un fichero rgba o bgra privado e inmutable con file.path, sequence y revision. El transporte directo de ficheros de Kitty se reserva para la capa de página primary por defecto; las capas secundarias con nombre usan RGBA en línea propio. BGRA siempre se copia, se reordena y se pinta en línea. Herdr responde con un pane_graphics_frame_ack solo después de que la terminal acepte el fichero, o de instalar un respaldo en línea seguro. Un fallo confirmado del transporte por fichero desactiva los ficheros directos para esa conexión de cliente sin desactivar el ratón por píxel exacto. Un tiempo límite o la pérdida del cliente cierran el flujo sin confirmar la reutilización de la fuente. Los clientes que no pueden negociar transporte directo por fichero se quedan en el respaldo en línea propio.

Los ficheros directos son siempre fotogramas RGBA canónicos completos de ancho * alto * 4. file_frame_max_bytes es el límite que sigue admitiendo el respaldo en línea propio. Los ficheros RGBA de la capa principal pueden usar el límite mayor file_frame_direct_max_bytes cuando file_frame_transport está disponible. Los fotogramas por encima del límite de respaldo solo se confirman cuando la terminal acepta la transferencia directa; el rechazo cierra el flujo. Si un fotograma no puede usar el respaldo en línea propio mientras su panel está temporalmente oculto, o no se puede colocar durante un repintado, Herdr sube la imagen sin mostrarla y reproduce su colocación cuando el panel vuelve a ser visible. file_frame_damage: true significa que Herdr acepta metadatos opcionales de zonas dañadas para eficiencia del anillo canónico del productor; aun así copia o presenta el fichero completo. El redimensionado y el repintado completo reproducen las colocaciones sin retransmitir píxeles.

pane.layout devuelve la instantánea de disposición de la pestaña con workspace_id, tab_id, zoomed, el area exterior, focused_pane_id, los rectángulos de los paneles y los rectángulos y proporciones de las divisiones. pane.neighbor y pane.edges incluyen esa misma instantánea para que los clientes tomen la siguiente decisión sin estado de disposición privado.

pane.process_info devuelve el pid del shell del panel, el id del grupo de procesos en primer plano cuando está disponible, y los procesos en primer plano con pid, nombre, argv/línea de comandos y directorio cuando la plataforma los expone.

layout.export devuelve un árbol de disposición de pestaña portable. Omite tab_id y pane_id para exportar la pestaña activa, pasa tab_id para exportar esa pestaña, o pasa pane_id para exportar la pestaña que contiene ese panel.

{"id":"req_export","method":"layout.export","params":{"tab_id":"w1:t1"}}

La respuesta incluye workspace_id, tab_id, zoomed, focused_pane_id y root. root es un árbol BSP de nodos pane y split. Los nodos de panel pueden incluir pane_id, label, cwd y un command argv. Los nodos de división usan direction (right o down), ratio, first y second.

layout.apply crea una pestaña nueva a partir de un árbol declarativo. Si se indica tab_id, Herdr crea primero la pestaña de reemplazo y después cierra la antigua. Restaura la estructura, las etiquetas, los directorios, el entorno y los comandos argv opcionales; no conserva PTY vivos, historial ni procesos en marcha.

{
"id": "req_apply",
"method": "layout.apply",
"params": {
"workspace_id": "wabc",
"tab_label": "dev",
"focus": true,
"root": {
"type": "split",
"direction": "right",
"ratio": 0.65,
"first": {
"type": "pane",
"label": "editor",
"cwd": "/repo"
},
"second": {
"type": "pane",
"label": "tests",
"cwd": "/repo",
"command": ["sh", "-c", "just test"],
"env": { "HERDR_ROLE": "tests" }
}
}
}
}

layout.set_split_ratio actualiza una división existente en la disposición de una pestaña. La respuesta es type: "layout_split_ratio_set" con el layout portable actualizado.

{"id":"req_ratio","method":"layout.set_split_ratio","params":{"tab_id":"w1:t1","path":[],"ratio":0.6}}

Los métodos que lanzan procesos aceptan un objeto env. Herdr aplica esos pares clave/valor solo al proceso recién lanzado. Herdr también inyecta HERDR_SOCKET_PATH, HERDR_ENV=1, HERDR_WORKSPACE_ID, HERDR_TAB_ID y HERDR_PANE_ID en los procesos de panel gestionados. Las variables gestionadas por Herdr prevalecen cuando entran en conflicto con las que aporta quien llama.

pane.swap admite la forma direccional y la explícita:

{"id":"req_swap_dir","method":"pane.swap","params":{"pane_id":"w1:p1","direction":"right"}}
{"id":"req_swap_explicit","method":"pane.swap","params":{"source_pane_id":"w1:p1","target_pane_id":"w1:p2"}}

El intercambio es solo dentro de la misma pestaña. Conserva la forma de las divisiones, sus proporciones, los ids de los paneles y los procesos en marcha. La respuesta es type: "pane_swap" con changed, reason opcional, source_pane_id, target_pane_id opcional, focused_pane_id y layout. Los valores de reason son no_neighbor, same_pane, not_found y cross_tab. Cuando una pestaña está ampliada, el intercambio mantiene la ampliación y modifica la disposición completa oculta.

pane.move mueve un panel en marcha a otra pestaña, a una pestaña nueva o a un espacio de trabajo nuevo:

{"id":"req_move_tab","method":"pane.move","params":{"pane_id":"w1:p2","destination":{"type":"tab","tab_id":"w1:t2","target_pane_id":"w1:p3","split":"right","ratio":0.5},"focus":true}}
{"id":"req_move_new_tab","method":"pane.move","params":{"pane_id":"w1:p2","destination":{"type":"new_tab","workspace_id":"w1","label":"logs"},"focus":true}}
{"id":"req_move_new_workspace","method":"pane.move","params":{"pane_id":"w1:p2","destination":{"type":"new_workspace","label":"logs","tab_label":"main"},"focus":true}}

Los movimientos a una pestaña existente requieren split: "right" | "down". target_pane_id es opcional y por defecto es el panel enfocado de la pestaña de destino. Los cambios dentro de la misma pestaña siguen siendo pane.swap; mover a la pestaña de origen devuelve changed: false con reason: "same_tab". Los movimientos que implican una pestaña ampliada de origen o destino devuelven changed: false con reason: "zoomed_tab".

La respuesta es type: "pane_move" con changed, reason opcional, previous_pane_id, previous_workspace_id, previous_tab_id, el pane movido, source_layout opcional, target_layout, los registros opcionales del espacio de trabajo o pestaña creados, los ids opcionales del espacio de trabajo o pestaña cerrados, y focused_pane_id. Los movimientos entre espacios de trabajo mantienen vivos el panel interno y la terminal, pero asignan un nuevo id público en el espacio de trabajo de destino. Los suscriptores pueden escuchar pane.moved; Herdr no emite eventos falsos de cierre o creación de panel para el proceso movido.

pane.zoom alterna, activa o desactiva la ampliación en la pestaña del panel de destino:

{"id":"req_zoom_toggle","method":"pane.zoom","params":{"pane_id":"w1:p1"}}
{"id":"req_zoom_on","method":"pane.zoom","params":{"pane_id":"w1:p1","mode":"on"}}
{"id":"req_zoom_off","method":"pane.zoom","params":{"pane_id":"w1:p1","mode":"off"}}

Omitir pane_id apunta al panel enfocado activo del servidor. La respuesta es type: "pane_zoom" con changed, zoom_changed, focus_changed, reason opcional, pane_id, focused_pane_id, zoomed y layout. changed es true cuando ha cambiado la ampliación o el foco. Los valores de reason son single_pane, already_zoomed y already_unzoomed.

El comando de la CLI para notification.show es:

Ventana de terminal
herdr notification show "build failed" --body "api workspace" --position top-left --sound request

Mostrar una notificación al usuario a través de la entrega de avisos configurada:

{"id":"req_notify","method":"notification.show","params":{"title":"build failed","body":"api workspace","position":"top-left","sound":"request"}}

title es obligatorio y debe contener texto visible después de quitar los caracteres de control y los espacios repetidos. body es opcional. Herdr convierte saltos de línea, tabuladores, retornos de carro y espacios repetidos en espacios, y después recorta el texto a 80 caracteres en title y 240 en body. Un title que quede vacío al sanearlo devuelve invalid_params. position es opcional y solo se aplica cuando ui.toast.delivery = "herdr"; las posiciones de escritorio son relativas al marco completo de Herdr, y si se omite se usa ui.toast.herdr.position. Las entregas terminal, system y off ignoran position. sound es opcional y puede ser none, done o request; por defecto es none y solo suena cuando la notificación se muestra.

La respuesta indica si se mostró algo:

{"id":"req_notify","result":{"type":"notification_show","shown":true,"reason":"shown"}}

Los motivos posibles son shown, disabled, rate_limited, no_foreground_client y busy. disabled significa ui.toast.delivery = "off". busy significa que no se sustituyó un aviso ya presente en la aplicación. Las entregas terminal y system son de mejor esfuerzo a través del cliente de Herdr conectado en primer plano.

Fijar o borrar el título de la ventana de la terminal exterior del cliente en primer plano:

{"id":"req_title","method":"client.window_title.set","params":{"title":"herdr api"}}
{"id":"req_title_clear","method":"client.window_title.clear","params":{}}

client.window_title.clear devuelve el título a ui.window_title. La respuesta es type: "client_window_title" con changed y un reason de set, cleared o no_foreground_client.

Los métodos de worktree gestionan copias de Git como espacios de trabajo de Herdr. worktree.create crea una copia y devuelve los registros nuevos workspace, tab, root_pane y worktree. Si la rama pedida ya existe en local, la usa; si no, la crea a partir de la base pedida o de HEAD. worktree.open abre una copia existente o devuelve el espacio de trabajo ya abierto. worktree.remove ejecuta git worktree remove sobre un espacio de trabajo hijo enlazado y nunca borra la rama.

Crear un worktree desde un espacio de trabajo de origen:

{"id":"req_1","method":"worktree.create","params":{"workspace_id":"w1","branch":"worktree/api","focus":false}}

Abrir una copia existente:

{"id":"req_2","method":"worktree.open","params":{"workspace_id":"w1","branch":"worktree/api","focus":true}}

Eliminar una copia enlazada:

{"id":"req_3","method":"worktree.remove","params":{"workspace_id":"2","force":false}}

Usa como mucho uno de workspace_id o cwd en worktree.list, worktree.create y worktree.open; omite ambos para usar el espacio de trabajo activo. Usa exactamente uno de path o branch en worktree.open. Los valores cwd y path en bruto deben ser absolutos; la CLI expande los --cwd y --path relativos antes de enviar las peticiones. Las respuestas de espacio de trabajo incluyen una procedencia worktree opcional cuando el espacio pertenece a un grupo de worktree. Los comandos de worktree pueden emitir workspace.updated cuando un espacio de trabajo existente adquiere o cambia su procedencia.

Los comandos de worktree también emiten eventos de ciclo de vida. worktree.create emite workspace.created, tab.created, pane.created y worktree.created. worktree.open emite worktree.opened, y también los eventos de creación de espacio de trabajo, pestaña y panel cuando abre un espacio de trabajo nuevo. worktree.remove emite worktree.removed; si el espacio de trabajo enlazado sigue abierto, emite también workspace.closed.

workspace.close rechaza cerrar un espacio de trabajo principal mientras haya espacios de worktree enlazados abiertos, salvo que sus parámetros incluyan "close_group": true; devuelve workspace_group_close_required cuando falta esa intención explícita. Un cierre de grupo explícito emite un workspace.closed por cada espacio de trabajo que cierra.

agent.view.set instala una proyección declarativa transitoria para la vista integrada de agentes. La proyección se reevalúa cada vez que cambian los datos de los agentes o el contexto de la interfaz. Controla la barra lateral desplegada y plegada, la lista de agentes móvil, los destinos del ratón, el foco indexado y la navegación al agente siguiente o anterior. No cambia agent.list, las notificaciones, la detección ni los contadores globales de atención.

Mostrar los agentes del espacio actual o los que necesitan atención en otros, ordenados por atención y por la transición de estado más reciente:

{
"id": "view_set",
"method": "agent.view.set",
"params": {
"source": "plugin:example.agent-views",
"label": "focus",
"filter": {
"op": "any",
"filters": [
{
"op": "eq",
"field": "workspace_id",
"value": {"context": "current_workspace_id"}
},
{
"op": "in",
"field": "status",
"values": ["blocked", "done"]
}
]
},
"sort": [
{"field": "attention", "order": "desc"},
{"field": "state_change_seq", "order": "desc"}
]
}
}

Los nodos de filtro usan los valores de op all, any, not, eq, in o exists. Los campos de filtro integrados son status, workspace_id, tab_id, pane_id, agent, seen y state_change_seq. Usa {"token":"nombre"} como campo para filtrar por los metadatos de panel informados por plugins. Los valores son cadenas, booleanos, números sin signo o un objeto de contexto. Los valores de contexto son current_workspace_id y current_tab_id, y solo pueden compararse con el campo de ID correspondiente. En un cliente con máquinas guardadas, la vista del servidor seleccionado se aplica a la lista combinada de agentes. El contexto de espacio de trabajo y pestaña actuales incluye esa máquina seleccionada, así que un ID idéntico en otra máquina no coincide; las ramas de filtro independientes, como que status sea blocked, siguen coincidiendo con agentes de cualquier máquina conectada. Los valores efectivos de estado son idle, working, blocked, done y unknown; done significa en espera y aún no visto.

Los campos de orden son workspace_order, tab_order, pane_order, attention, status, agent, seen, state_change_seq o {"token":"nombre"}. Los órdenes son estables, se evalúan en orden y aceptan asc o desc. Los valores ausentes quedan detrás de los presentes. Si se omite sort, sigue activa la política ui.agent_panel_sort. Un orden personalizado sustituye temporalmente esa política sin reescribir la configuración.

source identifica al dueño. Los plugins usan plugin:<HERDR_PLUGIN_ID>; Herdr rechaza las vistas de un plugin cuando ese plugin falta o está desactivado. Otros llamantes pueden usar su propia fuente sin plugin:. Un set correcto sustituye la vista anterior de forma atómica. La vista dura hasta que se borra, se sustituye, su plugin dueño se desactiva, desenlaza o desinstala, o el servidor termina. Los plugins que quieran un comportamiento duradero deberían guardar la consulta bajo HERDR_PLUGIN_STATE_DIR y volver a aplicarla desde un gancho [[startup]].

Borrar sin condiciones, o solo cuando la fuente indicada sigue siendo dueña de la vista:

{"id":"view_clear","method":"agent.view.clear","params":{}}
{"id":"view_clear_owned","method":"agent.view.clear","params":{"source":"plugin:example.agent-views"}}

Si la fuente no coincide, la vista activa no cambia. Las respuestas de set y clear usan type: "agent_view" e informan de active, source y label opcional.

La API de plugins es una interfaz temprana para herramientas ejecutables de flujo de trabajo. Un plugin es un paquete con un manifiesto herdr-plugin.toml. El manifiesto declara ganchos de arranque, acciones compartibles, ganchos de eventos, puntos de entrada de paneles de terminal y manejadores de enlaces. Los ganchos de arranque se ejecutan una vez tras la restauración, cuando la API está lista. Las acciones y los paneles son solo de manifiesto; el registro de acciones en tiempo de ejecución y la creación de paneles argv en tiempo de ejecución no forman parte de la v1.

Los plugins instalados y enlazados persisten entre reinicios. Herdr escribe un registro plugins.json junto a session.json en plugin.link, plugin.unlink, plugin.enable y plugin.disable. Los comandos herdr plugin install y herdr plugin link escriben ese mismo registro cuando Herdr no está en marcha, y el arranque lo carga automáticamente. Al arrancar, Herdr vuelve a leer cada manifiesto desde su ruta original; si el fichero falta o no se puede leer, la entrada se conserva con un campo warnings para que plugin.list lo muestre.

Herdr valida los valores on de los ganchos de eventos contra los nombres de evento conocidos al enlazar. Un nombre no reconocido no impide el enlace, pero la información del plugin devuelta incluye un aviso (p. ej. "unknown event 'worktree.craeted'"). Consulta el campo warnings en las respuestas de plugin.link y plugin.list.

Enlazar un manifiesto de plugin local:

{"id":"req_plugin_link","method":"plugin.link","params":{"path":"/ruta/al/plugin","enabled":true}}

plugin.link también acepta metadatos source opcionales. La CLI los usa cuando instala desde GitHub, para que plugin.list pueda mostrar el origen, la referencia pedida, el commit resuelto y la ruta de la copia gestionada:

{"id":"req_plugin_link","method":"plugin.link","params":{"path":"/managed/plugin/herdr-plugin.toml","enabled":true,"source":{"kind":"github","owner":"ogulcancelik","repo":"herdr-plugin-examples","subdir":"worktree-bootstrap","requested_ref":"main","resolved_commit":"abc123","managed_path":"/data/plugins/github/<managed-checkout>","installed_unix_ms":1780000000000}}}

La ruta puede ser un directorio de plugin que contenga herdr-plugin.toml o la ruta directa del manifiesto. La forma del manifiesto es:

id = "example.worktree-bootstrap"
name = "Worktree Bootstrap"
version = "0.1.0"
min_herdr_version = "0.7.0"
description = "Prepare new worktrees"
platforms = ["linux", "macos", "windows"]
[[build]]
command = ["bun", "install"]
[[actions]]
id = "bootstrap"
title = "Bootstrap worktree"
contexts = ["workspace"]
command = ["bun", "run", "bootstrap.ts"]
[[events]]
on = "worktree.created"
command = ["bun", "run", "bootstrap.ts"]
[[panes]]
id = "board"
title = "Worktree board"
placement = "overlay"
command = ["bun", "run", "board.ts"]
[[link_handlers]]
id = "github-issue"
title = "Open GitHub issue"
pattern = "^https://github\\.com/[^/]+/[^/]+/(issues|pull)/[0-9]+$"
action = "bootstrap"

min_herdr_version es obligatorio. El servidor se niega a enlazar un plugin cuando el campo falta, no es válido o es más nuevo que el binario de Herdr en ejecución.

Declara platforms a nivel superior con los identificadores de sistema (linux, macos, windows) que admite tu plugin. Omitir platforms está permitido para desarrollo local: plugin.link funciona, pero la respuesta incluye un aviso. Los comandos de construcción, las acciones, los ganchos de eventos, los paneles y los manejadores de enlaces pueden declarar sus propias platforms para sustituir la lista del plugin; si se omiten, la heredan. Invocar una acción o abrir un panel cuyas plataformas efectivas no incluyan el sistema actual devuelve un error platform_unsupported.

Listar, activar, desactivar o desenlazar plugins:

{"id":"req_plugin_list","method":"plugin.list","params":{}}
{"id":"req_plugin_disable","method":"plugin.disable","params":{"plugin_id":"example.worktree-bootstrap"}}
{"id":"req_plugin_enable","method":"plugin.enable","params":{"plugin_id":"example.worktree-bootstrap"}}
{"id":"req_plugin_unlink","method":"plugin.unlink","params":{"plugin_id":"example.worktree-bootstrap"}}

Las acciones se resuelven a partir del manifiesto enlazado. plugin.action.list devuelve todas las acciones de todos los plugins instalados; pasa plugin_id para filtrar.

{"id":"req_plugin_actions","method":"plugin.action.list","params":{}}
{"id":"req_plugin_actions_filtered","method":"plugin.action.list","params":{"plugin_id":"example.worktree-bootstrap"}}

plugin.action.list devuelve las platforms efectivas de cada acción tras aplicar la herencia del plugin.

Invocar una acción por su id cualificado o por su id a secas:

{"id":"req_plugin_invoke","method":"plugin.action.invoke","params":{"action_id":"example.worktree-bootstrap.bootstrap","context":{"invocation_source":"keybinding"}}}

plugin.action.invoke resuelve la acción del manifiesto, arranca su comando y devuelve el contexto de invocación construido por Herdr más el registro del comando arrancado. Los campos de contexto que falten se rellenan con el espacio de trabajo activo, la pestaña, el panel enfocado, la procedencia de worktree y el id de la petición. Invocar una acción de un plugin desactivado devuelve un error plugin_disabled.

Herdr inyecta HERDR_SOCKET_PATH, HERDR_BIN_PATH, HERDR_ENV=1, HERDR_PLUGIN_ID, HERDR_PLUGIN_ROOT, HERDR_PLUGIN_CONFIG_DIR, HERDR_PLUGIN_STATE_DIR, HERDR_PLUGIN_CONTEXT_JSON y los valores disponibles de HERDR_WORKSPACE_ID, HERDR_TAB_ID y HERDR_PANE_ID. Los comandos de acción reciben además HERDR_PLUGIN_ACTION_ID; los ganchos de eventos reciben HERDR_PLUGIN_EVENT y HERDR_PLUGIN_EVENT_JSON; los comandos de panel reciben HERDR_PLUGIN_ENTRYPOINT_ID.

Listar los registros recientes de comandos de acción y de evento:

{"id":"req_plugin_logs","method":"plugin.log.list","params":{"plugin_id":"example.worktree-bootstrap","limit":20}}

Los ganchos de eventos se ejecutan para los plugins instalados y activados cuando Herdr emite un evento con ese nombre, como worktree.created.

En la v1 no hay una API de almacenamiento de plugins gestionada por Herdr. HERDR_PLUGIN_CONFIG_DIR y HERDR_PLUGIN_STATE_DIR solo sirven para descubrir rutas; los plugins son dueños de sus ficheros, esquemas, migraciones y limpieza.

Abrir una interfaz de terminal gestionada:

{"id":"req_plugin_pane","method":"plugin.pane.open","params":{"plugin_id":"example.board","entrypoint":"board","placement":"zoomed","target_pane_id":"w1:p1","env":{"HERDR_ROLE":"board"},"focus":true}}

plugin.pane.open requiere un plugin instalado, activado y compatible con la plataforma, y lanza el punto de entrada [[panes]] del manifiesto como panel de terminal argv. El placement del manifiesto es overlay por defecto; el placement de la petición lo sustituye por overlay, popup, split, tab o zoomed. Las colocaciones de superposición y ventana emergente usan el panel en mosaico activo como contexto de lanzamiento. Las terminales emergentes son modales de sesión y no cambian la disposición de la pestaña; los campos opcionales width y height fijan su tamaño exterior en celdas de terminal o porcentajes como "80%". Las dimensiones omitidas son la mitad del tamaño de la terminal, y los valores demasiado pequeños se ajustan al mínimo. Una ventana emergente no tiene ID de panel, queda fuera de todas las API pane.* y de agentes, no emite eventos de ciclo de vida de panel, deja el contexto de foco del plugin en el panel en mosaico subyacente y no exporta HERDR_PANE_ID a su proceso. Lanzarla devuelve ok; popup.close cierra la ventana activa y devuelve popup_not_open cuando no hay ninguna. Los paneles de división y ampliados apuntan a un panel existente; los de pestaña pueden apuntar a un espacio de trabajo. Los paneles de división, pestaña, ampliado y superposición se comportan como paneles normales de Herdr, y plugin.pane.focus y plugin.pane.close siguen funcionando sobre ellos.

Herdr usa JSON delimitado por saltos de línea sobre un socket local. En Unix es un socket de dominio Unix. En Windows, una tubería con nombre.

Envía una petición por línea:

{"id":"req_1","method":"ping","params":{}}

Una respuesta correcta incluye el mismo id:

{"id":"req_1","result":{"type":"pong"}}

En las líneas de petición que llegan a decodificarse como JSON, las respuestas de error también devuelven el id de la petición, incluso cuando el método o los parámetros no son válidos. Si el JSON no es válido o no tiene un id de cadena de nivel superior inequívoco, la respuesta de error usa un id vacío. Los errores de transporte, como UTF-8 no válido, pueden cerrar la conexión sin respuesta.

Las suscripciones a eventos mantienen la conexión abierta después de la respuesta inicial.

El socket por defecto vive bajo tu directorio de configuración de Herdr.

Las sesiones con nombre tienen sockets separados:

~/.config/herdr/herdr.sock
~/.config/herdr/sessions/<nombre>/herdr.sock

Orden de resolución:

  1. --session <nombre> explícito en la CLI
  2. HERDR_SOCKET_PATH
  3. HERDR_SESSION=<nombre>
  4. socket de la sesión por defecto

Usa HERDR_SOCKET_PATH solo para cambios de bajo nivel.

En los plugins, prefiere invocar HERDR_BIN_PATH y los comandos de la CLI cuando necesites un comportamiento portable en Windows. Los clientes de socket en bruto son responsables de usar la forma de socket local nativa de cada plataforma.

Las integraciones informan del estado de un agente con pane.report_agent.

{
"id": "req_1",
"method": "pane.report_agent",
"params": {
"pane_id": "w1:p1",
"source": "custom:docs",
"agent": "docs-bot",
"state": "working",
"message": "building docs"
}
}

state lleva el estado semántico del agente y afecta a las esperas, las notificaciones y el estado agregado. Informa de los valores solo visuales aparte, mediante metadatos.

Las integraciones oficiales que solo aportan sesión informan de las referencias de sesión nativas con pane.report_agent_session. Las integraciones que informan de estado también pueden incluir referencias de sesión nativas en pane.report_agent. Los informes de sesión independientes del estado no afectan a las esperas, las notificaciones ni el estado agregado.

{
"id": "req_2",
"method": "pane.report_agent_session",
"params": {
"pane_id": "w1:p1",
"source": "herdr:codex",
"agent": "codex",
"agent_session_id": "..."
}
}

pane.get, pane.list, agent.get y agent.list exponen un objeto de solo lectura agent_session cuando Herdr tiene guardada una referencia de sesión nativa:

{
"agent_session": {
"source": "herdr:codex",
"agent": "codex",
"kind": "id",
"value": "..."
}
}

Si no hay ninguna guardada, el campo se omite.

pane.get, pane.list, agent.get y agent.list exponen también foreground_cwd cuando Herdr puede resolver el directorio del proceso que controla el PTY del panel. El campo cwd sigue siendo el directorio del panel o espacio de trabajo usado en las etiquetas, en el seguimiento del directorio y en el estado de sesión restaurado.

PaneInfo y AgentInfo exponen los campos opcionales terminal_title y terminal_title_stripped. terminal_title es el último título OSC 0/2 tras la normalización de seguridad. terminal_title_stripped elimina un glifo inicial reconocido de actividad o spinner y el espacio que le sigue. Estos valores, gestionados por el servidor, son efímeros en un reinicio en frío y son independientes del title de metadatos y del estado semántico del agente.

Usa pane.report_metadata cuando un gancho de usuario quiera personalizar la presentación sin apropiarse del estado de ciclo de vida de una integración de Herdr.

{
"id": "req_2",
"method": "pane.report_metadata",
"params": {
"pane_id": "w1:p1",
"source": "user:claude-title",
"agent": "claude",
"title": "Refactor auth middleware",
"display_agent": "Claude: auth",
"state_labels": {
"working": "refactoring auth",
"idle": "ready",
"done": "review ready"
},
"tokens": {
"summary": "refactor auth",
"model": "opus"
},
"ttl_ms": 3600000
}
}

Los informes de metadatos son solo visuales. Unos metadatos válidos pueden sustituir el título del panel, el nombre de agente mostrado, las etiquetas de estado visibles y tokens con nombre arbitrarios. working, blocked, idle, las esperas, las notificaciones y el estado agregado siguen viniendo del estado semántico. La restauración nativa de la sesión viene de las referencias oficiales guardadas. agent es una protección opcional de los campos de presentación frente a la etiqueta autoritativa del agente; applies_to_source protege igualmente los campos de presentación frente a la fuente de autoridad de ciclo de vida activa. Estas protecciones no se aplican a los parches de tokens: quien informa de los tokens se encarga de borrarlos y refrescar su TTL. Usa display_agent para cambiar el nombre visible. Las claves de state_labels deben ser idle, working, blocked, done o unknown.

Los mapas de tokens son parches por recurso. Una cadena fija una clave, un null JSON la borra, y las claves omitidas no cambian. Gana la última actualización aceptada. El TTL opcional se aplica de forma independiente a las claves actualizadas en ese informe. Los tokens de panel se exponen en las respuestas de get y list de paneles y agentes, y pueden pintarse como $name en las filas de agente de la barra lateral. Un informe puede mencionar como mucho 16 claves de token, y un panel o espacio de trabajo puede conservar como mucho 32. Los nombres de token tienen de 1 a 32 letras ASCII, dígitos, guiones bajos o guiones.

Los tokens de espacio de trabajo usan el mismo contrato:

{"id":"req_3","method":"workspace.report_metadata","params":{"workspace_id":"w1","source":"user:jj","tokens":{"jj_status":"2 changes","old":null},"ttl_ms":5000}}

Las respuestas de get y list de espacio de trabajo exponen el mapa tokens resultante, y las filas de espacio de la barra lateral pueden pintar valores como $jj_status. Los cambios y las caducidades por TTL emiten workspace.metadata_updated con la última instantánea del espacio de trabajo. Este evento está disponible para los suscriptores de la API pero no invoca ganchos de eventos de plugins.

El texto de presentación se normaliza antes de guardarse. Herdr recorta los espacios de los extremos, elimina los caracteres de control y limita title, display_agent, cada etiqueta de estado y los valores de token a 80 caracteres. Un valor de token que quede vacío al normalizarlo borra esa clave.

source y applies_to_source son identificadores de fuente. Deben tener 80 caracteres o menos y solo pueden contener letras ASCII, dígitos, dos puntos, punto, guion bajo y guion.

Usa ttl_ms para metadatos de corta duración. Debe estar entre 1 y 86400000 milisegundos. Omítelo para metadatos que deban quedarse hasta que se sustituyan, se borren o se cierre el panel o el espacio de trabajo. Los campos de presentación conservan su caducidad por fuente; cada token actualizado en la llamada recibe su propio plazo. Los metadatos de token no se restauran tras reiniciar el servidor.

Usa seq cuando un gancho pueda enviar actualizaciones desordenadas. Para la misma source, los informes con un número de secuencia menor o igual que el último aceptado los acepta la API pero los ignora el estado del panel. Un panel o espacio de trabajo acepta informes de tokens con secuencia de como mucho 32 fuentes distintas durante su vida; borrar o caducar no libera esos huecos.

Suscríbete a eventos cuando necesites un flujo de larga duración:

{
"id": "sub_1",
"method": "events.subscribe",
"params": {
"subscriptions": [
{ "type": "pane.agent_status_changed", "pane_id": "w1:p1", "agent_status": "blocked" }
]
}
}

La primera respuesta confirma la suscripción. Las líneas siguientes son eventos enviados por el servidor. Todas las entradas deben ser válidas: si algún panel referenciado no existe, Herdr rechaza la petición completa con un error y cierra la conexión. Refresca la lista de paneles y reintenta, en vez de suponer que las demás entradas quedaron suscritas. Las suscripciones de ciclo de vida empiezan cuando se acepta la petición y no reproducen los eventos retenidos antes de ese momento.

Los eventos de ciclo de vida y de estado de agente se entregan en lotes acotados, en orden dentro de cada suscripción. El historial de eventos no es duradero. Si un suscriptor se queda atrás respecto al historial retenido, incluso mientras sus suscripciones se inicializan, el servidor envía una respuesta de error con el id de la petición original y error.code: "events_lost", y cierra esa conexión de suscripción en vez de seguir en silencio con eventos perdidos. Los demás clientes siguen conectados. El historial es compartido entre tipos de evento, así que un desbordamiento se informa aunque los eventos descartados no hubieran coincidido con los filtros de esa suscripción.

Ante events_lost, trata el estado en caché como obsoleto. Abre una suscripción nueva, espera a subscription_started y sigue leyendo mientras pides session.snapshot por otra conexión. Usa lecturas autoritativas para conciliar el estado actual: sustituye la caché por la instantánea y trata los eventos entrantes como señales de invalidación que disparan otra lectura. Serializa los refrescos y vuelve a refrescar si llegan eventos mientras hay una lectura en curso.

Las instantáneas y los eventos no comparten un límite de secuencia. El orden se garantiza dentro de cada entrada de suscripción, no entre entradas ni respecto a una instantánea, así que no reproduzcas sin más los eventos almacenados sobre la instantánea. La recuperación restaura el estado actual, no el historial de eventos perdido. Otro events_lost obliga a suscribirse y conciliar de nuevo. Los lectores lentos pueden necesitar aumentar su capacidad de lectura o reducir la carga de eventos.

Las suscripciones a eventos de espacio de trabajo incluyen workspace.created, workspace.updated, workspace.metadata_updated, workspace.renamed, workspace.moved, workspace.reordered, workspace.closed y workspace.focused. workspace.metadata_updated informa de cambios de tokens y de caducidades por TTL sin invocar ganchos de eventos de plugins. Los demás eventos de espacio de trabajo describen el ciclo de vida de la interfaz y el runtime de Herdr. workspace.created incluye una procedencia opcional workspace.worktree cuando el espacio pertenece a un grupo de worktree. workspace.moved incluye el workspace_id movido, el insert_index pedido y la lista ordenada workspaces actualizada. workspace.reordered incluye los workspace_ids movidos de forma atómica, el before_workspace_id opcional y la lista ordenada workspaces autoritativa. workspace.closed incluye una instantánea final workspace cuando Herdr todavía puede identificarlo antes de eliminarlo. Las suscripciones a eventos de pestaña incluyen tab.created, tab.closed, tab.focused, tab.renamed y tab.moved. tab.moved incluye el tab_id movido, workspace_id, el insert_index pedido y la lista ordenada tabs actualizada de ese espacio de trabajo. Las suscripciones a eventos de panel incluyen pane.created, pane.updated, pane.closed, pane.focused, pane.moved, pane.exited, pane.agent_detected, pane.output_matched, pane.agent_status_changed y pane.scroll_changed. pane.focused informa también de los cambios manuales de selección de panel desde cualquier cliente conectado a este servidor. No mueve las vistas de los demás clientes, y su carga no identifica al cliente. Seleccionar un panel ya seleccionado no lo emite de nuevo. Los cambios de título de la terminal pueden emitir pane.updated, pero los cambios del título en bruto debidos solo al spinner no lo emiten cuando terminal_title_stripped no cambia. pane.scroll_changed se limita a un pane_id y emite pane_id, workspace_id y las métricas scroll actuales cada vez que Herdr observa una instantánea de desplazamiento distinta. Las suscripciones a eventos de disposición incluyen layout.updated. El evento lleva el PaneLayoutSnapshot actualizado de una pestaña. Los clientes que mantienen una caché con session.snapshot deberían usar este evento para refrescar la disposición afectada con una lectura autoritativa; una carga retrasada puede ser anterior a su última instantánea.

Las suscripciones a eventos de worktree incluyen worktree.created, worktree.opened y worktree.removed. Describen el ciclo de vida de las copias de Git. worktree.created incluye el workspace abierto y el worktree creado. worktree.opened incluye el workspace de destino, el worktree abierto y already_open. worktree.removed incluye el workspace_id, el worktree eliminado y forced.

Usa events.subscribe para los eventos de ciclo de vida. Los ayudantes de espera dedicados se documentan aparte cuando se admite una espera de un solo uso.

Usa pane.read a través de la CLI salvo que estés escribiendo un cliente del protocolo.

Ventana de terminal
herdr pane read w1:p1 --source visible --lines 80
herdr pane read w1:p1 --source recent --lines 120
herdr pane read w1:p1 --source recent-unwrapped --lines 120
herdr pane read w1:p1 --source detection

recent-unwrapped es útil para registros porque ignora el ajuste de línea. detection devuelve la instantánea del fondo del búfer que usa la detección de agentes por pantalla.

Usa las esperas para coordinar agentes y scripts.

Ventana de terminal
herdr agent wait w1:p1 --until done
herdr agent wait w1:p1 --until blocked

Las esperas de agente observan el estado semántico, no la finalización de un comando cualquiera.

Las respuestas correctas tienen este aspecto:

{
"id": "req_1",
"result": {
"type": "pane_info",
"pane": {
"pane_id": "w1:p1",
"terminal_id": "term_abc123",
"workspace_id": "w1",
"tab_id": "w1:t1",
"focused": true,
"agent_status": "working",
"revision": 42
}
}
}

server.agent_manifests devuelve las fuentes activas de los manifiestos de detección de agentes y los diagnósticos de actualización remota, sin recargar las reglas:

{
"id": "req_1",
"result": {
"type": "agent_manifest_status",
"last_check_unix": 1781043522,
"last_result": "checked",
"manifests": [
{
"agent": "cursor",
"source": "/home/me/.config/herdr/agent-detection/cursor.toml",
"source_kind": "local override",
"active_version": "2026.06.10.1",
"cached_remote_version": "2026.06.10.1",
"local_override_shadowing_remote": true,
"remote_update_result": "current"
}
]
}
}

Los campos como last_check_unix, last_result, active_version, cached_remote_version, remote_update_result, remote_update_error, remote_last_checked_unix y warning se omiten cuando no están disponibles. server.reload_agent_manifests devuelve agent_manifest_reload con la misma forma de elementos manifests tras recargar la caché de reglas en memoria.

agent.explain evalúa la instantánea de detección del panel de destino en el servidor en marcha, con su caché de manifiestos activa:

{
"id": "req_2",
"method": "agent.explain",
"params": { "target": "w1:p1" }
}

La respuesta contiene el mismo objeto de explicación que imprime herdr agent explain --json, incluidos el estado final, la fuente y versión del manifiesto, la regla que ha coincidido, la evidencia de las reglas evaluadas, el motivo de omisión de estado, el motivo del respaldo a idle y screen_detection_skip_reason cuando una autoridad de gancho de ciclo de vida completa hace que las reglas de pantalla no sean autoritativas.

Los clientes necesitan un servidor en marcha que admita agent.explain; después de actualizar Herdr, reinicia el servidor o haz un traspaso en caliente antes de confiar en este método.

Los errores tienen este aspecto:

{
"id": "req_1",
"error": {
"code": "not_found",
"message": "pane not found"
}
}

La interfaz de Herdr pintada por el cliente usa una generación estable de puntos de acceso para servidores locales y SSH. Las compilaciones de cliente y servidor no tienen que coincidir. Durante la conexión acuerdan los códecs básicos de instantánea, pantalla, entrada y binarios, y el servidor anuncia los métodos de la API y las capacidades opcionales que admite. La federación de máquinas SSH guardadas requiere la capacidad surface_interest, para que solo la máquina seleccionada transmita la superficie de un panel, y la capacidad health_check, para que una conexión rota en silencio no pueda quedarse como «en línea» indefinidamente. Un servidor sin ese soporte de ciclo de vida se queda en Atención hasta que se actualiza expresamente. Los demás métodos que falten desactivan solo esas acciones y muestran un aviso local en el cliente; no desconectan la interfaz. Las acciones rechazadas o que agotan su tiempo también se informan sin cerrar la conexión. Los servidores anteriores a la generación 1 de puntos de acceso necesitan una última actualización.

El protocolo binario numerado se mantiene para las operaciones internas y entre una misma instalación, incluida la conexión directa a terminales y el traspaso en caliente. Comprueba ping o herdr status antes de usar esas operaciones entre compilaciones distintas. Los clientes de la API JSON deberían ignorar los campos desconocidos y tratar los métodos no admitidos como errores normales.