fix: align Cursor hook contract
This commit is contained in:
1 parent
16e7e7a9a6
commit
4f9108099c
4 files changed
+36
-4
No files matched your search
@@ -29,6 +29,7 @@ This repository publishes the open-source server, console, integration catalog,
|
||||
- Write Auggie hooks only to `~/.augment/settings.json`; keep system and workspace settings read-only. Generate `.cmd` wrappers on Windows and `.sh` wrappers on Unix because Auggie dispatches supported script paths, and express hook timeouts in milliseconds.
|
||||
- Validate Auggie matcher syntax during installation with Node.js `new RegExp`; keep status and uninstall independent from the JavaScript validator so recovery remains available offline.
|
||||
- Write Cline file hooks to `$CLINE_DIR/hooks` with `~/.cline/hooks` as the default; keep Documents and workspace hook roots read-only. Use supported event filenames, preserve official hook input byte-for-byte, use `process.execPath` in Node and Go wrappers, and resolve Python runtimes from absolute shebangs. Translate guard exit code `2` into JSON stdout with `cancel: true`. Treat hook errors, timeouts, and invalid control JSON as fail-open.
|
||||
- Model Cursor as one CLI-and-IDE hook contract. Preserve user, project, and enterprise sources in documented priority order; forward `tool_name`, `tool_input`, and `conversation_id`; use exit code `2` for denial; record `failClosed` as the per-script failure-mode control.
|
||||
- Preserve Factory Droid's scope-root `hooks.json` precedence, legacy nested hook source, and per-event `settings.json` fallback. Scope-root and legacy files store event keys at the document root; settings stores the same map under `hooks`. Edit only effective user sources; keep project and organization sources read-only. Preserve JSONC comments through syntax-tree edits, use SDK-native absolute runtime commands, commit generated runtime artifacts and hook sources as one recoverable transaction, and require `/hooks` review after external changes.
|
||||
- Qwen Code `0.20.0` resolves user settings through explicit `QWEN_HOME`, then user-level `.qwen/.env`, then `~/.env`, with `~/.qwen/settings.json` as the default. Keep workspace settings read-only. Preserve JSON comments, reject trailing commas and duplicate keys before writes, express timeouts in milliseconds, propagate native exit code `2` through PowerShell, and require `/hooks` review.
|
||||
- Commit Qwen Code runtime config, private key, audit runtime, and user settings in one rollback-capable transaction. Status requires enabled `PreToolUse` and `PostToolUse` hooks with matching managed runtime files.
|
||||
|
||||
@@ -8,6 +8,8 @@ Grok Build adapters write native user hook files under `$GROK_HOME/hooks` or `~/
|
||||
|
||||
GitHub Copilot command `preToolUse` hooks deny on crashes and every non-zero exit. Command timeouts continue through the normal permission flow, so `timeout_failure_mode` records that explicit exception when it differs from `failure_mode`.
|
||||
|
||||
Cursor uses the same `preToolUse` and `postToolUse` contract across its CLI and IDE. User, project, and enterprise hook sources merge by documented priority; command exit code `2` denies an action, while per-script `failClosed` controls crash, timeout, and invalid-output behavior.
|
||||
|
||||
`delivery_state` is computed from the `node`, `python`, and `go` adapter flags:
|
||||
|
||||
| State | Meaning |
|
||||
|
||||
@@ -148,20 +148,28 @@
|
||||
"id": "cursor",
|
||||
"name": "Cursor",
|
||||
"vendor": "Anysphere",
|
||||
"surface": "ide",
|
||||
"surface": "cli_and_ide",
|
||||
"integration_mode": "command_hooks",
|
||||
"config_format": "json",
|
||||
"config_paths": [
|
||||
"~/.cursor/hooks.json",
|
||||
".cursor/hooks.json"
|
||||
"/Library/Application Support/Cursor/hooks.json",
|
||||
"/etc/cursor/hooks.json",
|
||||
"C:\\ProgramData\\Cursor\\hooks.json",
|
||||
".cursor/hooks.json",
|
||||
"~/.cursor/hooks.json"
|
||||
],
|
||||
"events": {
|
||||
"before_tool": "preToolUse",
|
||||
"after_tool": "postToolUse"
|
||||
},
|
||||
"event_fields": {
|
||||
"name": "tool_name",
|
||||
"input": "tool_input",
|
||||
"session": "conversation_id"
|
||||
},
|
||||
"blocking": {
|
||||
"mechanism": "exit_code_2",
|
||||
"failure_mode": "fail_open"
|
||||
"failure_mode": "configurable"
|
||||
},
|
||||
"adapters": { "node": true, "python": true, "go": true },
|
||||
"delivery_state": "available",
|
||||
|
||||
@@ -296,6 +296,27 @@ test('high-drift providers retain their verified hook contracts', async () => {
|
||||
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',
|
||||
|
||||
Reference in new issue
Block a user