perf: lighter, louder local install — vendored ReDoc, bootstrap failures shown in the session

- Plugin bootstrap: a failed npm install, a Node older than 22.5 or a failed UI
  build is recorded in runtime/last-failure.json; the next SessionStart prints
  it once as a systemMessage naming the log and /agenthub-doctor (a different
  failure is reported again; a successful bootstrap clears it). The foreground
  pass checks the Node version itself and spawns no worker on an old Node.
- ReDoc: the standalone bundle (redoc 2.5.4, MIT, licence files kept) is
  vendored under server/vendor/redoc/ and the `redoc` dependency dropped —
  a runtime install (npm ci --omit=dev --ignore-scripts) goes 126 MB -> 45 MB.
  vendor/ is excluded from the header audit and prettier.
- git missing from PATH: lane git actions answer 503 EGITMISSING with the
  install command instead of a bare ENOENT.
- package.json engines: node >=22.5.0 (node:sqlite), matching MIN_NODE.
- Docs: INSTALL.md is the one install/setup guide (SETUP.md merged in and now a
  pointer); no VS Code extension claim, one client-install hint, no
  windows-build-tools, better-sqlite3 notes scoped to checkouts, new
  "Plugin bootstrap never comes up" troubleshooting entry.
This commit is contained in:
2026-10-16 10:16:54 +07:00
parent ecbbb4dd8f
commit 9a4ed54cf7
26 changed files with 2667 additions and 1527 deletions
+17 -6
View File
@@ -61,13 +61,13 @@ 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.)
- Node **>= 22.5**. A plugin install has no native `better-sqlite3`, so the
server stores data through `node:sqlite`, which landed in 22.5. The bootstrap
refuses on anything older instead of letting the server crash, and says so in
the session (below). A checkout needs the same (`engines` in `package.json`).
- 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))
[INSTALL.md](../INSTALL.md))
Skills and commands are invoked as `/agenthub-<plugin>:<name>`. Agents are dispatched automatically by Claude Code (or named explicitly).
@@ -124,7 +124,7 @@ waits on an install:
1. **Fast path** — recorded state matches this plugin build and a server is live → exit. "Live" means a discovery entry whose pid answers AND whose `startedAt` is after this boot (60 s margin): an entry left over from before a reboot names a pid the OS may have handed to an unrelated process, and without systemd (macOS) nothing else clears it.
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).
3. **Node gate** — refuse below 22.5 with one line (see Prerequisites). Also checked by the foreground pass itself (it costs nothing), which then spawns no worker and tells the session at once.
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** — only when the dependencies changed (`depsHash` covers what npm installs — the dependency lists and the lockfile's package tree — never the release's own `version`, so a plain version bump reinstalls nothing): `npm install --omit=dev --ignore-scripts` into the runtime dir, output in `runtime/npm-install.log`, run as the npm bundled with the node running the bootstrap (`npmCommand`: its `npm-cli.js` beside `process.execPath`, no shell, that node's directory first on PATH; `npm` on PATH only when that node ships none) — the update chain runs with the dashboard server's environment, whose PATH need not reach `npm.cmd` on Windows. The UI build below and the doctor's npm row use the same npm (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.
@@ -153,6 +153,17 @@ goes to `~/.claude/agenthub/runtime/bootstrap.log`; npm's own output goes to
`npm-install.log` and the UI build's to `client-build.log` next to it; the server's own output goes to
`server.log`.
**A failure is reported once, in the session.** The worker's output is
discarded, so a Node that is too old, a failed npm install or a failed UI build
is recorded in `runtime/last-failure.json` (kind, message, log file). The NEXT
foreground pass — its stdout is what Claude Code reads — prints it as a
SessionStart `{"systemMessage": "AgentHub: … — details in <log>. Run
/agenthub-doctor …"}` and marks it reported, so the same failure is not repeated
every session; a different failure is reported again, and a bootstrap that
succeeds removes the file. The steady state prints nothing, and the report is a
single small read (plus one write, only when there is something to show) — the
fast path still spawns nothing.
### A retired build never acts
`claude plugin update` unpacks the new version into a **new** cache directory