claude-crap 0.1.2
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 +308 -0
- package/LICENSE +21 -0
- package/README.md +550 -0
- package/bin/claude-crap.mjs +141 -0
- package/dist/adapters/bandit.d.ts +48 -0
- package/dist/adapters/bandit.d.ts.map +1 -0
- package/dist/adapters/bandit.js +145 -0
- package/dist/adapters/bandit.js.map +1 -0
- package/dist/adapters/common.d.ts +73 -0
- package/dist/adapters/common.d.ts.map +1 -0
- package/dist/adapters/common.js +78 -0
- package/dist/adapters/common.js.map +1 -0
- package/dist/adapters/eslint.d.ts +52 -0
- package/dist/adapters/eslint.d.ts.map +1 -0
- package/dist/adapters/eslint.js +142 -0
- package/dist/adapters/eslint.js.map +1 -0
- package/dist/adapters/index.d.ts +47 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +64 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/semgrep.d.ts +30 -0
- package/dist/adapters/semgrep.d.ts.map +1 -0
- package/dist/adapters/semgrep.js +130 -0
- package/dist/adapters/semgrep.js.map +1 -0
- package/dist/adapters/stryker.d.ts +55 -0
- package/dist/adapters/stryker.d.ts.map +1 -0
- package/dist/adapters/stryker.js +165 -0
- package/dist/adapters/stryker.js.map +1 -0
- package/dist/ast/cyclomatic.d.ts +48 -0
- package/dist/ast/cyclomatic.d.ts.map +1 -0
- package/dist/ast/cyclomatic.js +106 -0
- package/dist/ast/cyclomatic.js.map +1 -0
- package/dist/ast/index.d.ts +26 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +23 -0
- package/dist/ast/index.js.map +1 -0
- package/dist/ast/language-config.d.ts +70 -0
- package/dist/ast/language-config.d.ts.map +1 -0
- package/dist/ast/language-config.js +192 -0
- package/dist/ast/language-config.js.map +1 -0
- package/dist/ast/tree-sitter-engine.d.ts +133 -0
- package/dist/ast/tree-sitter-engine.d.ts.map +1 -0
- package/dist/ast/tree-sitter-engine.js +270 -0
- package/dist/ast/tree-sitter-engine.js.map +1 -0
- package/dist/config.d.ts +57 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/crap-config.d.ts +97 -0
- package/dist/crap-config.d.ts.map +1 -0
- package/dist/crap-config.js +144 -0
- package/dist/crap-config.js.map +1 -0
- package/dist/dashboard/server.d.ts +65 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +147 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +574 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/crap.d.ts +71 -0
- package/dist/metrics/crap.d.ts.map +1 -0
- package/dist/metrics/crap.js +67 -0
- package/dist/metrics/crap.js.map +1 -0
- package/dist/metrics/index.d.ts +31 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +27 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/score.d.ts +143 -0
- package/dist/metrics/score.d.ts.map +1 -0
- package/dist/metrics/score.js +224 -0
- package/dist/metrics/score.js.map +1 -0
- package/dist/metrics/tdr.d.ts +106 -0
- package/dist/metrics/tdr.d.ts.map +1 -0
- package/dist/metrics/tdr.js +117 -0
- package/dist/metrics/tdr.js.map +1 -0
- package/dist/metrics/workspace-walker.d.ts +43 -0
- package/dist/metrics/workspace-walker.d.ts.map +1 -0
- package/dist/metrics/workspace-walker.js +137 -0
- package/dist/metrics/workspace-walker.js.map +1 -0
- package/dist/sarif/index.d.ts +21 -0
- package/dist/sarif/index.d.ts.map +1 -0
- package/dist/sarif/index.js +19 -0
- package/dist/sarif/index.js.map +1 -0
- package/dist/sarif/sarif-builder.d.ts +128 -0
- package/dist/sarif/sarif-builder.d.ts.map +1 -0
- package/dist/sarif/sarif-builder.js +79 -0
- package/dist/sarif/sarif-builder.js.map +1 -0
- package/dist/sarif/sarif-store.d.ts +205 -0
- package/dist/sarif/sarif-store.d.ts.map +1 -0
- package/dist/sarif/sarif-store.js +246 -0
- package/dist/sarif/sarif-store.js.map +1 -0
- package/dist/sarif/sarif-validator.d.ts +45 -0
- package/dist/sarif/sarif-validator.d.ts.map +1 -0
- package/dist/sarif/sarif-validator.js +138 -0
- package/dist/sarif/sarif-validator.js.map +1 -0
- package/dist/schemas/tool-schemas.d.ts +216 -0
- package/dist/schemas/tool-schemas.d.ts.map +1 -0
- package/dist/schemas/tool-schemas.js +208 -0
- package/dist/schemas/tool-schemas.js.map +1 -0
- package/dist/sdk.d.ts +45 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +44 -0
- package/dist/sdk.js.map +1 -0
- package/dist/tools/index.d.ts +24 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +23 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/test-harness.d.ts +75 -0
- package/dist/tools/test-harness.d.ts.map +1 -0
- package/dist/tools/test-harness.js +137 -0
- package/dist/tools/test-harness.js.map +1 -0
- package/dist/workspace-guard.d.ts +53 -0
- package/dist/workspace-guard.d.ts.map +1 -0
- package/dist/workspace-guard.js +61 -0
- package/dist/workspace-guard.js.map +1 -0
- package/package.json +133 -0
- package/plugin/.claude-plugin/plugin.json +29 -0
- package/plugin/.mcp.json +18 -0
- package/plugin/CLAUDE.md +143 -0
- package/plugin/bundle/dashboard/public/index.html +368 -0
- package/plugin/bundle/dashboard/public/vendor/vue.global.prod.js +9 -0
- package/plugin/bundle/mcp-server.mjs +8718 -0
- package/plugin/bundle/mcp-server.mjs.map +7 -0
- package/plugin/bundle/tdr-engine.mjs +50 -0
- package/plugin/bundle/tdr-engine.mjs.map +7 -0
- package/plugin/hooks/hooks.json +62 -0
- package/plugin/hooks/lib/crap-config.mjs +152 -0
- package/plugin/hooks/lib/gatekeeper-rules.mjs +257 -0
- package/plugin/hooks/lib/hook-io.mjs +151 -0
- package/plugin/hooks/lib/quality-gate.mjs +329 -0
- package/plugin/hooks/lib/test-harness.mjs +152 -0
- package/plugin/hooks/post-tool-use.mjs +245 -0
- package/plugin/hooks/pre-tool-use.mjs +290 -0
- package/plugin/hooks/session-start.mjs +109 -0
- package/plugin/hooks/stop-quality-gate.mjs +226 -0
- package/plugin/package.json +18 -0
- package/plugin/skills/adopt/SKILL.md +74 -0
- package/plugin/skills/analyze/SKILL.md +77 -0
- package/plugin/skills/check-test/SKILL.md +50 -0
- package/plugin/skills/score/SKILL.md +31 -0
- package/scripts/bug-report.mjs +328 -0
- package/scripts/build-fast.mjs +130 -0
- package/scripts/bundle-plugin.mjs +74 -0
- package/scripts/doctor.mjs +320 -0
- package/scripts/install.mjs +192 -0
- package/scripts/lib/cli-ui.mjs +122 -0
- package/scripts/postinstall.mjs +127 -0
- package/scripts/run-tests.mjs +95 -0
- package/scripts/status.mjs +110 -0
- package/scripts/uninstall.mjs +72 -0
- package/src/adapters/bandit.ts +191 -0
- package/src/adapters/common.ts +133 -0
- package/src/adapters/eslint.ts +187 -0
- package/src/adapters/index.ts +78 -0
- package/src/adapters/semgrep.ts +150 -0
- package/src/adapters/stryker.ts +218 -0
- package/src/ast/cyclomatic.ts +131 -0
- package/src/ast/index.ts +33 -0
- package/src/ast/language-config.ts +231 -0
- package/src/ast/tree-sitter-engine.ts +385 -0
- package/src/config.ts +109 -0
- package/src/crap-config.ts +196 -0
- package/src/dashboard/public/index.html +368 -0
- package/src/dashboard/public/vendor/vue.global.prod.js +9 -0
- package/src/dashboard/server.ts +205 -0
- package/src/index.ts +696 -0
- package/src/metrics/crap.ts +101 -0
- package/src/metrics/index.ts +51 -0
- package/src/metrics/score.ts +329 -0
- package/src/metrics/tdr.ts +155 -0
- package/src/metrics/workspace-walker.ts +146 -0
- package/src/sarif/index.ts +31 -0
- package/src/sarif/sarif-builder.ts +139 -0
- package/src/sarif/sarif-store.ts +347 -0
- package/src/sarif/sarif-validator.ts +145 -0
- package/src/schemas/tool-schemas.ts +225 -0
- package/src/sdk.ts +110 -0
- package/src/tests/adapters/bandit.test.ts +111 -0
- package/src/tests/adapters/dispatch.test.ts +100 -0
- package/src/tests/adapters/eslint.test.ts +138 -0
- package/src/tests/adapters/semgrep.test.ts +125 -0
- package/src/tests/adapters/stryker.test.ts +103 -0
- package/src/tests/crap-config.test.ts +228 -0
- package/src/tests/crap.test.ts +59 -0
- package/src/tests/cyclomatic.test.ts +87 -0
- package/src/tests/dashboard-http.test.ts +108 -0
- package/src/tests/dashboard-integrity.test.ts +128 -0
- package/src/tests/integration/mcp-server.integration.test.ts +352 -0
- package/src/tests/pre-tool-use-hook.test.ts +178 -0
- package/src/tests/sarif-store.test.ts +241 -0
- package/src/tests/sarif-validator.test.ts +164 -0
- package/src/tests/score.test.ts +260 -0
- package/src/tests/skills-frontmatter.test.ts +172 -0
- package/src/tests/stop-quality-gate-strictness.test.ts +243 -0
- package/src/tests/tdr.test.ts +86 -0
- package/src/tests/test-harness.test.ts +153 -0
- package/src/tests/workspace-guard.test.ts +111 -0
- package/src/tools/index.ts +24 -0
- package/src/tools/test-harness.ts +158 -0
- package/src/workspace-guard.ts +64 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crap-config.js","sourceRoot":"","sources":["../src/crap-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Vue.js dashboard for claude-crap — Fastify HTTP server.
|
|
3
|
+
*
|
|
4
|
+
* The dashboard runs in the same Node.js process as the MCP server,
|
|
5
|
+
* but on a separate TCP port (default 5117). It exposes:
|
|
6
|
+
*
|
|
7
|
+
* GET / → static index.html (Vue 3 SPA from CDN)
|
|
8
|
+
* GET /api/score → live ProjectScore JSON from the score engine
|
|
9
|
+
* GET /api/sarif → consolidated SARIF 2.1.0 document
|
|
10
|
+
* GET /api/health → simple {status:"ok"} liveness probe
|
|
11
|
+
*
|
|
12
|
+
* The server binds to `127.0.0.1` only — never to `0.0.0.0` — so the
|
|
13
|
+
* dashboard cannot be reached from outside the developer's machine.
|
|
14
|
+
*
|
|
15
|
+
* If the configured port is already in use (or the bind otherwise
|
|
16
|
+
* fails), `startDashboard()` rejects gracefully and the caller falls
|
|
17
|
+
* back to "no dashboard". The MCP server will keep running.
|
|
18
|
+
*
|
|
19
|
+
* IMPORTANT: this module never writes to stdout. The MCP stdio
|
|
20
|
+
* transport reserves stdout for JSON-RPC framing, so all logs and
|
|
21
|
+
* errors here go through the same pino-on-stderr instance the rest of
|
|
22
|
+
* the server uses.
|
|
23
|
+
*
|
|
24
|
+
* @module dashboard/server
|
|
25
|
+
*/
|
|
26
|
+
import type { Logger } from "pino";
|
|
27
|
+
import type { CrapConfig } from "../config.js";
|
|
28
|
+
import { type WorkspaceStats } from "../metrics/score.js";
|
|
29
|
+
import type { SarifStore } from "../sarif/sarif-store.js";
|
|
30
|
+
/**
|
|
31
|
+
* Callback used by the dashboard to refresh workspace LOC stats on
|
|
32
|
+
* every score request. The MCP server provides this so the dashboard
|
|
33
|
+
* does not have to know how to walk the disk itself.
|
|
34
|
+
*/
|
|
35
|
+
export type WorkspaceStatsProvider = () => Promise<WorkspaceStats>;
|
|
36
|
+
/**
|
|
37
|
+
* Inputs accepted by {@link startDashboard}.
|
|
38
|
+
*/
|
|
39
|
+
export interface StartDashboardOptions {
|
|
40
|
+
/** Fully resolved server configuration. */
|
|
41
|
+
readonly config: CrapConfig;
|
|
42
|
+
/** Live SARIF store the dashboard reads findings from. */
|
|
43
|
+
readonly sarifStore: SarifStore;
|
|
44
|
+
/** Function that returns up-to-date LOC + file count for the workspace. */
|
|
45
|
+
readonly workspaceStatsProvider: WorkspaceStatsProvider;
|
|
46
|
+
/** Pino logger from the MCP server (writes to stderr). */
|
|
47
|
+
readonly logger: Logger;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Handle returned by {@link startDashboard}. Use `url` to build the
|
|
51
|
+
* link the user clicks; call `close()` during shutdown.
|
|
52
|
+
*/
|
|
53
|
+
export interface DashboardHandle {
|
|
54
|
+
readonly url: string;
|
|
55
|
+
close(): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Boot the Fastify dashboard server. Resolves with a {@link DashboardHandle}
|
|
59
|
+
* once the server is listening, or rejects when the bind fails (caller
|
|
60
|
+
* should treat that as a non-fatal degradation).
|
|
61
|
+
*
|
|
62
|
+
* @param options Configuration, store, and provider callback.
|
|
63
|
+
*/
|
|
64
|
+
export declare function startDashboard(options: StartDashboardOptions): Promise<DashboardHandle>;
|
|
65
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +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;AAC/C,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;;;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;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAqD7F"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Vue.js dashboard for claude-crap — Fastify HTTP server.
|
|
3
|
+
*
|
|
4
|
+
* The dashboard runs in the same Node.js process as the MCP server,
|
|
5
|
+
* but on a separate TCP port (default 5117). It exposes:
|
|
6
|
+
*
|
|
7
|
+
* GET / → static index.html (Vue 3 SPA from CDN)
|
|
8
|
+
* GET /api/score → live ProjectScore JSON from the score engine
|
|
9
|
+
* GET /api/sarif → consolidated SARIF 2.1.0 document
|
|
10
|
+
* GET /api/health → simple {status:"ok"} liveness probe
|
|
11
|
+
*
|
|
12
|
+
* The server binds to `127.0.0.1` only — never to `0.0.0.0` — so the
|
|
13
|
+
* dashboard cannot be reached from outside the developer's machine.
|
|
14
|
+
*
|
|
15
|
+
* If the configured port is already in use (or the bind otherwise
|
|
16
|
+
* fails), `startDashboard()` rejects gracefully and the caller falls
|
|
17
|
+
* back to "no dashboard". The MCP server will keep running.
|
|
18
|
+
*
|
|
19
|
+
* IMPORTANT: this module never writes to stdout. The MCP stdio
|
|
20
|
+
* transport reserves stdout for JSON-RPC framing, so all logs and
|
|
21
|
+
* errors here go through the same pino-on-stderr instance the rest of
|
|
22
|
+
* the server uses.
|
|
23
|
+
*
|
|
24
|
+
* @module dashboard/server
|
|
25
|
+
*/
|
|
26
|
+
import { promises as fs } from "node:fs";
|
|
27
|
+
import { dirname, resolve } from "node:path";
|
|
28
|
+
import { fileURLToPath } from "node:url";
|
|
29
|
+
import Fastify from "fastify";
|
|
30
|
+
import fastifyStatic from "@fastify/static";
|
|
31
|
+
import { computeProjectScore, } from "../metrics/score.js";
|
|
32
|
+
/**
|
|
33
|
+
* Boot the Fastify dashboard server. Resolves with a {@link DashboardHandle}
|
|
34
|
+
* once the server is listening, or rejects when the bind fails (caller
|
|
35
|
+
* should treat that as a non-fatal degradation).
|
|
36
|
+
*
|
|
37
|
+
* @param options Configuration, store, and provider callback.
|
|
38
|
+
*/
|
|
39
|
+
export async function startDashboard(options) {
|
|
40
|
+
const { config, sarifStore, workspaceStatsProvider, logger } = options;
|
|
41
|
+
// Resolve the public/ directory. After `npm run build` the compiled
|
|
42
|
+
// server lives in `dist/dashboard/server.js`, but we keep the static
|
|
43
|
+
// SPA assets in `src/dashboard/public/` so we don't need a postbuild
|
|
44
|
+
// copy step. We probe both candidate locations in priority order.
|
|
45
|
+
const publicRoot = await resolvePublicRoot(logger);
|
|
46
|
+
const fastify = Fastify({
|
|
47
|
+
logger: false, // we route everything through pino-on-stderr ourselves
|
|
48
|
+
disableRequestLogging: true,
|
|
49
|
+
});
|
|
50
|
+
await fastify.register(fastifyStatic, {
|
|
51
|
+
root: publicRoot,
|
|
52
|
+
prefix: "/",
|
|
53
|
+
decorateReply: false,
|
|
54
|
+
});
|
|
55
|
+
// ------------------------------------------------------------------
|
|
56
|
+
// /api/health — liveness probe
|
|
57
|
+
// ------------------------------------------------------------------
|
|
58
|
+
fastify.get("/api/health", async () => ({ status: "ok", server: "claude-crap", version: "0.1.0" }));
|
|
59
|
+
// ------------------------------------------------------------------
|
|
60
|
+
// /api/score — live project score
|
|
61
|
+
// ------------------------------------------------------------------
|
|
62
|
+
fastify.get("/api/score", async () => {
|
|
63
|
+
const stats = await workspaceStatsProvider();
|
|
64
|
+
const score = await buildScore(config, sarifStore, stats, urlOf(fastify, config));
|
|
65
|
+
return score;
|
|
66
|
+
});
|
|
67
|
+
// ------------------------------------------------------------------
|
|
68
|
+
// /api/sarif — consolidated SARIF 2.1.0 document
|
|
69
|
+
// ------------------------------------------------------------------
|
|
70
|
+
fastify.get("/api/sarif", async () => sarifStore.toSarifDocument());
|
|
71
|
+
// ------------------------------------------------------------------
|
|
72
|
+
// / — static SPA fallback (Fastify-static handles index.html)
|
|
73
|
+
// ------------------------------------------------------------------
|
|
74
|
+
await fastify.listen({ port: config.dashboardPort, host: "127.0.0.1" });
|
|
75
|
+
const url = `http://127.0.0.1:${config.dashboardPort}`;
|
|
76
|
+
logger.info({ url, publicRoot }, "claude-crap dashboard listening");
|
|
77
|
+
return {
|
|
78
|
+
url,
|
|
79
|
+
async close() {
|
|
80
|
+
await fastify.close();
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Probe the candidate public/ directories in priority order and return
|
|
86
|
+
* the first one that contains an `index.html`. Throws when none of the
|
|
87
|
+
* candidates exist — that points at a packaging mistake the developer
|
|
88
|
+
* should fix immediately.
|
|
89
|
+
*
|
|
90
|
+
* @param logger Pino instance for diagnostics.
|
|
91
|
+
*/
|
|
92
|
+
async function resolvePublicRoot(logger) {
|
|
93
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
94
|
+
const candidates = [
|
|
95
|
+
// 0. Bundled layout: plugin/bundle/mcp-server.mjs → ./dashboard/public
|
|
96
|
+
resolve(here, "dashboard", "public"),
|
|
97
|
+
// 1. Compiled layout: dist/dashboard/server.js → ./public next to it
|
|
98
|
+
// (only present if a build step copies the assets — not used
|
|
99
|
+
// today, but accepted so a future copy step does not break us).
|
|
100
|
+
resolve(here, "public"),
|
|
101
|
+
// 2. Source-relative layout: dist/dashboard/server.js → ../../src/dashboard/public
|
|
102
|
+
// This is the default — no copy step required because we resolve
|
|
103
|
+
// upward from `dist/` into `src/` at runtime.
|
|
104
|
+
resolve(here, "..", "..", "src", "dashboard", "public"),
|
|
105
|
+
];
|
|
106
|
+
for (const candidate of candidates) {
|
|
107
|
+
try {
|
|
108
|
+
await fs.access(resolve(candidate, "index.html"));
|
|
109
|
+
return candidate;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// probe next
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
logger.error({ candidates }, "dashboard public/ directory not found");
|
|
116
|
+
throw new Error(`[claude-crap] dashboard: index.html not found in any of ${candidates.join(", ")}`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolve the canonical dashboard URL using the live Fastify address
|
|
120
|
+
* info. Falls back to the configured port when the address info is
|
|
121
|
+
* not yet available (e.g. on the very first request during startup).
|
|
122
|
+
*/
|
|
123
|
+
function urlOf(fastify, config) {
|
|
124
|
+
const addresses = fastify.addresses?.() ?? [];
|
|
125
|
+
const first = addresses[0];
|
|
126
|
+
if (first) {
|
|
127
|
+
const host = first.address === "::" || first.address === "0.0.0.0" ? "127.0.0.1" : first.address;
|
|
128
|
+
return `http://${host}:${first.port}`;
|
|
129
|
+
}
|
|
130
|
+
return `http://127.0.0.1:${config.dashboardPort}`;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Wrap {@link computeProjectScore} so the dashboard endpoint can call
|
|
134
|
+
* it with the live store and provide consistent location metadata.
|
|
135
|
+
*/
|
|
136
|
+
async function buildScore(config, sarifStore, workspace, dashboardUrl) {
|
|
137
|
+
return computeProjectScore({
|
|
138
|
+
workspaceRoot: config.pluginRoot,
|
|
139
|
+
minutesPerLoc: config.minutesPerLoc,
|
|
140
|
+
tdrMaxRating: config.tdrMaxRating,
|
|
141
|
+
workspace,
|
|
142
|
+
sarifStore,
|
|
143
|
+
dashboardUrl,
|
|
144
|
+
sarifReportPath: sarifStore.consolidatedReportPath,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* claude-crap MCP server — entrypoint.
|
|
4
|
+
*
|
|
5
|
+
* Transport: stdio. The server is launched by `.mcp.json` with the
|
|
6
|
+
* arguments `--transport stdio` and it never opens sockets or listens
|
|
7
|
+
* on the network: all communication with Claude Code happens over
|
|
8
|
+
* stdin/stdout as JSON-RPC messages.
|
|
9
|
+
*
|
|
10
|
+
* What this file wires together:
|
|
11
|
+
*
|
|
12
|
+
* Tools:
|
|
13
|
+
* - compute_crap (CRAP index for one function)
|
|
14
|
+
* - compute_tdr (Technical Debt Ratio for a scope)
|
|
15
|
+
* - analyze_file_ast (tree-sitter AST metrics for a source file)
|
|
16
|
+
* - ingest_sarif (normalize + dedupe an external SARIF report)
|
|
17
|
+
* - ingest_scanner_output (route Semgrep/ESLint/Bandit/Stryker native output through an adapter and persist the normalized SARIF)
|
|
18
|
+
* - require_test_harness (check that a production source file has a matching test)
|
|
19
|
+
* - score_project (aggregate the workspace into Maintainability / Reliability / Security / Overall ratings)
|
|
20
|
+
*
|
|
21
|
+
* Resources:
|
|
22
|
+
* - sonar://metrics/current (live CRAP / TDR / rating snapshot)
|
|
23
|
+
* - sonar://reports/latest.sarif (last consolidated SARIF document)
|
|
24
|
+
*
|
|
25
|
+
* The handlers delegate to pure engines in `./metrics`, `./ast` and
|
|
26
|
+
* `./sarif`, so the index file stays focused on routing and
|
|
27
|
+
* cross-cutting concerns (configuration, logging, error boundaries).
|
|
28
|
+
*
|
|
29
|
+
* @module index
|
|
30
|
+
*/
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG"}
|