Описывает стек и устройство компонентов. Детали реализации конкретного кода намеренно опущены — это видение, не имплементация.
- TypeScript на Node.js 24.
- MCP — официальный SDK (
@modelcontextprotocol/sdk), транспорт HTTP. - SQLite — встроенный
node:sqlite: синхронный (удобно для CLI и HTTP-сервера), без нативных бинарников — собирается кросс-платформенно, FTS5 в комплекте. - tree-sitter —
web-tree-sitter(WASM, без нативной сборки под каждую платформу) плюс WASM-грамматики нужных языков. - File watching —
chokidar, два независимых watcher'а. - Frontmatter —
gray-matter(разбор YAML-шапки заметок). - CLI —
commanderдля one-shot команд; TUI —Ink. - Векторный слой (
sqlite-vec) — отложен, схема остаётся совместимой.
Вся логика, не знает ни про MCP, ни про CLI:
- Note store — чтение/запись
.mdс frontmatter; атомарная запись (.tmp→ обновление индекса в транзакции → atomic rename). - Index layer — SQLite по схеме из
02, режим WAL, FTS5. - Structural indexer — tree-sitter; инкрементально по content hash.
- Search / ranking — отсечка членства +
weight × idf × text_relevance; термы текстового запроса стеммятся (вендорный русский Snowball) и матчатся префиксом — см.03. - Anchor verifier — резолв якорей:
symbol/file— SQL и stat,env— парсинг.env*,entity— реестр. - Watchers — два, с дебаунсом ~500 мс.
Тонкий фронтенд: 8 инструментов из 05, транслирует вызовы в core.
commander для команд + Ink для TUI-навигатора. Прямой фронтенд над core.
- Реконсиляция на старте контейнера. Сервис при запуске сравнивает content
hash файлов с
file_indexи переиндексирует расхождения — ловит правки, сделанные пока контейнер был выключен. CLI делает то же при своём запуске. - Бутстрап. При пустом индексе — полная индексация всего проекта.
- Watcher на код → изменённый файл переиндексируется tree-sitter'ом,
его символы в
symbol_indexпереписываются целиком (delete + insert). - Watcher на
.memory/→ изменённый.mdперечитывается, его строки в note-индексе и FTS обновляются. - Пересчёт
anchor_statusзатронутых якорей — при изменении кода, дёшево.
- Запись заметки атомарна: запись
.tmp→ транзакция SQLite → atomic rename. - Меж-процессный lock-файл в
.memory/на операции записи (CLI и MCP-сервер могут работать одновременно). - SQLite WAL — параллельные читатели при одном писателе.
- ID заметки генерирует сервер (короткий хэш) — на вход
create_noteне принимается. Replay-идемпотентности поidнет: каждыйcreate_noteсоздаёт новую заметку, коллизия хэша гасится ретраем генерации. Дедуп пересекающихся заметок — задача скилла (search→update_note), не писателя.
Отдельного конфиг-файла (.memory/config.yaml) нет — настраивать в проекте
нечего:
- Игнорируемые пути — индексатор уважает
.gitignoreпроекта (vendor/,node_modules/,storage/и т.п. уже там). Дизайн и так предполагает git. - Языки tree-sitter — определяются по расширению файла; набор
поддерживаемых — это грамматики, вшитые в сервис. Файл с неизвестным
расширением пропускается: его нет в
symbol_index, ноfile:-якоря на него работают. Vue SFC (.vue) — особый случай: собственной грамматики нет, индексатор извлекает блок(и)<script>/<script setup>и парсит их содержимое JS/TS-грамматикой со сдвигом строк, чтобыsymbol:-якоря на Vue-компоненты резолвились. - Коэффициенты ранжирования (множители весов, BM25-пол) — константы в core, подбираются эмпирически при разработке, не per-project.
Единственный параметр — корень индексируемого проекта — задаётся при
развёртывании (env-переменная и монтирование в docker-compose.yml), не
в .memory/. Нужен в основном разработчику системы, чтобы прогонять сервис
на разных проектах.
Каталог .memory/ содержит: notes/, entities.md, временный onboarding.md,
index.db (в .gitignore), lock-файл.
- memory-service — постоянный сервис в
docker-compose.ymlцелевого проекта, соседний с его контейнерами. Монтирует репозиторий (rw на.memory/, ro на остальное); корень проекта — env-переменная. - Транспорт MCP — HTTP: Claude Code из своего контейнера обращается
к сервису по compose-сети по имени (
http://memory:PORT). - Один контейнер на проект — свой
.memory/и свойindex.db. Dockerfileлежит в репозитории сервиса. В целевой проект добавляется блокserviceв егоdocker-compose.yml; образ собирается локально из SSH-клона приватного репозитория либо берётся из приватного Docker-реестра. Блок коммитится в проект — память «приезжает» вместе с ним.- CLI вызывается через
docker compose exec memory <команда>. .memory/*.mdиentities.md— в git;index.db(вместе с WAL-sidecar'амиindex.db-wal/index.db-shm) и lock-файл — в.gitignore.
- Векторный (семантический) поиск —
sqlite-vec. - Кейс B онбординга как отдельная машинерия (остаётся как guidance в скилле).