Files
Nathan Brake 91d34bb9b2 feat: redesign web dashboard with workspace-centric layout (#607)
* feat: redesign web dashboard with workspace-centric layout

Replaces the flat session-list web UI with a Conductor-inspired workspace layout:

- Sidebar groups sessions by project directory with expandable tree
- Split content pane: terminal left, inline diff right (resizable, collapsible)
- Workspace header with lifecycle badges and action buttons
- New session creation modal with project combobox and agent grid
- Terminal auto-reconnect with countdown (3 retries, then manual)
- Mobile: collapsible sidebar overlay, responsive font sizes, touch targets

Backend changes:
- Print all network interface IPs (including Tailscale) on aoe serve
- Persist auth token for 24 hours so URLs survive restarts
- Unset TMUX env in PTY spawn so serve works inside tmux
- Remove unused API endpoints (groups, profiles, worktrees, delete, update)
- Bump cargo build parallelism from 4 to 8

Also removes 12 dead component files and consolidates duplicated status
color mappings and session-active checks into shared lib/session.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: default sidebar closed on mobile, remove duplicate empty state

- Sidebar defaults to closed on viewports < 768px so mobile users
  see the main content immediately instead of a full-screen overlay
- Removed duplicate "No sessions yet" message from sidebar; the main
  content area already shows the CTA. Sidebar only shows "No matches"
  when actively searching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: rewrite Playwright tests for workspace-centric dashboard

Rewrites all 34 e2e tests for the new UI layout:
- Dashboard layout: header, empty state, offline indicator
- Sidebar: toggle, desktop default open, search
- Create session modal: all fields, submit states, close behaviors
- Settings: gear button, keyboard shortcut
- Keyboard shortcuts: n, D, ?, s, Escape
- Mobile: sidebar closed by default, overlay, touch targets
- Design system: warm navy background, DM Sans font, focus rings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: group worktree sessions by main repo path in sidebar

Worktree sessions have project_path pointing to the worktree directory
(e.g., ~/.agent-of-empires/worktrees/feat-auth), not the original repo.
This caused the sidebar to show the worktree dir name instead of the
repo name.

Now uses main_repo_path from the API (the actual repo root) for grouping
when available, falling back to project_path for non-worktree sessions.
So all sessions for agent-of-empires show under "agent-of-empires"
regardless of whether they use worktrees.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: remove screenshot artifacts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: show static title in header instead of selected session name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove header title text entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: flatten sidebar to simple session list, remove nesting

Removes project directory grouping, expand/collapse state, and
project status aggregation. Sessions are now a flat list with
status dot, name, and agent badge. Simpler foundation to build on.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: remove multi-agent session tabs from content area

Each session gets its own sidebar entry now, no need for tabs
within the terminal pane. Removes handleSelectSessionTab dead code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: remove search box from sidebar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: rebuild web frontend on source changes instead of skipping

build.rs previously short-circuited when web/dist/ existed, silently
ignoring source changes. Now it always runs npm run build when cargo
detects web source file changes via rerun-if-changed directives.

Also skips npm install when node_modules already exists to keep
incremental rebuilds fast.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: check .package-lock.json for npm install completeness, remove unused var

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add non-null assertion for groupSessions[0] in useWorkspaces

Groups are always created with at least one session, so the first
element is never undefined. TypeScript strict mode flagged it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace sun icon with gear, move settings to sidebar footer

The SVG was a sun/brightness icon, not a gear. Replaced with a proper
gear icon (Lucide settings path). Moved from the header to the sidebar
footer so it's accessible whether sidebar is open or closed on mobile.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace hamburger icon with sidebar panel toggle icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: swap blue-tinted navy surfaces to neutral slate

Replaces the warm navy palette (#0f172a etc) with neutral zinc tones
(#18181b etc) for a cleaner, more professional dark background.
Updates terminal theme to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: resizable sidebar, filter button, and diff panel toggle

- Sidebar is draggable to resize (200-480px), width persisted in localStorage
- Filter button (funnel icon) next to New Session toggles a search input
  that filters sessions by name, branch, agent, or title
- Right sidebar toggle (mirrored panel icon) in header to show/hide
  the diff panel, highlights when panel is open

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: split right panel into diff viewer (top) and shell (bottom)

The right sidebar is now vertically split: git diff viewer in the upper
half, paired terminal shell in the lower half. The shell section has a
host/container toggle that appears when the session is sandboxed.

Shell terminals are placeholder for now (marked "coming soon").

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: allow right panel to open even with no session selected

ContentSplit and RightPanel now always render. When no session is
selected, the left pane shows the empty state and the right pane
shows empty diff/shell placeholders. The toggle button in the header
works regardless.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove unused TerminalView import from RightPanel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace loud New Session button with subtle header + icon

Sidebar header now shows "SESSIONS" label with a gray + icon button
and filter icon. Much less visually dominant than the full-width
amber button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: diff panel stuck on loading, sessions header casing

The diff panel got stuck on "Loading changes..." when the API returned
an empty diff (raw === ""). The early return skipped setLoading(false).
Fixed by moving setLoading outside the cache comparison.

Also changed "SESSIONS" header to normal case "Sessions".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: wire paired host/container terminals in right panel

Adds two new WebSocket endpoints:
- /sessions/{id}/terminal/ws - attaches to the TerminalSession (host shell)
- /sessions/{id}/container-terminal/ws - attaches to ContainerTerminalSession

The right panel's lower half now connects to the actual paired tmux
terminal sessions instead of showing a placeholder. Host/Container
toggle switches between the two WebSocket paths. Only shows the
container toggle when the session is sandboxed.

useTerminal now accepts a wsPath parameter to support different
WebSocket endpoints while reusing all the xterm/reconnect logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: auto-create paired terminal on demand from web dashboard

Adds POST /api/sessions/{id}/terminal endpoint that calls
instance.start_terminal() to create the paired tmux session if it
doesn't already exist. The frontend calls this automatically when
the right panel's shell section mounts, so users don't need to
pre-create terminals from the TUI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: auto-create container terminal on demand

Adds POST /api/sessions/{id}/container-terminal endpoint that calls
start_container_terminal_with_size() to create the container tmux
session. The frontend now calls the appropriate endpoint (host or
container) based on the shell mode toggle before connecting the
WebSocket.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: match header background to sidebar (surface-900)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: switch fonts from DM Sans/Satoshi to Inter

Inter is the standard developer tool font (Linear, Vercel, Raycast).
Replaces DM Sans (body) and Satoshi (display) with Inter for both,
giving the UI a cleaner, more IDE-like feel. Removes the Fontshare
CDN dependency since Satoshi is no longer loaded.

Also updates theme-color meta tag to match the neutral slate palette.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: lighten sidebar/header from near-black to slate gray

surface-900 (#18181b -> #1e1e21) and surface-850 (#202023 -> #232326)
are now noticeably lighter, giving the sidebar and header a slate feel
rather than pure black. Terminal background (surface-950) stays dark.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: invisible resize handles, only show cursor and highlight on hover

Removed the visible bg-surface-700 border from both sidebar and
content split drag handles. Now invisible by default, cursor changes
to col-resize on hover, and a subtle highlight appears while hovering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: remove stop/restart/review/archive buttons and dead code

Removes:
- Stop and Restart buttons from WorkspaceHeader
- Review, Archive, Unarchive lifecycle buttons
- handleStop, handleRestart, handleLifecycleChange from App.tsx
- stopSession, restartSession API functions
- stop_session, restart_session Rust handlers and routes
- setLifecycleOverride, getLifecycleOverrides, localStorage lifecycle system
- WorkspaceStatus "reviewing" and "archived" variants (now just active/idle)
- Unused Status import from api.rs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove Settings text label, keep just the gear icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: match terminal background to Ghostty default (#282c34)

Swaps the near-black terminal background to Ghostty's default warm
dark gray (#282c34). Feels more like a real terminal and less like
a void. Updates both the xterm.js theme and the CSS surface-950 token.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: sidebar lighter than content, subtler borders (Conductor-style)

Restructures the surface hierarchy:
- Sidebar + header: surface-800 (#2c2c30) - lightest, like Conductor
- Main content/workspace header: surface-900 (#1c1c1f) - darker
- Terminal: surface-950 (#17171a) - darkest

Softens all borders to border-surface-700/20 (barely visible) instead
of solid borders, matching Conductor's refined restraint. The visual
depth now comes from surface color differences, not hard lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: subtle filter icon active state instead of orange highlight

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: subtle active state for right sidebar toggle too

Both header panel toggle buttons now use dim/secondary gray states
instead of orange highlights.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: left sidebar toggle highlights when sidebar is open

Matches the right panel toggle behavior: dim when closed,
slightly brighter when open.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: cargo fmt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: replace create session modal with "not supported yet" dialog

Removes CreateWorkspaceModal, createSession API function, fetchAgents,
AgentInfo type, pendingSelectRef, knownPaths memo, and handleCreate.
The + button now shows a simple dialog directing users to the CLI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: hide right panel on mobile viewports

The right pane (diff + shell) and its drag handle are now hidden
below md breakpoint. On mobile the terminal gets the full width.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: right panel toggle visible on mobile, opens as overlay

The right panel toggle button is now always visible in the header.
On mobile, tapping it opens the diff/shell panel as a full-screen
overlay with a close button. On desktop, behavior is unchanged
(inline split pane with drag handle).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 21:25:49 -04:00
..