orchestration.md: nueva subseccion 'Via preferida: tools MCP fleet_*' con mapa
operacion->tool (fleet_list/drain/classify/set_dod/kill/spawn) marcando el MCP
orchestrator como via preferida sobre ./fn run (permisos pre-aprobados, salida
estructurada, telemetria) y el ./fn run / binario fleetview como fallback CLI.
Corrige la afirmacion obsoleta de que 'fleetview list --json no incluye todavia
role/dod_contract/dod_status': el CLI ya los expone directamente y el MCP rellena
los vacios desde el sidecar goal.json. Anade notify_desktop_go_infra a la tabla
del grupo. orquestador.md: linea en el flujo senalando el MCP como via preferida.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expone el grupo de capacidad de orquestación de flota (fleet_list/drain/classify/
kill/set_dod/spawn) como tools MCP tipadas para el Claude orquestador. Binario en
apps/orchestrator_mcp (sub-repo). Command relativo igual que registry_mcp; stdio
por defecto, sin flags. Listo para /mcp reconnect.
Fixes B (fan-out duro=6), C (hook_fleet_state_inject reancla role=orchestrator),
D (command 555->299 lineas, maquinaria extraida a .claude/rules/orchestration.md).
Verificado adversarial: met (todas las clausulas re-ejecutadas independientes).
El doc hablaba de "tope de fan-out para no explotar la flota" sin numero. Se
fija un maximo DURO: 6 ejecutores role=executor activos simultaneos por
orquestador. Al alcanzarlo, el orquestador no lanza mas: encola las sub-tareas
restantes hasta que un slot se libere (ejecutor verificado met + kill_fleet_agent).
Justificacion: ya hubo el caso de 30 agentes que no cerraban nada y, al competir
todos por el mismo rate-limit compartido, hubo que desactivar goal_refine. Mas
ejecutores no es mas throughput; el cuello de botella es el rate-limit compartido
y los DoD que nadie cierra.
Escrito en el splitter + regla dura de orchestration.md (detalle + justificacion)
y en las reglas duras del command (numero + encolado, puntero al detalle).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El command /orquestador (555 lineas) se cargaba entero en contexto cada turno y
predicaba "responde conciso" siendo el mismo prolijo. Se parte en dos:
- Nueva regla .claude/rules/orchestration.md con la maquinaria estable: seguir
la flota (fleetview, tiempo de actividad), cola del watcher (events.jsonl,
push activo, FLEET-STATE), clasificacion (classify_fleet_termination),
politicas por clasificacion, verificador adversarial, auto-kill
(kill_fleet_agent), nudge, splitter, cadencia y el catalogo de funciones del
grupo orchestration. Todo el contenido sustantivo se mueve integro.
- El command queda con la doctrina y el flujo: arranque (marcar role +
confirmacion), diferencia con fn-orquestador/autopilot, ciclo de 8 pasos
(resumido donde la maquinaria se fue a la regla, con punteros), reglas duras,
anti-patrones, ejemplo end-to-end y salida del modo. Baja de 555 a 299 lineas.
Redundancias colapsadas a una canonica + punteros: "NUNCA Agent tool para
lanzar trabajo" vive en el paso 8; "nunca pkill/killall claude" en el paso 6.
El resto referencia esos pasos.
Fila 38 anadida a .claude/rules/INDEX.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El modo /orquestador dependia de que su prompt siguiera en contexto. Ahora el
hook UserPromptSubmit que ya filtra por role=orchestrator reinyecta tambien una
linea recordatorio del rol cada turno, reanclando el modo independientemente del
prompt. Se emite antes de la guarda del venv para sobrevivir a un watcher caido.
El path limpio (sin goal.json o role != orchestrator) sigue saliendo con exit 0
y stdout vacio.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Integra las 4 mejoras de la tanda: (1) --parent en los ejemplos de spawn y la
explicacion del routing del watcher por parent_orchestrator; (2) regla de
auto-kill — cerrar cada ejecutor con kill_fleet_agent tras verificar met, con sus
guards; (3) push activo del watcher (tmux send-keys al pane del orquestador padre)
+ indicador 'idle nuevo sin ver' de la TUI fleetview (los implementa otro agente,
aqui solo se describen); (4) el dod movil del statusline ya no se regenera con LLM
por turno (objetivo/DoD fijo, ajustable con dod:). Anade mark_claude_parent y
kill_fleet_agent a la tabla del grupo orchestration.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cierra UN ejecutor por sessionId (exacto/prefijo) o PID: SIGTERM al proceso claude
(cierre limpio, recuperable con --resume) + kill-window de su window tmux. Lo usa
el orquestador para liberar el slot idle de cada ejecutor en cuanto verifica que
su DoD-contrato esta met. Guards: NO mata a un role=orchestrator (leido del
goal.json) ni a la sesion que invoca (PID propio por ancestros /proc). --dry-run
para inspeccionar sin tocar nada. Overrides FN_FLEET_* para tests. Tag grupo
orchestration. Tests: 17 asserts (golden por sessionId/PID/prefijo, guards
orchestrator/self rc=3, errores rc=2).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Nuevo flag opcional --parent: persiste parent_orchestrator en el goal.json del
Claude recien lanzado (via mark_claude_parent, en background). Habilita el routing
del watcher de fleetview, que asi sabe a que pane de orquestador empujar el aviso
de cierre del ejecutor. El bloque background ahora cubre --role y/o --parent
encadenados secuencialmente (primero role, luego parent) para evitar la carrera de
lectura-modificacion-escritura sobre el goal.json. Retro-compatible: sin --parent,
el spawn se comporta igual que antes. Bump 1.0.0 -> 1.1.0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Helper py analogo a mark_claude_role: resuelve el sessionId de un Claude recien
arrancado por su PID (sondeando sessions/<pid>.json) y escribe SOLO la clave
parent_orchestrator en su goal.json, preservando el resto. Lo consume
spawn_fleet_agent --parent para que el watcher de fleetview rutee los avisos del
ejecutor a su orquestador padre. Tests: escribe+preserva, goal inexistente,
parent vacio (ValueError), timeout sin crash.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El orquestador no se enteraba de los cambios de estado de su flota: el drenado
era manual y el peek documentado `./fn run drain_fleet_events --advance false`
devolvia un falso `{total_new:0, cursor:0}` porque `fn run` mapea los argumentos
posicionalmente y no parsea flags `--nombre valor` (events_path acababa valiendo
"--advance", una ruta inexistente).
- drain_fleet_events: nuevo helper _normalize_fn_run_flags que renormaliza el
patron `--advance <bool>` aplanado por `fn run`, de modo que el peek funciona
directo desde la CLI sin tocar el runner de Go. Bump 1.1.0 + growth log + tests
del normalizador (unit y end-to-end por HOME).
- summarize_fleet_transitions (nueva, pure, grupo claude-fleet): resume el dict
by_classification de drain en un bloque de una linea con las tres categorias
accionables (terminados / reclaman / estancados), dedup por session_id y
truncado de objetivo.
- hook_fleet_state_inject.sh (UserPromptSubmit): si la sesion es role=orchestrator
(leido de ~/.claude/goals/<session_id>.json), hace peek de la cola sin mover el
cursor y emite el bloque FLEET-STATE cada turno. Degrada limpio si el watcher
esta caido, la cola no existe o la sesion no es orquestador.
El registro del hook va en .claude/settings.local.json (gitignored, fuera de este
commit). Pendiente, lo integra otro agente: documentar el bloque FLEET-STATE en
.claude/commands/orquestador.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El orquestador reporta el tiempo de actividad (cuanto lleva sin avanzar)
via fleetview list AGE/idle_seconds, no el etime (vida del proceso = 8h de
sesion), que no es progreso.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El orquestador responde conciso (velocidad de iteracion sobre detalle) y
va pinneado arriba en el sidebar de fleetview via role=orchestrator. Se
corrige una regla previa que afirmaba erroneamente un comportamiento de
no-conmutacion del pane (no era lo pedido).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- spawn_fleet_agent (bash/functions/infra): lanza un Claude como window de
la sesion tmux de un perfil fleet (no kitty suelta), con --skill para
arrancar en un modo (ej. /orquestador), --prompt-file para ejecutores
autocontenidos, y --role para marcar el goal.json via mark_claude_role.
Asi ejecutores y orquestador viven en la flota, visibles en fleetview y
conmutables con /fleet focus.
- skill /orquestador: paso 2 ahora prefiere spawn_fleet_agent sobre kitty
cuando se opera dentro de un perfil fleet ($FLEET_SOCKET seteado); tabla
de funciones del grupo actualizada.
Validado en vivo: el orquestador arranca en la flota fleet2 en modo
(MODO ORQUESTADOR activo), role=orchestrator marcado, pinneado arriba en
la TUI; los 9 ejecutores existentes intactos.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- mark_claude_role (python/functions/infra): resuelve PID->sessionId
esperando sessions/<PID>.json y escribe role en el goal.json sin pisar
el resto. 4 tests.
- launch_fleetclaude: el pane derecho arranca el ORQUESTADOR con el skill
/orquestador embebido como primer prompt; tras arrancar, mark_claude_role
le pone role=orchestrator (en background, no-fatal) para que la TUI lo
pinee arriba; ademas siembra 1 ejecutor idle inicial en su propia window.
- skill /orquestador: regla 'no te vigiles a ti mismo' (ignora en la cola
su propia sesion y cualquier role=orchestrator).
Validado en vivo (perfil aislado): claude /orquestador entra en modo,
role marcado, idle sembrado, pin correcto, fleet2 intacto.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Primitivas (python/functions/infra):
- drain_fleet_events: consume la cola del watcher (~/.claude/fleet/
events.jsonl) desde un cursor, agrupa por clasificacion, marca
urgentes. 7 tests.
- set_dod_contract: escribe el DoD-contrato fijo (dod_contract/dod_status)
en el goal.json de un agente sin pisar el resto (escritura atomica).
5 tests.
Skill /orquestador evolucionado (sin romper lo existente): vigila la
flota por su DoD (no por 'esta vivo'). Nueva seccion 'Consumo de la cola
de la flota': DoD-contrato obligatorio al lanzar, drenar la cola,
politicas por clasificacion (RECLAMA escala / DICE_TERMINADO verifica /
ESTANCADO nudge / MAL_LANZADO re-DoD), verificador independiente del
ejecutor (lee el report vs dod_contract), splitter con tope de fan-out,
y cadencia (drain al actuar + heartbeat).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Transicion real MAL_LANZADO->DICE_TERMINADO escrita a la cola JSONL con
la TUI viva. Hallazgo: la flota actual clasifica MAL_LANZADO (sin
dod_contract), comportamiento correcto que Fase 3 corrige.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refleja la decisión real: el watcher no es un daemon aparte sino que se
embebe en fleetview (reutiliza su polling); la cola es JSONL en
~/.claude/fleet/events.jsonl (sin SQLite/CGO).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fase 1, piezas 1+2:
- ClaudeFleet + list_claude_fleet ganan DodContract/DodStatus/Role,
leidos de goals/<sessionId>.json (.dod_contract/.dod_status/.role).
Aditivo: fleetview sigue compilando.
- classify_fleet_termination (pura): clasifica el estado de terminacion
de un agente (RECLAMA/MAL_LANZADO/DICE_TERMINADO/ESTANCADO/TRABAJANDO)
con precedencia fija, para que un watcher sin LLM decida. 34 tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diseño del sistema para manejar 20-30 agentes Claude hablando solo con
uno: 4 roles (orquestador/splitter/ejecutores/verificador), DoD-contrato
fijo en goal.json como criterio estable de terminación, máquina de
terminación clasificable sin LLM, y 3 fases (watcher edge-triggered,
orquestador reactivo + verificador independiente, spawn en flota +
splitter). Métrica de salud = throughput de DoD cumplidos.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Slash command que envuelve el modo CLI de fleetview (list/focus) para
preguntar por la flota de Claudes vivos o saltar con foco a una
conversación dentro de la sesión tmux fleet, desde cualquier sesión.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
La funcion direccionaba panes por indice literal ("console.0",
"windowID.0", filtro pane_index != "0"). El socket aislado de fleetview
(tmux -L fleet) hereda ~/.tmux.conf, asi que con `pane-base-index 1`
(config muy comun) el primer pane es el indice 1 y no existe el 0:
join-pane fallaba con "can't find pane: 0" tras haber hecho ya el
break-pane, dejando la sesion fleet con las windows desperdigadas y sin
el sidebar de la TUI.
Ahora resuelve el pane sidebar como el de MENOR pane_index y opera
siempre por pane_id (estable e inmune al base-index). Helpers nuevos:
tmuxConsolePanes, tmuxFirstPaneID, tmuxPanesSorted, tmuxSidebarWidth.
Tests actualizados a base-index-agnostico (localizan el sidebar por
menor indice, no por "0") y el default de ancho del sidebar pasa de 47
a 52 para coincidir con launch_fleetclaude.
Bump v1.0.0 -> v1.0.1 + Capability growth log.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- launch_fleetclaude: si hay TTY, exec tmux attach en la terminal actual (no abre
ventana kitty nueva); atajos alt+q (cerrar flota con confirmacion) y alt+flecha
izquierda (volver atras); estetica neutra de tmux (status/bordes gris).
- ancho del sidebar 47 -> 52; tmux_swap_window_into_console preserva 52 por defecto.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Renombra la funcion entrypoint y su comando a fleetclaude. Ademas, sobre el .sh:
- atajos nuevos: alt+0 (= alt+n), alt+k (kill), alt+r (resume picker),
alt+flecha-izquierda (volver atras), alt+q (cerrar toda la flota con confirmacion).
- mouse on, remain-on-exit off (cierra window al salir el Claude).
- estetica neutra de tmux: status bar y bordes de pane en gris (sin verde fosforo),
borde activo igual que inactivo (separacion simple sin resaltado de foco).
Docs (INDEX, claude-fleet.md) actualizadas al nuevo nombre.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sistema FleetView para centralizar la flota de procesos Claude Code vivos en una
sola ventana kitty + tmux (socket aislado -L fleet) con un panel TUI:
- list_claude_fleet (+ tipo claude_fleet): escanea ~/.claude/sessions + goals +
runtime, valida procesos vivos (anti-PID-reciclado), join por sessionId.
- list_resumable_claudes (+ tipo resumable_claude): sesiones cerradas reanudables.
- wrappers tmux: tmux_new_claude_window (con --resume), tmux_swap_window_into_console
(preserva ancho del sidebar), tmux_map_claude_panes.
- launch_kittyclaude: comando entrypoint; instala atajos alt+flechas/enter/n/0/k/r,
mouse on, remain-on-exit off; fija el ancho del sidebar con hooks.
- docs/capabilities/claude-fleet.md + entrada en el INDEX.
Incluye ademas funciones datascience en progreso (excel/duckdb/postgres) y ajustes
varios de docs e infra de otra sesion, agrupados aqui para no perderlos.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Antes de calcular el centro y despachar el pointer, ambos esperan a que el
elemento sea accionable (visible + stable + hit-test contra elementFromPoint),
evitando clicks/hover tragados por overlays/banners o por elementos aún
montándose o animándose. Si la comprobación no converge en 2s, se cae al
cálculo de centro previo (sin regresión). Modo 'instant' sigue saltando al
click JS directo.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tras estudiar el código de Playwright (sources/playwright), 4 primitivas nuevas y
1 endurecida para que la interacción web sea fiable:
- cdp_wait_actionable: visible + stable (2 rAF) + enabled + hit-test (elementFromPoint
cruzando shadow DOM) + retry backoff + scroll cycling. Devuelve el punto validado.
Réplica de _retryAction/_checkElementIsStable/expectHitTarget de Playwright.
- cdp_select_dropdown: desplegables custom (combobox/MUI/select2/headlessui): click real
en trigger -> espera apertura (aria-expanded/[role=option] visible) -> click real en
la opción. Resuelve el fallo nº1: clicar antes de que monte el listbox.
- cdp_select_option (endurecida v1.1.0): valida <select> real, match value/label
normalizado/índice, option.selected para multiple, eventos input{composed}+change.
- cdp_fill: escribir fiable en inputs React/Vue: focus -> select-all -> Input.insertText
(sin native value setter, como Playwright); native setter solo para inputs especiales.
- cdp_find_by_role: localizar por rol ARIA + accessible name (estilo getByRole),
reutilizando el AX tree de cdp_get_ax_outline.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CdpCollectConsole gana un parametro maxEntries (default 200): al alcanzarlo deja
de acumular y marca una ConsoleEntry final '_truncated', evitando reventar la
salida en paginas verbosas. Ademas descarta los eventos console anteriores al
inicio de la captura (backlog acumulado en la conexion CDP viva), capturando solo
lo emitido dentro de la ventana durationMs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cuatro primitivas CDP nuevas para el dominio browser, base de nuevas tools del
browser_mcp:
- cdp_collect_console: snapshot temporal de console + exceptions + log entries
- cdp_print_pdf: Page.printToPDF -> []byte
- cdp_select_option: selecciona <option> en un <select> y dispara input/change
- cdp_set_file_input: sube archivos a un <input type=file> via DOM.setFileInputFiles
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The function code and its registry metadata were created together but the
.md was left untracked by the auto-commit. Add it so the indexed function
has its companion metadata versioned.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Añade fetch_http_fingerprint_cdp_py_browser (domain browser): recoge el HTML
renderizado tras ejecutar JavaScript usando un Chrome remoto via CDP, componiendo
cdp_open_url_and_wait + cdp_eval. Devuelve la misma estructura que el fetch
estático para que detect_web_tech lo consuma sin cambios.
Integra use_cdp en el pipeline fingerprint_web_stack (v1.1.0): combina los headers
reales del fetch estático con el HTML post-JS del CDP. Detecta frameworks de SPA
(React/Vue/Angular/Next) que el fetch estático no ve porque montan el DOM en
runtime. Si no hay Chrome en cdp_port, degrada al fetch estático con un warning
(no rompe). cdp_port=9333 (Chrome aislado) recomendado para terceros, 9222 diario.
Verificado en vivo (Chrome 9333): sobre una SPA cuyo marcador de framework solo
aparece tras ejecutar JS, el estático detecta solo nginx; con use_cdp=True detecta
además Next.js, React y Node.js.
Tests: 48 verdes (error path sin Chrome + happy path mockeado + degradación).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sincroniza la documentación con los cambios de comportamiento:
- cdp_wait_load.md: descripción y notas reflejan el cambio de polling a evento Page.loadEventFired con fast path; bump a v1.1.0; añade tag de grupo 'navegator' y growth log.
- cdp_type_text.md: corrige la nota (envía 2 eventos keyDown+keyUp, no 3; ya no manda el char extra que duplicaba) y la pausa aleatoria; documenta la función hermana rápida CdpInsertText; bump a v1.1.0; tag 'navegator'; growth log.
- cdp_type_ref.md: documenta CdpTypeRefFast (camino rápido insertText) frente a CdpTypeRef (camino human); bump a v1.1.0; growth log.
Optimiza el dominio browser para que el manejo del navegador via CDP sea mucho más rápido en automatización propia, manteniendo el camino sigiloso disponible.
- CDPConn cachea los enable de Accessibility/Network/Page por conexión (ensureAX/ensureNetwork/ensurePage): elimina un round-trip redundante en cada percepción y espera, que son las operaciones más frecuentes del bucle percibir->actuar del agente.
- sendCDP adquiere timeout (cdpCmdTimeout 30s): antes una respuesta que Chrome nunca enviaba colgaba la goroutine del tool indefinidamente; ahora falla limpio y el retry puede reconectar.
- CdpWaitLoad pasa de polling de document.readyState cada 200ms a esperar el evento Page.loadEventFired, con fast path inicial de readyState y re-chequeo anti-carrera tras suscribir. Si la página ya está cargada retorna en microsegundos.
- cdp_wait_idle usa ensureNetwork y deja de hacer Network.disable al salir (borraba el estado y forzaba el enable de nuevo).
- Nuevas funciones de escritura rápida: CdpInsertText (todo el texto en un solo Input.insertText) y CdpTypeRefFast (focus + insertText). El chequeo de foco se extrajo a assertEditableFocus, compartido con CdpTypeText.
- CdpTypeText pasa su pausa entre caracteres de 10ms fija a aleatoria 15-65ms (ritmo humano irregular).
- El modo 'auto' se añade al perfil de ratón (MouseProfileForMode, mouseHumanDefaults, clickPauseMs) como alias rápido de 'fast'.
No se tocan las firmas públicas existentes; CdpTypeRef y CdpTypeText conservan su comportamiento (camino human).
Hash estable (tel normalizado > email > nombre normalizado) para importaciones
idempotentes: re-importar el mismo .vcf matchea la fila existente sin depender de
UIDs opacos ni de nombres que el pipeline de import transforma. Prefijo v1- para
versionar el algoritmo. Funcion pura + 5 tests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>