8546748759
Dependencies
- Security: body-parser and multer DoS advisories fixed (npm audit: 0).
- Server: Express 5 (query parser kept "extended", req.body defaults to {},
SPA catch-all /{*splat}, send-file helper restores Express 4's dot-folder
rule for sendFile/download, alerts ack route without inline regex),
better-sqlite3 13, js-yaml 5 (server/lib/yaml.js keeps js-yaml 4's default
schema), uuid dropped for crypto.randomUUID, node-pty beta.18, multer 2.5.
- Client: React 19, xterm 6 (WebGL renderer replaces the removed canvas one,
DOM fallback on context loss; Alt+arrow word moves re-mapped), lucide-react 1,
TypeScript 7, i18next/react-i18next/codemirror minors.
Workspace rename step 4
- `agenthub lanes` and `--lane` exit 1 with "renamed: use …"; client api.ts,
the CLI and the MCP server call /api/workspaces; /api/lanes stays mounted.
Server mode (S3): members manage their own Claude Code config
- server/lib/cc-target.js resolves whose config a /cc-config request touches
and gates the router by allowlist; /profiles* and /plugins/update-all stay
admin-only. Member writes go through write-as, CLI calls through sudo as the
member (never -y), reads through openSafe; cc_config_changed reaches only
its owner. Not verified live on an S3 install yet.
Other
- Chat: an HTML file is an artifact only when written whole and not a project
page (index.html, or under src/, public/, templates/, …).
- OpenAPI covers every /api route; openapi-coverage.test.js guards it.
- read-pool test keeps its event loop alive (its worker is unref'd).
- Docs: plan statuses, checklists, CLI.md, LANES.md, SERVER-MODE.md, API.md.
81 lines
5.8 KiB
Markdown
81 lines
5.8 KiB
Markdown
# Workspace redesign — overview and phase plan
|
|
|
|
_Status: specs written 2026-10-01; all four phases are built (sidebar tree + status bar + workbench `ba2c4e1`, grouped Settings with search `eb90244`, Orca themes + notification sounds `b71024f`, the lane → workspace copy rename). Kept as the design record. Each phase was one PR, executed in order._
|
|
|
|
## 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 |
|