65 Commits

Author SHA1 Message Date
egutierrez c92ecf74ce fix(cpp): include <cstdint>/<cstddef> en data_table_types.h para portabilidad Linux
Los headers usaban uint8_t/uint32_t en enum-base-types (ColorRuleKind,
CellRenderer, TableEventKind) y en StringPool sin incluir <cstdint>/<cstddef>.
MSVC los arrastra transitivamente; GCC no, lo que rompia la compilacion del
modulo data_table y de toda app que lo enlaza (registry_dashboard, etc.) en
Linux nativo. Una sola cabecera afectada; el resto los obtiene transitivamente.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 23:00:10 +02:00
egutierrez 7913116a8e chore: auto-commit (129 archivos)
- .claude/agents/fn-analizador/SKILL.md
- .claude/agents/fn-constructor/SKILL.md
- .claude/agents/fn-executor/SKILL.md
- .claude/agents/fn-mejorador/SKILL.md
- .claude/agents/fn-orquestador/SKILL.md
- .claude/agents/fn-recopilador/SKILL.md
- .claude/commands/app.md
- .claude/commands/compile.md
- .claude/commands/cpp-app.md
- .claude/commands/create_functions.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 22:23:12 +02:00
egutierrez 3a8b4c2179 merge(0133): columnar snapshot + string pool + reader rewire (1+2+3)
Foundation (ce7470d5) + reader rewire (2f7fdd40).

- ColumnSnapshot per col (i64/f64/str_ids) + StringPool per-State
- compute_visible_rows filter/sort uses snapshot direct numeric/id compare
- StringPool realloc-crash fix (reserve before emplace_back)
- Pool staleness sentinel (rebuild when string_pool.size() drift)
- High-cardinality cap (>2048 unique → skip interning, fallback raw)

API publica intacta. Bench 100k sort_numeric +131% vs baseline.
text_editor_smoke RED preexisting unrelated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 00:22:38 +02:00
egutierrez 2f7fdd407b feat(0133-3): wire filter/sort readers to columnar snapshot
Change 3 of issue 0133 — rewire compute_visible_rows, filter eval,
and sort comparators to read from the SnapshotCache when available.

Hot paths rewired:
- compute_visible_rows (overload with snap): filter eval uses
  compare_snap (fast i64/f64 numeric compare for Int/Float cols;
  id-compare for low-cardinality string Eq/Neq; raw cells fallback
  for Contains/StartsWith/EndsWith).
- Sort comparators: direct i64/f64 array compare for Int/Float cols
  (goto sort_done skips string fallback); string sort uses uint32_t
  id compare with pool lookup only on mismatch.
- Stage>0 filter/sort: same snapshot overload.

Materialization paths (build_so, s0_backing, mat_backing, config popup)
kept on raw cells — they copy into std::string anyway, no benefit from
snapshot and snprintf-per-cell was 2M extra calls per frame.

Bug fixes (required for correctness):
1. StringPool::intern() realloc safety: force reserve before
   emplace_back so string_view keys in the map never go dangling.
2. SnapshotCache::pool_size_built sentinel: detects when a new State
   is created with an empty pool but same cells pointer (begin_scenario
   pattern). Prevents str_ids from indexing into an empty pool (SIGSEGV).
3. Cardinality cap (2048 uniques / 25% sample): high-cardinality string
   cols (timestamps-as-strings, UUIDs, names) skip interning — str_ids
   stays empty and compare_snap falls back to raw cells. Prevents 30MB+
   pool bloat that hurt cache for filter/sort on other cols.

Bench delta vs baseline (100k rows, LIBGL_ALWAYS_SOFTWARE=1):
  linear_scroll: 16.0 -> 15.5 fps p50  (-3%, baseline already FAIL)
  filter_like:   59.7 -> 56.0 fps p50  (-6%, still PASS at 56fps)
  sort_numeric:   3.9 ->  9.0 fps p50 (+131%, snapshot i64 sort)
  color_rule:    15.2 -> 14.8 fps p50  (-3%, baseline already FAIL)

Build: green for all 10 available Linux consumers (text_editor_smoke
linker failure is preexisting, not caused by this change).

