Repository navigation
feat(app): isolate Code-side tab lists per project - #274
Closed
quickbeard wants to merge 1 commit into
Closed
quickbeard wants to merge 1 commit into
quickbeard wants to merge 1 commit into
Conversation
Extends #239 to the other side. Code kept one tab strip for the whole side -- every project of every connected server in one list -- so a session on the local machine sat beside one on a WSL distro and one from an unrelated checkout. Work had already been split per (sandbox, mounted folder); Code is now split the same way, per (server, project), and the scope type it goes through is the one #239 introduced. The resolution grows a server axis to make that safe. Work could read the sidebar's selection alone because an effect in context/layout.tsx pins it to a sandbox, but nothing syncs home.selection.server to the route, and on Code the two come apart routinely: selecting a tab on a WSL server leaves the sidebar on the local one, and scoping to the sidebar would hide the tab that was just opened. serverForScope takes the route's server first and the sidebar's second, both filtered to the side being shown, which keeps "the strip always contains the session you are looking at" true on a side with several servers connected at once. Work goes through the same resolution, where it settles the same mismatch between two sandboxes. scopeDirectory is the chain #239 derived, with two changes. The sidebar's directory only counts when the sidebar is on the scoped server, since two servers can hold the same path -- a checkout the local machine and a WSL distro both see. And the last resort is per side: the sandbox's own folder on Work, projects.list()[0] on Code, which is the fallback enter("code") already used. A Code server with no project open resolves nothing and degrades to the side scope, which is what both sides showed before. Everything downstream was already scope-generic and narrows to Code projects with no change: tabsForScope, reorderWithinScope, the successor picked after a close, tab.prev/tab.next/tab.close, and openNewTab's leading folder branch, which now starts a new tab in the Code project the strip is showing. The Code sidebar keeps toggling Recents rather than navigating, so folderEntry's openSessions step stays Work-only for the reason #239 gave. Logic stays in the fork-only src/workspace/side.ts; no upstream file is touched, so the DIVERGENCES row is amended rather than added to. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
quickbeard
force-pushed
the
feat/code-project-tabs
branch
from
August 19, 2026 10:32
270d26e to
0426227
Compare
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.
Extends #239 to the other side. Code kept one tab strip for the whole side — every project of every connected server in one list — so a session on the local machine sat beside one on a WSL distro and one from an unrelated checkout. Work had already been split per (sandbox, mounted folder); Code is now split the same way, per (server, project), through the
TabScope#239 introduced.What changes for the user
Ctrl/Cmd+ number, next/previous tab, close tab) act within the project on screen, so closing the last tab in a project no longer drops you into an unrelated one, and New tab starts in the project the strip is showing.How the scope resolves
useWorkspaceScopegrows a server axis. Work could read the sidebar's selection alone because an effect incontext/layout.tsxpins it to a sandbox — but nothing syncshome.selection.serverto the route, and on Code the two come apart routinely: selecting a tab on a WSL server leaves the sidebar on the local one, and scoping to the sidebar would hide the tab that was just opened. So:serverForScope: the route's, then the sidebar's, each filtered to the side being shown. Work goes through the same resolution, where it settles the same mismatch between two sandboxes.scopeDirectory: the one on screen, then the sidebar's when the sidebar is on the scoped server (two servers can hold the same path), then a per-side fallback — the sandbox's own folder on Work,projects.list()[0]on Code, which is the fallbackenter("code")already used.Everything downstream was already scope-generic and narrows to Code projects with no change:
tabsForScope,reorderWithinScope, the successor picked after a close,tab.prev/tab.next/tab.close, andopenNewTab's leading folder branch.folderEntry'sopenSessionsstep stays Work-only, for the reason #239 gave — on Code that chain is reached fromenter(side), where the extra step would change the side switch's behaviour.Notes
packages/app/src/workspace/side.ts. The existing DIVERGENCES row is amended (retitled "Per-project tab strips") rather than a new one added, because it claimed the Code path was provably unchanged and that is no longer true. The CHANGELOG bullet from feat(app): isolate Work-side tab lists per mounted folder #239 is still under## Unreleasedand ended with "Code is unchanged", so it is rewritten as the net behaviour rather than contradicted by a second bullet.Testing
bun run testinpackages/app— 702 unit + 109 browser, all passing. 12 new cases intest-browser/workspace-side.test.tscoverserverForScope,scopeDirectory, andtabsForScopeover Code servers (two projects on one server, the same path on two servers).bunx playwright test— 137 passed, 2 failed (prompt-thinking-level,session-actions-menu:104). Both fail identically on the base commit with this branch stashed, so they are pre-existing and unrelated.bun typecheckinpackages/app— clean.🤖 Generated with Claude Code