Skip to content

fix(cursor): use factual tool redirects for Claude-family models - #6664

Merged
lidge-jun merged 5 commits into
lidge-jun:devfrom
geunwoojun99:fix/cursor-redirect-wording
Oct 6, 2026
Merged

lidge-jun merged 5 commits into
lidge-jun:devfrom
geunwoojun99:fix/cursor-redirect-wording

Conversation

@geunwoojun99

@geunwoojun99 geunwoojun99 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Explicit Claude-family Cursor targets receive factual tool guidance and native-tool refusals, without instructions to conceal the redirect or suppress tool-selection commentary. Catalogs with tools end with “Continue the task with that tool call.” Code mode points inside the freeform exec cell; separately listed tools remain callable at the top level.
  • The adapter no longer arms the routing-commentary sniffer for Claude-family targets. Previously, truthful prose such as “Cursor-native Shell is unavailable. I will use exec.” could trigger a corrective retry and then terminate a tool-result continuation before its next tool call. Tool-envelope echo guards retain their existing predicates.
  • Empty client/MCP catalogs now say that no client tools are available and ask for an answer without tools or a report of the limitation. Dispatcher fallback uses its actual advertised definitions instead of inventing shell_command, exec_command, or apply_patch tools.
  • The final request model selects the wording in both encoded system roots and per-turn execution context. Other model families, including Auto/default whose resolved family is unknown, retain byte-identical legacy wording and the existing commentary guard. Execution authorization, unsafe-native opt-in, foreground-shell ownership fences, tool names, argument schemas, and wire shapes are unchanged.
  • Updated the public adapter reference, Cursor structure contract, regression fixtures, and both test-layout registrations. This is a focused compatibility change, not a new execution capability.

Related

Upstream issue #1992 (Cursor adapter injects hide-from-user policy that downstream agents treat as prompt injection) was closed as completed, but the concealment wording this change removes for Claude-family targets is still present on dev. This change does not alter that wording for other model families.

Verification

Commands below run from the repository root unless they explicitly enter docs-site. Result excerpts are copied from executed checks; no unrun check is reported as passing.

Security review of the diff against origin/dev covered secrets, authentication, and unsafe defaults; no exposed secrets, auth changes, or broadened execution permissions/defaults were found.

Regression proof

Before the fixes, the new selected regressions reproduced the Claude continuation abort, nonexistent-tool wording for two empty-catalog paths, and catalog-less fallback ignoring an advertised MCP tool. The non-Claude abort/retry control already passed.

bun test tests/providers/cursor/cursor-tool-wording.test.ts --test-name-pattern 'factual routing prose|accurately report no tools|dispatcher catalog without'
 1 pass
 37 filtered out
 5 fail
 15 expect() calls
Ran 6 tests across 1 file. [743.00ms]
Exit code: 1

After the fixes, the same selection passed. It includes fragmented factual prose followed by a tool call in both code-mode and flat-shell Claude continuations, the unchanged non-Claude abort/retry behavior, every denied filesystem/shell/fetch frame with empty catalogs, and fallback using an actual MCP definition.

bun test tests/providers/cursor/cursor-tool-wording.test.ts --test-name-pattern 'factual routing prose|accurately report no tools|dispatcher catalog without'
 6 pass
 37 filtered out
 0 fail
 153 expect() calls
Ran 6 tests across 1 file. [531.00ms]
Exit code: 0

Final local checks

bun run typecheck
$ bun x tsc --noEmit
Exit code: 0
bun test tests/providers/cursor/cursor-tool-wording.test.ts tests/providers/cursor/cursor-native-exec-policy.test.ts tests/providers/cursor/cursor-silent-redirect.test.ts tests/providers/cursor/cursor-native-exec-shell.test.ts tests/providers/cursor/cursor-tool-definitions.test.ts tests/providers/cursor/cursor-envelope-echo-retry.test.ts
 219 pass
 0 fail
 2047 expect() calls
Ran 219 tests across 6 files. [689.00ms]
Exit code: 0
bun run structure:check
$ bun scripts/structure-ssot.ts
structure/ SSOT checks passed
Exit code: 0
bun run privacy:scan
$ bun scripts/privacy-scan.ts
Privacy scan passed
Exit code: 0
bun test tests/test-layout.test.ts tests/test-layout-tooling.test.ts tests/ci-workflows/file-size-ratchet.test.ts
 27 pass
 0 fail
 640 expect() calls