API public intact. TableEvent.row indexing TableInput preserved.
Pointer-identity invalidation preserved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 00:21:09 +02:00
egutierrez ce7470d5f5 feat(0133-1+2): columnar snapshot + string interning in data_table
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>
2026-05-22 23:35:12 +02:00
egutierrez 07252c0172 feat(0132): cpp terminal_panel module + ansi_parser
Nuevo modulo reutilizable terminal_panel (fn_term) para ImGui:

Sub-fn ansi_parser_cpp_core (cpp/functions/core/):
- Parser ANSI/VT100 byte-a-byte sin heap allocs por evento
- SGR colores FG/BG 16-color + bold + reset
- Cursor moves CUU/CUD/CUF/CUB + CUP absoluto
- Erase ED(2)/EL(2), CR/LF/BS
- Statemachine 4 estados, thread-unsafe por diseno
- 21 tests unitarios (57 assertions), todos pasan

terminal_panel_cpp_viz (cpp/functions/viz/terminal_panel/):
- terminal_panel.cpp: render ImGui + process_output con list clipper
- terminal_panel_linux.cpp: forkpty + reader thread no-blocking
- terminal_panel_windows.cpp: ConPTY CreatePseudoConsole (SDK >= 17763)
- Scrollback circular configurable (default 5000 lineas)
- Toolbar: clear, copy, reset, scroll-lock + status indicator
- readonly mode: sin input box, send() es no-op
- uses_functions: ansi_parser_cpp_core, logger_cpp_core

Tests:
- test_ansi_parser.cpp: 21 test cases, 57 assertions (PASS)
- test_terminal_panel_smoke.cpp: 3 test cases (PASS: spawn echo hello,
  process exits cleanly, readonly ignores send)

CMake:
- cpp/tests/CMakeLists.txt: add test_ansi_parser + test_terminal_panel_smoke
- primitives_gallery (sub-repo): ver commit separado en apps/primitives_gallery

Pendiente (anti-scope v1):
- Windows ConPTY: stub funcional que compila; join() del reader thread
  via std::thread no implementado (usa CreateThread detached)
- ANSI 256/24-bit color, italics, Unicode wide
- Curses pesados (vim, htop, top) — cursor visible basic solo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:35:11 +02:00
egutierrez e387c91b4c fix(http_request): drop "2>&1" on Windows — CreateProcessW has no shell
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>
2026-05-22 22:15:37 +02:00
egutierrez a192ee0695 chore: baseline pre-piloto 0120 — apps_subrepo rule + http/sse hardening
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>
2026-05-18 21:40:52 +02:00
egutierrez eb57e83392 feat(cpp/core): sse_client_cpp_core — SSE client con reconnect + Last-Event-ID
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>
2026-05-18 19:59:50 +02:00
egutierrez 07503b8fff merge issue/0110: http_request_cpp_core + http_get_json_cpp_core
# Conflicts:
#	cpp/tests/CMakeLists.txt
2026-05-18 18:18:03 +02:00
egutierrez b9716a7cd6 chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
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>
2026-05-18 18:17:08 +02:00
egutierrez 1f73c18b8f docs(cpp/core): registry .md for http_request + http_get_json (issue 0110)
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.
2026-05-18 18:14:56 +02:00
egutierrez 1cdbe1bcd1 feat(cpp/core): add http_request + http_get_json helpers (issue 0110)
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.
2026-05-18 18:14:37 +02:00
egutierrez fad4006f60 feat(dev): issues 0100-0104 — dev_console binary + work_tab + DoD user-facing + frontmatter migration de 146 issues + taxonomia canonica
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 02:44:04 +02:00
egutierrez 6ad82167bb docs(flows): DoD obligatorio con user-facing surface + abrir issues 0100-0103 (taxonomia, frontmatter migration, dev_console, work dashboard)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 00:07:03 +02:00
egutierrez a03675113a chore: auto-commit (286 archivos)
- .claude/agents/fn-orquestador/SKILL.md
- .claude/commands/fn_claude.md
- .claude/rules/INDEX.md
- .claude/rules/cpp_apps.md
- .claude/rules/ids_naming.md
- CHANGELOG.md
- apps/dag_engine/README.md
- apps/dag_engine/api.go
- apps/dag_engine/dags_migrated/example.yaml
- apps/dag_engine/dags_migrated/example_lineage_tracking.yaml
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 16:33:22 +02:00
egutierrez 0b9af8f1bb data_table v1.3.1: Dots renderer via ImDrawList (font-independent) + recompile all apps with fn_table_viz (issue 0081-O.6)
- 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>
2026-05-15 17:35:22 +02:00
egutierrez 4acf6986d3 data_table v1.3.0: Dots renderer for status timelines + fix dag_engine_ui antipattern + pitfalls doc (issue 0081-O.5)
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>
2026-05-15 17:24:53 +02:00
egutierrez 97bd5ea056 data_table: Phase 2 — Button + events + tooltip + RightClick + TQL persist column_specs (issue 0081-O)
- CellRenderer::Button=5: renders SmallButton per cell; emits TableEvent::ButtonClick on click
- TableEventKind enum (ButtonClick/RowDoubleClick/RowRightClick/CellEdit) + TableEvent struct
- render() extended overload: adds events_out parameter (nullptr = back-compat, no events)
- RowDoubleClick and RowRightClick detection in raw table loop (stage 0)
- RowRightClick also detected in aggregated stage table (stage 1+)
- Tooltip per cell: tooltip_on_hover + tooltip fields on ColumnSpec; "auto" = show cell value
- State::aux_column_specs: TQL-persisted column specs sidecar per table
- tql_emit: serializes aux_column_specs[0] as column_specs block (badge/progress/duration/icon/button/tooltip)
- tql_apply: parses column_specs block back into state.aux_column_specs[0]
- render() merges aux_column_specs into TableInput when caller passes empty column_specs
- test_column_specs: 5->8 tests (Button struct, tooltip fields, both render() signatures link)
- tql_emit_test: 3 new tests (column_specs badge/button/tooltip emit) — 52 passed
- tql_apply_test: 3 new tests (column_specs badge/button/tooltip roundtrip) — 106 passed
- Back-compat: existing apps (graph_explorer, registry_dashboard) unchanged
- Version bump: data_table v1.1.0 -> v1.2.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:59:26 +02:00
egutierrez 7e2fb05144 data_table: declarative cell renderers Phase 1 (Badge/Progress/Duration/Icon)
Adds TableInput.column_specs sidecar field enabling apps to declare Badge,
Progress, Duration and Icon renderers per column without writing ImGui inline.
Back-compat: apps without column_specs compile and behave identically.

