Chat UI:
- Each Claude/Codex session keeps its own chat/terminal view; Settings only
sets how new sessions open.
- Composer + menu: upload, project files and folders (#54, also dragged from
the Files/Changes tree), context files, recent uploads, skills, plugins.
- Activity side panel (progress, outputs, files read, uploads, memory,
skills, connectors) with a file preview; edited-file counts per turn.
- Permission-mode chip (Shift+Tab steps, read back from the pane:
server/lib/pane-mode.js, GET|POST /api/run/:id/permission-mode).
- Stop (Esc) while the main agent works; the status is checked per agent
(with session_id /api/agents ignores its status filter) and re-read every
5 s while Stop shows.
- Dropped images shown in the conversation (GET /api/run/drop/:name, the
requester's own drop dir), full-size viewer.
- A plain-text paste over 5,000 characters is attached as pasted-text.txt,
so no prompt reaches tmux/argv limits (#68).
Changes panel: every /api/lanes/:id/git* route takes ?source=<lane_sources
id> (sourceFolder; ENOSOURCE otherwise) and a folder picker switches the
whole panel to a workspace's extra folder (#70).
Server mode S3 (one Linux user per account) — experimental, verified with
fake sudo plus a P6 managed-settings spike on a test account:
- member tmux listing runs in the background (cached, 15 s => unknown);
- transcript snapshot copy is async, chunked, temp file + rename;
- Express Layer patch only on Express 4;
- tmux capturePane/sendKey go to the member's own server.
Docs: the multi-user design moved in as docs/plans/server-mode/README.md
(the AgentHub-Server repo is gone); S3-PLAN P6 result; LANES/API/openapi.
- Sidebar: a tool filter (shown once workspaces of two tools exist, kept in
agenthub.sidebar.projects → tool; reordering under it keeps the hidden
workspaces' places), and search that also finds a workspace by one of its
session names, showing only the matching sessions.
- Workspace home: the repository it belongs to (root, main branch, worktree
count) under the title, and each recent's cost.
- Transcript page: an explicit Resume for a Claude session started in a
workspace's own folder (SessionResumeButton). It warns that a resume re-reads
the whole transcript, re-reads the live panes, then starts in the first free
pane and opens it; a live session offers Open pane instead.
/workspace?lane=<id> opens on the workspace's home (WorkspaceHome): a prompt
box whose Start opens a new session in the first free pane slot, Recents (a
live session attaches its pane, any other opens its transcript, nothing
resumes), and Instructions / Memory / Context / Folder. Instructions live in
lanes.instructions, extra folders and uploaded files in the new lane_sources
table (copies under <data dir>/workspace-context/<lane id>/); spawnRun reads
them from the lane's rows and hands Claude --add-dir + an appended system
prompt file, Codex --add-dir + developer_instructions. Memory is read-only.
Every dashboard pane carries AGENTHUB_RUN_ID; hooks forward it and the run
records which session the pane holds (a Claude pane follows /clear and
/resume but not a nested claude -p), so the sidebar and notifications open
the right pane (&run=). Settings loses its Projects group; Worktrees now
decides which worktrees Add folder suggests.
The sidebar's project tree becomes a flat workspace list (WorkspaceTree):
one row per workspace in the stored order, each expanding to its sessions.
A session that still has a live pane opens /workspace?lane=<id>&run=<runId>,
which only attaches pane 0 to that tmux session; any other session opens
its read-only transcript. Nothing in the sidebar starts or resumes a run.
Settings moves from a tab bar to /settings/<section>: a left nav grouped
General / Agents / Routing / Git / Projects (a select on narrow screens), a
search box over every section (Ctrl/Cmd+F, Enter opens the first match), and
row primitives. Each AI tool has its page under agents/<id>, the AI Tools
modal becomes the Agents page, Pricing shows every vendor, Git → Worktrees
sets which untracked worktrees the sidebar lists, and each project gets a
page with its own worktree override and Forget all. ?tool= and #ai-tools
links redirect to the path form.
The Workspace page's lane strip moves into the sidebar as a project tree:
workspaces grouped by git repository (new GET /api/projects, cached in
memory, POST /api/projects/refresh), untracked worktrees with Adopt, inline
rename, drag/Alt+arrow ordering and a right-click row menu. The selected
workspace is the URL's ?lane=, one shared lane list feeds the tree, the new
bottom status bar and the page. The Changes panel gains an activity bar
(Files / Changes / Sessions, with resume), and split panes get a header.