Summary
The Cursor integration (rtk init --global --agent cursor) does not rewrite shell commands. Both rtk hook cursor and hooks/cursor/rtk-rewrite.sh treat rtk rewrite exit code 3 as a failure and return {} (pass-through), so commands run unchanged and RTK filtering never applies.
This appears to be the same root cause as #2200 (OpenClaw plugin), but it also affects the official Cursor hook shipped with RTK.
Environment
- RTK: 0.42.3
- OS: macOS (darwin 25.4.0)
- Agent: Cursor IDE (Agent mode,
preToolUse hook)
- Hook config:
~/.cursor/hooks.json with matcher: "Shell" and command: "rtk hook cursor"
Steps to reproduce
- Install RTK and run:
rtk init --global --agent cursor
- Restart Cursor.
- Ask the agent to run:
- Observe raw
git status output instead of RTK-compact output.
Expected behavior
git status should be transparently rewritten to rtk git status, and the agent should see compact output like:
* branch-name
clean — nothing to commit
Actual behavior
The command runs as plain git status. rtk gain --history does not record the command. Simulating the hook also returns {}:
printf '%s' '{"tool_input":{"command":"git status"}}' | rtk hook cursor
# → {}
Root cause
rtk rewrite returns exit code 3 when it has a rewrite suggestion, but the hook treats any non-zero exit as failure:
# hooks/cursor/rtk-rewrite.sh (line 47)
REWRITTEN=$(rtk rewrite "$CMD" 2>/dev/null) || { echo '{}'; exit 0; }
Even though stdout contains the correct rewrite (rtk git status), the || branch runs and discards it.
Verified manually:
$ rtk rewrite "git status"
rtk git status
$ echo $?
3
The script comment says "rtk rewrite exits 1 when there's no rewrite", but successful rewrites also use a non-zero exit code (3), which breaks the hook logic.
Workaround (confirmed working)
Replace the hook command with a wrapper that captures stdout regardless of exit code:
REWRITTEN=$(rtk rewrite "$CMD" 2>/dev/null || true)
if [ -z "$REWRITTEN" ] || [ "$CMD" = "$REWRITTEN" ]; then
echo '{}'
exit 0
fi
jq -n --arg cmd "$REWRITTEN" '{
"permission": "allow",
"updated_input": { "command": $cmd }
}'
After applying this workaround, git status is correctly rewritten and RTK-compact output is returned.
Suggested fix
- Fix
rtk rewrite to exit 0 on successful rewrite (breaking change for callers that rely on exit 3), or
- Update all hook integrations (
hooks/cursor/rtk-rewrite.sh, rtk hook cursor, OpenClaw, etc.) to read stdout on exit code 3 instead of treating it as an error.
Related: #2200, PR #2202
Summary
The Cursor integration (
rtk init --global --agent cursor) does not rewrite shell commands. Bothrtk hook cursorandhooks/cursor/rtk-rewrite.shtreatrtk rewriteexit code 3 as a failure and return{}(pass-through), so commands run unchanged and RTK filtering never applies.This appears to be the same root cause as #2200 (OpenClaw plugin), but it also affects the official Cursor hook shipped with RTK.
Environment
preToolUsehook)~/.cursor/hooks.jsonwithmatcher: "Shell"andcommand: "rtk hook cursor"Steps to reproduce
git statusoutput instead of RTK-compact output.Expected behavior
git statusshould be transparently rewritten tortk git status, and the agent should see compact output like:Actual behavior
The command runs as plain
git status.rtk gain --historydoes not record the command. Simulating the hook also returns{}:Root cause
rtk rewritereturns exit code 3 when it has a rewrite suggestion, but the hook treats any non-zero exit as failure:Even though stdout contains the correct rewrite (
rtk git status), the||branch runs and discards it.Verified manually:
The script comment says "rtk rewrite exits 1 when there's no rewrite", but successful rewrites also use a non-zero exit code (3), which breaks the hook logic.
Workaround (confirmed working)
Replace the hook command with a wrapper that captures stdout regardless of exit code:
After applying this workaround,
git statusis correctly rewritten and RTK-compact output is returned.Suggested fix
rtk rewriteto exit 0 on successful rewrite (breaking change for callers that rely on exit 3), orhooks/cursor/rtk-rewrite.sh,rtk hook cursor, OpenClaw, etc.) to read stdout on exit code 3 instead of treating it as an error.Related: #2200, PR #2202