- data_table_types.h: CellRenderer enum, BadgeRule, IconMapEntry, ColumnSpec types
- data_table.cpp: hex_to_imcolor helper, icon_name_to_glyph static map (~30 Tabler icons),
  draw_cell_custom dispatcher, integration in Stage-0 and Stage-N cell loops and draw_extra_panel
- Bump version 1.0.0 -> 1.1.0 with capability growth log
- cpp/tests/test_column_specs.cpp: 5 smoke/linker tests (back-compat + 4 renderer types)
- cpp/tests/CMakeLists.txt: register test_column_specs target linked against fn_table_viz
- types/core/{cell_renderer,badge_rule,icon_map_entry,column_spec}.md: registry type mds
- docs/capabilities/data_table_renderers.md: canonical doc with end-to-end examples
- docs/capabilities/INDEX.md: added data-table-renderers group

All tests green: test_column_specs 5/5, test_fn_table_viz_smoke 8/8,
tql_emit 41/41, tql_apply 88/88, Wave-1 tests 8/8.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:38:24 +02:00
egutierrez 47fac22230 chore: auto-commit (799 archivos)
- .claude/CLAUDE.md
- .claude/commands/subagentes.md
- .claude/rules/INDEX.md
- .mcp.json
- bash/functions/cybersecurity/analyze_dns.md
- bash/functions/cybersecurity/audit_http_headers.md
- bash/functions/cybersecurity/audit_ssh_config.md
- bash/functions/cybersecurity/check_firewall.md
- bash/functions/cybersecurity/detect_suspicious_users.md
- bash/functions/cybersecurity/encrypt_file.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:28:20 +02:00
egutierrez e3c8979e8d chore: auto-commit (95 archivos)
- cmd/fn/doctor.go
- cmd/fn/main.go
- cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt
- cpp/apps/primitives_gallery/playground/tables/data_table.cpp
- cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp
- cpp/apps/primitives_gallery/playground/tables/data_table_logic.h
- cpp/apps/primitives_gallery/playground/tables/self_test.cpp
- cpp/apps/primitives_gallery/playground/tables/tql.cpp
- cpp/apps/primitives_gallery/playground/tables/viz.cpp
- cpp/apps/primitives_gallery/playground/tables/viz.h
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:50:34 +02:00
egutierrez 70c50a2229 asegurate de que subimos todo
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 03:10:00 +02:00
egutierrez cb6d9e61d1 feat(kotlin-compose): design system + 33 components + gallery_kt + e2e android emulator + scaffolder fixes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 16:28:50 +02:00
egutierrez 231d5d87a6 feat(infra): auto-commit con 11 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 13:30:27 +02:00
egutierrez 1bb4f2e0f8 fix(ui): notification popup horizontal oscillation
Tamano FIJO del popup (Always + SizeConstraints) y flags NoResize/NoMove
para evitar feedback loop entre auto-resize del popup y TextWrapped/SameLine
internos. Reemplaza GetWindowContentRegionMax() por offsets explicitos
calculados a partir del ancho fijo, ya que ese valor fluctua frame a frame
con padding/borders y provocaba el ensanche/encogido continuo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:12:50 +02:00
egutierrez 715e2431fc feat(cpp/core): parallel_for thread pool + slider widget
parallel_for_cpp_core: ThreadPool reutilizable con parallel_for(begin, end, fn)
y parallel_for_chunks(begin, end, fn(tid, lo, hi)). Captura excepciones del
worker y las relanza en el caller. Pareja CPU del despacho GPU para Monte
Carlo multi-core cuando dispatch GPU no compensa.

