Claude Code Mods: события, API и сценарии
Карта событий Claude Code Mods: точки подключения, ограничения, безопасность и сценарии для интерфейса, контекста и контроля действий агента.
Содержание · 26 разделов
Как это устроено
Чтобы в списке было проще ориентироваться, разделю точки подключения на три группы:
| Группа | Что происходит | Пример |
|---|---|---|
| События движка | Claude Code собирается выполнить действие | `tool.call`, `prompt.submit`, `ui.render` |
| Классические события | Наступает событие, знакомое по settings hooks | `classic.PostToolUse`, `classic.Stop` |
| Вызовы mods API | Мод обращается к API среды | `fs.read`, `process.run`, `model.complete` |
Такое разделение есть в справочнике, в разделах Events и Mods API calls. Группы пересекаются: например, ui.close встречается и при закрытии панели пользователем, и при вызове API. Поэтому просто сложить количество строк и получить общее число событий не получится.
Если работали с Express, принцип будет знаком: цепочка middleware. Обработчик получает $ — API среды, e — данные события и next — переход к следующему обработчику. Он может пропустить событие дальше, изменить данные или обработать его самостоятельно. Подробности — в руководстве по событиям.
Но есть нюанс: у каждого события свой формат входных данных и ответа. Вернуть deny в любом обработчике не получится. Я бы начинал с конкретной задачи, находил подходящее событие и уже затем смотрел его типы и ограничения. В корпоративном окружении часть возможностей может быть закрыта политикой организации.
События движка
Начнём с событий, которые возникают в работе самого Claude Code: вызов инструмента, отправка промпта, запуск субагента, отрисовка панели. В таблицах — что можно изменить и где это пригодится.
Инструменты
Источник: Mods reference, группа Tools и Guard or change a tool call.
| Событие | Что можно сделать | Возможный сценарий |
|---|---|---|
| `tool.call` | Перехватить вызов, изменить аргументы, отказать, вернуть свой результат или дождаться решения пользователя | Предварительный просмотр рискованной команды; проверка пути перед записью; журнал вызовов |
| `tool.check` | Участвовать в решении `allow`, `ask` или `deny` после остальных проверок, с учётом политик организации | Дополнительное согласование операции в зависимости от ветки Git или состояния задачи |
| `tool.describe` | Изменить описание инструмента; управлять его отложенной загрузкой через tool search | Уточнить назначение похожих инструментов; убрать редко используемый инструмент из начального набора |
Тут важно различать сам вызов и разрешение на него. tool.call позволяет вмешаться в выполнение, tool.check — в решение, можно ли его выполнять. Ещё один нюанс: если мод вернул свой результат вместо вызова инструмента, реальная операция могла вообще не произойти.
Промпты и контекст
Источник: справочник, группа Prompts and what Claude reads. Дополнительные поля редактора описаны в типах PromptEditInput и PromptEditResult; перед реализацией их нужно сверить с установленной версией.
| Событие | Когда срабатывает и что позволяет | Возможный сценарий |
|---|---|---|
| `prompt.submit` | Промпт отправлен: изменить текст, добавить контекст для модели или остановить отправку | Добавить подходящие знания из памяти; добавить сведения о проекте |
| `prompt.fill` | Текст помещается в поле ввода как черновик | Подготовить шаблон запроса на ревью |
| `prompt.suggest` | Появляется подсказка в поле ввода | Предложить следующий шаг по текущему этапу работы |
| `prompt.edit` | Пользователь редактирует ввод; подробный контракт допускает преобразование вставляемого текста | Привести вставленный текст к нужному виду; проверить формат без сетевого запроса на каждое нажатие |
| `prompt.compose` | Собираются разделы системного промпта | Сформировать профиль инструкций для определённого процесса |
| `prompt.section` | Обрабатывается отдельный именованный раздел системного промпта | Заменить раздел либо исключить его, если это разрешено политикой |
| `prompt.context` | Формируется начальный контекст разговора | Добавить сведения о репозитории или согласованной задаче |
| `prompt.attachment` | Claude Code добавляет собственное сообщение, например напоминание | Адаптировать служебную подсказку к рабочему процессу |
| `skill.prompt` | Разворачивается текст навыка | Подставить проектные параметры в инструкцию навыка |
| `attribution.text` | Формируется атрибуция коммита или pull request | Привести подпись к принятому в команде формату |
Значения origin.kind и типы вложений могут меняться от версии к версии. Если логика мода зависит от конкретного значения, проверьте его в локальных типах.
Отдельно про скрытие данных. Можно убрать email с экрана, но он по-прежнему останется в контексте модели или сохранённой истории. Для записи демо это удобно; для удаления чувствительных данных одной такой правки мало.
Команды и настройки
Источник: справочник, группа Commands and configuration; регистрация собственных команд разобрана в Use the mods API.
| Событие | Что происходит | Возможный сценарий |
|---|---|---|
| `command.run` | Выполняется slash-команда; мод может обработать её и вернуть результат | `/harness-status`, `/review-summary`, открытие панели |
| `command.describe` | Формируется описание команды в списке | Понятные описания команд проекта; скрытие ненужной позиции |
| `config.set` | Меняется строка `/config`; значение можно скорректировать или отклонить | Проверить допустимый диапазон настройки |
| `config.describe` | Отображается строка `/config` | Добавить понятное название и пояснение |
Если мод спрятал настройку в интерфейсе, это ещё не значит, что её нельзя поменять другим способом. Обязательные правила нужно проверять там, где они действительно применяются.
Ходы модели
Источник: Follow a turn.
| Событие | Что происходит | Возможный сценарий |
|---|---|---|
| `turn.start` | Начинается ход | Зафиксировать время и состояние задачи |
| `turn.step` | Отправляется очередной запрос модели внутри хода | Выбрать доступную модель или effort для этого запроса; собрать статистику токенов и кэша |
| `turn.complete` | Ход завершился, в том числе после прерывания | Обновить панель, записать длительность и расход, добавить краткую строку результата |
За один ход Claude может несколько раз обратиться к модели и вызвать инструменты. Поэтому на turn.step удобно смотреть отдельные запросы, а на turn.complete — результат всего хода.
У turn.step есть техническая особенность: обработчик работает как async generator. Если хотите подменять ответ модели, придётся разобраться с форматом потока в своей сборке — особенно с thinking- и tool-call-блоками. Совместимость такой подмены с разными моделями нужно проверять отдельно.
Сессия
Источник: справочник, группа Session и обмен сообщениями между сессиями.
| Событие | Что происходит | Возможный сценарий |
|---|---|---|
| `session.start` | Мод начинает работу перед первым промптом и после своей перезагрузки | Зарегистрировать команды и инструменты; запустить таймер обновления панели |
| `session.end` | Завершается сессия либо выполняется переход вроде `/clear`, `/resume`, `/branch` | Короткая финальная запись состояния |
| `session.compact` | Готовится сжатие контекста | Отложить compaction с объяснением; при поддержке контракта уточнить, что сохранить в сводке |
| `session.receive` | Приходит сообщение от другого агента или сессии | Убрать повторные сообщения; отметить входящее сообщение |
| `session.send` | Отправляется сообщение другому агенту или сессии | Проверить адресата; запретить отправку по правилам процесса |
| `session.append` | Строка разговора готовится к сохранению | Преобразовать сохраняемое содержимое в пределах контракта |
| `session.attach` | К сессии подключается другой клиент | Отметить подключение в панели состояния |
| `session.detach` | Клиент отключается | Обновить сведения о подключениях |
| `session.measure` | Обновляются измерения после хода или доля использованного лимита плана | Обновить показатели контекста, лимитов и стоимости |
Подводный камень: /clear, /resume и /branch сами по себе не запускают session.start повторно. Инициализацию мода и смену разговора стоит обрабатывать отдельно.
У session.compact в типах v2.1.277 описаны дополнительные возможности: менять instructions, набор сообщений и возвращать собственный результат сжатия. Если хотите использовать их в своём моде, сначала сверьтесь с типами установленной версии.
С session.append похожая история про данные: изменение одной сохраняемой строки не убирает её из предыдущих запросов, результатов инструментов или других журналов. На одном этом событии обещать полное удаление секрета я бы не стал.
Субагенты
Источник: справочник, группа Subagents.
| Событие | Что можно сделать | Возможный сценарий |
|---|---|---|
| `agent.offer` | Не предлагать определённый тип субагента | Убрать агента, который не подходит текущему этапу |
| `agent.spawn` | Выбрать модель запускаемого субагента или отклонить запуск | Проверить условия запуска; назначить доступную модель по роли |
В опубликованных типах у agent.spawn можно менять и другие параметры: промпт, тип агента, фоновый режим, рабочую директорию. При этом есть исключения — например, fork наследует модель родителя. Поэтому назначить любую модель любому субагенту не получится.
Интерфейс
Источник: Draw in the interface и таблица событий интерфейса.
| Событие | Что происходит | Возможный сценарий |
|---|---|---|
| `ui.render` | Отрисовывается область интерфейса | Панель процесса, индикатор контекста, оформление результата инструмента |
| `ui.resolve` | Формируется таблица доступных UI-элементов | Настройка элементов для последующих модов, если позволяет политика |
| `ui.press` | Нажата кнопка мода | Открыть детали проверки или запустить явно выбранное действие |
| `ui.input` | Изменено поле ввода мода | Фильтрация списка задач |
| `ui.select` | Выбран пункт списка | Переключить представление или профиль |
| `ui.focus` | Меняется фокус внутри панели или полосы над промптом | Управление клавиатурной навигацией |
| `ui.scroll` | Меняется положение прокрутки | Навигация в журнале событий |
| `ui.close` | Закрывается панель | Обработать закрытие пользователем, модом или при выгрузке |
| `ui.message` | Элемент `Client` отправляет данные своему моду | Обмен сообщениями с собственным интерактивным компонентом |
| `ui.fault` | Компонент `Client` не загрузился, не отрисовался или завершился ошибкой исполнения | Показать упрощённый вариант интерфейса и сведения об ошибке |
ui.close есть и среди событий интерфейса, и среди методов API. Для ui.fault в справочнике указана минимальная версия 2.1.289 — на более старой сборке рассчитывать на него не стоит.
Теперь про то, где именно можно рисовать интерфейс. В Render sites перечислены такие области:
| Где рисуем | Имена областей |
|---|---|
| Собственные панели и полоса над промптом | `Pane`, `AbovePrompt` |
| Сообщения и инструменты | `UserMessage`, `AssistantMessage`, `ToolUse`, `ToolResult`, `ToolGroup`, `CommandOutput` |
| Другие элементы | `AskUserQuestion`, `Spinner`, `SessionMode`, `PromptHint` |
| Только терминал | `ToolProgress`, `TurnDuration`, `InfoNotice` |
AskUserQuestion — диалог, в котором агент задаёт пользователю вопросы. Запрос разрешения на действие — другой элемент интерфейса. Возможность изменить первый не означает, что можно перерисовать второй.
Другие моды
Источник: справочник, группа Other mods и корпоративные policy-моды.
| Событие | Что можно сделать | Возможный сценарий |
|---|---|---|
| `plugin.register` | Проверить декларацию загружаемого мода и отказаться от его загрузки | Не допускать расширения, которые запускают процессы или читают определённые переменные окружения |
| `engine.create` | Изменить создаваемый объект mods API | Добавить собственную группу методов или ограничить доступные возможности |
Здесь всё зависит от порядка загрузки. Мод, который проверяет другие расширения, должен стоять раньше них. Как это настроить, показано в административной документации.
Телеметрия
Источник: справочник, группа Telemetry.
| Событие | Назначение | Возможный сценарий |
|---|---|---|
| `telemetry.log` | Перехват записи телеметрии | Фильтрация потока в собственный collector |
| `telemetry.mark` | Событие отметки использования функции | Работа с доступным потоком отметок; наличие фактических событий требует проверки |
Для установленного мода в таблице указан фильтр { to: 'collector' }. Подписка через * телеметрию не захватит. При этом наличие подписки ещё не гарантирует, что в неё придут нужные отметки — это нужно проверить в своей сессии.
Есть и другая тонкость: слушать телеметрию и отправлять собственные записи через $.telemetry.* — разные возможности. Отправка через эти методы разрешена движку и встроенным модам; это отражено в типах telemetry-мода. Поэтому считать их обычным API для аналитики своего плагина не стоит.
Классические события: `classic.*`
Если уже работали с settings hooks, здесь будут знакомые названия. Эти события доступны с префиксом classic. и именем события, например classic.PostToolUse, с соответствующими данными на входе. Связь описана в Mods reference, а допустимые ответы — в Hooks reference.
Ниже — 33 имени из исходной подборки. Для удобства убрал из таблицы повторяющийся префикс, но при регистрации он нужен: classic.PostToolUseclassic.PostToolUse, а не просто PostToolUse.
| События | Возможный сценарий |
|---|---|
| `PreToolUse` | Проверка вызова до выполнения |
| `PostToolUse`, `PostToolUseFailure` | Запись результата либо разбор ошибки инструмента |
| `PostToolBatch` | Сводка после завершения всей группы вызовов, включая параллельные |
| `PermissionRequest`, `PermissionDenied` | Обработка запроса разрешения или отказа в формате, который поддерживает событие |
| `Stop`, `StopFailure` | Проверка завершения работы или обработка нештатного окончания |
| `SubagentStart`, `SubagentStop`, `TeammateIdle` | Наблюдение за жизненным циклом исполнителей |
| `TaskCreated`, `TaskCompleted` | Обновление панели задач |
| `FileChanged`, `CwdChanged`, `DirectoryAdded` | Обновление контекста проекта при изменении файлов и рабочей области |
| `WorktreeCreate`, `WorktreeRemove` | Подготовка и учёт изолированных рабочих деревьев |
| `InstructionsLoaded`, `ConfigChange` | Учёт загруженных инструкций и изменений конфигурации |
| `PreModelSwitch`, `PostModelSwitch` | Проверка или фиксация переключения модели |
| `PreCompact`, `PostCompact` | Сохранение важных фактов вокруг сжатия контекста |
| `Elicitation`, `ElicitationResult` | Обработка запроса дополнительного ввода от MCP-сервера и его результата |
| `MessageDisplay`, `Notification` | Изменение отображения или обработка уведомлений |
| `SessionStart`, `Setup`, `SessionEnd` | Инициализация, настройка и завершение |
| `UserPromptSubmit`, `UserPromptExpansion` | Работа с отправленным запросом и разворачиванием команды в промпт |
Что можно вернуть из обработчика, зависит от события. Например, MessageDisplayMessageDisplay меняет отображение сообщения. Текст, который сохраняется в истории и отправляется модели, остаётся прежним.
И ещё оговорка для корпоративных окружений: при активном sec-default перехват classic.* пользовательским модом может быть недоступен. К этому вернусь в разделе про безопасность.
Mods API: что может делать сам мод
До этого речь шла в основном о действиях агента. Но мод и сам может прочитать файл, запустить процесс или сделать HTTP-запрос. Для этого есть mods API. Например, tool.call позволяет работать с вызовом инструмента, а fs.read — с чтением файла через API самого мода. Ограничения у этих путей различаются.
В справочнике есть общее правило: методы API также доступны как события с именем namespace.method. Часть этих имён уже встречалась выше, поэтому здесь удобнее смотреть на возможности по группам.
| Пространство | Методы из текущей публичной таблицы | Что на этом можно построить |
|---|---|---|
| `fs` | `read`, `write`, `list`, `exists`, `stat`, `ancestors` | Журнал обращений к файлам; ограничение записи |
| `process` | `run`, `spawn` | Учёт и контроль запуска внешних программ |
| `http` | `fetch` | Контроль запросов, проходящих через этот API |
| `mcp` | `call`, `connect` | Работа с MCP-инструментами и серверами |
| `model` | `complete`, `fork`, `classify` | Вспомогательные модельные задачи, проверка параметров вызова |
| `store` | `get`, `set`, `delete`, `keys` | Общее хранилище значений между сессиями на машине |
| `state` | `get`, `set` | Реактивное состояние интерфейса и мода |
| `env` | `get`, `set` | Учёт чтения и изменения переменных окружения |
| `settings` | `read` | Чтение настроек в пределах разрешённого контракта |
| `clock` | `now`, `sleep`, `after`, `every` | Таймеры и фоновое обновление состояния |
| `audio` | `play`, `speak` | Звуковой сигнал или озвучивание статуса |
| `ui` | `resolve`, `invalidate`, `open`, `close`, `panes`, `focus`, `scroll`, `toast`, `status`, `log`, `notice`, `ask`, `copy`, `selection`, `blit` | Панели, навигация, вопросы, уведомления, работа с выделением |
| `command` | `register`, `run`, `list` | Собственные команды и их вызов |
| `tool` | `register`, `call`, `check`, `list` | Регистрация инструментов, вызовы и проверка разрешений |
| `agent` | `register`, `spawn`, `list` | Регистрация и запуск субагентов |
| `config` | `list`, `set` | Доступ к конфигурации |
| `prompt` | `submit`, `read`, `fill`, `suggest`, `compose` | Работа с вводом и запуск следующего хода |
| `turn` | `abort` | Прерывание текущего хода |
| `session` | `messages`, `cwd`, `root`, `model`, `turns`, `id`, `repo`, `surfaces`, `usage`, `version`, `compact`, `send`, `append`, `authorize` | Данные сессии, сообщения, статистика и операции с разговором |
| `telemetry` | `log`, `mark` | Ограниченный служебный API; не универсальная отправка аналитики из пользовательского мода |
Сведения о самом плагине можно получить через $.plugin.name и $.plugin.root. Это свойства; прибавлять их к списку вызываемых методов-событий не нужно.
Ещё два нюанса, на которые я бы обратил внимание:
session.surfaceв старых типах помечен deprecated. Для нового кода смотритеsession.surfaces— это имя используется и в публичном справочнике.- Можно ли перехватывать
ui.askчерезon('ui.ask', ...)? Исходная подборка утверждала, что нельзя. Приведённых материалов недостаточно для уверенного ответа по v2.1.289, поэтому перед реализацией такой проверки нужно испытать свою сборку.
И здесь важен порядок обработчиков: мод видит те вызовы API, которые проходят через него дальше по цепочке. Все процессы и сетевые соединения на машине он таким способом контролировать не начинает.
Подводные камни
Где будет работать интерфейс
С интерфейсом есть ограничения. По таблице сред исполнения, обработчики могут работать в разных типах сессий, если туда загружен плагин. А собственные панели доступны в терминале и поддерживаемых сессиях Desktop.
В панели чата VS Code, claude -p и Agent SDK нельзя рассчитывать на ту же панель. В Remote Control интерфейс мода остаётся в локальном терминале. Для cloud-сессии плагин должен быть доставлен в неё; в WSL-сессиях Desktop плагины не поддерживаются.
Поэтому для важных действий я бы сразу предусмотрел команду или текстовый ответ. Если панель недоступна, пользователь всё равно должен понимать, что произошло и как продолжить.
Время и ошибки
Обработчик не может выполняться бесконечно. В таблице Limits указаны такие ограничения:
| Ограничение | Значение |
|---|---|
| Собственное время обработчика | Обычно 10 секунд |
| `prompt.edit` | 50 мс |
| Обработчик `.catch` | 1 секунда |
| Все `session.end` вместе | По умолчанию 1,5 секунды; бюджет настраивается |
Время ожидания внутри next и большинства API-вызовов обычно не расходует собственный бюджет обработчика. Но $.clock.sleep — исключение: его ожидание учитывается.
Теперь неприятный нюанс. Если обработчик упал до next, а обработчика ошибки нет, хук пропускается. Если ошибка произошла после завершения next, сохраняется уже полученный результат. Для мода, который должен блокировать опасную команду, это принципиально: заранее решите, что делать при собственной ошибке. Пример с .catch и запретом операции есть в документации.
Что на самом деле защищает sec-default
Для Team/Enterprise и окружений с управляемыми настройками есть встроенный guard sec-default: по умолчанию он не позволяет пользовательским модам отменять deny-правила для вызовов инструментов Claude. Администратор может изменить это через allowModsToOverrideDenyRules.
В опубликованном коде sec-default есть ещё одно ограничение: пользовательские моды пропускаются при обработке classic.*, prompt.section, prompt.context, prompt.compose, skill.prompt, attribution.text и settings.read. Обычные settings hooks при этом продолжают работать.
Отказ managed PreToolUse имеет окончательный приоритет. С обычным PreToolUse и правилом ask ситуация другая: мод может изменить итоговое решение. Поэтому фраза «sec-default не даёт обходить permission-правила» требует уточнения — какие именно правила и для каких действий.
Про безопасность
Trade-off никуда не делся: чем больше контроля, тем выше цена ошибки. Мод — это код, который работает с правами вашей учётной записи, включая доступ к файлам, процессам и сети.
Но песочницей мод от этого не становится — его собственные обращения к файлам и запуск процессов через $.fs и $.process правилами для инструментов Claude не ограничиваются. Поэтому доверие к автору расширения всё равно имеет значение.
Отсутствие обычного Node.js-доступа здесь легко принять за изоляцию. На деле мод получает доступ к окружению через mods API. Отсутствие require само по себе ничего не гарантирует; при этом речь идёт о правах вашей учётной записи, а не об автоматическом получении root-прав.
Кэш и повторное выполнение
Динамическое изменение контекста и инструкций может снижать эффективность prompt cache — на это указывает руководство по событиям. Я бы не добавлял в стабильные разделы системного промпта текущее время, случайные идентификаторы и показатели, которые постоянно меняются.
С повторными вызовами тоже стоит быть аккуратнее. Инструмент мог записать файл или отправить сообщение, а затем вернуть ошибку. Если просто запустить его ещё раз, можно получить повторный эффект. Перед добавлением retry проверьте идемпотентность — то есть не создаст ли повторное выполнение ещё одну операцию.
Шаблоны подписки
Подписываться можно и по шаблонам. В опубликованных типах описаны *, варианты вроде tool.*, отрицания и фильтры по значениям, спискам и регулярным выражениям. У телеметрии, как уже разобрали выше, свои ограничения.
Для первого мода я бы выбирал точные имена событий. Так проще понять, что вы действительно перехватили, и не получить лишнюю работу на каждом событии.
Что я бы попробовал собрать
Ниже — несколько идей, с которых можно начать. Для каждой указал события и то, что я бы проверил перед использованием.
| Сценарий | Основные события и методы | Что проверить до использования |
|---|---|---|
| Панель harness-hub | `session.measure`, `turn.complete`, `ui.render`, `$.process.run` | Актуальность данных; не выполняется ли долгая работа во время отрисовки |
| Панель recall | `prompt.submit`, `ui.render`, `$.http.fetch` или MCP | Что именно добавлено в контекст; не добавляются ли одни и те же знания повторно |
| Предпросмотр опасной команды | `tool.call`, `$.ui.ask` | Отказ пользователя, закрытие диалога, тайм-аут, запуск без UI |
| Проверка разрешения по состоянию задачи | `tool.check` | Приоритет managed-политик и взаимодействие с другими модами |
| Выбор модели для отдельного шага | `turn.step`, `agent.spawn` | Доступность модели, стоимость, правила наследования |
| Наблюдение за исполнителями | `agent.spawn`, `turn.complete`, `session.receive`, `session.send` | Различие главного агента и субагентов; повторные доставки |
| Учёт стоимости и задержек | `turn.step`, `turn.complete`, `session.measure` | Не учитывается ли один запрос дважды — отдельно и в сумме за ход |
| Просмотр изменений | `classic.PostToolUse`, `ui.render`, `command.run` | Какие правки действительно выполнены; доступен ли classic-перехват |
| Режим демонстрации | `ui.render` или `classic.MessageDisplay` | Что скрыто только на экране и где данные остаются доступны |
| Политика установки модов | `plugin.register`, перехват API-вызовов | Порядок загрузки и область действия проверки |
Для моего dz-harness самый интересный сценарий — вывести состояние харнесса прямо в Claude Code: на каком этапе задача, какие знания попали в контекст и что показали проверки. Начал бы с панели состояния и recall, где видно, что именно память добавила агенту.
Общую логику, память и проверки я бы сохранял переносимыми между средами. А моды использовал как дополнительный слой интеграции — чтобы происходящее внутри харнесса было проще видеть и контролировать.
План такой интеграции вынес в отдельный issue в dz-harness: панель состояния, отдельное описание того, как мод подключается и работает, и проверка совместимости защит. Там же — последовательность работ и критерии, по которым можно будет проверить результат.
А будут ли моды работать с моделями других разработчиков?
Отдельный вопрос, который хочется проверить на практике. Anthropic не поддерживает подключение non-Claude моделей через шлюзы, поэтому официальную совместимость здесь обещать нельзя.
Можно предположить, что часть обработчиков интерфейса и инструментов будет работать и со сторонним адаптером. Но это предположение по архитектуре. Подтвердить его можно только на конкретной связке.
При этом $.model.complete использует учётные данные сессии, а $.model.fork — её модель и системный промпт; это описано в API. Эти методы сами по себе не дают универсального доступа к любому LLM-провайдеру.
Если уже пробовали — расскажите, какая модель, через какой адаптер и какие именно моды заработали.
Как попробовать и проверить свой мод
В руководстве по созданию модов есть команды для запуска и проверки. Я бы прошёл по ним в таком порядке:
➊ Проверьте установленную версию:
claude --version➋ Посмотрите код плагина, который собираетесь запустить, и выполните статическую проверку:
claude plugin validate ./my-modВ строке hooks: должны быть ожидаемые подписки, в calls: — обращения к API. Успешная валидация говорит о прохождении этой проверки. Работает ли сам сценарий и можно ли доверять коду, нужно разбирать отдельно.
➌ Загрузите мод в тестовом проекте:
claude --plugin-dir ./my-modПосле загрузки смотрите типы внутри его каталога:
.claude-plugin/types/claude-code/index.d.tsЕсли этот файл расходится с веб-документацией, приоритет у локальных типов — документация прямо на это указывает.
➍ Если у мода есть тесты, выполните их из его каталога:
claude plugin test➎ Проверьте, что произойдёт при нормальном выполнении, отказе пользователя, ошибке обработчика, hot reload и запуске без интерфейса. Если мод отвечает за защиту, добавьте второй мод, который пытается изменить разрешение, и посмотрите на итог. Для экспериментов со сторонней моделью запишите версии Claude Code, адаптера и самой модели.
Если плагин загружается, но ничего не делает, начните с проверки загрузки и доверия к проекту. Совет про IS_DEMO=1 из исходной подборки я бы не давал как универсальный: его актуальная связь с запуском mods в приведённых материалах не подтверждена.
Что уточнил при сверке исходной подборки
При подготовке разбора сравнивались разные версии: публичный Mods reference для v2.1.289 и опубликованные типы, помеченные v2.1.277. Поэтому детали из старого файла типов нельзя автоматически переносить в новую сборку.
Локально claude plugin validate и поведенческие тесты не запускались. Утверждения про «138 подтверждённых событий» и «3 115 отклонённых имён» оставил за рамками: без логов и типов той сборки подтвердить эти числа нельзя.
| Что было в исходнике | Что уточнил |
|---|---|
| «138 событий; проверено 3 115 других имён» | Убрал неподтверждённые результаты локального эксперимента |
| Разбиение `44 + 33 + 61` | Не использую как общий итог: группы пересекаются, API зависит от версии |
| `ui.close` только в разделе API | Включил и в события интерфейса |
| В документации нет `ui.fault` и `ui.selection` | В reference v2.1.289 оба имени уже есть |
| `ui.fault` только про загрузку и отрисовку | Добавил ошибку исполнения — фазу `run` |
| `session.surface` как обычный метод | Указал deprecated; для нового кода ориентир — `session.surfaces` |
| `telemetry.mark` практически недоступен | Разделил подписку, наличие событий и право отправлять записи |
| `ui.ask` точно нельзя перехватывать | Оставил вопрос для проверки на конкретной сборке |
| У всех обработчиков 10 секунд | Добавил исключения: `prompt.edit`, `.catch` и общий бюджет `session.end` |
| Любое ожидание API не расходует бюджет | Уточнил исключение для `$.clock.sleep` |
| Хуки работают во всех средах | Добавил условия загрузки плагина и ограничение Desktop/WSL |
| Любой classic-хук может блокировать или менять результат | Уточнил, что допустимый ответ зависит от события |
| sec-default защищает все операции | Уточнил, какие правила он сохраняет и почему собственные вызовы API мода ими не изолированы |
| Поля из старых типов автоматически актуальны для v2.1.289 | Отделил опубликованный снимок от типов установленной сборки |
Мой вывод
Для меня самое интересное здесь — возможность видеть работу агента прямо в процессе: какой контекст он получил, почему остановился, что показали проверки. И там же дать пользователю действие: посмотреть детали, отменить команду или продолжить.
Начал бы с одной понятной задачи. Например, показать, какие знания попали в контекст, или разобрать последствия команды до запуска. Под такую задачу уже проще выбрать событие и понять, приносит ли мод пользу.
С разрешениями, системными инструкциями и потоком ответов работы будет больше: там особенно важны версия API, порядок модов и поведение при ошибках. Эту карту удобно держать под рукой при проектировании. А дальше — собирать небольшой мод и проверять его на своём рабочем сценарии.
Первоисточники
- Mods reference — публичная карта событий, методов, UI и лимитов.
- React to events — middleware, порядок вызовов, ошибки и разрешения.
- Use the mods API — команды, инструменты, модели и обмен сообщениями.
- Draw in the interface — панели и элементы интерфейса.
- Manage mods for your organization — sec-default и корпоративная политика.
- Hooks reference — классические события и их результаты.
- Create a mod — локальные типы, validate и тестирование.
- Mods overview — права и среды исполнения.
- Troubleshoot a mod — диагностика загрузки.
- Типы Anthropic на проверенном коммите — снимок, помеченный v2.1.277.
- Исходник sec-default на том же коммите.
Автор: @llm_notes.
- https://code.claude.com/docs/en/plugins/mods/reference
- https://code.claude.com/docs/en/plugins/mods/events
- https://code.claude.com/docs/en/plugins/mods/api
- https://code.claude.com/docs/en/plugins/mods/interface
- https://code.claude.com/docs/en/plugins/mods/admin
- https://code.claude.com/docs/en/hooks
- https://code.claude.com/docs/en/plugins/mods/create
- https://code.claude.com/docs/en/plugins/mods/overview
- https://code.claude.com/docs/en/plugins/mods/troubleshoot
- https://code.claude.com/docs/en/llm-gateway
- https://github.com/anthropics/claude-code/blob/2bfb629dfaff0c8318047a4beb93cf1dc5b58b18/mods/types/claude-code.d.ts
- https://github.com/anthropics/claude-code/blob/2bfb629dfaff0c8318047a4beb93cf1dc5b58b18/mods/sec-default/hooks/register.ts
Обсудить разбор
Напишите, если хотите разобрать свою задачу в таком же формате