f0d8a5ad04
NodeGroups window kind=Group ahora expone un boton SmallButton(TI_ARROW_UP) por fila que saca la entidad del grupo (group_id = NULL) y dispara reload del grafo. kind=Table mantiene el comportamiento de issue 0011. - entity_ops: nueva op `entity_clear_group_id(db, id)` idempotente. Si la columna group_id no existe (BD pre-0035a) retorna true como no-op. Falla solo si la entidad no existe o SQLite revienta. - views.cpp: extra columna "promote" en kind=Group, tooltip header diferenciado por kind, boton conectado a app.want_clear_group_id_entity. - main.cpp: handler que ejecuta entity_clear_group_id, marca windows como dirty, llama reload_after_mutation y loguea `[node_groups] promoted X out of group`. - gx-cli: flag `node update --clear-group-id` (booleano) y exposicion MCP en inputSchema + MCP_DISPATCH defaults para que el agente Echo pueda promover via tool calls. - tests: 3 nuevos CLI (clear, idempotente, combinable con --name) y 4 MCP (defaults, schema, dispatch end-to-end, idempotente). WSL: 102 passed (95 base + 7). Windows: 91 passed, 11 skipped (84 base + 7). Refs: issues/0036d-promote-kind-aware.md
2.5 KiB
2.5 KiB
id, title, status, priority, created, parent, depends_on
| id | title | status | priority | created | parent | depends_on | |
|---|---|---|---|---|---|---|---|
| 0036d | Promote en NodeGroups ramificado por kind (Table row vs Group child) | done | high | 2026-05-04 | 0036 |
|
Objetivo
Boton "Promote" por fila en la NodeGroups window. La accion se
ramifica por kind:
- kind = Table (DuckDB row): comportamiento actual del issue 0011 — INSERT entity nueva apuntando a la fila DuckDB. Idempotente: si ya existe entidad para ese row_id, no duplica.
- kind = Group (entidad hija): UPDATE clear group_id. La entidad sale del grupo y aparece como nodo libre en el canvas tras reload.
Cambios
Nueva op en entity_ops (Group promote)
// Saca la entidad de su grupo (group_id = NULL). No-op si ya estaba
// fuera (group_id ya era NULL). Idempotente.
bool entity_clear_group_id(const char* db_path, const char* entity_id);
Tambien anyadir su pareja MCP en gx-cli:
gx-cli node update <id> --clear-group-id
(Para que el agente Echo pueda promover entidades del grupo via MCP. Argumento booleano que dispara la op directa, sin pasar por el flujo de --notes/--name.)
Render del boton Promote
En la pintura de la window (en views.cpp), por cada fila visible
mostrar un SmallButton(TI_ARROW_UP) con tooltip:
- kind = Table:
"Promote row to entity"— comportamiento existente. - kind = Group:
"Promote out of group (move to canvas)"— llama a la nueva op.
Tras la accion, marcar g_app.want_reload = true para que el grafo
se refresque y la entidad reaparezca suelta.
Tooltip del header
Cuando entras a la window, mostrar un texto suave indicando el comportamiento del Promote segun kind. Una sola linea, color text muted.
Acceptance criteria
- Click promote en row de Group: la entidad pierde
group_id(verificable por SQL), reload del grafo la muestra suelta colgando del source via la relacion existente. - Click promote en row de Group ya promovida (group_id ya NULL): no-op sin error.
- Click promote en row de Table: comportamiento como hoy. Sin regresion en flow existente.
- Tooltip diferenciado entre kinds.
- Tests pytest:
test_entity_clear_group_id_removes_membershiptest_entity_clear_group_id_idempotenttest_gx_cli_node_update_clear_group_id(CLI)- MCP regression:
clear_group_iden defaults
TBD
Branch issue/0036d-promote-kind-aware, merge --no-ff a master.
Out of scope
- Promote masivo (multi-select) — fase 2.
- Re-agrupar por tipo (multi-select dentro de NodeGroups window) — fase 2.