@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.
- package/CHANGELOG.md +24 -0
- package/README.md +14 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +7 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.js +5 -23
- package/dist/index.js.map +1 -1
- package/dist/sloop-bridge.d.ts +10 -1
- package/dist/sloop-bridge.d.ts.map +1 -1
- package/dist/sloop-bridge.js +102 -160
- package/dist/sloop-bridge.js.map +1 -1
- package/dist/state.d.ts +2 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +6 -2
- package/dist/state.js.map +1 -1
- package/dist/tools/analyze-content.js +1 -1
- package/dist/tools/analyze-content.js.map +1 -1
- package/dist/tools/analyze-file.d.ts.map +1 -1
- package/dist/tools/analyze-file.js +4 -6
- package/dist/tools/analyze-file.js.map +1 -1
- package/dist/tools/analyze-files.d.ts.map +1 -1
- package/dist/tools/analyze-files.js +75 -71
- package/dist/tools/analyze-files.js.map +1 -1
- package/dist/tools/apply-all-quick-fixes.d.ts.map +1 -1
- package/dist/tools/apply-all-quick-fixes.js +65 -139
- package/dist/tools/apply-all-quick-fixes.js.map +1 -1
- package/dist/tools/apply-quick-fix.d.ts.map +1 -1
- package/dist/tools/apply-quick-fix.js +5 -76
- package/dist/tools/apply-quick-fix.js.map +1 -1
- package/dist/tools/health-check.d.ts.map +1 -1
- package/dist/tools/health-check.js +15 -7
- package/dist/tools/health-check.js.map +1 -1
- package/dist/tools/list-active-rules.d.ts.map +1 -1
- package/dist/tools/list-active-rules.js +3 -2
- package/dist/tools/list-active-rules.js.map +1 -1
- package/dist/utils/file-registration.js +1 -1
- package/dist/utils/file-registration.js.map +1 -1
- package/dist/utils/formatting.d.ts.map +1 -1
- package/dist/utils/quick-fix.d.ts +14 -0
- package/dist/utils/quick-fix.d.ts.map +1 -0
- package/dist/utils/quick-fix.js +44 -0
- package/dist/utils/quick-fix.js.map +1 -0
- package/dist/utils/scope.d.ts +24 -3
- package/dist/utils/scope.d.ts.map +1 -1
- package/dist/utils/scope.js +46 -7
- package/dist/utils/scope.js.map +1 -1
- package/dist/utils/sloop.d.ts.map +1 -1
- package/dist/utils/sloop.js +5 -1
- package/dist/utils/sloop.js.map +1 -1
- package/package.json +1 -1
- package/dist/tools/analyze-project.d.ts +0 -7
- package/dist/tools/analyze-project.d.ts.map +0 -1
- package/dist/tools/analyze-project.js +0 -109
- package/dist/tools/analyze-project.js.map +0 -1
|
@@ -4,163 +4,89 @@ import { ensureSloopBridge } from "../utils/sloop.js";
|
|
|
4
4
|
import { getOrCreateScope } from "../utils/scope.js";
|
|
5
5
|
import { notifyFileSystemChanged } from "../utils/filesystem.js";
|
|
6
6
|
import { transformSloopIssues } from "../utils/transforms.js";
|
|
7
|
+
import { applyTextEdits } from "../utils/quick-fix.js";
|
|
8
|
+
function applyFixesToFile(filePath, issues) {
|
|
9
|
+
const applied = [];
|
|
10
|
+
const failed = [];
|
|
11
|
+
// Sort descending by line to avoid line number shifts
|
|
12
|
+
const sorted = [...issues].sort((a, b) => {
|
|
13
|
+
return (b.textRange?.startLine || b.startLine || 0) - (a.textRange?.startLine || a.startLine || 0);
|
|
14
|
+
});
|
|
15
|
+
for (const issue of sorted) {
|
|
16
|
+
const line = issue.textRange?.startLine || issue.startLine || 0;
|
|
17
|
+
const rule = issue.ruleKey;
|
|
18
|
+
const quickFix = issue.quickFixes[0];
|
|
19
|
+
try {
|
|
20
|
+
const lines = readFileSync(filePath, 'utf-8').split('\n');
|
|
21
|
+
applyTextEdits(lines, quickFix);
|
|
22
|
+
writeFileSync(filePath, lines.join('\n'), 'utf-8');
|
|
23
|
+
applied.push({ line, rule, message: quickFix.message || 'Applied automated fix' });
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
failed.push({ line, rule, error: error instanceof Error ? error.message : String(error) });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { applied, failed };
|
|
30
|
+
}
|
|
31
|
+
function formatFixList(label, items) {
|
|
32
|
+
if (items.length === 0)
|
|
33
|
+
return '';
|
|
34
|
+
const lines = items.map(i => `- Line ${i.line}: ${i.rule} - ${i.message || i.error}`);
|
|
35
|
+
return `**${label}:**\n${lines.join('\n')}\n\n`;
|
|
36
|
+
}
|
|
37
|
+
function formatRemainingIssues(remaining) {
|
|
38
|
+
if (remaining.length === 0)
|
|
39
|
+
return `🎉 All issues resolved! The file has no remaining code quality issues.\n`;
|
|
40
|
+
let out = `**Remaining Issues (require manual fixing):**\n`;
|
|
41
|
+
for (const severity of ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO']) {
|
|
42
|
+
const issues = remaining.filter(i => i.severity === severity);
|
|
43
|
+
if (issues.length === 0)
|
|
44
|
+
continue;
|
|
45
|
+
out += `\n${severity} (${issues.length}):\n`;
|
|
46
|
+
for (const issue of issues)
|
|
47
|
+
out += `- Line ${issue.line}: ${issue.rule} - ${issue.message}\n`;
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
function formatSummary(filePath, applied, failed, remaining) {
|
|
52
|
+
let summary = `✅ **Quick fixes applied**\n\nFile: ${filePath}\nApplied: ${applied.length} fixes\n`;
|
|
53
|
+
if (failed.length > 0)
|
|
54
|
+
summary += `Failed: ${failed.length} fixes\n`;
|
|
55
|
+
summary += `Remaining issues: ${remaining.length}\n\n`;
|
|
56
|
+
summary += formatFixList('Fixed Issues', applied);
|
|
57
|
+
summary += formatFixList('Failed Fixes', failed);
|
|
58
|
+
summary += formatRemainingIssues(remaining);
|
|
59
|
+
return summary;
|
|
60
|
+
}
|
|
7
61
|
export async function handleApplyAllQuickFixes(args) {
|
|
8
62
|
const { filePath } = args;
|
|
9
|
-
console.error(`[MCP] Applying all quick fixes for ${filePath}`);
|
|
10
|
-
// Validate file exists
|
|
11
63
|
if (!existsSync(filePath)) {
|
|
12
64
|
throw new SloopError(`File not found: ${filePath}`, `The file ${filePath} does not exist. Please check the path and try again.`, false);
|
|
13
65
|
}
|
|
14
|
-
// Analyze the file to get all issues with quick fixes
|
|
15
66
|
const bridge = await ensureSloopBridge();
|
|
16
|
-
const scopeId = getOrCreateScope(filePath);
|
|
67
|
+
const scopeId = await getOrCreateScope(filePath);
|
|
17
68
|
const rawResult = await bridge.analyzeFilesAndTrack(scopeId, [filePath]);
|
|
18
69
|
const rawIssues = rawResult.raisedIssues?.length ? rawResult.raisedIssues : (rawResult.rawIssues || []);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const issuesWithQuickFixes = rawIssues.filter((issue) => {
|
|
22
|
-
const hasQuickFixes = issue.quickFixes && issue.quickFixes.length > 0;
|
|
23
|
-
if (hasQuickFixes) {
|
|
24
|
-
console.error(`[DEBUG] Issue at line ${issue.textRange?.startLine || issue.startLine}: ${issue.ruleKey} has ${issue.quickFixes.length} quick fixes`);
|
|
25
|
-
}
|
|
26
|
-
return hasQuickFixes;
|
|
27
|
-
});
|
|
28
|
-
console.error(`[MCP] Found ${issuesWithQuickFixes.length} issues with quick fixes`);
|
|
29
|
-
if (issuesWithQuickFixes.length === 0) {
|
|
70
|
+
const fixableIssues = rawIssues.filter((issue) => issue.quickFixes?.length > 0);
|
|
71
|
+
if (fixableIssues.length === 0) {
|
|
30
72
|
return {
|
|
31
|
-
content: [
|
|
32
|
-
{
|
|
73
|
+
content: [{
|
|
33
74
|
type: "text",
|
|
34
75
|
text: `ℹ️ **No quick fixes available**\n\nFile: ${filePath}\nTotal issues: ${rawIssues.length}\n\nNone of the issues in this file have automated quick fixes available. All issues must be fixed manually.`,
|
|
35
|
-
},
|
|
36
|
-
],
|
|
76
|
+
}],
|
|
37
77
|
};
|
|
38
78
|
}
|
|
39
|
-
|
|
40
|
-
const sortedIssues = [...issuesWithQuickFixes].sort((a, b) => {
|
|
41
|
-
const aLine = a.textRange?.startLine || a.startLine || 0;
|
|
42
|
-
const bLine = b.textRange?.startLine || b.startLine || 0;
|
|
43
|
-
return bLine - aLine; // Descending order
|
|
44
|
-
});
|
|
45
|
-
// Apply each quick fix
|
|
46
|
-
const appliedFixes = [];
|
|
47
|
-
const failedFixes = [];
|
|
48
|
-
for (const issue of sortedIssues) {
|
|
49
|
-
const line = issue.textRange?.startLine || issue.startLine || 0;
|
|
50
|
-
const rule = issue.ruleKey;
|
|
51
|
-
const quickFix = issue.quickFixes[0]; // Use first available quick fix
|
|
52
|
-
console.error(`[MCP] Applying fix for ${rule} at line ${line}`);
|
|
53
|
-
try {
|
|
54
|
-
// Read current file content
|
|
55
|
-
let fileContent = readFileSync(filePath, 'utf-8');
|
|
56
|
-
const lines = fileContent.split('\n');
|
|
57
|
-
// Apply the quick fix edits
|
|
58
|
-
const fileEdits = quickFix.inputFileEdits || quickFix.fileEdits || [];
|
|
59
|
-
if (fileEdits.length > 0) {
|
|
60
|
-
for (const fileEdit of fileEdits) {
|
|
61
|
-
if (fileEdit.textEdits) {
|
|
62
|
-
// Sort edits in reverse order to maintain line numbers
|
|
63
|
-
const sortedEdits = [...fileEdit.textEdits].sort((a, b) => {
|
|
64
|
-
const aStart = a.range?.startLine || 0;
|
|
65
|
-
const bStart = b.range?.startLine || 0;
|
|
66
|
-
return bStart - aStart;
|
|
67
|
-
});
|
|
68
|
-
for (const edit of sortedEdits) {
|
|
69
|
-
const startLine = (edit.range?.startLine || 1) - 1;
|
|
70
|
-
const startCol = edit.range?.startLineOffset || 0;
|
|
71
|
-
const endLine = (edit.range?.endLine || startLine + 1) - 1;
|
|
72
|
-
const endCol = edit.range?.endLineOffset || lines[endLine]?.length || 0;
|
|
73
|
-
const newText = edit.newText || '';
|
|
74
|
-
if (startLine === endLine) {
|
|
75
|
-
const currentLine = lines[startLine];
|
|
76
|
-
lines[startLine] = currentLine.substring(0, startCol) + newText + currentLine.substring(endCol);
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
const firstLine = lines[startLine].substring(0, startCol) + newText;
|
|
80
|
-
const lastLine = lines[endLine].substring(endCol);
|
|
81
|
-
lines.splice(startLine, endLine - startLine + 1, firstLine + lastLine);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Write back to file
|
|
88
|
-
fileContent = lines.join('\n');
|
|
89
|
-
writeFileSync(filePath, fileContent, 'utf-8');
|
|
90
|
-
appliedFixes.push({
|
|
91
|
-
line,
|
|
92
|
-
rule,
|
|
93
|
-
message: quickFix.message || 'Applied automated fix',
|
|
94
|
-
});
|
|
95
|
-
console.error(`[MCP] Successfully applied fix for ${rule} at line ${line}`);
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
console.error(`[MCP] Failed to apply fix for ${rule} at line ${line}:`, error);
|
|
99
|
-
failedFixes.push({
|
|
100
|
-
line,
|
|
101
|
-
rule,
|
|
102
|
-
error: error instanceof Error ? error.message : String(error),
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
// Notify SLOOP about file changes
|
|
107
|
-
console.error(`[Cache] Sending file system update notification...`);
|
|
79
|
+
const { applied, failed } = applyFixesToFile(filePath, fixableIssues);
|
|
108
80
|
await notifyFileSystemChanged(filePath, scopeId);
|
|
109
81
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
110
|
-
// Re-analyze to get remaining issues
|
|
111
82
|
const finalResult = await bridge.analyzeFilesAndTrack(scopeId, [filePath]);
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
// Format summary
|
|
115
|
-
let summary = `✅ **Quick fixes applied**\n\n`;
|
|
116
|
-
summary += `File: ${filePath}\n`;
|
|
117
|
-
summary += `Applied: ${appliedFixes.length} fixes\n`;
|
|
118
|
-
if (failedFixes.length > 0) {
|
|
119
|
-
summary += `Failed: ${failedFixes.length} fixes\n`;
|
|
120
|
-
}
|
|
121
|
-
summary += `Remaining issues: ${remainingIssues.length}\n\n`;
|
|
122
|
-
if (appliedFixes.length > 0) {
|
|
123
|
-
summary += `**Fixed Issues:**\n`;
|
|
124
|
-
for (const fix of appliedFixes) {
|
|
125
|
-
summary += `- Line ${fix.line}: ${fix.rule} - ${fix.message}\n`;
|
|
126
|
-
}
|
|
127
|
-
summary += `\n`;
|
|
128
|
-
}
|
|
129
|
-
if (failedFixes.length > 0) {
|
|
130
|
-
summary += `**Failed Fixes:**\n`;
|
|
131
|
-
for (const fail of failedFixes) {
|
|
132
|
-
summary += `- Line ${fail.line}: ${fail.rule} - ${fail.error}\n`;
|
|
133
|
-
}
|
|
134
|
-
summary += `\n`;
|
|
135
|
-
}
|
|
136
|
-
if (remainingIssues.length > 0) {
|
|
137
|
-
summary += `**Remaining Issues (require manual fixing):**\n`;
|
|
138
|
-
const groupedBySeverity = transformedRemaining.reduce((acc, issue) => {
|
|
139
|
-
if (!acc[issue.severity])
|
|
140
|
-
acc[issue.severity] = [];
|
|
141
|
-
acc[issue.severity].push(issue);
|
|
142
|
-
return acc;
|
|
143
|
-
}, {});
|
|
144
|
-
for (const severity of ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO']) {
|
|
145
|
-
const issues = groupedBySeverity[severity] || [];
|
|
146
|
-
if (issues.length > 0) {
|
|
147
|
-
summary += `\n${severity} (${issues.length}):\n`;
|
|
148
|
-
for (const issue of issues) {
|
|
149
|
-
summary += `- Line ${issue.line}: ${issue.rule} - ${issue.message}\n`;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
summary += `🎉 All issues resolved! The file has no remaining code quality issues.\n`;
|
|
156
|
-
}
|
|
83
|
+
const remainingRaw = finalResult.raisedIssues?.length ? finalResult.raisedIssues : (finalResult.rawIssues || []);
|
|
84
|
+
const remaining = transformSloopIssues(remainingRaw);
|
|
157
85
|
return {
|
|
158
|
-
content: [
|
|
159
|
-
{
|
|
86
|
+
content: [{
|
|
160
87
|
type: "text",
|
|
161
|
-
text:
|
|
162
|
-
},
|
|
163
|
-
],
|
|
88
|
+
text: formatSummary(filePath, applied, failed, remaining),
|
|
89
|
+
}],
|
|
164
90
|
};
|
|
165
91
|
}
|
|
166
92
|
//# sourceMappingURL=apply-all-quick-fixes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply-all-quick-fixes.js","sourceRoot":"","sources":["../../src/tools/apply-all-quick-fixes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"apply-all-quick-fixes.js","sourceRoot":"","sources":["../../src/tools/apply-all-quick-fixes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply-quick-fix.d.ts","sourceRoot":"","sources":["../../src/tools/apply-quick-fix.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apply-quick-fix.d.ts","sourceRoot":"","sources":["../../src/tools/apply-quick-fix.ts"],"names":[],"mappings":"AAOA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,GAAG;;;;;GAuDlD"}
|
|
@@ -3,19 +3,17 @@ import { SloopError } from "../errors.js";
|
|
|
3
3
|
import { ensureSloopBridge } from "../utils/sloop.js";
|
|
4
4
|
import { getOrCreateScope } from "../utils/scope.js";
|
|
5
5
|
import { notifyFileSystemChanged } from "../utils/filesystem.js";
|
|
6
|
+
import { applyTextEdits } from "../utils/quick-fix.js";
|
|
6
7
|
export async function handleApplyQuickFix(args) {
|
|
7
8
|
const { filePath, line, rule } = args;
|
|
8
9
|
console.error(`[MCP] Applying quick fix for ${rule} at ${filePath}:${line}`);
|
|
9
|
-
// Validate file exists
|
|
10
10
|
if (!existsSync(filePath)) {
|
|
11
11
|
throw new SloopError(`File not found: ${filePath}`, `The file ${filePath} does not exist. Please check the path and try again.`, false);
|
|
12
12
|
}
|
|
13
|
-
// Re-analyze the file to get current issues with quick fixes
|
|
14
13
|
const bridge = await ensureSloopBridge();
|
|
15
|
-
const scopeId = getOrCreateScope(filePath);
|
|
14
|
+
const scopeId = await getOrCreateScope(filePath);
|
|
16
15
|
const rawResult = await bridge.analyzeFilesAndTrack(scopeId, [filePath]);
|
|
17
16
|
const rawIssues = rawResult.raisedIssues?.length ? rawResult.raisedIssues : (rawResult.rawIssues || []);
|
|
18
|
-
// Find the issue at the specified line with the specified rule
|
|
19
17
|
const targetIssue = rawIssues.find((issue) => {
|
|
20
18
|
const issueLine = issue.textRange?.startLine || issue.startLine || 0;
|
|
21
19
|
return issueLine === line && issue.ruleKey === rule;
|
|
@@ -26,80 +24,11 @@ export async function handleApplyQuickFix(args) {
|
|
|
26
24
|
if (!targetIssue.quickFixes || targetIssue.quickFixes.length === 0) {
|
|
27
25
|
throw new SloopError(`No quick fix available`, `The issue at line ${line} (${rule}) does not have an automated quick fix available.`, false);
|
|
28
26
|
}
|
|
29
|
-
// Apply the first quick fix
|
|
30
27
|
const quickFix = targetIssue.quickFixes[0];
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
writeFileSync(
|
|
34
|
-
targetIssue: {
|
|
35
|
-
ruleKey: targetIssue.ruleKey,
|
|
36
|
-
textRange: targetIssue.textRange,
|
|
37
|
-
quickFixes: targetIssue.quickFixes
|
|
38
|
-
},
|
|
39
|
-
quickFix: quickFix
|
|
40
|
-
}, null, 2), 'utf-8');
|
|
41
|
-
let fileContent = readFileSync(filePath, 'utf-8');
|
|
42
|
-
const lines = fileContent.split('\n');
|
|
43
|
-
// Apply each edit in the quick fix
|
|
44
|
-
const fileEdits = quickFix.inputFileEdits || quickFix.fileEdits || [];
|
|
45
|
-
if (fileEdits.length > 0) {
|
|
46
|
-
console.error(`[DEBUG] Found ${fileEdits.length} file edits`);
|
|
47
|
-
for (const fileEdit of fileEdits) {
|
|
48
|
-
if (fileEdit.textEdits) {
|
|
49
|
-
console.error(`[DEBUG] Found ${fileEdit.textEdits.length} text edits`);
|
|
50
|
-
// Sort edits in reverse order to maintain line numbers
|
|
51
|
-
const sortedEdits = [...fileEdit.textEdits].sort((a, b) => {
|
|
52
|
-
const aStart = a.range?.startLine || 0;
|
|
53
|
-
const bStart = b.range?.startLine || 0;
|
|
54
|
-
return bStart - aStart; // Reverse order
|
|
55
|
-
});
|
|
56
|
-
for (const edit of sortedEdits) {
|
|
57
|
-
const startLine = (edit.range?.startLine || 1) - 1; // Convert to 0-based
|
|
58
|
-
const startCol = edit.range?.startLineOffset || 0;
|
|
59
|
-
const endLine = (edit.range?.endLine || startLine + 1) - 1;
|
|
60
|
-
const endCol = edit.range?.endLineOffset || lines[endLine]?.length || 0;
|
|
61
|
-
const newText = edit.newText || '';
|
|
62
|
-
console.error(`[DEBUG] Applying edit at line ${startLine + 1}:${startCol} to ${endLine + 1}:${endCol}`);
|
|
63
|
-
console.error(`[DEBUG] Old text: "${lines[startLine].substring(startCol, endCol)}"`);
|
|
64
|
-
console.error(`[DEBUG] New text: "${newText}"`);
|
|
65
|
-
// Apply the edit
|
|
66
|
-
if (startLine === endLine) {
|
|
67
|
-
const line = lines[startLine];
|
|
68
|
-
lines[startLine] = line.substring(0, startCol) + newText + line.substring(endCol);
|
|
69
|
-
console.error(`[DEBUG] Result: "${lines[startLine]}"`);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
// Multi-line edit
|
|
73
|
-
const firstLine = lines[startLine].substring(0, startCol) + newText;
|
|
74
|
-
const lastLine = lines[endLine].substring(endCol);
|
|
75
|
-
lines.splice(startLine, endLine - startLine + 1, firstLine + lastLine);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
console.error('[DEBUG] No fileEdits found in quick fix!');
|
|
83
|
-
}
|
|
84
|
-
// Write the modified content back
|
|
85
|
-
fileContent = lines.join('\n');
|
|
86
|
-
console.error(`[DEBUG] About to write file: ${filePath}`);
|
|
87
|
-
console.error(`[DEBUG] File content length: ${fileContent.length} chars`);
|
|
88
|
-
console.error(`[DEBUG] First 200 chars: ${fileContent.substring(0, 200)}`);
|
|
89
|
-
try {
|
|
90
|
-
writeFileSync(filePath, fileContent, 'utf-8');
|
|
91
|
-
console.error(`[DEBUG] File written successfully`);
|
|
92
|
-
}
|
|
93
|
-
catch (err) {
|
|
94
|
-
console.error(`[DEBUG] Error writing file:`, err);
|
|
95
|
-
throw err;
|
|
96
|
-
}
|
|
97
|
-
// Notify SLOOP that file system was updated (proper cache invalidation)
|
|
98
|
-
console.error(`[Cache] Sending file system update notification...`);
|
|
28
|
+
const lines = readFileSync(filePath, 'utf-8').split('\n');
|
|
29
|
+
applyTextEdits(lines, quickFix);
|
|
30
|
+
writeFileSync(filePath, lines.join('\n'), 'utf-8');
|
|
99
31
|
await notifyFileSystemChanged(filePath, scopeId);
|
|
100
|
-
console.error(`[Cache] File system update notification sent, waiting for SLOOP to process...`);
|
|
101
|
-
// CRITICAL: Give SLOOP time to process the file system notification
|
|
102
|
-
// Without this delay, the next analysis request may arrive before SLOOP updates its registry
|
|
103
32
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
104
33
|
return {
|
|
105
34
|
content: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply-quick-fix.js","sourceRoot":"","sources":["../../src/tools/apply-quick-fix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"apply-quick-fix.js","sourceRoot":"","sources":["../../src/tools/apply-quick-fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../src/tools/health-check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../src/tools/health-check.ts"],"names":[],"mappings":"AAyBA,wBAAsB,iBAAiB;;;;;GAyHtC"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
2
|
-
import { join } from "path";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
|
-
import {
|
|
5
|
-
import { sessionResults, batchResults, sloopBridge, serverStartTime } from "../state.js";
|
|
4
|
+
import { sessionResults, batchResults, getSloopBridge, serverStartTime } from "../state.js";
|
|
6
5
|
// Get package root directory (where sonarlint-backend is installed)
|
|
7
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
7
|
const __dirname = dirname(__filename);
|
|
9
8
|
const PACKAGE_ROOT = join(__dirname, '..', '..'); // Go up from dist/tools/ to package root
|
|
9
|
+
function getHealthStatus(pluginsExist) {
|
|
10
|
+
if (!pluginsExist)
|
|
11
|
+
return "degraded";
|
|
12
|
+
return getSloopBridge() ? "healthy" : "ready";
|
|
13
|
+
}
|
|
10
14
|
// Read version from package.json
|
|
11
15
|
function getPackageVersion() {
|
|
12
16
|
try {
|
|
@@ -26,7 +30,7 @@ export async function handleHealthCheck() {
|
|
|
26
30
|
const memoryUsage = process.memoryUsage();
|
|
27
31
|
const memoryMB = Math.round(memoryUsage.heapUsed / 1024 / 1024);
|
|
28
32
|
// Check SLOOP status - reflect actual backend state
|
|
29
|
-
const sloopStatus =
|
|
33
|
+
const sloopStatus = getSloopBridge() ? "running" : "not started (starts on first analysis)";
|
|
30
34
|
// Get plugin information
|
|
31
35
|
const pluginsDir = join(PACKAGE_ROOT, "sonarlint-backend", "plugins");
|
|
32
36
|
const pluginsExist = existsSync(pluginsDir);
|
|
@@ -52,7 +56,7 @@ export async function handleHealthCheck() {
|
|
|
52
56
|
batchResults: batchResults.size,
|
|
53
57
|
};
|
|
54
58
|
const healthStatus = {
|
|
55
|
-
status: pluginsExist
|
|
59
|
+
status: getHealthStatus(pluginsExist),
|
|
56
60
|
version: getPackageVersion(),
|
|
57
61
|
uptime: {
|
|
58
62
|
milliseconds: uptimeMs,
|
|
@@ -72,7 +76,7 @@ export async function handleHealthCheck() {
|
|
|
72
76
|
rss: `${Math.round(memoryUsage.rss / 1024 / 1024)}MB`,
|
|
73
77
|
},
|
|
74
78
|
cache: cacheStats,
|
|
75
|
-
tools: ["check_quality", "check_files", "check_code", "
|
|
79
|
+
tools: ["check_quality", "check_files", "check_code", "list_rules", "fix_issue", "fix_all_issues", "health_check"],
|
|
76
80
|
features: [
|
|
77
81
|
"Session storage for multi-turn conversations",
|
|
78
82
|
"Batch analysis",
|
|
@@ -82,7 +86,11 @@ export async function handleHealthCheck() {
|
|
|
82
86
|
],
|
|
83
87
|
};
|
|
84
88
|
let output = `# SonarLint MCP Server Health Check\n\n`;
|
|
85
|
-
|
|
89
|
+
let statusEmoji = "⚠️ Degraded";
|
|
90
|
+
if (healthStatus.status === "healthy")
|
|
91
|
+
statusEmoji = "✅ Healthy";
|
|
92
|
+
else if (healthStatus.status === "ready")
|
|
93
|
+
statusEmoji = "🟡 Ready";
|
|
86
94
|
output += `**Status**: ${statusEmoji}\n`;
|
|
87
95
|
output += `**Version**: ${healthStatus.version}\n`;
|
|
88
96
|
output += `**Uptime**: ${healthStatus.uptime.formatted}\n\n`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health-check.js","sourceRoot":"","sources":["../../src/tools/health-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"health-check.js","sourceRoot":"","sources":["../../src/tools/health-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-active-rules.d.ts","sourceRoot":"","sources":["../../src/tools/list-active-rules.ts"],"names":[],"mappings":"AAEA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,GAAG;;;;;
|
|
1
|
+
{"version":3,"file":"list-active-rules.d.ts","sourceRoot":"","sources":["../../src/tools/list-active-rules.ts"],"names":[],"mappings":"AAEA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,GAAG;;;;;GA4EpD"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ensureSloopBridge } from "../utils/sloop.js";
|
|
2
2
|
export async function handleListActiveRules(args) {
|
|
3
3
|
const { language } = args;
|
|
4
|
-
|
|
4
|
+
const langSuffix = language ? ` for ${language}` : '';
|
|
5
|
+
console.error(`[MCP] Listing active rules${langSuffix}`);
|
|
5
6
|
const bridge = await ensureSloopBridge();
|
|
6
7
|
try {
|
|
7
8
|
const response = await bridge.listAllStandaloneRulesDefinitions();
|
|
@@ -26,7 +27,7 @@ export async function handleListActiveRules(args) {
|
|
|
26
27
|
let output = `# Active SonarLint Rules\n\n`;
|
|
27
28
|
let totalRules = 0;
|
|
28
29
|
// Sort languages alphabetically
|
|
29
|
-
const sortedLangs = [...rulesByLanguage.keys()].sort();
|
|
30
|
+
const sortedLangs = [...rulesByLanguage.keys()].sort((a, b) => a.localeCompare(b));
|
|
30
31
|
for (const lang of sortedLangs) {
|
|
31
32
|
const rules = rulesByLanguage.get(lang);
|
|
32
33
|
totalRules += rules.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-active-rules.js","sourceRoot":"","sources":["../../src/tools/list-active-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAS;IACnD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAA6B,CAAC;IAEnD,
|
|
1
|
+
{"version":3,"file":"list-active-rules.js","sourceRoot":"","sources":["../../src/tools/list-active-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ export function buildClientFileDtos(filePaths, configScopeId, projectRoot) {
|
|
|
21
21
|
fsPath: filePath,
|
|
22
22
|
ideRelativePath: relative(baseDir, filePath),
|
|
23
23
|
configScopeId,
|
|
24
|
-
isTest: /
|
|
24
|
+
isTest: /tests?[/\\]/.test(filePath),
|
|
25
25
|
charset: 'UTF-8',
|
|
26
26
|
content,
|
|
27
27
|
detectedLanguage: sloopLanguage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-registration.js","sourceRoot":"","sources":["../../src/utils/file-registration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAc/D;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAmB,EACnB,aAAqB,EACrB,WAAoB;IAEpB,MAAM,OAAO,GAAG,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,OAAO,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;QAC9B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,aAAa,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE/E,OAAO;YACL,GAAG,EAAE,UAAU,QAAQ,EAAE;YACzB,MAAM,EAAE,QAAQ;YAChB,eAAe,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;YAC5C,aAAa;YACb,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"file-registration.js","sourceRoot":"","sources":["../../src/utils/file-registration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAc/D;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAmB,EACnB,aAAqB,EACrB,WAAoB;IAEpB,MAAM,OAAO,GAAG,WAAW,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,OAAO,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;QAC9B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,aAAa,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE/E,OAAO;YACL,GAAG,EAAE,UAAU,QAAQ,EAAE;YACzB,MAAM,EAAE,QAAQ;YAChB,eAAe,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;YAC5C,aAAa;YACb,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;YACpC,OAAO,EAAE,OAAO;YAChB,OAAO;YACP,gBAAgB,EAAE,aAAa;YAC/B,aAAa,EAAE,IAAI;SACpB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +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,
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../src/utils/formatting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAyCnE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAkD7E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared logic for applying SLOOP quick-fix text edits to file content.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Apply a SLOOP quick fix's text edits to an array of lines (mutates in place).
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyTextEdits(lines: string[], quickFix: any): void;
|
|
8
|
+
/**
|
|
9
|
+
* Filter issues by minimum severity level.
|
|
10
|
+
*/
|
|
11
|
+
export declare function filterBySeverity<T extends {
|
|
12
|
+
severity: string;
|
|
13
|
+
}>(issues: T[], minSeverity: string): T[];
|
|
14
|
+
//# sourceMappingURL=quick-fix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quick-fix.d.ts","sourceRoot":"","sources":["../../src/utils/quick-fix.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI,CA2BnE;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC7D,MAAM,EAAE,CAAC,EAAE,EACX,WAAW,EAAE,MAAM,GAClB,CAAC,EAAE,CAGL"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared logic for applying SLOOP quick-fix text edits to file content.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Apply a SLOOP quick fix's text edits to an array of lines (mutates in place).
|
|
6
|
+
*/
|
|
7
|
+
export function applyTextEdits(lines, quickFix) {
|
|
8
|
+
const fileEdits = quickFix.inputFileEdits || quickFix.fileEdits || [];
|
|
9
|
+
for (const fileEdit of fileEdits) {
|
|
10
|
+
if (!fileEdit.textEdits)
|
|
11
|
+
continue;
|
|
12
|
+
// Sort edits in reverse order to maintain line numbers
|
|
13
|
+
const sortedEdits = [...fileEdit.textEdits].sort((a, b) => {
|
|
14
|
+
return (b.range?.startLine || 0) - (a.range?.startLine || 0);
|
|
15
|
+
});
|
|
16
|
+
for (const edit of sortedEdits) {
|
|
17
|
+
const startLine = (edit.range?.startLine || 1) - 1;
|
|
18
|
+
const startCol = edit.range?.startLineOffset || 0;
|
|
19
|
+
const endLine = (edit.range?.endLine || startLine + 1) - 1;
|
|
20
|
+
const endCol = edit.range?.endLineOffset || lines[endLine]?.length || 0;
|
|
21
|
+
const newText = edit.newText || '';
|
|
22
|
+
if (startLine === endLine) {
|
|
23
|
+
const line = lines[startLine];
|
|
24
|
+
lines[startLine] = line.substring(0, startCol) + newText + line.substring(endCol);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const firstLine = lines[startLine].substring(0, startCol) + newText;
|
|
28
|
+
const lastLine = lines[endLine].substring(endCol);
|
|
29
|
+
lines.splice(startLine, endLine - startLine + 1, firstLine + lastLine);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const SEVERITY_ORDER = {
|
|
35
|
+
INFO: 0, MINOR: 1, MAJOR: 2, CRITICAL: 3, BLOCKER: 4
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Filter issues by minimum severity level.
|
|
39
|
+
*/
|
|
40
|
+
export function filterBySeverity(issues, minSeverity) {
|
|
41
|
+
const minLevel = SEVERITY_ORDER[minSeverity] ?? 0;
|
|
42
|
+
return issues.filter(issue => (SEVERITY_ORDER[issue.severity] ?? 0) >= minLevel);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=quick-fix.js.map
|