opencode-sonarqube 1.2.45 → 1.2.47
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/README.md +3 -6
- package/dist/index.js +7 -68
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ OpenCode Plugin for SonarQube integration - Enterprise-level code quality from t
|
|
|
4
4
|
|
|
5
5
|
[](https://sonarqube.example.com)
|
|
6
6
|
[](https://sonarqube.example.com)
|
|
7
|
-
[](https://sonarqube.example.com)
|
|
8
8
|
[](./LICENSE)
|
|
9
9
|
|
|
10
10
|
## Features
|
|
@@ -120,7 +120,6 @@ Create `.sonarqube/config.json` in your project root:
|
|
|
120
120
|
{
|
|
121
121
|
"level": "enterprise",
|
|
122
122
|
"autoAnalyze": true,
|
|
123
|
-
"autoFix": false,
|
|
124
123
|
"newCodeDefinition": "previous_version"
|
|
125
124
|
}
|
|
126
125
|
```
|
|
@@ -131,7 +130,6 @@ Create `.sonarqube/config.json` in your project root:
|
|
|
131
130
|
|--------|------|---------|-------------|
|
|
132
131
|
| `level` | `"enterprise"` \| `"standard"` \| `"relaxed"` \| `"off"` | `"enterprise"` | Analysis strictness level |
|
|
133
132
|
| `autoAnalyze` | `boolean` | `true` | Auto-analyze when AI becomes idle |
|
|
134
|
-
| `autoFix` | `boolean` | `false` | Automatically attempt to fix issues |
|
|
135
133
|
| `projectKey` | `string` | auto | SonarQube project key (auto-generated from package.json or directory) |
|
|
136
134
|
| `projectName` | `string` | auto | Display name on SonarQube |
|
|
137
135
|
| `qualityGate` | `string` | `"Sonar way"` | Quality gate to use |
|
|
@@ -155,8 +153,7 @@ Create `.sonarqube/config.json` in your project root:
|
|
|
155
153
|
```json
|
|
156
154
|
{
|
|
157
155
|
"level": "enterprise",
|
|
158
|
-
"autoAnalyze": true
|
|
159
|
-
"autoFix": false
|
|
156
|
+
"autoAnalyze": true
|
|
160
157
|
}
|
|
161
158
|
```
|
|
162
159
|
|
|
@@ -480,7 +477,7 @@ This project maintains enterprise-level quality:
|
|
|
480
477
|
| Metric | Value |
|
|
481
478
|
|--------|-------|
|
|
482
479
|
| Test Coverage | 96% |
|
|
483
|
-
| Tests |
|
|
480
|
+
| Tests | 612 |
|
|
484
481
|
| Bugs | 0 |
|
|
485
482
|
| Vulnerabilities | 0 |
|
|
486
483
|
| Code Smells | 0 |
|
package/dist/index.js
CHANGED
|
@@ -4050,7 +4050,6 @@ var init_types2 = __esm(() => {
|
|
|
4050
4050
|
password: exports_external2.string().min(1).describe("SonarQube password"),
|
|
4051
4051
|
level: exports_external2.enum(["enterprise", "standard", "relaxed", "off"]).default("enterprise").describe("Analysis strictness level"),
|
|
4052
4052
|
autoAnalyze: exports_external2.boolean().default(true).describe("Auto-analyze when agent becomes idle"),
|
|
4053
|
-
autoFix: exports_external2.boolean().default(false).describe("Automatically attempt to fix issues"),
|
|
4054
4053
|
projectKey: exports_external2.string().optional().describe("SonarQube project key (auto-generated if not set)"),
|
|
4055
4054
|
projectName: exports_external2.string().optional().describe("SonarQube project display name"),
|
|
4056
4055
|
qualityGate: exports_external2.string().optional().describe("Quality gate to use"),
|
|
@@ -16524,7 +16523,6 @@ var configLogger = {
|
|
|
16524
16523
|
var DEFAULT_CONFIG = {
|
|
16525
16524
|
level: "enterprise",
|
|
16526
16525
|
autoAnalyze: true,
|
|
16527
|
-
autoFix: false,
|
|
16528
16526
|
newCodeDefinition: "previous_version",
|
|
16529
16527
|
sources: "src"
|
|
16530
16528
|
};
|
|
@@ -19340,23 +19338,17 @@ function formatAnalysisOutput(result, config2) {
|
|
|
19340
19338
|
message += formatActionPrompt(result, config2);
|
|
19341
19339
|
return message;
|
|
19342
19340
|
}
|
|
19343
|
-
function formatActionPrompt(result,
|
|
19341
|
+
function formatActionPrompt(result, _config) {
|
|
19344
19342
|
const blockerCount = result.issues.blocker;
|
|
19345
19343
|
const criticalCount = result.issues.critical;
|
|
19346
19344
|
if (blockerCount === 0 && criticalCount === 0) {
|
|
19347
19345
|
return "";
|
|
19348
19346
|
}
|
|
19349
|
-
|
|
19347
|
+
return `
|
|
19350
19348
|
|
|
19351
19349
|
---
|
|
19352
19350
|
|
|
19353
|
-
**Action Required:** Found ${blockerCount} blocker(s) and ${criticalCount} critical issue(s).`;
|
|
19354
|
-
if (config2.autoFix) {
|
|
19355
|
-
prompt += " I will now attempt to fix these issues.";
|
|
19356
|
-
} else {
|
|
19357
|
-
prompt += " Please review and fix these issues before continuing.";
|
|
19358
|
-
}
|
|
19359
|
-
return prompt;
|
|
19351
|
+
**Action Required:** Found ${blockerCount} blocker(s) and ${criticalCount} critical issue(s). Please review and fix these issues before continuing.`;
|
|
19360
19352
|
}
|
|
19361
19353
|
function createIdleHook(getConfig, getDirectory) {
|
|
19362
19354
|
return async function handleSessionIdle() {
|
|
@@ -19560,7 +19552,6 @@ ${result.message}`;
|
|
|
19560
19552
|
const defaultConfig = {
|
|
19561
19553
|
level: config2.level || "enterprise",
|
|
19562
19554
|
autoAnalyze: true,
|
|
19563
|
-
autoFix: true,
|
|
19564
19555
|
sources: config2.sources || "src",
|
|
19565
19556
|
newCodeDefinition: "previous_version"
|
|
19566
19557
|
};
|
|
@@ -20052,7 +20043,7 @@ function getSeveritiesFromLevel(level) {
|
|
|
20052
20043
|
}
|
|
20053
20044
|
|
|
20054
20045
|
// src/index.ts
|
|
20055
|
-
import { readFileSync, writeFileSync
|
|
20046
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
20056
20047
|
|
|
20057
20048
|
// src/cli.ts
|
|
20058
20049
|
var CLI_HELP = `
|
|
@@ -20272,10 +20263,7 @@ function shouldIgnoreFile2(filePath) {
|
|
|
20272
20263
|
return IGNORED_FILE_PATTERNS2.some((pattern) => pattern.test(filePath));
|
|
20273
20264
|
}
|
|
20274
20265
|
var SonarQubePlugin = async ({ client, directory, worktree }) => {
|
|
20275
|
-
const safeLog = (
|
|
20276
|
-
appendFileSync("/tmp/sonarqube-plugin-debug.log", `${new Date().toISOString()} ${msg}
|
|
20277
|
-
`);
|
|
20278
|
-
};
|
|
20266
|
+
const safeLog = (_msg) => {};
|
|
20279
20267
|
const pluginImportUrl = import.meta.url;
|
|
20280
20268
|
const resolveDirectoryFromImportUrl = () => {
|
|
20281
20269
|
try {
|
|
@@ -20418,44 +20406,6 @@ ${blockerNote}Use \`sonarqube({ action: "issues" })\` to see details or \`sonarq
|
|
|
20418
20406
|
});
|
|
20419
20407
|
} catch {}
|
|
20420
20408
|
};
|
|
20421
|
-
const triggerAutoFix = async (issues) => {
|
|
20422
|
-
if (!currentSessionId || issues.length === 0)
|
|
20423
|
-
return;
|
|
20424
|
-
const blockers = issues.filter((i) => i.severity === "BLOCKER");
|
|
20425
|
-
const critical = issues.filter((i) => i.severity === "CRITICAL");
|
|
20426
|
-
if (blockers.length === 0 && critical.length === 0)
|
|
20427
|
-
return;
|
|
20428
|
-
const issueList = [...blockers, ...critical].slice(0, 5).map((i) => `- ${i.file}:${i.line ?? "?"} - ${i.message}`).join(`
|
|
20429
|
-
`);
|
|
20430
|
-
const fixPrompt = `## SonarQube Auto-Fix Request
|
|
20431
|
-
|
|
20432
|
-
The following critical issues were found and need to be fixed:
|
|
20433
|
-
|
|
20434
|
-
${issueList}
|
|
20435
|
-
|
|
20436
|
-
Please fix these issues now. Focus on:
|
|
20437
|
-
1. Security vulnerabilities first (BLOCKER)
|
|
20438
|
-
2. Then reliability issues (CRITICAL)
|
|
20439
|
-
|
|
20440
|
-
After fixing, I will re-run the analysis to verify.`;
|
|
20441
|
-
try {
|
|
20442
|
-
await client.session.prompt({
|
|
20443
|
-
path: { id: currentSessionId },
|
|
20444
|
-
body: {
|
|
20445
|
-
parts: [{ type: "text", text: fixPrompt }]
|
|
20446
|
-
}
|
|
20447
|
-
});
|
|
20448
|
-
} catch (error45) {
|
|
20449
|
-
await client.app.log({
|
|
20450
|
-
body: {
|
|
20451
|
-
service: "opencode-sonarqube",
|
|
20452
|
-
level: "error",
|
|
20453
|
-
message: "Failed to trigger auto-fix",
|
|
20454
|
-
extra: { error: String(error45) }
|
|
20455
|
-
}
|
|
20456
|
-
});
|
|
20457
|
-
}
|
|
20458
|
-
};
|
|
20459
20409
|
const qualityGatePattern = /Quality Gate: \[(PASS|FAIL)\] (\w+)/;
|
|
20460
20410
|
const issueCountPattern = /Blockers: (\d+), Critical: (\d+), Major: (\d+), Minor: (\d+), Info: (\d+)/;
|
|
20461
20411
|
const parseAnalysisResult = (message) => {
|
|
@@ -20497,26 +20447,15 @@ After fixing, I will re-run the analysis to verify.`;
|
|
|
20497
20447
|
hooks.fileEdited({ filePath: payload.path });
|
|
20498
20448
|
}
|
|
20499
20449
|
};
|
|
20500
|
-
const injectAnalysisResults = async (message,
|
|
20450
|
+
const injectAnalysisResults = async (message, _config, sessionId) => {
|
|
20501
20451
|
try {
|
|
20502
20452
|
await client.session.prompt({
|
|
20503
20453
|
path: { id: sessionId },
|
|
20504
20454
|
body: {
|
|
20505
|
-
noReply:
|
|
20455
|
+
noReply: true,
|
|
20506
20456
|
parts: [{ type: "text", text: message }]
|
|
20507
20457
|
}
|
|
20508
20458
|
});
|
|
20509
|
-
if (config2.autoFix && lastAnalysisResult) {
|
|
20510
|
-
const state = await getProjectState(getDirectory());
|
|
20511
|
-
if (state?.projectKey) {
|
|
20512
|
-
const api2 = createSonarQubeAPI(config2, state);
|
|
20513
|
-
const issues = await api2.issues.getFormattedIssues({
|
|
20514
|
-
projectKey: state.projectKey,
|
|
20515
|
-
severities: ["BLOCKER", "CRITICAL"]
|
|
20516
|
-
});
|
|
20517
|
-
await triggerAutoFix(issues);
|
|
20518
|
-
}
|
|
20519
|
-
}
|
|
20520
20459
|
} catch (error45) {
|
|
20521
20460
|
await client.app.log({
|
|
20522
20461
|
body: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-sonarqube",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.47",
|
|
4
4
|
"description": "OpenCode Plugin for SonarQube integration - Enterprise-level code quality from the start",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"homepage": "https://github.com/mguttmann/opencode-sonarqube#readme",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@opencode-ai/plugin": "^1.1.34",
|
|
41
|
+
"opencode-sonarqube": "^1.2.45",
|
|
41
42
|
"zod": "^3.24.0"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|