Skip to main content

Ссылка на крючки GitHub Copilot

Найдите события крючков, форматы конфигурации и входные полезные нагрузки для хуков в Второй пилот CLI и Copilot облачный агент.

Introduction

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

Крючки поддерживаются двумя Copilot поверхностями: Второй пилот CLI и Copilot облачный агент. Большинство конфигурационных форматов и событий одинаковы, но окружение выполнения и набор событий, которые могут запускаться, различаются.

На протяжении всей статьи поведение, отличающееся между двумя поверхностями, отмечается в заметках «только для CLI» и «только для облачных агентов». Всё, что не отмечено, относится к обеим.

Местоположение крючков

Места, где запускаются крючки и где можно хранить конфигурационные файлы крючков, зависят от поверхности:

  • **Второй пилот CLI ** — крючки запускаются на локальной машине разработчика в той же оболоке, что и CLI. Все события с крючками, описанные в этой статье, поддерживаются CLI.

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

    • Hook на уровне репозитория —.github/hooks/*.json в корне репозитория.
    • Файлы хуков на уровне пользователя — *.json файлы в каталоге hooks на уровне пользователя. По умолчанию это ~/.copilot/hooks/ на macOS и Linux или %USERPROFILE%\.copilot\hooks\ на Windows. Если COPILOT_HOME установлено, то это .$COPILOT_HOME/hooks/
    • Встроенный hooks блок в настройках репозиторияhooks поле на верхнем уровне ( .github/copilot/settings.json Git committed) или .github/copilot/settings.local.json (обычно gitignore и пользователю) в репозитории. Также читаются кросс-инструменты .claude/settings.json и .claude/settings.local.json файлы в репозитории.
    • Встроенный hooks блок в пользовательской конфигурацииhooks поле на верхнем уровне ~/.copilot/settings.json.
    • Крючки, добавленные установленными плагинами — объявленные каждым плагином в отдельном hooks.json (или ниже hooks/hooks.json) в каталоге установки плагина.
  • **Copilot облачный агент ** — крючки работают внутри эфемерной песочницы Linux, которая предоставляет облачные агенты для каждой задачи. Песочница неинтерактивна, имеет ограниченную сеть и уничтожается после завершения работы. Подмножество событий срабатывает, и признаются только bash (или command) записи.

    Конфигурация крючка загружается из .github/hooks/*.json файлов в клонированном репозитории.

Среда выполнения облачных агентов

Этот раздел применяется только кCopilot облачный агент В нём описываются ограничения, влияющие на то, как вы пишете скрипты hook и настраиваете записи hook для заданий облачных агентов.

НедвижимостьЦенность
Операционная системаLinux. Учитывается только поле bash командных крюков; powershell записи игнорируются. Кросс-платформенное command поле считается запасным вариантом.
Рабочий каталог
          `/workspace` когда репозиторий клонируется, иначе `/root`. Используйте этот путь при установке `cwd` записи hook или при ссылке на файлы из скрипта. |

| Filesystem | Эфемерно. Файлы, написанные с помощью hooks (логи, CSV, транскрипты), выбрасываются после окончания работы. Чтобы сохранить выход крючка, отправьте его через http вход с крючком. | | Исходящая сеть | Ограничен файрволом облачных агентов. По умолчанию доступны только имена хостов GitHub и Copilot; чтобы получить доступ к любому другому хосту (например, https://hooks.example.com), требуется правило разрешения межсетевого экрана, настроенное администратором. | | Доступные переменные среды | GITHUB_COPILOT_API_TOKEN и GITHUB_COPILOT_GIT_TOKEN происходят в песочнице. COPILOT_AGENT_PROMPT удерживает подсказку, с которой была вызвана работа. HOME установлена на /root, поэтому любой скрипт крюка, разрешающий ~/... пути, записывает в эфемерную песочницу. GITHUB_TOKEN не задан. | | Интерактивность | Полностью неинтерактивный. Агент работает с заранее предоставленными всеми разрешениями инструментов, поэтому не отображаются диалоги разрешений и уведомления не появляются пользователю. | | Обнаружение конфигурации | В задании облачного агента по умолчанию существует единственная конфигурация крючка, которая .github/hooks/*.json существует внутри клонированного репозитория. Песочница не поставляется с пользовательскими hook-файлами, settings.json, config.json, или установленными плагинами. |

Формат конфигурации крючка

Конфигурационные файлы крючка используют формат JSON с версией 1.

Командные крючки

Командные хуки запускают shell-скрипты и поддерживаются на всех типах хуков.

Примечание.

Только облачный агент. Облачный агент запускает крючки в песочнице Linux. Признаётся только поле bash ; powershell заявки игнорируются. Кросс-платформенное command поле считается запасным вариантом.

{
  "version": 1,
  "hooks": {
    "preToolUse": [
      {
        "type": "command",
        "bash": "your-bash-command",
        "powershell": "your-powershell-command",
        "cwd": "optional/working/directory",
        "env": { "VAR": "value" },
        "timeoutSec": 30
      }
    ]
  }
}
ПолеTypeОбязательныйDescription
bashstringОдно из значений bash, powershell или command.Команда shell для Unix.
commandstringОдно из значений bash, powershell или command.Кроссплатформенный запасной вариант применяется, когда ни то, ни bash``powershell другое не предусмотрено для текущей платформы.
cwdstringНетРабочая папка для команды (относительно корня репозитория или абсолюта).
envobjectНетПеременные среды для установки (поддерживает расширение переменных).
powershellstringОдно из значений bash, powershell или command.Команда shell для Windows.
timeoutSecНомерНетВремя ожидания в секундах. По умолчанию: 30.
type"command"ДаЭтот параметр должен содержать значение "command".

HTTP-крючки

HTTP-хуки отправляют входную полезность в виде JSON POST на URL.

Примечание.

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

{
  "version": 1,
  "hooks": {
    "postToolUse": [
      {
        "type": "http",
        "url": "https://hooks.example.com/copilot",
        "headers": { "X-Source": "copilot-cli" },
        "allowedEnvVars": ["GITHUB_TOKEN"],
        "timeoutSec": 30
      }
    ]
  }
}
ПолеTypeОбязательныйDescription
allowedEnvVarsstring[]НетИмена переменных среды, которые могут быть расширены внутри headers значений. Когда установлен, url нужно использовать https://.
headersobjectНетЗапросите заголовки для включения.
timeoutSecНомерНетВремя ожидания в секундах. По умолчанию: 30.
type"http"ДаЭтот параметр должен содержать значение "http".
urlstringДаЦелевой URL-адрес. Обязательно использовать http: или https:. Для preToolUse и permissionRequest, обязательно использовать https:// , потому что ответ может предоставлять разрешения инструментам.

Подсказочные зацепки

Подсказочные крючки автоматически отправляют текст так, будто его написал сам пользователь. Они поддерживаются только на sessionStart. Текст может быть подсказкой на естественном языке или командой слэша.

Примечание.

** Второй пилот CLI Только.** Подсказки запускают только для новых интерактивных сессий. Они не срабатывают при возобновлении и не срабатывают в неинтерактивном режиме запросов (-p).

Примечание.

Облачный агент. Задания облачных агентов выполняются неинтерактивно (аналогично -p), поэтому prompt записи с крючками могут не срабатывать. Проверьте поведение в своей среде, прежде чем полагаться на них.

{
  "version": 1,
  "hooks": {
    "sessionStart": [
      {
        "type": "prompt",
        "prompt": "Your prompt text or /slash-command"
      }
    ]
  }
}
ПолеTypeОбязательныйDescription
type"prompt"ДаЭтот параметр должен содержать значение "prompt".
promptstringДаТекст для отправки — это может быть сообщение на естественном языке или команда слэша.

События с крючками

В таблице ниже перечислены все поддерживаемые события. Столбец «Облачный агент» показывает, срабатывает ли событие под облачным агентом, и отмечает различия в поведении.

СобытиеСрабатывает, когдаОбработка выходаОблачный агент
agentStopГлавный агент завершает ход.Да — может блокировать и заставлять продолжение.Пожары.
          `decision: "block"` заставляет делать ещё один ход, который всё равно учитывается в тайм-ауте работы. |

| errorOccurred | Ошибка возникает во время выполнения. | Нет | Пожары. | | notification | Срабатывает асинхронно, когда CLI отправляет системное уведомление (завершение оболочки, завершение работы агента или простоя, запросы разрешения, диалоги вызова). Удар и забыть: никогда не блокирует сессию. Поддерживает matcher regex на notification_type. | Опционально — можно вводить additionalContext в сессию. | Не стреляет. Облачный агент не отображает уведомления пользователю (см. строку интерактивности в таблице среды выполнения облачных агентов выше). | | permissionRequest | Срабатывает до запуска сервиса разрешений (движок правил, утверждение сессии, авторазрешение/автозапрет и подсказка пользователя). Если выход объединённого крючка возвращается behavior: "allow" или "deny", это решение приводит к короткому замыканию нормального потока разрешений. Поддерживает matcher regex на toolName. | Да — можно разрешить или отклонить программно. | Вызовы инструментов предварительно одобрены, поэтому этот крюк либо не срабатывает, либо не действует. Используйте preToolUse для принятия решений по разрешению. | | postToolUse | После успешного завершения каждого инструмента. | Нет | Пожары. | | postToolUseFailure | После того, как инструмент завершается с неудачей. | Да — может предоставить навигацию по восстановлению через additionalContext (код 2 выхода для командных хуков). | Пожары. | | preCompact | Вот-вот начнётся уплотнение контекста (ручное или автоматическое). Поддерживают matcher фильтрацию по триггерам ("manual" или "auto"). | Нет — только уведомление. | Огонь только с trigger: "auto". Нет пользователя, который бы запросил ручное уплотнение. | | preToolUse | Перед тем, как каждый инструмент сработает. | Да — можно разрешать, отрицать или изменять. | Пожары. Решение считается "ask" так "deny" , что нет доступного пользователя для ответа. | | sessionEnd | Сессия заканчивается. | Нет | Пожары — один раз за работу. reason обычно "complete", "error", или "timeout"; "abort" и "user_exit" не ожидаются, потому что пользователя нет. | | sessionStart | Начинается новая или возобновлённая сессия. | Опционально — можно вводить additionalContext в сессию. | Уволяется один раз за каждую работу, как новая сессия (не резюме). См. примечание Prompt hooks выше для поведения prompt записей в облачном агенте. | | subagentStart | Появляется субагент (до его запуска). Поддерживает matcher фильтрацию по имени агента. | Опционально — не может блокировать создание, но additionalContext предшествует подсказке субагента. | Пожары. | | subagentStop | Субагент завершает. | Да — может блокировать и заставлять продолжение. | Пожары. | | userPromptSubmitted | Пользователь отправляет запрос. | Нет | Срабатывает максимум один раз — по запросу, который подают на работу. Нет никакого дополнительного ввода пользователя. |

Полезные нагрузки для ввода событий hook

Каждое событие с крючком доставляет JSON-полезную нагрузку обработчику крючков. Поддерживаются два формата полезной нагрузки, выбираемых по имени события, используемому в конфигурации крючка:

  • camelCase format — Настройте имя события в camelCase (например, sessionStart). Поля используют CamelCase.
  • VS Code совместимый формат — Настройте имя события в PascalCase (например, SessionStart). Поля используют snake_case для соответствия VS CodeCopilot формату расширения.

sessionStart / SessionStart

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;      // Unix timestamp in milliseconds
    cwd: string;
    source: "startup" | "resume" | "new";
    initialPrompt?: string;
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "SessionStart";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    source: "startup" | "resume" | "new";
    initial_prompt?: string;
}

sessionEnd / SessionEnd

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "SessionEnd";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}

userPromptSubmitted / UserPromptSubmit

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    prompt: string;
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "UserPromptSubmit";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    prompt: string;
}

preToolUse / PreToolUse

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    toolName: string;
    toolArgs: unknown;
}
          **
          VS Code Совместимый вход:**

При настройке с именем PreToolUseсобытия PascalCase полезная нагрузка использует snake_case имена полей, чтобы соответствовать формату VS CodeCopilot расширения:

{
    hook_event_name: "PreToolUse";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    tool_name: string;
    tool_input: unknown;    // Tool arguments (parsed from JSON string when possible)
}

postToolUse / PostToolUse

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    toolName: string;
    toolArgs: unknown;
    toolResult: {
        resultType: "success";
        textResultForLlm: string;
    }
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "PostToolUse";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    tool_name: string;
    tool_input: unknown;
    tool_result: {
        result_type: "success";
        text_result_for_llm: string;
    }
}

postToolUseFailure / PostToolUseFailure

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    toolName: string;
    toolArgs: unknown;
    error: string;
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "PostToolUseFailure";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    tool_name: string;
    tool_input: unknown;
    error: string;
}

agentStop / Stop

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    transcriptPath: string;
    stopReason: "end_turn";
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "Stop";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    transcript_path: string;
    stop_reason: "end_turn";
}

subagentStart

          **Входные данные:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    transcriptPath: string;
    agentName: string;
    agentDisplayName?: string;
    agentDescription?: string;
}

subagentStop / SubagentStop

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    transcriptPath: string;
    agentName: string;
    agentDisplayName?: string;
    stopReason: "end_turn";
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "SubagentStop";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    transcript_path: string;
    agent_name: string;
    agent_display_name?: string;
    stop_reason: "end_turn";
}

errorOccurred / ErrorOccurred

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    error: {
        message: string;
        name: string;
        stack?: string;
    };
    errorContext: "model_call" | "tool_execution" | "system" | "user_input";
    recoverable: boolean;
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "ErrorOccurred";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    error: {
        message: string;
        name: string;
        stack?: string;
    };
    error_context: "model_call" | "tool_execution" | "system" | "user_input";
    recoverable: boolean;
}

preCompact / PreCompact

          **Ввод CamelCase:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    transcriptPath: string;
    trigger: "manual" | "auto";
    customInstructions: string;
}
          **
          VS Code Совместимый вход:**
{
    hook_event_name: "PreCompact";
    session_id: string;
    timestamp: string;      // ISO 8601 timestamp
    cwd: string;
    transcript_path: string;
    trigger: "manual" | "auto";
    custom_instructions: string;
}

preToolUse Контроль принятия решений

Крюк preToolUse может управлять выполнением инструмента, записывая JSON-объект в stdout.

ПолеЦенностиDescription
permissionDecision
          `"allow"`, , `"deny"``"ask"` | Работает ли инструмент. Пустой выход использует стандартное поведение. В облачном агенте `"ask"` рассматривается как `"deny"` отсутствие доступного пользователя для ответа. |

| permissionDecisionReason | string | Агенту показали разум. Требуется при принятии решения "deny". | | modifiedArgs | object | Замените аргументы инструментов вместо оригиналов. |

agentStop

           / 
          `subagentStop` Контроль принятия решений
ПолеЦенностиDescription
decision
          `"block"`, `"allow"` | 
          `"block"` заставляет другого агента поступить, используя `reason` это как подсказку. |

| reason | string | Подсказка для следующего хода, когда decision ."block" |

permissionRequest Контроль принятия решений

Примечание.

** Второй пилот CLI Только.** Крючок permissionRequest не применяется в Copilot облачный агент— вызовы инструментов там предварительно одобрены (см. строку интерактивности в таблице среды исполнения облачных агентов). Используйте preToolUse для принятия решений по разрешению в облачном агенте.

          `permissionRequest` Крюк срабатывает до запуска сервиса разрешений — до проверки правил, одобрения сессии, авторазрешения/автозапрета и подсказки пользователя. Если крючки возвращаются `behavior: "allow"` или `"deny"`, это решение приводит к короткому замыканию нормального потока разрешений. Возврат ничего не выходит на обычную обработку разрешений. Используйте его для программного одобрения или отклонения вызовов инструментов — особенно полезно в режиме CLI pipe (`-p`) и других CLI CI, где нет интерактивного запроса. Это не относится к облачному агенту.

Все настроенные permissionRequest крючки работают для каждого запроса (кроме read типов hook с разрешениями, которые срабатывают перед хуками). Выходы крючка объединяются с более поздними выходами хука, переопределяя более ранние.

          **Матчер:** Необязательный регулярный выражение, тестируемое против `toolName`. Закрепленное как `^(?:pattern)$`; должно совпадать с полным именем инструмента. При установке крюк срабатывает только при совпадающих названиях инструментов.

Выводите JSON в stdout, чтобы контролировать решение о разрешении:

ПолеЦенностиDescription
behavior
          `"allow"`, `"deny"` | Одобрить или отклонить этот инструмент. |

| message | string | Причина возвращалась к LLM при отказе. | | interrupt | boolean | В true сочетании с "deny", агент полностью останавливается. |

Вернуть пустой выход или {} провалиться в нормальный поток разрешений. Для командных хуков выходной код 2 рассматривается как отказ; stdout JSON (если он есть) объединяется с {"behavior":"deny"}, а stderr игнорируется.

notification Крюк

Примечание.

** Второй пилот CLI Только.** notification Крюк не стреляет под Copilot облачный агент.

          `notification` Крюк срабатывает асинхронно, когда CLI издаёт системное уведомление. Эти хуки — это система «убери и забудь»: они никогда не блокируют сессию, а любые ошибки фиксируются и пропускаются.

          **Входные данные:**
{
    sessionId: string;
    timestamp: number;
    cwd: string;
    hook_event_name: "Notification";
    message: string;           // Human-readable notification text
    title?: string;            // Short title (e.g., "Permission needed", "Shell completed")
    notification_type: string; // One of the types listed below
}
          **Типы уведомлений:**
TypeКогда он срабатывает
shell_completedЗаканчивается фоновая (асинхронная) команда shell
shell_detached_completedЗавершается отделённая оболочная сессия
agent_completedФоновый субагент заканчивает (выполнен или неудачно)
agent_idleАгент фона заканчивает ход и переходит в состояние простоя (ожидание write_agent)
permission_promptАгент запрашивает разрешение на запуск инструмента
elicitation_dialogАгент запрашивает дополнительную информацию у пользователя
          **Output:**
{
    additionalContext?: string; // Injected into the session as a user message
}

Если additionalContext он возвращается, текст вводится в сессию в виде предварительного пользовательского сообщения. Это может запустить дальнейшую обработку агентов, если сессия находится в простое. Возврат {} или опустошение выхода, чтобы не предпринимать действия.

          **Матчер:** Опциональный регуляр на `notification_type`. Паттерн закреплён как `^(?:pattern)$`. Опустите `matcher` все типы уведомлений.

Фильтрация матчеров

Несколько событий принимают необязательный matcher регулярный выражений на каждом записи крюка, который фильтрует и вызывает срабатывание хука. Узор закреплён как ^(?:matcher)$ и должен соответствовать полному значению. Некорректные регексы приводят к пропуску записи с крюком.

| Событие | matcher против него встречается | |-------|------------------------------| | notification | notification_type | | permissionRequest | toolName | | preCompact | trigger ("manual" или "auto") | | preToolUse | toolName | | subagentStart | agentName |

Имена инструментов для подбора крючков

Имя инструментаDescription
ask_userЗадайте пользователю уточняющий вопрос. В облачном агенте нет пользователя, поэтому ask_user не даёт полезного результата.
bashВыполнять команды оболочки (Unix).
createСоздавайте новые файлы.
editИзменять содержимое файла.
globИщите файлы по шаблону.
grepПоиск по содержимому файла.
powershellВыполнять команды shell (Windows). Не отображается в облачном агенте (песочница Linux).
taskЗапускайте задачи субагентов.
viewЧтение содержимого файла.
web_fetchЗагружайте веб-страницы.

Если настраивать несколько хуков одного типа, они выполняются по порядку. Для preToolUse, если какой-либо крюк возвращается "deny", инструмент блокируется. Сбои хуков (ненулевые коды выхода, кроме 2, или тайм-ауты) регистрируются и пропускаются — они никогда не блокируют выполнение агента.

Коды выхода для командных крючков

Код выходаЗначение
0Успех.
          `stdout` парсируется как выходной JSON для хука, если он присутствует. |

| 2 | По умолчанию это воспринимается как предупреждение. stderr показывают пользователю, но забег продолжается. Для permissionRequest, выход 2 рассматривается как {"behavior":"deny"} , и любой stdout JSON объединяется. Для , выход 2 рассматривается как additionalContext и stdout добавляется к неудаче, postToolUseFailureпоказанному агенту. | | Другие ненулевые значения | Зарегистрировано как сбой с крюком. Запуск продолжается (fail-open). |

Отключить все крючки

Используйте disableAllHooks его, когда хотите сохранить конфигурацию крючка на диске, но остановить её работу — например:

  • Отладка проблемы — и вы хотите убедиться, что причиной является крючок, не удаляя конфигурацию.
  • Приостановка автоматизации во время чувствительной задачи (обзор кода, ветка выпуска, работа с секретами) без потери настройки. (Второй пилот CLI только.)
  • Отправка файла hooks в системе контроля версий, от которого участники могут отказаться локально, установив эту опцию в своём репозитории settings.json. (Второй пилот CLI только.)
  • Временное отключение медленных или шумных хуков во время интерактивной сессии. (Второй пилот CLI только.)

Установите disableAllHooks верхний true уровень, чтобы пропускать все крючки в файле без удаления.

{
  "version": 1,
  "disableAllHooks": false,
  "hooks": {
    "preToolUse": [ /* hook entries */ ]
  }
}

Поведение зависит от того, где вы устанавливаете флаг:

  • Внутри одного .github/hooks/*.json файла пропускаются только объявленные крючки. Удостоен уважения от обоих Второй пилот CLI и Copilot облачный агент.
  • На верхнем уровне репозитория settings.jsonВторой пилот CLI только. Каждый хук из каждого источника (файлы репозитория, пользовательские файлы, плагины и встроенные блоки хуков) пропускается для сессий в этом репозитории. Облачный агент не загружается settings.json.

Дополнительные материалы