From 1772ddaa96f5b14bb580e0b796f6f210be0b95c0 Mon Sep 17 00:00:00 2001 From: minhn4 Date: Mon, 10 Aug 2026 16:50:59 +0700 Subject: [PATCH 1/3] feat(app): retire the layout toggle and the theme picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Settings -> General loses the "New layout" switch and Settings -> Appearance loses the "Theme" picker. The fork ships one layout and one theme; light/dark stays as the Color scheme axis. Neither is merely hidden. `newLayoutDesigns` is now a constant rather than a read of the persisted preference, so a profile carrying `newLayoutDesigns: false` still comes up on the new layout, and `setNewLayoutDesigns` / `layoutTransitionAvailable` / `newInterfaceNoticeVisible` / `dismissNewInterfaceNotice` are removed from the context rather than stubbed, so re-introducing the toggle is a compile error. The sunset machinery goes with them. For themes the lock is `normalize()` in the theme context, which every entry point already passes through — init, the mount-time migration, `load`, the cross-tab storage listener, `setTheme`, `previewTheme`. That also migrates for free: the existing onMount block rewrites a stale `opencode-theme-id` and clears the cached palette CSS. `oc-theme-preload.js` does the same before mount so an upgrading user never sees a frame of their old palette. The `theme.cycle` command (mod+shift+t) and the per-theme `theme.set.` entries are gone; the colour-scheme commands stay. The bundled theme files, the `names` map and the LegacyServerLayout branches in app.tsx are deliberately left alone — that shell still mounts on /:dir routes, and removing either is a large conflict surface against upstream for no user-visible gain. `legacy-new-session.spec.ts` is deleted (it asserted a redirect to a route that no longer resolves) and `session-timeline-projection` now asserts inline comments instead of the CommentStrip row, which only the retired layout produced. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 13 ++ DIVERGENCES.md | 2 + .../performance/timeline-stability/fixture.ts | 3 - .../e2e/regression/legacy-new-session.spec.ts | 41 ------- .../session-timeline-projection.spec.ts | 7 +- packages/app/public/oc-theme-preload.js | 31 ++--- .../app/src/components/settings-general.tsx | 95 +------------- .../src/components/settings-v2/general.tsx | 78 +----------- .../interface-transition.stories.tsx | 76 ------------ .../settings-v2/interface-transition.tsx | 54 -------- packages/app/src/context/settings.test.ts | 59 +-------- packages/app/src/context/settings.tsx | 116 ++---------------- packages/app/src/pages/layout.tsx | 34 ----- .../composer/session-revert-dock.stories.tsx | 3 - packages/app/src/theme-preload.test.ts | 19 ++- packages/ui/src/theme/context.tsx | 23 ++-- 16 files changed, 71 insertions(+), 583 deletions(-) delete mode 100644 packages/app/e2e/regression/legacy-new-session.spec.ts delete mode 100644 packages/app/src/components/settings-v2/interface-transition.stories.tsx delete mode 100644 packages/app/src/components/settings-v2/interface-transition.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index afb5b9f471..e82bc3570c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,19 @@ file is the human-readable summary of what changed and why. ### Desktop / Web UI +- **One layout, one theme** — two settings are gone, and with them the ways back + to interfaces this fork does not ship. Settings → General no longer has the + **New layout** switch: the current layout is the only one, and a profile that + had the old one turned on — from an older build or another machine — now opens + on the new one. Settings → Appearance no longer has the **Theme** picker, and + the command palette drops **Cycle theme** (previously `⌘⇧T`) and the **Use + theme: …** entries. If you had picked one of the bundled palettes, the app + switches back to its own on first launch and forgets the choice. **Color + scheme** is untouched — system, light and dark all still work, as do + **Cycle color scheme** (`⌘⇧S`) and the **Use color scheme: …** commands, and + so do the UI, code and terminal font settings. The terminal client keeps its + own separate theme picker. + - **Session rows have a ⋮ menu** — every session in the sidebar's Recents and on the **View all** list now carries a vertical three-dot button at its right edge, appearing on hover. It opens the same menu the ⋯ button beside a session diff --git a/DIVERGENCES.md b/DIVERGENCES.md index 725ee85a54..3b61069d92 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -100,6 +100,8 @@ from the squash message first, or use a plain merge. | `packages/app/src/components/titlebar.tsx` | Two changes, both to the **v2 titlebar branch only** (`useV2Titlebar()`); the legacy branch below it is untouched. (1) The Home button (and its `home.toggle` command, `mod+b`) opens a new session instead of toggling between `/` and the last active tab: `tabs.toggleHome(...)` becomes a `goHome` that selects an already-open draft if there is one and otherwise falls through to the existing `openNewTab()` project-resolution chain. Its pressed / `aria-pressed` state keys on `layout.route().type === "draft"` rather than `"home"`. The icon, label (`home.title`) and keybind are unchanged, as is `tabs.toggleHome` itself, which is simply no longer called. (2) `` is dropped from that row and the component gains an `export`, so the sidebar can render the DEV/BETA badge at its bottom instead; `Titlebar` keeps its `debugTools` prop because the legacy branch still renders the badge inline. (3) Two buttons added to the row: a sidebar collapse toggle (`sidebar-right` icon, `data-action="titlebar-sidebar-toggle"`, `pressed` while open) as its **first** child, ahead of the `windows() || linux()` `WindowsAppMenu`; and a Search button (`magnifying-glass`, `data-action="titlebar-search"`) immediately after Home, navigating to `/?focus=search`. The toggle reads the fork-only `useAppSidebar()` and is wrapped in ``, which is what keeps it out of the legacy shell. Labels reuse the existing `command.sidebar.toggle` and `home.sessions.search.placeholder` keys — no new i18n. | The home screen is a new session in this fork, so Home has to go there; toggling into the recent-sessions list contradicted that. Reuse-before-create keeps repeated presses from stacking up draft tabs — unlike the New session button, which is expected to always make a new one. Moving the badge lets Home lead the titlebar (measured: x 137 → 92 on macOS, the traffic-light inset). | Keep our `goHome` and the removed indicator. If upstream reworks the titlebar, re-apply both rather than restoring `toggleHome` or the inline badge. If upstream deletes `tabs.toggleHome`, nothing here breaks. Do not remove `Titlebar`'s `debugTools` prop — the legacy titlebar still needs it. Keep `useAppSidebar()` optional-by-design: `useV2Titlebar()` is just `newLayoutDesigns()`, so this titlebar also renders inside the legacy shell, which has no provider — swapping it for `createSimpleContext` would throw there (verified: with the new layout off, the legacy shell renders its own rail, no toggle, and no exception). | | `packages/app/src/pages/layout-new.tsx` (again) | Mounts the fork-only ``, which on desktop redirects one time per boot to a new-session draft (reusing an existing empty draft rather than stacking one up per launch). It pins its decision to the pathname the window came up on and disarms as soon as anything navigates, so it can never hijack a later visit to `/` — the sidebar's "View all" links there. Desktop-only: in the browser there is no "launch" distinct from "navigate to /", so redirecting would make the recents screen unreachable by URL and would break two `packages/app/e2e` specs that `goto("/")`. | Launching should put you in front of a prompt, the way Claude Desktop does, rather than on a list. This supersedes the desktop's restore-last-screen behaviour (`getLastActiveUrl`, `packages/desktop/src/renderer/index.tsx`); the previous session stays one click away in Recents and its tab is still restored. | Keep the mount. If upstream restructures this layout, re-add it. Do not "simplify" the boot-window guard into a plain `location.pathname === "/"` check — that is the bug it exists to prevent. | | `packages/app/src/pages/layout-new.tsx`, `packages/app/src/pages/home.tsx`, `packages/app/src/i18n/{en,es}.ts` | **Persistent app sidebar.** Upstream's project column is an `