Skip to content

Glym143/ccclean

Repository files navigation

ccclean

License: MIT Python 3.8+ Platform

Утилита для очистки контекста сессий Claude Code. Удаляет старые сообщения с начала диалога, чтобы освободить место в окне контекста — с подтверждением и (опционально, флаг --summary) кратким резюме удаляемого фрагмента.

Работает напрямую с .jsonl-файлами сессий в ~/.claude/projects/.


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

Длинные сессии Claude Code забивают окно контекста, и работать становится тяжело: модель упирается в лимит, авто-компакт срабатывает не вовремя и сжимает всё подряд. ccclean даёт точечный контроль: ты сам решаешь, сколько токенов освободить и какой именно старый кусок диалога удалить — предварительно увидев его краткое содержание. Текущая (свежая) часть разговора остаётся нетронутой.

В отличие от встроенного /compact (который сжимает весь диалог в резюме), ccclean просто отрезает самое старое начало активной ветки, сохраняя последние сообщения дословно.


Что умеет

  • ✂️ Точная обрезка — указываешь объём (10k, 50k, 1.5m), утилита срезает старые сообщения с начала так, чтобы освободить не меньше запрошенного.
  • 🔢 Честный подсчёт токенов — по умолчанию через официальный Anthropic count_tokens API (точно), либо офлайн через tiktoken (--fast). Учитывает текст, thinking, вызовы инструментов и картинки.
  • 📋 Резюме удаляемого (опционально) — с флагом --summary перед удалением показывает краткую сводку фрагмента (через DeepSeek), чтобы ты понял, что теряешь. По умолчанию выключено.
  • 📊 Реальная занятость окна — показывает фактический объём контекста из логов (usage), включая системный промпт, схемы инструментов, MCP и CLAUDE.md.
  • 🗂 Интерактивный выбор сессии — без аргументов открывает список диалогов (через fzf, с поиском по заголовку), не нужно вспоминать id.
  • 🔓 Снятие блока «context limit reached» — Claude Code определяет лимит по usage последнего ответа, а не пересчитывает урезанные сообщения. После резки ccclean опускает этот счётчик на usage_subtract (по умолч. 200k, ключ в config.json) — заметно ниже реально срезанного, чтобы авто-компакт не сработал перед первым запросом после резюме. Реальный контекст всё равно < лимита, так что сервер примет запрос, а Claude Code пересчитает счётчик уже по факту.
  • 💾 Безопасность — авто-бэкап перед каждой резкой, проверка целостности, защита от удаления всего диалога, корректная переподшивка корня.

Установка

Нужен Python 3.8+ и pip. Остальное (tiktoken, anthropic, fzf) утилита доустановит сама при первом запуске.

git clone https://github.com/Glym143/ccclean.git
cd ccclean
./install.sh

install.sh:

  • делает ccclean.py исполняемым;
  • создаёт симлинк ccclean в первом доступном каталоге из PATH (/opt/homebrew/bin, /usr/local/bin или ~/.local/bin) — без sudo;
  • создаёт конфиг ~/.config/ccclean/config.json (права 600).

Если выбран ~/.local/bin, а его нет в PATH — добавь в ~/.zshrc/~/.bashrc: export PATH="$HOME/.local/bin:$PATH"

Ключи API

Впиши ключи в ~/.config/ccclean/config.json:

{
  "deepseek_api_key": "sk-...",
  "anthropic_api_key": "sk-ant-..."
}
  • anthropic_api_key — точный подсчёт токенов (режим по умолчанию). Получить: https://console.anthropic.com/ → API Keys.
  • deepseek_api_key — резюме удаляемого фрагмента. Получить: https://platform.deepseek.com/ → API Keys.

Можно задать переменными окружения (имеют приоритет): ANTHROPIC_API_KEY, DEEPSEEK_API_KEY.

Без ключа Anthropic — авто-фолбэк на офлайн tiktoken (приблизительно). Без ключа DeepSeek — резюме пропускается.


Использование

ccclean                       # выбрать сессию из списка + срезать 10k (по умолчанию)
ccclean 30k                   # выбрать сессию + срезать 30k
ccclean <session-id>          # конкретная сессия + срезать 10k
ccclean <session-id> 30k      # конкретная сессия + срезать 30k
ccclean <session-id> --keep 200k     # оставить последние ~200k токенов
ccclean <session-id> 50k --dry-run   # показать план, ничего не менять
ccclean <session-id> 100k --fast     # быстрый офлайн-подсчёт (tiktoken)

Объём — позиционно (30k, 50000, 1.5m) или флагом --free/--keep (флаг приоритетнее). Порядок аргументов не важен. session-id можно указывать сокращённо (как в списке выбора). Полный список флагов: ccclean -h.

Если объём не указан, берётся default_free из ~/.config/ccclean/config.json (по умолчанию 10k) — поменяй там, чтобы сменить дефолт раз и навсегда.

После очистки возобнови сессию:

claude --resume <session-id>

Авто-чистка при заполнении контекста (хук + ccclaude)

Чтобы не чистить вручную, есть автоматический режим: когда контекст заполняется и Claude Code запускает компакт, хук перехватывает его и вместо лоссового сжатия запускает ccclean, после чего сессия перезапускается уже разгруженной.

install.sh настраивает это сам:

  • ставит команду-обёртку ccclaude;
  • кладёт хук ~/.claude/hooks/ccclean-hook.sh;
  • регистрирует его в ~/.claude/settings.json на событие PreCompact только для авто-компакта (ручной /compact не трогаем — раз ты сам его запустил, значит компакт тебе и нужен);
  • включает autoCompactEnabled: true (нужно, чтобы хук срабатывал сам);
  • ставит autoCompactWindow: 1000000 — поднимает порог авто-компакта почти к реальному потолку модели (Claude Code считает порог как окно − ~33k), чтобы «context limit reached» не срабатывал преждевременно.

