kg2cytoscape

Визуализация графа знаний из файла памяти в Cytoscape Desktop через CyREST (REST-API, порт 1234).

Скрипт читает JSONL-файл памяти, создаваемый эталонной реализацией сервера памяти Anthropic (Knowledge Graph Memory MCP Server), строит сеть «сущности + наблюдения + связи» и оформляет её так, чтобы граф читался с первого взгляда: цвет — по типу, размер — по числу связей, облака — по кластерам.

Возможности

  • Три раскладки: force-directed (дефолт), timeline (хронологическая лента по порядку наблюдений), clusters (облака AutoAnnotate по сущностям).
  • Инкрементальное обновление (--update): дописывает в уже нарисованную сеть только новые сущности/наблюдения/связи, не сдвигая существующие узлы, не меняя их цвета и раскладку.
  • Автослежение (--watch): при изменении файла памяти сеть обновляется сама (опрос mtime/размера с настраиваемым интервалом).
  • Визуальный язык: сущности — круги (цвет по типу, размер по степени), наблюдения — скруглённые квадраты (цвет родителя), подписи в тултипах, рёбра окрашены по типу связи.

Требования

  • Cytoscape 3.10.4 (запущен) с включённым приложением CyREST;
  • для режима clusters — плагин AutoAnnotate;
  • Node.js 18+ (используется встроенный fetch).

Быстрый старт

node kg2cytoscape.mjs example.jsonl                     # граф force-directed
node kg2cytoscape.mjs example.jsonl --layout timeline   # хронологическая лента
node kg2cytoscape.mjs example.jsonl --layout clusters   # облака по сущностям
node kg2cytoscape.mjs example.jsonl --filter resume     # только проект resume

Обновление по мере роста памяти:

node kg2cytoscape.mjs example.jsonl --update            # разовый инкремент
node kg2cytoscape.mjs example.jsonl --watch             # следить за файлом
node kg2cytoscape.mjs example.jsonl --watch --interval 3000

Опции

Опция Значение
--name <имя> имя сети в Cytoscape (дефолт — имя файла)
--layout <тип> force-directed | timeline | clusters
--host, --port адрес CyREST (дефолт localhost:1234)
--keep не удалять прежнюю сеть с тем же именем
--dry-run только разбор файла, без обращения к Cytoscape
--style <имя> имя стиля (дефолт KG Memory)
--update инкрементальная синхронизация с существующей сетью
--watch автослежение за файлом (не завершается, Ctrl+C — выход)
--interval <мс> период опроса файла в режиме --watch (дефолт 2000)
--filter <префикс> оставить только один проект по неймспейсу; можно повторять. Связанные соседи (другой проект, infra:*) подтягиваются на один шаг

Порядок аргументов свободный: --dry-run example.jsonl и example.jsonl --dry-run равнозначны.

Формат файла памяти

Файл памяти создаётся эталонной реализацией сервера памяти Anthropic (Knowledge Graph Memory MCP Server) — именно она пишет сущности и связи в формате {type:"entity"|"relation"}, который и читает этот скрипт. То есть формат входа — не наш собственный, а стандартный «memory» от Anthropic; при желании файл можно наполнить из любой другой системы, соблюдая ту же схему. Обезличенный пример — example.jsonl; личная рабочая память в репозиторий не входит.

JSONL, по одной записи в строке:

{"type":"entity","name":"project:alpha","entityType":"project","observations":["первое наблюдение","второе наблюдение"]}
{"type":"relation","from":"project:alpha","to":"file:main.ts","relationType":"depends_on"}
  • Каждое observation становится отдельным узлом-вершиной, связанным с сущностью ребром has_observation; порядок наблюдений = хронология.
  • Есть универсальный запасной разбор (id / source-target / триплеты «S | P | O»).

Файл скрипт только читает — повредить память невозможно.

Как это выглядит

Ниже — кадры, снятые из Cytoscape (CyREST, экспорт PNG) на синтетической памяти: сущности — круги (цвет по типу, размер по степени), наблюдения — квадраты, цвет наследуется от родителя.

1. Force-directed, небольшая память. Каждый «веер» — сущность со своими наблюдениями; крупнее круг — больше связей.

force-directed, малая сеть

2. Force-directed, большая память (115 сущностей, 470 узлов). Видно несколько независимых кластеров-проектов.

force-directed, большая сеть

3. Режим clusters, небольшая память. Облака AutoAnnotate вокруг каждой сущности, метка — частотные слова из её наблюдений.

clusters, малая сеть

4. Режим clusters, средняя память. Облака разведены, чтобы не накладываться; метки читаются.

clusters, средняя сеть

5. Режим timeline. Хронологическая лента: сущности выстроены по порядку наблюдений (колонка kg_order).

