No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-18 21:39:08 +03:00
opencode-cleaner.py first commit 2026-08-18 21:39:08 +03:00
README.md first commit 2026-08-18 21:39:08 +03:00

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 Отключить цветной вывод.

Модель безопасности

  1. Проверка занятости БД. Перед каждым действием скрипт через lsof/fuser проверяет, что opencode.db, opencode.db-wal и opencode.db-shm никто не держит открытым (кроме самого скрипта). Если держит — например, запущенный opencode — просмотр доступен, но удаление/purge/vacuum блокируются. Сначала закройте opencode.
  2. Dry-run по умолчанию. Удаление всегда сначала показывает, что именно будет удалено (сессии + дерево потомков, количество строк по таблицам, приблизительный объём), и только после явного подтверждения y/n выполняется.
  3. Бэкап перед удалением. Перед любой деструктивной операцией копируются 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.