cc1e88fe55
Both issues delivered end-to-end: 0128 (backend, merged via dataforge/agents_and_robots/pulls/1): - HTTP daemon in cmd/launcher with apikey Bearer auth + SSE - LIVE at https://agents.organic-machine.com via Coolify Traefik + LE cert - systemd Restart=always - Unified status autodetect fix applied 0129 (frontend, merged via dataforge/agents_dashboard/pulls/1): - C++ ImGui app in projects/element_agents/apps/agents_dashboard - 4 panels: Connection / Agents / Logs / Status - secret_store_cpp_infra new function (DPAPI Windows / XOR Linux) - Deployed to Windows Desktop, App Hub tarjeta visible Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
181 lines
7.3 KiB
Markdown
181 lines
7.3 KiB
Markdown
---
|
|
id: "0129"
|
|
title: "agents_dashboard: C++ ImGui frontend para gestionar agentes Matrix"
|
|
status: pendiente
|
|
type: feature
|
|
domain:
|
|
- agents
|
|
- tui
|
|
scope: app
|
|
priority: alta
|
|
depends:
|
|
- "0128"
|
|
blocks: []
|
|
related: []
|
|
created: 2026-05-22
|
|
updated: 2026-05-22
|
|
tags: [cpp, imgui, agents, dashboard, sse, http-client]
|
|
dod_evidence_schema:
|
|
- id: scaffold_ok
|
|
kind: cmd
|
|
expected: "ls projects/element_agents/apps/agents_dashboard/{app.md,main.cpp,CMakeLists.txt,.git} todos existen"
|
|
required: true
|
|
- id: build_windows
|
|
kind: cmd
|
|
expected: "cmake --build cpp/build/windows --target agents_dashboard -j → exit 0"
|
|
required: true
|
|
- id: appicon_embedded
|
|
kind: cmd
|
|
expected: "x86_64-w64-mingw32-objdump -h cpp/build/windows/apps/agents_dashboard/agents_dashboard.exe | grep .rsrc"
|
|
required: true
|
|
- id: hub_card_visible
|
|
kind: screenshot
|
|
expected: "App Hub muestra tarjeta agents_dashboard con icono robot violeta + description correcta"
|
|
required: true
|
|
- id: connection_flow
|
|
kind: screenshot
|
|
expected: "Panel Connection con base_url + apikey input, LED verde tras handshake exitoso con backend"
|
|
required: true
|
|
- id: agents_table_populated
|
|
kind: screenshot
|
|
expected: "Tabla Agents muestra >=7 filas con id/status/uptime/msg_24h + botones accion"
|
|
required: true
|
|
- id: start_stop_works
|
|
kind: screenshot
|
|
expected: "Click stop sobre test-bot lo apaga (status cambia a stopped en menos de 2s); click start lo reinicia"
|
|
required: true
|
|
- id: logs_sse_streaming
|
|
kind: screenshot
|
|
expected: "Panel Logs streamea lineas en vivo de assistant-bot (lineas nuevas aparecen sin pulsar refresh)"
|
|
required: true
|
|
- id: apikey_encrypted_local
|
|
kind: cmd
|
|
expected: "strings cpp/build/windows/apps/agents_dashboard/local_files/agents_dashboard.db | grep -v '<plaintext apikey>' (apikey no aparece en claro)"
|
|
required: true
|
|
- id: e2e_self_test
|
|
kind: cmd
|
|
expected: "agents_dashboard.exe --self-test exit 0 (verifica subsistemas: GL loader, http client, SSE client, DB local)"
|
|
required: true
|
|
---
|
|
|
|
# 0129 — agents_dashboard C++ ImGui frontend
|
|
|
|
## Contexto
|
|
|
|
Cuando 0128 cierre, el backend `agents_and_robots` expondra HTTPS API + SSE en `agents.organic-machine.com` con apikey. Necesitamos frontend local C++ ImGui que consuma esa API y permita gestionar agentes sin SSH ni terminal.
|
|
|
|
## Decision
|
|
|
|
C++ ImGui app en `projects/element_agents/apps/agents_dashboard/`. Sub-repo Gitea `dataforge/agents_dashboard`. Integrada en App Hub con icono propio.
|
|
|
|
Scope v0.1 = lo que 0128 expone: list + start/stop/restart + logs SSE. v0.2 anade send-message + config-edit cuando backend los exponga.
|
|
|
|
## Tareas
|
|
|
|
### 1. Scaffold (REGLA: scaffolder canonico, NUNCA a mano)
|
|
|
|
```bash
|
|
./fn run init_cpp_app agents_dashboard \
|
|
--project element_agents \
|
|
--desc "Frontend C++ ImGui para gestionar agentes Matrix de agents_and_robots via HTTPS+apikey, SSE para logs/status en vivo"
|
|
```
|
|
|
|
Tras scaffold:
|
|
- `git init` dentro de `projects/element_agents/apps/agents_dashboard/` (regla `apps_subrepo.md`).
|
|
- Trio `app.md`: `description` + `icon.phosphor: "robot"` + `icon.accent: "#8b5cf6"`.
|
|
- `./fn run regenerate_app_icons agents_dashboard`.
|
|
- `./fn run refresh_app_hub` para que aparezca en el hub.
|
|
|
|
### 2. Funciones del registry — buscar primero
|
|
|
|
| Necesidad | Buscar en registry | Si falta |
|
|
|---|---|---|
|
|
| HTTP client C++ (sync GET/POST + Bearer + JSON body) | `mcp__registry__fn_search query="http client" lang="cpp"` | Delegar `fn-constructor`: `http_client_cpp_infra` con libcurl |
|
|
| SSE client C++ | `sse_client_cpp_core` (FRESH 7d) | ✓ reuso directo |
|
|
| JSON parse/serialize C++ | buscar nlohmann wrapper | Si falta, vendoring `cpp/vendor/json.hpp` (single-header) |
|
|
| Data table | `data_table_cpp_viz` | ✓ reuso |
|
|
| Secret store local (DPAPI Windows) | buscar | Si falta: `secret_store_cpp_infra` (DPAPI wrap, base64 fallback Linux) |
|
|
| Ring buffer C++ | buscar | Si falta: `ring_buffer_cpp_core` |
|
|
|
|
Delegacion paralela: **una sola llamada Agent con N tool_use blocks paralelos** para las que falten (regla `delegation.md`).
|
|
|
|
### 3. Paneles UI
|
|
|
|
- **Connection** — `base_url` input + apikey input (mask) + boton "Test" → GET /health + GET /agents. LED estado SSE (gris/amarillo/verde/rojo). Save credentials en `local_files/agents_dashboard.db` encriptadas via secret_store.
|
|
- **Agents** — `data_table_cpp_viz` con cols:
|
|
- id (texto)
|
|
- status (icono colored: running=green, stopped=gray, crashed=red)
|
|
- uptime (humanized)
|
|
- msg_24h (numero)
|
|
- actions (botones `▶ ⏹ ↻` por fila)
|
|
- Filtro por substring + sort por col.
|
|
- **Logs** — selector agente (combo) + tail viewport (ring buffer 5000 lineas) + autoscroll toggle + boton "Pause". Stream via `/sse/agents/{id}/logs`.
|
|
- **Status feed** — panel collapsible con eventos del `/sse/status` (timeline reciente).
|
|
|
|
### 4. Persistencia local
|
|
|
|
- `<exe_dir>/local_files/agents_dashboard.db` (SQLite via funciones del registry o sqlite3 directo).
|
|
- Schema migraciones en `migrations/001_init.sql`:
|
|
```sql
|
|
CREATE TABLE connections (
|
|
id INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
base_url TEXT NOT NULL,
|
|
apikey_encrypted BLOB NOT NULL,
|
|
last_used DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
CREATE TABLE app_state (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT
|
|
);
|
|
```
|
|
- `app_settings.ini` via `fn_ui::settings_*` (theme, layout).
|
|
- apikey cifrada con DPAPI Windows (clave nunca abandona la maquina).
|
|
|
|
### 5. Build + deploy local
|
|
|
|
- CMake target `agents_dashboard` en `cpp/CMakeLists.txt` (auto via scaffolder).
|
|
- Build Windows: `cmake --build cpp/build/windows --target agents_dashboard -j`.
|
|
- Deploy local: `./fn run redeploy_cpp_app_windows agents_dashboard projects/element_agents/apps/agents_dashboard --build`.
|
|
- Icono via windres (gestionado por `add_imgui_app`).
|
|
|
|
### 6. Tests + e2e_checks
|
|
|
|
```yaml
|
|
e2e_checks:
|
|
- id: build
|
|
cmd: "cmake --build cpp/build/windows --target agents_dashboard -j"
|
|
timeout_s: 180
|
|
- id: self_test
|
|
cmd: "./cpp/build/windows/apps/agents_dashboard/agents_dashboard.exe --self-test"
|
|
timeout_s: 30
|
|
- id: pytest_mock
|
|
cmd: "cd projects/element_agents/apps/agents_dashboard/tests && python3 -m pytest -x -q"
|
|
timeout_s: 60
|
|
```
|
|
|
|
Mock server pytest emula 0128 (list/start/stop + SSE) y verifica que la app C++ conecta + popula tabla + start/stop funciona en headless con `--capture` mode.
|
|
|
|
## Acceptance
|
|
|
|
- [ ] App arranca, muestra Connection panel.
|
|
- [ ] Tras meter apikey valida → tabla Agents populated con datos reales de VPS.
|
|
- [ ] Stop/Start desde UI cambia estado real del agente en VPS.
|
|
- [ ] Logs streamea lineas nuevas sin polling.
|
|
- [ ] Cerrar y reabrir app → credentials persisten (cifradas).
|
|
- [ ] Sin red / apikey invalida → error visible, app no crashea.
|
|
- [ ] `--self-test` exit 0.
|
|
- [ ] Visible en App Hub con icono + description correctos.
|
|
|
|
## DoD humano
|
|
|
|
- **Donde:** Windows Desktop → App Hub → Click "agents_dashboard".
|
|
- **Latencia:** logs SSE < 1s lag. Lista agents < 200ms tras handshake.
|
|
- **Onboarding:** First-run wizard pide base_url + apikey; tooltip explica donde obtener la key (gestor de secretos del VPS).
|
|
|
|
## Riesgos
|
|
|
|
- libcurl en Windows mingw-w64: cross-compile setup. Si `http_client_cpp_infra` no existe, dedicar tiempo al wrapper antes de UI.
|
|
- DPAPI solo Windows: fallback Linux puede ser texto plano con permisos 0600 + warning visible en UI.
|
|
- SSE reconnect logic: backoff exponencial + indicador de estado claro.
|