fix(node): sync transactional Codex hooks

This commit is contained in:
ZacharyZhang-NY committed 2026-07-20 02:14:25 -04:00
1 parent 91b4251fea
commit f501df5077
23 files changed
+2898 -1657

No files matched your search

-294
View File
@@ -248,297 +248,3 @@ test('adapter delivery claims resolve to source files in every SDK mirror', asyn
}
}
});
test('high-drift providers retain their verified hook contracts', async () => {
const catalog = await readJson('integrations/catalog.json');
const providers = new Map(catalog.providers.map((provider) => [provider.id, provider]));
assert.deepEqual(providers.get('augment').config_paths, [
'/etc/augment/settings.json',
'C:\\ProgramData\\Augment\\settings.json',
'.augment/settings.local.json',
'.augment/settings.json',
'~/.augment/settings.json',
]);
assert.deepEqual(providers.get('augment').events, {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
});
assert.deepEqual(providers.get('augment').event_fields, {
name: 'tool_name',
input: 'tool_input',
session: 'conversation_id',
});
assert.deepEqual(providers.get('augment').blocking, {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
});
assert.deepEqual(providers.get('codex').config_paths, [
'~/.codex/hooks.json',
'.codex/hooks.json',
]);
assert.deepEqual(providers.get('codex').contract_variants, [
{
id: 'inlinetoml',
release_channel: 'stable',
activation: 'Hooks configured inline in an active Codex config.toml or managed requirements.toml layer',
config_format: 'toml',
config_paths: [
'~/.codex/config.toml',
'.codex/config.toml',
'requirements.toml',
],
events: {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
},
event_fields: {
name: 'tool_name',
input: 'tool_input',
session: 'session_id',
},
blocking: {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
},
source_url: 'https://learn.chatgpt.com/docs/hooks',
},
{
id: 'pluginbundle',
release_channel: 'stable',
activation: 'An enabled Codex plugin supplies hooks through its manifest or default hooks file',
config_format: 'plugin',
config_paths: [
'.codex-plugin/plugin.json',
'hooks/hooks.json',
],
events: {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
},
event_fields: {
name: 'tool_name',
input: 'tool_input',
session: 'session_id',
},
blocking: {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
},
source_url: 'https://learn.chatgpt.com/docs/hooks',
},
]);
assert.deepEqual(providers.get('copilot').config_paths, [
'$COPILOT_HOME/hooks/*.json',
'~/.copilot/hooks/*.json',
'.github/hooks/*.json',
]);
assert.deepEqual(providers.get('copilot').events, {
before_tool: 'preToolUse',
after_tool: 'postToolUse',
});
assert.deepEqual(providers.get('copilot').event_fields, {
name: 'toolName',
input: 'toolArgs',
session: 'sessionId',
});
assert.deepEqual(providers.get('copilot').blocking, {
mechanism: 'any_nonzero_exit',
failure_mode: 'fail_closed',
timeout_failure_mode: 'fail_open',
});
assert.equal(providers.get('cursor').surface, 'cli_and_ide');
assert.deepEqual(providers.get('cursor').config_paths, [
'/Library/Application Support/Cursor/hooks.json',
'/etc/cursor/hooks.json',
'C:\\ProgramData\\Cursor\\hooks.json',
'.cursor/hooks.json',
'~/.cursor/hooks.json',
]);
assert.deepEqual(providers.get('cursor').events, {
before_tool: 'preToolUse',
after_tool: 'postToolUse',
});
assert.deepEqual(providers.get('cursor').event_fields, {
name: 'tool_name',
input: 'tool_input',
session: 'conversation_id',
});
assert.deepEqual(providers.get('cursor').blocking, {
mechanism: 'exit_code_2',
failure_mode: 'configurable',
});
assert.deepEqual(providers.get('droid').config_paths, [
'~/.factory/hooks.json',
'~/.factory/settings.json',
'.factory/hooks.json',
'.factory/settings.json',
]);
assert.deepEqual(providers.get('droid').events, {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
});
assert.deepEqual(providers.get('droid').event_fields, {
name: 'tool_name',
input: 'tool_input',
session: 'session_id',
});
assert.deepEqual(providers.get('droid').blocking, {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
});
assert.deepEqual(providers.get('droid').contract_variants, [
{
id: 'nestedhooks',
release_channel: 'legacy',
activation: 'An existing nested hooks file remains active until Droid saves and archives it',
config_format: 'json',
config_paths: [
'~/.factory/hooks/hooks.json',
'.factory/hooks/hooks.json',
],
events: {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
},
event_fields: {
name: 'tool_name',
input: 'tool_input',
session: 'session_id',
},
blocking: {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
},
source_url: 'https://docs.factory.ai/reference/hooks-reference',
},
]);
assert.equal(providers.get('cline').integration_mode, 'command_hooks');
assert.equal(providers.get('cline').config_format, 'script');
assert.deepEqual(providers.get('cline').config_paths, [
'~/Documents/Cline/Hooks/',
'$CLINE_DIR/hooks/',
'.clinerules/hooks/',
'.cline/hooks/',
]);
assert.deepEqual(providers.get('cline').events, {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
});
assert.deepEqual(providers.get('cline').event_fields, {
name: 'tool_call.name/tool_result.name',
input: 'tool_call.input/tool_result.input',
session: 'taskId',
});
assert.deepEqual(providers.get('cline').blocking, {
mechanism: 'json_stdout_cancel',
failure_mode: 'fail_open',
});
assert.deepEqual(providers.get('kimi').events, {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
});
assert.equal(providers.get('kimi').config_format, 'toml');
assert.deepEqual(providers.get('kimi').config_paths, [
'$KIMI_CODE_HOME/config.toml',
'~/.kimi-code/config.toml',
]);
assert.deepEqual(providers.get('kimi').contract_variants, [
{
id: 'pythoncli',
release_channel: 'legacy',
activation: 'kimi-cli',
config_format: 'toml',
config_paths: ['~/.kimi/config.toml'],
events: {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
},
event_fields: {
name: 'tool_name',
input: 'tool_input',
session: 'session_id',
},
blocking: {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
},
source_url: 'https://moonshotai.github.io/kimi-cli/en/customization/hooks.html',
},
]);
assert.deepEqual(providers.get('grok').event_fields, {
name: 'toolName',
input: 'toolInput',
session: 'sessionId',
});
assert.deepEqual(providers.get('grok').config_paths, [
'$GROK_HOME/hooks/*.json',
'~/.grok/hooks/*.json',
'.grok/hooks/*.json',
]);
assert.deepEqual(providers.get('grok').events, {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
});
assert.deepEqual(providers.get('grok').blocking, {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
});
assert.deepEqual(providers.get('kirocli').config_paths, [
'~/.kiro/agents/*.json',
'.kiro/agents/*.json',
]);
assert.deepEqual(providers.get('kirocli').contract_variants, [
{
id: 'v3',
release_channel: 'early_access',
activation: 'kiro-cli --v3',
config_format: 'json',
config_paths: ['~/.kiro/hooks/*.json', '.kiro/hooks/*.json'],
events: {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
},
event_fields: {
name: 'tool_name',
input: 'tool_input',
session: 'session_id',
},
blocking: {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
},
source_url: 'https://kiro.dev/docs/cli/v3/hooks/',
},
]);
assert.deepEqual(providers.get('kiroide').config_paths, [
'.kiro/hooks/*.json',
]);
assert.deepEqual(providers.get('kiroide').events, {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
});
assert.deepEqual(providers.get('kiroide').blocking, {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
});
assert.equal(providers.get('qwen').config_format, 'json');
assert.deepEqual(providers.get('qwen').config_paths, [
'$QWEN_HOME/settings.json',
'~/.qwen/settings.json',
'.qwen/settings.json',
]);
assert.deepEqual(providers.get('qwen').events, {
before_tool: 'PreToolUse',
after_tool: 'PostToolUse',
});
assert.deepEqual(providers.get('qwen').event_fields, {
name: 'tool_name',
input: 'tool_input',
session: 'session_id',
});
assert.deepEqual(providers.get('qwen').blocking, {
mechanism: 'exit_code_2',
failure_mode: 'fail_open',
});
});