fix(orchestrator): scope sessions per project + redesign the Open picker#2071
Closed
sinelaw wants to merge 9 commits into
Closed
fix(orchestrator): scope sessions per project + redesign the Open picker#2071sinelaw wants to merge 9 commits into
sinelaw wants to merge 9 commits into
Conversation
Document the cross-project confusion from v2 global session persistence: scoping principles, current vs. proposed wireframes, and the scope-toggle interaction model. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
The Open picker now foregrounds only the active window's project, with an "N in other projects" affordance and an Alt+P scope toggle that reveals every session (grouped current-project-first, each cross-project row labeled). Filtering still searches globally, so nothing is hidden — it's just not dumped on the user when they relaunch in a different project. Also fixes a latent panic in the widget row-zip: column truncation appends a multi-byte ellipsis but byte-unit overlays were clamped to the pre-truncation length, so an overlay end could point inside a multi-byte char and the span splitter sliced mid-char. Overlays now snap to a char boundary of the truncated line. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
At startup the editor reopens the session the user last used in the launch cwd's project, and never a session from a different project. The pick is strictly cwd-scoped (env.active if it belongs to the cwd, else the most-recent session for the cwd, else a clean base window), so launching in one project can't drag another project's worktree, files, or tabs into the window. A clean base now keys off the picked window rather than a lookup by id, so a stale persisted id-1 window from another project can't lend its label/root/state to it. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
…ffordance The "N in other projects" row added 2 lines below the sessions list without shrinking the list's height budget, so the sessions column outgrew the preview pane and pushed the footer hint bar off the bottom of the fixed-height panel in the scoped view. Subtract the affordance's rows from the list's reserved rows so both panes keep the same height. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
Address the gaps from comparing the picker to the wireframes: - Add a visible, clickable scope toggle (‹ This project › / ‹ All projects ›) under the filter; Alt+P still flips it (both call the same toggleScope()). - Widen the sessions column 25% -> 34% and tag cross-project rows with the project basename so they read `· api-service` instead of truncating to `· tmp_o…`. - Subtract the scope-toggle row from the list height budget so the footer hint stays on-screen. Update the design-doc wireframes to match what shipped and strengthen the e2e test to assert the scope control renders. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
Rework the Open picker layout per the reviewed wireframe: - Tabular session rows: `[id] NAME … PROJECT` with a column header; drop the ACT/RUN glyph column (active id renders in the active-tab colour). PROJECT column shows the basename only for cross-project rows. - Replace the inline scope toggle with a labelled `Project: [ <name> ▾ (Alt+P) ]` control (the Alt+P hint lives on the button) and a labelled Filter field. - `/` focuses the filter; placeholder updated to advertise it. - Fit the list (and so the floating panel) to the session count so a handful of sessions gives a compact panel instead of a tall box padded with blank rows. - Shorten the New button to `[ + New Alt+N ]`. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
The floating-panel key dispatcher fed plain chars straight to the focused text input, consulting explicit mode bindings only for named keys and Ctrl/Alt chords. So the orchestrator picker's `/`-to-focus- filter binding never fired (and any plugin binding a bare key in a floating-panel mode was dead). Defer plain chars to an explicit mode binding first, mirroring the existing named-key / modified-char deference; unbound chars still feed the focused input. Lock `/`-focus + live filtering in the picker e2e test and update the design-doc wireframes to the shipped tabular layout. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
The content-fit list height collapsed the floating panel to a short box in the middle of the screen when there were only a few sessions. Fill the full height budget instead (the list pads with blank rows) so the dialog stays vertically full as before. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
After switching sessions, Quick Open and Live Grep kept targeting the first project: - FileProvider cached the file list with no cwd key, so it served the first-loaded project's files forever. Key the cache by cwd and carry the cwd through the async load message so results for a stale cwd (the user switched mid-load) are dropped. - set_active_window updated working_dir but never refreshed the plugin state snapshot that getCwd() reads, so getCwd()-based plugins (Live Grep, finders) targeted the previous project. Refresh the snapshot before firing active_window_changed. Also: the Open picker now defaults to all-projects and remembers the scope across opens. https://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y
122d172 to
9b081b8
Compare
Owner
Author
|
Merged in a different PR |
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.
Summary
Fixes the reported orchestration bug where launching in one project pulled in another day's / another project's directories, files, and sessions, and reworks the Open picker around per-project scoping.
Root cause. In 0.3.7 orchestrator persistence moved from per-cwd files to a single global
windows.json. Two surfaces then leaked across projects:Changes
Boot (no cross-project bleed):
pick_active_window_for_cwdis now strictly cwd-scoped: reopen the session last used in the launch cwd's project (env.activeif it belongs to the cwd, else the most-recent session for that cwd, else a clean base window). A different project's session is never auto-activated. Honors a directory passed on the CLI (fresh /path), not just the shell cwd.Open picker:
Alt+Ptoggle reveals all projects. Filtering is always global.[id] NAME … PROJECTwith a column header; the PROJECT column labels cross-project rows; sessions sort current-project-first. Active session's[id]renders in the active-tab colour.Project: [ <name> ▾ (Alt+P) ]scope control and a labelledFilterfield;/focuses the filter.Host fixes (found while testing):
/bound in a picker mode was dead. Plain chars now defer to an explicit mode binding first.Docs: design doc updated with the scoping principles, wireframes, and the shipped layout.
Test plan
cargo test -p fresh-editor --lib orchestrator_persistence::tests(cwd-scoped boot pick: never-crosses-projects, last-used, most-recent fallback, clean-base)cargo test -p fresh-editor --lib widgets::render(char-boundary regression test)cargo test -p fresh-editor --test orchestrator_persistence_pathscargo test -p fresh-editor --test e2e_tests orchestrator(scoping default +Alt+Preveal-all +/-focus live filtering; form typing unaffected)webapp/api-service+ an in-place session in non-gitdata; verified scoped vs all-projects views, the Project control,/-focus + filtering, clean per-cwd boot, and compact panel sizinghttps://claude.ai/code/session_01UhCtdAe4SYg6QUsXuYKc9y