Skip to content

fix(desktop): solve #5989 — "Remove from sidebar" wipes the workspace pane layout and orphans its agents - #5991

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
triage/issue-5989-30276416872
Open

github-actions[bot] wants to merge 1 commit into
mainfrom
triage/issue-5989-30276416872

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Root cause

tombstoneSidebarWorkspaceRecord (apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/sidebarMutations.ts) hid the workspace and overwrote its layout:

draft.sidebarState.isHidden = true;
draft.paneLayout = createEmptyPaneLayout();   // every tab and split, gone

The re-add path, ensureSidebarWorkspaceRecord, only flips isHidden back to false — it has no branch that rebuilds a layout — so the wipe was unrecoverable. And because terminalRuntimeRegistry.release() deliberately does not kill the PTY, terminals whose panes had just been discarded kept running with nothing in the app referencing them.

Both symptoms came from that one line. The same function backs project removal, so "Remove project from sidebar" wiped every worktree's layout too.

The fix

Drop the paneLayout wipe. Hiding is now what its own doc comment claims: a sidebar-placement change.

Pane runtimes are still released on hide — nothing renders a hidden workspace, so keeping xterm views attached and WebSockets open would be pure waste — but release() persists the terminal's buffer and leaves the host-service session alive, and the WebSocket route only ever attaches to an existing session. So re-adding the workspace remounts the same panes from the preserved layout and reattaches to the still-running agents.

Nothing else depended on the layout being emptied on hide:

  • useVisibleSidebarWorkspaceIds excludes hidden rows, so notifications (V2NotificationController) and the ports list stay filtered.
  • ResourceConsumption filters hidden rows via getVisibleSidebarWorkspaces.
  • useGlobalBrowserLifecycle is a GC for panes absent from any persisted layout; a preserved layout simply means it no longer treats those webviews as removed, and the explicit browserRuntimeRegistry.destroy() on hide still runs.
  • removeWorkspaceFromSidebar (the post-delete cleanup path, used when the workspace really is deleted) is untouched.

Tests

sidebarMutations.test.ts, all three failing before the change and passing after:

  • tombstoneSidebarWorkspaceRecord > keeps the row's pane layout — hides a row holding two tabs, one split across two terminal panes, and asserts the layout survives. Before: {version: 1, tabs: [], activeTabId: null}.
  • removeProjectFromSidebarState > keeps the pane layout of each tombstoned worktree — same guarantee via the project-removal path.
  • hide → re-add round trip — the reported journey end to end: hide, then ensureSidebarWorkspaceRecord, and assert the workspace comes back visible with its tabs, splits and terminal ids intact.

ensureSidebarWorkspaceRecord is now exported so the round trip can be tested through the real re-add path rather than a stand-in.

Ran: bun test src/renderer/routes/_authenticated (10/10 in this file; the 2 remaining React.forwardRef is not a function module-load errors elsewhere in that directory are pre-existing — 4 of them on main), tsc --noEmit clean, bun run lint clean.

Not included

The reporter's suggestions (2)–(4) — a confirm dialog / undo toast, at-stake counts, moving the affordance into the context menu — are deliberately left out. With the layout preserved the action is no longer destructive, so gating it is a UX call rather than a data-loss fix. Worth deciding separately.

Closes #5989


Open in Stage

Summary by cubic

Fixes the “Remove from sidebar” action wiping workspace/project pane layouts and orphaning agents by making hide a pure visibility change that preserves layout and restores it on re-add. Fixes #5989.

  • Bug Fixes
    • Preserve paneLayout when hiding a workspace or project; only set isHidden and clear pin so tabs, splits, and terminal ids return on re-add.
    • Release pane runtimes on hide to free UI resources without killing sessions; re-adding reattaches to the same running agents.
    • Added tests for layout preservation and the hide → re-add flow; exported ensureSidebarWorkspaceRecord to cover the real path.

Written for commit 5a2c504. Summary will update on new commits.

Review in cubic

…idebar

"Remove from sidebar" replaced the workspace's paneLayout with an empty
one, so re-adding the workspace brought it back with no tabs or splits.
Releasing a terminal runtime does not kill its PTY, so any agents running
in those panes stayed alive with nothing referencing them.

Tombstoning now only changes sidebar placement. The runtimes are still
released (nothing renders a hidden workspace), but the layout stays on the
row, so re-adding remounts the same panes and reattaches to the still
running terminal sessions.

Refs #5989
@ghost

ghost commented Jul 27, 2026

Copy link
Copy Markdown

Ready to review this PR? Stage has broken it down into 4 individual chapters for you:

Title
1 Export and document workspace restoration logic
2 Preserve pane layout when hiding workspaces
3 Update UI documentation for reversible unpinning
4 Verify layout preservation in sidebar tests
Open in Stage

Chapters generated by Stage for commit 5a2c504 on Jul 27, 2026 2:54pm UTC.

@github-actions

Copy link
Copy Markdown
Contributor Author

This PR has had no activity for 53 days and will close in 7 days unless there is new activity. If this contribution is still important or relevant, please leave a comment to keep it open. If it closes, you are welcome to reopen it or ask a maintainer to reopen it. Thank you for contributing!

@github-actions github-actions Bot added the stale label Sep 28, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] "Remove from sidebar" wipes the workspace's whole pane layout and orphans its running agents — one click, no confirm, no undo

0 participants