# 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: [OVERVIEW.vi.md](OVERVIEW.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 stage` still 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 needs `tmux` installed** — see [Prerequisites](#prerequisites). - **Git, from the dashboard.** Each workspace card shows its branch, `↑ahead ↓behind` and 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; each is a copy taken at upload, so edit the original and add it again — a Folder is read live) 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. A session can be pinned to the top of its workspace's list. The Files tab also works in a folder that is not a git repo, and downloads any file or uploads new ones into the workspace (never over an existing file) — on a server install, how a member with no SSH moves files. - **Settings as one page per section** (`/settings/
`): a left nav grouped General (Appearance — language, theme, pet — / Notifications / System) / Agents (AI tools, one page per installed AI tool, AI Proxy) / Data (Database / Pricing / Snapshots & reports / Git — logins and which untracked worktrees a workspace's Add folder suggests), a search box (Ctrl+F) over every section whose results deep-link a row's sub-tab and anchor. Model prices live only on Pricing; a tool's page links there. - **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 and `settings.json` stay 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. It also picks the workspace terminals' font: JetBrains Mono (default), the rounded Maple Mono, or the browser's own fixed-width font (which may lack some Vietnamese letters) — and its size (11–20 px, default 13), both applied to open terminals at once — and the interface's **Text size** (Small / Default / Large / Larger: a 14 / 16 / 17 / 18 px root font size that every text in the UI scales with). Saved to the account. Text across the UI and the terminals is one step heavier than stock (regular 500, bold 700), and the Chat UI default sits at the top of the page. - **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`, plus `agenthub 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](MCP.md)), a Claude Code statusline with session and today's cost (`agenthub statusline install`, [docs/STATUSLINE.md](STATUSLINE.md)), and Prometheus rules + Grafana boards for `/api/metrics` (`docker-compose.monitoring.yml`, [docs/MONITORING.md](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](SERVER-MODE.md)). ## Prerequisites | Need | Version | Required for | |---|---|---| | **Node.js** | >= 22.5 (`node:sqlite`; Node 20 is end-of-life) | 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. ```bash 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/bin` to `PATH` in `~/.zshrc`. There is no systemd, so the dashboard runs until logout/reboot and comes back at the next Claude Code session, or by hand with `agenthub start`. Details and a checklist to verify it: [INSTALL.md § macOS](../INSTALL.md#macos). Verify, both from your shell and from the server's point of view: ```bash 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-`, so the browser terminal and a local `tmux attach -t agenthub-lane-` (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`](PLUGINS.md). ## Install from a checkout ```bash 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 . Development, with hot reload: ```bash 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: ```bash 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 ` command to run once yourself. The same is a switch in the dashboard — Settings → System → **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](PLUGINS.md#auto-start-on-boot) in `docs/PLUGINS.md`. ## The CLI `agenthub` is linked by `npm run setup`; otherwise call `node bin/agenthub.js`. ```bash 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 # run ONE pipeline node's own command (no id: list them) agenthub stage # 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. ```bash 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/.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`](LANES.md#custom-pipeline-templates)); 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