- 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>
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>
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>
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.
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).
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.
- 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.
- 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.
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.
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).
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.
- 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].
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.
Sustituye ~30 lineas de cableado manual de save/load/list/delete contra
layout_storage_sqlite por dos llamadas a la nueva API publica:
g_layouts = fn_ui::layout_storage_open("shaders_lab.db");
fn_ui::layout_storage_make_callbacks(g_layouts, g_layout_cb);
El blob pendiente lo gestiona el storage (layout_storage_apply_pending).
on_reset se override para ademas re-mostrar los paneles de shaders_lab.
La tabla ui_layouts heredada queda intacta — la nueva API usa
imgui_layouts en la misma BD.
Documenta la convencion de uses_functions para C++:
- El indexer no deduce automaticamente las dependencias C++
- El .md del consumidor declara las dependencias
- Framework (cpp/framework/) y apps (cpp/apps/) no se registran en
uses_functions; se anotan en notes: del huerfano
Tambien indexada en .claude/rules/INDEX.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>