Skip to content

Temp fix: don't advertise readOnlyHint to Cursor under HITL (unblocks approval banner)#40

Open
pragati-agrawal-glean wants to merge 1 commit into
mainfrom
fix/cursor-disable-readonlyhint-hitl
Open

Temp fix: don't advertise readOnlyHint to Cursor under HITL (unblocks approval banner)#40
pragati-agrawal-glean wants to merge 1 commit into
mainfrom
fix/cursor-disable-readonlyhint-hitl

Conversation

@pragati-agrawal-glean

Copy link
Copy Markdown
Contributor

Temp fix — unblocks the Cursor HITL approval banner

Symptom: In Cursor, requires_approval actions via run_tool hang ~5 minutes with no approval banner, then fail closed. Works fine in Claude Code.

Root cause (investigated, evidence-backed): a Cursor client regression between 3.10.20 → 3.12.17, not a plugin or SDK change.

  • readOnlyHint:true on run_tool is git-constant since 2026-06-15; the elicitation/create payload is byte-identical regardless of the annotation (verified with an SDK 1.29.0 in-memory harness).
  • Live logs show the version correlation: on 3.10.20 a readOnlyHint:true run_tool rendered and got a 16-second human decline; after auto-update to 3.12.17, the same call times out at exactly 300000ms with no UI, twice.
  • Cursor 3.12.17 only paints an elicitation banner on its attended/lease tool-call lane; the auto-run/unattended lane silently dead-ends. readOnlyHint (0 references in the entire Cursor bundle; annotations stripped on ingest) pushes run_tool toward the non-interactive lane.

This change: thread client identity into runToolAnnotations and omit readOnlyHint for Cursor (clientInfo.name starts with cursor) so the call stays on the interactive lane and the banner renders. Claude Code keeps readOnlyHint:true (renders regardless of lane; hint still suppresses its native prompt). Losing the hint on Cursor costs nothing — Cursor strips tool annotations anyway.

Scope: deliberately minimal, isolated from PR #39 (which chased the now-disproven empty-schema hypothesis). Temporary until the Cursor-side rendering regression is fixed upstream.

Validation

  • npm run typecheck clean; npx vitest run 189/189, incl. a new case asserting Cursor gets no readOnlyHint.
  • Pending your live confirmation: on Cursor 3.12.17, a requires_approval action should now show the Approve/Deny banner instead of hanging. This is also the decisive A/B for the root cause — if it renders with the hint gone and hangs with it present (same version, same machine), readOnlyHint is proven the discriminator.

Known caveats / follow-ups

  • If the live A/B shows no difference, the real lane-selector is Cursor's run-mode/auto-run classification, not readOnlyHint — then this is a no-op and we pursue the run-mode angle + upstream Cursor fix.
  • Separately worth hardening (not in this PR): the HITL gate checks getClientCapabilities()?.elicitation truthy, but the SDK's elicitInput requires .elicitation.form — a bare-elicitation client would throw.
  • File the Cursor bug upstream (repro + version bisect available).

🤖 Generated with Claude Code

Cursor 3.12.x only renders a server-initiated elicitation on its attended
tool-call lane. run_tool marked readOnlyHint:true lands on Cursor's
auto-run lane, where the HITL approval elicitation is silently dropped —
producing a 5-minute silent hang and a fail-closed timeout with no
approval banner. Cursor also strips tool `annotations` on ingest (and has
zero references to readOnlyHint in its bundle), so the hint never
suppressed a native prompt there anyway.

Thread the client identity into runToolAnnotations and omit readOnlyHint
when the client is Cursor (clientInfo.name starts with "cursor"), keeping
run_tool on the interactive lane so the banner renders. Claude Code is
unaffected: it renders elicitation regardless of lane, and the hint still
suppresses its native prompt.

Temporary until the Cursor-side rendering regression is fixed upstream.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@swarup-padhi-glean swarup-padhi-glean left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also have a demo video in the PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants