claude-crap 0.3.6 → 0.3.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.
Files changed (88) hide show
  1. package/README.md +25 -0
  2. package/dist/adapters/common.d.ts +1 -1
  3. package/dist/adapters/common.d.ts.map +1 -1
  4. package/dist/adapters/common.js +1 -1
  5. package/dist/adapters/common.js.map +1 -1
  6. package/dist/adapters/dart-analyzer.d.ts +41 -0
  7. package/dist/adapters/dart-analyzer.d.ts.map +1 -0
  8. package/dist/adapters/dart-analyzer.js +120 -0
  9. package/dist/adapters/dart-analyzer.js.map +1 -0
  10. package/dist/adapters/index.d.ts +1 -0
  11. package/dist/adapters/index.d.ts.map +1 -1
  12. package/dist/adapters/index.js +4 -0
  13. package/dist/adapters/index.js.map +1 -1
  14. package/dist/crap-config.d.ts +2 -0
  15. package/dist/crap-config.d.ts.map +1 -1
  16. package/dist/crap-config.js +36 -28
  17. package/dist/crap-config.js.map +1 -1
  18. package/dist/dashboard/file-detail.d.ts +77 -0
  19. package/dist/dashboard/file-detail.d.ts.map +1 -0
  20. package/dist/dashboard/file-detail.js +120 -0
  21. package/dist/dashboard/file-detail.js.map +1 -0
  22. package/dist/dashboard/server.d.ts +5 -0
  23. package/dist/dashboard/server.d.ts.map +1 -1
  24. package/dist/dashboard/server.js +103 -1
  25. package/dist/dashboard/server.js.map +1 -1
  26. package/dist/index.js +36 -4
  27. package/dist/index.js.map +1 -1
  28. package/dist/metrics/workspace-walker.d.ts +4 -1
  29. package/dist/metrics/workspace-walker.d.ts.map +1 -1
  30. package/dist/metrics/workspace-walker.js +12 -28
  31. package/dist/metrics/workspace-walker.js.map +1 -1
  32. package/dist/scanner/auto-scan.d.ts +9 -1
  33. package/dist/scanner/auto-scan.d.ts.map +1 -1
  34. package/dist/scanner/auto-scan.js +27 -5
  35. package/dist/scanner/auto-scan.js.map +1 -1
  36. package/dist/scanner/bootstrap.d.ts +1 -1
  37. package/dist/scanner/bootstrap.d.ts.map +1 -1
  38. package/dist/scanner/bootstrap.js +9 -0
  39. package/dist/scanner/bootstrap.js.map +1 -1
  40. package/dist/scanner/complexity-scanner.d.ts +56 -0
  41. package/dist/scanner/complexity-scanner.d.ts.map +1 -0
  42. package/dist/scanner/complexity-scanner.js +161 -0
  43. package/dist/scanner/complexity-scanner.js.map +1 -0
  44. package/dist/scanner/detector.d.ts +24 -4
  45. package/dist/scanner/detector.d.ts.map +1 -1
  46. package/dist/scanner/detector.js +105 -10
  47. package/dist/scanner/detector.js.map +1 -1
  48. package/dist/scanner/runner.d.ts +4 -1
  49. package/dist/scanner/runner.d.ts.map +1 -1
  50. package/dist/scanner/runner.js +12 -3
  51. package/dist/scanner/runner.js.map +1 -1
  52. package/dist/schemas/tool-schemas.d.ts +1 -1
  53. package/dist/schemas/tool-schemas.js +1 -1
  54. package/dist/schemas/tool-schemas.js.map +1 -1
  55. package/dist/shared/exclusions.d.ts +53 -0
  56. package/dist/shared/exclusions.d.ts.map +1 -0
  57. package/dist/shared/exclusions.js +126 -0
  58. package/dist/shared/exclusions.js.map +1 -0
  59. package/package.json +3 -1
  60. package/plugin/.claude-plugin/plugin.json +1 -1
  61. package/plugin/bundle/dashboard/public/index.html +432 -12
  62. package/plugin/bundle/mcp-server.mjs +747 -137
  63. package/plugin/bundle/mcp-server.mjs.map +4 -4
  64. package/plugin/package-lock.json +15 -2
  65. package/plugin/package.json +2 -1
  66. package/scripts/bundle-plugin.mjs +2 -1
  67. package/src/adapters/common.ts +1 -1
  68. package/src/adapters/dart-analyzer.ts +161 -0
  69. package/src/adapters/index.ts +4 -0
  70. package/src/crap-config.ts +55 -18
  71. package/src/dashboard/file-detail.ts +195 -0
  72. package/src/dashboard/public/index.html +432 -12
  73. package/src/dashboard/server.ts +140 -1
  74. package/src/index.ts +37 -4
  75. package/src/metrics/workspace-walker.ts +15 -27
  76. package/src/scanner/auto-scan.ts +41 -4
  77. package/src/scanner/bootstrap.ts +11 -0
  78. package/src/scanner/complexity-scanner.ts +222 -0
  79. package/src/scanner/detector.ts +114 -10
  80. package/src/scanner/runner.ts +12 -2
  81. package/src/schemas/tool-schemas.ts +1 -1
  82. package/src/shared/exclusions.ts +156 -0
  83. package/src/tests/adapters/dispatch.test.ts +2 -2
  84. package/src/tests/auto-scan.test.ts +2 -2
  85. package/src/tests/complexity-scanner.test.ts +263 -0
  86. package/src/tests/exclusions.test.ts +117 -0
  87. package/src/tests/file-detail-api.test.ts +258 -0
  88. package/src/tests/scanner-detector.test.ts +31 -11
