- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| opencode-cleaner.py | ||
| README.md | ||
opencode-cleaner
Интерактивный помощник для очистки базы данных opencode.
Скрипт показывает список сессий и позволяет удалить выбранную сессию каскадно со всем, что к ней относится, а также находит и удаляет orphan-записи, оставшиеся после удалений другими программами.
Зачем это нужно
База opencode — это SQLite-файл
~/.local/share/opencode/opencode.db
Большинство таблиц связаны с session внешним ключом с ON DELETE CASCADE и удаляются сами. Но таблицы event и event_sequence привязаны к сессии только логически — через aggregate_id = <session_id>, без внешнего ключа обратно на session. Поэтому при удалении сессии события остаются в базе как мусор. У автора на реальной базе в event скопилось 97 000 строк, из которых ~59 000 — orphan-события уже удалённых сессий (при том, что самих активных сессий меньше тридцати).
Этот скрипт корректно чистит именно эту цепочку, плюс проверяет целостность и позволяет вернуть место на диске.
Возможности
- Список сессий со статистикой: сообщения, части, события, todos, стоимость, токены, флаги archive/child.
- Удаление сессии каскадно, включая:
- дочерние сессии по
parent_id(всё поддерево); - все
message,part,todo,session_share,session_message,session_input,session_context_epoch(через FK CASCADE); event_sequenceиeventпоaggregate_id— то, что другие инструменты оставляют.
- дочерние сессии по
- Поиск orphan-записей: события удалённых сессий, висячие
message/part/todoи т. п., а также структурные проблемы (session.parent_id/project_id,workspace/permission/project_directoryбез проекта — только отчёт). - Vacuum / reclaim space —
wal_checkpoint(TRUNCATE)+VACUUM, чтобы файл реально уменьшился после чистки. - Проверка структуры БД — если схема opencode изменится, скрипт заблокируется и попросит обновление, а не сломает данные.
Требования
- Linux, Python 3.7+ (только стандартная библиотека, ничего ставить не нужно).
lsofилиfuser— для проверки, что базу никто не держит открытой (обычно уже есть в системе).- Утилита
sqlite3не нужна — используется встроенный в Python модульsqlite3.
Запуск
python3 opencode-cleaner.py
По умолчанию используется ~/.local/share/opencode/opencode.db. Все операции чтения (просмотр, поиск orphans) работают даже при запущенном opencode; деструктивные операции блокируются, пока база занята другим процессом.
Главное меню:
1 List sessions — список сессий, выбор → просмотр → удаление
2 Find orphan records — поиск orphan-записей → очистка
3 Vacuum / reclaim space — сжать файл после чистки
4 Re-check database lock — перепроверить, что база свободна
0 Quit
Параметры
| Параметр | Описание |
|---|---|
--db PATH |
Путь к opencode.db (по умолчанию ~/.local/share/opencode/opencode.db). |
--backup-dir PATH |
Каталог для бэкапов (по умолчанию ~/.local/share/opencode/backups). |
--skip-backup |
Не делать бэкап перед удалением (опасно). |
--skip-verify |
Пропустить проверку схемы (опасно, только для экстренных случаев). |
--no-color |
Отключить цветной вывод. |
Модель безопасности
- Проверка занятости БД. Перед каждым действием скрипт через
lsof/fuserпроверяет, чтоopencode.db,opencode.db-walиopencode.db-shmникто не держит открытым (кроме самого скрипта). Если держит — например, запущенныйopencode— просмотр доступен, но удаление/purge/vacuum блокируются. Сначала закройте opencode. - Dry-run по умолчанию. Удаление всегда сначала показывает, что именно будет удалено (сессии + дерево потомков, количество строк по таблицам, приблизительный объём), и только после явного подтверждения
y/nвыполняется. - Бэкап перед удалением. Перед любой деструктивной операцией копируются
opencode.db,opencode.db-wal,opencode.db-shmвbackups/opencode-<дата-время>/. Откатиться — просто вернуть эти файлы на место (при остановленном opencode).
Проверка схемы
При запуске скрипт сверяет структуру базы с ожидаемой: наличие нужных таблиц, колонок и внешних ключей с ON DELETE CASCADE, от которых зависит корректность работы. Принцип такой:
- Регрессии блокируются. Если нужная таблица/колонка пропала или изменился/исчез ключевой
CASCADE— скрипт печатает список проблем и завершается с кодом2, ничего не меняя. - Аддитивные изменения tolerated. Новые таблицы и новые колонки не считаются ошибкой — скрипт остаётся совместимым с будущими дополнениями схемы opencode.
Если проверка не прошла — обновите скрипт под новую схему. Экстренно обойти можно ключом --skip-verify (на свой риск).
Как это работает с таблицами
Сессии и их данные (aggregate_id/session_id = идентификатору сессии):
| Таблица | Связь | Удаляется как |
|---|---|---|
message, part, todo, session_share, session_message, session_input, session_context_epoch |
FK → session ON DELETE CASCADE |
автоматически при удалении сессии |
event_sequence |
aggregate_id = session id, без FK на session |
удаляется явно скриптом |
event |
FK → event_sequence ON DELETE CASCADE |
каскадом после удаления event_sequence |
Резервное копирование и восстановление
Бэкап создаётся в ~/.local/share/opencode/backups/opencode-<YYYYMMDD-HHMMSS>/ и содержит три файла (opencode.db, opencode.db-wal, opencode.db-shm). Восстановление:
# 1. полностью закройте opencode
# 2. верните файлы на место
cp ~/.local/share/opencode/backups/opencode-20260807-120000/opencode.db* \
~/.local/share/opencode/
Размер бэкапа равен текущему размеру базы вместе с WAL — на больших базах это может быть несколько гигабайт. После чистки имеет смысл запустить Vacuum, чтобы и база, и последующие бэкапы стали меньше.
Ограничения
- Поддерживается только Linux (для определения процессов используется
/procс фолбэком наps). - Скрипт рассчитан на текущую схему opencode; при её смене сработает блокировка проверки схемы — нужно будет обновить скрипт.
- Удаление необратимо — но бэкап делается всегда, если не передан
--skip-backup.