c90dd7b147
The residue an interrupted update leaves behind is invisible: the server
runs, every doctor row reads OK, and the unit quietly still names a cache
directory Claude Code deleted during the update. Nothing surfaces it until
a reboot, when the dashboard does not come back and nothing recorded why.
- fastPathOk now rejects a stale unit, so the next SessionStart repairs it
instead of short-circuiting. `unitIsStale` is pure fs on purpose: that
path runs on every session and may not spawn a process.
- Repairing the unit is not restarting the server. A current, healthy
server keeps running and the corrected unit takes effect at the next
start (`pendingSystemdRestart = systemdOwned && needsServer`), and the
detached-spawn fallback is guarded by needsServer so a stale unit alone
cannot start a second server onto a bound port.
- systemdOwned now also requires the unit to be ACTIVE. Installed-but-
stopped owns nothing: skipping the stop there and asking systemd to start
would bind an occupied port and crash-loop under Restart=always.
- /agenthub-doctor gains a systemd row naming the consequence ("will NOT
come back after a reboot") and the fix. WARN, never FAIL — the dashboard
in front of you works, and having no unit at all is a normal setup.
The fast-path test pins the regression against an otherwise fully healthy
install, live server included; without a live server it would have passed
against the unfixed code either way.
2.5 KiB
2.5 KiB
description
| description |
|---|
| Diagnose a plugin-installed AgentHub — Node, npm, disk, bootstrap, server, hooks, CLI, systemd, tmux, UI build |
Run the diagnostic and report what it found. Do not fix anything unless the user asks.
node "${CLAUDE_PLUGIN_ROOT}/scripts/plugin-doctor.js"
Print the output verbatim, then add at most three lines of guidance based on the
FAIL and WARN rows:
FAIL Node→ the installed Node is too old fornode:sqlite; the server cannot start until Node is upgraded.FAIL Hooks→ duplicate hook entries double every token and cost figure. Starting a new Claude Code session removes them automatically (the bootstrap backs the file up assettings.json.agenthub-bakfirst).FAIL Server→ run/agenthub-update, then check~/.claude/agenthub/runtime/bootstrap.logandserver.log.FAIL Runtime deps→ the install is incomplete, not merely absent. Delete~/.claude/agenthub/runtime/node_modulesbefore running/agenthub-update; reinstalling over the broken tree is what let it survive.FAIL npmorFAIL Disk→ nothing else in the report can be trusted until these are fixed; both silently truncate installs.WARN agenthub CLI→ print the exactexport PATH=...line from the output.WARN Skill plugins→ the pipelines name slash commands no installed plugin provides. The dashboard is unaffected;/agenthub:ship-feature(-lane)is what stops partway. The bootstrap normally installs these itself, so this row also means that attempt has not run or did not succeed — say/agenthub-updateretries it, and print theclaude plugin install …line from the output as the manual route.WARN systemd→ when it says the unit names a previous plugin version, the dashboard is running now but will NOT come back after a reboot. Starting a new Claude Code session repairs it; print the--forcecommand from the output as the immediate fix. "installed but not running" just needssystemctl --user start agenthub.WARN tmux→ only the run console,agenthub lanes shelland the session-reload keystrokes are affected; monitoring, lanes and the CLI are not. Print the install command from the output. If the row saysokbut Start Run still fails, the server has a different PATH than this check — ask it directly withcurl -s localhost:4820/api/run/tmux.WARN Dashboard UI→ run/agenthub-opento build the bundle. When the row quotes a build error, report that error — it is the actual problem.
No preamble, no summary of things that passed.