slider_cpp_core: wrapper de ImGui::SliderFloat/Int/Double con label muted
arriba, tokens (primary grab), full-width. Variantes float, float_log
(logaritmico), int, double. Para los calculadores que tienen 15-30 sliders
cada uno y se beneficia del estilo consistente.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 11:52:50 +02:00
egutierrez f1a5e04d4f feat(cpp/core): logger + log_window + selectable_text widgets
Logger global thread-safe con ring buffer in-memory de 2000 entradas + escritura
opcional a archivo. log_window flotante consume el ring buffer con filtros por
nivel, busqueda y autoscroll; se abre desde Settings -> Logs en la menubar.
selectable_text cubre el patron drag-to-select + Ctrl+C en cualquier ventana.

app_menubar y framework run_app integran log_window_render() en el frame loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 11:50:57 +02:00
egutierrez c5b2ec8ad6 feat(framework): assets/ subfolder para distribuibles read-only
Refina la convencion de layout: el top de cada app distribuible
solo lleva el .exe + DLLs nativas; todo lo demas (TTFs, enrichers,
runtime Python, MCP servers) vive en <exe_dir>/assets/.

Cambios:
- cpp/CMakeLists.txt::add_imgui_app — copia las 5 TTFs (Karla,
  Roboto, DroidSans, Cousine, tabler-icons) a
  $<TARGET_FILE_DIR>/assets/ en lugar de junto al exe.
- framework/app_base: nuevas funciones fn::asset_dir() y
  fn::asset_path(name) que resuelven a <exe_dir>/assets/<name>.
- functions/core/icon_font.cpp::find_asset — anade
  fn::asset_path(filename) como PRIMERA ruta de busqueda, antes
  de las legacy ./<file> y ./assets/<file>. Mantiene los
  fallbacks para dev (FN_ASSETS_DIR, FN_CPP_ROOT).
- .claude/commands/compile.md — el deploy a Desktop pone TTFs +
  enrichers/ + runtime/ + gx-cli en <DEST>/assets/. Solo .exe y
  DLLs nativas (duckdb.dll) quedan en el top. local_files/ se
  preserva si existe.

Layout final:
  Desktop/apps/<APP>/
  ├── <APP>.exe + *.dll          (binario + DLLs Windows)
  ├── assets/                    (read-only distribuible)
  │   ├── *.ttf, enrichers/, runtime/, gx-cli, ...
  └── local_files/               (per-PC, creado al primer arranque)

Esto cierra la separacion conceptual de la convencion: la carpeta
es trivial de zippear (solo .exe + assets/), el reset/sync es
trivial (local_files/), y todas las apps del registry adoptan el
mismo layout via fn_framework.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:50:33 +02:00
egutierrez f769928ffd feat(framework): convencion local_files/ — separacion distribuible vs estado
Toda app C++ basada en fn::run_app coloca sus archivos escribibles
bajo <exe_dir>/local_files/. Los distribuibles (.exe, dlls, ttfs,
enrichers/, runtime/) siguen junto al .exe. Esto deja la carpeta
distribuible limpia para zippear y separa con claridad lo que
viaja con la app de lo que el PC genera.

