Files
AgentHub/README.md
T
nntrivi2001 952e8584f0 feat: per-change-block hunk actions (#50), codex lanes without a pipeline, macOS LaunchAgent
- git (#50): stage-hunk/discard-hunk take an optional `block` — one run of
  consecutive +/- lines inside an @@ hunk. `onlyBlock` (server/lib/git-diff.js)
  cuts git's fresh hunk down to it, folding the other blocks into the side
  being checked; LaneDiffView hangs one review bar per block (unified + split)
  and its arrows walk blocks.
- git exclude: entries AgentHub writes for a lane go to the COMMON git dir with
  the lane's path prefix (server/lib/git-exclude.js, used by router-apply and
  lane-mcp) — a linked worktree's own info/exclude is never read by git, and a
  subdir lane has no .git. MCP sync no longer fails with ENOTDIR on a worktree
  lane or creates a stray .git in a non-repo lane.
- codex lanes carry no pipeline: codex-ingest mirrors only idle/running,
  codex-nudge is removed, agents install writes nothing for codex, the
  Workspace hides stage/pipeline/feature pickers/PipelineMap for them, and
  every server start clears leftover codex stage data and the old AGENTS.md
  stage block.
- Changes panel: a whole file opens for reading and enters the editor on a
  click on its text (caret at the clicked line), not automatically.
- macOS: LaunchAgent start-at-login (scripts/launchd-service.js, picked by
  scripts/service-manager.js).
- Adds the AgentHub introduction slides and their image-embedding script.
2026-09-25 17:30:28 +07:00

15 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; lanes track parallel agent work through a pipeline; and the agenthub CLI drives real terminal sessions, lane 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

  • Lanes. One lane per working directory, surviving session restarts. A lane moves through pipeline stages and the dashboard shows where it is.
  • Stage detection. 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 lane's directory — the exact TUI you'd see locally, fully interactive, resumable, and attachable from a real terminal too via agenthub lanes shell. Which CLI it starts is the lane's own setting. This is the part that needs tmux installed — see Prerequisites.
  • Git, from the dashboard. Each lane 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 lane 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-lane app stacks. A repo that declares .agenthub/profile/ gets its own slot, ports and services per lane (agenthub lanes up|down|logs).
  • Ship pipelines. /agenthub:ship-full and /agenthub:ship-quick drive a feature from intake to PR, declaring every stage to the dashboard as it goes.

Configure

  • Claude Code + Codex configuration explorer. Settings hosts one panel 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; light: Default, Apple Light, IntelliJ Light, Canvas. Each mode remembers its own theme, so the sidebar's quick toggle swaps between the two. Per-browser only.
  • A CLI for all of it (agenthub, plus agenthub repl), a PWA install, and a UI in English, Vietnamese, Chinese and Korean.

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 lane operation (worktrees, branch/status reads)
tmux 3.x The browser run console, agenthub lanes 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 lanes
GitHub CLI (gh) any Optional — only for agenthub lanes ci status and the PR stages of the ship pipelines
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 lanes shell fail without it. Everything else (sessions, analytics, lanes, 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/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.

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 lane'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 lanes shell) are two clients on the same pane — they stay in sync, and killing the dashboard never kills the run.

The superpowers plugin

The superpowers plugin is required by the ship-feature pipelines only, not by the dashboard. /agenthub:ship-feature and /agenthub:ship-feature-lane drive superpowers:brainstorming, writing-plans, test-driven-development, requesting-code-review and verification-before-completion phase by phase, and both built-in pipeline templates name those same slash commands as their per-node drivers. Without it the dashboard, hooks and CLI all work normally — the two pipeline skills are what stop partway. /agenthub-doctor reports it as a WARN row.

You do not normally have to install it. The plugin's SessionStart bootstrap installs it for you, once, in its detached worker — so a session never waits on the clone, and the current session needs /reload-plugins before the skills resolve (any later session picks them up on its own). The outcome is logged to ~/.claude/agenthub/runtime/bootstrap.log, and /agenthub-update retries a failed one. To install it by hand instead, or after opting out:

claude plugin install superpowers@claude-plugins-official

Set AGENTHUB_AUTO_INSTALL_PLUGINS=0 to opt out of the automatic install. Only the plugins on a fixed allowlist in server/lib/skill-plugins.js are ever installed this way — superpowers today. A custom pipeline template naming some other plugin's command is reported by /agenthub-doctor and never installed, because a template is a file anyone can drop into DASHBOARD_PIPELINES_DIR.

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. Plugin installs get the same persistence automatically — 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 lanes             # lanes with stage and progress
agenthub lanes pipeline    # this lane's pipeline template, or switch it
agenthub lanes node <id>   # run ONE pipeline node's own command (no id: list them)
#                        (in a session: /intake, /qc, /ship-full, /ship-quick …)
agenthub stage <name>      # declare the current lane's stage
agenthub tail              # live event feed

agenthub --help lists the rest.

Lanes

A lane 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 lane — 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 lanes add --cwd /path/to/repo --title "My feature"    # adopt
agenthub lanes add --repo /path/to/repo --slug my-feature      # managed worktree

Every lane also carries the CLI that drives it — claude (the default) or codex — picked in the Add-lane modal and fixed for the life of the lane. A Codex lane's run panel offers Codex's own sandbox, approval and reasoning-effort choices, and resumes with codex resume --last. Codex emits none of this dashboard's hooks, so a Codex lane records its runs but stays absent from Sessions and Analytics. A Codex lane also carries no pipeline — no stage, no pipeline map, nothing inferred or advanced; the dashboard only mirrors its running/idle status from Codex's own rollout journals on disk ($CODEX_HOME/sessions/**/rollout-*.jsonl, polled every DASHBOARD_CODEX_POLL_MS ms, default 15000).

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 lane can move backwards between work sessions. Detection never writes the declared stage, and an inferred node never renders as done.

A lane's pipeline template can be switched after creation — agenthub lanes pipeline <template> from the terminal, or the pipeline-template picker next to the lane's title in the Workspace detail panel. Both re-resolve the lane's current declared stage against the new template's nodes and warn if it no longer matches one.

A lane can also run its own application stack, isolated per lane, when its repository declares a profile at <repo>/.agenthub/profile/ — a profile.env of declarations plus shell hooks the dashboard calls. Each lane gets a slot, and its ports and per-lane directories derive from it:

agenthub lanes up          # boot the stack of the lane owning this directory
agenthub lanes runtime     # slot, ports, service health
agenthub lanes logs api    # tail a service log
agenthub lanes down

Services are fully detached, so restarting the dashboard never stops a running lane. This is resource namespacing on the host, not a container: lanes 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 runs them plus Prettier.

Layout

Path What
server/ Express API, SQLite schema, hook ingest, lane and worktree libraries
client/ React 18 + Vite + Tailwind dashboard
bin/agenthub.js CLI
docs/ Architecture, API, lanes, database
plugins/ Claude Code plugins shipped with the dashboard

Docs