Проблема
5-часовой и недельный лимиты Claude Code прерывают долгие агентные циклы. Разрыв SSH убивает сессию. Просыпаешься — задача на полпути, терминал мёртв.
Что делает
- Оборачивает
claude, чтобы пережить 5-часовой блок: спит до сброса и возобновляет ту же session UUID. - Работает в именованной tmux-сессии — разрывы SSH не страшны.
- Трёхуровневая детекция (детерминизм впереди, LLM — опционально и по согласию).
- Автоматически обрабатывает новое интерактивное модальное окно лимита (выбирает безопасный пункт «Stop and wait»).
- Мульти-сессия:
vibe work feature-aиvibe work bugfixживут параллельно, состояние изолировано. - Ядро зависит только от
bash,jq,curl,tmux. Никакого npm и pip.
Установка (один раз)
git clone https://github.com/zhihuiyuze/vibe-coding-auto-resume.git ~/vibe
cd ~/vibe
./install.sh
source ~/.bashrc
Идемпотентна. Симлинкает инструменты в ~/.local/bin/, добавляет shell-функцию vibe, дописывает snippet tmux. Никогда не трогает ~/.claude/; никогда не запускает sudo за вас.
Три сценария — выберите свой
1. Начинаю новую задачу в Claude
cd ~/dev/<ваш-проект>
vibe work # cd сюда + открыть именованную tmux-сессию
vibe run # замена `claude` — те же флаги, тот же UI
Работайте с Claude как обычно. Когда 5-часовой блок исчерпан, vibe run спит до сброса и перезапускает ту же session UUID автоматически. Новое интерактивное модальное окно Anthropic (What do you want to do? 1. Stop and wait …) обрабатывается автоматически — выбирается только безопасный пункт «Stop and wait».
Отсоединиться: Ctrl+b d. Вернуться: vibe work.
2. Хочу продолжить сессию, начатую раньше
Если помните session UUID:
cd ~/dev/<ваш-проект>
vibe work
vibe run --resume <session-uuid>
Не помните, но это последняя сессия в проекте:
vibe run --mode continue # эквивалент `claude --continue` + автовозобновление
Список кандидатов по именам JSONL:
ls -t ~/.claude/projects/$(pwd | sed 's|/|-|g')/*.jsonl | head -5
# имя файла без `.jsonl` = session UUID
3. SSH оборвался — как убедиться, что задача жива, и вернуться к ней
tmux держит процесс, а не ваш shell. SSH умер, сессия жива. Пошагово:
ssh you@server # 1. переподключаемся
tmux ls # 2. жива ли ваша vibe-* сессия?
# ожидается, например: "vibe-default: 1 windows (...)"
vibe work # 3. реаттач (или `vibe work <name>` если имя задавали)
# попадаете ровно туда, где остановились
После реаттача — посмотреть, что произошло без вас: Ctrl+b [, далее PageUp / стрелки, q для выхода. Если за это время был rate limit, wrapper уже обработал — увидите [vibe-run] Sleeping … until … и возобновление в scrollback.
Подсмотреть без аттача (с другой машины, просто проверить статус):
ssh you@server "tmux ls"
ssh you@server "tmux capture-pane -t vibe-default -p | tail -50"
ssh you@server "vibe status"
Если tmux ls отвечает no server running, машина перезагрузилась или tmux был OOM-killed. tmux-сессия потеряна, но JSONL-история Claude — нет. Используйте сценарий 2 выше, чтобы продолжить.
Обнаружение и жонглирование сессиями
vibe ls показывает все vibe-* tmux-сессии с их cwd, статусом аттача и пометкой ← here, когда cwd совпадает с вашим:
$ vibe ls
vibe-boldfox /home/u/dev/projectA ← here [attached]
vibe-feature-x /home/u/dev/projectA ← here
vibe-quietowl /home/u/dev/scratch
vibe work без аргументов теперь сначала использует это обнаружение, прежде чем падать на имя по хэшу cwd:
- 0 совпадений → создаёт новую сессию (имя по хэшу cwd).
- 1 совпадение → аттачится напрямую, без вопросов.
- N совпадений → интерактивный picker (
1..Nчтобы выбрать,nдля новой).
Явный vibe work <name> пропускает обнаружение — имя всегда выигрывает. Для часто посещаемых проектов давайте явное имя (vibe work projectA) — переживает переименования путей и читаемо в vibe ls.
Опционально: умнее детекция через LLM
L1 (парсинг JSONL) и L2 (regex по pane) покрывают типовые формы rate limit без внешних вызовов. Чтобы устойчивее обрабатывать смену формулировок TUI и извлекать время сброса, которое regex упускает, включите L3:
echo 'DEEPSEEK_API_KEY=sk-...' >> ~/.config/vibe/env # chmod 600, создан установщиком
chmod 600 ~/.config/vibe/env
source ~/.bashrc
Провайдеры: DeepSeek (~$0.05/блок), Anthropic Claude Haiku, OpenAI gpt-4o-mini, Ollama (локально, [untested]). При выключённом L3 (по умолчанию до добавления ключа) ничто не покидает вашу машину.
Как работает детекция
Когда claude завершается, три сигнала решают, что произошло:
| Уровень | Читает | Когда полезен |
|---|---|---|
| L1 | ~/.claude/projects/<cwd>/*.jsonl — собственный лог Claude | Всегда включён. Считает токены и границы блока. |
| L2 | tmux capture-pane + scrollback | Сообщение о лимите видно в основной панели. |
| L2.5 | Сканирование хвоста JSONL | Сообщения сабагентов, ушедшие за пределы видимой панели. |
| L3 | LLM-классификатор (DeepSeek / Claude Haiku / OpenAI / Ollama) | Опционально. Устойчив к изменениям формулировок; семантически извлекает время сброса. |
L1 и L2/L2.5 — полностью локально. L3 опционален и стоит примерно $0.05 за блок с DeepSeek.
Флаги CLI
vibe run [...args]
--resume <uuid> возобновить конкретную сессию (передаётся один раз, для всех циклов)
--threshold <0..1> мягкий потолок (по умолчанию выключен — «сжигаем блок»)
--max-cycles <n> циклов возобновления за вызов (0 = без лимита, по умолчанию 1)
--mode auto|session-id|continue
--provider deepseek|claude|openai|ollama
--no-l3 принудительно только L1+L2
--dangerously-skip-permissions
-p "prompt"
... любые другие флаги пробрасываются в claude
Конфигурация
| Где | Что |
|---|---|
~/.config/vibe/env | LLM-ключи и настройки (chmod 600). Подгружается из bashrc-блока с set -a. |
~/.local/state/vibe/<name>/ | Кэш UUID сессии. Изолирован между vibe work foo и vibe work bar. |
<ваш-проект>/HANDOFF.md | Файл преемственности между сессиями. Создаётся только если запустить vibe setup-workspace изнутри проекта. |
Чего никогда не делает
- Не трогает каталоги других проектов без явного
vibe setup-workspaceизнутри. - Не подгружает
.env/.env.localвашего проекта. Учётки инструмента живут в~/.config/vibe/env; ваш env — ваш. - Не запускает
sudo. Установщик распечатает одну-две команды, которым sudo нужен, и остановится. - Ничего не отправляет наружу, если L3 выключен (по умолчанию — до добавления ключа).
- Никогда не выбирает платные опции в модальном окне лимита. Только «Stop and wait» — не «Switch to usage credits» и не «Upgrade your plan».
Документация
- AGENTS.md — архитектура, гайд контрибьютора, spec-first.
- docs/architecture.md — полная схема потока данных.
- docs/design/ — по одному принятому design-документу на фичу.