timeline

6. Инкрементальное обновление (--update). Слева — уже сложившийся граф, справа — новый проект zeta, дописанный в память: он появился отдельным кластером, а позиции существующих узлов не сдвинулись.

инкрементальное обновление

Визуальный язык

  • Сущности — круги, цвет по типу (палитра Tableau 10), диаметр в пикселях 24 + 9·√(степень). Здесь степень — число связей узла: у сущности это её наблюдения плюс смысловые связи. Базовые 24 px получает узел без связей, а каждое новое ребро добавляет тем меньше пикселей, чем их уже больше (корень сглаживает рост, чтобы крупные узлы не «раздувались»): 1 связь → 33 px, 4 → 42, 9 → 51, 16 → 60, 25 → 69. Наблюдения всегда 18 px.
  • Наблюдения — квадраты 18 px, цвет наследуют от родительской сущности.
  • Рёбра has_observation — тонкие и полупрозрачные; смысловые связи — толстые, цвет по типу связи.
  • Наведение на узел показывает тултип (тип, число наблюдений, текст, дата).

Навык memory-curator

В каталоге .agents/skills/memory-curator/ лежит навык в открытом формате Agent Skills (SKILL.md + скрипты). Он задаёт правила наполнения памяти MCP-сервера memory, чтобы граф получался читаемым: атомарные наблюдения, неймспейсы, набор типов сущностей и связей. Включает автономный линтер scripts/lint-memory.mjs (нужен только Node.js).

Навык переносим: агенты с поддержкой формата Agent Skills подхватывают его из .agents/skills/ прямо из репозитория. Для клиента с другой раскладкой каталог навыка достаточно скопировать в его хранилище скиллов.

Сопутствующие файлы

  • src/ — модули приложения (см. «Архитектура и модули»).
  • ROADMAP.md — планы развития (что сделано и что предстоит).
  • test/ — юнит-тесты (npm test).
  • package.json — метаданные и скрипт тестирования.
  • fake_kg.py — генератор тестового потока записей памяти (python fake_kg.py out.jsonl).
  • AGENTS.md — подробная документация: полная схема колонок kg_*, особенности CyREST 3.10.4, правила экранирования, режим clusters, известные ограничения.
  • example.jsonl — обезличенный пример файла памяти (вход); рабочая память memory.jsonl в репозиторий не входит.
  • .agents/skills/memory-curator/ — переносимый навык (формат Agent Skills) с правилами наполнения памяти и автономным линтером.

Архитектура и модули

Код разбит по уровням абстракции: сверху — сценарии, снизу — примитивы. Каждый модуль решает одну задачу и по возможности состоит из чистых функций (без ввода-вывода и сети), поэтому покрыт юнит-тестами (npm test).

Уровень Каталог Модули и назначение
L0 src/core/ text.mjs — обрезка строк, разбор даты наблюдения; escape.mjs — экранирование аргументов CyREST; log.mjs — единый формат сообщений.
L1 src/parse/ records.mjs — разбор отдельной записи (родной формат + универсальный); parse.mjs — чтение JSONL/JSON в сырой граф.
L2 src/graph/ model.mjs — дедупликация рёбер, степени, размеры, карта «наблюдение → родитель»; filter.mjs — срез графа по проекту с замыканием на один шаг (--filter); colors.mjs — палитры и подбор цветов; geometry.mjs — размещение узлов и разведение облаков.
L3 src/cyrest/ client.mjs — транспорт CyREST (сети, представления, координаты, рёбра); columns.mjs — таблицы атрибутов kg_*; style.mjs — визуальный стиль.
L4 src/usecases/ build.mjs — полная сборка сети; sync.mjs — инкрементальное обновление; watch.mjs — автослежение за файлом.
L5 kg2cytoscape.mjs, src/cli/ args.mjs — разбор аргументов; точка входа — оркестрация сценариев.

Поток данных: parse (текст → записи → сырой граф) → graph (модель, цвета, геометрия) → usecases (сценарий) → cyrest (запросы к Cytoscape). Логика каждого уровня описана в комментариях к модулям и в REFACTORING.md.

Тестирование

npm test        # юнит-тесты (встроенный node:test, без зависимостей)

Тесты покрывают чистые уровни (текст, экранирование, разбор, модель, цвета, геометрия, стиль, разбор аргументов, чтение рёбер/координат) — их можно запускать без Cytoscape.

Подробности

Вся «кухня» (внутренние колонки, поведение команд CyREST и AutoAnnotate, экранирование аргументов, подводные камни) описана в AGENTS.md — этот README намеренно остаётся кратким.

Лицензия

Unlicense — общественное достояние (public domain). Код можно использовать, изменять и распространять без ограничений, в том числе коммерчески, без указания авторства.