claude-crap 0.4.7 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/dashboard/server.d.ts +6 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +99 -31
- package/dist/dashboard/server.js.map +1 -1
- package/dist/tests/helpers/dashboard-test-helpers.d.ts +94 -0
- package/dist/tests/helpers/dashboard-test-helpers.d.ts.map +1 -0
- package/dist/tests/helpers/dashboard-test-helpers.js +159 -0
- package/dist/tests/helpers/dashboard-test-helpers.js.map +1 -0
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/bundle/mcp-server.mjs +70 -13
- package/plugin/bundle/mcp-server.mjs.map +2 -2
- package/src/dashboard/server.ts +119 -42
- package/src/tests/dashboard-adoption.test.ts +553 -0
- package/src/tests/helpers/dashboard-test-helpers.ts +203 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.8] - 2026-04-19
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Dashboard port thrash when multiple MCP launchers boot concurrently.**
|
|
13
|
+
Claude Code can spawn several MCP server instances against the same
|
|
14
|
+
workspace (duplicate plugin registrations, stale sessions, etc.).
|
|
15
|
+
The previous `killStaleDashboard` implementation sent SIGTERM to the
|
|
16
|
+
prior pidfile owner on every boot so it could reclaim port 5117 —
|
|
17
|
+
with N concurrent launchers this became a loop where each instance
|
|
18
|
+
killed the last, the pidfile churned, and most instances ended up
|
|
19
|
+
with `dashboard = null`. `score_project` then returned
|
|
20
|
+
`dashboardUrl: null` to the user even though a dashboard was usually
|
|
21
|
+
reachable on 5117. `startDashboard` now **adopts** a healthy pidfile
|
|
22
|
+
owner (`/api/health` probe with a 500 ms timeout) instead of killing
|
|
23
|
+
it, and only terminates zombies (PID alive, port unresponsive).
|
|
24
|
+
Losing an `EADDRINUSE` race also falls back to adoption rather than
|
|
25
|
+
throwing, so two launchers starting in the same millisecond still
|
|
26
|
+
converge cleanly. `DashboardHandle` gained a read-only
|
|
27
|
+
`adopted: boolean` flag; adopted handles have a no-op `close()` so
|
|
28
|
+
one MCP shutdown cannot strand its siblings. Covered by a new
|
|
29
|
+
29-assertion suite in `src/tests/dashboard-adoption.test.ts` (6
|
|
30
|
+
characterization + 23 edge cases: adoption happy path, zombie
|
|
31
|
+
detection, concurrent boot race, pidfile hygiene, owner/adopter
|
|
32
|
+
close semantics). (`src/dashboard/server.ts`.)
|
|
33
|
+
|
|
8
34
|
## [0.4.7] - 2026-04-18
|
|
9
35
|
|
|
10
36
|
### Fixed
|
|
@@ -54,9 +54,15 @@ export interface StartDashboardOptions {
|
|
|
54
54
|
/**
|
|
55
55
|
* Handle returned by {@link startDashboard}. Use `url` to build the
|
|
56
56
|
* link the user clicks; call `close()` during shutdown.
|
|
57
|
+
*
|
|
58
|
+
* `adopted === true` means another claude-crap process already owned
|
|
59
|
+
* the dashboard port when we booted, and we are piggy-backing on its
|
|
60
|
+
* HTTP server. Adopted handles have a no-op `close()` because tearing
|
|
61
|
+
* down the Fastify instance would strand the other MCP servers.
|
|
57
62
|
*/
|
|
58
63
|
export interface DashboardHandle {
|
|
59
64
|
readonly url: string;
|
|
65
|
+
readonly adopted: boolean;
|
|
60
66
|
close(): Promise<void>;
|
|
61
67
|
}
|
|
62
68
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAIrE;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IACxD,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAIrE;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;IACxD,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAsJ7F"}
|
package/dist/dashboard/server.js
CHANGED
|
@@ -41,6 +41,24 @@ import { buildFileDetail } from "./file-detail.js";
|
|
|
41
41
|
*/
|
|
42
42
|
export async function startDashboard(options) {
|
|
43
43
|
const { config, sarifStore, workspaceStatsProvider, logger } = options;
|
|
44
|
+
const pidFilePath = resolvePidFilePath(config);
|
|
45
|
+
// Adopt-don't-steal: if a prior MCP server is already serving the
|
|
46
|
+
// dashboard on this port AND is healthy, piggy-back on it instead of
|
|
47
|
+
// killing it. This is what keeps N concurrent launchers from
|
|
48
|
+
// thrashing the port in an endless SIGTERM loop.
|
|
49
|
+
const adoption = await tryAdoptExisting(pidFilePath, config.dashboardPort, logger);
|
|
50
|
+
if (adoption) {
|
|
51
|
+
logger.info({ url: adoption.url, ownerPid: adoption.pid, port: config.dashboardPort }, "adopted existing claude-crap dashboard");
|
|
52
|
+
return {
|
|
53
|
+
url: adoption.url,
|
|
54
|
+
adopted: true,
|
|
55
|
+
async close() {
|
|
56
|
+
// No-op: we never bound a socket of our own, so there is
|
|
57
|
+
// nothing to release. Removing the pidfile here would make the
|
|
58
|
+
// owner's `close()` race with our cleanup.
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
44
62
|
// Resolve the public/ directory. After `npm run build` the compiled
|
|
45
63
|
// server lives in `dist/dashboard/server.js`, but we keep the static
|
|
46
64
|
// SPA assets in `src/dashboard/public/` so we don't need a postbuild
|
|
@@ -118,18 +136,36 @@ export async function startDashboard(options) {
|
|
|
118
136
|
fastify.get("/", async (_request, reply) => {
|
|
119
137
|
return reply.sendFile("index.html");
|
|
120
138
|
});
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
// The pidfile was either missing, stale, or pointed at a zombie —
|
|
140
|
+
// `tryAdoptExisting` has already cleaned it up. Try to bind. If we
|
|
141
|
+
// lose a race against another launcher that bound between our probe
|
|
142
|
+
// and our listen, fall back to adoption instead of failing.
|
|
143
|
+
try {
|
|
144
|
+
await fastify.listen({ port: config.dashboardPort, host: "127.0.0.1" });
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
const code = err.code;
|
|
148
|
+
if (code === "EADDRINUSE") {
|
|
149
|
+
await fastify.close().catch(() => { });
|
|
150
|
+
const raceAdoption = await tryAdoptExisting(pidFilePath, config.dashboardPort, logger);
|
|
151
|
+
if (raceAdoption) {
|
|
152
|
+
logger.info({ url: raceAdoption.url, ownerPid: raceAdoption.pid, port: config.dashboardPort }, "dashboard bind lost race, adopted concurrent owner");
|
|
153
|
+
return {
|
|
154
|
+
url: raceAdoption.url,
|
|
155
|
+
adopted: true,
|
|
156
|
+
async close() { },
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
throw err;
|
|
161
|
+
}
|
|
127
162
|
const url = `http://127.0.0.1:${config.dashboardPort}`;
|
|
128
163
|
logger.info({ url, publicRoot }, "claude-crap dashboard listening");
|
|
129
|
-
// Write PID file so
|
|
164
|
+
// Write PID file so sibling MCP servers can find us and adopt.
|
|
130
165
|
writePidFile(pidFilePath, config.dashboardPort);
|
|
131
166
|
return {
|
|
132
167
|
url,
|
|
168
|
+
adopted: false,
|
|
133
169
|
async close() {
|
|
134
170
|
removePidFile(pidFilePath);
|
|
135
171
|
await fastify.close();
|
|
@@ -233,61 +269,93 @@ function isPidAlive(pid) {
|
|
|
233
269
|
}
|
|
234
270
|
}
|
|
235
271
|
/**
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
272
|
+
* Probe an existing dashboard and decide whether the current process
|
|
273
|
+
* can adopt it instead of binding its own Fastify server.
|
|
274
|
+
*
|
|
275
|
+
* Returns `{ url, pid }` only when all four conditions hold:
|
|
276
|
+
* 1. A pidfile exists and parses as JSON.
|
|
277
|
+
* 2. The recorded PID is still alive (signal-0 probe).
|
|
278
|
+
* 3. The pidfile's recorded port matches the configured port.
|
|
279
|
+
* 4. A GET on `/api/health` responds within ~500ms.
|
|
240
280
|
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
281
|
+
* Returns `null` in every other case, but with a side-effect that makes
|
|
282
|
+
* the call-site's next step obvious:
|
|
283
|
+
* - Missing / corrupt / dead-PID / port-mismatch → pidfile is removed
|
|
284
|
+
* so the caller can bind cleanly.
|
|
285
|
+
* - Zombie (PID alive, port unresponsive) → stale owner is
|
|
286
|
+
* SIGKILL'd and the pidfile is removed. This is the one case where
|
|
287
|
+
* we still have to kill something, because the socket belongs to a
|
|
288
|
+
* process that is not talking HTTP anymore.
|
|
244
289
|
*/
|
|
245
|
-
async function
|
|
290
|
+
async function tryAdoptExisting(pidFilePath, port, logger) {
|
|
246
291
|
if (!existsSync(pidFilePath))
|
|
247
|
-
return;
|
|
292
|
+
return null;
|
|
248
293
|
let stale;
|
|
249
294
|
try {
|
|
250
295
|
stale = JSON.parse(readFileSync(pidFilePath, "utf8"));
|
|
251
296
|
}
|
|
252
297
|
catch {
|
|
253
|
-
|
|
298
|
+
logger.info({ pidFilePath }, "corrupt dashboard pidfile, removing");
|
|
254
299
|
removePidFile(pidFilePath);
|
|
255
|
-
return;
|
|
300
|
+
return null;
|
|
256
301
|
}
|
|
257
302
|
if (!isPidAlive(stale.pid)) {
|
|
258
|
-
logger.info({ stalePid: stale.pid }, "stale dashboard
|
|
303
|
+
logger.info({ stalePid: stale.pid }, "stale dashboard pidfile (process dead), removing");
|
|
259
304
|
removePidFile(pidFilePath);
|
|
260
|
-
return;
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
if (stale.port !== port) {
|
|
308
|
+
// The recorded owner is on a different port than we want. Don't
|
|
309
|
+
// adopt it, don't kill it — just treat the pidfile as unrelated.
|
|
310
|
+
logger.info({ stalePort: stale.port, wantedPort: port }, "dashboard pidfile points at different port, ignoring");
|
|
311
|
+
removePidFile(pidFilePath);
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
const healthy = await probeDashboardHealth(port);
|
|
315
|
+
if (healthy) {
|
|
316
|
+
return { url: `http://127.0.0.1:${port}`, pid: stale.pid };
|
|
261
317
|
}
|
|
262
|
-
//
|
|
263
|
-
|
|
318
|
+
// Zombie: PID is alive but not serving HTTP. Most likely the owner
|
|
319
|
+
// crashed mid-init or is stuck. Terminate it so we can take over.
|
|
320
|
+
logger.warn({ stalePid: stale.pid, port }, "dashboard pidfile owner is unresponsive, terminating");
|
|
264
321
|
try {
|
|
265
322
|
process.kill(stale.pid, "SIGTERM");
|
|
266
323
|
}
|
|
267
324
|
catch {
|
|
268
|
-
|
|
269
|
-
removePidFile(pidFilePath);
|
|
270
|
-
return;
|
|
325
|
+
/* already gone */
|
|
271
326
|
}
|
|
272
|
-
// Wait up to 3 seconds for the process to exit.
|
|
273
327
|
for (let i = 0; i < 30; i++) {
|
|
274
328
|
if (!isPidAlive(stale.pid))
|
|
275
329
|
break;
|
|
276
330
|
await new Promise((r) => setTimeout(r, 100));
|
|
277
331
|
}
|
|
278
|
-
// If still alive after 3s, escalate to SIGKILL.
|
|
279
332
|
if (isPidAlive(stale.pid)) {
|
|
280
333
|
try {
|
|
281
334
|
process.kill(stale.pid, "SIGKILL");
|
|
282
335
|
}
|
|
283
|
-
catch {
|
|
284
|
-
/* best effort */
|
|
285
|
-
}
|
|
336
|
+
catch { /* best effort */ }
|
|
286
337
|
await new Promise((r) => setTimeout(r, 200));
|
|
287
338
|
}
|
|
288
339
|
removePidFile(pidFilePath);
|
|
289
|
-
//
|
|
340
|
+
// Let the OS release the TCP port before the caller tries to bind.
|
|
290
341
|
await new Promise((r) => setTimeout(r, 300));
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Low-latency health probe. Resolves `true` when the dashboard replies
|
|
346
|
+
* 2xx to `/api/health` within 500ms, `false` on any other outcome
|
|
347
|
+
* (timeout, connection refused, 5xx, etc.).
|
|
348
|
+
*/
|
|
349
|
+
async function probeDashboardHealth(port) {
|
|
350
|
+
try {
|
|
351
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/health`, {
|
|
352
|
+
signal: AbortSignal.timeout(500),
|
|
353
|
+
});
|
|
354
|
+
return res.ok;
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
291
359
|
}
|
|
292
360
|
// Directory exclusions are now centralized in src/shared/exclusions.ts.
|
|
293
361
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared setup utilities for dashboard-adoption tests.
|
|
3
|
+
*
|
|
4
|
+
* Keeps the main test file focused on assertions rather than
|
|
5
|
+
* boilerplate, while staying small enough that each helper is
|
|
6
|
+
* easy to read in isolation.
|
|
7
|
+
*
|
|
8
|
+
* @module tests/helpers/dashboard-test-helpers
|
|
9
|
+
*/
|
|
10
|
+
import { type Logger } from "pino";
|
|
11
|
+
import type { CrapConfig } from "../../config.js";
|
|
12
|
+
import { SarifStore } from "../../sarif/sarif-store.js";
|
|
13
|
+
import type { StartDashboardOptions } from "../../dashboard/server.js";
|
|
14
|
+
/**
|
|
15
|
+
* A pino logger that discards all output. Passing this to
|
|
16
|
+
* `startDashboard` keeps test runs noise-free while still satisfying
|
|
17
|
+
* the `Logger` type constraint.
|
|
18
|
+
*/
|
|
19
|
+
export declare function silentLogger(): Logger;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a random TCP port in the 6000–6999 range that is not bound
|
|
22
|
+
* at the moment of the call. The OS chooses the exact port by binding
|
|
23
|
+
* to port 0 then immediately releasing the socket; there is a tiny
|
|
24
|
+
* TOCTOU window, but in practice it is negligible for unit tests that
|
|
25
|
+
* run serially.
|
|
26
|
+
*
|
|
27
|
+
* Staying in the 6000–6999 range keeps tests away from the production
|
|
28
|
+
* dashboard port (5117) and from common well-known service ports.
|
|
29
|
+
*/
|
|
30
|
+
export declare function findFreePort(): Promise<number>;
|
|
31
|
+
/**
|
|
32
|
+
* Context returned by {@link makeWorkspace}. Call `cleanup()` inside
|
|
33
|
+
* the `after` hook of each test to remove the temporary directory.
|
|
34
|
+
*/
|
|
35
|
+
export interface WorkspaceContext {
|
|
36
|
+
/** Absolute path to the isolated temporary workspace root. */
|
|
37
|
+
pluginRoot: string;
|
|
38
|
+
/** Absolute path to `.claude-crap/dashboard.pid` inside the workspace. */
|
|
39
|
+
pidFilePath: string;
|
|
40
|
+
/** Teardown — removes the entire temp directory tree. */
|
|
41
|
+
cleanup(): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create an isolated temporary workspace directory and ensure the
|
|
45
|
+
* `.claude-crap/` subdirectory exists so pidfile writes always succeed.
|
|
46
|
+
* Returns paths and a cleanup function.
|
|
47
|
+
*/
|
|
48
|
+
export declare function makeWorkspace(): Promise<WorkspaceContext>;
|
|
49
|
+
/**
|
|
50
|
+
* Minimal {@link CrapConfig} suitable for a test invocation of
|
|
51
|
+
* `startDashboard`. Every field that the function actually reads is
|
|
52
|
+
* supplied with a sane default; callers can override `dashboardPort`
|
|
53
|
+
* and `pluginRoot` as needed.
|
|
54
|
+
*/
|
|
55
|
+
export declare function makeConfig(pluginRoot: string, dashboardPort: number): CrapConfig;
|
|
56
|
+
/**
|
|
57
|
+
* Build an empty {@link SarifStore} rooted at `pluginRoot`. No file is
|
|
58
|
+
* written to disk; `loadLatest()` is intentionally NOT called here —
|
|
59
|
+
* the tests that need a pre-seeded store will do so themselves.
|
|
60
|
+
*/
|
|
61
|
+
export declare function makeSarifStore(pluginRoot: string): SarifStore;
|
|
62
|
+
/**
|
|
63
|
+
* Bundle a complete {@link StartDashboardOptions} object from a
|
|
64
|
+
* workspace context + port. Used by tests that call `startDashboard`
|
|
65
|
+
* directly.
|
|
66
|
+
*/
|
|
67
|
+
export declare function makeOptions(pluginRoot: string, dashboardPort: number): StartDashboardOptions;
|
|
68
|
+
/**
|
|
69
|
+
* Shape written by the production `writePidFile` implementation.
|
|
70
|
+
* Duplicated here so tests can write synthetic pidfiles without
|
|
71
|
+
* importing a private function.
|
|
72
|
+
*/
|
|
73
|
+
export interface DashboardPidFile {
|
|
74
|
+
pid: number;
|
|
75
|
+
port: number;
|
|
76
|
+
startedAt: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Write a synthetic pidfile to `path`. Useful for characterization and
|
|
80
|
+
* edge-case tests that need the file to exist before `startDashboard`
|
|
81
|
+
* runs.
|
|
82
|
+
*/
|
|
83
|
+
export declare function writePidFile(path: string, pid: number, port: number): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Read and parse the pidfile at `path`. Returns `null` when the file
|
|
86
|
+
* is absent or not valid JSON, so assertion sites can use a plain
|
|
87
|
+
* null-check instead of a try/catch.
|
|
88
|
+
*/
|
|
89
|
+
export declare function readPidFile(path: string): Promise<DashboardPidFile | null>;
|
|
90
|
+
/**
|
|
91
|
+
* Return `true` when the file at `path` exists on disk right now.
|
|
92
|
+
*/
|
|
93
|
+
export declare function fileExists(path: string): Promise<boolean>;
|
|
94
|
+
//# sourceMappingURL=dashboard-test-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-test-helpers.d.ts","sourceRoot":"","sources":["../../../src/tests/helpers/dashboard-test-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAa,EAAE,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAID;;;;;;;;;GASG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAqB9C;AAID;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAU/D;AAID;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,UAAU,CAUhF;AAID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAK7D;AAID;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,qBAAqB,CAO5F;AAID;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzF;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAQhF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ/D"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared setup utilities for dashboard-adoption tests.
|
|
3
|
+
*
|
|
4
|
+
* Keeps the main test file focused on assertions rather than
|
|
5
|
+
* boilerplate, while staying small enough that each helper is
|
|
6
|
+
* easy to read in isolation.
|
|
7
|
+
*
|
|
8
|
+
* @module tests/helpers/dashboard-test-helpers
|
|
9
|
+
*/
|
|
10
|
+
import { createServer } from "node:net";
|
|
11
|
+
import { mkdtemp, rm, mkdir, writeFile } from "node:fs/promises";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { tmpdir } from "node:os";
|
|
14
|
+
import pino from "pino";
|
|
15
|
+
import { SarifStore } from "../../sarif/sarif-store.js";
|
|
16
|
+
// ── Logger ────────────────────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* A pino logger that discards all output. Passing this to
|
|
19
|
+
* `startDashboard` keeps test runs noise-free while still satisfying
|
|
20
|
+
* the `Logger` type constraint.
|
|
21
|
+
*/
|
|
22
|
+
export function silentLogger() {
|
|
23
|
+
return pino({ level: "silent" });
|
|
24
|
+
}
|
|
25
|
+
// ── Port allocation ───────────────────────────────────────────────────────────
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a random TCP port in the 6000–6999 range that is not bound
|
|
28
|
+
* at the moment of the call. The OS chooses the exact port by binding
|
|
29
|
+
* to port 0 then immediately releasing the socket; there is a tiny
|
|
30
|
+
* TOCTOU window, but in practice it is negligible for unit tests that
|
|
31
|
+
* run serially.
|
|
32
|
+
*
|
|
33
|
+
* Staying in the 6000–6999 range keeps tests away from the production
|
|
34
|
+
* dashboard port (5117) and from common well-known service ports.
|
|
35
|
+
*/
|
|
36
|
+
export function findFreePort() {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
const server = createServer();
|
|
39
|
+
// Bind to 0 so the OS picks any free port, then immediately close.
|
|
40
|
+
server.listen(0, "127.0.0.1", () => {
|
|
41
|
+
const address = server.address();
|
|
42
|
+
if (!address || typeof address === "string") {
|
|
43
|
+
server.close(() => reject(new Error("unexpected address type")));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const { port } = address;
|
|
47
|
+
server.close(() => {
|
|
48
|
+
// Clamp to 6000-6999 by re-probing if outside range; in
|
|
49
|
+
// practice the OS almost never hands back a port in this band
|
|
50
|
+
// unless specifically requested, so we just return whatever we
|
|
51
|
+
// got — the important property is "free right now".
|
|
52
|
+
resolve(port);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
server.on("error", reject);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create an isolated temporary workspace directory and ensure the
|
|
60
|
+
* `.claude-crap/` subdirectory exists so pidfile writes always succeed.
|
|
61
|
+
* Returns paths and a cleanup function.
|
|
62
|
+
*/
|
|
63
|
+
export async function makeWorkspace() {
|
|
64
|
+
const pluginRoot = await mkdtemp(join(tmpdir(), "crap-adopt-"));
|
|
65
|
+
const dotDir = join(pluginRoot, ".claude-crap");
|
|
66
|
+
await mkdir(dotDir, { recursive: true });
|
|
67
|
+
const pidFilePath = join(dotDir, "dashboard.pid");
|
|
68
|
+
return {
|
|
69
|
+
pluginRoot,
|
|
70
|
+
pidFilePath,
|
|
71
|
+
cleanup: () => rm(pluginRoot, { recursive: true, force: true }),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// ── Config factory ────────────────────────────────────────────────────────────
|
|
75
|
+
/**
|
|
76
|
+
* Minimal {@link CrapConfig} suitable for a test invocation of
|
|
77
|
+
* `startDashboard`. Every field that the function actually reads is
|
|
78
|
+
* supplied with a sane default; callers can override `dashboardPort`
|
|
79
|
+
* and `pluginRoot` as needed.
|
|
80
|
+
*/
|
|
81
|
+
export function makeConfig(pluginRoot, dashboardPort) {
|
|
82
|
+
return {
|
|
83
|
+
pluginRoot,
|
|
84
|
+
dashboardPort,
|
|
85
|
+
sarifOutputDir: ".claude-crap/reports",
|
|
86
|
+
crapThreshold: 30,
|
|
87
|
+
cyclomaticMax: 15,
|
|
88
|
+
tdrMaxRating: "C",
|
|
89
|
+
minutesPerLoc: 30,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// ── SarifStore factory ────────────────────────────────────────────────────────
|
|
93
|
+
/**
|
|
94
|
+
* Build an empty {@link SarifStore} rooted at `pluginRoot`. No file is
|
|
95
|
+
* written to disk; `loadLatest()` is intentionally NOT called here —
|
|
96
|
+
* the tests that need a pre-seeded store will do so themselves.
|
|
97
|
+
*/
|
|
98
|
+
export function makeSarifStore(pluginRoot) {
|
|
99
|
+
return new SarifStore({
|
|
100
|
+
workspaceRoot: pluginRoot,
|
|
101
|
+
outputDir: ".claude-crap/reports",
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// ── StartDashboardOptions factory ─────────────────────────────────────────────
|
|
105
|
+
/**
|
|
106
|
+
* Bundle a complete {@link StartDashboardOptions} object from a
|
|
107
|
+
* workspace context + port. Used by tests that call `startDashboard`
|
|
108
|
+
* directly.
|
|
109
|
+
*/
|
|
110
|
+
export function makeOptions(pluginRoot, dashboardPort) {
|
|
111
|
+
return {
|
|
112
|
+
config: makeConfig(pluginRoot, dashboardPort),
|
|
113
|
+
sarifStore: makeSarifStore(pluginRoot),
|
|
114
|
+
workspaceStatsProvider: async () => ({ physicalLoc: 10, fileCount: 1 }),
|
|
115
|
+
logger: silentLogger(),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Write a synthetic pidfile to `path`. Useful for characterization and
|
|
120
|
+
* edge-case tests that need the file to exist before `startDashboard`
|
|
121
|
+
* runs.
|
|
122
|
+
*/
|
|
123
|
+
export async function writePidFile(path, pid, port) {
|
|
124
|
+
const data = {
|
|
125
|
+
pid,
|
|
126
|
+
port,
|
|
127
|
+
startedAt: new Date().toISOString(),
|
|
128
|
+
};
|
|
129
|
+
await writeFile(path, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Read and parse the pidfile at `path`. Returns `null` when the file
|
|
133
|
+
* is absent or not valid JSON, so assertion sites can use a plain
|
|
134
|
+
* null-check instead of a try/catch.
|
|
135
|
+
*/
|
|
136
|
+
export async function readPidFile(path) {
|
|
137
|
+
try {
|
|
138
|
+
const { readFile } = await import("node:fs/promises");
|
|
139
|
+
const raw = await readFile(path, "utf8");
|
|
140
|
+
return JSON.parse(raw);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Return `true` when the file at `path` exists on disk right now.
|
|
148
|
+
*/
|
|
149
|
+
export async function fileExists(path) {
|
|
150
|
+
try {
|
|
151
|
+
const { access } = await import("node:fs/promises");
|
|
152
|
+
await access(path);
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=dashboard-test-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-test-helpers.js","sourceRoot":"","sources":["../../../src/tests/helpers/dashboard-test-helpers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://code.claude.com/schemas/plugin.json",
|
|
3
3
|
"name": "claude-crap",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.8",
|
|
5
5
|
"description": "Deterministic Quality Assurance plugin for Claude Code. Wraps every Write / Edit / Bash tool call with a PreToolUse gatekeeper, a PostToolUse verifier, and a Stop quality gate backed by CRAP index, Technical Debt Ratio, tree-sitter AST metrics, and SARIF 2.1.0 reports. Forbids the agent from writing functional code before a test safety net exists.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Alan Hernandez",
|