@nielspeter/sonarlint-mcp-server 0.1.3 → 0.2.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 (86) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +6 -12
  3. package/dist/errors.d.ts +22 -0
  4. package/dist/errors.d.ts.map +1 -0
  5. package/dist/errors.js +44 -0
  6. package/dist/errors.js.map +1 -0
  7. package/dist/index.js +115 -1330
  8. package/dist/index.js.map +1 -1
  9. package/dist/resources/session.d.ts +18 -0
  10. package/dist/resources/session.d.ts.map +1 -0
  11. package/dist/resources/session.js +84 -0
  12. package/dist/resources/session.js.map +1 -0
  13. package/dist/sloop-bridge.d.ts +0 -3
  14. package/dist/sloop-bridge.d.ts.map +1 -1
  15. package/dist/sloop-bridge.js +0 -19
  16. package/dist/sloop-bridge.js.map +1 -1
  17. package/dist/state.d.ts +19 -0
  18. package/dist/state.d.ts.map +1 -0
  19. package/dist/state.js +25 -0
  20. package/dist/state.js.map +1 -0
  21. package/dist/tools/analyze-content.d.ts +7 -0
  22. package/dist/tools/analyze-content.d.ts.map +1 -0
  23. package/dist/tools/analyze-content.js +78 -0
  24. package/dist/tools/analyze-content.js.map +1 -0
  25. package/dist/tools/analyze-file.d.ts +7 -0
  26. package/dist/tools/analyze-file.d.ts.map +1 -0
  27. package/dist/tools/analyze-file.js +66 -0
  28. package/dist/tools/analyze-file.js.map +1 -0
  29. package/dist/tools/analyze-files.d.ts +7 -0
  30. package/dist/tools/analyze-files.d.ts.map +1 -0
  31. package/dist/tools/analyze-files.js +106 -0
  32. package/dist/tools/analyze-files.js.map +1 -0
  33. package/dist/tools/analyze-project.d.ts +7 -0
  34. package/dist/tools/analyze-project.d.ts.map +1 -0
  35. package/dist/tools/analyze-project.js +109 -0
  36. package/dist/tools/analyze-project.js.map +1 -0
  37. package/dist/tools/apply-all-quick-fixes.d.ts +7 -0
  38. package/dist/tools/apply-all-quick-fixes.d.ts.map +1 -0
  39. package/dist/tools/apply-all-quick-fixes.js +166 -0
  40. package/dist/tools/apply-all-quick-fixes.js.map +1 -0
  41. package/dist/tools/apply-quick-fix.d.ts +7 -0
  42. package/dist/tools/apply-quick-fix.d.ts.map +1 -0
  43. package/dist/tools/apply-quick-fix.js +113 -0
  44. package/dist/tools/apply-quick-fix.js.map +1 -0
  45. package/dist/tools/health-check.d.ts +7 -0
  46. package/dist/tools/health-check.d.ts.map +1 -0
  47. package/dist/tools/health-check.js +113 -0
  48. package/dist/tools/health-check.js.map +1 -0
  49. package/dist/tools/list-active-rules.d.ts +7 -0
  50. package/dist/tools/list-active-rules.d.ts.map +1 -0
  51. package/dist/tools/list-active-rules.js +48 -0
  52. package/dist/tools/list-active-rules.js.map +1 -0
  53. package/dist/types.d.ts +62 -0
  54. package/dist/types.d.ts.map +1 -0
  55. package/dist/types.js +5 -0
  56. package/dist/types.js.map +1 -0
  57. package/dist/utils/filesystem.d.ts +8 -0
  58. package/dist/utils/filesystem.d.ts.map +1 -0
  59. package/dist/utils/filesystem.js +74 -0
  60. package/dist/utils/filesystem.js.map +1 -0
  61. package/dist/utils/formatting.d.ts +13 -0
  62. package/dist/utils/formatting.d.ts.map +1 -0
  63. package/dist/utils/formatting.js +94 -0
  64. package/dist/utils/formatting.js.map +1 -0
  65. package/dist/utils/language.d.ts +12 -0
  66. package/dist/utils/language.d.ts.map +1 -0
  67. package/dist/utils/language.js +44 -0
  68. package/dist/utils/language.js.map +1 -0
  69. package/dist/utils/scope.d.ts +8 -0
  70. package/dist/utils/scope.d.ts.map +1 -0
  71. package/dist/utils/scope.js +30 -0
  72. package/dist/utils/scope.js.map +1 -0
  73. package/dist/utils/sloop.d.ts +10 -0
  74. package/dist/utils/sloop.d.ts.map +1 -0
  75. package/dist/utils/sloop.js +39 -0
  76. package/dist/utils/sloop.js.map +1 -0
  77. package/dist/utils/transforms.d.ts +23 -0
  78. package/dist/utils/transforms.d.ts.map +1 -0
  79. package/dist/utils/transforms.js +64 -0
  80. package/dist/utils/transforms.js.map +1 -0
  81. package/package.json +10 -7
  82. package/scripts/setup-sonarlint.sh +115 -39
  83. package/dist/sonarlint-bridge.d.ts +0 -33
  84. package/dist/sonarlint-bridge.d.ts.map +0 -1
  85. package/dist/sonarlint-bridge.js +0 -91
  86. package/dist/sonarlint-bridge.js.map +0 -1
