# Workspace redesign — overview and phase plan _Status: specs written 2026-10-01, nothing implemented yet. Each phase is one PR, executed in order; a later phase assumes the earlier ones are merged._ ## Why AgentHub's lane surface grew one card at a time: a horizontal lane strip on `/workspace`, a detail header below it, a Changes panel beside that, and a Settings page made of horizontal tabs. Orca (https://github.com/stablyai/orca, MIT, source cloned at `/tmp/orca-repo` while these specs were written) solved the same problem — many agent worktrees on one screen — with a left-hand **project → workspace** tree, a terminal workbench in the middle, an activity-bar panel on the right and a full-page grouped Settings screen. We are **borrowing Orca's information architecture, not its look**. The decisions below are fixed for every phase: | Decision | Value | | --- | --- | | Visual theme | **Unchanged.** Keep AgentHub's tokens, dark Radix slate + blue accent, warm light theme, the named themes, Inter + JetBrains Mono. Orca's neutral palette is added only as two more *named* themes in phase 3. | | Terminology | **Only the word changes**: "lane" → "workspace" in UI copy (en + vi), docs prose, CLI output prose (phase 0). Every identifier stays — `/api/lanes`, `agenthub lanes`, `--lane`, `AGENTHUB_LANE_ID`, DB tables, tmux names, component/file/type names, i18n keys, test ids. | | Grouping | Sidebar lists **Projects** (one per git repo = the main worktree's root), each expanded into its **workspaces** (one per lane) and the repo's **untracked worktrees** (from `git worktree list`), the latter shown by default with a user setting to hide them. | | Existing pages | Dashboard, Sessions, Workflows all stay as top-level nav items. Nothing is removed. | | Split panes | The existing 1 / 2 / 4 pane layout (`splitViewStorage.ts`) stays and gains a tab-style header per pane. | | Changes panel | Keeps its Narrow / Medium / Full-screen sizes; gains an activity bar (Files · Changes · Sessions). | | Status bar | A new one-line bar at the bottom of the shell: connection, running / needs-you counts, today's cost, update chip. **No provider quota** — reading Claude quota rotates the stored OAuth token (`cc-usage.js`), and the CLI shows it inside the pane anyway. | | Per-project settings | Phase 2. | | Notification sounds | Phase 3. | | Fonts | Unchanged: UI Inter (`client/tailwind.config.js`), terminal JetBrains Mono 13px (`TerminalView.tsx`). The `claude` CLI has no font of its own — it renders in whatever font the hosting terminal uses. | ## Phases | # | Spec | Scope | Size | | --- | --- | --- | --- | | 0 | [00-rename-lane-to-workspace.md](00-rename-lane-to-workspace.md) | Copy-only rename: i18n values, escaped UI literals, CLI prose, docs. No identifier changes. | small, mechanical | | 1 | [01-sidebar-and-workbench.md](01-sidebar-and-workbench.md) | Project tree in the sidebar, lane strip removed, workspace cards with status dot + context menu, untracked worktrees, pane tab headers, right-panel activity bar with a Sessions tab, status bar. | large | | 2 | [02-settings.md](02-settings.md) | Settings as a full-page grouped nav with search, `/settings/:section` routes, row primitives, per-project pane, worktree-visibility setting moved here. | medium | | 3 | [03-appearance-and-sounds.md](03-appearance-and-sounds.md) | Two Orca-derived named themes, notification sounds per category. | small | Phase 1 may start before phase 0 is merged; its new UI strings must already say "workspace". New code keeps using the existing `Lane*` identifiers, `api.lanes` and `/api/lanes` — only new *user-facing* text uses the new word. ## Ground rules for every phase - Follow the repo's `CLAUDE.md` rules verbatim. Three bind these specs hardest: the console has **exactly one render site** and collapses with CSS; the console never writes a lane's stage; lane git facts come from `GET …/:id/git`, never from the list endpoint. - Every new or edited `.ts/.tsx/.js/.css` file starts with the header from `skills/file-headers/` (`bash skills/file-headers/scripts/check-headers.sh` must exit 0). - Backend changes: `npm run test:server` (private tmux server — never run the suites bare). Frontend: `npm run test:client`; snapshot baselines in `client/src/pages/__tests__/screens.snapshot.test.tsx` are regenerated with `cd client && npx vitest run -u` **only after** the diff was reviewed as the intended change, and the PR says which screens changed. - Docs are part of the change-set: `CLAUDE.md` (its sync marker and any statement made wrong), `docs/API.md`, `docs/CLI.md`, `docs/LANES.md` (file name kept; prose says "workspace"), `client/README.md`, `README.md`. Apply the `update-project-docs` skill before finishing. - i18n: every new string goes into **both** `client/src/i18n/locales/en/*.json` and `…/vi/*.json` (see `docs/I18N.md`); no hardcoded UI text. - No new runtime dependency unless the spec names it. The specs name none. - Keep response shapes backward compatible; add fields, never rename or drop one in the same release as its consumer. - Each PR ends with a before/after screenshot of every changed screen in the PR body (the Orca reference screenshots used for these specs live in `docs/plans/workspace-redesign/reference/`). ## Verification matrix (all phases) | Check | Command | | --- | --- | | Server suite | `npm run test:server` | | Client suite | `npm run test:client` | | Type check | `cd client && npx tsc --noEmit` | | Headers | `bash skills/file-headers/scripts/check-headers.sh` | | Build | `npm run build` | | Manual | `npm run dev`, open `/workspace`, `/settings`, create a workspace from the sidebar, start a run, resume a session from the Sessions tab, switch theme Dark/Light/System on every changed screen |