refactor(surface): remove the main-area surface concept entirely

activeSurface was permanently 'chat' after the legacy mobile layout
removal, so the whole concept is gone: the store field, surfaceGuard,
setActiveSurface/setSurfaceGuard, the per-runtime surface memory in
prepare/restoreForRuntimeSwitch, and WorkspaceSurface itself. All ~30
setActiveSurface('chat') call sites were no-ops and are deleted;
always-true 'is the chat active' checks in keyboard shortcuts, Header
and ChatContainer are unconditional now. FilesView's dirty-file guard
kept its file-switch and close protection but drops the surface-switch
branch nothing could trigger. TerminalView visibility comes only from
its callers. The router keeps parsing legacy ?tab= links (they open the
matching context-panel surface) via its own RouteTab type and no longer
serializes a tab or diff file into URLs — desktop URLs never carried
them anyway.
This commit is contained in:
Bohdan Triapitsyn
2026-08-24 16:36:41 +03:00
parent c6e39f15fe
commit c82f188fc8
31 changed files with 49 additions and 276 deletions
@@ -151,7 +151,6 @@ export const captureSelectionMarkdownForChat = (): string | null => {
export const addSelectionToChat = (): boolean => {
const markdown = captureSelectionMarkdownForChat();
useUIStore.getState().setActiveSurface('chat');
useUIStore.getState().setSessionSwitcherOpen(false);
if (markdown) {
+3 -3
View File
@@ -1,6 +1,6 @@
import type { WorkspaceSurface } from '@/stores/useUIStore';
import {
type RouteState,
type RouteTab,
VALID_TABS,
VALID_SETTINGS_SECTIONS,
ROUTE_PARAMS,
@@ -52,13 +52,13 @@ function parseSessionId(params: URLSearchParams): string | null {
* Parse main tab from URL parameters.
* Returns null if missing or invalid.
*/
function parseTab(params: URLSearchParams): WorkspaceSurface | null {
function parseTab(params: URLSearchParams): RouteTab | null {
const value = params.get(ROUTE_PARAMS.TAB);
if (!value) {
return null;
}
const normalized = value.toLowerCase().trim() as WorkspaceSurface;
const normalized = value.toLowerCase().trim() as RouteTab;
if (VALID_TABS.includes(normalized)) {
return normalized;
}
@@ -65,10 +65,8 @@ afterAll(() => {
const sessionState = (sessionId: string): AppRouteState => ({
sessionId,
tab: 'chat',
isSettingsOpen: false,
settingsPath: '',
diffFile: null,
});
describe('updateBrowserURL embedded-session-chat guard', () => {
@@ -1,4 +1,3 @@
import type { WorkspaceSurface } from '@/stores/useUIStore';
import { isEmbeddedSessionChat } from '@/components/layout/contextPanelEmbeddedChat';
import { ROUTE_PARAMS } from './types';
@@ -7,17 +6,10 @@ import { ROUTE_PARAMS } from './types';
*/
export interface AppRouteState {
sessionId: string | null;
tab: WorkspaceSurface;
isSettingsOpen: boolean;
settingsPath: string;
diffFile: string | null;
}
/**
* Default tab when none is specified.
*/
const DEFAULT_TAB: WorkspaceSurface = 'chat';
/**
* Serialize application state to URL search parameters.
* Only includes parameters that differ from defaults to keep URLs clean.
@@ -38,15 +30,6 @@ function serializeRoute(state: AppRouteState): URLSearchParams {
return params;
}
// Tab - only include if not the default
if (state.tab !== DEFAULT_TAB) {
params.set(ROUTE_PARAMS.TAB, state.tab);
}
// Diff file - only include when on diff tab
if (state.tab === 'diff' && state.diffFile && state.diffFile.trim().length > 0) {
params.set(ROUTE_PARAMS.FILE, state.diffFile);
}
return params;
}
+5 -4
View File
@@ -1,5 +1,4 @@
import type { SidebarSection } from '@/constants/sidebar';
import type { WorkspaceSurface } from '@/stores/useUIStore';
/**
* Represents the current route state derived from URL parameters.
@@ -9,7 +8,7 @@ export interface RouteState {
/** Session ID to navigate to */
sessionId: string | null;
/** View selected through the legacy `tab` URL parameter. */
tab: WorkspaceSurface | null;
tab: RouteTab | null;
/** Settings section - when non-null, settings dialog should be open */
settingsPath: string | null;
/** File path for diff view */
@@ -17,9 +16,11 @@ export interface RouteState {
}
/**
* Valid values for the legacy `tab` URL parameter.
* Valid values for the legacy `tab` URL parameter. Non-chat tabs open the
* matching context-panel surface; the chat always owns the main area.
*/
export const VALID_TABS: readonly WorkspaceSurface[] = ['chat', 'git', 'diff', 'terminal', 'files'] as const;
export type RouteTab = 'chat' | 'git' | 'diff' | 'terminal' | 'files';
export const VALID_TABS: readonly RouteTab[] = ['chat', 'git', 'diff', 'terminal', 'files'] as const;
/**
* Valid settings section values for URL routing.