@@ -0,0 +1,113 @@
1
+ import { existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { dirname } from "path";
5
+ import { sessionResults, batchResults, sloopBridge, serverStartTime } from "../state.js";
6
+ // Get package root directory (where sonarlint-backend is installed)
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ const PACKAGE_ROOT = join(__dirname, '..', '..'); // Go up from dist/tools/ to package root
10
+ export async function handleHealthCheck() {
11
+ console.error(`[MCP] Running health check...`);
12
+ const uptimeMs = Date.now() - serverStartTime;
13
+ const uptimeSeconds = Math.floor(uptimeMs / 1000);
14
+ const uptimeMinutes = Math.floor(uptimeSeconds / 60);
15
+ const uptimeHours = Math.floor(uptimeMinutes / 60);
16
+ const memoryUsage = process.memoryUsage();
17
+ const memoryMB = Math.round(memoryUsage.heapUsed / 1024 / 1024);
18
+ // Check SLOOP status
19
+ const sloopStatus = sloopBridge ? "running" : "not started";
20
+ // Get plugin information
21
+ const pluginsDir = join(PACKAGE_ROOT, "sonarlint-backend", "plugins");
22
+ const pluginsExist = existsSync(pluginsDir);
23
+ let plugins = [];
24
+ if (pluginsExist) {
25
+ const files = readdirSync(pluginsDir);
26
+ const jarFiles = files.filter(f => f.endsWith('.jar'));
27
+ for (const jarFile of jarFiles) {
28
+ // Parse plugin name and version from filename
29
+ const match = jarFile.match(/sonar-(\w+)-plugin-([\d.]+)\.jar/);
30
+ if (match) {
31
+ plugins.push({
32
+ name: match[1].charAt(0).toUpperCase() + match[1].slice(1),
33
+ version: match[2],
34
+ status: "active",
35
+ });
36
+ }
37
+ }
38
+ }
39
+ // Cache statistics
40
+ const cacheStats = {
41
+ sessionResults: sessionResults.size,
42
+ batchResults: batchResults.size,
43
+ };
44
+ const healthStatus = {
45
+ status: sloopStatus === "running" && pluginsExist ? "healthy" : "degraded",
46
+ version: "1.0.0 (Phase 3)",
47
+ uptime: {
48
+ milliseconds: uptimeMs,
49
+ seconds: uptimeSeconds,
50
+ minutes: uptimeMinutes,
51
+ hours: uptimeHours,
52
+ formatted: `${uptimeHours}h ${uptimeMinutes % 60}m ${uptimeSeconds % 60}s`,
53
+ },
54
+ backend: {
55
+ status: sloopStatus,
56
+ pluginsDirectory: pluginsExist ? "found" : "missing",
57
+ },
58
+ plugins,
59
+ memory: {
60
+ heapUsed: `${memoryMB}MB`,
61
+ heapTotal: `${Math.round(memoryUsage.heapTotal / 1024 / 1024)}MB`,
62
+ rss: `${Math.round(memoryUsage.rss / 1024 / 1024)}MB`,
63
+ },
64
+ cache: cacheStats,
65
+ tools: ["analyze_file", "analyze_files", "analyze_content", "list_active_rules", "health_check"],
66
+ features: [
67
+ "Session storage for multi-turn conversations",
68
+ "Batch analysis",
69
+ "Content analysis (unsaved files)",
70
+ "MCP resources",
71
+ "Quick fixes support",
72
+ ],
73
+ };
74
+ let output = `# SonarLint MCP Server Health Check\n\n`;
75
+ output += `**Status**: ${healthStatus.status === "healthy" ? "✅ Healthy" : "⚠️ Degraded"}\n`;
76
+ output += `**Version**: ${healthStatus.version}\n`;
77
+ output += `**Uptime**: ${healthStatus.uptime.formatted}\n\n`;
78
+ output += `## Backend Status\n\n`;
79
+ output += `- **SLOOP Backend**: ${healthStatus.backend.status}\n`;
80
+ output += `- **Plugins Directory**: ${healthStatus.backend.pluginsDirectory}\n\n`;
81
+ if (plugins.length > 0) {
82
+ output += `## Active Plugins\n\n`;
83
+ for (const plugin of plugins) {
84
+ output += `- **${plugin.name}**: v${plugin.version} (${plugin.status})\n`;
85
+ }
86
+ output += `\n`;
87
+ }
88
+ output += `## Memory Usage\n\n`;
89
+ output += `- **Heap Used**: ${healthStatus.memory.heapUsed}\n`;
90
+ output += `- **Heap Total**: ${healthStatus.memory.heapTotal}\n`;
91
+ output += `- **RSS**: ${healthStatus.memory.rss}\n\n`;
92
+ output += `## Cache Statistics\n\n`;
93
+ output += `- **Session Results**: ${healthStatus.cache.sessionResults} stored\n`;
94
+ output += `- **Batch Results**: ${healthStatus.cache.batchResults} stored\n\n`;
95
+ output += `## Available Tools\n\n`;
96
+ for (const tool of healthStatus.tools) {
97
+ output += `- ${tool}\n`;
98
+ }
99
+ output += `\n`;
100
+ output += `## Features\n\n`;
101
+ for (const feature of healthStatus.features) {
102
+ output += `- ${feature}\n`;
103
+ }
104
+ return {
105
+ content: [
106
+ {
107
+ type: "text",
108
+ text: output,
109
+ },
110
+ ],
111
+ };
112
+ }
113
+ //# sourceMappingURL=health-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.js","sourceRoot":"","sources":["../../src/tools/health-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function handleListActiveRules(args: any): Promise<{
2
+ content: {
3
+ type: "text";
4
+ text: string;
5
+ }[];
6
+ }>;
7
+ //# sourceMappingURL=list-active-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-active-rules.d.ts","sourceRoot":"","sources":["../../src/tools/list-active-rules.ts"],"names":[],"mappings":"AAAA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,GAAG;;;;;GAoDpD"}
@@ -0,0 +1,48 @@
1
+ export async function handleListActiveRules(args) {
2
+ const { language } = args;
3
+ console.error(`[MCP] Listing active rules${language ? ` for ${language}` : ''}`);
4
+ // TODO: Extract actual rules from SLOOP plugins via RPC
5
+ // For now, return a summary of known rules
6
+ let output = `# Active SonarLint Rules\n\n`;
7
+ if (!language || language === 'javascript' || language === 'typescript') {
8
+ output += `## JavaScript/TypeScript Rules\n\n`;
9
+ output += `**Total Rules**: 265\n\n`;
10
+ output += `### Rule Categories\n\n`;
11
+ output += `- **Code Smells**: Rules that detect maintainability issues\n`;
12
+ output += ` - \`S1481\`: Unused local variables\n`;
13
+ output += ` - \`S1854\`: Useless assignments\n`;
14
+ output += ` - \`S3504\`: Prefer let/const over var\n`;
15
+ output += ` - \`S107\`: Too many parameters\n`;
16
+ output += ` - \`S4144\`: Duplicate implementations\n`;
17
+ output += ` - \`S2589\`: Always-truthy expressions\n\n`;
18
+ output += `- **Bugs**: Rules that detect potential errors\n`;
19
+ output += ` - \`S2259\`: Null pointer dereference\n`;
20
+ output += ` - \`S3776\`: Cognitive complexity\n\n`;
21
+ output += `- **Security**: Rules that detect security vulnerabilities\n`;
22
+ output += ` - \`S5852\`: Regular expression DoS\n`;
23
+ output += ` - \`S2068\`: Hard-coded credentials\n\n`;
24
+ }
25
+ if (!language || language === 'python') {
26
+ output += `## Python Rules\n\n`;
27
+ output += `**Total Rules**: ~200\n\n`;
28
+ output += `### Rule Categories\n\n`;
29
+ output += `- **Code Smells**: Maintainability issues\n`;
30
+ output += ` - \`S1066\`: Nested if statements\n`;
31
+ output += ` - \`S1192\`: String literals duplicated\n\n`;
32
+ output += `- **Bugs**: Potential errors\n`;
33
+ output += ` - \`S5754\`: Unreachable code\n\n`;
34
+ output += `- **Security**: Security vulnerabilities\n`;
35
+ output += ` - \`S5659\`: Weak encryption\n\n`;
36
+ }
37
+ output += `\n---\n\n`;
38
+ output += `*Note: This is a summary of active rules. Full rule details are available at https://rules.sonarsource.com/*\n`;
39
+ return {
40
+ content: [
41
+ {
42
+ type: "text",
43
+ text: output,
44
+ },
45
+ ],
46
+ };
47
+ }
48
+ //# sourceMappingURL=list-active-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-active-rules.js","sourceRoot":"","sources":["../../src/tools/list-active-rules.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAS;IACnD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAA6B,CAAC;IAEnD,OAAO,CAAC,KAAK,CAAC,6BAA6B,QAAQ,CAAC,CAAC,CAAC,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEjF,wDAAwD;IACxD,2CAA2C;IAC3C,IAAI,MAAM,GAAG,8BAA8B,CAAC;IAE5C,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QACxE,MAAM,IAAI,oCAAoC,CAAC;QAC/C,MAAM,IAAI,0BAA0B,CAAC;QACrC,MAAM,IAAI,yBAAyB,CAAC;QACpC,MAAM,IAAI,+DAA+D,CAAC;QAC1E,MAAM,IAAI,yCAAyC,CAAC;QACpD,MAAM,IAAI,sCAAsC,CAAC;QACjD,MAAM,IAAI,4CAA4C,CAAC;QACvD,MAAM,IAAI,qCAAqC,CAAC;QAChD,MAAM,IAAI,4CAA4C,CAAC;QACvD,MAAM,IAAI,8CAA8C,CAAC;QACzD,MAAM,IAAI,kDAAkD,CAAC;QAC7D,MAAM,IAAI,2CAA2C,CAAC;QACtD,MAAM,IAAI,yCAAyC,CAAC;QACpD,MAAM,IAAI,8DAA8D,CAAC;QACzE,MAAM,IAAI,yCAAyC,CAAC;QACpD,MAAM,IAAI,2CAA2C,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,IAAI,qBAAqB,CAAC;QAChC,MAAM,IAAI,2BAA2B,CAAC;QACtC,MAAM,IAAI,yBAAyB,CAAC;QACpC,MAAM,IAAI,6CAA6C,CAAC;QACxD,MAAM,IAAI,uCAAuC,CAAC;QAClD,MAAM,IAAI,+CAA+C,CAAC;QAC1D,MAAM,IAAI,gCAAgC,CAAC;QAC3C,MAAM,IAAI,qCAAqC,CAAC;QAChD,MAAM,IAAI,4CAA4C,CAAC;QACvD,MAAM,IAAI,oCAAoC,CAAC;IACjD,CAAC;IAED,MAAM,IAAI,WAAW,CAAC;IACtB,MAAM,IAAI,gHAAgH,CAAC;IAE3H,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,MAAM;aACb;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Shared type definitions for the SonarLint MCP Server
3
+ */
4
+ export interface AnalysisIssue {
5
+ line: number;
6
+ column: number;
7
+ endLine: number;
8
+ endColumn: number;
9
+ severity: "INFO" | "MINOR" | "MAJOR" | "CRITICAL" | "BLOCKER";
10
+ rule: string;
11
+ ruleDescription: string;
12
+ message: string;
13
+ quickFix?: QuickFix;
14
+ }
15
+ export interface QuickFix {
16
+ description: string;
17
+ edits: TextEdit[];
18
+ }
19
+ export interface TextEdit {
20
+ startLine: number;
21
+ startColumn: number;
22
+ endLine: number;
23
+ endColumn: number;
24
+ newText: string;
25
+ }
26
+ export interface AnalysisResult {
27
+ filePath: string;
28
+ language: string;
29
+ issues: AnalysisIssue[];
30
+ summary: {
31
+ total: number;
32
+ bySeverity: {
33
+ blocker: number;
34
+ critical: number;
35
+ major: number;
36
+ minor: number;
37
+ info: number;
38
+ };
39
+ rulesChecked: number;
40
+ };
41
+ }
42
+ export interface BatchAnalysisResult {
43
+ files: Array<{
44
+ filePath: string;
45
+ language: string;
46
+ issueCount: number;
47
+ issues: AnalysisIssue[];
48
+ }>;
49
+ summary: {
50
+ totalFiles: number;
51
+ totalIssues: number;
52
+ filesWithIssues: number;
53
+ bySeverity: {
54
+ blocker: number;
55
+ critical: number;
56
+ major: number;
57
+ minor: number;
58
+ info: number;
59
+ };
60
+ };
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE;YACV,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;QACF,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,aAAa,EAAE,CAAC;KACzB,CAAC,CAAC;IACH,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE;YACV,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;KACH,CAAC;CACH"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared type definitions for the SonarLint MCP Server
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * File system utilities for SLOOP integration
3
+ */
4
+ /**
5
+ * Notify SLOOP that file system was updated (proper cache invalidation)
6
+ */
7
+ export declare function notifyFileSystemChanged(filePath: string, configScopeId: string): Promise<void>;
8
+ //# sourceMappingURL=filesystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/utils/filesystem.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsEpG"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * File system utilities for SLOOP integration
3
+ */
4
+ import { dirname, relative } from "path";
5
+ import { readFileSync } from "fs";
6
+ import { scopeMap } from "../state.js";
7
+ import { detectLanguage, languageToEnum } from "./language.js";
8
+ import { ensureSloopBridge } from "./sloop.js";
9
+ /**
10
+ * Notify SLOOP that file system was updated (proper cache invalidation)
11
+ */
12
+ export async function notifyFileSystemChanged(filePath, configScopeId) {
13
+ const uri = `file://${filePath}`;
14
+ // Get project root from scopeMap (reverse lookup)
15
+ let projectRoot;
16
+ for (const [root, scopeId] of scopeMap.entries()) {
17
+ if (scopeId === configScopeId) {
18
+ projectRoot = root;
19
+ break;
20
+ }
21
+ }
22
+ // If no project root found, use file's directory
23
+ if (!projectRoot) {
24
+ projectRoot = dirname(filePath);
25
+ }
26
+ const relativePath = relative(projectRoot, filePath);
27
+ try {
28
+ const bridge = await ensureSloopBridge();
29
+ // Detect language from file extension
30
+ const language = detectLanguage(filePath);
31
+ const languageEnum = languageToEnum(language);
32
+ // CRITICAL: Tell SLOOP the file is "open" so it will re-analyze on file system updates
33
+ // Without this, SLOOP ignores changes to "closed" files
34
+ bridge.sendNotification('file/didOpenFile', {
35
+ configurationScopeId: configScopeId,
36
+ fileUri: uri
37
+ });
38
+ console.error(`[FS] Marked file as open: ${filePath}`);
39
+ // Read the actual file content to pass to SLOOP
40
+ // This ensures SLOOP gets the latest content instead of reading from its cache
41
+ const fileContent = readFileSync(filePath, 'utf-8');
42
+ // Build ClientFileDto
43
+ // Pass BOTH fsPath and content - fromDto will call setDirty(content) which takes precedence
44
+ const clientFileDto = {
45
+ uri,
46
+ ideRelativePath: relativePath,
47
+ configScopeId,
48
+ isTest: null,
49
+ charset: 'UTF-8',
50
+ fsPath: filePath, // Provide fsPath for analyzers that need it
51
+ content: fileContent, // Providing content calls setDirty(), which takes precedence over fsPath
52
+ detectedLanguage: languageEnum, // e.g., "JS", "TS", "PYTHON"
53
+ isUserDefined: true // CRITICAL: Must be true for SLOOP to analyze!
54
+ };
55
+ // Send file/didUpdateFileSystem notification
56
+ bridge.sendNotification('file/didUpdateFileSystem', {
57
+ addedFiles: [],
58
+ changedFiles: [clientFileDto],
59
+ removedFiles: []
60
+ });
61
+ console.error(`[FS] Notified file system update:`);
62
+ console.error(`[FS] URI: ${uri}`);
63
+ console.error(`[FS] Language: ${languageEnum}`);
64
+ console.error(`[FS] Relative: ${relativePath}`);
65
+ console.error(`[FS] ConfigScopeId: ${configScopeId}`);
66
+ console.error(`[FS] Content length: ${fileContent.length} chars`);
67
+ console.error(`[FS] First 100 chars: ${fileContent.substring(0, 100)}`);
68
+ }
69
+ catch (err) {
70
+ console.error(`[FS] Failed to notify file system update for ${filePath}:`, err);
71
+ // Don't throw - this is not critical
72
+ }
73
+ }
74
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/utils/filesystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Output formatting utilities
3
+ */
4
+ import type { AnalysisResult, BatchAnalysisResult } from "../types.js";
5
+ /**
6
+ * Format analysis result for display
7
+ */
8
+ export declare function formatAnalysisResult(result: AnalysisResult): string;
9
+ /**
10
+ * Format batch analysis result for display
11
+ */
12
+ export declare function formatBatchAnalysisResult(result: BatchAnalysisResult): string;
13
+ //# sourceMappingURL=formatting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAiB,MAAM,aAAa,CAAC;AAEtF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAyCnE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CA8C7E"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Output formatting utilities
3
+ */
4
+ /**
5
+ * Format analysis result for display
6
+ */
7
+ export function formatAnalysisResult(result) {
8
+ const { filePath, language, issues, summary } = result;
9
+ let output = `# Analysis Results: ${filePath}\n\n`;
10
+ output += `**Language**: ${language}\n`;
11
+ output += `**Rules Checked**: ${summary.rulesChecked}\n`;
12
+ output += `**Total Issues**: ${summary.total}\n\n`;
13
+ if (summary.total === 0) {
14
+ output += "✅ No issues found!\n";
15
+ return output;
16
+ }
17
+ // Severity breakdown
18
+ output += `## Issues by Severity\n\n`;
19
+ if (summary.bySeverity.blocker > 0)
20
+ output += `- 🔴 **BLOCKER**: ${summary.bySeverity.blocker}\n`;
21
+ if (summary.bySeverity.critical > 0)
22
+ output += `- 🟠 **CRITICAL**: ${summary.bySeverity.critical}\n`;
23
+ if (summary.bySeverity.major > 0)
24
+ output += `- 🟡 **MAJOR**: ${summary.bySeverity.major}\n`;
25
+ if (summary.bySeverity.minor > 0)
26
+ output += `- 🔵 **MINOR**: ${summary.bySeverity.minor}\n`;
27
+ if (summary.bySeverity.info > 0)
28
+ output += `- ⚪ **INFO**: ${summary.bySeverity.info}\n`;
29
+ output += `\n`;
30
+ // Detailed issues
31
+ output += `## Detailed Issues\n\n`;
32
+ // Sort by line number
33
+ const sortedIssues = [...issues].sort((a, b) => a.line - b.line);
34
+ for (const issue of sortedIssues) {
35
+ output += `### Line ${issue.line}:${issue.column} - ${issue.severity}\n\n`;
36
+ output += `**Rule**: \`${issue.rule}\`\n\n`;
37
+ output += `**Message**: ${issue.message}\n\n`;
38
+ if (issue.quickFix) {
39
+ output += `**Quick Fix Available**: ${issue.quickFix.description}\n\n`;
40
+ }
41
+ output += `---\n\n`;
42
+ }
43
+ return output;
44
+ }
45
+ /**
46
+ * Format batch analysis result for display
47
+ */
48
+ export function formatBatchAnalysisResult(result) {
49
+ const { files, summary } = result;
50
+ let output = `# Batch Analysis Results\n\n`;
51
+ output += `**Total Files**: ${summary.totalFiles}\n`;
52
+ output += `**Files with Issues**: ${summary.filesWithIssues}\n`;
53
+ output += `**Total Issues**: ${summary.totalIssues}\n\n`;
54
+ // Overall severity breakdown
55
+ output += `## Overall Issues by Severity\n\n`;
56
+ if (summary.bySeverity.blocker > 0)
57
+ output += `- 🔴 **BLOCKER**: ${summary.bySeverity.blocker}\n`;
58
+ if (summary.bySeverity.critical > 0)
59
+ output += `- 🟠 **CRITICAL**: ${summary.bySeverity.critical}\n`;
60
+ if (summary.bySeverity.major > 0)
61
+ output += `- 🟡 **MAJOR**: ${summary.bySeverity.major}\n`;
62
+ if (summary.bySeverity.minor > 0)
63
+ output += `- 🔵 **MINOR**: ${summary.bySeverity.minor}\n`;
64
+ if (summary.bySeverity.info > 0)
65
+ output += `- ⚪ **INFO**: ${summary.bySeverity.info}\n`;
66
+ output += `\n`;
67
+ // File-by-file breakdown
68
+ output += `## Issues by File\n\n`;
69
+ for (const file of files) {
70
+ if (file.issueCount === 0) {
71
+ output += `### ✅ ${file.filePath}\n\nNo issues found.\n\n`;
72
+ }
73
+ else {
74
+ output += `### ${file.filePath} (${file.issueCount} issue${file.issueCount > 1 ? 's' : ''})\n\n`;
75
+ // Group by severity
76
+ const bySeverity = {};
77
+ for (const issue of file.issues) {
78
+ if (!bySeverity[issue.severity]) {
79
+ bySeverity[issue.severity] = [];
80
+ }
81
+ bySeverity[issue.severity].push(issue);
82
+ }
83
+ for (const [severity, issues] of Object.entries(bySeverity)) {
84
+ output += `**${severity}** (${issues.length}):\n`;
85
+ for (const issue of issues) {
86
+ output += `- Line ${issue.line}: ${issue.message} [\`${issue.rule}\`]\n`;
87
+ }
88
+ output += `\n`;
89
+ }
90
+ }
91
+ }
92
+ return output;
93
+ }
94
+ //# sourceMappingURL=formatting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAEvD,IAAI,MAAM,GAAG,uBAAuB,QAAQ,MAAM,CAAC;IACnD,MAAM,IAAI,iBAAiB,QAAQ,IAAI,CAAC;IACxC,MAAM,IAAI,sBAAsB,OAAO,CAAC,YAAY,IAAI,CAAC;IACzD,MAAM,IAAI,qBAAqB,OAAO,CAAC,KAAK,MAAM,CAAC;IAEnD,IAAI,OAAO,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,sBAAsB,CAAC;QACjC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,qBAAqB;IACrB,MAAM,IAAI,2BAA2B,CAAC;IACtC,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,qBAAqB,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC;IAClG,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,GAAG,CAAC;QAAE,MAAM,IAAI,sBAAsB,OAAO,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC;IACrG,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,mBAAmB,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC5F,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,mBAAmB,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC5F,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,iBAAiB,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;IACxF,MAAM,IAAI,IAAI,CAAC;IAEf,kBAAkB;IAClB,MAAM,IAAI,wBAAwB,CAAC;IAEnC,sBAAsB;IACtB,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAEjE,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,MAAM,IAAI,YAAY,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,QAAQ,MAAM,CAAC;QAC3E,MAAM,IAAI,eAAe,KAAK,CAAC,IAAI,QAAQ,CAAC;QAC5C,MAAM,IAAI,gBAAgB,KAAK,CAAC,OAAO,MAAM,CAAC;QAE9C,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,4BAA4B,KAAK,CAAC,QAAQ,CAAC,WAAW,MAAM,CAAC;QACzE,CAAC;QAED,MAAM,IAAI,SAAS,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAA2B;IACnE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAElC,IAAI,MAAM,GAAG,8BAA8B,CAAC;IAC5C,MAAM,IAAI,oBAAoB,OAAO,CAAC,UAAU,IAAI,CAAC;IACrD,MAAM,IAAI,0BAA0B,OAAO,CAAC,eAAe,IAAI,CAAC;IAChE,MAAM,IAAI,qBAAqB,OAAO,CAAC,WAAW,MAAM,CAAC;IAEzD,6BAA6B;IAC7B,MAAM,IAAI,mCAAmC,CAAC;IAC9C,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC;QAAE,MAAM,IAAI,qBAAqB,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC;IAClG,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,GAAG,CAAC;QAAE,MAAM,IAAI,sBAAsB,OAAO,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC;IACrG,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,mBAAmB,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC5F,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC;QAAE,MAAM,IAAI,mBAAmB,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC5F,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,iBAAiB,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;IACxF,MAAM,IAAI,IAAI,CAAC;IAEf,yBAAyB;IACzB,MAAM,IAAI,uBAAuB,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,IAAI,CAAC,QAAQ,0BAA0B,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,UAAU,SAAS,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;YAEjG,oBAAoB;YACpB,MAAM,UAAU,GAAoC,EAAE,CAAC;YACvD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;gBAClC,CAAC;gBACD,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;YAED,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,QAAQ,OAAO,MAAM,CAAC,MAAM,MAAM,CAAC;gBAClD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,MAAM,IAAI,UAAU,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,IAAI,OAAO,CAAC;gBAC3E,CAAC;gBACD,MAAM,IAAI,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Language detection and mapping utilities
3
+ */
4
+ /**
5
+ * Detect language from file extension
6
+ */
7
+ export declare function detectLanguage(filePath: string): string;
8
+ /**
9
+ * Map language name to SLOOP Language enum
10
+ */
11
+ export declare function languageToEnum(language: string): string;
12
+ //# sourceMappingURL=language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/utils/language.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcvD"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Language detection and mapping utilities
3
+ */
4
+ import { extname } from "path";
5
+ /**
6
+ * Detect language from file extension
7
+ */
8
+ export function detectLanguage(filePath) {
9
+ const ext = extname(filePath).toLowerCase();
10
+ const languageMap = {
11
+ '.js': 'javascript',
12
+ '.jsx': 'javascript',
13
+ '.ts': 'typescript',
14
+ '.tsx': 'typescript',
15
+ '.py': 'python',
16
+ '.java': 'java',
17
+ '.go': 'go',
18
+ '.php': 'php',
19
+ '.rb': 'ruby',
20
+ '.html': 'html',
21
+ '.css': 'css',
22
+ '.xml': 'xml',
23
+ };
24
+ return languageMap[ext] || 'unknown';
25
+ }
26
+ /**
27
+ * Map language name to SLOOP Language enum
28
+ */
29
+ export function languageToEnum(language) {
30
+ const enumMap = {
31
+ 'javascript': 'JS',
32
+ 'typescript': 'TS',
33
+ 'python': 'PYTHON',
34
+ 'java': 'JAVA',
35
+ 'go': 'GO',
36
+ 'php': 'PHP',
37
+ 'ruby': 'RUBY',
38
+ 'html': 'HTML',
39
+ 'css': 'CSS',
40
+ 'xml': 'XML',
41
+ };
42
+ return enumMap[language] || language.toUpperCase();
43
+ }
44
+ //# sourceMappingURL=language.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.js","sourceRoot":"","sources":["../../src/utils/language.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,WAAW,GAA2B;QAC1C,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,MAAM;QACf,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,KAAK;KACd,CAAC;IACF,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,OAAO,GAA2B;QACtC,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,KAAK;KACb,CAAC;IACF,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Configuration scope management utilities
3
+ */
4
+ /**
5
+ * Get or create configuration scope for a project
6
+ */
7
+ export declare function getOrCreateScope(filePath: string): string;
8
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwBzD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Configuration scope management utilities
3
+ */
4
+ import { dirname } from "path";
5
+ import { createHash } from "crypto";
6
+ import { scopeMap, getSloopBridge } from "../state.js";
7
+ /**
8
+ * Get or create configuration scope for a project
9
+ */
10
+ export function getOrCreateScope(filePath) {
11
+ const projectRoot = dirname(filePath);
12
+ const scopeId = scopeMap.get(projectRoot);
13
+ if (scopeId) {
14
+ return scopeId;
15
+ }
16
+ // Create new scope ID based on project root hash
17
+ const hash = createHash('md5').update(projectRoot).digest('hex').substring(0, 8);
18
+ const newScopeId = `scope-${hash}`;
19
+ console.error(`[MCP] Creating new configuration scope: ${newScopeId} for ${projectRoot}`);
20
+ // Add scope to SLOOP
21
+ const sloopBridge = getSloopBridge();
22
+ if (sloopBridge) {
23
+ sloopBridge.addConfigurationScope(newScopeId, {
24
+ name: `Project: ${projectRoot}`,
25
+ });
26
+ }
27
+ scopeMap.set(projectRoot, newScopeId);
28
+ return newScopeId;
29
+ }
30
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEvD;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * SLOOP bridge initialization and management
3
+ */
4
+ import { SloopBridge } from "../sloop-bridge.js";
5
+ export declare const PACKAGE_ROOT: string;
6
+ /**
7
+ * Ensure SLOOP bridge is initialized
8
+ */
9
+ export declare function ensureSloopBridge(): Promise<SloopBridge>;
10
+ //# sourceMappingURL=sloop.d.ts.map
@@ -0,0 +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"}