Describe the Bug
Version: cursor-agent CLI 2026.09.26-dd393fe (reproduced on macOS arm64 and Linux x64; also present in 2026.09.08 / 09.10 / 09.18)
Feature: importing Claude Code plugins (~/.claude/plugins/installed_plugins.json) and converting their hooks/hooks.json
When cursor-agent runs a hook imported from a Claude Code plugin, what the hook receives and how its response is read do not match the Claude Code hook contract. Plugins that enforce policy in PreToolUse hooks (for example “block git commit until review passes”) are silently bypassed under Cursor, with no error shown.
1. tool_name is Cursor’s name, not the Claude name the hook matched on
The converter maps the Claude matcher Bash to Cursor’s Shell tool, so the hook fires. But the stdin payload says "tool_name": "Shell". A Claude hook that checks tool_name == "Bash" concludes the call is not its concern and allows it.
Expected: for claude-plugin hooks, report the Claude tool name that the matcher was translated from (Shell → Bash).
2. cwd is an empty string for Shell calls
The payload has "cwd": "" and "tool_input": {"cwd": ""}. The real directory appears only in workspace_roots. A hook that resolves “which repository is this command in” from cwd falls back to its own process cwd, which is inside the plugin cache, and evaluates the wrong repository.
Expected: cwd set to the directory the command runs in, as in Claude Code.
3. Exec-form hooks lose args
Claude Code supports {"type":"command","command":"/path/launcher","args":[...]}. The converter copies only command, so the launcher starts with no arguments.
Expected: carry args through, either as argv or safely quoted into the command string, with ${CLAUDE_PLUGIN_ROOT} substituted before quoting.
4. Converted hooks are always failClosed: false
A hook that times out or cannot spawn is dropped, and the tool proceeds. For a policy hook that is a fail-open.
Expected: let the plugin declare fail-closed.
5. Legacy {"decision":"block","reason":...} is ignored for PreToolUse
The top-level legacy decision object is not translated into a deny. Only hookSpecificOutput.permissionDecision is honoured, and translating that one depends on enableClaudeNestedHookSpecificOutputCompatibility. Claude Code itself still honours the legacy shape.
Minimal repro (1 + 2)
- In a scratch directory, create
.cursor/hooks.jsonwith apreToolUsehook that copies stdin to a file. - Run:
cursor-agent -p --trust --force "Run the shell command: echo hi" - Inspect the captured payload:
"tool_name":"Shell","cwd":"","tool_input":{"command":"echo hi","cwd":"","timeout":30000}.
For the end-to-end effect, install any Claude Code plugin whose PreToolUse Bash hook denies git commit, then ask cursor-agent to commit in a git repo. The commit succeeds.
Steps to Reproduce
-
Create a minimal Claude Code plugin:
P=$HOME/cc-repro-plugin
mkdir -p “$P/.claude-plugin” “$P/hooks”
echo ‘{“name”:“cc-repro”,“version”:“1.0.0”}’ > “$P/.claude-plugin/plugin.json”
cat > “$P/hooks/log.sh” <<‘EOF’
#!/bin/bash
{ echo “argv: $*”; cat; echo; } >> /tmp/cc-hook.log
echo ‘{“decision”:“block”,“reason”:“repro: blocked by plugin hook”}’
EOF
chmod +x “$P/hooks/log.sh”
cat > “$P/hooks/hooks.json” <<‘EOF’
{“hooks”:{“PreToolUse”:[{“matcher”:“Bash”,“hooks”:[
{“type”:“command”,“command”:“${CLAUDE_PLUGIN_ROOT}/hooks/log.sh”,“args”:[“hello”],“timeout”:10}
]}]}}
EOF -
Register and enable it the way Claude Code does:
- in
~/.claude/plugins/installed_plugins.json, add under"plugins":
"cc-repro@local": [{"scope":"user","installPath":"<$HOME>/cc-repro-plugin","version":"1.0.0"}] - in
~/.claude/settings.json, add:"enabledPlugins": {"cc-repro@local": true}
- in
-
In any git repo, run:
cursor-agent -p --trust --force "Run the shell command: echo hi" -
Look at
/tmp/cc-hook.logand at whetherecho hiran.
Actual (cursor-agent 2026.09.26-dd393fe, unmodified):
argv:is empty:argswas dropped (#3)- the payload has
"tool_name":"Shell"(#1) - the payload has
"cwd":""and"tool_input":{"command":"echo hi","cwd":"","timeout":30000}(#2) echo hiruns even though the hook returned{"decision":"block",...}(#5)
Expected (same plugin under Claude Code):
argv: hello"tool_name":"Bash"cwdis the repo directory- the tool call is blocked with the hook’s reason
Operating System
MacOS
Linux
Version Information
cursor-agent CLI 2026.09.26-dd393fe
- macOS 27.0 (26A428), arm64
- Ubuntu 24.04.5 LTS, x86_64
Also present in 2026.09.08, 2026.09.10 and 2026.09.18.
Does this stop you from using Cursor
Yes - Cursor is unusable