Skip to main content
Мод — это плагин Claude Code plugin с файлом входа, называемым модулем hooks: файл JavaScript или TypeScript, функции которого Claude Code вызывает при возникновении событий. Есть два способа создать мод:
  • Попросите Claude написать его: опишите, что вы хотите в сеансе Claude Code
  • Напишите его сами: следуйте руководству, чтобы узнать, как работает код мода. Вам не нужны Node.js, бандлер или этап сборки, потому что Claude Code загружает файлы .js и .ts напрямую.
Если вы еще не решили, является ли мод правильным инструментом, сначала прочитайте сравнение на странице обзора.
Моды требуют Claude Code v2.1.287 или позже. В вашей оболочке выполните claude --version, чтобы проверить. Чтобы узнать, могут ли моды загружаться для вас, см. Проверка возможности загрузки модов.

Попросите Claude написать мод

Опишите нужный вам мод в интерактивном сеансе Claude Code, и Claude напишет его. Claude работает из встроенного skill с именем plugin-authoring, который сообщает ему, где написать мод, какие события и методы есть в вашей версии, и как загружается мод. Claude может загрузить skill, когда вы попросите мод, или вы можете загрузить его сами, выполнив /plugin-authoring в приглашении Claude Code. Мод запускается после того, как вы его одобрите, кроме сеансов, где мод, написанный Claude, не может загрузиться.
1

Опишите мод

Попросите мод своими словами, например make a mod that shows the current git branch above the prompt. Claude пишет мод в отдельном каталоге в папке модов сеанса, которая находится в ~/.claude/dev-mods/, за которой следует ID сеанса. Полный путь мода выглядит как ~/.claude/dev-mods/3f2a9c1e-5b7d-4e8a-9c21-6d0f4b8a7e13/git-branch/.
В режимах разрешений default и acceptEdits permission modes Claude Code спрашивает перед тем, как Claude создаст каждый из файлов мода, потому что ~/.claude — это защищённый путь. Одобрите каждый файл по мере его появления.
2

Одобрите мод

Когда Claude сохраняет первый файл, Claude Code спрашивает, следует ли включить горячую перезагрузку для сеанса. Горячая перезагрузка запускает моды, написанные Claude в этом сеансе, и подхватывает каждое последующее изменение.Выберите один из этих ответов:
  • Enable for this session: моды в папке модов сеанса загружаются при завершении хода и перезагружаются в конце каждого хода, который их изменяет. Ваш ответ действует для сеанса, включая после его возобновления.
  • Not now: ничего не загружается пока. Файлы остаются там, где их написал Claude, и моды загружаются при следующем запуске этого сеанса. Чтобы мод никогда не загружался, удалите его каталог.
3

Проверьте, что мод загрузился

Выполните /plugin в приглашении Claude Code и нажимайте Tab, пока не будет выбрана вкладка Installed. Она перечисляет мод, и вы можете отключить его там.
4

Попробуйте мод

Используйте то, что вы просили. Для примера приглашения текущее имя ветки появляется над полем приглашения. Если мод не делает то, что вы хотели, скажите Claude, что изменить. Мод перезагружается в конце каждого хода, который изменяет его файлы, поэтому вы можете попробовать изменение сразу после завершения Claude.

Используйте мод в других сеансах

Мод, написанный Claude, загружается только в сеансе, который его создал, и Claude Code удаляет папку модов этого сеанса после того, как она старше cleanupPeriodDays. Чтобы сохранить мод, скопируйте его каталог из папки модов в место по вашему выбору, например ~/mods/git-branch. Затем выберите, как его загружать:
  • В сеансе, который вы запускаете: в вашей оболочке выполните claude --plugin-dir ~/mods/git-branch
  • Для других людей: добавьте его на маркетплейс, чтобы они могли его установить

Сеансы, где мод, написанный Claude, не может загрузиться

