СведумДокументация

Хуки

Команда или проверка моделью на вашем сообщении, перед шагом агента и после его хода — например, не давать агенту закончить, пока тесты не проходят.

Хук — команда или проверка, которую «Сведум» запускает в определённый момент работы агента: когда вы отправили сообщение, перед шагом, после шага или когда агент закончил ход. Хук может не передать сообщение агенту, запретить шаг, спросить вас или вернуть агента к работе с причиной: «тесты падают», «не обновлён README». Формат тот же, что у хуков Claude Code, — файл .svedum/hooks.json в проекте.

.svedum/hooks.json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [{ "type": "command", "command": "sh scripts/check-before-stop.sh" }]
      }
    ]
  }
}
scripts/check-before-stop.sh
#!/bin/sh
if ! bun test > /tmp/tests.log 2>&1; then
  echo "Тесты падают — исправь и проверь снова:" >&2
  tail -20 /tmp/tests.log >&2
  exit 2
fi

Агент дописал ответ, хук запустил тесты, они упали — агент получает причину из скрипта и продолжает работу в том же ходе. Пока хук работает, в чате видно «Хук проверяет ход»: ход можно остановить, и хук остановится вместе с ним, а сообщение, которое вы напишете в это время, агент прочитает после хука.

События

СобытиеКогда срабатывает
SessionStartПервый ход нового чата и первый запрос после сжатия контекста
UserPromptSubmitВы отправили сообщение, агент его ещё не прочитал
PreToolUseАгент собирается сделать шаг: запустить команду, записать файл, вызвать подключение
PostToolUseШаг сделан
StopАгент закончил ход, и новых сообщений в очереди нет
StopFailureХод закончился ошибкой

Остальные события Claude Code, например Notification и PreCompact, «Сведум» не вызывает.

Виды хуков

  • command — команда в папке проекта. На вход, в stdin, она получает JSON о событии: чат, путь к журналу хода, последний ответ агента, а у хуков шага — сам шаг. Код выхода 2 у Stop возвращает агента к работе, а текст из stderr становится причиной; код 0 — агент заканчивает. Другой код — ошибка хука: всё идёт так, как если бы хука не было.
  • prompt — проверка моделью: в поле prompt — условие, а $ARGUMENTS подставит в него данные события. Условие не выполнено — у Stop агент продолжает с причиной, которую назвала модель, у PreToolUse шаг не выполняется, у UserPromptSubmit сообщение не передаётся агенту. Проверяет недорогая модель; свою задаёт поле model.

timeout задаётся в секундах, как в Claude Code: по умолчанию 600 для command, 30 для command у UserPromptSubmit и 30 для prompt. Значение от 1000 читается как миллисекунды: "timeout": 30000 — это 30 секунд. Подряд хук возвращает агента к работе не больше восьми раз, потом агент заканчивает ход.

Хуки сообщения и начала чата

UserPromptSubmit получает в поле prompt текст, который вы отправили, — и первое сообщение хода, и те, что вы дописали, пока агент работал. Хук может не передать сообщение агенту: код выхода 2, "decision": "block" или "continue": false. Тогда сообщение остаётся в чате с отметкой «Не передано агенту» и причиной из stderr или reason; причину видите только вы, агент не видит ни её, ни само сообщение. Если в ходе больше ничего нет, агент не отвечает.

SessionStart срабатывает на первом ходе нового чата ("source": "startup") и после каждого сжатия контекста ("source": "compact"); matcher сравнивается с source. Остановить агента он не может.

У обоих событий текст, который команда печатает в stdout при коде 0, и additionalContext из JSON агент читает сразу после вашего сообщения или после сводки сжатого контекста — например, текущую ветку или правила на сегодня. В чатах агентов, которых запустил другой агент, эти события не срабатывают.

Если ход пришлось повторить, например после перезапуска «Сведума», хук может сработать на том же сообщении ещё раз: пишите его так, чтобы повтор ничего не ломал.

Хуки шагов

