fix(cursor,hub): defer ACP reopen merge until ACP session/load ready#949
Open
heavygee wants to merge 3 commits into
Open
fix(cursor,hub): defer ACP reopen merge until ACP session/load ready#949heavygee wants to merge 3 commits into
heavygee wants to merge 3 commits into
Conversation
5 tasks
There was a problem hiding this comment.
Findings
- [Major] Legacy Cursor rows without
cursorSessionProtocolnow wait for an ACP-only ready handshake —resumeSessiontreats missing protocol as ACP via(metadata.cursorSessionProtocol ?? 'acp') === 'acp', but the CLI still routes the same metadata shape (flavor: cursor,cursorSessionIdpresent, protocol missing) to the legacy stream-json launcher. Legacy stream-json does not emit the new ACP bootstrap ready event on the spawned new session, so reopen/resume waits 30s and returnsresume_failedeven though the legacy runner started. Evidence:hub/src/sync/syncEngine.ts:1162,cli/src/cursor/utils/cursorProtocol.ts:15.
Summary
- Review mode: initial
- One Major issue found: hub-side ACP detection diverges from CLI Cursor protocol routing for pre-#799 legacy rows.
Testing
- Not run (automation). Suggested: add a hub reopen/resume test for a Cursor archived row with
cursorSessionIdand nocursorSessionProtocol, asserting it does not callwaitForSessionResumeReadyand can complete through legacy routing.
HAPI Bot
heavygee
added a commit
to heavygee/hapi
that referenced
this pull request
Jun 18, 2026
Move cursor protocol detection to shared and use resolveCursorRemoteProtocol in hub resume/dedup paths so pre-tiann#799 legacy rows (cursorSessionId without cursorSessionProtocol) skip waitForSessionResumeReady like stream-json CLI. Fixes HAPI Bot Major on tiann#949. Co-authored-by: Cursor <cursoragent@cursor.com>
Collaborator
Author
|
Addressed the [Major] in 62348c5:
CI re-running on push. |
There was a problem hiding this comment.
Findings
- No issues found.
Summary
- Review mode: follow-up after new commits
- Prior bot finding about legacy Cursor rows without
cursorSessionProtocolwas addressed by sharingresolveCursorRemoteProtocolbetween CLI and hub and covering the legacy reopen/dedup cases. Residual risk: this review did not execute the test suite.
Testing
- Not run (automation).
HAPI Bot
heavygee
added a commit
to heavygee/hapi
that referenced
this pull request
Jun 18, 2026
Move cursor protocol detection to shared and use resolveCursorRemoteProtocol in hub resume/dedup paths so pre-tiann#799 legacy rows (cursorSessionId without cursorSessionProtocol) skip waitForSessionResumeReady like stream-json CLI. Fixes HAPI Bot Major on tiann#949. Co-authored-by: Cursor <cursoragent@cursor.com>
62348c5 to
2fc65ec
Compare
There was a problem hiding this comment.
Findings
- No issues found.
Summary
- Review mode: follow-up after new commits
- No issues found in the current diff. Re-checked Cursor ACP ready gating, archived-row preservation on failed reopen, legacy protocol routing, and the added regression tests. Residual risk: this review did not execute the test suite.
Testing
- Not run (automation).
HAPI Bot
Hub waited only for runner webhook (active) before mergeSessions, so a failed ACP session/load could delete the archived recovery row anyway. Emit ready after bootstrap, wait for that handshake on Cursor ACP resume, defer archive-metadata clear until success, and skip dedup merge of archived cursor ACP rows until the target is ready. Fixes tiann#917 Co-authored-by: Cursor <cursoragent@cursor.com>
Move cursor protocol detection to shared and use resolveCursorRemoteProtocol in hub resume/dedup paths so pre-tiann#799 legacy rows (cursorSessionId without cursorSessionProtocol) skip waitForSessionResumeReady like stream-json CLI. Fixes HAPI Bot Major on tiann#949. Co-authored-by: Cursor <cursoragent@cursor.com>
2fc65ec to
09c9d84
Compare
There was a problem hiding this comment.
Findings
- [Major] Preserve legacy Cursor protocol before spawning —
reopenSessionnow callsresumeSessionbeforeclearSessionArchiveMetadata, so pre-#799 Cursor rows withcursorSessionIdbut nocursorSessionProtocolare spawned without ever stampingstream-json. The hub-sideresolveCursorRemoteProtocol(metadata)correctly skips the ACP ready wait, but the new CLI process only receives--resumeplusexistingSessionId;bootstrapExistingSessionpreserves no protocol when the old row has none, socursorRemoteLauncherdefaults to ACP and triessession/loadon a legacy stream-json id. This breaks the legacy fallback path covered by the new test because the test pre-creates the spawned session with no protocol instead of exercising CLI metadata bootstrap. Evidence:hub/src/sync/syncEngine.ts:1291, related CLI routing atcli/src/cursor/runCursor.ts:45,cli/src/cursor/loop.ts:59,cli/src/cursor/cursorRemoteLauncher.ts:11.
Questions
- None.
Summary
- Review mode: follow-up after new commits
- One Major regression found: archived legacy Cursor sessions can be reopened through the ACP launcher instead of stream-json when migration is disabled/skipped.
Testing
- Not run (automation).
HAPI Bot
Defer clearSessionArchiveMetadata until resume succeeds (tiann#917), but pre-tiann#799 rows need stream-json on the existing row before spawn so CLI bootstrap routes to legacy launcher instead of defaulting to ACP session/load. Fixes HAPI Bot Major on tiann#949. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Findings
- No findings.
Questions
- None.
Summary
- Review mode: follow-up after new commits
- The prior Major finding around legacy Cursor protocol stamping before spawn is addressed in this head. I did not find any new Blocker/Major/Minor issues in the changed lines. Residual risk is mainly the Cursor ACP reopen/dedup timing path, but the PR adds focused hub and CLI tests for the ready handshake, rollback, legacy skip, and dedup behavior.
Testing
- Not run (automation).
HAPI Bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #917
Summary
{ type: 'ready' }event immediately after successful Cursor ACP bootstrap so the hub can detect load success before merging sessions.mergeSessionson Cursor ACP resume/reopen until the spawned session is active and has emitted ready (30s timeout).Problem
Investigation on the reported repro showed the archived session was merged away in ~2s while
session/loadwas still failing — not after a ~90s idle timeout. Premature merge destroyed the recovery path.Testing
bun typechecksessionModel.test.ts— three new POST /reopen on archived cursor ACP session: spawned cursor-agent dies ~90s after successful ACP load, merges away the original (no recovery) #917 handshake tests (all pass)cursorAcpRemoteLauncher.test.ts— ready emission + load failure loggingNotes
Does not fix sessions whose ACP store genuinely cannot load (missing/corrupt
store.db); those now fail with an error and preserved archive row instead of silent merge-away.Made with Cursor