Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,46 @@ file is the human-readable summary of what changed and why.

## Unreleased

### Desktop / Web UI

- **The sidebar is always on screen, and it carries your recent sessions** —
the Projects list plus Settings and Help used to be a column belonging to the
home screen, so opening a session left you with no navigation but the tab bar.
That column is now app chrome: it stays put on every screen. Settings and Help
are anchored to the bottom of it instead of trailing the last project, and a
new **Recents** section sits between the two, listing your latest sessions with
a **New session** row above them. Recents grows and shrinks with the window,
always leaving room for a **View all** row at the bottom of the section — you
never have to scroll to find it. **View all** opens the full recent-sessions
screen, unchanged from today, now framed by the sidebar. Below a narrow window
width the sidebar hides and the home screen keeps its previous stacked layout.

- **The desktop app opens on a new session** — launching used to drop you on a
list of past work. It now opens a fresh composer, reusing an existing empty
draft rather than accumulating one per launch. This replaces reopening the
screen the window was last on; that session is one click away in Recents, and
the tab bar still restores it. The browser UI is unaffected — there, `/` is a
URL you asked for, so it keeps showing the recents screen.

- **The channel badge moved to the bottom of the sidebar** — the blue **DEV**
(or **BETA**) tag used to sit at the far left of the titlebar, pushing the
Home button along with it. It now sits under Help at the foot of the sidebar,
and Home leads the titlebar. On a dev build the badge still toggles the debug
bar. Release builds show no badge, as before, and the sidebar closes the gap
rather than leaving a hole where it would have been.

- **The new-session screen sits on a card, like every other screen** — it was
painted in the same tone as the window chrome, so next to the sidebar it read
as empty space rather than as the screen you are on, while sessions and the
recents list floated on a raised white card. It now uses that same card.

- **The Home button goes to a new session** — it used to toggle between the
recent-sessions list and whichever tab you came from, which no longer matches
what the home screen is. It (and `mod+b`) now takes you to a new session,
selecting an already-open empty draft rather than opening another, and it
lights up while you are on one. The full list is still a click away under
**View all**.

## 1.18.4-8

