TL;DR
- Мод Claude Code состоит из трех файлов:
.claude-plugin/plugin.json,hooks/hooks.jsonс содержимым{"modules":["./index.ts"]}и TypeScript-модуля, который экспортируетregister(on). Для загрузки больше ничего не нужно. - В сборке 2.1.272 типизированный интерфейс, который создает
/plugin-types, занимает 11,783 строки вclaude-code.d.ts: 84 имени событий или вызовов в 23 группах.fs.readFileисчез, теперь этоfs.readиfs.write. - Хук
tool.callв 42 строки заставил модель читатьAPI_KEY=[REDACTED]вместо настоящего ключа и в инструменте Read, и в Bash: 27.9 мс на один нормальный переход и около 0 токенов, добавленных в сессию. - Хук, который спит дольше бюджета в 10 с или падает с исключением, пропускается, и команда ниже выполняется. В логе это видно, а по факту это обход: охранный Мод открыт при сбое (fail-open).
- Сгенерированный путь работает: одна фраза дала Мод на 190 строк плюс 53 строки тестов примерно за 4 минуты и $1.23.
claude plugin validateпрошел без предупреждений,claude plugin testпоказал 4 pass / 0 fail. - Одно не воспроизвелось: Мод загрузился под
claude -p, но молчал в интерактивном REPL через pty в двух попытках. Считайте загрузку в REPL непроверенной, пока не проверите в настоящем терминале.
Что показывают измерения
Все ниже запускалось на Claude Code 2.1.272 с установленной CLAUDE_CODE_ENABLE_FUNCTION_HOOKS: на написанном вручную Моде redact-secrets и на трех одноразовых Модах, созданных, чтобы его сломать. Саму функцию отслеживает предложение Function Hooks, которое пока остается самым близким к официальной спецификации s3.
Инструменты появились раньше документации. Сборка 2.1.272 содержит claude plugin validate, test, eval и details; test работает, хотя plugin --help не показывает его в списке команд s3. Запуск /plugin-types внутри сессии записал 11,783 строки в .claude/types/claude-code.d.ts, а также claude-code-mcp.d.ts на 3,438 строк с 150 MCP-инструментами из 7 серверов s3. В сгенерированных типах 84 имени событий или вызовов в 23 группах, и файл переименовывает одну вещь, о которой вы могли читать в сентябрьских постах: fs.readFile больше нет, интерфейс состоит из fs.read и fs.write s9. Те же типы говорят, что хук tool.call возвращает { result, context? } или { deny }; text и ref приходят из ядра и не входят в собственный ответ хука, поэтому переписывать нужно result, а не text s3.
claude plugin validate печатает footprint до первого запуска Мода: ./index.ts hooks: tool.call и ./index.ts calls: $.ui.toast, либо calls: nothing on $, если модуль не обращается к возможностям хоста s4. Эта статическая строка сегодня единственная проверка, которую каталог вроде awesome-claude-code-mods может автоматизировать, и это важно для следующего абзаца.
Редактирование секретов работает в режиме -p. Хук на 42 строки перехватил tool.call, и модель получила API_KEY=[REDACTED] там, где в файле и в выводе оболочки лежало sk-test1234567890abcdef, и для инструмента Read, и для Bash s3. Лог отладки показал для нормального перехода 27.9 мс на полный цикл, включая переход в worker и next() s3. claude plugin details оценил Мод примерно в 0 токенов, добавленных в каждую сессию: Мод это код внутри процесса, а не текст промпта, и это главный аргумент его сторонников против shell-хуков и skills s7.
Охранник открыт при сбое. Мод slow-guard, который спит 15 с, был прерван на бюджете в 10 с с сообщением hook failed: slow-guard: exceeded 10000ms budget (tool.call; skipped; what is below it ran in its place), и echo hi все равно выполнился s3. Мод throw-guard, который бросает исключение, был пропущен так же: hook failed: throw-guard: boom (tool.call; skipped; what is below it ran in its place), время 574.2 мс s3. В логе громко, по факту обход. Любой Мод, чья задача что-то блокировать, нужно читать с этим в голове: ошибка в охраннике это дыра, а не падение.
Генерация дешевая. По одной фразе модель написала рабочий Мод на 190 строк плюс 53 строки тестов примерно за 4 минуты, 34 хода и $1.23 (19,053 выходных токена, 497,282 прочитанных из кеша, 8,357 токенов рассуждения) s3. Этот Мод прошел claude plugin validate без предупреждений и claude plugin test с результатом 4 pass / 0 fail за 0.31 с и скрывал ключи вживую s3. На написанном вручную Моде claude plugin test отработал без API-ключа и без вызова модели: 1 pass за 0.25 с s3. Skill, который учит агентов писать Моды, уже существует, если хотите повторить опыт по шаблону s12.
Что не воспроизвелось: $.ui.toast ни разу не отобразился, потому что Мод не загрузился в REPL через pty в 2 попытках; в -p аналог проявился только строкой в отладочном логе. Наблюдалось обратное утверждению "только в REPL", которое ходит по X, а первопричину выделить не удалось s8. Heartbeat зависшего worker на 5 с тоже не проверялся; измерены только бюджет ожидания в 10 с и путь с исключением.
Измерения
| Случай | Что делает Мод | Результат | Время |
|---|---|---|---|
| redact-secrets, инструмент Read | Переписывает result в tool.call |
Модель видит API_KEY=[REDACTED] |
27.9 мс на переход |
| redact-secrets, инструмент Bash | Тот же хук, вывод оболочки | Модель видит API_KEY=[REDACTED] |
27.9 мс на переход |
| slow-guard | Спит 15 с внутри tool.call |
Пропущен, echo hi выполнился |
прерван на 10000 мс |
| throw-guard | Бросает boom внутри tool.call |
Пропущен, команда выполнилась | 574.2 мс |
| сгенерированный Мод | 190 строк + 53 строки тестов из одной фразы | validate: без предупреждений; test: 4 pass / 0 fail | ~4 мин, 34 хода, $1.23 |
claude plugin test на redact-secrets |
Без API-ключа, без вызова модели | 1 pass | 0.25 с |
claude plugin details |
Стоимость Мода в сессии | ~0 добавленных токенов | n/a |
Протокол: Claude Code 2.1.272, function hooks включены переменной окружения. Каждый Мод это каталог плагина с plugin.json, hooks/hooks.json и одним index.ts. Запуски шли через claude -p с включенным логом отладки; подготовленный файл и команда оболочки содержали sk-test1234567890abcdef. Случаи fail-open запускались Модом, который спит 15 с, и Модом, который бросает исключение, с echo hi в качестве охраняемой команды. Интерактивный REPL запускался через pty и не загрузил Мод в двух попытках.
Что сделать в понедельник
- Запустите
/plugin-typesв сессии и откройте.claude/types/claude-code.d.ts: найдитеfs.readиtool.call, прежде чем доверять любому сниппету из сентябрьского поста. - Напишите скелет Мода из трех файлов (
plugin.json,hooks/hooks.jsonс{"modules":["./index.ts"]},index.ts, экспортирующийregister(on)) и запустите на немclaude plugin validate: прочитайте строки footprinthooks:иcalls:. - Перенесите самый используемый shell-хук в обработчик
tool.call, который переписываетresult, и сравните время перехода в логе отладки с shell-версией. - Добавьте файл
claude plugin testрядом с Модом, чтобы охранник запускался в CI без API-ключа. - Оберните каждый обработчик-охранник в try/catch, который при сбое возвращает
{ deny }: в этой сборке исключение или зависание на 10 с пропускает вас и пропускает команду. - Проверяйте Мод под
claude -pи в своем настоящем интерактивном терминале по отдельности и записывайте, где он загрузился. - Перед установкой стороннего Мода запустите на нем
claude plugin validateи отклоняйте все, у кого в строкеcalls:указаны возможности хоста, не нужные Моду по смыслу.
Читать дальше
- Прочитайте issue с предложением целиком, включая PDF с архитектурой в комментариях: это единственный письменный контракт для
register(on), бюджетов и перехода в worker s3. - Сравните с дизайном Command Code Mods, который запускает TypeScript против
ModApiв процессе хоста: у систем общая форма и закрытый ранний доступ s2. - Превью claudefa.st написано, когда функция еще была предложением: полезно увидеть, что изменилось между текстом от 3 сентября и бинарником 2.1.272 s9.
- Заметка Prathkum это самое ясное короткое объяснение, почему хуки в процессе выигрывают у shell-хуков по токенам и задержке s7.
- cc-mod-waitwhat хороший первый Мод для чтения: UI над промптом, ничего не пишется в транскрипт s11.
- cc-arcade показывает, как далеко достает
$.ui: игры, нарисованные над промптом из Мода s5. - Справочник по хукам все еще описывает shell-модель; держите его открытым, чтобы сопоставить каждое старое событие с новым именем
noun.events1. - Скептики на X утверждают, что плагины уже все это покрывают, а интерфейс будет ломаться в каждом релизе; переименованная группа
fsэто один аргумент в их пользу s23.
Источники
- Function Hooks proposal (issue #91870), GitHub, anthropics/claude-code. Почему читать: единственный текст, похожий на спецификацию Модов, с PDF об архитектуре и историей выпуска в комментариях.
- Hooks reference, Claude Code docs. Почему читать: shell-модель хуков, с которой вы мигрируете, событие за событием.
- Command Code Mods documentation, Command Code. Почему читать: прототип с той же формой TypeScript внутри процесса, помогает увидеть, что Anthropic скопировала или обошла.
- awesome-claude-code-mods, GitHub, karanb192. Почему читать: автоматически сканируемый каталог публичных Модов, где footprint из validate это единственная проверка.
- cc-arcade, GitHub, sezaakgun. Почему читать: демо, которое сделало функцию заметной, и обзор
$.ui. - Boris Cherny announcement tweet, X, Boris Cherny. Почему читать: заявление о запуске от инженера Anthropic, так как блог-поста нет.
- Prathkum: Function Hooks explained, X, Prathkum. Почему читать: лучшее короткое объяснение хуков против Модов для тех, кто уже пишет shell-хуки.
- shipnotesai reaction thread, X, shipnotesai. Почему читать: где ходило утверждение "только в REPL", которое наш запуск опроверг.
- Claude Code Function Hooks: Preview Behind a Flag, claudefa.st. Почему читать: объяснение до релиза, удобно сверять предложение с бинарником.
- cc-mod-waitwhat, GitHub, GGGODLIN. Почему читать: небольшой читаемый Мод, который пишет в UI, а не в транскрипт.
- claude-mods-skill, GitHub, BeLazy167. Почему читать: skill для генерации Модов, если хотите повторить опыт с одной фразой.
- AxialisSoftware reaction, X, AxialisSoftware. Почему читать: скептическая позиция в одном твите.
FAQ
Заменяет ли Мод мои shell-хуки уже сегодня?
Пока нет, если что-то должно блокироваться. В 2.1.272 хук, который бросает исключение или стоит дольше 10 с, пропускается, и команда выполняется. Shell-хуки продолжают работать, поэтому блокирующие оставьте там, пока не появится объявленный catch или опция fail-closed.
Зачем нужен validate, если Мод и так работает?
Потому что его строки hooks: и calls: это единственный статический взгляд на то, чего Мод касается в $. Для вашего Мода это подтверждение footprint; для стороннего Мода это весь обзор, который вы получаете до запуска кода в вашем процессе.
Сколько стоит Мод за сессию?
claude plugin details показал около 0 добавленных токенов. Мод это код, работающий в движке, а не текст в промпте, и в этом его главное преимущество перед skill или правилом в CLAUDE.md.
Почему Мод загрузился в -p, но не в REPL?
Неизвестно. Две попытки через pty молчали, пока claude -p загружал и применял хук. Вероятная причина в окружении pty, а не в самой функции, поэтому проверьте на своем терминале, прежде чем полагаться на любую из сторон.
AIDive