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.
Files changed (202) hide show
  1. package/CHANGELOG.md +308 -0
  2. package/LICENSE +21 -0
  3. package/README.md +550 -0
  4. package/bin/claude-crap.mjs +141 -0
  5. package/dist/adapters/bandit.d.ts +48 -0
  6. package/dist/adapters/bandit.d.ts.map +1 -0
  7. package/dist/adapters/bandit.js +145 -0
  8. package/dist/adapters/bandit.js.map +1 -0
  9. package/dist/adapters/common.d.ts +73 -0
  10. package/dist/adapters/common.d.ts.map +1 -0
  11. package/dist/adapters/common.js +78 -0
  12. package/dist/adapters/common.js.map +1 -0
  13. package/dist/adapters/eslint.d.ts +52 -0
  14. package/dist/adapters/eslint.d.ts.map +1 -0
  15. package/dist/adapters/eslint.js +142 -0
  16. package/dist/adapters/eslint.js.map +1 -0
  17. package/dist/adapters/index.d.ts +47 -0
  18. package/dist/adapters/index.d.ts.map +1 -0
  19. package/dist/adapters/index.js +64 -0
  20. package/dist/adapters/index.js.map +1 -0
  21. package/dist/adapters/semgrep.d.ts +30 -0
  22. package/dist/adapters/semgrep.d.ts.map +1 -0
  23. package/dist/adapters/semgrep.js +130 -0
  24. package/dist/adapters/semgrep.js.map +1 -0
  25. package/dist/adapters/stryker.d.ts +55 -0
  26. package/dist/adapters/stryker.d.ts.map +1 -0
  27. package/dist/adapters/stryker.js +165 -0
  28. package/dist/adapters/stryker.js.map +1 -0
  29. package/dist/ast/cyclomatic.d.ts +48 -0
  30. package/dist/ast/cyclomatic.d.ts.map +1 -0
  31. package/dist/ast/cyclomatic.js +106 -0
  32. package/dist/ast/cyclomatic.js.map +1 -0
  33. package/dist/ast/index.d.ts +26 -0
  34. package/dist/ast/index.d.ts.map +1 -0
  35. package/dist/ast/index.js +23 -0
  36. package/dist/ast/index.js.map +1 -0
  37. package/dist/ast/language-config.d.ts +70 -0
  38. package/dist/ast/language-config.d.ts.map +1 -0
  39. package/dist/ast/language-config.js +192 -0
  40. package/dist/ast/language-config.js.map +1 -0
  41. package/dist/ast/tree-sitter-engine.d.ts +133 -0
  42. package/dist/ast/tree-sitter-engine.d.ts.map +1 -0
  43. package/dist/ast/tree-sitter-engine.js +270 -0
  44. package/dist/ast/tree-sitter-engine.js.map +1 -0
  45. package/dist/config.d.ts +57 -0
  46. package/dist/config.d.ts.map +1 -0
  47. package/dist/config.js +78 -0
  48. package/dist/config.js.map +1 -0
  49. package/dist/crap-config.d.ts +97 -0
  50. package/dist/crap-config.d.ts.map +1 -0
  51. package/dist/crap-config.js +144 -0
  52. package/dist/crap-config.js.map +1 -0
  53. package/dist/dashboard/server.d.ts +65 -0
  54. package/dist/dashboard/server.d.ts.map +1 -0
  55. package/dist/dashboard/server.js +147 -0
  56. package/dist/dashboard/server.js.map +1 -0
  57. package/dist/index.d.ts +32 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +574 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/metrics/crap.d.ts +71 -0
  62. package/dist/metrics/crap.d.ts.map +1 -0
  63. package/dist/metrics/crap.js +67 -0
  64. package/dist/metrics/crap.js.map +1 -0
  65. package/dist/metrics/index.d.ts +31 -0
  66. package/dist/metrics/index.d.ts.map +1 -0
  67. package/dist/metrics/index.js +27 -0
  68. package/dist/metrics/index.js.map +1 -0
  69. package/dist/metrics/score.d.ts +143 -0
  70. package/dist/metrics/score.d.ts.map +1 -0
  71. package/dist/metrics/score.js +224 -0
  72. package/dist/metrics/score.js.map +1 -0
  73. package/dist/metrics/tdr.d.ts +106 -0
  74. package/dist/metrics/tdr.d.ts.map +1 -0
  75. package/dist/metrics/tdr.js +117 -0
  76. package/dist/metrics/tdr.js.map +1 -0
  77. package/dist/metrics/workspace-walker.d.ts +43 -0
  78. package/dist/metrics/workspace-walker.d.ts.map +1 -0
  79. package/dist/metrics/workspace-walker.js +137 -0
  80. package/dist/metrics/workspace-walker.js.map +1 -0
  81. package/dist/sarif/index.d.ts +21 -0
  82. package/dist/sarif/index.d.ts.map +1 -0
  83. package/dist/sarif/index.js +19 -0
  84. package/dist/sarif/index.js.map +1 -0
  85. package/dist/sarif/sarif-builder.d.ts +128 -0
  86. package/dist/sarif/sarif-builder.d.ts.map +1 -0
  87. package/dist/sarif/sarif-builder.js +79 -0
  88. package/dist/sarif/sarif-builder.js.map +1 -0
  89. package/dist/sarif/sarif-store.d.ts +205 -0
  90. package/dist/sarif/sarif-store.d.ts.map +1 -0
  91. package/dist/sarif/sarif-store.js +246 -0
  92. package/dist/sarif/sarif-store.js.map +1 -0
  93. package/dist/sarif/sarif-validator.d.ts +45 -0
  94. package/dist/sarif/sarif-validator.d.ts.map +1 -0
  95. package/dist/sarif/sarif-validator.js +138 -0
  96. package/dist/sarif/sarif-validator.js.map +1 -0
  97. package/dist/schemas/tool-schemas.d.ts +216 -0
  98. package/dist/schemas/tool-schemas.d.ts.map +1 -0
  99. package/dist/schemas/tool-schemas.js +208 -0
  100. package/dist/schemas/tool-schemas.js.map +1 -0
  101. package/dist/sdk.d.ts +45 -0
  102. package/dist/sdk.d.ts.map +1 -0
  103. package/dist/sdk.js +44 -0
  104. package/dist/sdk.js.map +1 -0
  105. package/dist/tools/index.d.ts +24 -0
  106. package/dist/tools/index.d.ts.map +1 -0
  107. package/dist/tools/index.js +23 -0
  108. package/dist/tools/index.js.map +1 -0
  109. package/dist/tools/test-harness.d.ts +75 -0
  110. package/dist/tools/test-harness.d.ts.map +1 -0
  111. package/dist/tools/test-harness.js +137 -0
  112. package/dist/tools/test-harness.js.map +1 -0
  113. package/dist/workspace-guard.d.ts +53 -0
  114. package/dist/workspace-guard.d.ts.map +1 -0
  115. package/dist/workspace-guard.js +61 -0
  116. package/dist/workspace-guard.js.map +1 -0
  117. package/package.json +133 -0
  118. package/plugin/.claude-plugin/plugin.json +29 -0
  119. package/plugin/.mcp.json +18 -0
  120. package/plugin/CLAUDE.md +143 -0
  121. package/plugin/bundle/dashboard/public/index.html +368 -0
  122. package/plugin/bundle/dashboard/public/vendor/vue.global.prod.js +9 -0
  123. package/plugin/bundle/mcp-server.mjs +8718 -0
  124. package/plugin/bundle/mcp-server.mjs.map +7 -0
  125. package/plugin/bundle/tdr-engine.mjs +50 -0
  126. package/plugin/bundle/tdr-engine.mjs.map +7 -0
  127. package/plugin/hooks/hooks.json +62 -0
  128. package/plugin/hooks/lib/crap-config.mjs +152 -0
  129. package/plugin/hooks/lib/gatekeeper-rules.mjs +257 -0
  130. package/plugin/hooks/lib/hook-io.mjs +151 -0
  131. package/plugin/hooks/lib/quality-gate.mjs +329 -0
  132. package/plugin/hooks/lib/test-harness.mjs +152 -0
  133. package/plugin/hooks/post-tool-use.mjs +245 -0
  134. package/plugin/hooks/pre-tool-use.mjs +290 -0
  135. package/plugin/hooks/session-start.mjs +109 -0
  136. package/plugin/hooks/stop-quality-gate.mjs +226 -0
  137. package/plugin/package.json +18 -0
  138. package/plugin/skills/adopt/SKILL.md +74 -0
  139. package/plugin/skills/analyze/SKILL.md +77 -0
  140. package/plugin/skills/check-test/SKILL.md +50 -0
  141. package/plugin/skills/score/SKILL.md +31 -0
  142. package/scripts/bug-report.mjs +328 -0
  143. package/scripts/build-fast.mjs +130 -0
  144. package/scripts/bundle-plugin.mjs +74 -0
  145. package/scripts/doctor.mjs +320 -0
  146. package/scripts/install.mjs +192 -0
  147. package/scripts/lib/cli-ui.mjs +122 -0
  148. package/scripts/postinstall.mjs +127 -0
  149. package/scripts/run-tests.mjs +95 -0
  150. package/scripts/status.mjs +110 -0
  151. package/scripts/uninstall.mjs +72 -0
  152. package/src/adapters/bandit.ts +191 -0
  153. package/src/adapters/common.ts +133 -0
  154. package/src/adapters/eslint.ts +187 -0
  155. package/src/adapters/index.ts +78 -0
  156. package/src/adapters/semgrep.ts +150 -0
  157. package/src/adapters/stryker.ts +218 -0
  158. package/src/ast/cyclomatic.ts +131 -0
  159. package/src/ast/index.ts +33 -0
  160. package/src/ast/language-config.ts +231 -0
  161. package/src/ast/tree-sitter-engine.ts +385 -0
  162. package/src/config.ts +109 -0
  163. package/src/crap-config.ts +196 -0
  164. package/src/dashboard/public/index.html +368 -0
  165. package/src/dashboard/public/vendor/vue.global.prod.js +9 -0
  166. package/src/dashboard/server.ts +205 -0
  167. package/src/index.ts +696 -0
  168. package/src/metrics/crap.ts +101 -0
  169. package/src/metrics/index.ts +51 -0
  170. package/src/metrics/score.ts +329 -0
  171. package/src/metrics/tdr.ts +155 -0
  172. package/src/metrics/workspace-walker.ts +146 -0
  173. package/src/sarif/index.ts +31 -0
  174. package/src/sarif/sarif-builder.ts +139 -0
  175. package/src/sarif/sarif-store.ts +347 -0
  176. package/src/sarif/sarif-validator.ts +145 -0
  177. package/src/schemas/tool-schemas.ts +225 -0
  178. package/src/sdk.ts +110 -0
  179. package/src/tests/adapters/bandit.test.ts +111 -0
  180. package/src/tests/adapters/dispatch.test.ts +100 -0
  181. package/src/tests/adapters/eslint.test.ts +138 -0
  182. package/src/tests/adapters/semgrep.test.ts +125 -0
  183. package/src/tests/adapters/stryker.test.ts +103 -0
  184. package/src/tests/crap-config.test.ts +228 -0
  185. package/src/tests/crap.test.ts +59 -0
  186. package/src/tests/cyclomatic.test.ts +87 -0
  187. package/src/tests/dashboard-http.test.ts +108 -0
  188. package/src/tests/dashboard-integrity.test.ts +128 -0
  189. package/src/tests/integration/mcp-server.integration.test.ts +352 -0
  190. package/src/tests/pre-tool-use-hook.test.ts +178 -0
  191. package/src/tests/sarif-store.test.ts +241 -0
  192. package/src/tests/sarif-validator.test.ts +164 -0
  193. package/src/tests/score.test.ts +260 -0
  194. package/src/tests/skills-frontmatter.test.ts +172 -0
  195. package/src/tests/stop-quality-gate-strictness.test.ts +243 -0
  196. package/src/tests/tdr.test.ts +86 -0
  197. package/src/tests/test-harness.test.ts +153 -0
  198. package/src/tests/workspace-guard.test.ts +111 -0
  199. package/src/tools/index.ts +24 -0
  200. package/src/tools/test-harness.ts +158 -0
  201. package/src/workspace-guard.ts +64 -0
  202. package/tsconfig.json +27 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Bandit adapter.
