From fd60b2bf5af8685545d53e80b0f510072fcb77d7 Mon Sep 17 00:00:00 2001 From: Prateek Date: Thu, 19 Feb 2026 00:13:36 +0530 Subject: [PATCH] fix: enrich runtime state before restore check, remove dead branchExists - Add enrichSessionWithRuntimeState() call before isRestorable() in restore() so crashed sessions (status "working", agent exited) are correctly detected as terminal and eligible for restore. - Remove dead branchExists from SCM interface and scm-github plugin (defined but never called anywhere in the codebase). Co-Authored-By: Claude Opus 4.6 --- packages/core/src/session-manager.ts | 10 +++++++--- packages/core/src/types.ts | 3 --- packages/plugins/scm-github/src/index.ts | 20 -------------------- 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/packages/core/src/session-manager.ts b/packages/core/src/session-manager.ts index b08bd7163..1868c12d9 100644 --- a/packages/core/src/session-manager.ts +++ b/packages/core/src/session-manager.ts @@ -903,8 +903,13 @@ export function createSessionManager(deps: SessionManagerDeps): SessionManager { throw new Error(`Session ${sessionId} not found`); } - // 2. Reconstruct Session from metadata + // 2. Reconstruct Session from metadata and enrich with live runtime state. + // metadataToSession sets activity: null, so without enrichment a crashed + // session (status "working", agent exited) would not be detected as terminal + // and isRestorable would reject it. const session = metadataToSession(sessionId, raw); + const plugins = resolvePlugins(project); + await enrichSessionWithRuntimeState(session, plugins, true); // 3. Validate restorability if (!isRestorable(session)) { @@ -914,8 +919,7 @@ export function createSessionManager(deps: SessionManagerDeps): SessionManager { throw new SessionNotRestorableError(sessionId, "session is not in a terminal state"); } - // 4. Resolve plugins - const plugins = resolvePlugins(project); + // 4. Validate required plugins (plugins already resolved above for enrichment) if (!plugins.runtime) { throw new Error(`Runtime plugin '${project.runtime ?? config.defaults.runtime}' not found`); } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 98389df02..9080a60c5 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -535,9 +535,6 @@ export interface SCM { /** Check if PR is ready to merge */ getMergeability(pr: PRInfo): Promise; - - /** Optional: check if a branch exists in the repo */ - branchExists?(repoPath: string, branch: string): Promise; } // --- PR Types --- diff --git a/packages/plugins/scm-github/src/index.ts b/packages/plugins/scm-github/src/index.ts index 43d5c62c2..e47321afd 100644 --- a/packages/plugins/scm-github/src/index.ts +++ b/packages/plugins/scm-github/src/index.ts @@ -560,26 +560,6 @@ function createGitHubSCM(): SCM { blockers, }; }, - async branchExists(repoPath: string, branch: string): Promise { - try { - await execFileAsync("git", ["rev-parse", "--verify", `refs/heads/${branch}`], { - cwd: repoPath, - timeout: 30_000, - }); - return true; - } catch { - // Try remote ref - try { - await execFileAsync("git", ["rev-parse", "--verify", `refs/remotes/origin/${branch}`], { - cwd: repoPath, - timeout: 30_000, - }); - return true; - } catch { - return false; - } - } - }, }; }