package/README.md CHANGED
@@ -149,6 +149,31 @@ See [docs/contributing.md](./docs/contributing.md) for Windows setup details.
149
149
 
150
150
  ---
151
151
 
152
+ ## Supported Languages & Scanners
153
+
154
+ | Language | Extensions | AST analysis | Scanner | Auto-install | Monorepo |
155
+ | :------- | :--------- | :----------: | :------ | :----------: | :------: |
156
+ | TypeScript | `.ts` `.tsx` `.mts` `.cts` | Cyclomatic complexity | ESLint | Yes (npm) | Root |
157
+ | JavaScript | `.js` `.jsx` `.mjs` `.cjs` | Cyclomatic complexity | ESLint | Yes (npm) | Root |
158
+ | Python | `.py` `.pyi` | Cyclomatic complexity | Bandit | Manual | Root |
159
+ | Java | `.java` | Cyclomatic complexity | Semgrep | Manual | Root |
160
+ | C# | `.cs` | Cyclomatic complexity | Semgrep | Manual | Root |
161
+ | Dart / Flutter | `.dart` | LOC only | `dart analyze` | SDK required | Subdir probing |
162
+ | Vue | `.vue` | LOC only | ESLint (via root) | — | — |
163
+ | Go | `.go` | LOC only | — | — | — |
164
+ | Rust | `.rs` | LOC only | — | — | — |
165
+ | Ruby | `.rb` | LOC only | — | — | — |
166
+ | PHP | `.php` | LOC only | — | — | — |
167
+ | Swift | `.swift` | LOC only | — | — | — |
168
+ | Kotlin | `.kt` | LOC only | — | — | — |
169
+ | Scala | `.scala` | LOC only | — | — | — |
170
+
171
+ **AST analysis** = tree-sitter cyclomatic complexity per function. **LOC only** = counted toward workspace metrics but no per-function analysis.
172
+
173
+ **Monorepo support**: auto-scan probes `apps/`, `packages/`, `libs/` and npm workspaces for scanner configs in subdirectories (e.g., `apps/mobile/pubspec.yaml`).
174
+
175
+ ---
176
+
152
177
  ## Documentation
153
178
 
154
179
  | Section | Link |
@@ -21,7 +21,7 @@ import type { SarifLevel } from "../sarif/sarif-builder.js";
21
21
  * `ingest_scanner_output` MCP tool uses this as its `enum` constraint,
22
22
  * so keeping it narrow prevents drift.
23
23
  */
24
- export declare const KNOWN_SCANNERS: readonly ["semgrep", "eslint", "bandit", "stryker"];
24
+ export declare const KNOWN_SCANNERS: readonly ["semgrep", "eslint", "bandit", "stryker", "dart_analyze"];
25
25
  /**
26
26
  * Union of supported scanner identifiers.
27
27
  */