Мод, написанный Claude, загружается только после того, как вы его одобрите, в доверенной рабочей области, где разрешено запускать моды. В этих сеансах он не загружается:
  • Никого нет, чтобы одобрить: сеанс не может показать вам приглашение, как в запуске claude -p или в режиме dontAsk
  • Рабочая область не доверена: вы не приняли приглашение доверия для каталога
  • Моды остановлены: вы запустили с --safe-mode или --bare, вы установили disableAllHooks, или управляемые параметры вашей организации это блокируют

Напишите мод сами

В этом руководстве вы создаёте мод с именем first-mod, который подсчитывает вызовы инструментов, которые делает Claude, показывает счётчик рядом со спиннером во время работы Claude и добавляет команду /tally, которая его выводит. Затем вы читаете объявления типов, которые Claude Code пишет рядом с вашим модом, и выполняете claude plugin validate. Вместе они показывают вам события и методы, которые предлагает ваша версия, и что Claude Code читает из вашего кода. Эта запись показывает готовый мод. Спиннер подсчитывает вызовы инструментов, /tally выводит счётчик, и редактирование кода вступает в силу во время работы сеанса:
Вы пишете три файла:
1

Создайте каталог плагина

Создайте два каталога, которые содержат файлы:
2

Напишите манифест

Мод — это плагин, и моду нужен манифест. Манифест этого мода не имеет специальных полей. Сохраните это как first-mod/.claude-plugin/plugin.json:
first-mod/.claude-plugin/plugin.json
3

Скажите Claude Code, где находится ваш код

Когда Claude Code загружает плагин, он читает hooks/hooks.json плагина. Ключ modules в этом файле указывает путь к вашему коду, и его наличие делает плагин модом. Перечислите один путь, относительный к hooks.json. Здесь он указывает на register.js, который вы напишете на следующем шаге.Сохраните это как first-mod/hooks/hooks.json:
first-mod/hooks/hooks.json
4

Напишите код

Этот файл — это код мода, называемый модулем hooks. Когда мод загружается, Claude Code вызывает функцию register, которую экспортирует файл, и передаёт ей функцию с именем on. Каждый вызов on регистрирует обработчик события, называемый hook, для события, которое он называет.Сохраните это как first-mod/hooks/register.js:
first-mod/hooks/register.js
Файл хранит счётчик в calls и регистрирует четыре hook:
  • session.start запускается при запуске сеанса, перед вашим первым приглашением, и снова каждый раз, когда мод перезагружается. Он добавляет команду /tally в Claude Code.
  • tool.call запускается каждый раз, когда Claude собирается использовать инструмент. Он добавляет один к calls и просит Claude Code нарисовать интерфейс снова.
  • command.run запускается, когда вы вводите /tally. Он возвращает текст для вывода.
  • ui.render запускается каждый раз, когда Claude Code рисует спиннер. Он добавляет счётчик после слова спиннера.
Как работает пример мода объясняет три аргумента, которые принимает каждый hook, и что каждый из них возвращает.
5

Загрузите мод

Запустите Claude Code с флагом --plugin-dir, который загружает каталог плагина для одного сеанса без его установки:
6

Попробуйте мод

Попросите Claude сделать что-то, что требует нескольких вызовов инструментов, например list the files here and read the README. Пока Claude работает, слово спиннера сопровождается счётчиком, который растёт, как в Thinking · tool calls: 2…. Когда Claude закончит, введите /tally и нажмите Enter. Транскрипт показывает first-mod: Claude has made 2 tool calls since this mod loaded с вашим собственным счётчиком. Claude Code ставит имя плагина перед текстом команды.Чтобы проверить команду без интерактивного сеанса, выполните её в неинтерактивном режиме:
Если /tally не в списке команд, модуль не загрузился. См. Узнайте, почему мод ничего не делает.
7

Измените код во время работы сеанса

Оставьте сеанс открытым. В register.js измените ' · tool calls: ' на ' · tools used: ' в hook ui.render и сохраните. Выделенная строка — это та, которая изменяется:
first-mod/hooks/register.js
Строка в транскрипте говорит, что first-mod перезагрузился и перечисляет его hooks, и следующий спиннер использует новый текст, как в Thinking · tools used: 1….

