Commit Graph

475 Commits

Author SHA1 Message Date
egutierrez 09f7f0ba1c feat(datascience): GLiREL relation extractor (zero-shot triplets) drop-in con LLM
- glirel_load_model: cache por (model_name, device); device='auto' resuelve via torch
- extract_relations_glirel: tokeniza por whitespace, mapea spans char->token,
  llama predict_relations y devuelve RelationCandidate; fallback text.find si la
  entidad llega sin offsets; max_pairs=N -> top-N por score
- pyproject.toml: glirel en extra nlp

Closes #0039

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 16:41:09 +02:00
egutierrez 1bd315ce7b docs(issues): cerrar 0038 — GLiNER entity extractor
- Move dev/issues/0038-gliner-entity-extractor.md a completed/
- Update README link y estado a completado

Closes #0038

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 16:33:53 +02:00
egutierrez b15332686a test(datascience): corpus stub para gliner_load_model + extract_entities_gliner
11 tests sin necesidad de descargar el modelo (200 MB):
- StubModel duck-typed que valida el contrato de predict_entities
- Threshold y flat_ner se propagan al modelo
- Schema vacio lanza ValueError; schema sin labels validos warning + []
- Excepcion del modelo se captura
- Label desconocido se descarta
- gliner_load_model: ImportError simulado, cache hit, _resolve_device
  auto cae a cpu si torch no esta presente

Refs #0038

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 16:33:46 +02:00
egutierrez c663f9d6e8 feat(datascience): GLiNER entity extractor (zero-shot NER) drop-in con LLM
Funciones nuevas en python/functions/datascience/:
- gliner_load_model: carga + cachea modelo GLiNER por (name, device).
  device='auto' resuelve a cuda/cpu segun torch.cuda.is_available, sin
  fallar si torch no esta instalado. ImportError claro si falta gliner.
- extract_entities_gliner: contrato drop-in de extract_entities_llm
  (mismo entity_schema, mismo list[EntityCandidate]). El caller inyecta
  el modelo (cargado UNA vez por proceso). Anota offsets start/end en
  attributes para reconciliar con extract_iocs (issue 0040).

Diferencias vs LLM extractor:
- 50-200x mas rapido en GPU, 0 USD/token.
- Malo con IoCs tecnicos (lo cubre 0037).
- Threshold y flat_ner ajustables por dominio.

pyproject.toml: gliner como extra opcional `[nlp]` para no inflar el
.venv de quien no use NER. Instalacion: `uv pip install -e '.[nlp]'`.

Refs #0038 — Desbloquea 0039 (GLiREL) y 0040 (pipeline hibrido).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 16:33:38 +02:00
egutierrez 2cbf754620 docs(issues): cerrar 0037 — IoC regex extractor
- Move dev/issues/0037-ioc-regex-extractor.md a completed/
- Update README link y estado a completado
- Limpiar duplicado obsoleto de 0042 (ya estaba en completed/)

Closes #0037

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 16:24:25 +02:00
egutierrez 2b82b4b9ce test(cybersecurity): corpus para los 8 extractores + pipeline extract_iocs
30 tests cubriendo positivos y negativos por tipo:
- IPv4 valida/invalida + rangos limite
- IPv6 forma completa/comprimida
- Emails (caracteres validos en local part)
- Dominios con TLD valido vs desconocido
- Hashes MD5/SHA1/SHA256/SHA512 por longitud
- Wallets BTC legacy/bech32 y ETH
- CVEs 4 y 7 digitos
- MAC con `:` y `-` (separadores mezclados rechazados)
- Telefonos E.164 y ES local 9 digitos
- Pipeline filtrado por types y deduplicacion de spans contenidos

Refs #0037

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 16:24:18 +02:00
egutierrez 55dcdd1164 feat(cybersecurity): 8 IoC regex extractors + extract_iocs pipeline puro
Extractores nuevos en python/functions/cybersecurity/:
- extract_ip_addresses (IPv4 + IPv6 con validacion ipaddress)
- extract_emails (RFC 5322 simplificado)
- extract_domains (FQDNs con TLD valido, lista estatica)
- extract_file_hashes (MD5/SHA1/SHA256/SHA512, algoritmo por longitud)
- extract_crypto_wallets (BTC legacy + bech32, ETH 0x+40hex)
- extract_cve_ids (CVE-YYYY-NNNN+)
- extract_mac_addresses (xx:xx:xx + xx-xx-xx, separador uniforme)
- extract_phone_numbers (E.164 + ES local 9 digitos)

Pipeline:
- extract_iocs corre todos, deduplica spans contenidos. Mantiene
  purity:pure (kind:function con uses_functions no vacio) porque la
  regla del registry exige que los pipelines sean impuros.

Todas devuelven list[dict] con value/start/end/type para que el
caller (issues 0038-0040) pueda reconciliar offsets con spans NER
sin reparsing.

