feat: surface closed sessions in the "+" tab menu#88
Open
adamatan wants to merge 1 commit into
Open
Conversation
Adds a "Resume" section to both "+" launchers so a closed tab or archived task is one click away instead of buried in History: - Tab strip "+": lists recently closed secondary agent tabs (session-only), reopening them with their original session id so the agent resumes the prior conversation instead of starting fresh. - Sidebar project "+": lists the project's recently archived tasks, restoring via the existing task_restore path. Also relaxes the close-confirmation dialog: a new "Confirm before closing an agent tab" preference (default on) can be turned off via the dialog's "Don't ask again" checkbox, closing tabs immediately with a toast pointing back at Resume instead of a blocking modal every time. Fixes simion#77
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 #77
This PR solves a big usability issue I have: too many tasks and tabs open at the same time, just because I'm not sure I can close them. Adding the ability to reliably restore any closed tab (or archived task) helps me keep a focused environment, without the nagging fear that closing something means losing it for good.
UX
Technical change
src/store/app.ts: newclosedTabs: Record<taskId, ClosedTabEntry[]>slice, in-memory only (cleared on app restart, no new persistence/backend work).closeTabsnapshots a closing secondary tab (title, cli, session id) into this list right beforesyncDurableTabswould otherwise forget it for good; the main tab and shell tabs are excluded since they either auto-resume already or have no session. A newresumeClosedTabaction removes the entry and reopens it by constructing a freshTerminalTabwith the originalsessionIdpre-set, letting the existing resume-by-id logic inTerminalPanedo the rest (no changes needed there).src/components/task/TabBar.tsx: the "Resume" dropdown section, reusing the existingDropdownItem/DropdownLabelprimitives and the same icon-resolution helpers as the rest of the menu.src/components/sidebar/ProjectActionsMenuItems.tsx: same pattern, sourced froms.tasksfiltered toarchived && project_id === projectId, sorted most-recent-first (mirrorsHistoryView's sort), restoring via the existingtask_restoreIPC +setActiveTask.src/lib/closeTab.ts/src/store/prefs.ts: newconfirmBeforeCloseAgentTabpreference (default on), gating whether the confirmation dialog blocks the close; a toast with a bound "Resume" action fires on the fast path.CHANGELOG.md: added an[Unreleased]entry (not a version bump, that stays the maintainer's call at release time).useApp(s => s.closedTabs[task.id] ?? [])selector was minting a new array reference on every render, which (Zustand v5 usesuseSyncExternalStoreinternally) caused React's "Maximum update depth exceeded" crash. Fixed with a stable shared empty-array constant.Test coverage
npx tsc -bandnpm test(242 tests, all passing) after every change, including after rebasing onto the latest workspace→task rename migration.code-reviewersubagent), each finding and fixing one real bug (see above).--resume <the original session id>(not a fresh session), with a screenshot showing the terminal itself printing that resume argument. Repeated the same for the sidebar's archived-task Resume (restored an archived task, confirmed it un-archived and became the active task, Claude Code launched with "Welcome back").resume.integration.test.tscovers the underlying resume-by-id mechanism this reuses, but the new Resume-menu UI and the closedTabs capture/eviction logic are only covered by the manual e2e pass above. Happy to add unit coverage forclosedTabscapture/cap/resume inapp.test.tsif useful before merge.