feat(install): auto-start the dashboard on boot via systemd, no Claude Code needed
Adds ccam service install/uninstall/status for checkout installs and wires the same systemd --user unit into plugin-bootstrap.js, so plugin-installed colleagues get boot persistence too instead of needing a Claude Code session to (re)start the server after every reboot.
This commit is contained in:
+37
-3
@@ -133,7 +133,14 @@ waits on an install:
|
||||
5. **Legacy hook cleanup** — see above.
|
||||
6. **CLI** — write the `~/.local/bin/ccam` launcher, never clobbering a `ccam` the bootstrap did not write.
|
||||
7. **UI build** — `client/` is copied into the runtime dir and built there (`npm install && npm run build`), landing in `runtime/client-dist` — the same directory the server serves from. Skipped when a bundle for the current version already exists; a failure here does not fail the bootstrap (API and MCP still work, and `/ccam-open` can retry) but does mean `/run` 404s until it's fixed.
|
||||
8. **Server** — spawn `server/index.js` detached, with `NODE_PATH` at the runtime `node_modules` and `DASHBOARD_CLIENT_DIST` at the runtime `client-dist`.
|
||||
8. **Server** — on Linux with `systemd --user` available, install/refresh a
|
||||
`ccam.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.
|
||||
9. **Record state** — `runtime/state.json`.
|
||||
|
||||
The first run takes a few minutes — most of it is the UI build, which is what
|
||||
@@ -143,6 +150,26 @@ goes to `~/.claude/agent-dashboard/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`.
|
||||
|
||||
### Auto-start on boot
|
||||
|
||||
On Linux, every plugin bootstrap (not just the first) installs/refreshes a
|
||||
systemd `--user` service (`~/.config/systemd/user/ccam.service`, managed via
|
||||
`scripts/systemd-service.js` — shared with the checkout path's
|
||||
`ccam 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/agent-dashboard/runtime/bootstrap.log`, or run
|
||||
`sudo loginctl enable-linger <user>` once by hand). A pre-existing
|
||||
`ccam.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.
|
||||
|
||||
### Commands
|
||||
|
||||
| Command | Does |
|
||||
@@ -171,6 +198,9 @@ 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 `ccam.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/.../ccam/<version>/`
|
||||
- remove the hook entries `claude plugin install` wrote into
|
||||
`~/.claude/settings.json` (still pointing at that cache dir — they keep
|
||||
@@ -181,8 +211,12 @@ not assumed. It does **not**:
|
||||
For a clean machine, do all of this yourself:
|
||||
|
||||
```bash
|
||||
# 1. Stop the server (skip if ~/.claude/.agent-dashboard.json is already gone)
|
||||
kill "$(node -e 'console.log(JSON.parse(require("fs").readFileSync(require("os").homedir()+"/.claude/.agent-dashboard.json","utf8")).pid)')"
|
||||
# 1. Stop the server. On Linux, check for the systemd unit first — a bare
|
||||
# `kill` just gets restarted by it (Restart=on-failure).
|
||||
systemctl --user disable --now ccam.service 2>/dev/null
|
||||
rm -f ~/.config/systemd/user/ccam.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/.agent-dashboard.json","utf8")).pid)')" 2>/dev/null
|
||||
|
||||
# 2. Runtime state and the CLI launcher
|
||||
rm -rf ~/.claude/agent-dashboard/runtime # deps, UI bundle, logs, state
|
||||
|
||||
Reference in New Issue
Block a user