Как это устроено внутри Claude Code (из реверса бандла): блок наступает, когда счётчик usage последнего ответа ≥ автокомпакт-окно − резерв_вывода(≤20k) − 13k. Поэтому помогают два рычага: поднять окно (autoCompactWindow, делает install.sh) и опустить счётчик после чистки (usage_subtract, делает ccclean).

Как пользоваться: запускай Claude Code через обёртку (в терминале):

ccclaude --resume <session-id>      # вместо `claude --resume <session-id>`

Цикл при заполнении:

  1. Claude Code упирается в лимит → запускает авто-компакт.
  2. Хук ccclean-hook.sh помечает сессию и завершает claude (компакт отменён).
  3. Обёртка ccclaude видит метку → ждёт ~2с → ccclean <id> --force → перезапускает и сразу отправляет промпт: claude --resume <id> "continue".

Размер среза за цикл задаётся (по приоритету):

  1. переменная CCCLEAN_FREE (разово),
  2. ключ default_free в ~/.config/ccclean/config.json (постоянно),
  3. дефолт 10k.
CCCLEAN_FREE=300k ccclaude --resume <id>   # разово разгрузить переполненную сессию
// ~/.config/ccclean/config.json — поменять дефолт раз и навсегда
{ "default_free": "30k" }

Ограничения:

  • Работает в терминале, не внутри VS Code (хук завершает процесс claude; у VS Code другая модель процессов).
  • Если сессия у самого потолка, маленький срез (10k) может не вывести из лимита за один цикл — увеличь CCCLEAN_FREE для разовой разгрузки.

Проактивный режим (clean_at) — чистка ДО блокировки

Чтобы вообще не упираться в «context limit reached», есть второй хук — на событие Stop (после каждого ответа). Он читает текущий usage из транскрипта, и если он выше порога clean_at (ключ в config.json, напр. "940k"), заранее запускает тот же цикл чистки (kill → ccclean → restart) — пока ещё под лимитом. Так блок не наступает вовсе. Режим включается наличием clean_at в конфиге.

Автопродолжение после чистки (resume_prompt)

После перезапуска обёртка не просто открывает сессию, а сразу отправляет в неё промпт — чтобы работа продолжилась без твоего участия:

claude --resume <id> "continue"     # claude шлёт промпт сразу при старте

Текст задаётся ключом resume_prompt в config.json (по умолчанию "continue"):

{ "resume_prompt": "продолжай с того места где остановился" }

Пустая строка ("") → просто возобновление без автоотправки.

Безопасность хуков

Хуки Stop/PreCompact завершают процесс claude, поэтому действуют ТОЛЬКО в сессиях, запущенных через обёртку ccclaude (она ставит CCCLEAN_WRAPPED=1). В обычных сессиях (claude, VS Code) хуки — no-op, ничего не трогают.


Как это работает

  1. Находит файл сессии (по id или через интерактивный выбор).
  2. Восстанавливает активную ветку диалога — цепочку от последнего сообщения назад по parentUuid к корню (именно она грузится в контекст).
  3. Считает токены (Anthropic API — точно; --fast — tiktoken).
  4. Находит точку реза по нужному объёму, выравнивая её на границу сообщения пользователя (срежет не меньше запрошенного).
  5. Спрашивает подтверждение (и с флагом --summary — краткое резюме удаляемого через DeepSeek).
  6. Создаёт бэкап *.jsonl.bak-<дата>, удаляет старые сообщения, переподшивает корень.
  7. Проверяет целостность результата.

Для AI-агентов

Если эту утилиту запускает агент (а не человек) — учитывай:

  • Неинтерактивный режим: -y (без подтверждений), --fast (без сети, офлайн-подсчёт). Резюме через DeepSeek по умолчанию ВЫКЛЮЧЕНО — включается флагом --summary. Сессию обязательно указывай явным session-id — без него запустится интерактивный выбор и зависнет.
    ccclean <session-id> 50k --fast -y
  • Предпросмотр без изменений: --dry-run — печатает план («освободится ≈ X», «останется ≈ Y») и выходит, ничего не трогая. Удобно для оценки.
  • Гарантия: фактически срезается не меньше запрошенного объёма; число «освободится ≈» в выводе точно соответствует реальному удалению.
  • Только активная ветка: утилита трогает лишь текущую линейную цепочку диалога. Системный промпт, схемы инструментов, MCP и CLAUDE.md в контекст входят, но обрезкой не убираются (они не в .jsonl).
  • Безопасность по умолчанию: всегда создаётся бэкап (отключается --no-backup). Откат — копированием *.jsonl.bak-* поверх *.jsonl.
  • ⚠️ Запускать только при ЗАКРЫТОЙ целевой сессии: открытый процесс Claude Code перезапишет файл из памяти и затрёт правки. Утилита проверяет это через lsof и откажется резать открытую сессию (обход — --force).

Важно

  • Запускай только при закрытой очищаемой сессии (проверяется через lsof; открытую сессию утилита резать откажется, обход — --force).
  • Перед каждой резкой автоматически создаётся бэкап рядом с файлом сессии.
  • Подсчёт токенов через tiktoken (--fast) приблизительный (на кириллице занижает); для точных чисел используй режим по умолчанию (Anthropic API).

Лицензия

MIT © Glym143

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors