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>
This commit is contained in:
2026-06-17 00:04:41 +02:00
parent 7d395f39e5
commit 927437a8d8
58 changed files with 5961 additions and 2 deletions
+120
View File
@@ -0,0 +1,120 @@
---
name: add_xlsx_chart
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: impure
signature: "def add_xlsx_chart(xlsx_path: str, sheet_name: str, chart_type: str, data_range: str, cats_range: str = None, anchor: str = 'H2', title: str = '', x_title: str = '', y_title: str = '') -> dict"
description: "Anade un grafico nativo de openpyxl a una hoja EXISTENTE de un libro .xlsx existente, refiriendo rangos de celdas ya escritos. chart_type en {bar, line, pie, scatter} (BarChart/LineChart/PieChart/ScatterChart). data_range y cats_range en notacion Excel tipo 'B1:B10' (se convierten a Reference). anchor = celda destino del chart (ej. 'H2'). Acepta titulo del grafico y de los ejes X/Y. Guarda el libro. Es la pieza que completa el grupo excel para generar hojas con graficos: primero escribir datos (write_xlsx_sheets) y luego anadir el chart. Impura: escribe disco y NO lanza: en fallo (hoja/libro inexistente, chart_type invalido, rango invalido) devuelve {status: 'error', error}."
tags: [excel, xlsx, chart, openpyxl, spreadsheet, office, onlyoffice, viz, io, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [openpyxl]
params:
- name: xlsx_path
desc: "Ruta al archivo .xlsx EXISTENTE. Esta funcion NO crea el libro: escribe primero los datos con write_xlsx_sheets/upsert_xlsx_sheet. Vacio o inexistente devuelve {status: 'error'} (no lanza)."
- name: sheet_name
desc: "Nombre de la hoja (ya existente) donde se ancla el grafico y de la que provienen los rangos. Si no existe, devuelve {status: 'error'} con la lista de hojas disponibles."
- name: chart_type
desc: "Tipo de grafico. Uno de: 'bar', 'line', 'pie', 'scatter' (case-insensitive, se normaliza). Cualquier otro valor devuelve {status: 'error'} con la lista de validos."
- name: data_range
desc: "Rango de celdas de los valores a graficar, en notacion Excel tipo 'B1:B10'. Se convierte a openpyxl.chart.Reference (1-indexed). Si abarca la cabecera (fila 1), se toma el nombre de la serie de esa primera celda (titles_from_data). Rango invalido devuelve {status: 'error'}."
- name: cats_range
desc: "Rango de las categorias/etiquetas del eje X (o labels de pie), tipo 'A2:A10'. None (default) = sin categorias explicitas. Para scatter se usa como valores X (xvalues) de la serie."
- name: anchor
desc: "Celda destino (esquina superior izquierda) del grafico, p.ej. 'H2'. Default 'H2'. Ancla el chart sin desplazar las celdas de datos."
- name: title
desc: "Titulo del grafico. Vacio (default) = sin titulo."
- name: x_title
desc: "Titulo del eje X. Vacio (default) = sin titulo. Ignorado por pie (no tiene ejes)."
- name: y_title
desc: "Titulo del eje Y. Vacio (default) = sin titulo. Ignorado por pie (no tiene ejes)."
output: "Dict. En exito: {status: 'ok', chart_type: <str normalizado>, sheet: <str>, anchor: <str>}. En error: {status: 'error', error: '<mensaje>'}."
tested: true
tests: ["test_add_bar_chart_reabre_y_verifica", "test_add_line_chart", "test_add_pie_chart", "test_add_scatter_chart", "test_dos_charts_en_la_misma_hoja", "test_chart_type_invalido_devuelve_error", "test_hoja_inexistente_devuelve_error", "test_libro_inexistente_devuelve_error", "test_data_range_invalido_devuelve_error", "test_xlsx_path_vacio_devuelve_error"]
test_file_path: "python/functions/infra/add_xlsx_chart_test.py"
file_path: "python/functions/infra/add_xlsx_chart.py"
---
## Ejemplo
```python
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from infra.write_xlsx_sheets import write_xlsx_sheets
from infra.add_xlsx_chart import add_xlsx_chart
# 1) Escribe los datos (cabecera + filas)
write_xlsx_sheets("/tmp/ventas_chart.xlsx", {
"Ventas": [
["Mes", "Unidades"],
["Ene", 120],
["Feb", 150],
["Mar", 90],
["Abr", 200],
],
})
# 2) Anade un grafico de barras refiriendo los rangos ya escritos
res = add_xlsx_chart(
xlsx_path="/tmp/ventas_chart.xlsx",
sheet_name="Ventas",
chart_type="bar",
data_range="B1:B5", # incluye la cabecera 'Unidades' -> nombre de la serie
cats_range="A2:A5", # meses como categorias del eje X
anchor="D2", # esquina superior izquierda del chart
title="Unidades por mes",
x_title="Mes",
y_title="Unidades",
)
print(res)
# {'status': 'ok', 'chart_type': 'bar', 'sheet': 'Ventas', 'anchor': 'D2'}
# Verificar que el chart quedo en la hoja
from openpyxl import load_workbook
wb = load_workbook("/tmp/ventas_chart.xlsx")
print(len(wb["Ventas"]._charts)) # 1
```
## Cuando usarla
Usala cuando necesites **generar una hoja de Excel con un grafico** a partir de
datos que ya escribiste en el libro: dashboards exportables, reports con
visualizacion embebida, resumenes que se abren en Excel/OnlyOffice mostrando el
chart. Es el ultimo paso del flujo del grupo `excel`: `write_xlsx_sheets`
(o `upsert_xlsx_sheet`) escribe los datos, y esta funcion les anade el grafico
refiriendo sus rangos. Llamala una vez por grafico (puedes anadir varios a la
misma hoja con distintos `anchor`).
## Gotchas
- **Impura — escribe en disco.** Reabre el libro, anade el chart y lo GUARDA.
No lanza: devuelve `{"status": "error", ...}` ante libro inexistente, hoja
inexistente, `chart_type` invalido, rango invalido o openpyxl ausente.
- **El libro DEBE existir.** Esta funcion no crea el .xlsx ni escribe datos:
los rangos (`data_range`, `cats_range`) deben apuntar a celdas YA escritas.
Escribe primero con `write_xlsx_sheets`/`upsert_xlsx_sheet`.
- **openpyxl carga el libro entero en memoria** para reabrirlo y reescribirlo.
Para libros muy grandes esto consume RAM proporcional al tamano.
- **Los `Reference` de openpyxl son 1-indexed** (fila 1, columna 1 = A1). La
conversion desde notacion `'B1:B10'` la hace `range_boundaries` internamente;
si pasas un rango mal formado, devuelve error en vez de un chart vacio.
- **`titles_from_data`**: si `data_range` incluye la fila 1 (cabecera), el
nombre de la serie se toma de esa primera celda. Si tu `data_range` empieza en
fila 2 (solo datos), la serie queda sin nombre — incluye la cabecera para
etiquetarla.
- **scatter es distinto**: usa `data_range` como valores Y y `cats_range` como
valores X (xvalues) de una unica serie via `Series`. No usa `set_categories`
como bar/line/pie. Para scatter, pasa rangos de SOLO datos (sin cabecera) en
ambos.
- **pie ignora `x_title`/`y_title`** (no tiene ejes). Pasarlos no falla, se
ignoran silenciosamente.
- **El chart NO se recalcula solo**: openpyxl escribe la definicion del grafico;
Excel/LibreOffice lo renderiza al abrir. Si cambias los datos despues, vuelve
a llamar a la funcion o edita el rango — el chart referencia celdas, asi que
reflejara el valor que tengan al abrir el libro.
- **Requiere openpyxl** (ya instalado en `python/.venv`, version 3.1.5).