Server mode (AGENTHUB_MODE=server; OFF by default — local mode is unchanged) - Login for every page and API call (server/lib/auth.js, routes/auth.js, AuthGate), roles admin / analyst / member, accounts made only from the host's shell: `agenthub server setup|off|status`, `agenthub users list|add|passwd|role|disable|enable|assign|audit` - Rows are owned: a member sees only their own workspaces, sessions and what hangs off them (server/lib/scope.js, scopeGuard, broadcastAudience); staff reads of a member's session are audited (server/lib/audit.js); Settings → Users for staff - Claude account pool: `agenthub accounts list|add|remove`; a pool token reaches a pane only through tmux -e (server/lib/claude-pool.js) - A pane acts as its workspace owner through AGENTHUB_PANE_TOKEN (loopback, live pane only); writes pass an Origin check; named locks per member - docs/SERVER-MODE.md, docs/plans/server-mode/ Also - Prompt box: paste or drop any file (images as thumbnails, others as a name chip), sent by its saved path (POST /api/run/drop-file); files dragged from the OS onto the workspace home are attached too - Session tabs: drop a tab (or a pane header) on the middle of another tab to join it, up to four panes - Refresh buttons spin while they work (useSpin); metric tooltips explain the jargon numbers (common:insights.help.*) - Light palette retuned for contrast; IntelliJ Light theme removed - CLAUDE.md sync marker trimmed; its history moved to docs/CLAUDE-SYNC-LOG.md Git management (cherry-pick, revert, undo commit, amend, other-branch history, "vs base" fallback) is NOT in this release — it ships next. Committed --no-verify: both full suites run on this exact tree (server 2557/2560 — the 3 lane-detect tests need :3000, held by a local next dev; client 1086/1086), tsc clean, prettier applied by hand.
18 KiB
AgentHub
Internal SmartGift build. Local-first control surface for Claude Code agents —
monitoring is one part of it, not the whole. Hooks POST every tool call to an
Express + SQLite server and a React UI updates over WebSocket; workspaces track
parallel agent work, one working directory each; and the agenthub CLI drives real terminal
sessions, workspace runtimes, and Claude Code's own configuration.
AgentHub records and shows — it does not orchestrate. The session in control makes every decision.
Internal build — all rights reserved.
(Tiếng Việt: README.vi.md)
Main features
Observe
- Sessions, agents, events. Everything Claude Code emits, recorded and searchable: tool calls, token usage, cost, subagent trees, transcripts.
- Analytics and cost. Per-model token totals and estimated cost, with editable pricing rules; top tools, agent types, and workflow patterns.
- Activity feed and alerts. A live event stream, alert rules, and webhook targets that fire on them.
- History import. Every session under
~/.claude/projects/is imported on startup; archives from another machine come in through Settings → Import History (idempotent, never double-counts tokens). - Remote sources. Pull session history from other machines over SSH
(
agenthub remote-sources).
Drive
- Workspaces. One workspace per working directory, surviving session restarts. Once you install a pipeline template (none ships), a workspace moves through its stages and the dashboard shows where it is.
- Stage detection. With a template installed, the stage is inferred from the
tool stream, so a session that never calls
agenthub stagestill shows progress — rendered dashed amber and never as done, because an inference is not evidence. - Run Claude Code or Codex from the browser. A real terminal (tmux + a real
PTY, rendered with xterm.js) attached to a workspace's directory — the exact TUI
you'd see locally, fully interactive, resumable, and attachable from a real
terminal too via
agenthub workspace shell. Which CLI it starts is the workspace's own setting. This is the part that needstmuxinstalled — see Prerequisites. - Git, from the dashboard. Each workspace card shows its branch,
↑ahead ↓behindand its uncommitted files, with buttons for the ordinary moves: fetch, pull (always--ff-only), push, commit-all, and switching branch on a clean tree. Beside the workspace sits a collapsible Changes panel — an overview of the changed files, a full review of every diff, or one file at a time, comparing either uncommitted work or the whole branch against its base. There is no merge/rebase/reset button by design: recovery from those needs a terminal. - Per-workspace app stacks. A repo that declares
.agenthub/profile/gets its own slot, ports and services per workspace (agenthub workspace up|down|logs).
Configure
- Workspaces like Claude Desktop projects. The sidebar lists every workspace with its sessions under it (a live one opens its tmux pane, any other its conversation with a prompt box — sending a message resumes it, opening never does; Analyst in the right panel opens its analysis). A workspace opens on its home: a prompt box that starts a new session, Recents, and the workspace's own Instructions, Memory, Context files (picked with + or dragged in from the OS) and extra Folders, which Claude and Codex sessions start with. Files and images dragged onto a terminal or a prompt box are uploaded and attached by their saved path.
- Settings as one page per section (
/settings/<section>): a left nav grouped General (General / Data / About / Appearance / Pet / Notifications) / Agents / Routing / Cost / Git, a search box (Ctrl+F) over every section whose results deep-link a row's sub-tab and anchor, a page per installed AI tool, per-vendor model pricing, and which untracked worktrees a workspace's Add folder suggests. - Claude Code + Codex configuration explorer. Settings hosts one page per
tool: every plugin, skill, subagent, slash command, MCP server, hook, settings
file, memory file, marketplace, keybinding and statusline Claude Code knows
about — read for all of them, edit/create/delete for the text-file surfaces
(skills, agents, commands, output styles,
CLAUDE.md). Plugins, MCP, hooks andsettings.jsonstay read-only: they race with the live CLI. - Updates. Release-based update detection with an in-UI Update all (marketplaces → every plugin → AgentHub last → one session reload).
- Appearance. Settings → Appearance picks Dark / Light / System (follows the OS live) and a theme per mode — dark: Default, Darcula, Apple Dark, Orca Dark; light: Default, Apple Light, Canvas, Orca Light. Each mode remembers its own theme, so the sidebar's quick toggle swaps between the two. Per-browser only.
- Notification sounds. Settings → Notifications picks a sound (None, Chime, Pop, Alert — off by default) played with every notification shown, and each notification type can pick its own.
- A CLI for all of it (
agenthub, plusagenthub repl), a PWA install, and a UI in English, Vietnamese, Chinese and Korean. - Outside the dashboard, all opt-in: a read-only MCP server
(
claude mcp add agenthub -- agenthub mcp, docs/MCP.md), a Claude Code statusline with session and today's cost (agenthub statusline install, docs/STATUSLINE.md), and Prometheus rules + Grafana boards for/api/metrics(docker-compose.monitoring.yml, docs/MONITORING.md). - Server mode for a shared dashboard (
agenthub server setup): a login on every page and API call, with admin / member / analyst roles. It is off by default, and a local install does not change. It is login only, without per-user isolation yet (docs/SERVER-MODE.md).
Prerequisites
| Need | Version | Required for |
|---|---|---|
| Node.js | >= 20 (>= 22.5 for a plugin install) | Everything. Both suites are verified green on 24 and 26 |
| npm | 9+ | Ships with Node |
| git | any | Cloning, and every workspace operation (worktrees, branch/status reads) |
| tmux | 3.x | The browser run console, agenthub workspace shell, typing /reload-plugins into a live pane |
| Claude Code | 2.x | Hook ingestion — the whole monitoring side |
| Codex CLI | any | Optional — only for codex workspaces |
GitHub CLI (gh) |
any | Optional — only for agenthub workspace ci status |
| systemd (user) | — | Optional — only for agenthub service install (Linux auto-start on boot) |
Node 25 is the one version to avoid: it breaks 6 server tests through a
better-sqlite3 ABI mismatch and 20 client tests through a global localStorage
change. Both were gone again by 26 (1712 server + 488 client tests green on
v26.8.1).
Installing tmux
The dashboard shells out to the tmux binary; there is no bundled fallback, so
Start Run and agenthub workspace shell fail without it. Everything else
(sessions, analytics, workspaces, stage detection, the CLI) works fine.
sudo apt install tmux # Debian / Ubuntu
sudo dnf install tmux # Fedora / RHEL
brew install tmux # macOS
sudo pacman -S tmux # Arch
Windows has no native tmux — run AgentHub under WSL2 and install it there.
macOS (code-audited, untested on a Mac): brew install node git tmux (Node
= 22.5 for the plugin), add
~/.local/bintoPATHin~/.zshrc. There is no systemd, so the dashboard runs until logout/reboot and comes back at the next Claude Code session, or by hand withagenthub start. Details and a checklist to verify it: INSTALL.md § macOS.
Verify, both from your shell and from the server's point of view:
tmux -V # e.g. tmux 3.4
curl -s localhost:4820/api/run/tmux # {"available":true}
A workspace's run lives in a tmux session named agenthub-lane-<id>, so the browser
terminal and a local tmux attach -t agenthub-lane-<id> (or agenthub workspace shell) are two clients on the same pane — they stay in sync, and killing the
dashboard never kills the run.
Install as a Claude Code plugin
Two commands on a machine that has nothing but Claude Code, no clone and no
npm run setup:
/plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
/plugin install agenthub@agenthub
The first session start installs the hooks, boots the server, puts agenthub on
PATH; it runs detached, so the session never waits on
it. /agenthub-doctor reports the state, /agenthub-open builds the UI and prints the
URL, /agenthub-update refreshes after a plugin update. This path needs Node
>= 22.5 (no native better-sqlite3, so the server uses node:sqlite).
Details, including what to delete on uninstall:
docs/PLUGINS.md.
Install from a checkout
npm run setup # root and client dependencies
npm run build # builds the client into client/dist
npm start # serves the built client and the API on :4820
Open http://localhost:4820.
Development, with hot reload:
npm run dev # server on :4820, Vite client on :5173
DASHBOARD_PORT overrides the port, DASHBOARD_CLIENT_DIST overrides where the
built UI is served from (defaults to client/dist; the plugin install points it
at its own runtime directory). postinstall writes the Claude Code hook entries
that feed the dashboard — do not run it when the agenthub plugin is installed, or
every event is counted twice.
Run as a service (auto-start on boot)
npm start only runs while that terminal (or agenthub start's background
process) is alive — a reboot loses it. agenthub service install sets up a
systemd --user service (Linux) or a LaunchAgent (macOS) instead, so :4820 is up again on its own after
every reboot, with no manual step and no Claude Code (or any AI tool) needed
to trigger it:
npm run build # the service serves the built client, same as npm start
agenthub service install # Linux: ~/.config/systemd/user/agenthub.service
# macOS: ~/Library/LaunchAgents/io.smartgift.agenthub.plist
agenthub service status # systemctl --user status / launchctl print
agenthub service uninstall # disable and remove it
On Linux, agenthub service install also tries loginctl enable-linger so the service
starts on a cold boot, before anyone logs in; if that needs elevated rights on
your machine it prints the sudo loginctl enable-linger <user> command to run
once yourself. The same is a switch in the dashboard — Settings → About →
Start AgentHub automatically (off by default; it enables or disables the
unit and never stops the running server). Plugin installs get it only once
that switch is on — see
Auto-start on boot in docs/PLUGINS.md.
The CLI
agenthub is linked by npm run setup; otherwise call node bin/agenthub.js.
agenthub status # is the dashboard up
agenthub start # start it in the background and wait for healthy
agenthub service install # auto-start on boot via systemd --user (Linux)
agenthub sessions # recent sessions
agenthub workspaces # workspaces with stage and progress
agenthub workspace pipeline # this lane's pipeline template, or switch it
agenthub workspace node <id> # run ONE pipeline node's own command (no id: list them)
agenthub stage <name> # declare the current lane's stage
agenthub tail # live event feed
agenthub --help lists the rest.
Workspaces
A workspace is a working directory the dashboard watches. Two kinds:
- adopted — a directory you already had. The dashboard only reads it; it is never reset or deleted.
- managed — a git worktree the dashboard created under
LANES_ROOT. It may reset that worktree, behind a three-check destroy guard and a counted preflight the caller has to echo back. Removing a workspace — either kind — deletes only the dashboard's record of it: the working tree, its branch and its database stay, for you to delete yourself.
agenthub workspace add --cwd /path/to/repo --title "My feature" # adopt
agenthub workspace add --repo /path/to/repo --slug my-feature # managed worktree
Every workspace also carries the CLI that drives it — claude (the default) or
codex — picked in the Add-workspace modal and fixed for the life of the workspace. A
Codex workspace's run panel offers Codex's own sandbox, approval and reasoning-effort
choices, and resumes with codex resume --last. Codex sessions and token usage
are read from Codex's own rollout journals: every Codex session (a workspace's or
not) appears in Sessions with a Codex badge and is priced like any other,
with OpenAI rates filled in automatically (Settings → Codex → Overview). For a
live feed, install Codex hooks from the same tab: the next time Codex starts
it asks you to trust them (Trust all and continue), and from then on each
tool call lands in the session's timeline, a codex workspace turns running/idle as
each turn starts and ends, and "Codex needs your permission" shows on the workspace
card and as a notification while Codex waits for an approval. A Codex workspace also
carries no pipeline — no stage, no pipeline map, nothing inferred or
advanced; without hooks the dashboard mirrors its running/idle status from the
rollout journals on disk ($CODEX_HOME/sessions/**/rollout-*.jsonl, polled
every DASHBOARD_CODEX_POLL_MS ms, default 15000).
An Antigravity workspace runs Antigravity's agy CLI. Its sessions and token
usage are read from agy's own conversation files
(~/.gemini/antigravity-cli/conversations/<id>.db, every
DASHBOARD_ANTIGRAVITY_POLL_MS ms, default 15000): every agy CLI session
appears in Sessions with an Antigravity badge, priced with Gemini rates that
are filled in automatically (Settings → Antigravity). Antigravity hooks, in
the same tab, add a live feed: each tool call in the session's timeline and a
workspace that turns running/idle as a run starts and ends. agy asks for no trust,
and it has no hook for a permission prompt, so an Antigravity workspace never shows
"needs your permission". agy fires no hook when it exits, nor when a run ends
on an API error or a permission refused in headless mode, so a session gone
quiet is marked completed and its workspace set idle — after ten minutes of quiet
for a session the hooks report on (a long tool call writes nothing, and after a
Stop agy may still be waiting for you), after two minutes for one without
hooks. Antigravity workspaces carry no pipeline either.
Cursor sessions — the Cursor CLI's and the Cursor editor's agent chats — are
read from Cursor's agent transcripts
(~/.cursor/projects/*/agent-transcripts/, every DASHBOARD_CURSOR_POLL_MS ms,
default 15000) and appear in Sessions with a Cursor CLI badge. Cursor writes
no token counts or model ids there, so a Cursor session shows no tokens and no
cost.
Pipelines are dormant. AgentHub ships no pipeline template, so a workspace has no
stages until you drop a template JSON into DASHBOARD_PIPELINES_DIR (see
docs/LANES.md); until then
agenthub stage answers ENOPIPELINE and the Workspace hides the pipeline map.
Further development is planned.
The declared stage comes from agenthub stage. The inferred stage comes from tool
events and expires after DETECTION_TTL_MS (default 5 minutes), so a workspace can
move backwards between work sessions. Detection never writes the declared stage,
and an inferred node never renders as done.
A workspace's pipeline template can be switched after creation — agenthub workspace pipeline <template> from the terminal, or the pipeline-template picker next to
the workspace's title in the Workspace detail panel. Both re-resolve the workspace's
current declared stage against the new template's nodes and warn if it no
longer matches one.
A workspace can also run its own application stack, isolated per workspace, when its
repository declares a profile at <repo>/.agenthub/profile/ — a profile.env of
declarations plus shell hooks the dashboard calls. Each workspace gets a slot, and its
ports and per-workspace directories derive from it:
agenthub workspace up # boot the stack of the lane owning this directory
agenthub workspace runtime # slot, ports, service health
agenthub workspace logs api # tail a service log
agenthub workspace down
Services are fully detached, so restarting the dashboard never stops a running workspace. This is resource namespacing on the host, not a container: workspaces run as the same user and share the network.
docs/LANES.md has the pipeline model, the destroy guard, the
preflight contract, the Workspace page, the git surface (GET /api/lanes/:id/git,
/git/changes, /git/log, /git/file, /git/ls, /git/tree,
POST /:id/git/:action), and the full
runtime/profile contract.
Tests
npm run test:server # node:test
npm run test:client # Vitest
Both must be green before a commit. The pre-commit hook (.husky/pre-commit)
runs Prettier, then the tests the commit needs: both full suites for a big or
risky commit (over 10 code files, a dependency, build/test config or the hook
itself, a deleted file), only the related tests for a small one (vitest related for client/, the server test files that name each other staged
module), nothing for docs alone. AGENTHUB_FULL_TESTS=1 git commit … forces
both full suites.
Layout
| Path | What |
|---|---|
server/ |
Express API, SQLite schema, hook ingest, workspace and worktree libraries |
client/ |
React 18 + Vite + Tailwind dashboard |
bin/agenthub.js |
CLI |
mcp/, statusline/ |
Read-only MCP server and Claude Code statusline (opt-in) |
monitoring/ |
Prometheus config/rules and Grafana boards for /api/metrics |
docs/ |
Architecture, API, workspaces, database |
plugins/ |
Claude Code plugins shipped with the dashboard |
Docs
ARCHITECTURE.md— request flow, schema, WebSocket surfacedocs/LANES.md— workspaces, pipelines, stage detectiondocs/API.md— REST endpoints (openapi.yamlis generated)docs/DATABASE.md— tables and migrationsINSTALL.mdCLAUDE.md— the rules an agent working in this repo must follow