@@ -1 +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"}
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,qEAAsE,CAAC;AAElG;;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"}
@@ -19,7 +19,7 @@
19
19
  * `ingest_scanner_output` MCP tool uses this as its `enum` constraint,
20
20
  * so keeping it narrow prevents drift.
21
21
  */
22
- export const KNOWN_SCANNERS = ["semgrep", "eslint", "bandit", "stryker"];
22
+ export const KNOWN_SCANNERS = ["semgrep", "eslint", "bandit", "stryker", "dart_analyze"];
23
23
  /**
24
24
  * Default remediation effort in minutes per SARIF severity level. These
25
25
  * numbers are deliberately conservative — real projects should override
@@ -1 +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"}
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,EAAE,cAAc,CAAU,CAAC;AAOlG;;;;;;;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,41 @@
1
+ /**
2
+ * Adapter: `dart analyze --format=json` → SARIF 2.1.0.
3
+ *
4
+ * The Dart analyzer emits JSON with this shape:
5
+ *
6
+ * {
7
+ * "version": 1,
8
+ * "diagnostics": [
9
+ * {
10
+ * "code": "unused_import",
11
+ * "severity": "WARNING",
12
+ * "type": "STATIC_WARNING",
13
+ * "location": {
14
+ * "file": "/absolute/path/to/file.dart",
15
+ * "range": {
16
+ * "start": { "offset": 7, "line": 1, "column": 8 },
17
+ * "end": { "offset": 16, "line": 1, "column": 17 }
18
+ * }
19
+ * },
20
+ * "problemMessage": "Unused import: 'dart:io'.",
21
+ * "correctionMessage": "Try removing the import directive.",
22
+ * "documentation": "https://dart.dev/diagnostics/unused_import"
23
+ * }
24
+ * ]
25
+ * }
26
+ *
27
+ * Severity mapping:
28
+ * - "ERROR" → SARIF "error" (30 min effort)
29
+ * - "WARNING" → SARIF "warning" (15 min effort)
30
+ * - "INFO" → SARIF "note" (5 min effort)
31
+ *
32
+ * @module adapters/dart-analyzer
33
+ */
34
+ import { type AdapterResult } from "./common.js";
35
+ /**
36
+ * Convert `dart analyze --format=json` output to SARIF 2.1.0.
37
+ *
38
+ * @param rawOutput The JSON string or pre-parsed object from `dart analyze`.
39
+ */
40
+ export declare function adaptDartAnalyzer(rawOutput: unknown): AdapterResult;
41
+ //# sourceMappingURL=dart-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dart-analyzer.d.ts","sourceRoot":"","sources":["../../src/adapters/dart-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EACL,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AAsDrB;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,aAAa,CA+DnE"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Adapter: `dart analyze --format=json` → SARIF 2.1.0.
3
+ *
4
+ * The Dart analyzer emits JSON with this shape:
5
+ *
6
+ * {
7
+ * "version": 1,
8
+ * "diagnostics": [
9
+ * {
10
+ * "code": "unused_import",
11
+ * "severity": "WARNING",
12
+ * "type": "STATIC_WARNING",
13
+ * "location": {
14
+ * "file": "/absolute/path/to/file.dart",
15
+ * "range": {
16
+ * "start": { "offset": 7, "line": 1, "column": 8 },
17
+ * "end": { "offset": 16, "line": 1, "column": 17 }
18
+ * }
19
+ * },
20
+ * "problemMessage": "Unused import: 'dart:io'.",
21
+ * "correctionMessage": "Try removing the import directive.",
22
+ * "documentation": "https://dart.dev/diagnostics/unused_import"
23
+ * }
24
+ * ]
25
+ * }
26
+ *
27
+ * Severity mapping:
28
+ * - "ERROR" → SARIF "error" (30 min effort)
29
+ * - "WARNING" → SARIF "warning" (15 min effort)
30
+ * - "INFO" → SARIF "note" (5 min effort)
31
+ *
32
+ * @module adapters/dart-analyzer
33
+ */
34
+ import { wrapResultsInSarif, estimateEffortMinutes, } from "./common.js";
35
+ // ── Severity mapping ───────────────────────────────────────────────
36
+ function mapSeverity(dartSeverity) {
37
+ switch (dartSeverity.toUpperCase()) {
38
+ case "ERROR":
39
+ return "error";
40
+ case "WARNING":
41
+ return "warning";
42
+ case "INFO":
43
+ return "note";
44
+ default:
45
+ return "warning";
46
+ }
47
+ }
48
+ // ── Effort estimates per severity ──────────────────────────────────
49
+ const EFFORT_BY_SEVERITY = {
50
+ error: 30,
51
+ warning: 15,
52
+ note: 5,
53
+ none: 0,
54
+ };
55
+ // ── Public API ─────────────────────────────────────────────────────
56
+ /**
57
+ * Convert `dart analyze --format=json` output to SARIF 2.1.0.
58
+ *
59
+ * @param rawOutput The JSON string or pre-parsed object from `dart analyze`.
60
+ */
61
+ export function adaptDartAnalyzer(rawOutput) {
62
+ let parsed;
63
+ if (typeof rawOutput === "string") {
64
+ try {
65
+ parsed = JSON.parse(rawOutput);
66
+ }
67
+ catch {
68
+ throw new Error("[dart-analyzer adapter] rawOutput is not valid JSON");
69
+ }
70
+ }
71
+ else if (rawOutput && typeof rawOutput === "object" && "diagnostics" in rawOutput) {
72
+ parsed = rawOutput;
73
+ }
74
+ else {
75
+ throw new Error("[dart-analyzer adapter] rawOutput must be a JSON string or an object with a 'diagnostics' array");
76
+ }
77
+ if (!Array.isArray(parsed.diagnostics)) {
78
+ throw new Error("[dart-analyzer adapter] 'diagnostics' must be an array");
79
+ }
80
+ const results = [];
81
+ let totalEffortMinutes = 0;
82
+ for (const diag of parsed.diagnostics) {
83
+ const level = mapSeverity(diag.severity);
84
+ const effort = EFFORT_BY_SEVERITY[level] ?? estimateEffortMinutes(level);
85
+ totalEffortMinutes += effort;
86
+ results.push({
87
+ ruleId: diag.code,
88
+ level,
89
+ message: {
90
+ text: diag.problemMessage + (diag.correctionMessage ? ` ${diag.correctionMessage}` : ""),
91
+ },
92
+ locations: [
93
+ {
94
+ physicalLocation: {
95
+ artifactLocation: {
96
+ uri: diag.location.file,
97
+ },
98
+ region: {
99
+ startLine: diag.location.range.start.line,
100
+ startColumn: diag.location.range.start.column,
101
+ endLine: diag.location.range.end.line,
102
+ endColumn: diag.location.range.end.column,
103
+ },
104
+ },
105
+ },
106
+ ],
107
+ properties: {
108
+ effortMinutes: effort,
109
+ ...(diag.documentation ? { helpUri: diag.documentation } : {}),
110
+ },
111
+ });
112
+ }
113
+ return {
114
+ document: wrapResultsInSarif("dart_analyze", "1.0.0", results),
115
+ sourceTool: "dart_analyze",
116
+ findingCount: parsed.diagnostics.length,
117
+ totalEffortMinutes,
118
+ };
119
+ }
120
+ //# sourceMappingURL=dart-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dart-analyzer.js","sourceRoot":"","sources":["../../src/adapters/dart-analyzer.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,7 @@ export { adaptSemgrep } from "./semgrep.js";
29
29
  export { adaptEslint } from "./eslint.js";
30
30
  export { adaptBandit } from "./bandit.js";
31
31
  export { adaptStryker } from "./stryker.js";
32
+ export { adaptDartAnalyzer } from "./dart-analyzer.js";
32
33
  export { DEFAULT_EFFORT_BY_SEVERITY, KNOWN_SCANNERS, estimateEffortMinutes, wrapResultsInSarif, } from "./common.js";
33
34
  export type { AdapterResult, KnownScanner } from "./common.js";
34
35
  import type { AdapterResult, KnownScanner } from "./common.js";
@@ -1 +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"}
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;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EACL,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO/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,CAiBf"}
@@ -29,11 +29,13 @@ export { adaptSemgrep } from "./semgrep.js";
29
29
  export { adaptEslint } from "./eslint.js";
30
30
  export { adaptBandit } from "./bandit.js";
31
31
  export { adaptStryker } from "./stryker.js";
32
+ export { adaptDartAnalyzer } from "./dart-analyzer.js";
32
33
  export { DEFAULT_EFFORT_BY_SEVERITY, KNOWN_SCANNERS, estimateEffortMinutes, wrapResultsInSarif, } from "./common.js";
33
34
  import { adaptSemgrep } from "./semgrep.js";
34
35
  import { adaptEslint } from "./eslint.js";
35
36
  import { adaptBandit } from "./bandit.js";
36
37
  import { adaptStryker } from "./stryker.js";
38
+ import { adaptDartAnalyzer } from "./dart-analyzer.js";
37
39
  /**
38
40
  * Route a raw scanner output to the correct adapter based on its
39
41
  * name. Preferred entry point for the `ingest_scanner_output` MCP
@@ -55,6 +57,8 @@ export function adaptScannerOutput(scanner, rawOutput) {
55
57
  return adaptBandit(rawOutput);
56
58
  case "stryker":
57
59
  return adaptStryker(rawOutput);
60
+ case "dart_analyze":
61
+ return adaptDartAnalyzer(rawOutput);
58
62
  default: {
59
63
  const exhaustive = scanner;
60
64
  throw new Error(`[adapters] Unknown scanner: ${String(exhaustive)}`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","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;AAIrB,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;AAG5C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAqB,EACrB,SAAkB;IAElB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;QACjC,KAAK,QAAQ;YACX,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;QAChC,KAAK,QAAQ;YACX,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;QAChC,KAAK,SAAS;YACZ,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;QACjC,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,OAAO,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","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;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EACL,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAIrB,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;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAqB,EACrB,SAAkB;IAElB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;QACjC,KAAK,QAAQ;YACX,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;QAChC,KAAK,QAAQ;YACX,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;QAChC,KAAK,SAAS;YACZ,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;QACjC,KAAK,cAAc;YACjB,OAAO,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,OAAO,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -70,6 +70,8 @@ export interface CrapConfig {
70
70
  readonly strictness: Strictness;
71
71
  /** Where the strictness value actually came from. Useful for diagnostics. */
72
72
  readonly strictnessSource: "env" | "file" | "default";
73
+ /** User-defined exclusion patterns (directories with trailing `/`, or file globs). */
74
+ readonly exclude: ReadonlyArray<string>;
73
75
  }
74
76
  /**
75
77
  * Options accepted by {@link loadCrapConfig}. The only required
@@ -1 +1 @@
1
- {"version":3,"file":"crap-config.d.ts","sourceRoot":"","sources":["../src/crap-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAKH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,yCAA0C,CAAC;AAEzE;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAAqB,CAAC;AAEvD;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,6EAA6E;IAC7E,QAAQ,CAAC,gBAAgB,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAiBzE"}
1
+ {"version":3,"file":"crap-config.d.ts","sourceRoot":"","sources":["../src/crap-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAKH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,yCAA0C,CAAC;AAEzE;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAAqB,CAAC;AAEvD;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,6EAA6E;IAC7E,QAAQ,CAAC,gBAAgB,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IACtD,sFAAsF;IACtF,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACzC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAuBzE"}
@@ -68,6 +68,10 @@ export class CrapConfigError extends Error {
68
68
  * @throws {@link CrapConfigError} on any invalid input.
69
69
  */
70
70
  export function loadCrapConfig(options) {
71
+ // Always read the file to extract `exclude`, even when strictness
72
+ // comes from the environment variable.
73
+ const fileResult = readFromFile(options.workspaceRoot);
74
+ const exclude = fileResult?.exclude ?? [];
71
75
  const envRaw = process.env["CLAUDE_CRAP_STRICTNESS"];
72
76
  if (typeof envRaw === "string" && envRaw.trim() !== "") {
73
77
  const normalized = envRaw.trim().toLowerCase();
@@ -75,26 +79,13 @@ export function loadCrapConfig(options) {
75
79
  throw new CrapConfigError(`[crap-config] CLAUDE_CRAP_STRICTNESS="${envRaw}" is not a valid strictness. ` +
76
80
  `Expected one of: ${STRICTNESS_VALUES.join(", ")}.`);
77
81
  }
78
- return { strictness: normalized, strictnessSource: "env" };
82
+ return { strictness: normalized, strictnessSource: "env", exclude };
79
83
  }
80
- const fromFile = readFromFile(options.workspaceRoot);
81
- if (fromFile)
82
- return { strictness: fromFile, strictnessSource: "file" };
83
- return { strictness: DEFAULT_STRICTNESS, strictnessSource: "default" };
84
+ if (fileResult?.strictness) {
85
+ return { strictness: fileResult.strictness, strictnessSource: "file", exclude };
86
+ }
87
+ return { strictness: DEFAULT_STRICTNESS, strictnessSource: "default", exclude };
84
88
  }
85
- /**
86
- * Attempt to read and validate `.claude-crap.json` at the
87
- * workspace root. Returns `null` when the file is missing (which
88
- * is the common case for fresh installs). Throws
89
- * {@link CrapConfigError} on any other failure mode — a malformed
90
- * JSON file, a non-object root, a missing or wrong-type
91
- * `strictness` field, or an unknown enum value — so the caller
92
- * cannot accidentally drop into the default on a typo.
93
- *
94
- * @param workspaceRoot Absolute workspace root.
95
- * @returns The validated strictness, or `null` when no
96
- * file is present.
97
- */
98
89
  function readFromFile(workspaceRoot) {
99
90
  const filePath = join(workspaceRoot, ".claude-crap.json");
100
91
  let raw;
@@ -118,18 +109,35 @@ function readFromFile(workspaceRoot) {
118
109
  throw new CrapConfigError(`[crap-config] ${filePath} must be a JSON object at the top level`);
119
110
  }
120
111
  const doc = parsed;
121
- if (!("strictness" in doc))
122
- return null;
123
- const value = doc["strictness"];
124
- if (typeof value !== "string") {
125
- throw new CrapConfigError(`[crap-config] ${filePath}: 'strictness' must be a string, got ${typeof value}`);
112
+ // Parse strictness
113
+ let strictness = null;
114
+ if ("strictness" in doc) {
115
+ const value = doc["strictness"];
116
+ if (typeof value !== "string") {
117
+ throw new CrapConfigError(`[crap-config] ${filePath}: 'strictness' must be a string, got ${typeof value}`);
118
+ }
119
+ const normalized = value.trim().toLowerCase();
120
+ if (!isStrictness(normalized)) {
121
+ throw new CrapConfigError(`[crap-config] ${filePath}: 'strictness' is "${value}"; ` +
122
+ `expected one of ${STRICTNESS_VALUES.join(", ")}.`);
123
+ }
124
+ strictness = normalized;
126
125
  }
127
- const normalized = value.trim().toLowerCase();
128
- if (!isStrictness(normalized)) {
129
- throw new CrapConfigError(`[crap-config] ${filePath}: 'strictness' is "${value}"; ` +
130
- `expected one of ${STRICTNESS_VALUES.join(", ")}.`);
126
+ // Parse exclude
127
+ let exclude = [];
128
+ if ("exclude" in doc) {
129
+ const raw = doc["exclude"];
130
+ if (!Array.isArray(raw)) {
131
+ throw new CrapConfigError(`[crap-config] ${filePath}: 'exclude' must be an array of strings`);
132
+ }
133
+ for (const item of raw) {
134
+ if (typeof item !== "string") {
135
+ throw new CrapConfigError(`[crap-config] ${filePath}: every entry in 'exclude' must be a string, got ${typeof item}`);
136
+ }
137
+ }
138
+ exclude = raw;
131
139
  }
132
- return normalized;
140
+ return { strictness, exclude };
133
141
  }
134
142
  /**
135
143
  * Runtime type guard for the {@link Strictness} union. Lets callers
@@ -1 +1 @@
1
- {"version":3,"file":"crap-config.js","sourceRoot":"","sources":["../src/crap-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crap-config.js","sourceRoot":"","sources":["../src/crap-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * File detail builder for the dashboard.
3
+ *
4
+ * Given a workspace-relative file path, this module produces a rich
5
+ * detail payload combining source code, per-function AST metrics, and
6
+ * SARIF findings filtered to that file. The dashboard uses this to
7
+ * render a ReportGenerator-style annotated code view.
8
+ *
9
+ * The builder is extracted into its own module (rather than inlined in
10
+ * `server.ts`) so that:
11
+ * - The logic is unit-testable without booting the HTTP server.
12
+ * - The types are importable by both the Fastify route and tests.
13
+ *
14
+ * @module dashboard/file-detail
15
+ */
16
+ import { type SupportedLanguage } from "../ast/language-config.js";
17
+ import type { TreeSitterEngine } from "../ast/tree-sitter-engine.js";
18
+ import type { SarifStore } from "../sarif/sarif-store.js";
19
+ /** Per-function entry in the detail response. */
20
+ export interface FileDetailFunction {
21
+ readonly name: string;
22
+ readonly startLine: number;
23
+ readonly endLine: number;
24
+ readonly cyclomaticComplexity: number;
25
+ readonly lineCount: number;
26
+ }
27
+ /** Per-finding entry in the detail response. */
28
+ export interface FileDetailFinding {
29
+ readonly ruleId: string;
30
+ readonly level: string;
31
+ readonly message: string;
32
+ readonly sourceTool: string;
33
+ readonly startLine: number;
34
+ readonly startColumn: number;
35
+ readonly endLine: number;
36
+ readonly endColumn: number;
37
+ readonly effortMinutes: number;
38
+ }
39
+ /** Summary statistics for the file. */
40
+ export interface FileDetailSummary {
41
+ readonly totalFindings: number;
42
+ readonly errorCount: number;
43
+ readonly warningCount: number;
44
+ readonly noteCount: number;
45
+ readonly totalEffortMinutes: number;
46
+ readonly avgComplexity: number;
47
+ readonly maxComplexity: number;
48
+ }
49
+ /** Full response payload for the file detail endpoint. */
50
+ export interface FileDetailResponse {
51
+ readonly filePath: string;
52
+ readonly language: SupportedLanguage | null;
53
+ readonly physicalLoc: number;
54
+ readonly logicalLoc: number;
55
+ readonly cyclomaticMax: number;
56
+ readonly sourceLines: string[];
57
+ readonly functions: FileDetailFunction[];
58
+ readonly findings: FileDetailFinding[];
59
+ readonly summary: FileDetailSummary;
60
+ }
61
+ /** Input accepted by {@link buildFileDetail}. */
62
+ export interface BuildFileDetailInput {
63
+ readonly relativePath: string;
64
+ readonly workspaceRoot: string;
65
+ readonly astEngine?: TreeSitterEngine | undefined;
66
+ readonly sarifStore: SarifStore;
67
+ readonly cyclomaticMax: number;
68
+ }
69
+ /**
70
+ * Build the file detail payload. Pure function aside from the file
71
+ * read and the tree-sitter analysis (both deterministic for a given
72
+ * file).
73
+ *
74
+ * @throws When the file does not exist or the path escapes the workspace.
75
+ */
76
+ export declare function buildFileDetail(input: BuildFileDetailInput): Promise<FileDetailResponse>;
77
+ //# sourceMappingURL=file-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-detail.d.ts","sourceRoot":"","sources":["../../src/dashboard/file-detail.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAA0B,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAAE,gBAAgB,EAAmB,MAAM,8BAA8B,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,yBAAyB,CAAC;AAI3E,iDAAiD;AACjD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,uCAAuC;AACvC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,kBAAkB,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;CACrC;AAED,iDAAiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAID;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAwG7B"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * File detail builder for the dashboard.
3
+ *
4
+ * Given a workspace-relative file path, this module produces a rich
5
+ * detail payload combining source code, per-function AST metrics, and
6
+ * SARIF findings filtered to that file. The dashboard uses this to
7
+ * render a ReportGenerator-style annotated code view.
8
+ *
9
+ * The builder is extracted into its own module (rather than inlined in
10
+ * `server.ts`) so that:
11
+ * - The logic is unit-testable without booting the HTTP server.
12
+ * - The types are importable by both the Fastify route and tests.
13
+ *
14
+ * @module dashboard/file-detail
15
+ */
16
+ import { promises as fs } from "node:fs";
17
+ import { resolveWithinWorkspace } from "../workspace-guard.js";
18
+ import { detectLanguageFromPath } from "../ast/language-config.js";
19
+ // ── Builder ───────────────────────────────────────────────────────
20
+ /**
21
+ * Build the file detail payload. Pure function aside from the file
22
+ * read and the tree-sitter analysis (both deterministic for a given
23
+ * file).
24
+ *
25
+ * @throws When the file does not exist or the path escapes the workspace.
26
+ */
27
+ export async function buildFileDetail(input) {
28
+ const { relativePath, workspaceRoot, astEngine, sarifStore, cyclomaticMax } = input;
29
+ // 1. Guard against path traversal
30
+ const absolutePath = resolveWithinWorkspace(workspaceRoot, relativePath);
31
+ // 2. Read source
32
+ const source = await fs.readFile(absolutePath, "utf8");
33
+ const sourceLines = source.split(/\r?\n/);
34
+ // Remove trailing empty line from files ending with \n
35
+ if (sourceLines.length > 0 && sourceLines[sourceLines.length - 1] === "") {
36
+ sourceLines.pop();
37
+ }
38
+ const physicalLoc = sourceLines.length;
39
+ let logicalLoc = 0;
40
+ for (const line of sourceLines) {
41
+ if (line.trim().length > 0)
42
+ logicalLoc += 1;
43
+ }
44
+ // 3. AST analysis (if language is supported)
45
+ const language = detectLanguageFromPath(relativePath);
46
+ let functions = [];
47
+ if (language && astEngine) {
48
+ try {
49
+ const metrics = await astEngine.analyzeFile({
50
+ filePath: absolutePath,
51
+ language,
52
+ });
53
+ functions = metrics.functions.map((fn) => ({
54
+ name: fn.name,
55
+ startLine: fn.startLine,
56
+ endLine: fn.endLine,
57
+ cyclomaticComplexity: fn.cyclomaticComplexity,
58
+ lineCount: fn.lineCount,
59
+ }));
60
+ }
61
+ catch {
62
+ // Analysis failure is non-fatal — return empty functions
63
+ }
64
+ }
65
+ // 4. Filter SARIF findings for this file
66
+ const allFindings = sarifStore.list();
67
+ const fileFindings = allFindings.filter((f) => f.location.uri === relativePath);
68
+ const findings = fileFindings.map((f) => ({
69
+ ruleId: f.ruleId,
70
+ level: f.level,
71
+ message: f.message,
72
+ sourceTool: f.sourceTool,
73
+ startLine: f.location.startLine,
74
+ startColumn: f.location.startColumn,
75
+ endLine: f.location.endLine ?? f.location.startLine,
76
+ endColumn: f.location.endColumn ?? 0,
77
+ effortMinutes: typeof f.properties?.effortMinutes === "number"
78
+ ? f.properties.effortMinutes
79
+ : 0,
80
+ }));
81
+ // 5. Build summary
82
+ let errorCount = 0;
83
+ let warningCount = 0;
84
+ let noteCount = 0;
85
+ let totalEffortMinutes = 0;
86
+ for (const f of findings) {
87
+ if (f.level === "error")
88
+ errorCount += 1;
89
+ else if (f.level === "warning")
90
+ warningCount += 1;
91
+ else if (f.level === "note")
92
+ noteCount += 1;
93
+ totalEffortMinutes += f.effortMinutes;
94
+ }
95
+ const complexities = functions.map((f) => f.cyclomaticComplexity);
96
+ const maxComplexity = complexities.length > 0 ? Math.max(...complexities) : 0;
97
+ const avgComplexity = complexities.length > 0
98
+ ? Math.round((complexities.reduce((a, b) => a + b, 0) / complexities.length) * 100) / 100
99
+ : 0;
100
+ return {
101
+ filePath: relativePath,
102
+ language,
103
+ physicalLoc,
104
+ logicalLoc,
105
+ cyclomaticMax,
106
+ sourceLines,
107
+ functions,
108
+ findings,
109
+ summary: {
110
+ totalFindings: findings.length,
111
+ errorCount,
112
+ warningCount,
113
+ noteCount,
114
+ totalEffortMinutes,
115
+ avgComplexity,
116
+ maxComplexity,
117
+ },
118
+ };
119
+ }
120
+ //# sourceMappingURL=file-detail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-detail.js","sourceRoot":"","sources":["../../src/dashboard/file-detail.ts"],"names":[],"mappings":"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"}