PreToolUse и PostToolUse видят шаг так же, как в Claude Code: команда — это Bash, правка файла — Edit, вызов подключения — mcp__<сервер>__<инструмент>, запуск агента — Agent. В tool_input те же поля, что у Claude Code, например command или file_path с полным путём. Поэтому "matcher": "Edit|Write" из Claude Code работает и здесь; в matcher можно написать и имя инструмента «Сведума», например Shell.

Хук PreToolUse отвечает в hookSpecificOutput.permissionDecision:

  • deny или код выхода 2 — шаг не выполняется, агент получает причину из permissionDecisionReason или stderr.
  • ask — в чате появляется карточка разрешения с причиной хука. Решаете вы, в любом режиме разрешений, даже в «Разрешать всё»; кнопки «Всегда» на такой карточке нет. После «Разрешить» агент повторяет шаг, и он выполняется. Если отвечать некому — например, шаг делает агент, которого запустил другой агент, — шаг не выполняется.
  • allow — шаг идёт как обычно: режим разрешений и «Проверять» решают так же, как без хука. Хук может только запретить или спросить, но не разрешить сверх режима. → Проверка разрешений

updatedInput хук вернуть может, но «Сведум» его не применяет: шаг выполняется таким, каким его задумал агент.

Хук PostToolUse срабатывает, когда шаг уже сделан. Его additionalContext, reason при "decision": "block" или stderr при коде 2 агент прочитает сразу после результата шага — например, «запусти линтер».

Ответ хука в JSON

Вместо кода выхода команда может напечатать в stdout JSON — те же поля, что у Claude Code:

ПолеЧто делает
"decision": "block" и "reason"У Stop: агент продолжает работу, reason — его следующая задача
"decision": "block" у UserPromptSubmitСообщение не передаётся агенту, reason видите только вы
hookSpecificOutput.additionalContextПодсказка агенту; у Stop агент с ней продолжает работу
"continue": falseАгент заканчивает ход, даже если другой хук просит продолжить
stopReasonСообщение вам в чате, когда хук остановил агента
systemMessageСообщение вам в чате; агент его не видит

Если сработало несколько хуков, причины и подсказки всех складываются в одну, а из ответов PreToolUse побеждает самый строгий: deny, затем ask.

Подсказку, которую хук передал агенту, видите и вы: раскройте шаг хода — в нём строка «Хук добавил контекст», а её текст открывается по клику.

Перенос из Claude Code

Импорт из Claude переносит хуки проекта из .claude/settings.json и .claude/settings.local.json в .svedum/hooks.json. Хуки, которые уже есть в .svedum/hooks.json, остаются, импорт только добавляет недостающие. $CLAUDE_PROJECT_DIR в команде становится .: хук и так запускается в папке проекта. Если скрипт хука сам читает эту переменную, поправьте его. Ваши хуки из ~/.claude/settings.json не переносятся: в «Сведуме» хуки живут в проекте и в плагинах. → Переход с Cursor и Claude Code

Что из файла не работает

Файл можно взять из Claude Code целиком. То, чего в «Сведуме» нет, — другие события, хуки типа http и mcp_tool, хуки с async, незнакомые поля — пропускается, а остальное работает. Что пропущено, видно там же, где вы доверяете файлу: в «Персонализации» на вкладке «Подключения».

Доверие

Хуки запускают программы на вашем компьютере, поэтому .svedum/hooks.json работает только после того, как вы ему доверились: в «Персонализации» на вкладке «Подключения» появится карточка «Папка хочет запускать команды» — проверьте файл и нажмите «Доверять». После любого изменения файла «Сведум» спросит снова — и после импорта тоже. Запись в этот файл агент делает только с вашего разрешения: проверка разрешений такой шаг за вас не решает.

У облачного агента, который работает с подключённым репозиторием, хуки из .svedum/hooks.json этого репозитория работают без «Доверять»: репозиторий вы выбрали сами, когда его подключали. Сети у таких хуков нет — как и у команд самого агента на облачном компьютере.

Хуки в плагине

Плагин приносит хуки в файле hooks/hooks.json или в поле hooks своего plugin.json. Они работают, пока плагин включён. В каталог плагины с хуками не принимают — такой плагин ставят из папки. → Формат плагина

На странице