---
name: export_hub_icons
kind: function
lang: py
domain: infra
version: "1.1.0"
purity: impure
signature: "export_hub_icons(out_dir: str, *, size: int = 64, registry_root: str | None = None, style: str = 'fill_white') -> dict"
description: "Rasteriza iconos PNG para todas las apps C++/imgui del registry y los escribe en un directorio de salida. Consume registry.db para listar apps, lee icon.phosphor + icon.accent de cada app.md y usa la logica visual de generate_app_icon. Param `style` soporta 'fill_white' (default, glyph blanco solido), 'adaptive_duotone' y 'white_duotone' (glyph duotone Phosphor — alineado con generate_app_icon)."
tags: ["hub", "launcher", "icons", "suite", "png", "phosphor", "imgui", "cpp-windows"]
params:
  - name: out_dir
    desc: "Directorio de salida donde se escriben los <name>.png. Se crea si no existe. PNGs existentes se sobreescriben."
  - name: size
    desc: "Lado del cuadrado del PNG en pixels. Default 64. El hub launcher usa 64 para las tarjetas."
  - name: registry_root
    desc: "Ruta a la raiz del fn_registry. Si es None usa FN_REGISTRY_ROOT env o $HOME/fn_registry."
  - name: style
    desc: "Estilo del icono igual que generate_app_icon: 'fill_white' (default), 'adaptive_duotone' o 'white_duotone'. CLI: `--style <valor>`."
output: "dict con ok=True, count=N (PNGs escritos), out_dir (ruta absoluta), skipped (lista de {name, reason} para apps omitidas)."
uses_functions:
  - generate_app_icon_py_infra
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports:
  - cairosvg
  - Pillow
  - PyYAML
  - sqlite3
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/infra/export_hub_icons.py"
---

## Ejemplo

```bash
# Exportar iconos 64px al directorio local_files/icons del hub launcher (Windows via WSL)
python/.venv/bin/python3 -c "
import sys; sys.path.insert(0, 'python/functions')
from infra.export_hub_icons import export_hub_icons
print(export_hub_icons('/mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files/icons'))
"

# Exportar iconos a /tmp para smoke test
python/.venv/bin/python3 -c "
import sys; sys.path.insert(0, 'python/functions')
from infra.export_hub_icons import export_hub_icons
import json
print(json.dumps(export_hub_icons('/tmp/hub_icons_test'), indent=2))
"

# Via CLI directo con tamaño personalizado
cd $HOME/fn_registry
python/.venv/bin/python3 python/functions/infra/export_hub_icons.py /tmp/hub_icons --size 128
```

## Cuando usarla

Despues de compilar y desplegar `app_hub_launcher` a Windows Desktop, antes de lanzar la app: ejecutar esta funcion para generar los PNGs que el hub carga via `fn::gl_texture_load` al arrancar. Tambien util para regenerar los iconos tras cambiar el campo `icon:` en algun `app.md` o tras añadir una nueva app imgui al registry.

## Gotchas

- Requiere que `sources/phosphor-core/` este clonado en la raiz del registry (`git clone --depth=1 https://github.com/phosphor-icons/core.git sources/phosphor-core`). Si falta, todas las apps se omiten con "Phosphor SVG not found".
- Las apps sin campo `icon:` en su `app.md` usan el icono por defecto (`app-window`, accent `#64748b`) — no se omiten.
- `cairosvg` requiere `libcairo2` instalado en el sistema (`apt install libcairo2-dev` en Debian/Ubuntu). En WSL suele estar disponible si se uso anteriormente `generate_app_icon`.
- El campo `icon.phosphor` debe ser el nombre del glyph Phosphor **sin sufijo de weight** (ej. `"chart-bar"`, no `"chart-bar-fill"`). El sufijo `-fill.svg` se añade internamente.
- `out_dir` en rutas Windows desde WSL debe usar `/mnt/c/...` — no rutas Win32 directas.
- Apps con `dir_path` que apuntan a rutas fuera del registry (ej. `cpp/apps/shaders_lab`) se tratan igual: `root / dir_path / "app.md"`. Si la app no esta clonada localmente, su `app.md` falta y se omite.