Refs #0037

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 16:24:11 +02:00
egutierrez 4cdd650502 feat(cpp/apps): bump versions — chart_demo 0.2, gallery 0.3, shaders_lab 0.3 2026-04-29 00:56:24 +02:00
egutierrez b7d44c0347 feat(cpp/framework): viewports=true por defecto en AppConfig — ventanas arrastrables fuera del main 2026-04-29 00:54:43 +02:00
egutierrez d7dab5eec5 fix(primitives_gallery): Windows mkdir() solo acepta el path en --capture 2026-04-29 00:31:53 +02:00
egutierrez 5851ac97cd docs(issues): cerrar 0046 — actualizar README 2026-04-29 00:31:10 +02:00
egutierrez c686780377 merge: issue/0046-cpp-refactor-raw-imgui — implementación paralela 2026-04-29 00:30:36 +02:00
egutierrez d3cf6d2774 docs: cerrar issue 0046 2026-04-29 00:29:54 +02:00
egutierrez c0e5bc711b refactor(shaders_lab): usar modal_dialog en save-as (issue 0046)
El modal Save-as-generator usaba BeginPopupModal + InputText + Button
crudo. Ahora usa fn_ui::modal_dialog_begin/end + fn_ui::text_input +
fn_ui::button del registry. El error inline usa fn_tokens::colors::error
en vez de ImVec4(1, 0.4, 0.4, 1). Anade modal_dialog.cpp, text_input.cpp
y button.cpp al CMakeLists del app.

Raw ImGui::Begin*/Selectable/BeginPopupModal: 11 -> 8.
2026-04-29 00:29:50 +02:00
egutierrez eae1829923 refactor(primitives_gallery): usar tree_view en sidebar (issue 0046)
El sidebar agrupaba demos por categoria con un Selectable+PushStyleColor
manual por item. Ahora usa fn_ui::tree_view con las categorias como
ramas (default-open via SetNextItemOpen + ImGuiCond_FirstUseEver) y las
demos como hojas seleccionables. Visualmente equivalente: separadores
por categoria, item activo coloreado.

Raw ImGui::Begin*/Selectable: 4 -> 3 (Selectable eliminado).
2026-04-29 00:29:44 +02:00
egutierrez 32927c5e9f docs(issues): cerrar 0048 — actualizar README 2026-04-29 00:20:13 +02:00
egutierrez 61ae9fde4b merge: issue/0048-cpp-visual-tests-ci-gate — implementación paralela 2026-04-29 00:19:37 +02:00
egutierrez 2ba71c6d79 docs: cerrar issue 0048 2026-04-29 00:18:58 +02:00
egutierrez 0fc30ae4dd docs(cpp): tests visuales y CI gate en PATTERNS.md
Nueva seccion "Tests visuales y CI gate (issue 0048)" describiendo:
- Como capturar/regenerar goldens con cpp/scripts/update_goldens.sh.
- Como diagnosticar un diff (PNG actual en cpp/build/tests/visual_actual/
  vs golden en cpp/tests/golden/).
- Cuando test_visual SKIPea (sin goldens, sin binario, sin GL).
- CI gate check_tested.sh y los pasos para satisfacerlo.

Issue 0048.
2026-04-29 00:18:51 +02:00
egutierrez 04d89ec8ae chore(cpp/scripts): update_goldens.sh y check_tested.sh
- update_goldens.sh: build primitives_gallery + lanza --capture sobre
  cpp/tests/golden/ con LIBGL_ALWAYS_SOFTWARE=1.
- check_tested.sh [days]: CI gate que falla si una funcion C++ creada en
  los ultimos N dias (default 30) no tiene tested:true en su .md. Hookeado
  al final de run_tests.sh. No-op si registry.db no existe.

Issue 0048.
2026-04-29 00:18:45 +02:00
egutierrez e750894847 feat(cpp/tests): test_visual con png diff vs goldens (skip si vacio)
- png_diff.{h,cpp}: pixel_diff_ratio(path_a, path_b, channel_threshold) con
  stb_image. Devuelve PngDiffResult con pixels_total, pixels_different y
  diff_ratio. Si dimensiones difieren, diff_ratio=1.0.
- test_visual.cpp: invoca primitives_gallery --capture sobre tmpdir, compara
  cada PNG vs cpp/tests/golden/<demo>.png con tolerancia 1% pixels distintos
  (threshold 5/255 por canal). SKIPea con WARN si:
  * golden dir vacio (no hay goldens todavia)
  * binario primitives_gallery no construido
  * el binario falla al capturar (entorno sin GL)