### Agent
Expand Down
5 changes: 4 additions & 1 deletion DIVERGENCES.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,11 @@ from the squash message first, or use a plain merge.
| `packages/tui/src/component/logo.tsx` | Renders the lowercase codev wordmark from `wordmarkHalves` — one bold `<text>` per half, no per-char shadow cells — with "co" in `brand.navy` on light / `theme.text` on dark and "dev" in `brand.red`, instead of upstream's two-tone "open"+"code" | Banner is pixel-identical to the landing page wordmark (`codev-landing-page` `app/components/PixelWordmark.tsx`: `text-brand-navy dark:text-foreground` + `text-brand-red`), so the marketing site and the TUI read as one brand. Deliberately fixed brand colors rather than the theme's `secondary`, and no drop shadow — the landing wordmark has neither. | Keep our version wholesale. If upstream restructures the component, re-apply the two-half brand coloring rather than reverting to a theme color. |
| `packages/ui/src/components/logo.tsx`, `packages/ui/src/components/logo.css` | `Logo` renders the lowercase "codev" wordmark instead of upstream's "opencode": the `wordmarkHalves` pixel glyphs of `packages/tui/src/logo.ts` resolved to a 24x6 grid at one unit per pixel (viewBox `0 0 24 6`, was `0 0 234 42`), as two `<path>`s — `data-slot="logo-wordmark-co"` and `…-dev` — with no drop-shadow paths. Colors come from two custom properties defined in logo.css on `[data-component="logo-wordmark"]`: `--logo-wordmark-dev` is always brand red `#ee0033`, `--logo-wordmark-co` is brand navy `#19224c` on light and `var(--icon-strong-base)` on dark. The dark swap is declared three times — under `prefers-color-scheme: dark` for surfaces that never stamp a theme, then under both `[data-color-scheme="light"]` and `[data-color-scheme="dark"]` so the app's explicit choice (`packages/ui/src/theme/context.tsx` sets it on `<html>`) beats the OS preference in both directions. Brand hexes are literals, not theme tokens — same reasoning as the TUI component row. `Mark` and `Splash` (the square "o") are untouched. | The web/desktop banner is the same art the TUI home banner and the landing page wordmark draw, so every surface reads as one brand. | Keep our version wholesale. If upstream restructures the component, re-apply the two-half brand coloring rather than reverting to `--icon-*` tokens. |
| `packages/ui/src/v2/components/wordmark-v2.tsx` (+ fork-only `wordmark-v2.css`) | `WordmarkV2` — the watermark behind the v2 new-session composer (`packages/app/src/components/session/session-new-design-view.tsx`) — draws the codev wordmark from the same 24x6 pixel grid as `Logo` instead of upstream's 720x129 "opencode", as two `<path>`s (`data-slot="wordmark-v2-co"` / `…-dev`). Upstream's watermark treatment is kept verbatim: the `0.6` outer opacity and the alpha mask whose gradient fades the mark out over its bottom half (converted to the new viewBox: gradient `y1` 68/129 → 3.163/6). "co" keeps `fill="currentColor"` so it still follows the caller's `text-*` class; "dev" takes brand red `#ee0033`. Per-half opacities live in the new `wordmark-v2.css`, following the one-CSS-file-per-v2-component convention: `co` is `0.112` (upstream's own `0.16 × 0.7` nesting, flattened), `dev` is boosted to `0.224` on light and `0.336` on dark via `--wordmark-v2-dev-opacity`, declared under `prefers-color-scheme` and both `[data-color-scheme]` values like components/logo.css. The boost is deliberate and measured: at upstream's weight a saturated red composites to within a few levels of the grey "co" half against the dark background and the two-tone disappears entirely, while the same value already reads pink against the light one. | The component is currently **not rendered** — the new-session view drops it (see the row below) — but it stays rebranded and exported so reinstating the watermark does not bring the upstream mark back with it. | Keep our version wholesale, including the per-theme `dev` opacity. If upstream retunes the watermark opacities, re-derive the `dev` boost from the new base rather than adopting a single flat value. |
| `packages/app/src/components/session/session-new-design-view.tsx` | Drops the `WordmarkV2` watermark from the v2 new-session screen and centres the composer. Upstream absolutely positions the content block at `top-[25.375%]` to leave room for the wordmark above it; with the mark gone that offset just parks the composer high in an empty pane, so the outer element becomes `flex items-center justify-center` over `size-full` (carrying the `px-6` inset across) and the `mt-8` spacer under the wordmark goes away. | The wordmark reads as clutter on the desktop new-session screen; without it the pane should be balanced, not top-weighted. | Keep our centred layout. If upstream restyles this view, re-apply the drop + centring rather than restoring `top-[25.375%]`. Reinstating the watermark means restoring the offset too, or it will sit centred with the composer. |
| `packages/app/src/components/session/session-new-design-view.tsx`, `packages/app/src/pages/new-session.tsx` | Drops the `WordmarkV2` watermark from the v2 new-session screen and centres the composer. Upstream absolutely positions the content block at `top-[25.375%]` to leave room for the wordmark above it; with the mark gone that offset just parks the composer high in an empty pane, so the outer element becomes `flex items-center justify-center` over `size-full` (carrying the `px-6` inset across) and the `mt-8` spacer under the wordmark goes away. The pane also takes the same raised card every session sits on: `bg-v2-background-bg-deep` → `bg-v2-background-bg-base` in the view, and `new-session.tsx`'s `rounded-[10px]` wrapper gains `bg-v2-background-bg-base shadow-[var(--v2-elevation-raised)]` — the exact pair `SessionPanelFrame` (`pages/session.tsx`) applies with `newLayout raised`. Verified equal at runtime: same background, same eight-layer shadow, same 10px radius. | The wordmark reads as clutter on the desktop new-session screen; without it the pane should be balanced, not top-weighted. And with the sidebar always on screen, upstream's `bg-deep` made the draft screen read as an extension of the window chrome while every session floated on a card — the two screens have to match. | Keep our centred layout and the card. If upstream restyles this view, re-apply the drop + centring rather than restoring `top-[25.375%]`, and re-check the background against whatever `SessionPanelFrame` then uses rather than hardcoding `bg-base`. Reinstating the watermark means restoring the offset too, or it will sit centred with the composer. |
| `packages/app/src/pages/home.tsx`, `packages/app/src/pages/error.tsx`, `packages/enterprise/src/routes/share/[shareID].tsx` | `Logo` width utilities retuned for the codev wordmark's 4:1 box (upstream's is 5.57:1): home `md:w-xl` → `md:w-104`, error `w-58.5` → `w-42`, share (both call sites) `w-58.5` → `w-42` | Each value is the width at which the new wordmark renders at exactly the height the upstream one did, so no surrounding layout shifts. | Keep our widths; take upstream's surrounding changes. Recompute rather than restore if upstream changes the size. |
| `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) `<ChannelIndicator>` 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. | 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. |
| `packages/app/src/pages/layout-new.tsx` (again) | Mounts the fork-only `<LaunchNewSession />`, 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 `<aside>` owned by `NewHome`, so it exists only on `/`. It becomes app chrome: `layout-new.tsx` wraps its `<main>` in a row flex and renders the fork-only `<AppSidebar class="hidden lg:flex">` beside it, so the sidebar survives every navigation. **The row components stay in `home.tsx`** — `HomeUtilityNav`, `HomeServerRow`, `HomeProjectList`, `HomeProjectEmpty`, `HomeRecentlyClosedRow` and the classes `HOME_PROJECT_NAV_ROW` / `HOME_PROJECT_NAV_LABEL` / `HOME_SECTION_LABEL` gain an `export` and nothing else, so upstream edits to them still apply cleanly; the fork-only `src/components/app-sidebar.tsx` imports and composes them, adding only the column shell and the Recents section. `home.tsx` otherwise loses just `HomeProjectColumn` (dead once the sidebar owns that composition) and the `NewHome` selection/action block, and its grid collapses from `lg:grid-cols-[280px_minmax(0,720px)]` to one `max-w-[760px]` column. The sub-`lg` `HomeUtilityNav` mount is untouched, so the stacked mobile layout is upstream's. The state both screens need (`focusedServer`, `projects`, `selectedProject`, `newSessionProject`, `projectDirectories`, the session-index query, `openNewSession`, `openProjectNewSession`, `openSession`, `selectProject`, `addProjects`, `editProject`, `closeProject`, `unseenCount`, `clearNotifications`, `chooseProject`, `isBackgroundOpen`, `buildHomeSessionRecords`, `HomeSessionRecord`) moves to fork-only `src/pages/home-model.tsx`, which both callers instantiate — safe because the selection lives in `useLayout().home`, the index is one TanStack query deduped by key, and the server-normalizing effect is idempotent. New i18n keys `sidebar.recents`, `sidebar.recents.new`, `sidebar.recents.viewAll` in `en` + `es`. Every `data-component`/`data-action` hook is untouched (`home-project-row`, `home-add-project`, `home-session-row`, `home-session-search`, …) because `packages/app/e2e` selects on them. | The desktop app should navigate like Claude Desktop — one always-visible sidebar with Projects, Recents and pinned Settings/Help — instead of losing all navigation the moment a session opens. Exporting the row components in place rather than relocating them keeps `home.tsx` down to ~36 added lines: upstream changes to those components merge without a conflict, which relocating them would have forfeited. | Keep our structure. On conflict take upstream's `home.tsx` wholesale and re-apply the four edits: the `export` keywords, the `HomeProjectColumn` deletion, the `createHomeModel()` swap in `NewHome`, and the single-column grid. If upstream edits an exported row component, just take it. Never let a `data-component`/`data-action` hook drift — the e2e suite has no other handle on these rows. |
| `packages/desktop/icons/{dev,beta,prod}/` (all PNGs, `icon.icns`, `icon.ico`, `dock.png`), `packages/desktop/icons/README.md` | Regenerated from the fork-only `packages/desktop/icons/icon.svg` by the fork-only `packages/desktop/scripts/generate-icons.ts`: the brand-red `#ee0033` CoDev "C" — the `--mini` splash badge glyph, at the VS Code extension icon's proportions (unit = 120/1024, mark 480x600 centered) — on a white tile, replacing upstream's black/blueprint "o" mark. All three channels are byte-identical for now (chosen deliberately over upstream's per-channel treatments); the generator still writes them separately so a channel can diverge later. `icon.icns` members and `dock.png` use the macOS Big Sur grid (824/1024 inset + drop shadow); Windows, Linux and Store assets stay full-bleed. README rewritten from the Tauri-CLI + Image2Icon recipe to the generator. The stale Tauri-era `android/` and `ios/` subfolders are left untouched — nothing in the Electron build reads them. | Closes the "desktop app icons need design assets" rebrand gap: the Dock/taskbar icon was still upstream's mark. | Keep our assets and README (binary: take ours wholesale). Regenerate via the script rather than hand-editing; if upstream adds an icon size, add it to `FLAT_PNGS`/`ICONSET` and rerun. |
| `packages/tui/src/theme/assets/codev.json` (new file), `packages/tui/src/theme/index.ts`, `packages/tui/src/context/theme.tsx` | Added the `codev` theme — upstream's `opencode.json` palette with `darkSecondary` → `#0891b2` (brand teal) — registered it in the theme index, and made it the default/fallback theme (`"opencode"` → `"codev"` in the store default, kv fallback, and load-failure fallbacks). `theme/assets/opencode.json` itself matches upstream again. | Brand accent lives in a fork-owned theme instead of edits to upstream's palette; the default theme carries the brand. | Keep our theme file, its index registration, and the fallback strings; when upstream changes the opencode palette, mirror it into `codev.json` (keeping our `darkSecondary`). |
| `packages/opencode/src/cli/ui.ts` | `wordmark`/`logo()` render the lowercase codev wordmark via `ansiWordmark` (bold, no shadow, "dev" in brand red on TTY) | Help banner matches the TUI home banner. | Keep our wordmark + logo(); take upstream's surrounding changes. |
Expand Down
Loading
Loading