---
id: "0099"
title: "datahub app (launcher central para todas las apps)"
status: pendiente
type: feature
domain:
  - apps-infra
scope: app-scoped
priority: alta
depends: []
blocks: []
related: []
created: 2026-05-17
updated: 2026-05-17
tags: []
---
# 0099 — datahub app (launcher central para todas las apps)

**Status:** pendiente
**Created:** 2026-05-16
**Type:** app
**Priority:** alta
**Depends:** 0096 (apps/ standard) — DONE, iconos .ico (2026-05-16) — DONE
**Blocks:** —

## Problema

Cada app C++ del registry vive como `.exe` standalone en `/mnt/c/Users/lucas/Desktop/apps/<app>/<app>.exe`. Para arrancar cualquiera hay que:

1. Abrir Explorer en Desktop/apps.
2. Entrar al subdir de la app.
3. Doble-click al `.exe`.

Multiplicado por 11+ apps el ratio "tiempo-de-encontrar / tiempo-de-uso" es alto. Ademas:

- Nada indica si la app ya esta corriendo (PID, mem).
- Nada permite verla actualizada (rebuild + redeploy desde la UI).
- Sin descripcion/categoria visible — solo el nombre del exe + icono.

## Objetivo v1

App C++ ImGui standalone `apps/datahub/` que actua como **launcher central**:

1. **Catalogo de apps** desde `registry.db` tabla `apps` con `lang='cpp'` (y opcionalmente `lang='go'` con `framework='cli'`). Una card / fila por app con:
   - **Icono** (`<app_dir>/appicon.ico` rasterizado a textura GL — reusar `gl_texture_load`).
   - **Nombre** + descripcion del frontmatter.
   - **Tags** (chips: `service`, `gfx`, `tui`, `tools`, ...).
   - **Estado**: stopped / running (PID + mem via `is_cpp_app_running_windows_bash_infra`).
   - **Botones**: Launch / Stop / Redeploy / Open dir.
2. **Filtro**: por dominio (`tools`, `gfx`, `tui`, `infra`, ...), por tag (`service`, ...), por texto.
3. **Live updates**: polling cada 2s al status del proceso. WS opcional si pesa demasiado el polling de 11 procesos.
4. **Logs**: cada launch redirige stdout/stderr a `Desktop/apps/<app>/launch.log`. Boton `Tail log` abre panel lateral con ultimas 200 lineas.

## Fuera de v1

- **Programar launches** (cron / schedule) — separar a issue distinto.
- **Auto-update**: rebuild background al detectar `.exe` cambiado — v2.
- **Multi-PC**: solo PC local. Sin remote control.
- **Apps no-C++** (Go services, Python pipelines): listadas pero sin Launch button. Solo metadata.
- **Grafico de dependencias** entre apps (que app llama a que sqlite_api / dag_engine).

## Arquitectura

```
apps/datahub/
  app.md                       # frontmatter + e2e_checks
  CMakeLists.txt               # add_imgui_app(datahub ...)
  main.cpp                     # fn::run_app + render
  catalog.{cpp,h}              # lee registry.db apps via fn_match (SQLite read-only)
  process.{cpp,h}              # launch/stop/is_running (wrappers a is_cpp_app_running_windows + launch_cpp_app_windows)
  texture_cache.{cpp,h}        # carga .ico → GL texture (reusa gl_texture_load)
  tabs.{cpp,h}                 # Catalogo, Logs, Settings
  appicon.ico                  # icono propio (phosphor: 'squares-four' o 'app-window', accent #6366f1 indigo-500)
```

