Files
nntrivi2001 a6bd33bcff feat: workspaces own their sessions; desktop parity; sidebar and settings cleanup
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).
2026-10-02 13:19:50 +07:00
..

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

  1. Merge the Workflows page into the Dashboard → Analytics tab.
  2. The sidebar lists workspaces, each expanding to its sessions only — like Claude Desktop's project list (name ›, + on the row, sessions under it).
  3. 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.
  4. Clicking a session opens its tmux pane and never resumes it (a resume re-reads the whole transcript and burns tokens).
  5. The Orca parts are regrouped by workspace and kept where they still make sense.

Phase A — Workflows inside Analytics

  • Dashboard.tsx Analytics → the existing workflow sub-tab renders the whole Workflows page 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, i18n nav.workflows removed.
  • 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_runs row with that session_id, the tmux session agenthub-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.
  • 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.md and 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-dir for 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/instructions
  • GET /api/lanes/:id/sources, POST …/sources/folder {path}, POST …/sources/file (raw body, name header, size cap), DELETE …/sources/:sourceId — all sameOriginGuard.
  • 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 as tool.

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.