Files
fn_registry/dev/issues/0099-datahub-app-launcher.md
T

8.4 KiB

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

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// — 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)

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.