reveal non-Claude workspace tabs in a split above Claude

A live test of ui open diff surfaced that the workspace slot hardcoded
the Claude pane (primary = claude ?? active), so activating diff.view
flipped the registry but never rendered. Generalise _WorkspaceSlot: when
a non-Claude, non-editor workspace tab is the active one, reveal it in
the split region above Claude with a close affordance back to full-Claude
— so clide ui open diff actually shows the diff alongside the
conversation. Fixes the reveal for terminal/team-chat tabs too.

Closes T-233.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 11:20:02 +02:00
co-authored by Claude Opus 4.8
parent 870b773381
commit b64028ecf9
5 changed files with 113 additions and 7 deletions
+32
View File
@@ -137,6 +137,38 @@ void main() {
expect(tester.takeException(), isNull);
});
testWidgets('a non-Claude workspace tab reveals in the split above Claude with a close (T-233)', (tester) async {
registerTabs();
f.services.panels.contribute(TabContribution(id: 'diff.view', slot: Slots.workspace, title: 'Diff', build: (_) => const Text('DIFF')));
f.services.panels.activateTab(Slots.workspace, 'diff.view');
await pumpLayout(tester);
expect(tester.takeException(), isNull);
// Revealed alongside the conversation: both the diff and Claude render.
expect(find.text('DIFF'), findsOneWidget);
expect(find.text('CLAUDE'), findsOneWidget);
// The close affordance returns to full-Claude.
await tester.tap(find.bySemanticsLabel('Close'));
await tester.pump();
expect(f.services.panels.activeTabIn(Slots.workspace), 'claude.primary');
expect(find.text('DIFF'), findsNothing);
});
testWidgets('with no Claude pane, an active workspace tab takes the whole slot (no reveal chrome)', (tester) async {
final p = f.services.panels;
p.contribute(TabContribution(id: 'files.tree', slot: Slots.sidebar, title: 'Files', build: (_) => const Text('SIDEBAR')));
p.contribute(TabContribution(id: 'diff.view', slot: Slots.workspace, title: 'Diff', build: (_) => const Text('DIFF')));
p.contribute(TabContribution(id: 'markdown.viewer', slot: Slots.contextPanel, title: 'Preview', build: (_) => const Text('CONTEXT')));
p.activateTab(Slots.workspace, 'diff.view');
await pumpLayout(tester);
expect(tester.takeException(), isNull);
expect(find.text('DIFF'), findsOneWidget);
// No alongside-Claude chrome, since there is no Claude pane to sit over.
expect(find.bySemanticsLabel('Close'), findsNothing);
});
testWidgets('global intents dispatch through the app-root Actions', (tester) async {
await pumpApp(tester);
final ctx = tester.element(find.byType(RootLayout));