- CMakeLists: registra test_visual con FN_TEST_GOLDEN_DIR, FN_TEST_GALLERY_BIN,
  FN_TEST_TMP_DIR y FN_TEST_REPO_ROOT (para que la captura corra desde la
  raiz del repo y resuelva paths relativos como sql_workbench's registry.db).
- golden/: 41 PNGs iniciales generados en este entorno (WSL +
  LIBGL_ALWAYS_SOFTWARE=1). Pueden regenerarse con cpp/scripts/update_goldens.sh.

Issue 0048.
2026-04-29 00:18:39 +02:00
egutierrez 6be660fac6 feat(primitives_gallery): añadir --capture <dir> mode (offscreen render + glReadPixels)
Modo de captura que renderiza cada demo de la gallery en una ventana GLFW
invisible (GLFW_VISIBLE=GLFW_FALSE) y guarda PNG por demo via stb_image_write.

- capture.{h,cpp}: API gallery::run_capture(cfg, items) — warmup_frames,
  glReadPixels(GL_RGBA), flip vertical, stbi_write_png.
- main.cpp: parsea --capture <dir> antes de fn::run_app y delega a capture.cpp.
- vendor: stb_image_write.h v1.16 (mismo commit que stb_image.h).

Funciona en WSL con LIBGL_ALWAYS_SOFTWARE=1 (Mesa/llvmpipe). Si el entorno
no tiene contexto GL, el binario sale con rc!=0 sin generar PNGs.

Issue 0048.
2026-04-29 00:18:27 +02:00
egutierrez 98e134c935 docs(issues): cerrar 0043 — actualizar README 2026-04-29 00:10:25 +02:00
egutierrez cf8c602291 merge: issue/0043-cpp-apps-standardize-shell — implementación paralela 2026-04-29 00:09:43 +02:00
egutierrez ab3f1d442a docs: cerrar issue 0043 2026-04-29 00:08:56 +02:00
egutierrez 690b01e169 refactor(shaders_lab): usar AppConfig.panels + layouts_cb (issue 0043) 2026-04-29 00:08:40 +02:00
egutierrez 1b5d05dbaf refactor(primitives_gallery): usar AppConfig.about + init_gl_loader (issue 0043) 2026-04-29 00:06:51 +02:00
egutierrez 6bdcc98911 refactor(chart_demo): usar AppConfig.about (issue 0043) 2026-04-29 00:06:20 +02:00
egutierrez 98b7b460b8 docs(issues): cerrar 0045 — actualizar README 2026-04-29 00:00:56 +02:00
egutierrez 6286fdb9c7 merge: issue/0045-cpp-extract-pure-logic — implementación paralela 2026-04-28 23:59:45 +02:00
egutierrez 5a25095a54 docs: cerrar issue 0045 2026-04-28 23:59:08 +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 0cfaa27ee1 refactor(shaders_lab): extraer compile_* a compiler.{h,cpp} 2026-04-28 23:56:33 +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 6430e993c6 docs(issues): cerrar 0041, 0042, 0044, 0047 + actualizar README 2026-04-28 23:45:40 +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 eb5e3ef9ab merge: issue/0041-cpp-app-best-practices — implementación paralela 2026-04-28 23:44:24 +02:00
egutierrez 04ccf3f108 chore(cpp): script run_tests.sh para build+ctest one-shot 2026-04-28 23:42:38 +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 dfd73ec158 test(cpp): placeholders para top-19 primitivos UI (logica visual en 0048)
Cada placeholder garantiza que el .cpp compila y linka contra Catch2,
y reserva el slot para tests futuros una vez se extraiga logica pura
del componente. La validacion visual real vive en primitives_gallery
(issue 0048).

Cubre: tokens, button, select, text_input, badge, kpi_card, pie_chart,
bar_chart, tree_view, modal_dialog, toolbar, toast, empty_state,
page_header, dashboard_panel, dashboard_grid, sparkline, table_view,
icon_button.
2026-04-28 23:42:29 +02:00
egutierrez 0779c34ca8 test(cpp): tests reales para tween_curves, pie/kpi/bar math
- test_tween_curves: boundary conditions (t=0, t=0.5, t=1), monotonicidad
  para curvas no oscilantes, dispatch via apply(), names() no nulos.
- test_pie_chart_math: replica slice_at (anonymous namespace en pie_chart.cpp)
  y testea hit-test angular, edge del radio, distribucion proporcional.
- test_kpi_card_math: classify_delta (Up/Down/Flat) y pct_change con
  zero/negativos. La logica visual la cubre primitives_gallery (issue 0048).
- test_bar_chart_math: compute_y_range (incluye 0, negativos, vacio,
  single value) y clamp_bar_width [0.05, 1.0].
2026-04-28 23:42:22 +02:00
egutierrez 93a964a47d feat(cpp): integrar Catch2 en CMake con BUILD_TESTING + add_fn_test helper
cpp/tests/CMakeLists.txt compila Catch2 amalgamated como STATIC libreria
una sola vez. Cada test es su propio executable (CATCH_CONFIG_MAIN por
archivo) y se registra con add_test(). add_fn_test(name srcs...) es el
helper: incluye paths de cpp/functions y cpp/framework, linka catch2.

Tests que necesitan symbols reales (fn_framework, imgui) los anaden
explicitamente con target_link_libraries despues.
2026-04-28 23:42:14 +02:00
egutierrez 0585f851bb feat(cpp): vendor Catch2 v3.5.0 amalgamated
BSL-1.0. Single-header + single-source para tests con ctest.
2026-04-28 23:42:08 +02:00