--- name: export_hub_manifest kind: function lang: py domain: infra version: "1.0.0" purity: impure signature: "export_hub_manifest(out_path: str, *, registry_root: str | None = None) -> dict" description: "Genera el TSV sidecar para app_hub_launcher: consulta registry.db por todas las apps cpp/imgui, lee su app.md para extraer nombre, descripcion y accent_hex, y escribe un archivo TSV con cabecera a out_path. Retorna {ok, count, out_path}." tags: [hub, launcher, manifest, suite, cpp-windows] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [sqlite3, yaml, pathlib] params: - name: out_path desc: "Ruta de destino del archivo TSV. Puede ser absoluta o relativa al cwd. El directorio padre se crea si no existe." - name: registry_root desc: "Raiz del fn_registry. Si None, usa la variable de entorno FN_REGISTRY_ROOT o /home/lucas/fn_registry como fallback." output: "Dict {ok: True, count: N, out_path: str} con la ruta absoluta del TSV escrito y el numero de apps incluidas." tested: false tests: [] test_file_path: "" file_path: "python/functions/infra/export_hub_manifest.py" --- ## Ejemplo ```bash # Uso directo con fn run (la salida JSON se imprime en stdout) ./fn run export_hub_manifest_py_infra /mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files/hub_manifest.tsv ``` ```python # Desde un heredoc o pipeline Python import sys sys.path.insert(0, "python/functions") from infra import export_hub_manifest result = export_hub_manifest( "/mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files/hub_manifest.tsv" ) print(result) # {'ok': True, 'count': 12, 'out_path': '/mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files/hub_manifest.tsv'} ``` ```bash # Ver el contenido del TSV generado head -5 /mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files/hub_manifest.tsv # name display_name description accent_hex # chart_demo Chart Demo Demo ImGui de primitivos viz... #0ea5e9 # dag_engine_ui Dag Engine Ui Motor de DAGs con frontend... #f59e0b ``` ## Cuando usarla Antes de desplegar `app_hub_launcher` a Windows: genera el `hub_manifest.tsv` que el hub lee al arrancar para listar y colorear los botones de cada app. El hub en runtime no tiene acceso a `registry.db` ni a los `app.md` del WSL, por lo que necesita este sidecar. Ejecutar tras añadir o modificar una app C++ imgui en el registry. ## Gotchas - **PyYAML en el venv**: requiere `yaml` disponible en `python/.venv`. Ya instalado por defecto. Si falta: `cd python && uv pip install pyyaml`. - **app.md faltante no aborta**: si un `app.md` no existe o tiene frontmatter malformado, la app sigue apareciendo en el TSV con `description` vacía y accent `#64748b` (slate). Se imprime un WARN a stderr. - **Filtro estricto `lang='cpp' AND framework='imgui'`**: solo apps C++ con el shell `fn::run_app`. Apps Python, Bash o C++ sin imgui quedan excluidas. Correcto para el hub. - **La ruta `dir_path` en registry.db es relativa a la raiz del registry**: la funcion la combina con `registry_root` para construir el path absoluto al `app.md`. Si una app tiene `dir_path` incorrecto en su `app.md`, el WARN indicara cual falló. - **TSV UTF-8**: el hub debe abrir el archivo con encoding UTF-8. Tabs y saltos de linea en los campos se limpian automaticamente (reemplazados por espacio). - **`display_name` es generado, no leido**: se deriva del `name` de la app convirtiendo snake_case a Title Case. No se puede personalizar desde el `app.md` en esta version. ## Capability growth log *(sin cambios desde v1.0.0)*