Files
fn_registry/functions/infra/list_claude_fleet.md
T
egutierrez 927437a8d8 feat(infra): grupo claude-fleet — FleetView TUI + orquestacion de Claudes
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>
2026-06-17 00:04:41 +02:00

4.8 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path, notes
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path notes
list_claude_fleet function go infra 1.0.0 impure func ListClaudeFleetFrom(claudeDir string) ([]ClaudeFleet, error) | func ListClaudeFleet() ([]ClaudeFleet, error) Lista la flota de procesos Claude Code de la maquina local (Linux). Escanea ~/.claude/sessions/*.json, cruza cada PID vivo contra /proc para validar liveness (anti-PID-reciclado via procStart == campo 22 de /proc/<pid>/stat), une el goal/phase de ~/.claude/goals/<sessionId>.json, extrae KITTY_PID del environ y deriva los campos de display (Target, Rename). Devuelve todas las sesiones ordenadas por status (idle, waiting, busy, otro) y por updatedAt desc; el caller filtra por Alive. Pieza de datos de la app TUI fleetview.
claude-fleet
infra
claude
session
proc
fleet
tui
claude_fleet_go_infra
claude_fleet_go_infra
false error_go_core
name desc
claudeDir Directorio raiz de Claude Code a escanear (ej. /home/enmanuel/.claude). ListClaudeFleetFrom lo recibe explicito (testeable con t.TempDir()); ListClaudeFleet lo resuelve via os.UserHomeDir() + .claude.
Slice de ClaudeFleet (claude_fleet_go_infra), una entrada por sesion con JSON parseable en sessions/. Cada entrada lleva PID, KittyPID, SessionID, Rename, Target, Goal, Phase, Status, Cwd, TmuxWindow (""), Alive y UpdatedAt. Ordenado por rango de status y luego por UpdatedAt descendente. Devuelve slice vacio (sin error) si la carpeta sessions/ no existe; error si no se puede leer la carpeta por otra causa. true
TestListClaudeFleetFrom
TestListClaudeFleetFromMissingDir
functions/infra/list_claude_fleet_test.go functions/infra/list_claude_fleet.go Misma fuente de verdad que reboot_all_claudes_bash_infra (~/.claude/sessions/<PID>.json de Claude Code 2.1.x: pid, sessionId, cwd, procStart, status, updatedAt). Solo LEE y valida — no relanza ni mata nada. La validacion anti-PID-reciclado replica la del bash (procStart del JSON vs campo 22 de /proc/<pid>/stat) pero parseando de forma robusta el comm (campo 2 entre parentesis, que puede contener espacios y ')'): se toma lo que hay tras el ULTIMO ')' y starttime es el indice 19 de ese resto. TmuxWindow queda "" (se rellena en una fase posterior). Build tag //go:build !windows (depende de /proc, no portable a Windows).

Ejemplo

package main

import (
	"fmt"

	"fn-registry/functions/infra"
)

func main() {
	fleet, err := infra.ListClaudeFleet() // escanea ~/.claude
	if err != nil {
		panic(err)
	}
	for _, c := range fleet {
		if !c.Alive {
			continue // el caller filtra las sesiones muertas
		}
		fmt.Printf("[%s] %-20s pid=%d kitty=%d  %s\n",
			c.Status, c.Rename, c.PID, c.KittyPID, c.Target)
	}
}
// Variante testeable: escanea un directorio arbitrario (fixtures en tests).
fleet, _ := infra.ListClaudeFleetFrom("/home/enmanuel/.claude")
fmt.Println(len(fleet), "sesiones conocidas")

Cuando usarla

Cuando necesites enumerar las sesiones de Claude Code vivas en la maquina local para mostrarlas, monitorizarlas o actuar sobre ellas (TUI fleetview, dashboards, automatizaciones). Da el join PID -> sessionId -> cwd -> goal/phase ya resuelto y validado contra /proc, en lugar de reimplementarlo a mano cada vez. Usa ListClaudeFleetFrom en tests (inyectando un directorio con fixtures) y ListClaudeFleet en runtime real.

Gotchas

  • Impura: lee el filesystem y /proc. No es determinista entre llamadas (las sesiones nacen y mueren). Solo lectura — nunca mata ni relanza procesos.
  • Anti-PID-reciclado. Alive solo es true si el proceso existe Y su starttime (campo 22 de /proc/<pid>/stat) coincide con el procStart del JSON. Un JSON huerfano cuyo PID fue reasignado a otro proceso se marca Alive=false aunque ese PID este vivo. Si el JSON no trae procStart, basta con que el proceso exista.
  • Parseo del comm en /proc//stat. El campo 2 (comm) va entre parentesis y puede contener espacios y el caracter ')'. La funcion parsea tomando lo que hay tras el ULTIMO ')'; un split ingenuo por espacios daria un starttime equivocado.
  • /proc no es portable. Build tag //go:build !windows; depende de /proc/<pid>/stat y /proc/<pid>/environ (Linux). En macOS/BSD no funciona tal cual.
  • environ ilegible -> KittyPID=0. Si /proc/<pid>/environ no es legible (permisos, proceso de otro usuario, o el proceso ya murio entre el ReadDir y el ReadFile) KittyPID cae a 0 sin error. Tambien es 0 legitimamente cuando claude no corre bajo kitty (ej. tmux remoto).
  • Devuelve TODAS las sesiones con JSON parseable, vivas o muertas. El caller decide filtrar por Alive. Archivos no-.json y JSON corrupto se ignoran silenciosamente.
  • TmuxWindow siempre "". Reservado para una fase posterior; hoy no se rellena.