# Capability: notebook

Operar Jupyter Lab colaborativo desde cualquier sesion de Claude. Discover, read, exec, write, kernel. Sin MCP — funciones directas que resuelven `kernel_id` via `/api/sessions` y mantienen WebSocket 2s para Y.js propague.

## Funciones

| ID | Firma | Que hace |
|---|---|---|
| `jupyter_discover_py_notebook` | `def jupyter_discover(registry_root: str = "", ports: list[int] \| None = None) -> list[dict]` | Descubre instancias de Jupyter Lab activas escaneando archivos .jupyter-port en analysis/ y puertos comunes (8888-8892). Detecta el root_dir real de cada instancia via /proc/pid/cmdline (Linux) para identificar correctamente el analisis en escenarios multi-instancia. Para cada instancia consulta /api/status, /api/config, /api/kernels y /api/sessions via HTTP REST. |
| `jupyter_exec_py_notebook` | `jupyter_append_execute(notebook_path: str, code: str, server_url: str, token: str) -> dict` | Ejecuta codigo en kernels de Jupyter via REST + WebSocket clasico al kernel. Tres modos: append (añade celda y ejecuta), cell (ejecuta celda existente), kernel (ejecuta sin tocar notebook). NO usa el canal colaborativo Y.js. |
| `jupyter_kernel_py_notebook` | `def jupyter_kernel_list(server_url: str = "http://localhost:8888", token: str = "") -> list[dict]` | CRUD completo de kernels Jupyter via REST API. Expone ocho operaciones: list, start, restart, interrupt, shutdown, sessions, cleanup y shutdown-all. Usa solo stdlib (urllib, json), sin dependencias externas. |
| `jupyter_read_py_notebook` | `def jupyter_read_cells(notebook_path: str, server_url: str = 'http://localhost:8888', token: str = '', cell_index: int \| None = None) -> list[dict]` | Lee celdas de un notebook Jupyter abierto via el protocolo de colaboracion en tiempo real (CRDT/Y.js). Devuelve el estado actual incluyendo cambios no guardados. Expone tambien jupyter_notebook_info() para metadata rapida. |
| `jupyter_write_py_notebook` | `def jupyter_append_code(notebook_path: str, source: str, server_url: str = 'http://localhost:8888', token: str = '') -> dict` | Operaciones de escritura sobre celdas de un notebook Jupyter via colaboracion en tiempo real (WebSocket) y API REST. Expone siete operaciones: append_code, append_markdown, insert, edit, delete, create y batch. NO ejecuta celdas — solo modifica la estructura del notebook. create usa PUT /api/contents para crear notebooks nuevos sin necesidad de websocket. batch abre una unica conexion WebSocket para insertar N celdas en una sola operacion. |
| `notebook_to_pdf_bash_infra` | `notebook_to_pdf(project_dir: string, [pattern: string], [output_dir: string]) -> string` | Convierte notebooks Jupyter a PDF usando nbconvert webpdf con chromium. Lista los PDFs generados al finalizar. |


## Ejemplo canonico

```bash
PY="python/.venv/bin/python3"

# 1. Descubrir Jupyter activo
$PY python/functions/notebook/jupyter_discover.py --json

# 2. Leer notebook
$PY python/functions/notebook/jupyter_read.py notebooks/01.ipynb --json

# 3. Anadir celda + ejecutar (usuario lo ve en tiempo real)
$PY python/functions/notebook/jupyter_exec.py append notebooks/01.ipynb "df.describe()"

# 4. Ejecutar celda existente por indice
$PY python/functions/notebook/jupyter_exec.py cell notebooks/01.ipynb 3

# 5. Anadir markdown
$PY python/functions/notebook/jupyter_write.py append-markdown notebooks/01.ipynb "## Resumen"

# 6. Gestionar kernels
$PY python/functions/notebook/jupyter_kernel.py sessions
$PY python/functions/notebook/jupyter_kernel.py shutdown <kernel_id>
```

## Prerequisitos

- Jupyter Lab corriendo en modo colaborativo (`--collaborative`). Launcher estandar `run-jupyter-lab.sh` (generado por `init_jupyter_analysis`) ya lo incluye.
- Notebook abierto en navegador para que los cambios sean visibles en vivo.

## Fronteras

NO incluye:
- Conversion a PDF/HTML — usar `notebook_to_pdf_bash_infra` (no es notebook colaborativo).
- Scheduling de notebooks (papermill) — no implementado, crear funcion si surge necesidad.
- Crear analysis nuevo — usar `init_jupyter_analysis_bash_pipelines` (capability group `analysis-init`).

## Notas

- Reemplaza al MCP jupyter — no requiere registrar nada por directorio.
- Paths de notebooks relativos a raiz del servidor Jupyter (normalmente `analysis/<tema>/`).
- Token vacio por defecto. Si server tiene token, pasarlo con `--token`.
