Repository navigation
feat(tabs): resume the just-closed tab's agent session on Ctrl+Shift+T - #447
Merged
amirlehmam merged 1 commit intoNov 10, 2026
Merged
Conversation
Reopening a closed terminal tab restored its shell but dropped the agent conversation it was hosting. The reopen stack now keeps the agent session handle (Claude, Codex, OpenCode, agy, Qwen, omp, pi) on the most recently closed entry only, stamps it onto the reopened surface, and forces a one-shot resume through withClaudeResume regardless of the restore<Provider>Sessions preferences. Released sessions are not resumed.
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
2D42
later.
reopenClosedSurface(#64) brings back a closed terminal tab's shell, cwd, title and startup commands. A tab that was running an agent, though, comes back as a bare prompt. The conversation, which was the point of the tab, is gone, and the user has toclaude --resumeand pick it from the list by hand.With this change, Ctrl+Shift+T on a tab that was hosting an agent session resumes that conversation, through the same resume path session restore already uses (#186).
Behavior
SurfaceReffield (claudeSessionId,codexSessionId, …).providerLookupapplies at save time. If two providers' handles are stamped, the tab resumes neither.restore<Provider>Sessionspreferences do not gate this. They are off by default so a restart doesn't start an agent in every pane at once. Ctrl+Shift+T asks for exactly one tab. The override is a one-shot, module-level set inclaude-resume-command.ts. It is never stored, so nothing new is written to session.json.Implementation
src/renderer/store/surface-slice.tsClosedSurface.agentSession?: { field, id }, captured inpushClosedSurfacefrom the renderer'sagentStatesmirror, or from the surface's stamped field when main has no record yet.pushClosedSurfacenow takesget(all three call sites updated) and clearsagentSessionfrom older entries before pushing.reopenClosedSurfaceapplies the field withupdateSurfaceafteraddSurface. This is synchronous, before React mounts the terminal, so the first PTY create sees it. It then callsforceResumeOnSpawn.src/renderer/hooks/claude-resume-command.tsforceResumeOnSpawn(surfaceId)adds the surface to a set.withClaudeResumeconsumes the entry and treats every provider as enabled for that one call. Validation, the once-per-surface guard and launcher merging (mergeResume) are unchanged.The command is not appended to
startupCommands. Those are saved in session.json, so it would rerun on every restart even after the user quit the agent. The*SessionIdfields are re-stamped or pruned by main at save time, as for 8000 any restored tab.Tests
tests/unit/reopen-agent-session.test.ts(6 cases):codexSessionIdonly.npm test: the only 3 failures (git-view,git-worktree-git,worktree-diff) fail identically on a clean checkout.npm run lint: no findings in the changed files.Manual, isolated dev instance (
WMUX_INSTANCE, CDP-driven), 17/17 passedCtrl+Shift+Tkeypress reopens with the Claude session and spawnsclaude --resume <id>.null.console.error.claude "reply with just OK", close the tab, Ctrl+Shift+T, and the reopened tab resumes the same conversation (the same session id is reported again by Claude's own hook).Known limits
clearAgentStatebroadcastssessionId: nullto the renderer while main keeps the handle as an orphan for restart restore. The renderer cannot tell this apart from a normal exit. That could be fixed by sending the orphaned handle across, but it is out of scope here.claude --resumeanswers "No conversation found". Restart restore behaves the same way.