fix(plugins): serverIsLive() falsely reported a server as running

resolveAllDashboardPorts() falls back to [DEFAULT_PORT] when the discovery
file has no live entry — a reasonable guess for the CLI/hook handler, but
wrong for the bootstrap's own liveness check: with no server running at all,
the bootstrap believed one was already up and never called startDashboard(),
confirmed against a real plugin install where the dashboard never started.
plugin-doctor.js's "Server" row had the same bug. Both now read the discovery
file directly and check PID liveness via the new liveServers() (livePids()
reused it instead of duplicating the read).
This commit is contained in:
2026-08-10 16:22:13 +07:00
parent 022b2384ac
commit a65ee1512e
3 changed files with 57 additions and 22 deletions
+32
View File
@@ -31,6 +31,38 @@ after(() => {
fs.rmSync(TMP_HOME, { recursive: true, force: true });
});
describe("serverIsLive", () => {
const infoPath = path.join(TMP_HOME, ".agent-dashboard.json");
beforeEach(() => fs.rmSync(infoPath, { force: true }));
after(() => fs.rmSync(infoPath, { force: true }));
it("is false with no discovery file at all", () => {
// Regression: server-info's resolveAllDashboardPorts() falls back to
// [DEFAULT_PORT] when nothing is live (a reasonable guess for the CLI),
// which made the bootstrap wrongly believe a server was already running
// and skip starting its own.
assert.equal(boot.serverIsLive(), false);
});
it("is false when every recorded pid is dead", () => {
fs.writeFileSync(
infoPath,
JSON.stringify({ servers: [{ port: 4820, pid: 999999, startedAt: "x" }] })
);
assert.equal(boot.serverIsLive(), false);
});
it("is true when a recorded pid is actually alive", () => {
fs.writeFileSync(
infoPath,
JSON.stringify({ servers: [{ port: 4820, pid: process.pid, startedAt: "x" }] })
);
assert.equal(boot.serverIsLive(), true);
assert.deepEqual(boot.liveServers(), [{ port: 4820, pid: process.pid, startedAt: "x" }]);
});
});
describe("runtime location", () => {
it("lives under the shared data dir, not the plugin cache", () => {
assert.equal(boot.runtimeDir(), RT);