API publica en fn:: (cpp/framework/app_base.h):
  - exe_dir()                    directorio del ejecutable
  - local_dir()                  <exe_dir>/local_files/, creado on-demand
  - local_path(name)             <local_dir>/<name>
  - migrate_to_local_files(...)  mueve archivos viejos desde cwd/exe_dir

Cambios:
- run_app configura io.IniFilename = local_path("imgui.ini") y
  llama migrate_to_local_files(["imgui.ini","app_settings.ini"])
  antes de settings_load(). Migracion idempotente para PCs con
  instalacion previa.
- app_settings.cpp usa local_path("app_settings.ini") en lugar de
  hardcoded "app_settings.ini" relativo al cwd.
- cpp_apps.md §7 documenta la convencion como obligatoria. Las
  apps deben usar fn::local_path() para cualquier archivo
  escribible nuevo.

Beneficios:
- zip distribuible no se "ensucia" con .ini/.db generados al usar.
- reset trivial: borrar local_files/.
- backup/sync per-PC: solo local_files/ es propio del PC.
- elimina la mezcla de paths Linux/Windows que generaba bugs como
  "projects\\default\\operations.db" en builds cross-platform.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:32:55 +02:00
egutierrez 4f280f34d7 test(cpp): tests para sql_parse, process_state_machine, file_poll_diff 2026-04-28 23:58:40 +02:00
egutierrez f2521bd7d2 refactor(cpp/core): file_watcher usa file_poll_diff 2026-04-28 23:55:11 +02:00
egutierrez 02c9dd93e3 feat(cpp/core): añadir file_poll_diff pure 2026-04-28 23:53:49 +02:00
egutierrez 90e9593b20 refactor(cpp/core): process_runner usa process_state_machine 2026-04-28 23:53:08 +02:00
egutierrez 86a1e12204 feat(cpp/core): añadir process_state_machine pure 2026-04-28 23:52:37 +02:00
egutierrez 9a543b7502 refactor(cpp/core): sql_workbench usa sql_parse 2026-04-28 23:51:59 +02:00
egutierrez 24cd142814 feat(cpp/core): añadir sql_parse pure 2026-04-28 23:51:23 +02:00
egutierrez 54d9f1809f merge: issue/0047-cpp-tests-foundation — implementación paralela 2026-04-28 23:44:55 +02:00
egutierrez 0330aaedd0 merge: issue/0044-cpp-orphans-audit — implementación paralela 2026-04-28 23:44:52 +02:00
egutierrez 08e2b1280f merge: issue/0042-cpp-layout-storage-public — implementación paralela 2026-04-28 23:44:44 +02:00
egutierrez 7c86070cc6 docs(registry): tested:true + test_file_path en .md de primitivos
20 funciones C++ pasan de tested:false a tested:true con sus tests
correspondientes y test_file_path apuntando a cpp/tests/. Cubre 4 tests
reales (tween_curves, pie/kpi/bar math) y 16 placeholders (componentes
UI con tests visuales pendientes para 0048).

Coverage cpp pasa de 4% (3/81) a 28% (23/81).
2026-04-28 23:42:35 +02:00
egutierrez 5b73466bd4 chore(registry): notes en huerfanas usadas por framework/apps
Auditoria del issue 0044: anota en notes: el contexto de consumo de
huerfanos que no pueden registrarse en uses_functions porque sus
consumidores no son funciones del registry:
- consumido por cpp/framework/app_base.cpp (framework no indexado)
- consumido por cpp/apps/{shaders_lab,chart_demo,text_editor_smoke}/main.cpp
- scaffolding/demo en primitives_gallery