Как работает пример мода

Каждая функция, которую вы передаёте on, — это hook, который является обработчиком события. Claude Code передаёт каждому hook одни и те же три аргумента:
  • API модов, названный $: каждый метод, который мод может вызвать, чтобы выйти за пределы себя, в пространствах имён таких как $.ui и $.command
  • Событие, названное e: входные данные события как простые данные, такие как имя и аргументы вызова инструмента
  • Следующий обработчик, названный next: функция, которая передаёт событие другим модам, а затем собственному поведению Claude Code, и возвращает результат
Hooks в first-mod обрабатывают свои события тремя способами, которыми может обрабатывать hook:
  • Observe: hook session.start регистрирует команду, и hook tool.call подсчитывает вызов и просит перерисовку. Оба возвращают next(e), поэтому сеанс запускается и инструмент работает как обычно.
  • Answer: hook command.run возвращает свой собственный результат и никогда не вызывает next. Второй аргумент on, { command: 'tally' }, — это фильтр, называемый matcher, поэтому hook запускается только для /tally.
  • Rewrite: hook ui.render вызывает next с копией e, чей suffix содержит счётчик, поэтому Claude Code рисует свой обычный спиннер с вашим текстом после слова
Claude Code следит за каталогом, загруженным с --plugin-dir, и горячо перезагружает модуль hooks при изменении файла в нём. Каждая перезагрузка запускает register снова, поэтому calls возвращается к 0 и /tally начинает считать снова. Чтобы сохранить значение между перезагрузками, см. Сохранение состояния.

Продолжайте работать над модом

После загрузки мода вы можете попросить Claude изменить его, проверить ваш код против определений типов для вашей версии, перечислить события и вызовы, которые Claude Code находит в нём, и протестировать его.

Измените мод с помощью Claude

Чтобы изменить мод, который у вас уже есть, запустите сеанс с --plugin-dir, указывающим на каталог мода, чтобы то, что пишет Claude, загружалось в том же сеансе:
Затем попросите изменение, например add a /tally-reset command to this mod that sets the tally back to zero. Claude редактирует модуль hooks, выполняет claude plugin validate и исправляет то, что он сообщает. Каталог, который вы загружаете с --plugin-dir, — это защищённый путь, поэтому в режимах default и acceptEdits вас просят одобрить каждое редактирование Claude мода. Таблица защищённых путей даёт результат для других режимов разрешений. Файлы, которые Claude сохраняет во время его хода, перезагружаются при завершении хода, поэтому вы можете попробовать /tally-reset сразу после завершения Claude.

Получите определения типов для вашей версии

Каждый раз, когда Claude Code загружает или перезагружает мод из каталога, который вы передаёте --plugin-dir, или мод Claude написал для вас, он пишет файлы объявлений TypeScript, заканчивающиеся на .d.ts, в .claude-plugin/types/ внутри каталога мода. Они описывают точные события, методы API модов и элементы в версии Claude Code, которую вы запускаете, поэтому ваш редактор может автодополнять и проверять типы ваших hooks. Чтобы просмотреть объявления в Интернете, прочитайте mods/types/claude-code.d.ts в репозитории Claude Code, первая строка которого называет версию, которая его написала. Каталог содержит эти файлы: Если ваш мод не имеет собственного tsconfig.json, Claude Code добавляет один в корень мода, который расширяет сгенерированный, поэтому ваш редактор и tsc -p ./first-mod проверяют тип мода без дополнительной настройки. События и методы могут изменяться между выпусками, поэтому доверяйте этим файлам больше, чем любой странице, включая эту, когда они не согласны. claude-code/index.d.ts — это самый полный справочник для вашей сборки, с комментарием и примером для каждого метода API модов. Чтобы что-то найти, поищите в файле его имя, например 'tool.call'.

