From c914bcb44bf6f8d9f3be65cf5ce4a979c803c8d4 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 25 Aug 2026 13:25:57 +0200 Subject: [PATCH] feat(app): make Explorer a first-class pane host (#3826) --- CLAUDE.md | 2 +- docs/design.md | 6 + docs/development.md | 15 +- docs/explorer-sidebar.md | 74 + docs/glossary.md | 3 +- docs/plugins.md | 4 + docs/side-panel.md | 98 -- .../browser/agent-consecutive-turns.spec.ts | 37 +- packages/app/e2e/browser/changes-pane.spec.ts | 290 ++-- .../changes-shortcut-placement.spec.ts | 45 +- .../app/e2e/browser/commit-diff-panel.spec.ts | 10 +- .../e2e/browser/composer-diff-stat.spec.ts | 47 +- ...t-terminal-shortcut-pane-placement.spec.ts | 33 +- .../e2e/browser/empty-pane-keyboard.spec.ts | 39 +- .../browser/explorer-pane-placement.spec.ts | 38 +- .../app/e2e/browser/explorer-sidebar.spec.ts | 48 + .../browser/explorer-surface-upgrade.spec.ts | 36 +- packages/app/e2e/browser/file-editing.spec.ts | 8 + .../e2e/browser/file-tree-rail-toggle.spec.ts | 142 -- .../app/e2e/browser/hidden-split-pane.spec.ts | 60 - packages/app/e2e/browser/launcher-tab.spec.ts | 13 +- packages/app/e2e/browser/side-panel.spec.ts | 238 --- .../e2e/browser/sidebar-resize-handle.spec.ts | 4 +- .../app/e2e/browser/sidebar-workspace.spec.ts | 19 +- .../browser/workspace-model-restart.spec.ts | 21 - .../e2e/support/helpers/branch-switcher.ts | 18 +- .../app/e2e/support/helpers/split-pane.ts | 84 -- .../app/e2e/support/helpers/workspace-tabs.ts | 77 +- packages/app/package.json | 1 + .../app/perf/helpers/side-pane-performance.ts | 388 +++++ .../app/perf/side-pane-performance.spec.ts | 119 ++ packages/app/playwright.profile.config.ts | 18 + packages/app/src/agent-stream/view.tsx | 6 +- packages/app/src/app/_layout.tsx | 24 +- .../use-file-link.test.tsx | 2 +- .../src/assistant-file-links/use-file-link.ts | 2 +- .../workspace-contributions.test.ts | 3 +- .../command-center/workspace-contributions.ts | 32 +- .../command-center/workspace-file-search.ts | 1 + .../command-center/workspace-registration.tsx | 9 +- .../src/command-center/workspace-shortcuts.ts | 4 +- .../app/src/components/branch-switcher.tsx | 47 +- .../compact-explorer-sidebar-host.tsx | 74 +- .../components/compact-explorer-sidebar.tsx | 143 +- .../desktop/titlebar-drag-region.tsx | 9 +- .../components/desktop/window-controls.tsx | 208 +++ .../explorer-sidebar-layout.test.ts | 22 + .../src/components/explorer-sidebar-layout.ts | 27 + .../app/src/components/file-actions-menu.tsx | 81 +- .../app/src/components/file-explorer-pane.tsx | 183 +-- .../headers/header-toggle-button.tsx | 30 +- .../src/components/headers/menu-header.tsx | 31 +- packages/app/src/components/message.tsx | 2 +- packages/app/src/components/resize-handle.tsx | 147 +- .../src/components/sidebar-workspace-list.tsx | 36 +- .../sidebar/workspace-meta-row/index.tsx | 39 +- .../components/split-container-focus.test.ts | 27 +- .../src/components/split-container-focus.ts | 9 +- .../app/src/components/split-container.tsx | 624 ++++---- .../app/src/components/tree-primitives.tsx | 5 +- .../app/src/components/tree-rail-toggle.tsx | 57 +- .../app/src/components/ui/context-menu.tsx | 22 + .../app/src/components/ui/control-geometry.ts | 1 + .../ui/horizontal-scroll-boundary.tsx | 115 ++ .../src/components/ui/icon-button-chrome.ts | 113 ++ packages/app/src/components/ui/icon-color.ts | 9 + packages/app/src/components/ui/menu/index.ts | 1 + .../src/components/ui/menu/menu-geometry.ts | 2 + .../app/src/components/ui/menu/menu-item.tsx | 2 +- .../components/ui/pane-content-toolbar.tsx | 178 ++- .../components/ui/toolbar-label-trigger.tsx | 109 ++ .../app/src/composer/draft/workspace-tab.tsx | 13 +- .../app/src/composer/focused-chat-target.ts | 2 +- packages/app/src/constants/layout.ts | 5 +- .../browser/new-tab-requests/index.test.ts | 4 +- packages/app/src/desktop/browser/panel.tsx | 8 +- packages/app/src/desktop/electron/window.ts | 22 +- packages/app/src/desktop/host.ts | 24 +- .../src/desktop/window-chrome-presentation.ts | 48 + packages/app/src/file-pane/bar.tsx | 2 - packages/app/src/git/actions-split-button.tsx | 56 +- .../diff-document/document-file-header.tsx | 2 + packages/app/src/git/diff-document/index.tsx | 7 +- .../app/src/git/diff-document/surface.web.tsx | 81 +- packages/app/src/git/diff-document/types.ts | 1 + .../git/diff-document/workspace-cache.test.ts | 173 +++ .../src/git/diff-document/workspace-cache.tsx | 168 +++ packages/app/src/git/diff-pane.tsx | 1321 ++++++++++++----- packages/app/src/git/file-header.tsx | 41 +- .../app/src/git/pull-request-state-icon.tsx | 32 + .../use-changes-preferences/storage.test.ts | 18 + .../hooks/use-changes-preferences/storage.ts | 3 + packages/app/src/hooks/use-settings/index.ts | 2 + .../app/src/hooks/use-settings/storage.ts | 40 +- packages/app/src/i18n/resources.test.ts | 7 +- packages/app/src/i18n/resources/ar.ts | 23 +- packages/app/src/i18n/resources/en.ts | 69 +- packages/app/src/i18n/resources/es.ts | 23 +- packages/app/src/i18n/resources/fr.ts | 23 +- packages/app/src/i18n/resources/ja.ts | 23 +- packages/app/src/i18n/resources/ko.ts | 23 +- packages/app/src/i18n/resources/pt-BR.ts | 23 +- packages/app/src/i18n/resources/ru.ts | 25 +- packages/app/src/i18n/resources/zh-CN.ts | 22 +- packages/app/src/keyboard/actions.ts | 1 - .../keyboard/keyboard-action-dispatcher.ts | 4 +- .../src/keyboard/keyboard-shortcuts.test.ts | 15 - .../app/src/keyboard/keyboard-shortcuts.ts | 29 +- .../app/src/keyboard/route-shortcut.test.ts | 4 - packages/app/src/keyboard/route-shortcut.ts | 4 - .../app/src/mobile-panels/presentation.tsx | 1 + packages/app/src/panels/agent-panel.tsx | 22 +- packages/app/src/panels/agent-tracks.tsx | 30 +- packages/app/src/panels/changes/state.test.ts | 11 +- packages/app/src/panels/changes/state.ts | 22 +- packages/app/src/panels/diff-panel.tsx | 125 +- packages/app/src/panels/draft-panel.tsx | 8 +- packages/app/src/panels/file-panel.tsx | 66 +- packages/app/src/panels/files-panel.tsx | 81 +- packages/app/src/panels/new-tab-panel.tsx | 44 +- packages/app/src/panels/pane-context.tsx | 7 +- .../app/src/panels/panel-manifest.test.ts | 24 + packages/app/src/panels/panel-manifest.ts | 103 ++ packages/app/src/panels/panel-registry.ts | 61 +- .../src/panels/provider-subagent-panel.tsx | 8 +- .../app/src/panels/pull-request-panel.tsx | 23 +- packages/app/src/panels/register-panels.ts | 7 +- packages/app/src/panels/setup-panel.tsx | 8 +- packages/app/src/panels/terminal-panel.tsx | 8 +- .../command-center/contributions.test.ts | 13 +- .../plugins/command-center/contributions.ts | 24 +- .../plugins/command-center/registration.tsx | 18 +- packages/app/src/plugins/evaluate.test.ts | 54 +- packages/app/src/plugins/evaluate.ts | 32 +- packages/app/src/plugins/types.ts | 7 +- .../workspace-panels/locations.test.ts | 50 + .../src/plugins/workspace-panels/locations.ts | 72 + .../src/plugins/workspace-panels/panel.tsx | 8 +- .../workspace-panels/resolution.test.ts | 1 + packages/app/src/screens/settings-screen.tsx | 169 +-- .../settings/layout/layout-section.tsx | 126 ++ .../workspace/explorer-sidebar-tab-rail.tsx | 470 ++++++ .../screens/workspace/explorer-sidebar.tsx | 150 ++ .../workspace/workspace-desktop-tabs-row.tsx | 495 +++--- .../workspace/workspace-explorer-toggle.tsx | 95 ++ .../workspace-file-open-command.test.ts | 33 + .../workspace/workspace-file-open-command.ts | 5 +- .../workspace/workspace-header-menu.tsx | 63 +- .../workspace/workspace-new-tab-menu.tsx | 17 +- .../workspace-open-in-editor-button.tsx | 34 +- .../workspace/workspace-pane-content.test.tsx | 12 +- .../workspace/workspace-pane-content.tsx | 28 +- .../workspace/workspace-panel-host.tsx | 138 ++ .../screens/workspace/workspace-screen.tsx | 568 ++++--- .../workspace/workspace-scripts-button.tsx | 75 +- .../screens/workspace/workspace-tab-menu.ts | 2 +- .../workspace/workspace-tab-presentation.tsx | 9 +- .../navigation.ts | 2 + .../src/stores/workspace-layout-actions.ts | 307 ++-- .../src/stores/workspace-layout-store.test.ts | 443 +++--- .../app/src/stores/workspace-layout-store.ts | 632 ++++++-- .../workspace-subagents-integration.test.ts | 42 +- packages/app/src/styles/theme.ts | 2 + packages/app/src/utils/desktop-window.test.ts | 31 +- packages/app/src/utils/desktop-window.tsx | 95 +- packages/app/src/utils/host-routes.ts | 1 + .../app/src/utils/prepare-workspace-tab.ts | 5 +- .../app/src/utils/workspace-navigation.ts | 8 +- .../workspace-tabs/explorer-sidebar.test.ts | 88 ++ .../src/workspace-tabs/explorer-sidebar.ts | 124 ++ packages/app/src/workspace-tabs/identity.ts | 6 +- .../app/src/workspace-tabs/launcher/index.tsx | 92 +- .../launcher/internal/catalog.test.ts | 2 + .../launcher/internal/catalog.ts | 2 + packages/app/src/workspace-tabs/model.ts | 1 + .../app/src/workspace-tabs/open-beside.ts | 164 ++ .../app/src/workspace-tabs/side-panel.test.ts | 281 ---- packages/app/src/workspace-tabs/side-panel.ts | 337 ----- packages/app/src/workspace/file-open/index.ts | 2 +- packages/cli/src/commands/plugin/scaffold.ts | 11 +- packages/desktop/src/main.ts | 14 +- packages/desktop/src/preload.ts | 24 +- packages/desktop/src/window/chrome.test.ts | 48 + packages/desktop/src/window/chrome.ts | 31 + .../desktop/src/window/window-manager.test.ts | 120 +- packages/desktop/src/window/window-manager.ts | 125 +- packages/plugin/src/contracts.ts | 11 +- packages/plugin/src/index.ts | 2 + plugin-examples/local-plugin/index.ts | 1 + public-docs/plugins/index.md | 1 + public-docs/plugins/reference.md | 20 +- 191 files changed, 8634 insertions(+), 4730 deletions(-) create mode 100644 docs/explorer-sidebar.md delete mode 100644 docs/side-panel.md create mode 100644 packages/app/e2e/browser/explorer-sidebar.spec.ts delete mode 100644 packages/app/e2e/browser/file-tree-rail-toggle.spec.ts delete mode 100644 packages/app/e2e/browser/hidden-split-pane.spec.ts delete mode 100644 packages/app/e2e/browser/side-panel.spec.ts delete mode 100644 packages/app/e2e/support/helpers/split-pane.ts create mode 100644 packages/app/perf/helpers/side-pane-performance.ts create mode 100644 packages/app/perf/side-pane-performance.spec.ts create mode 100644 packages/app/playwright.profile.config.ts create mode 100644 packages/app/src/components/desktop/window-controls.tsx create mode 100644 packages/app/src/components/explorer-sidebar-layout.test.ts create mode 100644 packages/app/src/components/explorer-sidebar-layout.ts create mode 100644 packages/app/src/components/ui/horizontal-scroll-boundary.tsx create mode 100644 packages/app/src/components/ui/icon-button-chrome.ts create mode 100644 packages/app/src/components/ui/icon-color.ts create mode 100644 packages/app/src/components/ui/menu/menu-geometry.ts create mode 100644 packages/app/src/components/ui/toolbar-label-trigger.tsx create mode 100644 packages/app/src/desktop/window-chrome-presentation.ts create mode 100644 packages/app/src/git/diff-document/workspace-cache.test.ts create mode 100644 packages/app/src/git/diff-document/workspace-cache.tsx create mode 100644 packages/app/src/git/pull-request-state-icon.tsx create mode 100644 packages/app/src/panels/panel-manifest.test.ts create mode 100644 packages/app/src/panels/panel-manifest.ts create mode 100644 packages/app/src/plugins/workspace-panels/locations.test.ts create mode 100644 packages/app/src/plugins/workspace-panels/locations.ts create mode 100644 packages/app/src/screens/settings/layout/layout-section.tsx create mode 100644 packages/app/src/screens/workspace/explorer-sidebar-tab-rail.tsx create mode 100644 packages/app/src/screens/workspace/explorer-sidebar.tsx create mode 100644 packages/app/src/screens/workspace/workspace-explorer-toggle.tsx create mode 100644 packages/app/src/screens/workspace/workspace-file-open-command.test.ts create mode 100644 packages/app/src/screens/workspace/workspace-panel-host.tsx create mode 100644 packages/app/src/workspace-tabs/explorer-sidebar.test.ts create mode 100644 packages/app/src/workspace-tabs/explorer-sidebar.ts create mode 100644 packages/app/src/workspace-tabs/open-beside.ts delete mode 100644 packages/app/src/workspace-tabs/side-panel.test.ts delete mode 100644 packages/app/src/workspace-tabs/side-panel.ts create mode 100644 packages/desktop/src/window/chrome.test.ts create mode 100644 packages/desktop/src/window/chrome.ts diff --git a/CLAUDE.md b/CLAUDE.md index b72d99731c..d22e2b2381 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -52,7 +52,7 @@ At the start of non-trivial work, list `docs/` and skim anything relevant to the | [docs/qa.md](docs/qa.md) | QA evidence bar for pull requests — platform matrix, version drift, performance, UI proof | | [docs/mobile-testing.md](docs/mobile-testing.md) | Maestro and mobile test workflows | | [docs/mobile-panels.md](docs/mobile-panels.md) | Compact left/center/right panel ownership, worklet motion, gesture revisions, and Fabric constraints | -| [docs/side-panel.md](docs/side-panel.md) | The Side panel surface — its three renderings, tab placement intents, pane lifecycle, and the routing preference | +| [docs/explorer-sidebar.md](docs/explorer-sidebar.md) | Explorer sidebar and ordinary side-pane host contracts, lifecycle, placement, and routing preferences | | [docs/ad-hoc-daemon-testing.md](docs/ad-hoc-daemon-testing.md) | Isolated in-process daemon test harness | | [docs/browser-capture-harness.md](docs/browser-capture-harness.md) | Real-Electron browser screenshot harness and compositor-surface gotcha | | [docs/android.md](docs/android.md) | App variants, local/cloud builds, EAS workflows | diff --git a/docs/design.md b/docs/design.md index c1e6953625..21557dbedf 100644 --- a/docs/design.md +++ b/docs/design.md @@ -62,6 +62,10 @@ The button is `