Веб-интерфейс и TUI показывают у synthetic-сообщения только description, поэтому вместо «skill-compact-resurrect» там теперь сам текст. В README — где сообщение видно в веб-интерфейсе: в Timeline detail = Compact (по умолчанию) оно свёрнуто в группу вызовов тулов, в Everything — отдельной строкой.
78 lines
5.3 KiB
Markdown
78 lines
5.3 KiB
Markdown
# skill-compact-resurrect
|
||
|
||
Плагин для OpenCode 2. Когда сессия переживает compaction, скилы, загруженные до неё, пропадают из
|
||
контекста: сводка их не содержит, а модель об этом не знает и продолжает работать без инструкций скила.
|
||
Плагин возвращает эти скилы в системный промпт сразу после compaction.
|
||
|
||
## Как работает
|
||
|
||
Скил попадает в сессию двумя путями: модель вызывает тул `skill` (`{ id }`) и получает текст скила
|
||
результатом тула, или пользователь вызывает скил сам — тогда в истории появляется сообщение типа `skill`.
|
||
Compaction заменяет всё это сводкой.
|
||
|
||
Плагин висит на хуке `context`, который срабатывает перед каждым запросом к модели:
|
||
|
||
1. Читает текущий контекст сессии (`session.context`) и запоминает имена всех загруженных скилов. Список
|
||
хранится в `ctx.storage`, поэтому переживает перезапуск OpenCode. Повторный вызов скила переносит его в
|
||
конец списка, как самый свежий.
|
||
2. Если в контексте есть завершённая compaction, добавляет в системный промпт этого запроса тексты скилов,
|
||
загруженных до неё и не загруженных заново после.
|
||
|
||
Сами скилы в историю не пишутся: они живут в системном промпте до следующей compaction, а после неё
|
||
возвращаются снова. Скил, который модель загрузила повторно, не дублируется. Если скил с тех пор удалили или
|
||
переименовали, плагин об этом скажет.
|
||
|
||
Системный промпт в интерфейсе не виден, поэтому один раз на каждую compaction плагин:
|
||
|
||
- пишет в чат короткое служебное сообщение — «♻ После compaction восстановлены скилы: …». Ход модели оно
|
||
не запускает (`resume: false`);
|
||
- добавляет строку в `$XDG_DATA_HOME/opencode/log/skill-compact-resurrect.log`.
|
||
|
||
### Где видно сообщение в веб-интерфейсе
|
||
|
||
Служебные сообщения веб-интерфейс показывает одной строкой, и где именно — зависит от настройки
|
||
**Settings → Preferences → Timeline → Timeline detail**:
|
||
|
||
- **Compact** (по умолчанию) — служебные сообщения сгруппированы и свёрнуты. Сообщение плагина приходит
|
||
между шагами модели, поэтому оказывается внутри ближайшей группы вызовов («Used 1 Shell» и т. п.) и видно,
|
||
только если её раскрыть;
|
||
- **Everything** (ползунок до упора вправо) — служебные сообщения идут отдельной строкой, сообщение видно
|
||
сразу.
|
||
|
||
Отдельно от группировки — только compaction и смена модели или каталога; плагин на это повлиять не может.
|
||
|
||
## Установка
|
||
|
||
Положить ссылку на файл в `plugins/` конфига OpenCode — он подхватывает такие файлы сам:
|
||
|
||
```bash
|
||
ln -sfn "$PWD/skill-compact-resurrect.v2.ts" "${XDG_CONFIG_HOME:-$HOME/.config}/opencode/plugins/"
|
||
```
|
||
|
||
В `"plugin"` в `opencode.jsonc` его **не** добавлять: имя там считается npm-пакетом. Изменения в файле
|
||
применяются после перезапуска OpenCode.
|
||
|
||
## Опции
|
||
|
||
Задаются в `opencode.jsonc`: `"plugins": { "package": "<путь>", "options": { … } }`.
|
||
|
||
| Опция | По умолчанию | Что |
|
||
| --- | --- | --- |
|
||
| `maxRestoredSkills` | все | сколько последних скилов возвращать |
|
||
| `notify` | `true` | писать ли сообщение в чат |
|
||
|
||
## Проверка
|
||
|
||
После compaction в сессии, где загружались скилы, в чате должно появиться сообщение «♻ После compaction
|
||
восстановлены скилы: …», а в журнале — строка вида:
|
||
|
||
```
|
||
2026-10-29T12:00:00.000Z ses_… after msg_…: restored [bmad-build, bmad-spec]
|
||
```
|
||
|
||
Нет ни того, ни другого — проверить, что ссылка на плагин лежит в `plugins/` нужного конфига (того, что
|
||
OpenCode получает в `XDG_CONFIG_HOME`).
|
||
|
||
Требуется OpenCode 2 (API плагинов v2: `ctx.session.hook`, `ctx.session.context`, `ctx.session.synthetic`,
|
||
`ctx.skill`, `ctx.storage`). Проверено на 2.1.3.
|