3
+ *
4
+ * Bandit is a Python security linter. When run with `-f json` it
5
+ * emits a JSON report shaped like this (abbreviated):
6
+ *
7
+ * {
8
+ * "results": [
9
+ * {
10
+ * "filename": "app.py",
11
+ * "line_number": 42,
12
+ * "col_offset": 5,
13
+ * "test_id": "B608",
14
+ * "test_name": "hardcoded_sql_expressions",
15
+ * "issue_severity": "HIGH", // LOW | MEDIUM | HIGH
16
+ * "issue_confidence": "HIGH", // LOW | MEDIUM | HIGH
17
+ * "issue_text": "Possible SQL injection via string-based query construction.",
18
+ * "issue_cwe": { "id": 89 }
19
+ * }
20
+ * ],
21
+ * "metrics": { ... },
22
+ * "errors": [ ... ]
23
+ * }
24
+ *
25
+ * This adapter converts each `results[]` entry into a SARIF 2.1.0
26
+ * `result`, mapping Bandit severity levels to SARIF levels:
27
+ *
28
+ * LOW → "note"
29
+ * MEDIUM → "warning"
30
+ * HIGH → "error"
31
+ *
32
+ * Every finding gets a rule id of `bandit.<test_id>` (e.g.
33
+ * `bandit.B608`) so it is trivial to correlate with Bandit's own docs
34
+ * from inside the claude-crap dashboard.
35
+ *
36
+ * @module adapters/bandit
37
+ */
38
+ import { type AdapterResult } from "./common.js";
39
+ /**
40
+ * Accept a Bandit JSON report and return a normalized
41
+ * `PersistedSarif` document.
42
+ *
43
+ * @param input Raw Bandit JSON (string or parsed object).
44
+ * @returns Adapter result.
45
+ * @throws When the input does not look like a Bandit report.
46
+ */
47
+ export declare function adaptBandit(input: unknown): AdapterResult;
48
+ //# sourceMappingURL=bandit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bandit.d.ts","sourceRoot":"","sources":["../../src/adapters/bandit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAC;AAoBrB;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CA6DzD"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Bandit adapter.
3
+ *
4
+ * Bandit is a Python security linter. When run with `-f json` it
5
+ * emits a JSON report shaped like this (abbreviated):
6
+ *
7
+ * {
8
+ * "results": [
9
+ * {
10
+ * "filename": "app.py",
11
+ * "line_number": 42,
12
+ * "col_offset": 5,
13
+ * "test_id": "B608",
14
+ * "test_name": "hardcoded_sql_expressions",
15
+ * "issue_severity": "HIGH", // LOW | MEDIUM | HIGH
16
+ * "issue_confidence": "HIGH", // LOW | MEDIUM | HIGH
17
+ * "issue_text": "Possible SQL injection via string-based query construction.",
18
+ * "issue_cwe": { "id": 89 }
19
+ * }
20
+ * ],
21
+ * "metrics": { ... },
22
+ * "errors": [ ... ]
23
+ * }
24
+ *
25
+ * This adapter converts each `results[]` entry into a SARIF 2.1.0
26
+ * `result`, mapping Bandit severity levels to SARIF levels:
27
+ *
28
+ * LOW → "note"
29
+ * MEDIUM → "warning"
30
+ * HIGH → "error"
31
+ *
32
+ * Every finding gets a rule id of `bandit.<test_id>` (e.g.
33
+ * `bandit.B608`) so it is trivial to correlate with Bandit's own docs
34
+ * from inside the claude-crap dashboard.
35
+ *
36
+ * @module adapters/bandit
37
+ */
38
+ import { estimateEffortMinutes, wrapResultsInSarif, } from "./common.js";
39
+ const BANDIT = "bandit";
40
+ /**
41
+ * Accept a Bandit JSON report and return a normalized
42
+ * `PersistedSarif` document.
43
+ *
44
+ * @param input Raw Bandit JSON (string or parsed object).
45
+ * @returns Adapter result.
46
+ * @throws When the input does not look like a Bandit report.
47
+ */
48
+ export function adaptBandit(input) {
49
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
50
+ if (!parsed || typeof parsed !== "object") {
51
+ throw new Error(`[adapter:bandit] expected a JSON object`);
52
+ }
53
+ const report = parsed;
54
+ if (!Array.isArray(report.results)) {
55
+ throw new Error(`[adapter:bandit] report is missing a results[] array`);
56
+ }
57
+ const results = [];
58
+ let totalEffortMinutes = 0;
59
+ for (const finding of report.results) {
60
+ const filename = finding.filename;
61
+ if (typeof filename !== "string" || !filename)
62
+ continue;
63
+ const level = mapSeverity(finding.issue_severity);
64
+ // High-severity security findings cost more to fix than the
65
+ // generic default, so we bias the budget toward reality. Bandit
66
+ // is always security-focused, so every finding is treated as a
67
+ // security issue for TDR accounting downstream.
68
+ const effortOverride = level === "error" ? 120 : level === "warning" ? 60 : 20;
69
+ const effort = estimateEffortMinutes(level, effortOverride);
70
+ totalEffortMinutes += effort;
71
+ const testId = finding.test_id ?? "unknown";
72
+ const ruleId = `bandit.${testId}`;
73
+ const messageText = finding.issue_text ??
74
+ `${finding.test_name ?? "Bandit finding"} (${finding.issue_severity ?? "UNKNOWN"})`;
75
+ const startLine = typeof finding.line_number === "number" && finding.line_number > 0
76
+ ? finding.line_number
77
+ : 1;
78
+ const startColumn = typeof finding.col_offset === "number" && finding.col_offset >= 0
79
+ ? finding.col_offset + 1
80
+ : 1;
81
+ results.push(buildSarifResult({
82
+ ruleId,
83
+ level,
84
+ message: messageText,
85
+ uri: filename,
86
+ startLine,
87
+ startColumn,
88
+ effortMinutes: effort,
89
+ cwe: finding.issue_cwe?.id,
90
+ confidence: finding.issue_confidence,
91
+ }));
92
+ }
93
+ return {
94
+ document: wrapResultsInSarif(BANDIT, "unknown", results),
95
+ sourceTool: BANDIT,
96
+ findingCount: results.length,
97
+ totalEffortMinutes,
98
+ };
99
+ }
100
+ /**
101
+ * Map Bandit's `issue_severity` string to a SARIF level. Unknown
102
+ * values default to `"warning"` so findings are still surfaced.
103
+ */
104
+ function mapSeverity(severity) {
105
+ switch ((severity ?? "").toUpperCase()) {
106
+ case "HIGH":
107
+ return "error";
108
+ case "MEDIUM":
109
+ return "warning";
110
+ case "LOW":
111
+ return "note";
112
+ default:
113
+ return "warning";
114
+ }
115
+ }
116
+ /**
117
+ * Build the SARIF `result` object for a single Bandit finding. We
118
+ * stash the CWE id and Bandit confidence in the `properties` bag so
119
+ * consumers can surface them in the dashboard hot-spot view.
120
+ */
121
+ function buildSarifResult(opts) {
122
+ return {
123
+ ruleId: opts.ruleId,
124
+ level: opts.level,
125
+ message: { text: opts.message },
126
+ locations: [
127
+ {
128
+ physicalLocation: {
129
+ artifactLocation: { uri: opts.uri },
130
+ region: {
131
+ startLine: opts.startLine,
132
+ startColumn: opts.startColumn,
133
+ },
134
+ },
135
+ },
136
+ ],
137
+ properties: {
138
+ sourceTool: BANDIT,
139
+ effortMinutes: opts.effortMinutes,
140
+ ...(typeof opts.cwe === "number" ? { cwe: opts.cwe } : {}),
141
+ ...(typeof opts.confidence === "string" ? { confidence: opts.confidence } : {}),
142
+ },
143
+ };
144
+ }
145
+ //# sourceMappingURL=bandit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bandit.js","sourceRoot":"","sources":["../../src/adapters/bandit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Shared types and helpers for per-scanner SARIF adapters.
3
+ *
4
+ * Every adapter in this directory converts a scanner's native output
5
+ * into a `PersistedSarif` 2.1.0 document that the `SarifStore` can
6
+ * ingest directly. The adapters also enrich the finding `properties`
7
+ * bag with a stable `effortMinutes` field so the Stop quality gate and
8
+ * the Technical Debt Ratio computation can treat every source tool
9
+ * uniformly.
10
+ *
11
+ * Rule-level effort estimates live in `DEFAULT_EFFORT_BY_SEVERITY`.
12
+ * Individual adapters may override the default per rule id when the
13
+ * scanner attaches a more specific hint.
14
+ *
15
+ * @module adapters/common
16
+ */
17
+ import type { PersistedSarif } from "../sarif/sarif-store.js";
18
+ import type { SarifLevel } from "../sarif/sarif-builder.js";
19
+ /**
20
+ * The canonical list of scanners claude-crap understands. The
21
+ * `ingest_scanner_output` MCP tool uses this as its `enum` constraint,
22
+ * so keeping it narrow prevents drift.
23
+ */
24
+ export declare const KNOWN_SCANNERS: readonly ["semgrep", "eslint", "bandit", "stryker"];
25
+ /**
26
+ * Union of supported scanner identifiers.
27
+ */
28
+ export type KnownScanner = (typeof KNOWN_SCANNERS)[number];
29
+ /**
30
+ * Default remediation effort in minutes per SARIF severity level. These
31
+ * numbers are deliberately conservative — real projects should override
32
+ * them per rule via adapter-specific rule maps or via SARIF properties.
33
+ *
34
+ * The mapping follows the common-sense rule that every bug takes at
35
+ * least a test plus a patch, so even a note-level finding costs time.
36
+ */
37
+ export declare const DEFAULT_EFFORT_BY_SEVERITY: Readonly<Record<SarifLevel, number>>;
38
+ /**
39
+ * Envelope common to every adapter output. Adapters return a
40
+ * `PersistedSarif` document and a small stats block describing what
41
+ * they saw, so the MCP tool handler can echo those stats back to the
42
+ * LLM even when the SarifStore rejects duplicates.
43
+ */
44
+ export interface AdapterResult {
45
+ /** Normalized SARIF 2.1.0 document ready for `SarifStore.ingestRun`. */
46
+ readonly document: PersistedSarif;
47
+ /** Scanner identifier, propagated into every finding's `properties.sourceTool`. */
48
+ readonly sourceTool: KnownScanner;
49
+ /** Raw number of findings the adapter read from the scanner's native output. */
50
+ readonly findingCount: number;
51
+ /** Total estimated remediation effort across all findings, in minutes. */
52
+ readonly totalEffortMinutes: number;
53
+ }
54
+ /**
55
+ * Build a `PersistedSarif` document from a flat list of already-mapped
56
+ * result entries. Every adapter produces its results with the same
57
+ * shape and then calls this helper to wrap them in a valid 2.1.0 envelope.
58
+ *
59
+ * @param sourceTool Stable scanner identifier (e.g. `"semgrep"`).
60
+ * @param version Adapter version string stored in `tool.driver.version`.
61
+ * @param results Pre-built SARIF `result` entries.
62
+ */
63
+ export declare function wrapResultsInSarif(sourceTool: KnownScanner, version: string, results: ReadonlyArray<object>): PersistedSarif;
64
+ /**
65
+ * Estimate remediation effort for a single finding given its severity
66
+ * and an optional rule-specific override. Returns `minutes` clamped to
67
+ * a non-negative integer.
68
+ *
69
+ * @param level SARIF severity level (`"error"`, `"warning"`, ...).
70
+ * @param override Optional rule-specific effort in minutes.
71
+ */
72
+ export declare function estimateEffortMinutes(level: SarifLevel | undefined, override?: number): number;
73
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/adapters/common.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,cAAc,qDAAsD,CAAC;AAElF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAK1E,CAAC;AAEH;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,YAAY,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAC7B,cAAc,CAgBhB;AAyBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAM9F"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Shared types and helpers for per-scanner SARIF adapters.
3
+ *
4
+ * Every adapter in this directory converts a scanner's native output
5
+ * into a `PersistedSarif` 2.1.0 document that the `SarifStore` can
6
+ * ingest directly. The adapters also enrich the finding `properties`
7
+ * bag with a stable `effortMinutes` field so the Stop quality gate and
8
+ * the Technical Debt Ratio computation can treat every source tool
9
+ * uniformly.
10
+ *
11
+ * Rule-level effort estimates live in `DEFAULT_EFFORT_BY_SEVERITY`.
12
+ * Individual adapters may override the default per rule id when the
13
+ * scanner attaches a more specific hint.
14
+ *
15
+ * @module adapters/common
16
+ */
17
+ /**
18
+ * The canonical list of scanners claude-crap understands. The
19
+ * `ingest_scanner_output` MCP tool uses this as its `enum` constraint,
20
+ * so keeping it narrow prevents drift.
21
+ */
22
+ export const KNOWN_SCANNERS = ["semgrep", "eslint", "bandit", "stryker"];
23
+ /**
24
+ * Default remediation effort in minutes per SARIF severity level. These
25
+ * numbers are deliberately conservative — real projects should override
26
+ * them per rule via adapter-specific rule maps or via SARIF properties.
27
+ *
28
+ * The mapping follows the common-sense rule that every bug takes at
29
+ * least a test plus a patch, so even a note-level finding costs time.
30
+ */
31
+ export const DEFAULT_EFFORT_BY_SEVERITY = Object.freeze({
32
+ error: 60,
33
+ warning: 30,
34
+ note: 10,
35
+ none: 5,
36
+ });
37
+ /**
38
+ * Build a `PersistedSarif` document from a flat list of already-mapped
39
+ * result entries. Every adapter produces its results with the same
40
+ * shape and then calls this helper to wrap them in a valid 2.1.0 envelope.
41
+ *
42
+ * @param sourceTool Stable scanner identifier (e.g. `"semgrep"`).
43
+ * @param version Adapter version string stored in `tool.driver.version`.
44
+ * @param results Pre-built SARIF `result` entries.
45
+ */
46
+ export function wrapResultsInSarif(sourceTool, version, results) {
47
+ return {
48
+ $schema: "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0.json",
49
+ version: "2.1.0",
50
+ runs: [
51
+ {
52
+ tool: {
53
+ driver: {
54
+ name: sourceTool,
55
+ version,
56
+ },
57
+ },
58
+ results: results,
59
+ },
60
+ ],
61
+ };
62
+ }
63
+ /**
64
+ * Estimate remediation effort for a single finding given its severity
65
+ * and an optional rule-specific override. Returns `minutes` clamped to
66
+ * a non-negative integer.
67
+ *
68
+ * @param level SARIF severity level (`"error"`, `"warning"`, ...).
69
+ * @param override Optional rule-specific effort in minutes.
70
+ */
71
+ export function estimateEffortMinutes(level, override) {
72
+ if (typeof override === "number" && Number.isFinite(override) && override >= 0) {
73
+ return Math.round(override);
74
+ }
75
+ const base = DEFAULT_EFFORT_BY_SEVERITY[level ?? "warning"];
76
+ return Math.max(0, Math.round(base ?? 30));
77
+ }
78
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/adapters/common.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;AAOlF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAyC,MAAM,CAAC,MAAM,CAAC;IAC5F,KAAK,EAAE,EAAE;IACT,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,CAAC;CACR,CAAC,CAAC;AAmBH;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAwB,EACxB,OAAe,EACf,OAA8B;IAE9B,OAAO;QACL,OAAO,EAAE,qEAAqE;QAC9E,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACJ;gBACE,IAAI,EAAE;oBACJ,MAAM,EAAE;wBACN,IAAI,EAAE,UAAU;wBAChB,OAAO;qBACR;iBACF;gBACD,OAAO,EAAE,OAA0C;aACpD;SACF;KACgB,CAAC;AACtB,CAAC;AAyBD;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAA6B,EAAE,QAAiB;IACpF,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,GAAG,0BAA0B,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * ESLint adapter.
3
+ *
4
+ * ESLint's default JSON output (`eslint -f json .`) is NOT SARIF.
5
+ * This adapter converts it into a SARIF 2.1.0 document with one
6
+ * `result` per ESLint `messages[]` entry, mapping ESLint's numeric
7
+ * severity to SARIF levels:
8
+ *
9
+ * severity 0 → "note" (parser info / disabled)
10
+ * severity 1 → "warning"
11
+ * severity 2 → "error"
12
+ *
13
+ * ESLint's JSON shape:
14
+ *
15
+ * [
16
+ * {
17
+ * "filePath": "/abs/path/to/foo.js",
18
+ * "messages": [
19
+ * {
20
+ * "ruleId": "no-unused-vars",
21
+ * "severity": 1,
22
+ * "message": "'foo' is defined but never used.",
23
+ * "line": 10,
24
+ * "column": 5,
25
+ * "endLine": 10,
26
+ * "endColumn": 8
27
+ * }
28
+ * ],
29
+ * "errorCount": 0,
30
+ * "warningCount": 1,
31
+ * "fatalErrorCount": 0,
32
+ * "source": "...",
33
+ * "usedDeprecatedRules": []
34
+ * }
35
+ * ]
36
+ *
37
+ * We preserve the full `line`/`column` range when ESLint provides one
38
+ * so the dashboard's hot-spot table can show a precise location.
39
+ *
40
+ * @module adapters/eslint
41
+ */
42
+ import { type AdapterResult } from "./common.js";
43
+ /**
44
+ * Accept ESLint native JSON output and return a normalized
45
+ * `PersistedSarif` document plus counts.
46
+ *
47
+ * @param input Raw ESLint JSON (string or parsed array).
48
+ * @returns Adapter result.
49
+ * @throws When the input is not a valid ESLint report.
50
+ */
51
+ export declare function adaptEslint(input: unknown): AdapterResult;
52
+ //# sourceMappingURL=eslint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../../src/adapters/eslint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAGH,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,aAAa,CAAC;AAyBrB;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CA0CzD"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * ESLint adapter.
3
+ *
4
+ * ESLint's default JSON output (`eslint -f json .`) is NOT SARIF.
5
+ * This adapter converts it into a SARIF 2.1.0 document with one
6
+ * `result` per ESLint `messages[]` entry, mapping ESLint's numeric
7
+ * severity to SARIF levels:
8
+ *
9
+ * severity 0 → "note" (parser info / disabled)
10
+ * severity 1 → "warning"
11
+ * severity 2 → "error"
12
+ *
13
+ * ESLint's JSON shape:
14
+ *
15
+ * [
16
+ * {
17
+ * "filePath": "/abs/path/to/foo.js",
18
+ * "messages": [
19
+ * {
20
+ * "ruleId": "no-unused-vars",
21
+ * "severity": 1,
22
+ * "message": "'foo' is defined but never used.",
23
+ * "line": 10,
24
+ * "column": 5,
25
+ * "endLine": 10,
26
+ * "endColumn": 8
27
+ * }
28
+ * ],
29
+ * "errorCount": 0,
30
+ * "warningCount": 1,
31
+ * "fatalErrorCount": 0,
32
+ * "source": "...",
33
+ * "usedDeprecatedRules": []
34
+ * }
35
+ * ]
36
+ *
37
+ * We preserve the full `line`/`column` range when ESLint provides one
38
+ * so the dashboard's hot-spot table can show a precise location.
39
+ *
40
+ * @module adapters/eslint
41
+ */
42
+ import { estimateEffortMinutes, wrapResultsInSarif, } from "./common.js";
43
+ const ESLINT = "eslint";
44
+ /**
45
+ * Accept ESLint native JSON output and return a normalized
46
+ * `PersistedSarif` document plus counts.
47
+ *
48
+ * @param input Raw ESLint JSON (string or parsed array).
49
+ * @returns Adapter result.
50
+ * @throws When the input is not a valid ESLint report.
51
+ */
52
+ export function adaptEslint(input) {
53
+ const parsed = typeof input === "string" ? JSON.parse(input) : input;
54
+ if (!Array.isArray(parsed)) {
55
+ throw new Error(`[adapter:eslint] expected an array of file reports`);
56
+ }
57
+ const results = [];
58
+ let totalEffortMinutes = 0;
59
+ for (const fileReport of parsed) {
60
+ const filePath = fileReport?.filePath;
61
+ if (typeof filePath !== "string" || !filePath)
62
+ continue;
63
+ const messages = Array.isArray(fileReport.messages) ? fileReport.messages : [];
64
+ for (const msg of messages) {
65
+ const level = mapSeverity(msg.severity);
66
+ const ruleId = typeof msg.ruleId === "string" ? msg.ruleId : "eslint.unknown";
67
+ const line = typeof msg.line === "number" && msg.line > 0 ? msg.line : 1;
68
+ const column = typeof msg.column === "number" && msg.column > 0 ? msg.column : 1;
69
+ const effort = estimateEffortMinutes(level);
70
+ totalEffortMinutes += effort;
71
+ results.push(buildSarifResult({
72
+ ruleId,
73
+ level,
74
+ message: msg.message ?? ruleId,
75
+ uri: filePath,
76
+ startLine: line,
77
+ startColumn: column,
78
+ endLine: typeof msg.endLine === "number" ? msg.endLine : undefined,
79
+ endColumn: typeof msg.endColumn === "number" ? msg.endColumn : undefined,
80
+ effortMinutes: effort,
81
+ }));
82
+ }
83
+ }
84
+ return {
85
+ document: wrapResultsInSarif(ESLINT, "unknown", results),
86
+ sourceTool: ESLINT,
87
+ findingCount: results.length,
88
+ totalEffortMinutes,
89
+ };
90
+ }
91
+ /**
92
+ * Translate ESLint's numeric severity to a SARIF level. ESLint uses:
93
+ *
94
+ * 0 = off / disabled → `"note"` (informational)
95
+ * 1 = warn → `"warning"`
96
+ * 2 = error → `"error"`
97
+ *
98
+ * Unknown values default to `"warning"` so the finding is still
99
+ * visible without being treated as a blocker.
100
+ */
101
+ function mapSeverity(severity) {
102
+ switch (severity) {
103
+ case 2:
104
+ return "error";
105
+ case 1:
106
+ return "warning";
107
+ case 0:
108
+ return "note";
109
+ default:
110
+ return "warning";
111
+ }
112
+ }
113
+ /**
114
+ * Assemble a SARIF `result` object from the narrow set of fields an
115
+ * ESLint message provides. The shape matches what the SarifStore
116
+ * expects when hydrating a finding from a persisted document.
117
+ */
118
+ function buildSarifResult(opts) {
119
+ return {
120
+ ruleId: opts.ruleId,
121
+ level: opts.level,
122
+ message: { text: opts.message },
123
+ locations: [
124
+ {
125
+ physicalLocation: {
126
+ artifactLocation: { uri: opts.uri },
127
+ region: {
128
+ startLine: opts.startLine,
129
+ startColumn: opts.startColumn,
130
+ ...(opts.endLine !== undefined ? { endLine: opts.endLine } : {}),
131
+ ...(opts.endColumn !== undefined ? { endColumn: opts.endColumn } : {}),
132
+ },
133
+ },
134
+ },
135
+ ],
136
+ properties: {
137
+ sourceTool: ESLINT,
138
+ effortMinutes: opts.effortMinutes,
139
+ },
140
+ };
141
+ }
142
+ //# sourceMappingURL=eslint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/adapters/eslint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Public SDK entry point for the per-scanner SARIF adapters.
3
+ *
4
+ * Adapters convert a scanner's native output (SARIF, JSON, or some
5
+ * other structured format) into a normalized `PersistedSarif`
6
+ * document that the `SarifStore` can ingest directly. Every adapter
7
+ * enriches its findings with a stable `effortMinutes` value on the
8
+ * `properties` bag so the Stop quality gate and the project score
9
+ * engine can compute a Technical Debt Ratio.
10
+ *
11
+ * Usage:
12
+ *
13
+ * ```ts
14
+ * import {
15
+ * adaptScannerOutput,
16
+ * adaptSemgrep,
17
+ * adaptEslint,
18
+ * adaptBandit,
19
+ * adaptStryker,
20
+ * } from "claude-crap/adapters";
21
+ *
22
+ * const result = adaptScannerOutput("eslint", rawJsonFromEslint);
23
+ * sarifStore.ingestRun(result.document, result.sourceTool);
24
+ * ```
25
+ *
26
+ * @module adapters
27
+ */
28
+ export { adaptSemgrep } from "./semgrep.js";
29
+ export { adaptEslint } from "./eslint.js";
30
+ export { adaptBandit } from "./bandit.js";
31
+ export { adaptStryker } from "./stryker.js";
32
+ export { DEFAULT_EFFORT_BY_SEVERITY, KNOWN_SCANNERS, estimateEffortMinutes, wrapResultsInSarif, } from "./common.js";
33
+ export type { AdapterResult, KnownScanner } from "./common.js";
34
+ import type { AdapterResult, KnownScanner } from "./common.js";
35
+ /**
36
+ * Route a raw scanner output to the correct adapter based on its
37
+ * name. Preferred entry point for the `ingest_scanner_output` MCP
38
+ * tool — the dispatch is a single switch so the compiler can verify
39
+ * every case with `never` exhaustiveness.
40
+ *
41
+ * @param scanner One of the known scanner identifiers.
42
+ * @param rawOutput The scanner's native output (string or parsed).
43
+ * @returns A normalized `AdapterResult`.
44
+ * @throws When `scanner` is unknown or the raw output is malformed.
45
+ */
46
+ export declare function adaptScannerOutput(scanner: KnownScanner, rawOutput: unknown): AdapterResult;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EACL,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM/D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,OAAO,GACjB,aAAa,CAef"}