Token Stack — Guía de instalación
Token Stack — Guía de instalación
Section titled “Token Stack — Guía de instalación”Dashboard de tokens, cuota API y tareas para el universo AI OS. Muestra cuota Anthropic (ventana 5h), ahorro de tokens via Headroom, modo Caveman y kanban de proyectos.
Requisitos
Section titled “Requisitos”| Herramienta | Versión mínima | Dónde corre |
|---|---|---|
| Windows 11 | — | Host |
| WSL 2 (Ubuntu 22.04+) | — | Host |
| Node.js | v22+ | Windows |
| Python | 3.12+ | WSL |
| Claude Code CLI | última | Windows |
| Headroom | 0.26.0+ | WSL (venv) |
| Caveman plugin | — | Windows (.claude) |
| Ponytail plugin | — | Windows (.claude) |
| Node.js | v22+ | WSL (vía nvm, solo para CodeBurn WSL) |
Paso 1 — Instalar Headroom en WSL
Section titled “Paso 1 — Instalar Headroom en WSL”# En WSL (Ubuntu)python3 -m venv ~/.venv-headroomsource ~/.venv-headroom/bin/activatepip install "headroom-ai[all]"Verificar:
headroom --version # debe mostrar 0.26.0+Paso 2 — Parchear Headroom para capturar cuota API
Section titled “Paso 2 — Parchear Headroom para capturar cuota API”Anthropic envía la cuota de plan Pro como headers anthropic-ratelimit-unified-*
en cada respuesta streaming. Headroom no los expone en /stats, así que hay que
parchear su handler para escribirlos a disco.
Importante: Este parche se pierde al hacer pip install --upgrade headroom.
Guarda este script para re-aplicarlo tras cada actualización.
# En WSL — ejecutar una sola vez (o tras actualizar headroom)python3 << 'PATCH'path = '/home/TU_USUARIO/.venv-headroom/lib/python3.12/site-packages/headroom/proxy/handlers/streaming.py'
# Cambia TU_USUARIO y TU_USUARIO_WINDOWS por los tuyosWINDOWS_USER = 'TU_USUARIO_WINDOWS' # ej: Amed
with open(path, 'r') as f: content = f.read()
old = ''' forwarded_headers = { k: v for k, v in upstream_response.headers.items() if "ratelimit" in k.lower() or k.lower().startswith("x-codex") or k.lower() in ("request-id", "anthropic-request-id", "x-request-id") }
async def generate():'''
new = f''' forwarded_headers = {{ k: v for k, v in upstream_response.headers.items() if "ratelimit" in k.lower() or k.lower().startswith("x-codex") or k.lower() in ("request-id", "anthropic-request-id", "x-request-id") }}
# Capture Anthropic unified rate-limit headers → Windows .headroom dir _fh = forwarded_headers _u5h = _fh.get("anthropic-ratelimit-unified-5h-utilization") _u7d = _fh.get("anthropic-ratelimit-unified-7d-utilization") if _u5h is not None or _u7d is not None: import json as _json, time as _time, os as _os _rl_path = "/mnt/c/Users/{WINDOWS_USER}/.headroom/rate_limit.json" _rl_data = {{ "type": "unified", "fh_utilization": float(_u5h) if _u5h is not None else None, "fh_reset": _fh.get("anthropic-ratelimit-unified-5h-reset"), "fh_status": _fh.get("anthropic-ratelimit-unified-5h-status"), "7d_utilization": float(_u7d) if _u7d is not None else None, "7d_reset": _fh.get("anthropic-ratelimit-unified-7d-reset"), "7d_status": _fh.get("anthropic-ratelimit-unified-7d-status"), "overall_status": _fh.get("anthropic-ratelimit-unified-status"), "ts": int(_time.time() * 1000), }} try: _tmp = _rl_path + ".tmp" with open(_tmp, "w") as _f: _json.dump(_rl_data, _f) _os.replace(_tmp, _rl_path) except Exception: pass
async def generate():'''
if old in content: content = content.replace(old, new, 1) with open(path, 'w') as f: f.write(content) print('PATCH OK')else: print('ERROR: snippet no encontrado — versión de headroom distinta, revisar manualmente')PATCHVerificar sintaxis:
python3 -c "import py_compile; py_compile.compile('$HOME/.venv-headroom/lib/python3.12/site-packages/headroom/proxy/handlers/streaming.py', doraise=True); print('OK')"Paso 3 — Instalar Caveman plugin en Claude Code
Section titled “Paso 3 — Instalar Caveman plugin en Claude Code”# En Windows PowerShellclaude plugin install cavemanO siguiendo las instrucciones del repositorio del plugin.(https://github.com/juliusbrussee/caveman#install) (https://caveman.so)
Paso 4 — Instalar Ponytail plugin en Claude Code
Section titled “Paso 4 — Instalar Ponytail plugin en Claude Code”# En Windows PowerShellclaude plugin install ponytailO siguiendo las instrucciones del repositorio del plugin: https://github.com/dietrichgebert/ponytail
Paso 5 — Instalar CodeBurn (Windows + WSL)
Section titled “Paso 5 — Instalar CodeBurn (Windows + WSL)”CodeBurn no es un servidor persistente — lee los logs de sesión que ya
existen en disco (Claude Code, Cursor, Antigravity, OpenCode) y se levanta
on-demand via npx. No requiere instalación previa, solo Node disponible
en cada entorno donde vas a correrlo.
Windows (ve Claude Code, Cursor, Antigravity — puerto 4747):
npx codeburn web --port 4747WSL (necesario para ver OpenCode, que guarda sus sesiones en
~/.local/share/opencode/opencode.db, invisible desde Windows — puerto 4748):
Requiere Node ≥22 en WSL. Si no lo tenés, instalar vía nvm:
# En WSLcurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bashsource ~/.bashrcnvm install 22nvm use 22node --version # debe mostrar v22+Habilitar linger para que el proceso no muera al cerrar la sesión WSL (systemd mata procesos huérfanos sin linger):
sudo loginctl enable-linger $(whoami)# En WSLnpx codeburn web --port 4748Ambos se auto-arrancan desde iniciar_claude_code.ps1 / iniciar_opencode.ps1
si no están vivos — no hace falta lanzarlos a mano en el día a día.
Repo: https://github.com/getagentseal/codeburn
Paso 6 — Copiar los scripts del stack
Section titled “Paso 6 — Copiar los scripts del stack”Copia esta carpeta completa (_shared/token-stack/) a tu universo AI OS.
Estructura mínima necesaria:
_shared/token-stack/ caveman-stats-server.js ← Stats server (Node, puerto 8788) stats-db.js ← SQLite helpers tasks-api.js ← Lector de TASKS.md por mundo prompts-api.js ← Lector/escritor de _shared/prompts/prompts.json dashboard.html ← Dashboard principal headroom-dashboard.html ← Dashboard de Headroom (iframe) headroom-start.ps1 ← Arranca headroom + stats server iniciar_claude_code.ps1 ← Lanzador Claude Code (marca active-tool=claude) iniciar_opencode.ps1 ← Lanzador OpenCode (marca active-tool=opencode)Paso 7 — Crear directorio de datos en Windows
Section titled “Paso 7 — Crear directorio de datos en Windows”New-Item -ItemType Directory -Force "$env:USERPROFILE\.headroom"Paso 8 — Primera ejecución
Section titled “Paso 8 — Primera ejecución”Desde cualquier mundo del universo:
# En PowerShell (Windows), desde la carpeta del mundo.\iniciar_claude_code.ps1 # o .\iniciar_opencode.ps1Lo que hace iniciar_claude_code.ps1/iniciar_opencode.ps1:
- Detecta
_shared/token-stack/hacia arriba en el árbol - Si 8787/8788 no están activos, lanza
headroom-start.ps1 - Abre
http://127.0.0.1:8788en el browser - Lanza Claude Code/OpenCode con
ANTHROPIC_BASE_URL=http://127.0.0.1:8787
O lanzar el stack solo (sin Claude Code):
.\_shared\token-stack\headroom-start.ps1# Luego abre: http://127.0.0.1:8788Paso 9 — Enviar el primer mensaje
Section titled “Paso 9 — Enviar el primer mensaje”Con Claude Code abierto via iniciar_claude_code.ps1, envía cualquier mensaje.
Tras la primera respuesta, el dashboard mostrará la cuota API en tiempo real.
Qué verás en el dashboard
Section titled “Qué verás en el dashboard”http://127.0.0.1:8788 — Dashboard principal (Universe Command Center)
- Tab Tareas: Kanban por mundo + overview
- Tab Headroom: iframe del dashboard de Headroom
- Tab CodeBurn Win: iframe de codeburn (
npx codeburn web --port 4747) — gasto/tokens leído de logs de sesión ya existentes en disco Windows (~/.claude/projects/, Cursor, Antigravity, etc.). No es proxy, no compite con Headroom — datos complementarios (multi-tool, waste analysis, budgets) - Tab CodeBurn WSL: misma herramienta pero corriendo dentro de WSL (
:4748) — necesario porque OpenCode (lanzado víainiciar_opencode.ps1) guarda sus sesiones en el filesystem de WSL (~/.local/share/opencode/opencode.db), invisible para la instancia Windows. Requiere Node ≥22 en WSL (instalado víanvm, ver Paso 5) ysudo loginctl enable-linger <usuario>para que el proceso no muera al cerrar la sesión WSL (systemd mata procesos huérfanos sin linger). Se auto-arranca desdeiniciar_opencode.ps1si no está vivo. - Tab Agentes / Skills: catálogo instalado
- Tab Prompts: biblioteca de prompts reutilizables (título, descripción, cuerpo), CRUD, copiar al portapapeles — persiste en
_shared/prompts/prompts.json
En el iframe de Headroom (tab Headroom):
- Cuota API (ventana actual) — barra de % usado en 5h ·
<50%verde ·50-89%naranja ·≥90%rojo · reset countdown - Resumen de sesión — badge
Claude CodeoOpenCodesegún herramienta activa · tokens enviados, ahorro cache/compresión, coste total - Caveman Mode — turns, tokens ahorrados, modelo (solo Claude Code)
- Ahorro acumulado lifetime (solo Claude Code)
- Historial diario — gráficas y tabla filtrable por proyecto y herramienta (Claude/OpenCode)
Tool mode: Claude Code vs OpenCode
Section titled “Tool mode: Claude Code vs OpenCode”El dashboard detecta automáticamente qué herramienta está activa y adapta la vista.
Lanzar Claude Code:
.\iniciar_claude_code.ps1 # desde cualquier mundoLanzar OpenCode:
.\iniciar_opencode.ps1 # desde cualquier mundoCada script:
- Levanta el stack (8787/8788) si no está activo
- Escribe
claudeuopencodeen~/.headroom/active-tool - El dashboard cambia de vista automáticamente en ~5 segundos
Cuando OpenCode está activo, se ocultan las secciones exclusivas de Claude Code (Caveman Mode, Ahorro lifetime, Features activos) y aparece un panel con el proyecto activo.
Puertos
Section titled “Puertos”| Puerto | Servicio | Proceso |
|---|---|---|
| 8787 | Headroom proxy | WSL / Python |
| 8788 | Stats server + dashboard HTTP | Windows / Node |
| 4747 | CodeBurn web dashboard (Windows) | Windows / Node (npx codeburn web) |
| 4748 | CodeBurn web dashboard (WSL, ve OpenCode) | WSL / Node ≥22 vía nvm (npx codeburn web --port 4748) |
Solución de problemas
Section titled “Solución de problemas”“Sin datos aún” en cuota:
- Verifica que el parche del paso 2 está aplicado:
grep -c 'rate_limit.json' ~/.venv-headroom/lib/python3.12/site-packages/headroom/proxy/handlers/streaming.pydebe dar>0 - Reinicia headroom tras aplicar el parche
- Envía un mensaje en Claude Code (el parche solo se activa en requests streaming)
Dashboard no carga:
- Verifica que el stats server corre:
curl http://127.0.0.1:8788/ - NO abrir
dashboard.htmlcomo archivo (file://) — siempre via HTTP
Parche perdido tras pip upgrade headroom:
- Re-ejecutar el script del paso 2
Cambio de usuario Windows:
- Editar la línea
_rl_pathen el parche y enstreaming.pycon el nuevo usuario
Actualizar headroom sin perder el parche
Section titled “Actualizar headroom sin perder el parche”Script automatizado (recomendado):
# En Windows PowerShell, desde la carpeta del universo o cualquier mundo.\_shared\token-stack\headroom-update.ps1O directamente desde WSL:
bash /mnt/d/Proyect/empresa\ mia/ai-os/_shared/token-stack/headroom-update.shLo que hace el script:
pip install --upgrade headroomen el venv- Localiza
streaming.pyautomáticamente (detecta versión Python) - Re-aplica el parche de cuota API (salta si ya está presente)
- Verifica sintaxis Python
Verificar estado sin modificar nada:
.\_shared\token-stack\headroom-update.ps1 --checkManual (fallback si el script falla):
headroom NO está en PyPI — se distribuye como wheel en GitHub releases.
pip install --upgrade headroom fallará siempre (paquete no existe en PyPI,
y sin venv activo además da externally-managed-environment).
# 1. Activar venv y actualizar desde el wheel (ver TARGET_WHEEL en headroom-update.sh)source ~/.venv-headroom/bin/activatepip install "https://github.com/headroomlabs-ai/headroom/releases/download/vX.Y.Z/headroom_ai-X.Y.Z-cp310-abi3-manylinux_2_28_x86_64.whl"# 2. Re-aplicar (ver paso 2 arriba)python3 mi-parche.py