Ran 27 tests across 3 files. [881.00ms]
Exit code: 0

The changed-suite was run twice with identical commands. VALIDATION_TMPDIR denotes a pre-provisioned session-isolated temporary directory; its machine-specific value is deliberately omitted. The temporary-root override does not change the test selection. The first run failed; the second, identical rerun on the same working tree passed.

TMPDIR="$VALIDATION_TMPDIR" bun run test:changed
$ bun scripts/test.ts --changed=dev
[test] changed mode comparison ref: origin/dev; merge base: f92482065217bae891a88e27fd6c00012f212042
--changed: 14 changed files, running 597/2090 test files

run 1:  14116 pass, 37 skip, 68 fail, 1 error   Ran 14221 tests across 597 files. [334.63s]   Exit code: 1
run 2:  14184 pass, 37 skip,  0 fail            Ran 14221 tests across 597 files. [231.43s]   Exit code: 0

Run 1 failures were confined to five files:

File Failed tests in run 1
tests/claude-integration/claude-management-api.test.ts 18
tests/claude-integration/claude-messages-endpoint.test.ts 29
tests/claude-integration/claude-models-discovery.test.ts 13
tests/claude-integration/claude-native-passthrough.test.ts 6
tests/claude-integration/claude-picker-recovery.test.ts 2

Run 1 also reported one unhandled ENOENT reading ca.pem in claude-picker-recovery.test.ts. In run 1 the first failure in claude-management-api.test.ts was a 30 s timeout inside a synchronous child-process call (loadBundledCodexCatalog), after which later tests in the same file failed with SPEND_LEDGER_OWNER_HOME_CONFLICT because the timed-out test's server still held the process-wide spend-ledger owner. This is an inference from the captured stack traces, not a root-cause confirmation; the trigger of the initial timeout (likely machine load) was not identified.

Clean-dev comparison. The 68 failing test names were extracted from the run-1 log with timing suffixes stripped (68 distinct names in the five files above) and the five files were run with the same command on clean dev (f92482065, detached worktree $BASELINE_WORKTREE, node_modules symlinked from the primary checkout) and on this branch. The two runs were sequential, each with its own TMPDIR, and used the repository-pinned Bun 1.4.0 first on PATH:

FILES="tests/claude-integration/claude-management-api.test.ts tests/claude-integration/claude-messages-endpoint.test.ts tests/claude-integration/claude-models-discovery.test.ts tests/claude-integration/claude-native-passthrough.test.ts tests/claude-integration/claude-picker-recovery.test.ts"

git worktree add --detach "$BASELINE_WORKTREE" f92482065
ln -s "$PWD/node_modules" "$BASELINE_WORKTREE/node_modules"
ln -s "$PWD/gui/node_modules" "$BASELINE_WORKTREE/gui/node_modules"

# clean dev
(cd "$BASELINE_WORKTREE" && PATH="$PWD/node_modules/.bin:$PATH" TMPDIR="$DEV_TMPDIR" bun scripts/test.ts $FILES)
 197 pass
 0 fail
 3232 expect() calls
Ran 197 tests across 5 files. [17.60s]
Exit code: 0

# this branch
PATH="$PWD/node_modules/.bin:$PATH" TMPDIR="$BRANCH_TMPDIR" bun scripts/test.ts $FILES
 197 pass
 0 fail
 3232 expect() calls
Ran 197 tests across 5 files. [16.91s]
Exit code: 0

git worktree remove --force "$BASELINE_WORKTREE" && git worktree prune

Name comparison: shared failures 0, branch-only failures 0, dev-only failures 0. None of the 68 run-1 failures reproduced on either tree, and no run-1 failure reproduced in the identical full changed-suite rerun on this branch. The five files also pass when run together without the other 592 files, so no further per-file isolation run was needed. Conclusion: the run-1 failures are not reproducible and are not attributable to this change; they are consistent with a transient timeout cascade in the first run, but because they did not reproduce on clean dev either, "pre-existing on dev" is not claimed. The 597-file selection itself could not be run on clean dev, because --changed=dev selects nothing there; that exact interleaving was not compared.

