29a5da3e4e
`claude plugin update` unpacks the new version into a new cache directory and says "Restart to apply changes". A Claude Code process that was already running does not: it keeps loading the OLD directory, hooks and all. Every session such a process opened then ran the OLD plugin-bootstrap, which saw a state.json naming a different root, concluded the server had to be replaced, repointed agenthub.service at itself and restarted the dashboard onto the version the user had just upgraded away from. The dashboard reported the old version and offered the update again — once per session, forever, while installed_plugins.json and the cache both said the new version was installed. A /agenthub-update from that session "succeeded" and changed nothing. - `supersededBy()` reads Claude Code's installed_plugins.json. When a SIBLING cache directory is the recorded install, the bootstrap logs one line and returns "superseded" — no deps, no unit, no server. `--force` does not override it: the self-update chain forces from the NEW directory, which is never superseded, so the only --force refused is a deliberate downgrade. It cannot hand over either — the process it would replace is the one loading it — so the log line says to restart Claude Code. - Matched by sibling directory, not by the <plugin>@<marketplace> key: correct without parsing a cache path or trusting a name. A phantom entry (installPath that no longer exists) is ignored rather than wedging the bootstrap shut. Also adds `pruneRetiredPluginRoots()`, since the same updates leave a full copy of the repo — node_modules and all — per release; twelve of them measured 1.7 GB on one machine. It runs after writeState, so a bad prune cannot cost the record of a good bootstrap, and it protects four independent readings of "in use": this build, every installPath Claude Code records, the directory agenthub.service names (`unitRoot`, foreign unit included), and any directory still named in the user's settings.json hooks — that last one is the un-restarted process above, seen from the other side. Plus the 2 newest survivors as a rollback cushion, and nothing at all outside ~/.claude/plugins/cache/.
706 lines
44 KiB
Markdown
706 lines
44 KiB
Markdown
# AgentHub — Plugin Marketplace
|
||
|
||
Official Claude Code plugins for the Agent Monitor dashboard. The **`agenthub`** plugin _is_ the dashboard — hooks, server and the `agenthub` CLI, no checkout required. (It shipped an MCP server until `c7dbaf2`, which dropped it; the dashboard reads Claude Code's MCP configuration in the config explorer but no longer serves one.) On top of it, **10 focused plugins** extend Claude Code with skills, agents, slash commands, hooks, and CLI tools for deep analytics, cost guardrails, productivity automation, developer tools, AI-powered insights, session forensics, workflow/fleet intelligence, reliability & SLOs, config & memory governance, and dashboard connectivity.
|
||
|
||
Every plugin is powered by the local Agent Monitor REST API at `http://localhost:4820`. They are read-only advisors unless a skill explicitly documents a mutating endpoint (and those preview + confirm before acting).
|
||
|
||
## Quick Start
|
||
|
||
### Add the marketplace
|
||
|
||
```bash
|
||
claude plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
|
||
```
|
||
|
||
### Install the dashboard itself
|
||
|
||
```bash
|
||
claude plugin install agenthub@agenthub
|
||
```
|
||
|
||
That is the whole install: no clone, no `npm run setup`, no `npm run install-hooks`, no manual `npm start`. See [The `agenthub` plugin](#the-agenthub-plugin) below for what it does on first session start.
|
||
|
||
### Or via the Smartgift skills marketplace
|
||
|
||
`agenthub` is also listed as a standalone entry in
|
||
[`smartgift-claude-skills`](https://git.smartgift.io.vn/Smartgift-AI/smartgift-claude-skills)
|
||
— its `source` still points at this repo's `main` branch, so the two entries
|
||
install identically:
|
||
|
||
```bash
|
||
claude plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/smartgift-claude-skills.git
|
||
claude plugin install agenthub@sg
|
||
```
|
||
|
||
Pick whichever marketplace you already have added; installing `agenthub` from both
|
||
at once is redundant but harmless (Claude Code treats it as one plugin per
|
||
marketplace name, not per source).
|
||
|
||
### Install a focused plugin
|
||
|
||
```bash
|
||
claude plugin install agenthub-analytics@agenthub
|
||
claude plugin install agenthub-cost-guard@agenthub
|
||
claude plugin install agenthub-productivity@agenthub
|
||
claude plugin install agenthub-devtools@agenthub
|
||
claude plugin install agenthub-insights@agenthub
|
||
claude plugin install agenthub-sessions@agenthub
|
||
claude plugin install agenthub-workflows@agenthub
|
||
claude plugin install agenthub-quality@agenthub
|
||
claude plugin install agenthub-config@agenthub
|
||
claude plugin install agenthub-dashboard@agenthub
|
||
```
|
||
|
||
### Or install locally during development
|
||
|
||
```bash
|
||
# From the repo root, test a plugin locally
|
||
claude --plugin-dir plugins/agenthub-analytics
|
||
```
|
||
|
||
## Prerequisites
|
||
|
||
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated
|
||
- Node **>= 22.5** when installing via the `agenthub` plugin. A plugin install has no
|
||
native `better-sqlite3`, so the server stores data through `node:sqlite`, which
|
||
landed in 22.5. The bootstrap refuses with one line on anything older instead
|
||
of letting the server crash. (A checkout install still works on Node >= 20.)
|
||
- The Agent Monitor dashboard reachable at `http://localhost:4820` — the `agenthub`
|
||
plugin starts it for you; a checkout starts it with `npm start` (see
|
||
[SETUP.md](../SETUP.md))
|
||
|
||
Skills and commands are invoked as `/agenthub-<plugin>:<name>`. Agents are dispatched automatically by Claude Code (or named explicitly).
|
||
|
||
## The `agenthub` plugin
|
||
|
||
The marketplace's root entry (`"source": "./"`) is the entire repository, so
|
||
`server/`, `client/`, `scripts/` and `bin/agenthub.js` all land under
|
||
`${CLAUDE_PLUGIN_ROOT}` when Claude Code caches it. That is what makes a
|
||
checkout unnecessary.
|
||
|
||
### What it installs
|
||
|
||
| Component | Where it comes from |
|
||
|---|---|
|
||
| The eight event hooks | inline `hooks` in `.claude-plugin/plugin.json`, each running `scripts/hook-handler.js` |
|
||
| The dashboard server | started detached by the bootstrap, from the plugin cache |
|
||
| The `agenthub` CLI | a launcher written to `~/.local/bin/agenthub` |
|
||
| The dashboard UI (`/run` and every other client route) | built into the runtime dir by the bootstrap, so it works the moment `claude` starts |
|
||
| `/agenthub-doctor`, `/agenthub-update`, `/agenthub-open` | `plugins/agenthub/commands/` |
|
||
| `/ship-full`, `/ship-quick` and one command per pipeline node (`/intake`, `/plan`, `/implement`, `/tests`, `/e2e`, `/review`, `/qc`, `/gate`, `/publishing`, `/pr-open`, `/done`, …) | `plugins/agenthub/commands/`, one file per name |
|
||
| The skills (`ship-feature-lane`, `ship-feature`, `repo-onboarding`, `debug-live-issue`, `update-project-docs`, `file-headers`) | `skills/` at the repo root — which IS the plugin root, so they are auto-discovered as plugin skills |
|
||
| The agents (`qc-local`, `senior-gate-reviewer`, `backend-reviewer`, `frontend-reviewer`) | `agents/` at the repo root, auto-discovered the same way — exposed as `agenthub:<name>` |
|
||
|
||
Plugin skills are namespaced: they are invoked as `/agenthub:<name>`, with the bare
|
||
`/<name>` working as an alias unless another skill or command claims that name.
|
||
This is why `skills/` sits at the repo root instead of `.claude/skills/` — the
|
||
latter only loads for a session whose cwd is inside this checkout, which is
|
||
useless for a lane working in a different repo. `agenthub skills install` survives
|
||
as the fallback for a plain checkout without the plugin.
|
||
|
||
**The agents ship the same way, from the same files.** `agents/` at the repo
|
||
root holds all four (`qc-local`, `senior-gate-reviewer`, `backend-reviewer`,
|
||
`frontend-reviewer`), so the plugin exposes them as
|
||
`agenthub:<name>`. `agenthub lanes agents install` copies `qc-local` +
|
||
`senior-gate-reviewer` from that same directory into a lane's own
|
||
`.claude/agents/` — the highest-priority agent source — which is what makes the
|
||
bare `subagent_type: qc-local` in the pipeline skill resolve there. One source
|
||
file, two ways to reach it; the skill names the bare form first and falls back
|
||
to the `agenthub:` form. On a `codex` lane the same command installs the
|
||
`<!-- agenthub:stage:start -->` block in the lane's `AGENTS.md` instead — Codex
|
||
never reads `.claude/agents/`.
|
||
|
||
Because the plugin ships the hooks itself, `npm run install-hooks` is not needed
|
||
for plugin users — and must not be run alongside it. Events carry no id, so two
|
||
handlers mean every token and cost figure is counted twice. `claude plugin
|
||
install` writes the plugin's own hook entries into `~/.claude/settings.json`
|
||
too (`${CLAUDE_PLUGIN_ROOT}` resolved to the actual cache path) — confirmed
|
||
against a real install — so those entries also contain `hook-handler.js`, same
|
||
as a leftover checkout install. The bootstrap tells them apart by whether the
|
||
command resolves under `~/.claude/plugins/cache/`: only genuine checkout paths
|
||
are removed (backing `~/.claude/settings.json` up as `settings.json.agenthub-bak`
|
||
first), never the plugin's own. `/agenthub-doctor` reports the state using the same
|
||
check.
|
||
|
||
### First session start
|
||
|
||
`scripts/plugin-bootstrap.js` runs from `SessionStart`. It returns within
|
||
milliseconds — the real work happens in a detached worker, so a session never
|
||
waits on an install:
|
||
|
||
1. **Fast path** — recorded state matches this plugin build and a server is live → exit.
|
||
2. **Superseded check** — if Claude Code records a DIFFERENT build of this plugin as installed, this one logs a line and does nothing else (see [A retired build never acts](#a-retired-build-never-acts)).
|
||
3. **Node gate** — refuse below 22.5 with one line (see Prerequisites).
|
||
4. **Lock** — atomic `mkdir` lock holding the PID; reclaimed when the owner is dead or the lock is older than 10 minutes, so two sessions cannot race the install or spawn two servers.
|
||
5. **Install** — `npm install --omit=dev --ignore-scripts` into the runtime dir (never into the plugin cache, which is garbage-collected and replaced on every update). `--ignore-scripts` keeps the root `postinstall` from pulling the whole Vite client toolchain.
|
||
6. **Legacy hook cleanup** — see above.
|
||
7. **CLI** — write the `~/.local/bin/agenthub` launcher, never clobbering a `agenthub` the bootstrap did not write.
|
||
8. **UI build** — `client/` is copied into the runtime dir and built there (`npm ci --include=dev`, falling back to `npm install --include=dev`, then `npm run build`), landing in `runtime/client-dist` — the same directory the server serves from. `--include=dev` is required, not tidy: the entire build toolchain (`vite`, `typescript`, `@vitejs/plugin-react`, `tailwindcss`, `@types/*`) is a devDependency, and npm reads an inherited `NODE_ENV=production` as `--omit=dev`. Every bootstrap descended from the running server carries that env — the self-update chain, and any `SessionStart` fired by a `claude` inside a tmux pane the server started — so without the flag the install drops `vite` and the build dies on missing types. Skipped when a bundle for the current version already exists; a failure here does not fail the bootstrap (the API still works, and `/agenthub-open` can retry) but does mean `/run` 404s until it's fixed — and when a bundle from the PREVIOUS version is still on disk the failure is quieter still: the dashboard keeps serving the old UI against the new API, visible only as the Settings page's `UI build vX (rebuild client to match)` line.
|
||
9. **Server** — on Linux with `systemd --user` available, install/refresh a
|
||
`agenthub.service` unit (see [Auto-start on boot](#auto-start-on-boot)) instead
|
||
of a bare spawn, so the server is supervised and comes back after a reboot
|
||
with no Claude Code session involved. Everywhere else (macOS, Windows, or
|
||
no systemd), spawn `server/index.js` detached, with `NODE_PATH` at the
|
||
runtime `node_modules` and `DASHBOARD_CLIENT_DIST` at the runtime
|
||
`client-dist` — scoped to this session, same as before this fell back to
|
||
systemd.
|
||
10. **Record state** — `runtime/state.json`.
|
||
11. **Prune retired cache copies** — delete the plugin-cache directories earlier updates left behind (see [Pruning the plugin cache](#pruning-the-plugin-cache)). After step 10, so a prune that goes wrong cannot also cost the record of a bootstrap that went right.
|
||
12. **Hand over to systemd** — only when a unit of ours already owns the server
|
||
(see [Who may stop the server](#who-may-stop-the-server)). Deliberately
|
||
after step 10.
|
||
|
||
The first run takes a few minutes — most of it is the UI build, which is what
|
||
makes client-only routes (`http://localhost:4820/run`, and every other page)
|
||
work the moment `claude` starts, with no manual `/agenthub-open` step. Progress
|
||
goes to `~/.claude/agenthub/runtime/bootstrap.log`; `npm run build`'s own
|
||
output goes to `client-build.log` next to it; the server's own output goes to
|
||
`server.log`.
|
||
|
||
### A retired build never acts
|
||
|
||
`claude plugin update` unpacks the new version into a **new** cache directory
|
||
and prints "Restart to apply changes". A Claude Code process that was already
|
||
running does not: it keeps loading the OLD directory — skills, commands and
|
||
hooks included — until it is restarted.
|
||
|
||
That used to be self-inflicting. Every session such a process opened ran the
|
||
OLD `plugin-bootstrap.js`, which saw a `state.json` naming a different root,
|
||
concluded the server had to be replaced, repointed `agenthub.service` at itself
|
||
and restarted the dashboard onto the version the user had just upgraded away
|
||
from. The dashboard then reported the old version and offered the update again
|
||
— once per session, forever, while `installed_plugins.json` and the cache both
|
||
said the new version was installed. A `/agenthub-update` from that session
|
||
"succeeded" and changed nothing.
|
||
|
||
So the bootstrap now asks first (`supersededBy`): if Claude Code's
|
||
`~/.claude/plugins/installed_plugins.json` records a **sibling** directory as
|
||
the installed build of this plugin, this build logs one line and returns
|
||
`superseded` without touching dependencies, the unit, or the server. `--force`
|
||
does not override it — the self-update chain runs `--force` from the NEW
|
||
directory, which is never superseded, so the only `--force` this can refuse is
|
||
one that would deliberately downgrade.
|
||
|
||
It cannot hand over to the new build either: the process it would have to
|
||
replace is the one loading it. Restarting Claude Code is the fix, and the log
|
||
line says so.
|
||
|
||
Matching is by sibling directory rather than by the `<plugin>@<marketplace>`
|
||
key, which holds without parsing a cache path or trusting a name. An entry
|
||
pointing at a directory that no longer exists is ignored — a phantom must never
|
||
wedge a bootstrap shut.
|
||
|
||
### Pruning the plugin cache
|
||
|
||
Claude Code unpacks every update beside the last one and does not reliably
|
||
remove the old. A machine that tracks releases closely accumulates a full copy
|
||
of this repo — `node_modules` and all — per release; a dozen of them is
|
||
gigabytes.
|
||
|
||
Step 11 of the bootstrap (`pruneRetiredPluginRoots`) deletes them. This is the
|
||
only place anything in the plugin touches the cache, and the rule it appears to
|
||
break ("never write into the plugin cache") is about the *runtime* living
|
||
outside it, not about keeping retired copies forever.
|
||
|
||
Four independent readings of "still in use" are protected, and nothing matching
|
||
any of them is ever deleted:
|
||
|
||
| Protected | Why |
|
||
|---|---|
|
||
| This build | It is running. |
|
||
| Every `installPath` in `installed_plugins.json`, at any scope | Claude Code says it is installed. |
|
||
| The directory `agenthub.service` names (`unitRoot`, **foreign unit included**) | A service is executing from it. Not ours to rewrite is still not ours to delete. |
|
||
| Any directory named in the user's `settings.json` hooks | A Claude Code process that has not been restarted is still executing from there — this is the same directory the section above describes, seen from the other side. Deleting it would break that session's hooks mid-flight. |
|
||
|
||
Plus the newest `KEEP_RETIRED_ROOTS` (2) of whatever is left, as a rollback
|
||
cushion. Outside `~/.claude/plugins/cache/` the pruner does nothing at all — for
|
||
a git checkout the parent directory holds the user's own work. Best effort
|
||
throughout: a directory that will not delete is left alone, never an error.
|
||
|
||
### Auto-start on boot
|
||
|
||
On Linux, every plugin bootstrap (not just the first) installs/refreshes a
|
||
systemd `--user` service (`~/.config/systemd/user/agenthub.service`, managed via
|
||
`scripts/systemd-service.js` — shared with the checkout path's
|
||
`agenthub service install`, see the README). Its `ExecStart`/`WorkingDirectory`
|
||
point at the current plugin cache path, so a plugin update that moves the
|
||
cache directory rewrites and restarts the unit on the next session start, the
|
||
same self-healing pattern the CLI launcher already uses. The bootstrap also
|
||
tries `loginctl enable-linger` so the service starts on a cold boot before
|
||
anyone logs in; when that needs elevated rights, it's skipped silently (check
|
||
`~/.claude/agenthub/runtime/bootstrap.log`, or run
|
||
`sudo loginctl enable-linger <user>` once by hand). A pre-existing
|
||
`agenthub.service` unit not written by this bootstrap is left untouched, and the
|
||
server falls back to the old per-session detached spawn instead.
|
||
|
||
On macOS, Windows, or a Linux box without systemd, nothing changes: the
|
||
server is a detached spawn started fresh on the next `SessionStart` after a
|
||
reboot, same as always.
|
||
|
||
### Who may stop the server
|
||
|
||
**When a `agenthub.service` unit of ours exists, nothing else may stop the
|
||
dashboard.** The bootstrap that performs a self-update is spawned by the
|
||
running server, so it lives inside that server's systemd cgroup. SIGTERM-ing
|
||
the server from there breaks two ways at once:
|
||
|
||
- the server exits **0**, and the unit's old `Restart=on-failure` read a clean
|
||
exit as "meant to stop" — so systemd did not bring it back;
|
||
- `KillMode=control-group` (systemd's default) reaps **every** process in the
|
||
cgroup when the main process exits, including the bootstrap itself — mid-run,
|
||
before it could repoint the unit at the new plugin root or write
|
||
`runtime/state.json`.
|
||
|
||
The result was a dashboard that went down on every self-update and stayed down
|
||
until some later Claude Code session happened to bootstrap again, leaving a
|
||
stale `.bootstrap.lock` and a `state.json` still naming the previous version.
|
||
|
||
So the order is fixed, and `scripts/systemd-service.js` splits its API to
|
||
enforce it:
|
||
|
||
| Situation | What the bootstrap does |
|
||
|---|---|
|
||
| A unit of ours owns the server (`unitIsOurs`) | Never stops it. `writeUserService` repoints the unit at the new plugin root **without starting anything**, the rest of the bootstrap runs, state is written, the lock is released — and only then `restartUserService` asks systemd to restart, with `--no-block` so being killed by its own request costs nothing. |
|
||
| No unit, or a foreign one | Unchanged: stop the old server, then `installUserService` (or a detached spawn where there is no systemd). Nothing here is inside a unit's cgroup, so the stop is safe. |
|
||
|
||
The unit is written with **`Restart=always`**, not `on-failure`: a graceful
|
||
SIGTERM from anything at all would otherwise leave the dashboard down for good.
|
||
An explicit `systemctl stop` — which is what `agenthub service uninstall` and
|
||
the Settings panel do — still stops it.
|
||
|
||
`agenthub service install` (the checkout path) keeps using `installUserService`:
|
||
it runs from your own shell, outside the unit's cgroup, so it may block and
|
||
start in one step.
|
||
|
||
**A unit pointing at a retired plugin root repairs itself on the next session.**
|
||
This is the residue an interrupted update leaves behind, and it is invisible
|
||
while the dashboard is up: the server runs fine, every doctor row reads OK, and
|
||
then a reboot starts a cache directory Claude Code deleted during the update —
|
||
so the dashboard never comes back, for a reason nothing recorded. The fast path
|
||
therefore checks it (`unitIsStale`, pure fs — it may not spawn a process on
|
||
every `SessionStart`) and refuses to short-circuit, and the bootstrap rewrites
|
||
the unit.
|
||
|
||
Repairing the *unit* is not restarting the *server*: when the running server is
|
||
current and healthy, the corrected unit is simply left to take effect at the
|
||
next start (`pendingSystemdRestart = systemdOwned && needsServer`). Restarting
|
||
a working dashboard to fix a file that only matters at boot would be churn the
|
||
user feels for nothing. For the same reason the detached-spawn fallback is
|
||
guarded by `needsServer` — entering that branch for a stale unit alone would
|
||
start a second server onto a port the live one already holds.
|
||
|
||
`systemdOwned` requires the unit to be **active**, not merely present: an
|
||
installed-but-stopped unit owns nothing, and treating it as the owner would
|
||
skip the stop and then ask systemd to bind an occupied port — a crash loop,
|
||
courtesy of `Restart=always`.
|
||
|
||
### Commands
|
||
|
||
| Command | Does |
|
||
|---|---|
|
||
| `/agenthub-doctor` | Node version, bootstrap state, runtime deps, server liveness, duplicate hooks, CLI launcher + PATH, **systemd** (`WARN` when the unit names a retired plugin root — the dashboard will not survive a reboot — or when it is installed but stopped; no unit at all is fine), **tmux** (`WARN` when absent — only the run console, `agenthub lanes shell` and session reloads need it), **skill plugins** (see below), UI bundle |
|
||
| `/agenthub-update` | Pull the latest `agenthub` release via `claude plugin marketplace update` + `claude plugin update agenthub@<marketplace> -y`, then reinstall dependencies and restart the server (`plugin-bootstrap.js --force`). The plugin pull needs a manual `/reload-plugins` afterward to take effect in the current session — not scriptable from a command. |
|
||
| `/agenthub-open` | Rebuild the UI bundle and print the dashboard URL. Re-runs the bootstrap first when the server is down or still executing a plugin root that a mid-session `/plugin` update retired, so a fresh bundle never talks to an older server's routes |
|
||
| `/ship-full <requirement>` | Put the lane on the 16-node `ship-feature` template, then run `/agenthub:ship-feature-lane` **in this session**. The in-session twin of `agenthub ship-full` (which spawns its own `claude` from a terminal) |
|
||
| `/ship-quick <requirement>` | The same for the 8-node `default` template and `/agenthub:ship-feature` — stops at review/gate, no PR, no browser QC |
|
||
| One per pipeline node: `/intake`, `/plan`, `/implement`, `/tests`, `/e2e`, `/e2e-passed`, `/review`, `/qc-plan`, `/qc`, `/gate`, `/publishing`, `/pr-open`, `/reported`, `/watching-pr`, `/merged`, `/done` | Run just that node's own `command`, resolved through `agenthub lanes node <id> --print` against whichever template the lane is on (matched by id **or alias**, so `/implement` works on `default`'s `implement` and `ship-feature`'s `implementing`). A slash-command node is invoked in the current session, never as a nested `claude`; anything else runs as a shell argv in the lane's cwd. None of them declares a stage |
|
||
|
||
#### The `Skill plugins` row
|
||
|
||
Derived from the loaded pipeline templates, not hardcoded: every `/plugin:skill`
|
||
string a template names — as the pipeline's own `skill` or as one node's
|
||
`command` — has to come from an installed, enabled plugin. Today that means
|
||
**`superpowers`**, which `/agenthub:ship-feature` and `/agenthub:ship-feature-lane`
|
||
drive step by step (`brainstorming`, `writing-plans`,
|
||
`test-driven-development`, `requesting-code-review`,
|
||
`verification-before-completion`, `finishing-a-development-branch`). Install it
|
||
with `claude plugin install superpowers@claude-plugins-official`.
|
||
|
||
The row is a **WARN, never a FAIL**: the dashboard, hooks and CLI all work
|
||
without it, and only those two pipeline skills stop partway. A plugin listed but
|
||
explicitly disabled counts as missing — Claude Code will not resolve its skills.
|
||
The skills present as plain user skills under `~/.claude/skills/` count as
|
||
satisfied, so a hand-copied setup is not reported as broken. A custom template
|
||
in `DASHBOARD_PIPELINES_DIR` naming some other plugin's command is checked the
|
||
same way.
|
||
|
||
Both the derivation and the missing/satisfied rules live in
|
||
`server/lib/skill-plugins.js`, shared with the bootstrap below so the row and
|
||
the install can never disagree about what is missing.
|
||
|
||
#### Automatic install, and why it is allowlisted
|
||
|
||
`plugin-bootstrap.js` installs the missing plugins itself, at the very end of
|
||
its **detached worker** — never in the 10 s `SessionStart` hook, because the
|
||
install clones from the network. It runs `claude plugin install
|
||
superpowers@claude-plugins-official --scope user -y`; if that fails it registers
|
||
the marketplace (`claude plugin marketplace add anthropics/claude-plugins-official`)
|
||
and retries exactly once. Failure is logged with the manual command and nothing
|
||
throws — the dashboard, hooks and CLI do not need these plugins.
|
||
|
||
The result is recorded as `skillPluginsSettled` in the bootstrap's `state.json`,
|
||
which is also part of `fastPathOk()`: the check runs **once** per install, then
|
||
the hot path reads one flag. `/agenthub-update` (`--force`) is the retry.
|
||
`AGENTHUB_AUTO_INSTALL_PLUGINS=0` (or `false`/`off`) turns it off entirely.
|
||
|
||
An installed plugin only resolves in the **current** session after
|
||
`/reload-plugins`; a new session picks it up on its own. The log says so, since
|
||
the worker is detached and cannot tell the session that started it.
|
||
|
||
**Reporting is derived, installing is allowlisted.** The row above reads plugin
|
||
names out of the templates, which is right for a report. Installing from the
|
||
same source would not be: a template is a file anyone can drop into
|
||
`DASHBOARD_PIPELINES_DIR`, so it would turn "edit a JSON file" into "run this
|
||
vendor's plugin install command on the next session". Auto-install therefore
|
||
consults `AUTO_INSTALLABLE`, a fixed map in `server/lib/skill-plugins.js`, and
|
||
skips every other requirement — visible in the doctor, never installed. Adding
|
||
an entry there is a decision to install someone else's code on a user's machine
|
||
without asking; it belongs in a review, not in a config file.
|
||
|
||
### Where things live
|
||
|
||
| Thing | Location | Survives a plugin update |
|
||
|---|---|---|
|
||
| SQLite DB, transcripts | `~/.claude/agenthub/` | yes |
|
||
| `node_modules`, `client-dist`, logs, lock, `state.json` | `~/.claude/agenthub/runtime/` | yes (re-verified on every session start) |
|
||
| Source, hooks | the plugin cache version directory | no — re-bootstrapped |
|
||
|
||
The bootstrap deliberately does **not** set `DASHBOARD_DATA_DIR`: leaving the
|
||
default keeps a plugin-run server and a developer's `npm run dev` server on one
|
||
data directory, where `ingestGroupKey` already deduplicates hook ingest to a
|
||
single port.
|
||
|
||
### Uninstalling
|
||
|
||
`claude plugin uninstall agenthub@agenthub` only removes
|
||
the plugin from the enabled list — verified against a real install/uninstall,
|
||
not assumed. It does **not**:
|
||
|
||
- stop the running server (it keeps serving from the now-uninstalled cache dir)
|
||
- disable or remove the `agenthub.service` systemd `--user` unit (Linux) — it
|
||
will keep restarting the old server on every reboot, since `systemctl`
|
||
knows nothing about `claude plugin uninstall`
|
||
- remove the cached source under `~/.claude/plugins/cache/.../agenthub/<version>/`
|
||
- remove the hook entries `claude plugin install` wrote into
|
||
`~/.claude/settings.json` (still pointing at that cache dir — they keep
|
||
firing, and keep working, until the cache directory is eventually GC'd by
|
||
Claude Code, at which point they silently start failing)
|
||
- remove `~/.local/bin/agenthub` or `~/.claude/agenthub/runtime/`
|
||
|
||
For a clean machine, do all of this yourself:
|
||
|
||
```bash
|
||
# 1. Stop the server. On Linux, disable the systemd unit FIRST — the unit is
|
||
# Restart=always, so a bare `kill` is always undone by systemd.
|
||
systemctl --user disable --now agenthub.service 2>/dev/null
|
||
rm -f ~/.config/systemd/user/agenthub.service && systemctl --user daemon-reload 2>/dev/null
|
||
# Fallback for a detached (non-systemd) server, or if the unit above was absent:
|
||
kill "$(node -e 'console.log(JSON.parse(require("fs").readFileSync(require("os").homedir()+"/.claude/.agenthub.json","utf8")).pid)')" 2>/dev/null
|
||
|
||
# 2. Runtime state and the CLI launcher
|
||
rm -rf ~/.claude/agenthub/runtime # deps, UI bundle, logs, state
|
||
rm -f ~/.local/bin/agenthub
|
||
|
||
# 3. The hook entries claude plugin install wrote (settings.json is not
|
||
# ours to fully own — back it up first and only drop entries mentioning
|
||
# hook-handler.js)
|
||
node -e '
|
||
const fs = require("fs");
|
||
const p = require("os").homedir() + "/.claude/settings.json";
|
||
const d = JSON.parse(fs.readFileSync(p, "utf8"));
|
||
fs.copyFileSync(p, p + ".agenthub-bak2");
|
||
for (const [type, entries] of Object.entries(d.hooks || {})) {
|
||
const kept = entries.filter((e) => !JSON.stringify(e).includes("hook-handler.js"));
|
||
if (kept.length) d.hooks[type] = kept; else delete d.hooks[type];
|
||
}
|
||
fs.writeFileSync(p, JSON.stringify(d, null, 2) + "\n");
|
||
'
|
||
```
|
||
|
||
`~/.claude/agenthub/` still holds the SQLite database after all of the
|
||
above — delete that directory too only if you want the recorded history gone.
|
||
|
||
## Available Plugins
|
||
|
||
### 1. `agenthub-analytics` — Analytics & Monitoring
|
||
|
||
Deep analytics on sessions, token usage, costs, cache efficiency, model mix, and productivity.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Session Report | `/agenthub-analytics:session-report` | Per-model tokens (input/output/cache_read/cache_write + baselines), cost, agent hierarchy, tool activity, timeline |
|
||
| Cost Breakdown | `/agenthub-analytics:cost-breakdown` | Per-model cost via the pricing engine, daily trends, cache efficiency, optimization opportunities |
|
||
| Usage Trends | `/agenthub-analytics:usage-trends` | 365-day session/event trends, token volume, tool rankings, model distribution, event-type ratios |
|
||
| Productivity Score | `/agenthub-analytics:productivity-score` | Weighted scorecard: completion, token efficiency, tool effectiveness, velocity, cost efficiency |
|
||
| Cache Efficiency | `/agenthub-analytics:cache-efficiency` | Cache hit rate, write-vs-read reuse, sessions with poor cache reuse |
|
||
| Model Mix | `/agenthub-analytics:model-mix` | Share of tokens and cost per model family; expensive models doing cheap work |
|
||
|
||
**Commands:** `/agenthub-analytics:cost-today` · `/agenthub-analytics:top-spenders` · `/agenthub-analytics:burn-rate`
|
||
|
||
**Agents:** `analytics-advisor` (full advisor incl. workflow intelligence) · `token-economist` (token economics & reduction tactics)
|
||
|
||
**Hooks:** Logs `Stop` / `SubagentStop` events. **CLI:** `agenthub-stats` — terminal stats (sessions, cost, tokens).
|
||
|
||
---
|
||
|
||
### 2. `agenthub-cost-guard` — Budget Guardrails
|
||
|
||
Spend limits, forecasting, cost alerts, and model-routing savings.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Budget Set | `/agenthub-cost-guard:budget-set` | Define a budget and (optionally) arm a `token_threshold` alert rule; explains the $→token conversion |
|
||
| Spend Forecast | `/agenthub-cost-guard:spend-forecast` | Project week/month-end spend from the daily trend (moving average × remaining days) |
|
||
| Cost Alert | `/agenthub-cost-guard:cost-alert` | Review alert rules and fired alerts; explain exactly what tripped |
|
||
| Model Savings | `/agenthub-cost-guard:model-savings` | Estimate $ saved by routing eligible work to a cheaper model family |
|
||
| Daily Budget Check | `/agenthub-cost-guard:daily-budget-check` | Today's spend vs a daily budget, pace vs target, projected overage |
|
||
|
||
**Commands:** `/agenthub-cost-guard:budget` · `/agenthub-cost-guard:forecast` · `/agenthub-cost-guard:overspend`
|
||
|
||
**Agent:** `budget-sentinel` — watches spend vs target, projects month-end, recommends cuts. **Hooks:** fail-safe `Stop` event POST so budget tracking sees session ends.
|
||
|
||
---
|
||
|
||
### 3. `agenthub-productivity` — Productivity & Workflows
|
||
|
||
Standups, weekly/monthly reviews, sprint tracking, focus analysis, and workflow optimization.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Daily Standup | `/agenthub-productivity:daily-standup` | Standup from recent sessions — work by project (cwd), costs, tools, errors, velocity |
|
||
| Weekly Report | `/agenthub-productivity:weekly-report` | Daily session/event trends, per-session costs, token volumes, tool top-20, completion rates |
|
||
| Sprint Summary | `/agenthub-productivity:sprint-summary` | Per-project + per-model costs, token efficiency, subagent effectiveness, retrospective data |
|
||
| Workflow Optimizer | `/agenthub-productivity:workflow-optimizer` | Tool-flow transitions, effectiveness, delegation, error propagation, concurrency, compaction |
|
||
| Monthly Review | `/agenthub-productivity:monthly-review` | Month-over-month sessions, cost, tokens, completion, top projects, notable shifts |
|
||
| Time of Day | `/agenthub-productivity:time-of-day` | Activity/productivity bucketed by hour and day-of-week; peak vs low-output windows |
|
||
|
||
**Commands:** `/agenthub-productivity:standup` · `/agenthub-productivity:whats-next` · `/agenthub-productivity:focus-report`
|
||
|
||
**Agents:** `productivity-coach` (work-pattern review) · `focus-analyst` (deep-work / focus blocks). **Hooks:** session start/end timing.
|
||
|
||
---
|
||
|
||
### 4. `agenthub-devtools` — Developer Tools
|
||
|
||
Debugging, data-integrity inspection, event tracing, transcript search, diagnostics, export, and health checks.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Session Debug | `/agenthub-devtools:session-debug` | Full event chain, agent hierarchy, token usage with baselines, workflow intelligence |
|
||
| Hook Diagnostics | `/agenthub-devtools:hook-diagnostics` | Hook install, connectivity, handler validation, event delivery, data freshness |
|
||
| Data Export | `/agenthub-devtools:data-export` | Export sessions/events/analytics/costs as JSON/CSV/Markdown |
|
||
| Health Check | `/agenthub-devtools:health-check` | API, SQLite (WAL), WebSocket, endpoints, hooks, disk, data freshness |
|
||
| Event Trace | `/agenthub-devtools:event-trace` | Ordered event timeline for a session, highlighting gaps/failures |
|
||
| Transcript Grep | `/agenthub-devtools:transcript-grep` | Search a session transcript for a string/pattern with context |
|
||
|
||
**Commands:** `/agenthub-devtools:doctor` · `/agenthub-devtools:export` · `/agenthub-devtools:tail-events`
|
||
|
||
**Agents:** `issue-triager` (cross-component triage) · `db-inspector` (data-integrity inspection). **CLI:** `agenthub-doctor`, `agenthub-export`.
|
||
|
||
---
|
||
|
||
### 5. `agenthub-insights` — AI-Powered Insights
|
||
|
||
Pattern detection, anomaly alerting, forecasting, regression watch, benchmarking, optimization, and comparison.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Pattern Detect | `/agenthub-insights:pattern-detect` | Tool-flow transitions, recurring sequences, agent co-occurrence, delegation habits |
|
||
| Anomaly Alert | `/agenthub-insights:anomaly-alert` | Cost/token/event-ratio/complexity outliers (statistical) |
|
||
| Optimization Suggest | `/agenthub-insights:optimization-suggest` | Model downgrades, cache optimization, compaction reduction, tool reliability |
|
||
| Session Compare | `/agenthub-insights:session-compare` | Side-by-side tokens, costs, complexity, tool-flow, metadata deltas |
|
||
| Regression Watch | `/agenthub-insights:regression-watch` | Rising error rate, falling cache hits, growing compaction, climbing cost/session |
|
||
| Benchmark | `/agenthub-insights:benchmark` | Benchmark a session vs the rolling average; show percentile |
|
||
|
||
**Commands:** `/agenthub-insights:insights` · `/agenthub-insights:compare` · `/agenthub-insights:anomalies`
|
||
|
||
**Agents:** `insights-advisor` (strategic analysis) · `trend-forecaster` (near-future cost/usage projection).
|
||
|
||
---
|
||
|
||
### 6. `agenthub-sessions` — Session Forensics
|
||
|
||
Search, timeline, transcript replay, per-project rollups, and lifecycle management.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Session Search | `/agenthub-sessions:session-search` | Find sessions by project/model/status/date; rank by cost or recency |
|
||
| Session Timeline | `/agenthub-sessions:session-timeline` | Ordered timeline of one session's events with durations and tool names |
|
||
| Transcript Replay | `/agenthub-sessions:transcript-replay` | Walk a transcript turn-by-turn, summarizing each message |
|
||
| CWD Rollup | `/agenthub-sessions:cwd-rollup` | Roll up sessions by working directory: counts, cost, tokens, last-active |
|
||
| Session Cleanup | `/agenthub-sessions:session-cleanup` | Identify stale/empty sessions; preview before the cleanup endpoint deletes (confirm required) |
|
||
|
||
**Commands:** `/agenthub-sessions:find-session` · `/agenthub-sessions:replay` · `/agenthub-sessions:recent`
|
||
|
||
**Agent:** `session-investigator` — end-to-end investigation of a single session.
|
||
|
||
---
|
||
|
||
### 7. `agenthub-workflows` — Orchestration & Fleet Intelligence
|
||
|
||
Multi-agent structure analysis using the workflow intelligence API and Workflow-tool run journals.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| DAG Map | `/agenthub-workflows:dag-map` | Orchestration DAG: parent→child subagent edges, depth, fan-out |
|
||
| Delegation Audit | `/agenthub-workflows:delegation-audit` | Model delegation + subagent effectiveness; wasted delegations |
|
||
| Concurrency Report | `/agenthub-workflows:concurrency-report` | Concurrency lanes, parallelism, serialization bottlenecks |
|
||
| Error Propagation | `/agenthub-workflows:error-propagation` | Trace failures by depth and how they cascade across subagents |
|
||
| Fleet Runs | `/agenthub-workflows:fleet-runs` | Summarize Workflow-tool fleet runs (no-hook fleets ingested from run journals) |
|
||
|
||
**Commands:** `/agenthub-workflows:workflow` · `/agenthub-workflows:dag` · `/agenthub-workflows:runs`
|
||
|
||
**Agent:** `orchestration-analyst` — analyzes the 11 workflow datasets + fleet runs.
|
||
|
||
---
|
||
|
||
### 8. `agenthub-quality` — Reliability & SLOs
|
||
|
||
Error monitoring, hook-delivery health, SLO tracking with error budgets, and regression alerts.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Error Scan | `/agenthub-quality:error-scan` | Scan events for APIError + failure signals; group by tool/model; rank by frequency |
|
||
| API Error Report | `/agenthub-quality:api-error-report` | APIError detail: counts over time, affected sessions/models, likely causes |
|
||
| Hook Failure Audit | `/agenthub-quality:hook-failure-audit` | PreToolUse/PostToolUse balance, missing terminators, stale ingestion |
|
||
| SLO Check | `/agenthub-quality:slo-check` | Completion rate, tool success rate, error rate; error budget remaining |
|
||
| Regression Alert | `/agenthub-quality:regression-alert` | Compare this period's error/failure rates to the prior period; optional alert rule |
|
||
|
||
**Commands:** `/agenthub-quality:errors` · `/agenthub-quality:slo` · `/agenthub-quality:health`
|
||
|
||
**Agent:** `reliability-engineer` — treats Claude Code usage as a service with an error budget.
|
||
|
||
---
|
||
|
||
### 9. `agenthub-config` — Config & Memory Governance
|
||
|
||
Audit your Claude Code configuration and curate the file-based memory store via the Config Explorer API.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Config Audit | `/agenthub-config:config-audit` | Counts per surface (user vs project), duplicate skills/agents, shell-running hooks |
|
||
| Memory Review | `/agenthub-config:memory-review` | CLAUDE.md + per-project auto-memory files grouped by project; flag stale/oversized facts |
|
||
| Skill Inventory | `/agenthub-config:skill-inventory` | Installed skills + contributing plugins; overlap with your own skills |
|
||
| MCP Audit | `/agenthub-config:mcp-audit` | MCP servers (user + project): transport, command/args/env names, source file |
|
||
| Hook Inventory | `/agenthub-config:hook-inventory` | Hooks across settings + the hooks scripts dir; flag network/arbitrary-command hooks |
|
||
|
||
**Commands:** `/agenthub-config:audit-config` · `/agenthub-config:memory` · `/agenthub-config:inventory`
|
||
|
||
**Agent:** `config-auditor` — audits config sprawl, duplication, risky hooks, and stale memory.
|
||
|
||
> Memory Review can also edit the per-project memory store: auto-memory files are mutable via `PUT`/`DELETE /api/cc-config/file` with `{ scope: "auto-memory", type: "auto-memory", project, name }` (always backed up first).
|
||
|
||
---
|
||
|
||
### 10. `agenthub-dashboard` — Dashboard Connector
|
||
|
||
Quick status, live watch, and endpoint probing.
|
||
|
||
| Skill | Command | Purpose |
|
||
|-------|---------|---------|
|
||
| Dashboard Status | `/agenthub-dashboard:dashboard-status` | Health: API connectivity, session/event counts, hook status, data freshness |
|
||
| Quick Stats | `/agenthub-dashboard:quick-stats` | One-line metrics: active sessions, total cost, events, top tool, cache efficiency |
|
||
| Live Watch | `/agenthub-dashboard:live-watch` | Poll a few times to show live deltas (active sessions/agents, events, ws connections) |
|
||
| Endpoint Probe | `/agenthub-dashboard:endpoint-probe` | Probe each major API route and report reachability/shape |
|
||
|
||
**Commands:** `/agenthub-dashboard:status` · `/agenthub-dashboard:ping` · `/agenthub-dashboard:open-dashboard`
|
||
|
||
**Agent:** `dashboard-operator` — verifies the dashboard is up and guides start/restart/import. **Access:** direct tool access to the Agent Monitor API. **Settings:** default agent model.
|
||
|
||
---
|
||
|
||
## Data Model Reference
|
||
|
||
These plugins query the Agent Monitor API at `http://localhost:4820`. Key data shapes:
|
||
|
||
### Token Tracking
|
||
- **4 token types**: `input_tokens`, `output_tokens`, `cache_read_input_tokens`, `cache_creation_input_tokens`
|
||
- **4 baselines**: `baseline_input`, `baseline_output`, `baseline_cache_read`, `baseline_cache_write` (preserve pre-compaction tokens)
|
||
- **Effective total** = current + baseline (the `/api/analytics` totals are pre-summed)
|
||
|
||
### Cost Calculation
|
||
- Formula: `(tokens / 1,000,000) × rate_per_mtok` for each token type
|
||
- Model matching: longest `model_pattern` wins (e.g., `claude-sonnet-4-5%` beats `claude-sonnet-4%`)
|
||
- Pre-seeded rates for Opus, Sonnet, Haiku families
|
||
|
||
### Session Metadata (JSON)
|
||
- `thinking_blocks`: count of extended thinking blocks
|
||
- `turn_count`: number of conversation turns
|
||
- `total_turn_duration_ms`: cumulative turn processing time
|
||
- `usage_extras`: `{ service_tiers[], speeds[], inference_geos[] }`
|
||
|
||
### Event Types
|
||
`PreToolUse`, `PostToolUse`, `Stop`, `SubagentStop`, `SessionStart`, `SessionEnd`, `Notification`, `Compaction`, `APIError`, `TurnDuration`, `ToolError`, `Interrupted`
|
||
|
||
### Workflow Intelligence API (`/api/workflows/{sessionId}`)
|
||
11 datasets: `stats`, `orchestration` (DAG), `toolFlow` (transitions), `effectiveness` (subagent success), `patterns` (recurring sequences), `modelDelegation`, `errorPropagation` (by depth), `concurrency` (lanes), `complexity` (score), `compaction` (impact), `cooccurrence` (agent pairs)
|
||
|
||
### Alert Rules (`/api/alerts/rules`)
|
||
Rule types: `token_threshold` (`{ total_tokens }` — the spend-relevant guardrail), `event_pattern`, `inactivity`, `status_duration`.
|
||
|
||
### Config Explorer (`/api/cc-config/*`)
|
||
Read every Claude Code surface (skills, agents, commands, output-styles, plugins, marketplaces, mcp, hooks, settings, keybindings, statusline, memory). A plugin card's contribution chips are clickable: each one expands to name the skills / subagents / commands / output styles that plugin ships (from `contributes.items`), so the plugin's contents are readable without opening its install directory. `memory` includes the per-project file-based store with `scope: "auto-memory"` (carrying `project`, `name`, `isIndex`, `frontmatter`); those files plus `CLAUDE.md` are mutable via `PUT`/`DELETE /api/cc-config/file` with always-on timestamped backups. The page also **manages plugins and marketplaces**: paste a GitHub `owner/repo`, URL or local path to register a marketplace, then install / enable / disable / update / uninstall its plugins — each button runs the corresponding `claude plugin …` command on the dashboard host (argv array, never a shell string). Hooks and `settings.json` keys are editable per layer (user / project / project-local) through `PATCH /api/cc-config/settings`, a per-key merge that leaves every untouched key — including redacted secrets — exactly as it was.
|
||
|
||
## Plugin Development
|
||
|
||
To create your own plugins for the Agent Monitor, see the [Claude Code plugin documentation](https://docs.anthropic.com/en/docs/claude-code/plugins).
|
||
|
||
### Plugin structure
|
||
|
||
```
|
||
my-plugin/
|
||
├── .claude-plugin/
|
||
│ └── plugin.json # Required: name (== dir name), description, version
|
||
├── skills/
|
||
│ └── my-skill/
|
||
│ └── SKILL.md # Skill (description-only frontmatter; uses $ARGUMENTS)
|
||
├── agents/
|
||
│ └── my-agent.md # Agent (name == filename, model, tools, instructions)
|
||
├── commands/
|
||
│ └── my-command.md # Slash command (description, optional argument-hint)
|
||
├── hooks/
|
||
│ └── hooks.json # Event hooks (fail-safe, non-blocking)
|
||
├── bin/
|
||
│ └── my-cli-tool # CLI scripts (added to PATH)
|
||
└── settings.json # Plugin settings
|
||
```
|
||
|
||
Structure is validated by `server/__tests__/plugins-marketplace.test.js`, which enforces the marketplace↔directory bijection, `plugin.json` shape, name/dir agreement, and required frontmatter on every agent / skill / command.
|
||
|
||
Two of those shape rules exist because getting them wrong makes a plugin **listed but uninstallable**, with no other symptom — the marketplace loads fine and only `claude plugin install` fails:
|
||
|
||
- A subdirectory entry declares **`"source": "./plugins/<name>"`**, never `"path"`. `path` is not a source key the CLI accepts (`This plugin's marketplace entry is invalid: source: Invalid input`).
|
||
- A `plugin.json`'s **`repository` is a string**, not npm's `{ "type", "url" }` object (`Validation errors: repository: Invalid input`).
|
||
|
||
`server/__tests__/repo-links.test.js` guards the link side: no GitHub `owner/repo` marketplace shorthand (it resolves to github.com only — this repo is on Gitea, so the shorthand cannot work and no `GH_HOST`-style env var redirects it), no `raw.githubusercontent.com` / `*.github.io` / GitHub `/blob/<branch>/` URLs, no retired repository name, and no stale committed `openapi.yaml`.
|
||
|
||
### Testing locally
|
||
|
||
```bash
|
||
claude --plugin-dir /path/to/my-plugin # then use /my-plugin:my-skill some args
|
||
```
|
||
|
||
## Troubleshooting
|
||
|
||
### Dashboard not reachable
|
||
```bash
|
||
cd /path/to/AgentHub
|
||
npm start # or: npm run dev
|
||
```
|
||
|
||
### Hooks not installed
|
||
```bash
|
||
cd /path/to/AgentHub
|
||
npm run setup
|
||
```
|
||
|
||
### Plugin not found
|
||
```bash
|
||
claude plugin marketplace list
|
||
claude plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
|
||
```
|
||
|
||
## License
|
||
|
||
Internal SmartGift build — all rights reserved.
|