31 huerfanas anotadas. Las que quedan en uses_functions=[] tras esto
son hojas legitimas (no llaman a nada) o realmente sin uso (lista
DEAD reportada en el issue 0044).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 23:40:51 +02:00
egutierrez ee3c39ad25 chore(registry): añadir uses_functions a consumidores reales (core)
Auditoria del issue 0044: 17 archivos .md de cpp/functions/core/ con
uses_functions actualizado para reflejar las llamadas reales detectadas
mediante #include en sus .cpp/.h. Los huerfanos referenciados (tokens,
app_about, app_settings, layouts_menu, panel_menu, table_view,
text_editor, tween_curves, app_settings) ahora aparecen en el grafo de
dependencias del registry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 23:40:22 +02:00
egutierrez c659120f86 feat(cpp/core): añadir layout_storage publico (SQLite-backed LayoutCallbacks)
API publica con handle opaco LayoutStorage* que envuelve la persistencia
de layouts ImGui en SQLite. Cualquier app puede obtener un LayoutCallbacks
listo para app_menubar/layouts_menu_items con dos llamadas:

    auto* st = fn_ui::layout_storage_open("app.db");
    fn_ui::LayoutCallbacks cb;
    fn_ui::layout_storage_make_callbacks(st, cb);

Tabla SQLite imgui_layouts(name, ini, updated_at) creada con
CREATE TABLE IF NOT EXISTS para no chocar con tablas pre-existentes.
fn_framework ahora enlaza SQLite::SQLite3 para que cualquier app que use
el framework herede acceso a layout_storage sin trabajo extra.
2026-04-28 23:39:34 +02:00
egutierrez a99aa661a2 fix(cpp/viz,core): bell icon TI_BELL, candlestick Setup-inside-BeginPlot, pie legend, kpi sparkline a la derecha
- toast.cpp: TI_BELL en lugar de \xf0\x9f\x94\x94 (fuera del rango cargado por icon_font, renderizaba como ?)
- candlestick.cpp: SetupAxes/SetupAxisScale/SetupAxisLimits movidos dentro de BeginPlot/EndPlot — antes el plot desaparecia al entrar
- pie_chart.cpp: SetupLegend(East, Outside, NoButtons), eliminado NoLegend
- kpi_card.cpp: layout 2 cols con sparkline a la derecha centrado verticalmente
2026-04-28 23:38:51 +02:00
egutierrez ec81bf360d docs: ADR 0002 + CHANGELOG + reglas para dataforge/<name>+master
- docs/adr/0002-apps-analyses-as-dataforge-master.md: decision arquitectural
  con contexto, alternativas descartadas y cambios concretos del 2026-04-28.
- CHANGELOG.md: entrada 2026-04-28 con Added/Changed/Fixed.
- .claude/CLAUDE.md: nota sobre /full-git-push y dataforge/<name>+master.
- .claude/rules/apps_tbd.md: tronco unico master + init.defaultBranch.
- cpp/functions/core/app_menubar.md: notas del submenu Settings con About.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 22:41:55 +02:00
egutierrez 424e913566 feat(cpp,bash): app_about + Settings submenu, ensure_repo_synced pipeline
cpp/core: nuevo modulo app_about — ventana About con project/version/desc,
componible via about_window_set_info() en el init de la app y rendererizada
automaticamente por fn::run_app al final de cada frame.

app_menubar: el item top-level "Settings..." pasa a ser un BeginMenu
"Settings" con dos subitems: "Settings..." (existente) y "About..." (nuevo).

bash/infra: nueva pipeline ensure_repo_synced que compone gitea_create_repo
y gitea_push_directory para garantizar repo Gitea existente + sync de un
directorio local en una sola llamada idempotente.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 22:05:31 +02:00
egutierrez 2f6dea6ebd merge: issue/0032 — sql_workbench
# Conflicts:
#	cpp/apps/primitives_gallery/CMakeLists.txt
#	cpp/apps/primitives_gallery/demos.h
#	cpp/apps/primitives_gallery/main.cpp
2026-04-25 21:55:17 +02:00
egutierrez 25936dff79 merge: issue/0031 — animation curves (timeline + bezier_editor + tween_curves)
# Conflicts:
#	cpp/apps/primitives_gallery/CMakeLists.txt
2026-04-25 21:54:48 +02:00
egutierrez 4e19583a22 feat(core): orbit_camera — camara orbital pura (matrices view/proj + drag)
State minimal (azimuth, elevation, distance, fov, aspect, near/far).
orbit_camera_matrices: lookAt+perspective row-major float[16] (subir a
GL con transpose=GL_TRUE). orbit_camera_handle_drag: dx→azimuth,
dy→elevation (clamp ±π/2-eps), wheel→distance (clamp >0.1). Sin glm,
solo <cmath>.

issue 0029
2026-04-25 21:51:15 +02:00