feat(hooks): Add HTTP Hook, Function Hook and Async Hook support (#2827)

* add http/async/function type

* fix url error

* resolve comment

* align cc non blocking error

* fix hookRunner for async

* fix(hooks): update hook type validation to support http and function types

- Change validated hook types from ['command', 'plugin'] to ['command', 'http', 'function']
- Add validation for HTTP hooks requiring url field
- Add validation for function hooks requiring callback field
- Add comprehensive test coverage for all hook type validations

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(hooks): align SSRF protection with Claude Code behavior

- Allow 127.0.0.0/8 (loopback) for local dev hooks
- Allow localhost hostname for local dev hooks
- Allow ::1 (IPv6 loopback) for local dev hooks
- Add 100.64.0.0/10 (CGNAT) to blocked ranges (RFC 6598)
- Update tests to match Claude Code's ssrfGuard.ts behavior

This fixes HTTP hooks failing to connect to local dev servers.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* refactor(hooks): align HTTP hook security with Claude Code behavior

- Add CRLF/NUL sanitization for env var interpolation (header injection)
- Implement combined abort signal (external signal + timeout)
- Upgrade SSRF protection to DNS-level with ssrfGuard
  - Allow loopback (127.0.0.0/8, ::1) for local dev hooks
  - Block CGNAT (100.64.0.0/10) and IPv6 private ranges
- Increase default HTTP hook timeout to 10 minutes
- Fix VS Code hooks schema to support http type
  - Add url, headers, allowedEnvVars, async, once, statusMessage, shell fields
  - Note: "function" type is SDK-only (callback cannot be serialized to JSON)

* feat(hooks): enhance Function Hook with messages, skillRoot, shell, and matcher support

- Add MessagesProvider for automatic conversation history passing to function hooks
- Add FunctionHookContext with messages, toolUseID, and signal
- Add skillRoot support for skill-scoped session hooks
- Add shell parameter support for command hooks (bash/powershell)
- Add regex matcher support for hook pattern matching
- Add statusMessage to CommandHookConfig
- Change default function hook timeout from 60s to 5s
- Add comprehensive unit tests for all new features

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* add session hook for skill

* fix function hook parsing

* refactor ui for http hook/async hook/function hook

* update doc and add integration test

* change telemetryn type and refactor SSRF

* fix project level bug

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
DennisYu07 2026-04-16 10:10:33 +08:00 committed by GitHub
parent 70396d1276
commit b5115e731e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 9301 additions and 469 deletions

View file

@ -131,18 +131,36 @@ const HOOK_DEFINITION_ITEMS: SettingItemDefinition = {
items: {
type: 'object',
description:
'A hook configuration entry that defines a command to execute.',
'A hook configuration entry that defines a hook to execute.',
properties: {
type: {
type: 'string',
description: 'The type of hook.',
enum: ['command'],
description:
'The type of hook. Note: "function" type is only available via SDK registration, not settings.json.',
enum: ['command', 'http'],
required: true,
},
command: {
type: 'string',
description: 'The command to execute when the hook is triggered.',
required: true,
description:
'The command to execute when the hook is triggered. Required for "command" type.',
},
url: {
type: 'string',
description:
'The URL to send the POST request to. Required for "http" type.',
},
headers: {
type: 'object',
description:
'HTTP headers to include in the request. Supports env var interpolation ($VAR, ${VAR}).',
additionalProperties: { type: 'string' },
},
allowedEnvVars: {
type: 'array',
description:
'List of environment variables allowed for interpolation in headers and URL.',
items: { type: 'string' },
},
name: {
type: 'string',
@ -154,7 +172,7 @@ const HOOK_DEFINITION_ITEMS: SettingItemDefinition = {
},
timeout: {
type: 'number',
description: 'Timeout in milliseconds for the hook execution.',
description: 'Timeout in seconds for the hook execution.',
},
env: {
type: 'object',
@ -162,6 +180,25 @@ const HOOK_DEFINITION_ITEMS: SettingItemDefinition = {
'Environment variables to set when executing the hook command.',
additionalProperties: { type: 'string' },
},
async: {
type: 'boolean',
description:
'Whether to execute the hook asynchronously (non-blocking, for "command" type only).',
},
once: {
type: 'boolean',
description:
'Whether to execute the hook only once per session (for "http" type).',
},
statusMessage: {
type: 'string',
description: 'A message to display while the hook is executing.',
},
shell: {
type: 'string',
description: 'The shell to use for command execution.',
enum: ['bash', 'powershell'],
},
},
},
},
@ -1338,6 +1375,20 @@ const SETTINGS_SCHEMA = {
},
},
},
allowedHttpHookUrls: {
type: 'array',
label: 'Allowed HTTP Hook URLs',
category: 'Security',
requiresRestart: false,
default: [] as string[],
description:
'Whitelist of URL patterns for HTTP hooks. Supports * wildcard. If empty, all URLs are allowed (subject to SSRF protection).',
showInDialog: false,
items: {
type: 'string',
description: 'URL pattern (supports * wildcard)',
},
},
},
},