Metadata-Version: 2.4
Name: claude-memory-engine
Version: 0.7.1
Summary: Reusable lessons/memory engine for Claude Code: frontmatter lessons, auto-CATALOG, offline retrieval, path-triggered lessons, auto-maintenance, parallel-session and sub-agent guards.
Author: Arnoldig
License: Apache-2.0
Keywords: claude-code,memory,lessons,hooks,llm-agent
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Dynamic: license-file

<div align="center">

![claude-memory-engine](assets/banner.svg)

Долговременная автообновляемая память «уроков» для Claude Code: нужный урок показывается сам, когда он пригодится. Подбор подходящих уроков ведёт обычный код, а не ИИ, поэтому работает быстро, офлайн и без сторонних зависимостей.

![Лицензия: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue) ![Python: 3.9+](https://img.shields.io/badge/Python-3.9%2B-blue) ![Зависимости: нет](https://img.shields.io/badge/dependencies-none-brightgreen) ![Тесты: 200+](https://img.shields.io/badge/tests-200%2B-brightgreen)

**Русский** · [English](README.en.md)

</div>

## Что это

claude-memory-engine добавляет в Claude Code долговременную память «уроков». Урок: короткая запись о том, как в проекте принято делать, на какие ошибки уже наступали и что нельзя ломать. Уроки записывает сам ассистент по ходу работы над проектом; при желании вы можете добавлять их и сами, но это не обязательно. Движок упорядочивает уроки и подсказывает вашей LLM нужный урок тогда, когда он ей пригодится.

Важно: в движок входит только механизм. Ваши уроки (это ваши знания и, возможно, приватные данные) хранятся отдельно.

## Зачем это нужно

Когда работаешь с ИИ-ассистентом над проектом, возникает общая проблема: у него нет единой сквозной памяти. Из-за этого одни и те же ошибки повторяются раз за разом. Чтобы их избежать, приходится всё больше записывать в память проекта; она разрастается, а большой файл ассистент уже не читает целиком, и внимание достаётся только первым 200 строкам. В итоге вести сложный проект становится тяжело и долго.

Движок убирает эту боль: уроки лежат маленькими отдельными markdown-файлами, нужный урок показывается сам в подходящий момент, оглавление со всеми уроками собирается автоматически, а размер памяти держится под контролем. Подробнее: смотрите раздел «Возможности» ниже.

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

Самый короткий путь:

```
pip install claude-memory-engine
cd /путь/к/вашему/проекту
claude-memory init
```

Первая команда ставит движок. Команда `cd` переводит вас в папку вашего проекта. Команда `claude-memory init` подключает движок к этому проекту: создаёт файл настроек, папку для уроков и делает так, чтобы движок срабатывал в нужные моменты. На этом всё: подсказки заработают со следующей сессии Claude Code. Настраивать ничего не нужно, по умолчанию всё работает; как изменить настройки под себя, описано ниже в разделе «Настройка».

<div align="center">

![Установка claude-memory-engine](assets/install-demo.svg)

</div>

## Как устроено

Движок состоит из трёх слоёв.

1. **Логика.** Набор небольших программ на Python, которые делают всю работу: находят нужный урок, собирают оглавление, отправляют устаревшее в архив и так далее. Это чистый Python без сторонних библиотек, отдельно ставить ничего не нужно.

2. **Связка с Claude Code.** Один маленький скрипт, который Claude Code вызывает в нужные моменты (в начале сессии, перед правкой файла и тому подобное) и который просто запускает логику.

3. **Данные.** Сами уроки: ваши знания о проекте. Они хранятся отдельно и в движок не входят.

Зачем это деление: первые два слоя составляют универсальный механизм, который переносится в любой проект, а третий слой содержит только ваши приватные данные. Поэтому движок легко переиспользовать и даже открыть публично, а ваши уроки при этом остаются только у вас.

А вот что происходит на каждый ваш запрос: запрос приходит к Claude Code и через хук запускает движок; тот подбирает урок из памяти обычным кодом и возвращает его в контекст LLM; после этого ассистент отвечает с учётом урока.

```mermaid
flowchart LR
  Q["Ваш запрос"] -->|"1. запрос"| C["Claude Code (ваша LLM)"]
  C -->|"2. хук на запрос"| E["Движок: подбор урока кодом, не ИИ"]
  L["Уроки (markdown)"] -.->|"3. источник"| E
  E -->|"4. нужный урок"| C
  C -->|"5. ответ с учётом урока"| A["Ответ"]
```

Движок срабатывает и на другие события Claude Code: перед правкой файла (урок по пути), в начале и в конце сессии, при завершении работы.

## Пример вывода для вашего LLM-ассистента

Подсказку с подходящими уроками движок добавляет в контекст вашего LLM-ассистента (в чате вы её обычно не видите). Выглядит она примерно так:

```
[память] Возможно полезные уроки. Прочтите нужные ДО действий:
  • по смыслу:
    - api-error-format: ошибки отдаём в формате {code, message}
    - db-migrations: новые поля БД только через миграцию, не руками
  • по пути файла:
    - payment-flow: не менять статус оплаты вручную
```

Уроки в примере выдуманы для иллюстрации. По умолчанию надписи английские; перевод — в разделе «Настройка».

## Возможности

**Уроки и порядок**
- Уроки хранятся маленькими markdown-файлами с короткой шапкой (название, тема, ключевые слова) плюс одно «горячее ядро» (главный файл, который читается всегда) с ограничением размера, чтобы оно не разрасталось.
- Оглавление всех уроков собирается само из их тем; вручную его вести не нужно.

**Подсказки в нужный момент**
- На каждый ваш запрос движок сам подбирает подходящие уроки по словам и показывает их вашей LLM; если ничего важного нет, он молчит. Подбор делает обычный код, без обращения к ИИ.
- Урок можно привязать к файлу: тогда он покажется ровно перед тем, как ассистент соберётся править этот файл.
- Подсказки остаются быстрыми, даже когда уроков становится много (за счёт внутреннего кэша).

**Память сама себя поддерживает**
- Старые записи уходят в архив, большой архив остаётся удобным для поиска, а в конце сессии движок помечает устаревшие правила и оборванные привязки уроков к файлам.
- Размер памяти под контролем, в свалку она не превращается.

**Страховки**
- Если две сессии правят один и тот же файл памяти, вторая получает мягкое «перечитай и повтори» вместо тихой потери правок.
- В конце работы движок мягко напоминает записать урок, если после свежего коммита заметки ещё нет (особенно когда коммит закрывает задачу).
- При закрытии задачи движок один раз напоминает перепроверить уроки, привязанные к файлам, которые менялись в этой сессии: не устарели ли они после ваших изменений (и подсказывает близкие по смыслу уроки даже без привязки к пути). Так знания в памяти не расходятся с кодом.
- Не даёт случайно запустить вспомогательного помощника (суб-агента) на самой дорогой модели и ведёт журнал таких запусков.
- Предупреждает, если модель сессии незнакомая или список известных моделей давно не сверяли.
- Проверяет файл настроек при старте и ловит опечатки, пока они не сломали работу.

**Гибкость**
- Любой язык: все надписи движка переводятся через настройки, не трогая код.
- Корректно работает внутри git-worktree (отдельной рабочей копии репозитория).
- Ноль сторонних зависимостей: нужен только обычный Python.

## Карта модулей

Таблица для тех, кто будет читать или дорабатывать код: какая возможность каким модулем реализована. Обычному пользователю она не нужна.

**Уроки и порядок**

| Возможность | Модуль |
|---|---|
| Авто-оглавление и проверка здоровья памяти | `catalog_generate` |

**Подсказки**

| Возможность | Модуль |
|---|---|
| Подбор уроков по запросу | `memory_retrieve` |
| Кэш быстрого подбора | `sqlite_index` |
| Уроки по пути файла (в том числе в git-worktree) | `applies_to` |

**Память сама себя поддерживает**

| Возможность | Модуль |
|---|---|
| Архивирование старых уроков | `memory_archive` |
| Навигация по большому архиву | `precedent_index` |
| Удаление архивных уроков по сроку хранения | `archive_prune` |
| Пометка устаревшего в конце сессии | `staleness` |

**Страховки**

| Возможность | Модуль |
|---|---|
| Защита параллельных сессий | `memory_concurrency` |
| Формат однострочного маркера сессии | `session_marker_guard` |
| Напоминание записать урок на выходе | `stop_check` |
| Контроль дорогой модели у суб-агентов | `subagent_model_guard` |
| Журнал делегирования суб-агентам | `subagent_efficiency_log` |
| Напоминание сверить реестр моделей | `model_registry_guard` |
| Самопроверка настроек | `self_check` |

**Гибкость**

| Возможность | Модуль |
|---|---|
| Переводимые надписи (i18n) | `messages` |

**Инфраструктура**

| Возможность | Модуль |
|---|---|
| Все настройки движка | `config` |
| Запуск логики из хука | `hooks_cli` |
| Регистрация хуков в settings.json | `installer` |
| Команда `claude-memory` (init/uninstall/doctor/config) | `cli` |

## Установка

Поставить движок можно двумя способами. Оба дают один и тот же результат и одинаково подключают хуки. Разница только в том, где лежит сам движок: своя копия внутри каждого проекта (способ A) или одна общая установка на всю машину (способ B). На то, где хранятся уроки, выбор способа не влияет.

### Способ A: git + install.sh

Подходит, когда важно, чтобы проект был полностью самодостаточным: движок лежит внутри проекта, ничего внешнего.

```
git clone https://github.com/Arnoldig/claude-memory-engine.git
cd claude-memory-engine
./install.sh /путь/к/вашему/проекту /путь/к/папке/памяти
```

Скрипт `install.sh` кладёт движок внутрь проекта (в папку `.claude/memory_engine/`), ставит связующий скрипт, создаёт файл настроек и каталог памяти, а также прописывает хуки в `settings.json`, не затирая чужие. Повторный запуск безопасен: дубликаты не появляются. Аргументы можно опустить: тогда проектом считается текущая папка, а для памяти берётся `~/.claude/memory`.

### Способ B: pip + одна команда

Подходит, когда машина одна, а проектов много: движок ставится один раз, а подключается к проектам одной командой.

```
pip install claude-memory-engine
claude-memory init /путь/к/вашему/проекту /путь/к/папке/памяти
```

Здесь движок остаётся в окружении pip и в проект не копируется; команда `claude-memory init` разворачивает в проект только тонкий слой: связующий скрипт, файл настроек и регистрацию хуков. Аргументы те же и так же необязательны.

Важная деталь: связующий скрипт запоминает именно тот Python, которым вы поставили пакет. Если потом сменить окружение или переустановить пакет, выполните `claude-memory init` ещё раз, чтобы обновить эту привязку.

### Какой способ выбрать

| Вопрос | Способ A (git) | Способ B (pip) |
|---|---|---|
| Где лежит движок | внутри проекта, своя копия в каждом | один раз в окружении pip |
| Нужна ли копия исходников на машине | да | нет |
| Как обновить версию | склонировать заново и снова запустить `install.sh` | `pip install -U` в одном месте |
| Как подключить новый проект | склонировать и запустить `install.sh` | одна команда `claude-memory init` |
| Зависит ли проект от внешнего | нет, самодостаточен | да, нужен установленный пакет |

Коротко, по одному признаку: способ A держит отдельную копию движка внутри каждого проекта (проект ни от чего внешнего не зависит), а способ B держит один общий движок на всю машину (ставить и обновлять удобно в одном месте).

Уточнение: файл настроек у каждого проекта свой (`<проект>/.claude/claude-memory.config.json`) при любом способе установки. Поэтому отдельная память на каждый проект настраивается одинаково и в способе A, и в способе B. Общим для всех проектов в способе B остаётся только код движка.

Где хранить уроки (общий пул для всех проектов или отдельный на каждый проект) задаётся настройкой `memory_dir` и работает одинаково при любом способе: один и тот же путь к памяти у всех проектов даёт общий пул уроков, свой путь на проект даёт раздельные.

В обоих случаях хуки начинают работать со следующей сессии Claude Code.

## Настройка

Все настройки лежат в файле проекта `.claude/claude-memory.config.json`. Сразу после установки он минимальный и содержит только пути проекта:

```json
{
  "memory_dir": "~/.claude/memory",
  "project_root": "."
}
```

(у вас в этих двух строках будут реальные пути, подставленные при установке)

Менять что-либо не обязательно: из коробки всё работает на значениях по умолчанию. Чтобы настроить под себя, откройте файл любым текстовым редактором из корня проекта (вместо `$EDITOR` подставьте свой, например `nano` или `code`):

```
$EDITOR .claude/claude-memory.config.json
```

Если вы ставили движок через pip (способ B), есть две удобные команды: `claude-memory config` показывает текущие настройки, а `claude-memory doctor` проверяет файл на опечатки.

Ниже частые правки в формате «было → стало». Нужные ключи добавляются в файл рядом с уже имеющимися; файл целиком не заменяется.

**Перевести надписи движка на свой язык.** Добавлен ключ `messages`. В нём каждая строка заменяет одну встроенную английскую фразу: слева имя фразы, справа ваш текст. Заменяются только указанные строки, остальные остаются английскими.

```json
{
  "memory_dir": "~/.claude/memory",
  "project_root": ".",
  "messages": {
    "unit.chars": "символов",
    "retrieve.hook_header": "[память] Возможно полезные уроки. Прочтите нужные ДО действий:"
  }
}
```

Что именно меняется в этом примере:

| Имя фразы | Было (по умолчанию) | Стало |
|---|---|---|
| `unit.chars` | `chars` | `символов` |
| `retrieve.hook_header` | `[memory:retrieve] Possibly relevant lessons … (full list: CATALOG):` | `[память] Возможно полезные уроки. Прочтите нужные ДО действий:` |

Здесь `unit.chars`: слово для единицы размера, когда движок сообщает объём памяти (например, «12000 символов»). А `retrieve.hook_header`: заголовок, который движок печатает перед списком подсказанных уроков.

**Задать свои разделы в оглавлении уроков.** Добавлен ключ `topic_order` (слева короткое имя темы, справа заголовок раздела). По умолчанию это технические темы (`workflow`, `testing`, `infra`, `security`, `docs`, `core`); здесь заменяем их на свои.

```json
{
  "memory_dir": "~/.claude/memory",
  "project_root": ".",
  "topic_order": [
    ["backend", "Backend"],
    ["frontend", "Frontend"],
    ["ops", "Эксплуатация и CI"]
  ]
}
```

**Увеличить лимит «горячего ядра» (главного файла памяти).** Добавлены ключи `core_budget_bytes` и `core_size_unit`. По умолчанию лимит `15000`; здесь увеличиваем до `20000`.

```json
{
  "memory_dir": "~/.claude/memory",
  "project_root": ".",
  "core_budget_bytes": 20000,
  "core_size_unit": "chars"
}
```

Полный список всех опций со значениями по умолчанию находится в файле `examples/claude-memory.config.json` в репозитории.

## Требования

- Python 3.9 или новее.
- Claude Code (движок работает через его хуки).
- Сторонние библиотеки не нужны: используется только стандартная библиотека Python.

## Тесты и разработка

Этот раздел для тех, кто дорабатывает код движка: тесты проверяют, что после изменений всё по-прежнему работает правильно. Обычному пользователю они не нужны.

Тесты не требуют сети, внешней базы данных или Docker: только стандартная библиотека Python (их более 200). Запустить так:

```
pip install pytest
python3 -m pytest
```

Первая команда устанавливает `pytest` (программу, которая прогоняет тесты), вторая запускает весь набор и показывает, что всё «зелёное».

## Удаление

Движок не трогает ваши уроки: папка с уроками (`memory_dir`) при удалении остаётся на месте.

Если ставили через pip (способ B), отключить движок в проекте можно одной командой:

```
claude-memory uninstall
```

Она убирает из проекта связующий скрипт, регистрацию хуков и файл настроек. Чтобы убрать и сам пакет из окружения: `pip uninstall claude-memory-engine`.

Если ставили через git (способ A), удалите вручную папку `.claude/memory_engine/`, файл `.claude/hooks/cme_hook.sh`, файл `.claude/claude-memory.config.json` и строки с `cme_hook.sh` в `.claude/settings.json`.

## Статус

Движок стабилен и используется в реальном рабочем проекте. Вопросы, идеи и сообщения об ошибках приветствуются через Issues репозитория.

## Лицензия

Apache-2.0. См. файл [LICENSE](LICENSE).
