# memo Локальная библиотека заметок с семантическим поиском. > **Как этим пользоваться — [`MANUAL.md`](MANUAL.md).** Пошаговая инструкция для человека: > установка, команды, подключение к агенту, что мониторит демон, что можно удалять. > Остальной README — для разработки. **Markdown на диске — истина, `.db` рядом — пересобираемый кэш.** Агент (или человек) пишет и читает обычные `.md`-файлы своими штатными средствами: `memo` не требует ни специального API записи, ни изменения привычек. Он следит за файловой системой, держит рядом с каждой папкой-темой индекс (SQLite + sqlite-vec + FTS5) и отвечает на смысловые вопросы гибридным поиском (BM25 + вектор + RRF). ## Статус Реализовано и принято на эталонном корпусе. 38 тестов, мутационная проверка, сквозной recall@5 = 20/20. | Что | Вердикт приёмки | |---|---| | юнит-тесты всех модулей | ✅ | | мутационная проверка (13 мутаций) | ✅ все убиты | | индексация: 3 коллекции, повторный прогон — 0 обновлений | ✅ | | recall@5 на эталонном корпусе (sem 20/20, lex 3/3) | ✅ | | MCP-протокол живым клиентом + холодный старт | ✅ | ## Идея - Коллекций (папок-тем) — сколько угодно; они не мешают друг другу. - **Коллекция — каталог, в котором есть `*.md` напрямую** (не в подкаталогах). Вложенные папки без своих заметок коллекциями не считаются — иначе одни и те же файлы индексируются по нескольку раз. - Индекс каждой коллекции живёт в её `.memo/index.db` и **удаляется без потерь** — пересобирается. - Поиск — обычный read-only инструмент; записи в markdown он не делает никогда. - Только локально: эмбеддинг на CPU, сеть не нужна ни при индексации, ни при поиске. ## Состав (JVM-first, один Gradle-проект) ``` memo-cli # memo index|search|status — ручные проверки и приёмка без агента memo-core # чанкер по заголовкам, sqlite-схема, инкрементальная переиндексация, гибридный поиск memo-watch # демон: WatchService + debounce + реконсиляция по mtime memo-mcp # MCP-сервер (stdio): memo_search / memo_status / memo_reindex ``` `memo-core` не знает ни про watcher, ни про MCP — это драйверы поверх ядра. ## Быстрый старт ```bash ./gradlew installDist # собрать все дистрибутивы CLI=memo-cli/build/install/memo/bin/memo $CLI model # скачать модель (необязательно — скачается сама при первом запуске) $CLI index ~/notes # проиндексировать дерево (коллекции найдутся сами) $CLI search ~/notes "чем чинят карточку в jellyfin" $CLI search ~/notes "76.132" --mode lex --json $CLI status ~/notes ``` MCP-сервер (stdio), регистрируется как обычный MCP-сервер: ```json { "mcpServers": { "memo": { "command": "/opt/memo/memo-mcp", "env": { "MEMO_MODEL_DIR": "/opt/memo/models/siglip2" } } } } ``` Инструменты: `memo_search(path, query, k, mode)`, `memo_status(path)`, `memo_reindex(path)`. `memo_search` **сам создаёт индекс**, если его ещё нет — можно просто писать `.md` и сразу искать. Демон слежения (для правок мимо агента — людьми, git, сторонними редакторами): ```bash memo-watch/build/install/memo-watch/bin/memo-watch ~/notes ``` ## Приёмка ```bash bash scripts/accept.sh # полный прогон: сборка, тесты, мутации, индекс, recall, MCP bash scripts/accept.sh --fast # то же без мутационной проверки (самая долгая) ``` Правило проекта: **«зелёная сборка» ничего не доказывает.** Тесты проверяются мутациями (`e2e/mutations.tsv`): боевой код ломается, и нужный тест обязан упасть. Выжившая мутация — дыра в покрытии, а не удача. Приёмка идёт на реальном корпусе (`scripts/make_e2e_corpus.sh`), а не на моках. ## Документы | Документ | Что внутри | |---|---| | [`MANUAL.md`](MANUAL.md) | **инструкция для человека**: как пользоваться, команды, подключение к агенту | | [`docs/SPEC.md`](docs/SPEC.md) | полная спека: модель данных, индекс, маршрутизация, watcher, интерфейс, приёмка | | [`TASK.md`](TASK.md) | ТЗ для исполнителя: стек, схема БД, контракты, чего не делать | | [`TESTING.md`](TESTING.md) | тест-план: приёмочные проверки, команды, признаки провала | | [`docs/orders/`](docs/orders/) | журнал заказов исполнителю — с доказательствами дефектов, а не «сделай хорошо» | ## Зависимости (проверено 02.10.2026) | Что | Координата | Откуда | |---|---|---| | SQLite + sqlite-vec + FTS5 | `pw.binom.db:ksqlite:0.1.4` | Maven Central | | Текстовый эмбеддинг (SigLIP2 int8, 768 dims) | `pw.binom.ai.embeddingtext:api:5` + `:siglip:5` | `http://nexus.xx/repository/caffeine/` | Модель (в артефакты не входит, скачивается отдельно): ```bash mkdir -p models/siglip2 curl -fSL -o models/siglip2/text_model_int8.onnx http://static.binom.pw/models/siglip2/text_model_int8.onnx # 283M curl -fSL -o models/siglip2/tokenizer.model http://static.binom.pw/models/siglip2/tokenizer.model # 4.2M ``` ## Требования JDK 21. Индекс и поиск работают офлайн после скачивания модели. ## Лицензия Apache-2.0.