a6bd33bcff
Workspace sessions (docs/plans/desktop-parity, phases 1-5 and 7): - sessions.lane_id: a workspace lists only the sessions its panes held, stamped by bindRunSession (first writer wins, nested `claude -p` excluded); GET /api/sessions?lane=&archived= - session row state dot, double-click rename, archive (sessions.archived_at, hides only); the activity bar's duplicate Sessions tab removed - Fork beside Resume (--fork-session, Claude only), Ctrl/Cmd+click a live session opens it in a second pane, a diff line's comment is pasted into the workspace's last-focused pane (lib/panePaste.ts) dashboard_runs stability: - a pane's previous run is archived as <pane>@<started_at> instead of being overwritten by INSERT OR REPLACE - a run is flagged abandoned only once its tmux session is gone, at boot and on the run-heal beat (panes outlive a server restart) UI: - sidebar: no footer, language or theme block; small collapse button in the brand corner; version + update check in the connection details modal, a status-bar dot while a release is out; language in Settings -> General - one Switch component for every switch, the themed Checkbox for every checkbox (no native checkboxes) Also: AI Tools catalog trimmed to 10 built-ins (custom-file prompt modes tested through fixtures), and the workspace plans under docs/plans/ (the multi-user server plan lives in the AgentHub-Server repo).
Workspace = Claude-Desktop-style project (v2 of the workspace redesign)
Replaces the Orca-shaped project → workspace → worktree tree from phase 1.
Three phases, each one commit on main, in order.
What the user asked for
- Merge the Workflows page into the Dashboard → Analytics tab.
- The sidebar lists workspaces, each expanding to its sessions only —
like Claude Desktop's project list (name ›,
+on the row, sessions under it). - A workspace opens on a project home like Claude Desktop's: title, prompt box, Recents; on the right, Instructions, Memory, Context (files/documents) and Folder (folders) — no Scheduled.
- Clicking a session opens its tmux pane and never resumes it (a resume re-reads the whole transcript and burns tokens).
- The Orca parts are regrouped by workspace and kept where they still make sense.
Phase A — Workflows inside Analytics
Dashboard.tsxAnalytics → the existingworkflowsub-tab renders the wholeWorkflowspage body (pipelines, skill usage, Workflow-tool runs, DAG, error map, complexity, compaction, drill-in) under its current small cards./workflows→<Navigate to="/?tab=analytics&sub=workflow">; the sidebar loses its Workflows item;DocumentTitle, i18nnav.workflowsremoved.- No server change.
Phase B — Sidebar: workspaces → sessions
WORKSPACES + 🔍 ⚙
agenthub › +
SG_MiniApp ⌄ +
● Tách thông tin official account (● = a live tmux pane)
○ Kiến trúc tenant đơn mở rộng
scratch › +
- A flat list in the stored drag order (
agenthub.workspace.laneOrder, kept); the repo grouping, the "Folders" pseudo-project, untracked worktrees and Adopt leave the sidebar. - A row's chevron expands its sessions (
GET /api/sessions?cwd=&tool=, the newest 20, the session's name or first prompt). A dot shows a live pane. - Click the name → the workspace home (Phase C). Click
+→ the home with the prompt focused. Click a session:- its pane is alive (a
dashboard_runsrow with thatsession_id, the tmux sessionagenthub-lane-<id>[-slot]still there) → the session view attached to that pane — no new process, no resume; - no live pane → the read-only transcript (
/sessions/:id, Conversation tab), with Resume as a separate, explicit button that warns about context cost.
- its pane is alive (a
- Kept: rename (double-click), drag / Alt+↑↓ reorder, right-click menu (Start/Stop, Rename, router, readme, Copy path, Reset, Remove).
- Header:
+new workspace (the Add modal), search (filters workspaces and loaded session titles), a tool filter.
Phase C — Workspace home + sources
Route: /workspace?lane=<id> = home; /workspace?lane=<id>&run=<runId> = the
session view (today's terminal, split panes and the Files/Changes panel,
unchanged — the one-render-site console rule still holds).
Workspaces / SG_MiniApp 📌 ⋯
┌────────────────────────────────────────────┐ ┌ Instructions ✎ ┐
│ How can I help you today? │ │ text… │
│ + [Claude ▾] [model ▾] [effort ▾] [Run]│ ├ Memory View ────┤
└────────────────────────────────────────────┘ │ CLAUDE.md, auto │
Recents ├ Context + ─┤
Tách thông tin official account 2h ago ● │ spec.pdf notes… │
Kiến trúc tenant đơn mở rộng Sep 29 ├ Folder + ─┤
│ 📁 SG_MiniApp │
│ 📁 sg-shared │
└──────────────────┘
- Prompt box = today's run form (tool's model picker, permission, effort, bypass), compact. Run → a new pane, then the session view.
- Recents = the same session list as the sidebar, with time ago, cost and the live dot.
- Instructions — one text per workspace,
lanes.instructions. Reaches the agent at spawn: Claude--append-system-prompt <text>; Codex-c developer_instructions=<text>if 0.155 accepts it (verified while building — otherwise Claude-only, shown as "not supported by "). Never written into the user's repo. - Memory — read-only: the folder's
CLAUDE.md/AGENTS.mdand Claude's auto-memory dir for that cwd (<CLAUDE_HOME>/projects/<slug>/memory/). View memory opens them in the existing markdown viewer. - Context — files the user uploads (pdf, md, txt, images…, ≤ 10 MB each),
stored by AgentHub under
<data dir>/workspace-context/<laneId>/with a server-chosen name. The directory goes to the agent as--add-dir, and the appended instructions list the files, so the agent knows to read them. - Folder — the workspace's own cwd (fixed) plus extra folders, each
--add-dirfor Claude and Codex (both verified in--help); other tools show them as unsupported. + opens a folder picker that also suggests the repo's untracked worktrees (what is left of Adopt). A folder must exist, be a directory and not be or contain the OS home (validateHomeDir). - ⋯ menu = the row menu plus what Settings → Projects held (facts, worktree count, Forget).
Schema (migration-safe)
lanes.instructions TEXT(ADD COLUMN, null).CREATE TABLE IF NOT EXISTS lane_sources (id INTEGER PRIMARY KEY, lane_id INTEGER NOT NULL REFERENCES lanes(id) ON DELETE CASCADE, kind TEXT NOT NULL CHECK (kind IN ('folder','file')), path TEXT NOT NULL, name TEXT NOT NULL, size INTEGER, added_at TEXT NOT NULL).- Removing a workspace deletes its rows and AgentHub's own context copies — never a user folder.
API
GET/PUT /api/lanes/:id/instructionsGET /api/lanes/:id/sources,POST …/sources/folder {path},POST …/sources/file(raw body, name header, size cap),DELETE …/sources/:sourceId— allsameOriginGuard.GET /api/lanes/:id/memory→ the memory files above, read-only.- Spawn (
spawnRun) reads instructions + sources from the lane row, never from the request — the same rule astool.
Settings
- Projects group leaves Settings (now the workspace's ⋯ menu).
- Worktrees stays, renamed "Worktree suggestions": whether Add folder suggests untracked worktrees and from which sources.
Verification
Each phase: tests first for new logic, npm run test:server,
npm run test:client, headers, build, screenshots; docs + CLAUDE.md marker.