Change 1 — Columnar Snapshot Internal:
- Add ColumnSnapshot struct (type + str_ids/i64/f64 per column) in data_table_internal.h
- Add SnapshotCache struct with pointer-identity sentinel (last_cells_ptr)
- Add SnapshotCache field to UiState singleton
- In render(): rebuild snapshot after join materialization when cells ptr changes
Uses same pointer-identity pattern as existing stats_last_cells in State
Int/Float columns parsed once via parse_number; String/Auto interned
Change 2 — String Interning:
- Add StringPool struct (strings + unordered_map<string_view, uint32_t>) to data_table_types.h
- StringPool is per-State (NOT global) for table isolation
- intern(sv) inserts if absent, returns stable uint32_t index
- Cleared + rebuilt on each snapshot rebuild for index coherence
- Add string_pool field to State struct
Documentation:
- Extended header comment in data_table_internal.h describing design,
StringPool API, invariants (pointer-identity, row→snapshot_row),
and how stats_last_cells and snapshot coexist independently
Build: fn_module_data_table + tables_qa pass, no new errors (only
pre-existing -Wformat-truncation warnings unrelated to this change).
Public API (data_table.h, TableInput, render() signature) unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
POSIX popen routes via /bin/sh -c, so "2>&1" is a shell redirect. On
Windows we use CreateProcessW directly (no shell): curl receives "2>&1"
as a positional arg, treats it as a second URL, and fails with exit 3
"URL rejected: Bad hostname".
Stderr is already merged into the same pipe via STARTUPINFOW.hStdError
on Windows, so the redirect is also unnecessary there. Guard with
#ifndef _WIN32.
Also adds FN_HTTP_DEBUG env var to dump the cmdline + req.url for
future bug triage (zero-cost when unset).
Detected via agents_dashboard.exe --connect-test against
https://agents.organic-machine.com — same .exe with the fix now returns
"OK 11" in <2s.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DPAPI Windows + XOR Linux fallback para almacenar credentials sensibles
en SQLite local. Usado por agents_dashboard para cifrar apikeys.
Incluye encrypt/decrypt/is_strong + base64 helpers.
Issue: 0129
Co-Authored-By: fn-constructor <noreply@fn-registry.local>
Gitea repo dataforge/kanban_cpp archived (read-only).
Local apps/kanban_cpp/ deleted, CMake subdir registration removed.
registry.db entry + pc_locations row purged (regenerable via fn index +
manual delete since indexer upserts but does not purge orphaned apps).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WIP previo al lanzamiento de fn-orquestador piloto.
Commit como baseline para que /autonomous-task 0120 arranque con master limpio.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cliente Server-Sent Events C++ reusable (fn_sse::Client) con background
thread, exponential backoff, Last-Event-ID y stop() que no bloquea.
Implementacion clave: fork+execvp curl directamente (sin /bin/sh wrapper)
para tener el PID real del proceso curl en curl_pid_, lo que permite que
stop() → kill(SIGTERM) → fgets NULL → join() funcione sin bloqueo.
4 tests (Catch2): connect_and_receive_3_events, parse_event_field,
reconnect_on_disconnect, stop_kills_thread. Fixture Python SSE con
/health probe via http_request_cpp_core.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds add_subdirectory block for apps/kanban_cpp (lives in apps/ per issue
0096). The app itself is a sub-repo (gitignored via apps/*/), with its own
git history and master branch initialized.
Six panels reuse registry: http_request_cpp_core, kpi_card_cpp_viz,
sparkline_cpp_viz, agent_runs_timeline_cpp_viz, dod_evidence_panel_cpp_viz.
Backend Go on :8403 (independent operations.db from kanban_web).
Issue 0118.
fn_viz::render_agent_runs_timeline(TimelineState&):
- Filtros: multi-select apps, multi-select statuses, Since (days).
- Connection badge (● green / ◐ amber / ○ red) por state.connection_status.
- Tabla 7 cols: status icon | app chip | issue/card | branch | dod badge |
duration | started. Selectable SpanAllColumns dispara on_select callback.
- Footer: contadores per-status sobre el set completo.
Thread-safe: snapshot bajo runs_mutex al inicio del frame. SSE client
NO implementado — poll_sse_runs() es stub documentado en .md ## Gotchas.
Consumer puede usar http_request_cpp_core para polling fallback contra
GET /api/runs hasta que un endpoint /api/runs/stream estable aparezca.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ejemplo lanzable con DodPanelState mock + Cuando usarla (HITL DoD
validation) + Gotchas (screenshot stub, URL no validada, log read
each-frame, callbacks pueden mutar state, frame ImGui activo
requerido). Tag agents para capability group.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7 test cases via Catch2: count_status (3 escenarios incl. unknown
status y missing_required), find_evidence (2 lookup positivo/negativo)
y status_icon_id/status_color_token (mapeo de 4+2 keys). Linkamos solo
helpers — sin ImGui ni vendor extra.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DodItem/DodEvidence/DodPanelState + count_status/find_evidence/
status_icon_id/status_color_token. Sin ImGui — testeable en aislamiento.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1
del flow 0008 (kanban_cpp + agent_runner_api + DoD schema).
Incluye:
- dev/flows/0008-kanban-cpp-and-agent-workflows.md
- dev/issues/0112-0119*.md (7 sub-issues)
- WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Frontmatter + self-doc sections (Ejemplo, Cuando usarla, Gotchas) following
the contract in .claude/rules/function_growth_and_self_docs.md. Tags include
'http', 'client', 'curl', 'network', 'registry-gap', 'helper' so FTS surfaces
them when an agent asks for HTTP / fetch / GET / Bearer.
http_get_json declares uses_functions: [http_request_cpp_core] so the
dependency is auditable via mcp__registry__fn_uses.
Catch2-based tests that fork+exec a local python3 http.server fixture per
test binary. Covers:
http_request:
- GET 200 with body
- GET 404 (HTTP error != transport error)
- POST with body + Content-Type
- bearer_token shortcut adds Authorization: Bearer
- basic_user/basic_pass shortcut adds HTTP Basic (curl --user)
- invalid URL surfaces transport error (status=0)
- timeout_ms is honored (bails before server's 3s sleep)
http_get_json:
- parses 200 JSON body
- throws std::runtime_error on 404
- bearer_token reaches server (verified via echoed Authorization header)
- throws std::runtime_error on invalid JSON body
Tests skip gracefully if python3 isn't available (server.start() returns
false; SUCCEED with skip message). No external network required.
Local runs (Linux): 21 assertions / 7 cases (http_request), 6 / 4 (get_json),
all passing.
Promotes the inline curl-popen pattern duplicated across apps/services_monitor,
dag_engine_ui, data_factory into two reusable functions in cpp/functions/core/:
- http_request_cpp_core: generic HTTP client (GET/POST/PUT/DELETE/PATCH) via
cURL CLI through popen. Portable Linux/WSL/MinGW (no link-time libcurl).
Supports custom headers, raw body, Bearer/Basic auth shortcuts, timeout,
optional TLS verify skip. Returns status/body/headers/error/duration_ms.
- http_get_json_cpp_core: convenience wrapper over http_request — GET <url>,
expect 2xx, parse body as nlohmann::json. Throws std::runtime_error on
transport / non-2xx / parse failure.
Vendors nlohmann/json v3.11.3 single header at cpp/vendor/nlohmann/json.hpp
(MIT). No CMake target needed — header-only; consumers add
cpp/vendor/ to include path.
- Replace TextColored+glyph with ImDrawList::AddCircleFilled in CellRenderer::Dots.
Dots are now font-independent: no dependency on Unicode glyph coverage. Fixes
"dots show as ?" on Karla/Roboto/Inter fonts that lack Geometric Shapes block.
- dots_glyph_size now controls circle radius (px) instead of font scale.
- BadgeRule.label is ignored for Dots (documented in data_table_types.h + docs).
- data_table.md bumped to v1.3.1 with capability growth log entry.
- docs/capabilities/data_table_renderers.md: Dots section updated + Common pitfalls
entry added: "Asumir que cualquier glyph Unicode renderea".
- dag_engine_ui/tabs.cpp: removed stale "● glyph" comment from BadgeRule.
- Recompiled: dag_engine_ui, registry_dashboard, graph_explorer, navegator_dashboard,
odr_console. All 5 apps deployed to Desktop/apps/. Build Linux + tests 4/4 green.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PARTE A - CellRenderer::Dots (v1.3.0):
- Add Dots=8 to CellRenderer enum (data_table_types.h)
- Add dots_separator/dots_max/dots_show_count/dots_glyph_size fields to ColumnSpec
- Implement draw_cell_custom case Dots in data_table.cpp
- Parses comma-separated cell value into tokens
- Looks up each token in badges for color + optional glyph override
- Per-dot tooltip via tooltip_on_hover
- tql_emit: serialize renderer="dots" + dots_max/dots_show_count/dots_glyph_size/dots_separator
- tql_apply: deserialize all Dots fields
- tql_emit_test: +6 assertions (58 total, 0 failed)
- tql_apply_test: +8 assertions (114 total, 0 failed)
- test_column_specs: +2 tests (10/10 pass)
PARTE B - dag_engine_ui fix: 10 cols -> 6 cols (submodule commit 61314b7)
PARTE C - docs/capabilities/data_table_renderers.md:
- Update to v1.3.0
- Add decision tree for renderer selection
- Add CellRenderer::Dots section with canonical example
- Add Common pitfalls section (multiple columns, badge for free-text, etc.)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
apps/dag_engine/README.md cubre:
- Donde viven los DAGs y como apuntar el systemd unit.
- Workflow paso a paso para anadir uno nuevo (crear/validar/probar/recargar/verificar).
- Formato YAML completo: top-level fields + step fields + cron schedule + ejemplo de extremo a extremo (env, depends, retry_policy, continue_on, handlers).
- Comandos CLI (run/list/status/validate/server) + flags.
- 7 secciones de "que hacer si algo falla": DAG invisible, validation fail, step fallido, scheduler no dispara, WS disconnected, cleanup runs viejos, restaurar backup.
- Endpoints HTTP completos.
- Referencias a funciones del registry y commit de migracion.
app.md de dag_engine + dag_engine_ui apuntan a README.md.
gitlink dag_engine_ui actualizado a commit con app.md mejorado.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- executor.go: DagInfo anade LastRuns []store.DagRun. Pobla con e.store.ListRuns(name, 5, 0).
- cpp/apps/dag_engine_ui: gitlink al SHA con 5 puntitos R1..R5 via data_table BadgeRule.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- store/store.go: anade tags JSON lowercase a DagRun + DagStepResult para que REST y WS devuelvan misma forma.
- cpp/apps/dag_engine_ui: gitlink al SHA con http_client + data_http.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sub-repo Gitea: dataforge/dag_engine_ui (a crear cuando se ejecute /full-git-push).
Gitlink al SHA inicial del scaffolding.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Completa el batch de 20 type .md extraidos a cpp/types/core/ y
cpp/types/viz/ apuntando a cpp/functions/core/data_table_types.h.
Quedan 2 que faltaban en commits anteriores: DrillStep_cpp_core
(undo/redo de drills, fase 10) y FilterPreset_cpp_core (Last7/30/90d,
ExcludeNulls, NonZero, fase 10).
Total types indexados: 206. Tabla via mcp__registry__fn_search
"file_path:data_table_types" o sqlite SELECT por file_path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Apps que gestionan su propio LayoutStorage (cfg.auto_layouts=false +
cfg.layouts_cb=&own_cb) necesitan llamar layout_storage_apply_pending
en el momento correcto: despues de ImGui::NewFrame y ANTES de menubar
+ auto-dockspace + cualquier Begin() del frame.
Antes, si la app llamaba apply_pending dentro de render_fn (es decir,
mid-frame), ImGui cargaba el INI pero las dock-nodes no se restauraban
hasta el siguiente ciclo: las ventanas docked aparecian flotantes.
cfg.pre_frame es un std::function<void()> opcional que run_app y
run_app_test invocan justo despues de NewFrame, antes del bloque
auto_layouts_storage, antes de app_menubar y antes del auto-dockspace.
Default null = no-op, sin impacto en apps existentes.
Apps con auto_layouts=true (la mayoria) no necesitan tocar nada — el
framework ya hace apply_pending en su propio bloque. pre_frame es
puramente para apps con layout custom.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>