feat(gx-cli): expone columna notes en node create/update

El agente Echo (chat panel + claude -p) usa gx-cli para todas las
mutaciones del grafo. Antes solo podia setear name/type/status/
description/tags — pero los enrichers nuevos split_sentences y
extract_iocs_text leen entities.notes (lo que se escribe en el panel
Note del Inspector). Sin este flag, el agente no podia darle texto
largo a un nodo para luego enricharlo.

Cambios:
- node create: --notes "..." (vacio por default).
- node update: --notes "..." (replace) + --append-notes (concat con
  doble newline como separador, util para acumular contexto sin
  pisar lo previo).

Smoke test: replace y append funcionan, default vacio sigue ok.
This commit is contained in:
2026-05-03 15:40:58 +02:00
parent e4524684d7
commit 9b9df496da
+22 -3
View File
@@ -136,13 +136,15 @@ def cmd_node_create(args) -> None:
ts = _now_iso()
src = "agent:gx-cli"
description = args.description or ""
notes = args.notes or ""
cn = _connect(_ops_db())
try:
cn.execute(
"INSERT INTO entities (id, name, type_ref, description, source, "
"created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
(new_id, name, type_ref, description, src, ts, ts),
"INSERT INTO entities (id, name, type_ref, description, notes, "
"source, created_at, updated_at) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
(new_id, name, type_ref, description, notes, src, ts, ts),
)
cn.commit()
except sqlite3.IntegrityError as e:
@@ -187,6 +189,14 @@ def cmd_node_update(args) -> None:
if args.description is not None:
sets.append("description = ?")
params.append(args.description)
if args.notes is not None:
if args.append_notes and args.notes:
sets.append("notes = COALESCE(notes, '') || ?")
# separador con doble newline para legibilidad si ya hay contenido
params.append("\n\n" + args.notes)
else:
sets.append("notes = ?")
params.append(args.notes)
if args.tags is not None:
try:
tags = json.loads(args.tags) if args.tags.startswith("[") \
@@ -946,6 +956,9 @@ def main() -> None:
sp.add_argument("--name", required=True)
sp.add_argument("--type")
sp.add_argument("--description")
sp.add_argument("--notes",
help="texto libre del nodo (panel Note del Inspector). "
"Es lo que leen split_sentences y extract_iocs_text.")
sp.set_defaults(fn=cmd_node_create)
sp = n.add_parser("delete")
sp.add_argument("id")
@@ -956,6 +969,12 @@ def main() -> None:
sp.add_argument("--type")
sp.add_argument("--status")
sp.add_argument("--description")
sp.add_argument("--notes",
help="reemplaza el contenido de notes (panel Note). "
"Combinable con --append-notes para acumular.")
sp.add_argument("--append-notes", action="store_true",
help="anade --notes al final de las notas existentes "
"en vez de reemplazarlas (separador: doble newline).")
sp.add_argument("--tags",
help='JSON array o "tag1,tag2" CSV')
sp.set_defaults(fn=cmd_node_update)