- entity_ops: EntityRowSnapshot.group_id + SQL con COALESCE(group_id,'')
+ deteccion via PRAGMA para BDs viejas sin la columna.
- views.h: TableRow.group_id + AppState.table_filter_group_id /
table_filter_group_name (RAM-only).
- main.cpp: dispatch en want_open_note — si type_ref == "Group", setea
filtro de grupo + abre panel Table en vez de Note. Reset de search
buf y col_filters al entrar al drill-in para que el usuario vea todo
el contenido del grupo.
- views.cpp: build_visible compone group_id con search/tabs/col_filters
(AND). types_present se reduce a tipos presentes en el grupo cuando
hay drill-in activo. Header pintado en amarillo con TI_FOLDER +
contador + boton "Clear group filter". Al cerrarse el panel se
limpia el filtro automaticamente.
Tests: pytest 35 passed (WSL) / 24 passed + 11 skipped (Windows).
Refs: issues/0035d-tableview-drill-in.md
- entity_ops: entity_list_rows (bulk pull id/name/type_ref/status/updated_at).
- AppState::TableRow + cache + filtros (search substring + show_all toggle).
- views_table: tabs por type_ref (alfabetico) o tabla unica con todos los
tipos. ImGui::BeginTable con sort + clipper para >10k filas. Click en
Selectable selecciona el nodo en el viewport (clear + add via
graph_viewport_*).
- views_table_refresh_indices: degree + node_idx por user_data hash.
- main.cpp: panel "Table" en g_panels; cache build tras load_input y
reload_after_mutation.
Issue 0008 — capa de datos para el Inspector editable:
- struct MetadataField {key, value_str, is_string} — pares de la
columna metadata. is_string distingue '"foo"' de literal (number,
bool). EntityRecord agrupa los campos editables (id, name, type_ref,
description, status, tags[], metadata[]).
- entity_load_full: SELECT name/type/desc/status/tags/metadata, parsea
JSON plano con un parser propio (evita arrastrar libs). Soporta
escapes basicos (\n \t \" \\\\ etc.; \uXXXX → '?').
- entity_update: un solo UPDATE con tags+metadata serializados a JSON.
Toca updated_at.
- entity_list_distinct_tags: usa json_each (SQLITE_ENABLE_JSON1) para
enumerar tags distintas — autocomplete del Inspector.
- Parser JSON plano: parse_string_array, parse_flat_object. Solo
objetos planos (sin nested objects/arrays excepto consumirlos como
literal). Suficiente para el caso del Inspector.
- Writer JSON: build_string_array, build_flat_object con escape
apropiado. Si is_string=false pero el valor no es literal valido,
se re-emite como string para no producir JSON invalido.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bug fixes
- ImGui ID conflict en menu Change type: dedup tipos del grafo +
defaults; PushID/PopID por entrada.
- Dockspace ya no tapa la toolbar: se posiciona 44 px por debajo, asi
las ventanas dockeadas al borde superior quedan bajo la barra de
filtros, no detras.
- Hover radius proporcional al tamaño visual del nodo: query espacial
amplio (24/zoom) + filtro fino por (radio_visual + 2 px) / zoom. El
tooltip solo se dispara si el raton esta efectivamente sobre el nodo.
Layout
- Default layout = grid (en vez de force) para que los grafos cargados
se distribuyan ordenadamente al abrir.
- Boton "Reset layout" en la toolbar: limpia NF_PINNED en todos los
nodos, resetea velocidades y reaplica el layout activo.
- Nodos recien creados (add_node, duplicate) caen en un anillo poisson
alrededor del centro de la vista, no en el origen. Posicion
determinista por user_data para que el mismo nodo no salte entre
reloads.
Notes (markdown)
- Panel "Note" (dockeable) abierto con doble click sobre un nodo.
- entity_get_notes / entity_set_notes en entity_ops sobre la columna
`notes` de operations.db (ya existente en el schema).
- Ctrl+S guarda. Cabecera muestra entity, type, id.
- Dockspace host (PassthruCentralNode) bajo la toolbar para que las
ventanas Viewport/Legend/Inspector/Stats puedan dockearse dentro de la
app principal.
- Toolbar: input "Add node" con auto-deteccion de tipo (text/email/
ip_address/url/domain/phone). Insert en operations.db + reload.
- Context menu (right-click sobre nodo): Change type, Duplicate, Delete,
submenu "Run enricher" (placeholder hasta issues 0001-0003).
- Inspector: vecinos ahora muestran etiqueta de relacion ("-> employs",
"<- owns") usando rel_types[].name como label de arista.
- Default relation label k_default_relation_name="RELATED_TO" para
relaciones creadas sin nombre semantico explicito.
- Indice EntityIndex (FNV1a hash -> sql id) reconstruido tras cada load
para resolver mutaciones desde el grafo en memoria.
Issues planteadas para iteraciones siguientes:
- 0001: chat con Claude sobre el grafo (HTTP + tool-use)
- 0002: enricher GLiNER+GLiREL desde nodo texto
- 0003: enricher web (fetch URL/dominio + extract text)
- 0004: vista tabla por tipo de entidad