Skip to content

fix(runtime): recognize bare Cursor Agent titles for guarded sends - #7937

Closed
bbingz wants to merge 7 commits into
stablyai:mainfrom
bbingz:fix/notes-send-agent-guard-toctou
Closed

bbingz wants to merge 7 commits into
stablyai:mainfrom
bbingz:fix/notes-send-agent-guard-toctou

Conversation

@bbingz

@bbingz bbingz commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Treat a bare Cursor Agent native OSC or pane title as agent identity even though its provider status is intentionally null because hooks own working and idle state.
  • Preserve Claude management-screen and shell-title classification.
  • Keep isTerminalRunningAgent and getTerminalAgentStatus accurate so guarded note sends do not reject a live Cursor Agent session solely because the native title has no status suffix.
  • Add a focused runtime regression for the status-null Cursor Agent title.

Relation to #7935 and #9166

This PR originally included a generic guarded-send retry for the TOCTOU reported in #7935. That behavior landed through #9166 and closed #7935.

The branch is now synchronized with current main and narrowed to the remaining Cursor-specific classification gap. It no longer changes guarded-send retry logic and does not claim to close #7935.

Screenshots

No visual change.

Testing

  • pnpm test src/main/runtime/orca-runtime.test.ts src/shared/agent-detection.test.ts — 2 files / 817 tests passed
  • pnpm run typecheck:node
  • changed-file oxlint
  • changed-file oxfmt --check
  • git diff --check

AI Review Report

The final diff was reconciled against current main and reduced from four files to two. Generic retry comments and tests already covered by #9166 were removed. The remaining classifier uses the existing shared isCursorAgentTitle predicate and preserves the established management and shell boundaries. No platform-specific shortcut, path, shell, Git, SSH, or provider-transport behavior changes.

Security Audit

No new IPC, command execution, credential, filesystem, dependency, or persistence behavior. The change only classifies an existing trusted terminal title for the existing runtime agent-status guard.

Notes

Current scoped head: 96062d875b. The original #7935 implementation history remains in the branch history, while the merge result presented for review contains only the Cursor Agent title fix.

ELI5

A bare "Cursor Agent" terminal title was not treated as a running agent because status is null when hooks own idle/working state. Guarded sends and status helpers now recognize that title so live Cursor Agent sessions are not rejected by mistake.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This change adds a retrying agent-status probe for guarded terminal sends, repolling terminal status after an initial no-agent result before timing out. Cursor Agent pane-title detection now recognizes bare native OSC titles as active agents. The terminal.send RPC guard uses the new probe, and runtime and RPC tests cover detection, retry recovery, expiration, and guarded-send outcomes.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address #7935 by retrying guarded agent-status checks and still refusing confirmed no-agent or permission cases.
Out of Scope Changes check ✅ Passed The diff stays focused on the guarded-send runtime path and related tests, with no obvious unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title is concise and accurately summarizes the main change: recognizing bare Cursor Agent titles for guarded sends.
Description check ✅ Passed All required sections are present, and the summary, testing, security, and notes are detailed enough for review.

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.

@bbingz
bbingz force-pushed the fix/notes-send-agent-guard-toctou branch from 46b7042 to 054d723 Compare July 10, 2026 06:57
@bbingz

bbingz commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto latest origin/main. Fixed post-rebase test stub (resolveLiveLeafForHandle). terminal-send 14/14 + runtime guarded-send cases green. Head: 054d72384.

@bbingz
bbingz force-pushed the fix/notes-send-agent-guard-toctou branch 2 times, most recently from cfd7758 to 694377a Compare July 10, 2026 10:10
bbingz and others added 2 commits July 12, 2026 18:05
Guarded note sends re-check isRunningAgent at write time, so a brief
title or foreground miss refused live sessions with "not a recognized
agent session". Re-poll status for ~1.2s before hard-refusing, and treat
bare Cursor Agent native titles as agent identity for is-running checks.

Fixes stablyai#7935
terminal.send now uses resolveLiveLeafForHandle for stale-handle safety.
Update the no-agent guarded-send test stub so the probe path runs.
@bbingz
bbingz force-pushed the fix/notes-send-agent-guard-toctou branch from 694377a to c886b26 Compare July 12, 2026 10:05
@bbingz

bbingz commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto latest origin/main. Merged PR guarded-send retry (getTerminalAgentStatusForGuardedSend) with main's PTY-binding safety (getTerminalAgentStatusPtyId / exact binding asserts) and kept both guarded-send test suites.

Adapt guarded-send tests to the current runtime probe contract.
@bbingz

bbingz commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 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.

@bbingz bbingz changed the title fix(notes-send): tolerate transient agent-status gaps in send guard fix(runtime): recognize bare Cursor Agent titles for guarded sends Jul 18, 2026
@brennanb2025

Copy link
Copy Markdown
Contributor

Taking a look!

@brennanb2025

Copy link
Copy Markdown
Contributor

Reviewed and pushed a final cleanup. The scoped fix now treats the exact native Cursor Agent title as agent identity while leaving its working/idle status hook-owned, so guarded note sends accept the live session without weakening shell or management-title checks or adding polling; I also tightened the rationale comments. The branch merges cleanly with current origin/main, and the focused runtime/shared detection tests (817), node typecheck, changed-file lint, and formatting all pass.

@bbingz

bbingz commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@brennanb2025 Thanks for the final cleanup on the bare Cursor Agent title guard.

Still MERGEABLE on current main. Ready to merge from my side.

@nwparker nwparker added the bug Something isn't working label Jul 27, 2026
@nwparker

nwparker commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Closing as superseded — the linked issue(s) for this PR were fixed by another change that has already been merged.

Superseding merge: #9166

Thank you for the contribution! If anything remains unaddressed, please open a new issue or PR against current main.

@nwparker nwparker closed this Aug 3, 2026
@bbingz

bbingz commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

The generic #7935 startup TOCTOU was indeed fixed by #9166. This PR was subsequently narrowed to a separate two-file Cursor classification gap and no longer claims to close #7935.

On current main (c9a37f58d), detectAgentStatusFromTitle('Cursor Agent') intentionally returns null, while classifyAgentTitle() only accepts a non-null status and does not use the already-imported isCursorAgentTitle(). As a result, a live Cursor session whose only current identity evidence is the native bare title can still be classified as neutral; the focused regression in this PR covers that case.

Would you prefer this scoped PR to be reopened, or a fresh PR against current main?

@bbingz

bbingz commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Going ahead with a fresh PR against current main rather than reopening — this branch's base is too old to be worth rebasing.

Scope stays two lines. classifyAgentTitle (src/main/runtime/orca-runtime.ts:36993-37001) resolves agent identity only through detectAgentStatusFromTitle, which deliberately returns null for the bare native title (src/shared/agent-title-status.ts:155-157). isCursorAgentTitle is already imported in orca-runtime.ts:7 but is only consumed by isCursorAgentOrchestrationTarget (line 1230), so a live Cursor pane whose sole identity evidence is the native title still classifies as neutral.

Fix: classifyAgentTitle returns 'agent' when isCursorAgentTitle(title) is true, keeping the Claude management-title branch ahead of it, plus the focused regression from this PR. Verified against 2ff2a1b26.

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.

[Bug]: Intermittent "not a recognized agent session" when sending notes to a running agent (send-guard TOCTOU race)

3 participants