diff --git a/CHANGELOG.md b/CHANGELOG.md index c62f9cb470..1e51e8eb60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -294,6 +294,14 @@ already in use` and no way forward short of finding the file in a temporary selected at all — you can clear it by clicking the selected one — the list is empty rather than everything at once. ([#300](https://github.com/quickbeard/codev-code/pull/300)) +- **Starting the app returns you to what you were doing** — every launch opened + a **New session** tab, even when you had sessions open and were plainly in the + middle of something. Now a window with anything open comes back to the session + it was last in, on whichever side you were using — Code and Work each remember + their own — and a new session opens only when there is nothing to come back + to. If the session you were last in has since been deleted, or its server is + gone, the window settles on a tab that is already open instead of a dead one. + ([#301](https://github.com/quickbeard/codev-code/pull/301)) - **Typing `@` lists your files again** — the `@` menu was meant to offer files first, but on a bare `@` it showed only agents and references: it filled the diff --git a/DIVERGENCES.md b/DIVERGENCES.md index e30206afb0..c7e98444db 100644 --- a/DIVERGENCES.md +++ b/DIVERGENCES.md @@ -119,7 +119,7 @@ from the squash message first, or use a plain merge. | `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` | Four changes, all 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. (4) `openNewTab` routes all five of its project-resolution branches through a local `openDraftFor(...)`, which selects the draft already open for that server + directory — via the fork-only `findOpenDraft` in `pages/home-draft-reuse.ts` — and only calls `tabs.newDraft` when there is none. The `+` button gains `data-action="titlebar-new-tab"` so e2e can address it without colliding with the sidebar row, which carries the same accessible name. The model read off the active tab still seeds a *new* draft only; a reused one keeps its own, as selecting its tab by hand would. | 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, which is now the rule for every new-session affordance rather than a Home-only quirk (see the `openNewTab` change and `pages/home-draft-reuse.ts`). 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/context/tabs.tsx` | `newDraft` inserts with `tabs.unshift(tab)` instead of `tabs.push(tab)`, so a draft opens at the head of the tab strip. Session tabs (`addSessionTab`) still append, and nothing else about draft handling changes. | A draft is where you start a session, so it belongs at the front of the strip rather than behind every session already open — with several tabs open the New session tab was scrolling off the right-hand end. | Keep the `unshift`. On conflict take upstream's `newDraft` and swap the insert back. Note the knock-on: `promoteDraft` replaces the draft **at its own index**, so a promoted session keeps the head position and sessions accumulate newest-first. That is intended — the tab you are working in should not jump across the strip the moment you send the first message — but if it is ever unwanted, move the tab in `promoteDraft` rather than reverting this, or the New session tab goes back to the end. | -| `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` (again) | Mounts the fork-only ``, which on desktop decides one time per boot where the window lands: a window with tabs open on the showing side resumes that side's last session (`layout.home.lastSession`, validated with `sessionAlive` the way the Code/Work switch does), falling back to a session tab already open when that history is unusable; only a window with nothing open lands on a new-session draft (reusing an existing empty draft rather than stacking one up per launch). The chain lives in the exported pure `launchLanding`, tested in the fork-only `packages/app/test-browser/launch-landing.test.ts`, because the desktop-only path cannot be driven from the web e2e harness — the same split `workspace/side.ts`'s `folderEntry` uses. 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 `