Поддержать сессии с hook-плагинами в active_chain (OpenIsland) - #1
Open
blackbalancef wants to merge 1 commit into
Open
Поддержать сессии с hook-плагинами в active_chain (OpenIsland)#1blackbalancef wants to merge 1 commit into
blackbalancef wants to merge 1 commit into
Conversation
Утилиты вроде OpenIsland регистрируют хуки на PreToolUse/PostToolUse
и пр. Claude Code пишет результат каждого срабатывания как attachment-
узел (subType=hook_success) с собственным uuid и parentUuid, привязанным
к предыдущему user/assistant. В таких сессиях каждое сообщение перестаёт
быть листом — у него есть attachment-потомок.
active_chain раньше искал листы только среди {user,assistant} и на таких
сессиях не находил ни одного, выходя с "Не найдено ни одного листа".
Решение: лист — любой uuid без потомков. От attachment-листа цепочка
назад по parentUuid собирается корректно через user/assistant, msg_count
по-прежнему считает только user/assistant, next_user_cut выравнивает рез
по user-границе. На сессиях без hook-плагинов поведение не меняется.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
blackbalancef
force-pushed
the
fix/active-chain-hook-plugins
branch
from
June 10, 2026 14:38
a60ee46 to
eb67172
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Проблема
В сессиях, где включены хуки от внешних утилит (например, OpenIsland — Dynamic Island для macOS), Claude Code на каждое событие (PreToolUse, PostToolUse, Stop, SessionStart…) пишет в
.jsonlотдельный узелtype=attachmentс подтипомhook_success. У него собственныйuuidиparentUuid, указывающий на предыдущее сообщение. В результате каждое user/assistant получает attachment-потомка и перестаёт быть листом.active_chain()искал листы только среди{user, assistant}:На таких сессиях множество листьев пустое →
sys.exit("Не найдено ни одного листа диалога — файл пуст или повреждён."). Пользователь не может срезать контекст, хотя файл целый.Воспроизведение
В
.jsonlсессии с активным OpenIsland видно:Все 62/62 user-сообщений имели потомка — ни одного листа в
{user,assistant}.Решение
Лист — любой
uuidбез потомков. attachment-листы становятся допустимым стартом, а цепочка назад поparentUuidкорректно проходит через user/assistant.Что не меняется:
msg_countвсё так же считает толькоuser/assistantдля отображения.next_user_cutвсё так же выравнивает рез по user-границе.Тестирование
Песочница — копия живой сессии (354 объекта, 113 attachment'ов, 0 листов в u/a).
Не найдено ни одного листа диалога→ exit.broken=False.Живая сессия (с открытым процессом
claudeи OpenIsland-хуками):--resume: 157k → 96k (−61k освобождено).Не покрыто этим PR
/compactили серии--resume) остаются в файле после реза. Они не ломают--resume(Claude Code строит активную ветку от листа назад), но засоряют файл. Уборка orphan'ов — отдельная задача.Ограничения
next_user_cutвернётNoneи ccclean честно сообщит «не нашёл границу — попробуй меньший объём». До фикса в таком случае был бы выход на этапе листа, после — на этапе границы. Поведение по сути то же — отказ резать пустой диалог.