(cd docs-site && bun install --frozen-lockfile && bun run build)
Checked 379 installs across 484 packages (no changes) [143.00ms]
$ astro build
Node.js v20.20.2 is not supported by Astro!
Please upgrade Node.js to a supported version: ">=22.12.0"

error: script "build" exited with code 1
Exit code: 1

Dependency installation passed; the documentation build did not. No clean-dev build comparison was executed in this validation pass, and no baseline claim is made.

git diff --check
Exit code: 0

Scope exception and remaining coverage

  • Why no full suite: focused validation passed, and the documented test-scope exception applies: running all 2,090 files locally was disproportionately costly for this focused adapter change after two 597-file runs (334.63 s and 231.43 s). The 597-file changed suite was run twice: the first run failed (68 failures plus an error, including timeouts, none reproducible), the identical rerun passed with 0 failures. The full 2,090-file suite was not run. Focused behavior tests and explicit source-oracle/layout/file-size guards ran as well; these are not a substitute for a full-suite pass.
  • Remaining coverage: the full repository suite was not run locally under the documented scope exception; build the docs with supported Node. Exact-head repository CI is left to maintainers because fork contributors cannot start it; successful required CI remains necessary before merge.
  • Not checked: authenticated live Cursor behavior, a provider refusal reproduction, and native Windows execution. Automated tests establish emitted wording and local adapter continuation, not a guarantee of a model's response.
  • Scope exception rationale: the only runtime change beyond wording is the Claude-only commentary-sniffer gate, necessary because factual wording alone still aborted a continuation. Non-Claude output guards and execution permissions are not broadened.
  • Readiness evidence: the current upstream dev is one commit ahead of this PR (within the gate's at-most-10 policy); CodeRabbit reviewed the exact PR head with no actionable comments, and no Codex or CodeRabbit review threads are present.
  • GUI: no GUI changes; no screenshot is applicable.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

🤖 Generated with Claude Code

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Improvements
    • Cursor provides Claude-family models with factual guidance tailored to the tools available, including clear direction when tools are unavailable and explanations of execution limits.
    • For write and delete operations that are blocked by policy, responses clarify whether any files were changed.
    • Other Cursor models retain their existing tool guidance and behavior. Tool availability, execution policies, and approval and sandbox behavior are unchanged.

Explicit Claude-family Cursor targets now receive factual tool guidance and native-tool refusals,
without instructions to conceal the redirect. The routing-commentary sniffer is no longer armed for them.
Empty catalogs report no available tools; other model families keep their legacy wording.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 56af9166-a736-4ff0-b12c-9659574f0c88
📥 Commits

Reviewing files that changed from the base of the PR and between feb09d4 and 845fe16.

📒 Files selected for processing (6)
  • docs-site/src/content/docs/reference/adapters.md
  • src/adapters/cursor/tool-guidance.ts
  • src/adapters/cursor/tool-wording.ts
  • structure/providers/cursor.md
  • tests/fixtures/test-layout-expected.json
  • tests/providers/cursor/cursor-tool-wording.test.ts
 ______________________________________________________________________________________________________________________
< Separate views from models. Gain flexibility at low cost by designing your application in terms of models and views. >
 ----------------------------------------------------------------------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 45d6ab02-f1fa-4a67-acac-8af53b90bc7a
📥 Commits

Reviewing files that changed from the base of the PR and between 67dcfe7 and feb09d4.

📒 Files selected for processing (2)
  • scripts/test-layout/layout.json
  • tests/fixtures/test-layout-expected.json

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.


📝 Walkthrough

Walkthrough

Cursor now selects tool guidance and native-execution denial wording by model. Claude-family models receive factual guidance based on available tools. Other models retain legacy wording. Routing-commentary handling and tests cover the model-specific behavior.

Changes

Cursor tool wording

Layer / File(s) Summary
Model-specific tool guidance
src/adapters/cursor/tool-wording.ts, src/adapters/cursor/tool-guidance.ts, src/adapters/cursor/protobuf-request.ts
Helpers identify Claude-family model IDs and build redirect hints from available client and MCP tools. System guidance uses the request model ID and adds continuation text for plain-tool wording.
Per-turn redirects and refusal handling
src/adapters/cursor.ts, src/adapters/cursor/live-transport.ts, src/adapters/cursor/native-exec.ts, src/adapters/cursor/native-exec-fs.ts, structure/providers/cursor.md
The active model selects redirect hints and the plain-tool execution flag. Native write, delete, and apply-patch refusals use the selected wording. Routing-commentary sniffing excludes plain-tool targets.
Behavior coverage and documentation
tests/providers/cursor/cursor-tool-wording.test.ts, tests/fixtures/cursor-tool-wording.json, tests/fixtures/test-layout-expected.json, scripts/test-layout/layout.json, docs-site/src/content/docs/reference/adapters.md
Tests cover model selection, guidance, redirects, refusals, routing commentary, and per-turn updates. Fixtures, test-layout mappings, and documentation describe the behavior.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant ProtobufRequest
  participant LiveTransport
  participant NativeExec
  participant NativeExecFS
  ProtobufRequest->>ProtobufRequest: Build guidance with request model ID
  LiveTransport->>NativeExec: Pass model ID, redirect hint, and plainToolWording
  NativeExec->>NativeExec: Select fallback redirect when needed
  NativeExec->>NativeExecFS: Pass plainToolWording to mutation refusal
Loading

Merge Risk: ⚪ Minimal · up to feb09

No concrete merge-blocking behavior issue was identified in the reviewed changes; the remaining noted uncertainty does not establish a current risk.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 8 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: factual tool redirects for Claude-family models in Cursor.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 8 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ⬜ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

UI screenshot waived by a maintainer comment.
Automatic draft conversion failed. Please convert this pull request to a draft manually until every box above is ticked.

@geunwoojun99

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
github-actions Bot marked this pull request as ready for review October 6, 2026 07:37
@lidge-jun
lidge-jun marked this pull request as ready for review October 6, 2026 15:09
@lidge-jun

Copy link
Copy Markdown
Owner

Maintainer lane note (compat hardening sweep, lane B). Original change by @geunwoojun99; maintainer commits pushed to this branch (no force-push).

  • feb09d4a4a keeps scripts/test-layout/layout.json at 1,999 lines by putting the new cursor-tool-wording.test.ts registration on an existing line. The file has no baseline entry, so 2,000 lines trips the ratchet's NEW_OVERSIZED threshold.
  • fix(cursor): preserve bare client tool names for Claude Code sessions #6640 landed first and made bare client-tool aliasing depend on the request catalog: cursorToolWireName(tool, catalog?). Combined with this PR, clientTools.map(cursorToolWireName) passed the array index as the catalog. Claude-family requests with [Bash, Read] then threw catalog.some is not a function before the transport opened, and [Read, exec_command] listed Read while the catalog advertised ocx_client_Read.
  • 845fe16b07 merges current dev (including fix(cursor): preserve bare client tool names for Claude Code sessions #6640 as 4e25303) and fixes tool-wording.ts to pass the request catalog. It adds six regressions covering [Bash, Read], [Read, exec_command] and [exec_command, Read] through hint, guidance and live transport preparation. All six failed before the fix. The catalog contract is documented in structure/providers/cursor.md.

Verification on 845fe16b07: bun test ./tests/providers/cursor plus the ratchet and both layout guards 1,503 pass / 0 fail; bun run typecheck and bun run structure:check exit 0. Independent adversarial review (gpt-6.1-sol) of the combined change: PASS. The full local suite was not run (parallel lanes share the machine). Hosted Cross-platform CI run 37479896717 completed success on this exact head, including all nine Windows shards; Enforce PR target branch succeeded.

@lidge-jun

Copy link
Copy Markdown
Owner

Maintainer integration into dev (MAINTAINERS.md dev-only maintainer integration; not a self-approval or an independent review).

@lidge-jun
lidge-jun merged commit 9099e4b into lidge-jun:dev Oct 6, 2026
39 of 41 checks passed
@lidge-jun lidge-jun mentioned this pull request Oct 7, 2026
3 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants