@nielspeter/sonarlint-mcp-server 0.3.1 → 0.4.1

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 (54) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +14 -1
  3. package/dist/errors.d.ts.map +1 -1
  4. package/dist/errors.js +7 -1
  5. package/dist/errors.js.map +1 -1
  6. package/dist/index.js +5 -23
  7. package/dist/index.js.map +1 -1
  8. package/dist/sloop-bridge.d.ts +10 -1
  9. package/dist/sloop-bridge.d.ts.map +1 -1
  10. package/dist/sloop-bridge.js +102 -160
  11. package/dist/sloop-bridge.js.map +1 -1
  12. package/dist/state.d.ts +2 -1
  13. package/dist/state.d.ts.map +1 -1
  14. package/dist/state.js +6 -2
  15. package/dist/state.js.map +1 -1
  16. package/dist/tools/analyze-content.js +1 -1
  17. package/dist/tools/analyze-content.js.map +1 -1
  18. package/dist/tools/analyze-file.d.ts.map +1 -1
  19. package/dist/tools/analyze-file.js +4 -6
  20. package/dist/tools/analyze-file.js.map +1 -1
  21. package/dist/tools/analyze-files.d.ts.map +1 -1
  22. package/dist/tools/analyze-files.js +75 -71
  23. package/dist/tools/analyze-files.js.map +1 -1
  24. package/dist/tools/apply-all-quick-fixes.d.ts.map +1 -1
  25. package/dist/tools/apply-all-quick-fixes.js +65 -139
  26. package/dist/tools/apply-all-quick-fixes.js.map +1 -1
  27. package/dist/tools/apply-quick-fix.d.ts.map +1 -1
  28. package/dist/tools/apply-quick-fix.js +5 -76
  29. package/dist/tools/apply-quick-fix.js.map +1 -1
  30. package/dist/tools/health-check.d.ts.map +1 -1
  31. package/dist/tools/health-check.js +15 -7
  32. package/dist/tools/health-check.js.map +1 -1
  33. package/dist/tools/list-active-rules.d.ts.map +1 -1
  34. package/dist/tools/list-active-rules.js +3 -2
  35. package/dist/tools/list-active-rules.js.map +1 -1
  36. package/dist/utils/file-registration.js +1 -1
  37. package/dist/utils/file-registration.js.map +1 -1
  38. package/dist/utils/formatting.d.ts.map +1 -1
  39. package/dist/utils/quick-fix.d.ts +14 -0
  40. package/dist/utils/quick-fix.d.ts.map +1 -0
  41. package/dist/utils/quick-fix.js +44 -0
  42. package/dist/utils/quick-fix.js.map +1 -0
  43. package/dist/utils/scope.d.ts +24 -3
  44. package/dist/utils/scope.d.ts.map +1 -1
  45. package/dist/utils/scope.js +46 -7
  46. package/dist/utils/scope.js.map +1 -1
  47. package/dist/utils/sloop.d.ts.map +1 -1
  48. package/dist/utils/sloop.js +5 -1
  49. package/dist/utils/sloop.js.map +1 -1
  50. package/package.json +1 -1
  51. package/dist/tools/analyze-project.d.ts +0 -7
  52. package/dist/tools/analyze-project.d.ts.map +0 -1
  53. package/dist/tools/analyze-project.js +0 -109
  54. package/dist/tools/analyze-project.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quick-fix.js","sourceRoot":"","sources":["../../src/utils/quick-fix.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAe,EAAE,QAAa;IAC3D,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,IAAI,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC;IACtE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,SAAS;YAAE,SAAS;QAElC,uDAAuD;QACvD,MAAM,WAAW,GAAG,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE;YAClE,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,eAAe,IAAI,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;YACxE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;YAEnC,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;gBAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;gBAC9B,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACpF,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC;gBACpE,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAClD,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,cAAc,GAA2B;IAC7C,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;CACrD,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAW,EACX,WAAmB;IAEnB,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;AACnF,CAAC"}
@@ -2,9 +2,30 @@
2
2
  * Configuration scope management utilities
3
3
  */
4
4
  /**
5
- * Get or create configuration scope for a project.
5
+ * Get or create a SLOOP configuration scope for a project.
6
+ *
6
7
  * Uses the project root (detected via package.json, .git, etc.) so all files
7
- * in the same project share one scope and one analysis call.
8
+ * in the same project share one scope.
9
+ *
10
+ * ## CRITICAL: File registration ordering
11
+ *
12
+ * SLOOP calls `listFiles` immediately when it receives `addConfigurationScope`.
13
+ * If no files are registered in `scopeFiles` at that point, the scope initialises
14
+ * with an empty file list and analysis will hang waiting for files that SLOOP
15
+ * never received.
16
+ *
17
+ * The correct sequence is:
18
+ * 1. Pre-register file DTOs in `scopeFiles` (so `listFiles` can return them)
19
+ * 2. Send `addConfigurationScope` notification to SLOOP
20
+ * 3. Wait for `didChangeAnalysisReadiness` (scope is ready)
21
+ * 4. Call `analyzeFilesAndTrack`
22
+ *
23
+ * Never scan the project directory in `listFiles` — only return the files the
24
+ * caller explicitly asked to analyse. Scanning caused 500+ file responses and
25
+ * multi-minute hangs on real projects.
26
+ *
27
+ * @param filePath - A file used to detect the project root
28
+ * @param filePaths - All files to analyse (registered so listFiles returns them)
8
29
  */
9
- export declare function getOrCreateScope(filePath: string): string;
30
+ export declare function getOrCreateScope(filePath: string, filePaths?: string[]): Promise<string>;
10
31
  //# sourceMappingURL=scope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2BH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwBzD"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4BH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2C9F"}
@@ -4,7 +4,8 @@
4
4
  import { dirname, join } from "path";
5
5
  import { existsSync } from "fs";
6
6
  import { createHash } from "crypto";
7
- import { scopeMap, getSloopBridge } from "../state.js";
7
+ import { scopeMap, scopeToProjectRoot, scopeFiles, getSloopBridge } from "../state.js";
8
+ import { buildClientFileDtos } from "./file-registration.js";
8
9
  /**
9
10
  * Find the project root by walking up to find package.json, .git, etc.
10
11
  */
@@ -23,28 +24,66 @@ function findProjectRoot(startPath) {
23
24
  return startPath;
24
25
  }
25
26
  /**
26
- * Get or create configuration scope for a project.
27
+ * Get or create a SLOOP configuration scope for a project.
28
+ *
27
29
  * Uses the project root (detected via package.json, .git, etc.) so all files
28
- * in the same project share one scope and one analysis call.
30
+ * in the same project share one scope.
31
+ *
32
+ * ## CRITICAL: File registration ordering
33
+ *
34
+ * SLOOP calls `listFiles` immediately when it receives `addConfigurationScope`.
35
+ * If no files are registered in `scopeFiles` at that point, the scope initialises
36
+ * with an empty file list and analysis will hang waiting for files that SLOOP
37
+ * never received.
38
+ *
39
+ * The correct sequence is:
40
+ * 1. Pre-register file DTOs in `scopeFiles` (so `listFiles` can return them)
41
+ * 2. Send `addConfigurationScope` notification to SLOOP
42
+ * 3. Wait for `didChangeAnalysisReadiness` (scope is ready)
43
+ * 4. Call `analyzeFilesAndTrack`
44
+ *
45
+ * Never scan the project directory in `listFiles` — only return the files the
46
+ * caller explicitly asked to analyse. Scanning caused 500+ file responses and
47
+ * multi-minute hangs on real projects.
48
+ *
49
+ * @param filePath - A file used to detect the project root
50
+ * @param filePaths - All files to analyse (registered so listFiles returns them)
29
51
  */
30
- export function getOrCreateScope(filePath) {
52
+ export async function getOrCreateScope(filePath, filePaths) {
31
53
  const projectRoot = findProjectRoot(dirname(filePath));
32
54
  const scopeId = scopeMap.get(projectRoot);
33
55
  if (scopeId) {
56
+ // Scope exists — register any new files so listFiles returns them
57
+ if (filePaths?.length) {
58
+ const dtos = buildClientFileDtos(filePaths, scopeId, projectRoot);
59
+ const existing = scopeFiles.get(scopeId) || [];
60
+ scopeFiles.set(scopeId, [...existing, ...dtos]);
61
+ }
34
62
  return scopeId;
35
63
  }
36
- // Create new scope ID based on project root hash
37
64
  const hash = createHash('md5').update(projectRoot).digest('hex').substring(0, 8);
38
65
  const newScopeId = `scope-${hash}`;
39
66
  console.error(`[MCP] Creating new configuration scope: ${newScopeId} for ${projectRoot}`);
40
- // Add scope to SLOOP
67
+ scopeToProjectRoot.set(newScopeId, projectRoot);
68
+ scopeMap.set(projectRoot, newScopeId);
69
+ // Step 1: Pre-register files BEFORE creating scope.
70
+ // SLOOP calls listFiles synchronously during addConfigurationScope — the files
71
+ // must already be in scopeFiles or listFiles returns an empty list and the
72
+ // scope never becomes ready.
73
+ const pathsToRegister = filePaths?.length ? filePaths : [filePath];
74
+ const dtos = buildClientFileDtos(pathsToRegister, newScopeId, projectRoot);
75
+ scopeFiles.set(newScopeId, dtos);
76
+ // Step 2–3: Create scope and wait for readiness
41
77
  const sloopBridge = getSloopBridge();
42
78
  if (sloopBridge) {
79
+ const readyPromise = sloopBridge.waitForScopeReady(newScopeId);
43
80
  sloopBridge.addConfigurationScope(newScopeId, {
44
81
  name: `Project: ${projectRoot}`,
45
82
  });
83
+ console.error(`[MCP] Waiting for scope ${newScopeId} to become ready...`);
84
+ await readyPromise;
85
+ console.error(`[MCP] Scope ${newScopeId} is ready for analysis`);
46
86
  }
47
- scopeMap.set(projectRoot, newScopeId);
48
87
  return newScopeId;
49
88
  }
50
89
  //# sourceMappingURL=scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvD;;GAEG;AACH,SAAS,eAAe,CAAC,SAAiB;IACxC,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,MAAM,OAAO,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAEhG,OAAO,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,0BAA0B;QACvD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;gBAClC,OAAO,GAAG,CAAC;YACb,CAAC;QACH,CAAC;QACD,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,uCAAuC;IACvC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE1C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,iDAAiD;IACjD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,SAAS,IAAI,EAAE,CAAC;IAEnC,OAAO,CAAC,KAAK,CAAC,2CAA2C,UAAU,QAAQ,WAAW,EAAE,CAAC,CAAC;IAE1F,qBAAqB;IACrB,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,CAAC,qBAAqB,CAAC,UAAU,EAAE;YAC5C,IAAI,EAAE,YAAY,WAAW,EAAE;SAChC,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACtC,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sloop.d.ts","sourceRoot":"","sources":["../../src/utils/sloop.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOjD,eAAO,MAAM,YAAY,QAA2B,CAAC;AAErD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CA+B9D"}
1
+ {"version":3,"file":"sloop.d.ts","sourceRoot":"","sources":["../../src/utils/sloop.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOjD,eAAO,MAAM,YAAY,QAA2B,CAAC;AAErD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CAoC9D"}
@@ -19,6 +19,8 @@ export async function ensureSloopBridge() {
19
19
  if (existing) {
20
20
  return existing;
21
21
  }
22
+ const t0 = Date.now();
23
+ const elapsed = () => `${((Date.now() - t0) / 1000).toFixed(1)}s`;
22
24
  console.error("[MCP] Initializing SLOOP bridge...");
23
25
  // Check if plugins are downloaded
24
26
  const pluginsDir = join(PACKAGE_ROOT, "sonarlint-backend", "plugins");
@@ -26,10 +28,12 @@ export async function ensureSloopBridge() {
26
28
  throw new SloopError("Backend not found", "SonarLint backend not installed. The postinstall script may have failed. Try reinstalling: npm install -g @nielspeter/sonarlint-mcp-server", false);
27
29
  }
28
30
  try {
31
+ console.error(`[MCP] +${elapsed()} Creating bridge...`);
29
32
  const bridge = new SloopBridge(PACKAGE_ROOT);
33
+ console.error(`[MCP] +${elapsed()} Connecting (starts Java + sends initialize)...`);
30
34
  await bridge.connect();
31
35
  setSloopBridge(bridge);
32
- console.error("[MCP] SLOOP bridge initialized successfully");
36
+ console.error(`[MCP] +${elapsed()} SLOOP bridge initialized successfully`);
33
37
  return bridge;
34
38
  }
35
39
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"sloop.js","sourceRoot":"","sources":["../../src/utils/sloop.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,oEAAoE;AACpE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAE,yCAAyC;AAEhG;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAEpD,kCAAkC;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,mBAAmB,EAAE,SAAS,CAAC,CAAC;IACtE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAClB,mBAAmB,EACnB,4IAA4I,EAC5I,KAAK,CACN,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,UAAU,CAClB,+BAA+B,KAAK,EAAE,EACtC,uFAAuF,EACvF,IAAI,CACL,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"sloop.js","sourceRoot":"","sources":["../../src/utils/sloop.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,oEAAoE;AACpE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAE,yCAAyC;AAEhG;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAClC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAElE,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAEpD,kCAAkC;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,mBAAmB,EAAE,SAAS,CAAC,CAAC;IACtE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAClB,mBAAmB,EACnB,4IAA4I,EAC5I,KAAK,CACN,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,qBAAqB,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,iDAAiD,CAAC,CAAC;QACpF,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,wCAAwC,CAAC,CAAC;QAC3E,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,UAAU,CAClB,+BAA+B,KAAK,EAAE,EACtC,uFAAuF,EACvF,IAAI,CACL,CAAC;IACJ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nielspeter/sonarlint-mcp-server",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "MCP server providing SonarLint code analysis for Claude Desktop and other MCP clients",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -1,7 +0,0 @@
1
- export declare function handleAnalyzeProject(args: any): Promise<{
2
- content: {
3
- type: "text";
4
- text: string;
5
- }[];
6
- }>;
7
- //# sourceMappingURL=analyze-project.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyze-project.d.ts","sourceRoot":"","sources":["../../src/tools/analyze-project.ts"],"names":[],"mappings":"AAKA,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,GAAG;;;;;GAoInD"}
@@ -1,109 +0,0 @@
1
- import { existsSync, statSync, readdirSync } from "fs";
2
- import { join, extname, relative, basename } from "path";
3
- import { SloopError } from "../errors.js";
4
- import { handleAnalyzeFiles } from "./analyze-files.js";
5
- export async function handleAnalyzeProject(args) {
6
- const { projectPath, maxFiles = 100, minSeverity, excludeRules, includePatterns } = args;
7
- // Validate project path exists
8
- if (!existsSync(projectPath)) {
9
- throw new SloopError(`Project path not found: ${projectPath}`, `The directory ${projectPath} does not exist. Please check the path and try again.`, false);
10
- }
11
- const stats = statSync(projectPath);
12
- if (!stats.isDirectory()) {
13
- throw new SloopError(`Not a directory: ${projectPath}`, `The path ${projectPath} is not a directory. Please provide a directory path.`, false);
14
- }
15
- console.error(`[MCP] Scanning project: ${projectPath}`);
16
- // Define supported extensions
17
- const supportedExtensions = ['.js', '.jsx', '.ts', '.tsx', '.py', '.java', '.go', '.php', '.rb', '.html', '.css', '.xml'];
18
- // Directories to exclude
19
- const excludeDirs = new Set([
20
- 'node_modules', 'dist', 'build', '.git', '.svn', '.hg',
21
- 'coverage', '.next', '.nuxt', 'out', 'target', 'bin',
22
- '__pycache__', '.pytest_cache', '.mypy_cache', 'venv', '.venv'
23
- ]);
24
- // Recursively find all source files
25
- function findSourceFiles(dir, files = []) {
26
- try {
27
- const entries = readdirSync(dir, { withFileTypes: true });
28
- for (const entry of entries) {
29
- // Skip excluded directories
30
- if (entry.isDirectory() && excludeDirs.has(entry.name)) {
31
- continue;
32
- }
33
- const fullPath = join(dir, entry.name);
34
- if (entry.isDirectory()) {
35
- findSourceFiles(fullPath, files);
36
- }
37
- else if (entry.isFile()) {
38
- const ext = extname(entry.name);
39
- if (supportedExtensions.includes(ext)) {
40
- // Check includePatterns if specified
41
- if (includePatterns && includePatterns.length > 0) {
42
- const relativePath = relative(projectPath, fullPath);
43
- // Simple pattern matching (supports ** and *)
44
- const matches = includePatterns.some(pattern => {
45
- const regex = new RegExp('^' + pattern.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*') + '$');
46
- return regex.test(relativePath);
47
- });
48
- if (matches) {
49
- files.push(fullPath);
50
- }
51
- }
52
- else {
53
- files.push(fullPath);
54
- }
55
- }
56
- }
57
- }
58
- }
59
- catch (err) {
60
- console.error(`[MCP] Error scanning directory ${dir}:`, err);
61
- }
62
- return files;
63
- }
64
- const allFiles = findSourceFiles(projectPath);
65
- console.error(`[MCP] Found ${allFiles.length} source files`);
66
- if (allFiles.length === 0) {
67
- return {
68
- content: [
69
- {
70
- type: "text",
71
- text: `No source files found in ${projectPath}.\n\nSupported extensions: ${supportedExtensions.join(', ')}`,
72
- },
73
- ],
74
- };
75
- }
76
- // Limit number of files
77
- const filesToAnalyze = allFiles.slice(0, maxFiles);
78
- if (allFiles.length > maxFiles) {
79
- console.error(`[MCP] Limiting analysis to ${maxFiles} files (found ${allFiles.length})`);
80
- }
81
- // Use handleAnalyzeFiles to do the actual analysis
82
- const result = await handleAnalyzeFiles({
83
- filePaths: filesToAnalyze,
84
- groupByFile: true,
85
- minSeverity,
86
- excludeRules,
87
- });
88
- // Add project-specific context to the output
89
- const resultText = result.content[0].text;
90
- const projectSummary = `
91
- 📦 Project Scan: ${basename(projectPath)}
92
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
93
-
94
- Project Path: ${projectPath}
95
- Total Source Files: ${allFiles.length}
96
- Files Analyzed: ${filesToAnalyze.length}
97
- ${allFiles.length > maxFiles ? `⚠️ Limited to ${maxFiles} files (use maxFiles parameter to adjust)\n` : ''}
98
- ${resultText}
99
- `;
100
- return {
101
- content: [
102
- {
103
- type: "text",
104
- text: projectSummary,
105
- },
106
- ],
107
- };
108
- }
109
- //# sourceMappingURL=analyze-project.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyze-project.js","sourceRoot":"","sources":["../../src/tools/analyze-project.ts"],"names":[],"mappings":"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"}