fix(app): show Setup tabs only for failures (#3634)

* fix(app): only surface failed workspace setup

Running and successful setup snapshots were treated as reasons to seed a background Setup tab, adding noise to every workspace with setup commands. Seed only failed setup and classify that tab as main-workspace content so the failure stays visible without stealing focus.

* fix(app): surface failed setup once

Keep the failed-setup surfacing claim with the setup snapshot so closing its background tab remains respected after the workspace remounts. Explicitly prefer the main pane for a new failure tab without moving a user-placed existing tab.

* fix(app): keep setup tabs out of side panel

A preferred main-pane placement can fall back when users remove that pane. Keep that implicit fallback out of the focused Side panel when another workspace pane is available.
This commit is contained in:
Mohamed Boudra
2026-08-21 11:17:04 +02:00
committed by GitHub
parent bc02cfd8cd
commit 04624cb419
10 changed files with 271 additions and 61 deletions
@@ -921,6 +921,68 @@ describe("workspace-layout-store actions", () => {
expect(layout.focusedPaneId).toBe("explorer");
});
it("places a background setup tab in the main pane without moving focus", () => {
const workspaceKey = createWorkspaceKey();
const store = workspaceLayoutStore.getState();
store.openTab({
workspaceKey,
target: { kind: "agent", agentId: "agent-1" },
intent: "reveal",
});
store.focusPane(workspaceKey, "explorer");
const setupTabId = store.openTab({
workspaceKey,
target: { kind: "setup", workspaceId: WORKSPACE_ID },
intent: "background",
placement: { mode: "prefer", paneId: "main" },
});
const layout = workspaceLayoutStore.getState().layoutByWorkspace[workspaceKey];
expect(findPaneContainingTab(layout.root, setupTabId as string)?.id).toBe("main");
expect(layout.focusedPaneId).toBe("explorer");
});
it("keeps a failed setup tab out of the focused side panel when main was removed", () => {
const workspaceKey = createWorkspaceKey();
const store = workspaceLayoutStore.getState();
workspaceLayoutStore.setState((state) => ({
layoutByWorkspace: {
...state.layoutByWorkspace,
[workspaceKey]: normalizeLayout({
root: {
kind: "group",
group: {
id: "root",
direction: "horizontal",
sizes: [0.5, 0.5],
children: [
createPane({ id: "secondary", tabIds: [] }),
createPane({ id: "explorer", tabIds: [] }),
],
},
},
focusedPaneId: "explorer",
}),
},
sidePanelPaneIdByWorkspace: {
...state.sidePanelPaneIdByWorkspace,
[workspaceKey]: "explorer",
},
}));
const setupTabId = store.openTab({
workspaceKey,
target: { kind: "setup", workspaceId: WORKSPACE_ID },
intent: "background",
placement: { mode: "prefer", paneId: "main" },
});
const layout = workspaceLayoutStore.getState().layoutByWorkspace[workspaceKey];
expect(findPaneContainingTab(layout.root, setupTabId as string)?.id).toBe("secondary");
expect(layout.focusedPaneId).toBe("explorer");
});
it("keeps ambient browser opens out of the focused explorer pane", () => {
const workspaceKey = createWorkspaceKey();
const store = workspaceLayoutStore.getState();