Проверьте, что Claude Code читает из вашего мода

Чтобы увидеть ваш мод так, как Claude Code его видит, без запуска вашего кода или запуска сеанса, используйте claude plugin validate. Он проверяет манифест и выполняет тот же статический анализ на исходном коде модуля hooks, который Claude Code выполняет при загрузке мода. В вашей оболочке выполните его на каталоге мода:
Для first-mod вывод включает эти строки.
Строка hooks: перечисляет события, которые ваш модуль hook, каждое с его фильтром в скобках. Строка calls: перечисляет каждый метод API модов, который он вызывает. Модуль, который читает или устанавливает переменные окружения, также получает строки env reads: и env writes:, и тот, который использует $.state, получает state reads: и state writes:. Если событие, которое вы хотели hook, отсутствует в первой строке, Claude Code не будет вызывать этот hook либо. Обычная причина — неправильное написание имени события, которое команда сообщает как ошибку, такую как "tool.calls" is not an event. Следуйте этим правилам, чтобы статический анализ мог найти каждый hook и вызов:
  • Напишите каждый вызов API модов полностью: $, пространство имён, затем метод, как в $.store.get('notes'). Вы можете передать $ функции, объявленной на верхнем уровне того же файла, и для функции вашей с именем loadNotes строка calls: затем читает $.store.get (via loadNotes). Передача $ методу, функции, определённой внутри hook, или функции, которую вы импортируете из другого из ваших файлов, не проходит валидацию. Функции read и update, которые использует $.state, — это импорты, которые могут её принять. Не присваивайте $ или одно из его пространств имён переменной, не деструктурируйте его и не индексируйте его с вычисленным именем. const ui = $.ui не проходит с $.ui is used as a value.
  • Напишите имя события в каждом вызове on как строковый литерал, например 'tool.call'. Переменная или цикл по списку имён не проходит с the event name passed to on() is not a string literal.
  • Внутри register не объявляйте вторую переменную или параметр с именем on. Валидация не проходит с "on" is declared again (shadowed).
  • Импортируйте только из файлов внутри каталога плагина, по относительному пути. Единственный разрешённый голый импорт — это claude-code, для типов и нескольких помощников.
  • Используйте объявления import в верхней части файла, как в import { name } from './file.js'. Динамический import() не проходит с a dynamic import(); a hooks module imports its own files with an import declaration.
  • Напишите каждый файл как модуль ES, с import, а не require. Справочник перечисляет расширения файлов, которые загружает Claude Code.

Протестируйте мод

Вы можете написать автоматизированные тесты для мода и запустить их из вашей оболочки с claude plugin test, без сеанса, входа или сети. Тест вызывает события, которые обрабатывают ваши hooks, и проверяет, что сделали hooks. Этот тест вызывает два вызова инструментов, запускает /tally и проверяет, что ответ считает оба. Сохраните это как first-mod/tests/first-mod.test.ts:
first-mod/tests/first-mod.test.ts
В вашей оболочке выполните тесты из каталога first-mod:
Вывод называет каждый тест и прошёл ли он, с временем, которое варьируется от запуска к запуску:
Протестируйте мод охватывает заглушку вызова модели или хранилища, и тестирование таймеров и рисунков.

Поделитесь своим модом

Мод — это плагин, поэтому вы версионируете его в манифесте, и люди устанавливают и обновляют его с помощью команд /plugin. Чтобы дать его другим людям, добавьте его на маркетплейс. Перед этим проверьте name плагина: claude plugin validate не проходит имя, которое выглядит как одно из собственных Anthropic, например то, которое начинается с claude-. События и методы могут изменяться между выпусками, поэтому ваш README — это место, где нужно сказать, какую версию Claude Code вы тестировали. Продолжайте разработку против каталога с --plugin-dir, а не против установленной копии. Claude Code кэширует установленный плагин по версии, поэтому ваши редактирования не достигают установленной копии, пока вы не повысите версию и не установите снова.

Следующие шаги