Fuente de verdad:
- **registry.db** (read-only) — catalogo de apps + paths + tags.
- **Disk Desktop/apps/<app>/** — verifica que esta desplegada antes de mostrar Launch.

No tiene operations.db propia v1 — el estado de procesos es volatil. Si en v2 queremos historial de launches → `apps/datahub/operations.db` con tabla `launches`.

## Fases

| Fase | Que entra |
|---|---|
| **A. Scaffold** | `fn run init_cpp_app datahub --desc "Launcher central de apps del registry"`. Mapping icono: phosphor `squares-four-fill` accent `#6366f1`. Genera `appicon.ico`. |
| **B. catalog.cpp — query registry.db** | SELECT id, name, description, tags, dir_path FROM apps WHERE lang='cpp' (read-only `?mode=ro`). Helper `list_cpp_apps()` → `std::vector<AppEntry>`. |
| **C. UI catalog** | ImGui table (data_table o BeginTable) con filas, columnas: Icon / Name / Desc / Tags / Status / Actions. Filter bar arriba (text + tag chips). |
| **D. Icon textures** | Reusa `gl_texture_load`. Cache `<id> → GLuint`. Lazy load primer frame visible. Fallback a icono generico si `<app_dir>/appicon.ico` falta. |
| **E. Process control** | Wrappers a `is_cpp_app_running_windows_bash_infra` (status) + `launch_cpp_app_windows_bash_infra` (start) + taskkill (stop). Async via `process_runner_cpp_core` para no bloquear UI. |
| **F. Log tail panel** | Click `Tail log` → panel lateral. Reusa `file_watcher_cpp_core` + `selectable_text_cpp_core`. |
| **G. Redeploy boton** | Click `Redeploy` → spawn `./fn run redeploy_cpp_app_windows <app> <dir> --build` en background. Progress en status bar. |
| **H. e2e_checks + deploy** | build_cmake, binary_exists, self-test (--list-apps imprime JSON con N apps), cpp_apps_conformance. `redeploy_cpp_app_windows datahub`. |

## Funciones del registry usadas (sin codigo nuevo esperado)

| ID | Para que |
|---|---|
| `is_cpp_app_running_windows_bash_infra` | Status de cada app |
| `launch_cpp_app_windows_bash_infra` | Launch button |
| `redeploy_cpp_app_windows_bash_pipelines` | Redeploy button |
| `gl_texture_load_cpp_gfx` | .ico → GLuint |
| `data_table_cpp_viz` | Tabla catalogo |
| `process_runner_cpp_core` | Async shell exec |
| `file_watcher_cpp_core` | Log tail |
| `selectable_text_cpp_core` | Render log lines |
| `app_menubar_cpp_core` | Menu bar (View / Help) |
| `layouts_menu_cpp_core` | Layouts persistentes |
| `sqlite_open_cpp_infra` (si existe; si no, abrir directo con sqlite3_open_v2 read-only) | Read registry.db |

## Posibles funciones nuevas a delegar

| ID propuesto | Lang | Que hace | Justificacion |
|---|---|---|---|
| `list_registry_apps_cpp_core` | cpp core | Lee `apps` table de registry.db (read-only), devuelve `std::vector<AppEntry>`. | Reusable: datahub + cualquier dashboard futuro que liste apps. |
| `app_status_windows_cpp_core` | cpp core | Wrapper sync sobre `is_cpp_app_running_windows`. Devuelve `{pid, mem_mb, running}`. | Hoy solo existe como bash. Para C++ ImGui hace falta wrapper que parse el output. |

Decidir en fase B/E si delegar a `fn-constructor` o si el codigo cabe inline en datahub (criterio: si patron se repite en otra app -> registry; si es unico → datahub-local).

## e2e_checks (borrador para fase H)

```yaml
e2e_checks:
  - id: build
    cmd: "cmake --build cpp/build/linux --target datahub -j"
    timeout_s: 300
  - id: binary_exists
    cmd: "test -f cpp/build/linux/apps/datahub/datahub"
  - id: self_test
    cmd: "./cpp/build/linux/apps/datahub/datahub --list-apps"
    expect_stdout_contains: '"name":'
    timeout_s: 15
  - id: cpp_conformance
    cmd: "./fn doctor cpp-apps --json | jq '.[] | select(.app_id==\"datahub_cpp_tools\")'"
```

## Aceptacion v1

- `datahub.exe` lanzable desde Desktop con icono propio (phosphor squares-four / indigo).
- Lista las 11 apps actuales C++ con icono, nombre, descripcion, tags, estado.
- Botones Launch / Stop / Redeploy funcionales.
- Filtro por texto + tag funciona.
- Tail log de una app corriendo se actualiza en vivo (file_watcher).
- `fn doctor cpp-apps` reporta datahub conformante.
- No bloquea UI al lanzar/parar/redeployar (todo async).

## Riesgos / decisiones

| Riesgo | Mitigacion |
|---|---|
| Polling 11 procesos cada 2s es caro (taskkill.exe + tasklist.exe) | Si pesa, batch en una sola llamada `tasklist /fi "imagename eq <app1>.exe or imagename eq <app2>.exe ..."` o WS endpoint en sqlite_api que publique status. |
| Icono `.ico` no se decodifica en GL (PIL → png intermedio?) | `gl_texture_load` ya soporta `.ico` via stb_image (verificar). Si no, convertir a PNG cache al primer load. |
| Redeploy desde la UI puede tardar minutos | Lanzar background + barra de progreso. Permitir cancel. Lock por app (evitar dos redeploys simultaneos). |
| App "Datahub" se confunde con "Data Factory" (issue 0097) | Datahub = launcher (proceso control). Data Factory = lineage de datos. Cero solape funcional. Documentar la distincion en ambos app.md. |

## Pendientes posteriores (v2+)

- Schedule launches (cron-like).
- Health KPIs agregados (apps_running / apps_total / cpu / mem total).
- Integracion con `dag_engine_ui` para lanzar DAGs como apps.
- Auto-discovery de apps no-C++ con `launch_command` declarado en frontmatter.
- Sync entre PCs: ver que apps tiene desplegadas el otro PC (pc_locations).

## Referencias

- Iconos `.ico`: ver `.claude/rules/cpp_apps.md §11` y `generate_app_icon_py_infra` (creada 2026-05-16).
- Patron list-apps + tabla: similar a `registry_dashboard` Monitor tab.
- Patron process control: replicar como `dag_engine_ui` orquesta runs.
