sonar-autofix 0.0.5
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/.idea/workspace.xml +191 -0
- package/PUBLISHING_INSTRUCTIONS.md +136 -0
- package/README.md +86 -0
- package/config.example.json +30 -0
- package/package.json +17 -0
- package/packages/cli/index.js +132 -0
- package/packages/cli/package.json +23 -0
- package/packages/core/index.js +473 -0
- package/packages/core/package.json +22 -0
- package/packages/git-client/index.js +371 -0
- package/packages/git-client/package.json +17 -0
- package/packages/github-action/action.yml +71 -0
- package/packages/github-action/index.js +86 -0
- package/packages/github-action/package.json +17 -0
- package/packages/llm-client/index.js +419 -0
- package/packages/llm-client/package.json +17 -0
- package/packages/sonar-client/index.js +327 -0
- package/packages/sonar-client/package.json +20 -0
- package/packages/validator/index.js +170 -0
- package/packages/validator/package.json +17 -0
- package/prompts/fix-issues.md +51 -0
- package/prompts/retry-fix.md +42 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="AutoImportSettings">
|
|
4
|
+
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
|
+
</component>
|
|
6
|
+
<component name="ChangeListManager">
|
|
7
|
+
<list default="true" id="2b435513-27c8-4fc6-b596-5368f46599ce" name="Changes" comment="package publishing changes">
|
|
8
|
+
<change beforePath="$PROJECT_DIR$/packages/cli/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/packages/cli/index.js" afterDir="false" />
|
|
9
|
+
<change beforePath="$PROJECT_DIR$/packages/cli/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/cli/package.json" afterDir="false" />
|
|
10
|
+
<change beforePath="$PROJECT_DIR$/packages/core/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/index.js" afterDir="false" />
|
|
11
|
+
<change beforePath="$PROJECT_DIR$/packages/core/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/package.json" afterDir="false" />
|
|
12
|
+
<change beforePath="$PROJECT_DIR$/packages/git-client/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/git-client/package.json" afterDir="false" />
|
|
13
|
+
<change beforePath="$PROJECT_DIR$/packages/github-action/action.yml" beforeDir="false" afterPath="$PROJECT_DIR$/packages/github-action/action.yml" afterDir="false" />
|
|
14
|
+
<change beforePath="$PROJECT_DIR$/packages/github-action/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/packages/github-action/index.js" afterDir="false" />
|
|
15
|
+
<change beforePath="$PROJECT_DIR$/packages/github-action/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/github-action/package.json" afterDir="false" />
|
|
16
|
+
<change beforePath="$PROJECT_DIR$/packages/llm-client/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/llm-client/package.json" afterDir="false" />
|
|
17
|
+
<change beforePath="$PROJECT_DIR$/packages/sonar-client/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/sonar-client/package.json" afterDir="false" />
|
|
18
|
+
<change beforePath="$PROJECT_DIR$/packages/validator/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/packages/validator/package.json" afterDir="false" />
|
|
19
|
+
</list>
|
|
20
|
+
<option name="SHOW_DIALOG" value="false" />
|
|
21
|
+
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
22
|
+
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
23
|
+
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
24
|
+
</component>
|
|
25
|
+
<component name="EmbeddingIndexingInfo">
|
|
26
|
+
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
|
27
|
+
</component>
|
|
28
|
+
<component name="Git.Settings">
|
|
29
|
+
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
30
|
+
</component>
|
|
31
|
+
<component name="GithubDefaultAccount">
|
|
32
|
+
<option name="defaultAccountId" value="6dade5ab-73e2-43de-8589-5680489ff109" />
|
|
33
|
+
</component>
|
|
34
|
+
<component name="McpProjectServerCommands">
|
|
35
|
+
<commands />
|
|
36
|
+
<urls />
|
|
37
|
+
</component>
|
|
38
|
+
<component name="NextEditCompletionFeaturesState">
|
|
39
|
+
<decayedCancelled>
|
|
40
|
+
<entry key="MS100" value="1.6744833171325262" />
|
|
41
|
+
<entry key="MS500" value="2.58172093612023" />
|
|
42
|
+
<entry key="S2" value="2.8844669777281875" />
|
|
43
|
+
<entry key="S5" value="2.952829092826303" />
|
|
44
|
+
<entry key="S10" value="2.9775799052902783" />
|
|
45
|
+
<entry key="S30" value="3.2207563904736163" />
|
|
46
|
+
<entry key="S60" value="4.125034379367315" />
|
|
47
|
+
<entry key="M2" value="6.484005379877605" />
|
|
48
|
+
<entry key="M5" value="16.623270843638018" />
|
|
49
|
+
<entry key="M10" value="29.496886119445264" />
|
|
50
|
+
<entry key="M15" value="38.53321653752027" />
|
|
51
|
+
<entry key="M30" value="70.6509361650961" />
|
|
52
|
+
<entry key="H1" value="145.50802139516395" />
|
|
53
|
+
<entry key="H2" value="245.85094452197504" />
|
|
54
|
+
<entry key="H4" value="356.03484955949796" />
|
|
55
|
+
<entry key="D1" value="698.1026936159626" />
|
|
56
|
+
<entry key="W1" value="847.6316849660216" />
|
|
57
|
+
</decayedCancelled>
|
|
58
|
+
<decayedSelected>
|
|
59
|
+
<entry key="MS100" value="0.0" />
|
|
60
|
+
<entry key="MS500" value="0.0" />
|
|
61
|
+
<entry key="S2" value="8.004104522733288E-98" />
|
|
62
|
+
<entry key="S5" value="1.7659974950749445E-39" />
|
|
63
|
+
<entry key="S10" value="5.606983364968166E-20" />
|
|
64
|
+
<entry key="S30" value="6.007864112985362E-7" />
|
|
65
|
+
<entry key="S60" value="0.0011366291571186739" />
|
|
66
|
+
<entry key="M2" value="0.053374018625082606" />
|
|
67
|
+
<entry key="M5" value="0.5796786411829966" />
|
|
68
|
+
<entry key="M10" value="1.3138956828306059" />
|
|
69
|
+
<entry key="M15" value="1.7608935390999911" />
|
|
70
|
+
<entry key="M30" value="2.67969488017297" />
|
|
71
|
+
<entry key="H1" value="4.088046159387631" />
|
|
72
|
+
<entry key="H2" value="5.749963416540233" />
|
|
73
|
+
<entry key="H4" value="7.4206497976591725" />
|
|
74
|
+
<entry key="D1" value="11.833666975867306" />
|
|
75
|
+
<entry key="W1" value="13.637653890653624" />
|
|
76
|
+
</decayedSelected>
|
|
77
|
+
<decayedShown>
|
|
78
|
+
<entry key="MS100" value="1.5755714284839712" />
|
|
79
|
+
<entry key="MS500" value="2.55267875896726" />
|
|
80
|
+
<entry key="S2" value="2.8764410362323525" />
|
|
81
|
+
<entry key="S5" value="2.9495496407514823" />
|
|
82
|
+
<entry key="S10" value="2.975927565551862" />
|
|
83
|
+
<entry key="S30" value="3.220162936681101" />
|
|
84
|
+
<entry key="S60" value="4.1257516017012605" />
|
|
85
|
+
<entry key="M2" value="6.5362002384950975" />
|
|
86
|
+
<entry key="M5" value="17.19949398327749" />
|
|
87
|
+
<entry key="M10" value="30.807204946579795" />
|
|
88
|
+
<entry key="M15" value="40.29098126195295" />
|
|
89
|
+
<entry key="M30" value="73.32822699520365" />
|
|
90
|
+
<entry key="H1" value="149.59415118159862" />
|
|
91
|
+
<entry key="H2" value="251.59949415755062" />
|
|
92
|
+
<entry key="H4" value="363.45450004438277" />
|
|
93
|
+
<entry key="D1" value="709.9360002138405" />
|
|
94
|
+
<entry key="W1" value="861.2692745399029" />
|
|
95
|
+
</decayedShown>
|
|
96
|
+
</component>
|
|
97
|
+
<component name="ProjectColorInfo">{
|
|
98
|
+
"associatedIndex": 0,
|
|
99
|
+
"fromUser": false
|
|
100
|
+
}</component>
|
|
101
|
+
<component name="ProjectId" id="3HYLMP5y2Kv5j83bVaucxd9Nu7S" />
|
|
102
|
+
<component name="ProjectViewState">
|
|
103
|
+
<option name="hideEmptyMiddlePackages" value="true" />
|
|
104
|
+
<option name="showLibraryContents" value="true" />
|
|
105
|
+
</component>
|
|
106
|
+
<component name="PropertiesComponent"><![CDATA[{
|
|
107
|
+
"keyToString": {
|
|
108
|
+
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
|
109
|
+
"RunOnceActivity.MCP Project settings loaded": "true",
|
|
110
|
+
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
111
|
+
"RunOnceActivity.git.unshallow": "true",
|
|
112
|
+
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
|
113
|
+
"SONARLINT_PRECOMMIT_ANALYSIS": "true",
|
|
114
|
+
"codeWithMe.voiceChat.enabledByDefault": "false",
|
|
115
|
+
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
|
116
|
+
"git-widget-placeholder": "master",
|
|
117
|
+
"javascript.nodejs.core.library.configured.version": "24.18.0",
|
|
118
|
+
"javascript.nodejs.core.library.typings.version": "24.13.3",
|
|
119
|
+
"javascript.preferred.runtime.type.id": "node",
|
|
120
|
+
"junie.onboarding.icon.badge.shown": "true",
|
|
121
|
+
"last_opened_file_path": "/Users/divyaaditya/projects/sonar-autofix",
|
|
122
|
+
"node.js.detected.package.eslint": "true",
|
|
123
|
+
"node.js.detected.package.jshint": "true",
|
|
124
|
+
"node.js.detected.package.tslint": "true",
|
|
125
|
+
"node.js.selected.package.eslint": "(autodetect)",
|
|
126
|
+
"node.js.selected.package.jshint": "",
|
|
127
|
+
"node.js.selected.package.tslint": "(autodetect)",
|
|
128
|
+
"nodejs_interpreter_path": "node",
|
|
129
|
+
"nodejs_package_manager_path": "npm",
|
|
130
|
+
"settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings",
|
|
131
|
+
"to.speed.mode.migration.done": "true",
|
|
132
|
+
"ts.external.directory.path": "/Applications/WebStorm.app/Contents/plugins/javascript-plugin/jsLanguageServicesImpl/external"
|
|
133
|
+
}
|
|
134
|
+
}]]></component>
|
|
135
|
+
<component name="RecentsManager">
|
|
136
|
+
<key name="CopyFile.RECENT_KEYS">
|
|
137
|
+
<recent name="$PROJECT_DIR$" />
|
|
138
|
+
</key>
|
|
139
|
+
</component>
|
|
140
|
+
<component name="SharedIndexes">
|
|
141
|
+
<attachedChunks>
|
|
142
|
+
<set>
|
|
143
|
+
<option value="bundled-js-predefined-d6986cc7102b-4abd2a77f808-JavaScript-WS-262.9437.145" />
|
|
144
|
+
</set>
|
|
145
|
+
</attachedChunks>
|
|
146
|
+
</component>
|
|
147
|
+
<component name="TaskManager">
|
|
148
|
+
<task active="true" id="Default" summary="Default task">
|
|
149
|
+
<changelist id="2b435513-27c8-4fc6-b596-5368f46599ce" name="Changes" comment="" />
|
|
150
|
+
<created>1786040006836</created>
|
|
151
|
+
<option name="number" value="Default" />
|
|
152
|
+
<option name="presentableId" value="Default" />
|
|
153
|
+
<updated>1786040006836</updated>
|
|
154
|
+
<workItem from="1786040007924" duration="6453000" />
|
|
155
|
+
<workItem from="1786046840005" duration="601000" />
|
|
156
|
+
<workItem from="1786830049128" duration="109000" />
|
|
157
|
+
<workItem from="1786830198912" duration="598000" />
|
|
158
|
+
<workItem from="1787769103566" duration="9226000" />
|
|
159
|
+
<workItem from="1787817536391" duration="61000" />
|
|
160
|
+
<workItem from="1787859060707" duration="1282000" />
|
|
161
|
+
<workItem from="1787860367363" duration="674000" />
|
|
162
|
+
<workItem from="1788016099431" duration="1199000" />
|
|
163
|
+
<workItem from="1788165341480" duration="4495000" />
|
|
164
|
+
<workItem from="1788169983174" duration="1684000" />
|
|
165
|
+
<workItem from="1788171725187" duration="4774000" />
|
|
166
|
+
<workItem from="1788177896634" duration="4501000" />
|
|
167
|
+
<workItem from="1788182750659" duration="236000" />
|
|
168
|
+
</task>
|
|
169
|
+
<task id="LOCAL-00001" summary="package publishing changes">
|
|
170
|
+
<option name="closed" value="true" />
|
|
171
|
+
<created>1788181949023</created>
|
|
172
|
+
<option name="number" value="00001" />
|
|
173
|
+
<option name="presentableId" value="LOCAL-00001" />
|
|
174
|
+
<option name="project" value="LOCAL" />
|
|
175
|
+
<updated>1788181949023</updated>
|
|
176
|
+
</task>
|
|
177
|
+
<option name="localTasksCounter" value="2" />
|
|
178
|
+
<servers />
|
|
179
|
+
</component>
|
|
180
|
+
<component name="TypeScriptGeneratedFilesManager">
|
|
181
|
+
<option name="version" value="3" />
|
|
182
|
+
</component>
|
|
183
|
+
<component name="VcsManagerConfiguration">
|
|
184
|
+
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
|
|
185
|
+
<ignored-roots>
|
|
186
|
+
<path value="$PROJECT_DIR$" />
|
|
187
|
+
</ignored-roots>
|
|
188
|
+
<MESSAGE value="package publishing changes" />
|
|
189
|
+
<option name="LAST_COMMIT_MESSAGE" value="package publishing changes" />
|
|
190
|
+
</component>
|
|
191
|
+
</project>
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Publishing Instructions for sonar-autofix Monorepo
|
|
2
|
+
|
|
3
|
+
This document outlines how to publish all packages in this monorepo to npm.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
The project is a monorepo containing 7 packages under the `@sonar-autofix` scope:
|
|
7
|
+
1. @sonar-autofix/cli
|
|
8
|
+
2. @sonar-autofix/core
|
|
9
|
+
3. @sonar-autofix/git-client
|
|
10
|
+
4. @sonar-autofix/github-action
|
|
11
|
+
5. @sonar-autofix/llm-client
|
|
12
|
+
6. @sonar-autofix/sonar-client
|
|
13
|
+
7. @sonar-autofix/validator
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
1. You must have npm account with publish permissions
|
|
17
|
+
2. You need to be logged into npm: `npm login`
|
|
18
|
+
3. All packages must have unique versions (they currently all have version 0.0.1)
|
|
19
|
+
|
|
20
|
+
## Publishing Steps
|
|
21
|
+
|
|
22
|
+
### Option 1: Manual Publishing (Simplest)
|
|
23
|
+
```bash
|
|
24
|
+
# Navigate to each package and publish individually
|
|
25
|
+
cd packages/cli && npm publish
|
|
26
|
+
cd ../core && npm publish
|
|
27
|
+
cd ../git-client && npm publish
|
|
28
|
+
cd ../github-action && npm publish
|
|
29
|
+
cd ../llm-client && npm publish
|
|
30
|
+
cd ../sonar-client && npm publish
|
|
31
|
+
cd ../validator && npm publish
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Option 2: Using Changesets (Recommended for Version Management)
|
|
35
|
+
1. Install changesets:
|
|
36
|
+
```bash
|
|
37
|
+
npm install @changesets/cli --save-dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. Initialize changesets:
|
|
41
|
+
```bash
|
|
42
|
+
npx changeset init
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
3. Create a changeset for each package:
|
|
46
|
+
```bash
|
|
47
|
+
npx changeset add
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
4. Generate version updates and publish:
|
|
51
|
+
```bash
|
|
52
|
+
npx changeset version
|
|
53
|
+
npm publish
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Option 3: Using Lerna (Alternative)
|
|
57
|
+
1. Install lerna:
|
|
58
|
+
```bash
|
|
59
|
+
npm install lerna --save-dev
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
2. Configure lerna in root package.json:
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"name": "sonar-autofix",
|
|
66
|
+
"version": "0.0.1",
|
|
67
|
+
"lerna": {
|
|
68
|
+
"packages": [
|
|
69
|
+
"packages/*"
|
|
70
|
+
],
|
|
71
|
+
"version": "independent"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
3. Publish packages:
|
|
77
|
+
```bash
|
|
78
|
+
npx lerna publish --scope @sonar-autofix/*
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Package Structure
|
|
82
|
+
Each package contains:
|
|
83
|
+
- `index.js` - Main implementation file
|
|
84
|
+
- `package.json` - Package configuration (already properly set up)
|
|
85
|
+
- Some packages also contain additional files:
|
|
86
|
+
- `github-action` contains `action.yml`
|
|
87
|
+
- All packages have proper main entry points
|
|
88
|
+
|
|
89
|
+
## Configuration Notes
|
|
90
|
+
1. All package.json files already correctly specify:
|
|
91
|
+
- Scoped names: `@sonar-autofix/*`
|
|
92
|
+
- Proper main entry points
|
|
93
|
+
- Version numbers (currently 0.0.1 for all)
|
|
94
|
+
|
|
95
|
+
2. The root package.json includes:
|
|
96
|
+
- `workspaces` configuration
|
|
97
|
+
- Dependencies
|
|
98
|
+
|
|
99
|
+
3. Files to ensure are included in published packages:
|
|
100
|
+
- All JavaScript files (index.js)
|
|
101
|
+
- action.yml (for github-action package)
|
|
102
|
+
- All necessary source code files
|
|
103
|
+
|
|
104
|
+
## Publishing Considerations
|
|
105
|
+
1. **Version Management**: All packages currently have version 0.0.1 - you should update these to appropriate versions
|
|
106
|
+
2. **Scope**: All packages are correctly scoped under `@sonar-autofix`
|
|
107
|
+
3. **Dependencies**: Packages depend on each other (e.g., CLI depends on core, which depends on other packages)
|
|
108
|
+
4. **Publish Access**: Make sure you have permissions to publish to the `@sonar-autofix` scope
|
|
109
|
+
|
|
110
|
+
## Troubleshooting
|
|
111
|
+
1. If publishing fails due to version conflicts:
|
|
112
|
+
- Update version numbers in each package.json
|
|
113
|
+
- Ensure versions are unique and follow semantic versioning
|
|
114
|
+
|
|
115
|
+
2. If files appear to be missing:
|
|
116
|
+
- Check .npmignore files in each package directory
|
|
117
|
+
- Ensure no files are being excluded
|
|
118
|
+
|
|
119
|
+
3. If you get 404 errors:
|
|
120
|
+
- Make sure you're using the correct scope name
|
|
121
|
+
- Verify that your npm account has proper permissions
|
|
122
|
+
|
|
123
|
+
## Best Practices
|
|
124
|
+
1. Use semantic versioning (v0.1.0, v0.2.0, etc.)
|
|
125
|
+
2. Consider using changesets or lerna for consistent versioning across packages
|
|
126
|
+
3. Document breaking changes in changelogs
|
|
127
|
+
4. Test package installations in clean environments before publishing
|
|
128
|
+
|
|
129
|
+
## Testing After Publishing
|
|
130
|
+
After publishing, test installation:
|
|
131
|
+
```bash
|
|
132
|
+
# In a new project
|
|
133
|
+
npm install @sonar-autofix/cli
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Check that all expected files and functionality are present.
|
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# sonar-autofix
|
|
2
|
+
|
|
3
|
+
This is a monorepo for the GitHub Sonar Autofix project, which automatically fixes code issues found by SonarQube/SonarCloud using LLMs.
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
sonar-autofix/
|
|
9
|
+
├── packages/
|
|
10
|
+
│ ├── core/
|
|
11
|
+
│ ├── github-action/
|
|
12
|
+
│ ├── cli/
|
|
13
|
+
│ ├── sonar-client/
|
|
14
|
+
│ ├── llm-client/
|
|
15
|
+
│ ├── git-client/
|
|
16
|
+
│ └── validator/
|
|
17
|
+
├── prompts/
|
|
18
|
+
├── examples/
|
|
19
|
+
├── docs/
|
|
20
|
+
├── tests/
|
|
21
|
+
└── README.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Goal
|
|
25
|
+
|
|
26
|
+
Build a reusable GitHub Action and CLI that automatically:
|
|
27
|
+
1. Runs SonarQube/SonarCloud analysis
|
|
28
|
+
2. Fetches open issues
|
|
29
|
+
3. Uses an OpenAI-compatible LLM (LM Studio by default) to fix issues
|
|
30
|
+
4. Validates changes (build, lint, tests)
|
|
31
|
+
5. Re-runs Sonar
|
|
32
|
+
6. Repeats until no more fixable issues remain (or retry limit reached)
|
|
33
|
+
7. Commits changes
|
|
34
|
+
8. Pushes a branch
|
|
35
|
+
9. Creates a Pull Request
|
|
36
|
+
|
|
37
|
+
## Packages
|
|
38
|
+
|
|
39
|
+
### core
|
|
40
|
+
Responsible only for orchestration.
|
|
41
|
+
|
|
42
|
+
### sonar-client
|
|
43
|
+
- Run sonar-scanner
|
|
44
|
+
- Wait for Quality Gate
|
|
45
|
+
- Fetch issues
|
|
46
|
+
- Fetch hotspots
|
|
47
|
+
- Download source metadata
|
|
48
|
+
- Read metrics
|
|
49
|
+
|
|
50
|
+
### llm-client
|
|
51
|
+
Provider abstraction for various LLM providers:
|
|
52
|
+
- LM Studio
|
|
53
|
+
- OpenAI
|
|
54
|
+
- Azure OpenAI
|
|
55
|
+
- Anthropic
|
|
56
|
+
- Ollama
|
|
57
|
+
- OpenRouter
|
|
58
|
+
|
|
59
|
+
### git-client
|
|
60
|
+
- Create branch
|
|
61
|
+
- Checkout
|
|
62
|
+
- Commit
|
|
63
|
+
- Push
|
|
64
|
+
- Restore file
|
|
65
|
+
- Reset
|
|
66
|
+
- Create Pull Request (GitHub CLI)
|
|
67
|
+
|
|
68
|
+
### validator
|
|
69
|
+
Runs configurable commands:
|
|
70
|
+
- npm run build
|
|
71
|
+
- npm run lint
|
|
72
|
+
- npm test
|
|
73
|
+
|
|
74
|
+
### github-action
|
|
75
|
+
Thin wrapper that reads action inputs and invokes core.run()
|
|
76
|
+
|
|
77
|
+
### cli
|
|
78
|
+
Exposes `npx sonar-autofix` using the same core package
|
|
79
|
+
|
|
80
|
+
## Usage on Existing Projects
|
|
81
|
+
|
|
82
|
+
See [USAGE.md](USAGE.md) for detailed instructions on how to use this tool with your existing projects.
|
|
83
|
+
|
|
84
|
+
## Documentation
|
|
85
|
+
|
|
86
|
+
For more details, see [PROJECT.md](PROJECT.md)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"sonar": {
|
|
3
|
+
"host": "http://localhost:9000",
|
|
4
|
+
"project": "fundrest_core",
|
|
5
|
+
"token": "squ_31cadad2716678bde9ba02e7da4ce1b4c43c4944"
|
|
6
|
+
},
|
|
7
|
+
"llm": {
|
|
8
|
+
"provider": "lmstudio",
|
|
9
|
+
"endpoint": "http://localhost:1234/v1",
|
|
10
|
+
"model": "qwen3-coder-30b"
|
|
11
|
+
},
|
|
12
|
+
"validation": {
|
|
13
|
+
"build": [
|
|
14
|
+
"npm run build"
|
|
15
|
+
],
|
|
16
|
+
"lint": [
|
|
17
|
+
"npm run lint"
|
|
18
|
+
],
|
|
19
|
+
"tests": [
|
|
20
|
+
"npm test"
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"git": {
|
|
24
|
+
"branch": "sonar-autofix"
|
|
25
|
+
},
|
|
26
|
+
"retry": {
|
|
27
|
+
"maxIterations": 5
|
|
28
|
+
},
|
|
29
|
+
"prompt": {}
|
|
30
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sonar-autofix",
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"test": "node tests/core.test.js",
|
|
6
|
+
"test:structure": "node test-project.js"
|
|
7
|
+
},
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"workspaces": [
|
|
12
|
+
"packages/*"
|
|
13
|
+
],
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"axios": "^1.19.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// CLI entry point for Sonar Autofix
|
|
3
|
+
const CoreOrchestrator = require('@sonar-autofix/core');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* CLI interface for the Sonar Autofix tool
|
|
9
|
+
* Supports configuration via JSON file and/or environment variables.
|
|
10
|
+
*/
|
|
11
|
+
async function main() {
|
|
12
|
+
console.log('Sonar Autofix CLI');
|
|
13
|
+
console.log('=========================');
|
|
14
|
+
|
|
15
|
+
// Parse command line arguments
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
|
|
18
|
+
// Handle help
|
|
19
|
+
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
20
|
+
console.log('');
|
|
21
|
+
console.log('This tool automatically fixes Sonar issues using LLMs.');
|
|
22
|
+
console.log('');
|
|
23
|
+
console.log('Usage:');
|
|
24
|
+
console.log(' npx sonar-autofix --config <path> [options]');
|
|
25
|
+
console.log('');
|
|
26
|
+
console.log('Options:');
|
|
27
|
+
console.log(' --help, -h Show this help message');
|
|
28
|
+
console.log(' --version, -v Show version information');
|
|
29
|
+
console.log(' --config <path> Path to configuration JSON file');
|
|
30
|
+
console.log(' --dry-run Run without making changes');
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log('Environment Variables:');
|
|
33
|
+
console.log(' SONAR_HOST SonarQube/SonarCloud host URL');
|
|
34
|
+
console.log(' SONAR_PROJECT Sonar project key');
|
|
35
|
+
console.log(' SONAR_TOKEN Sonar authentication token');
|
|
36
|
+
console.log(' LLM_PROVIDER LLM provider (lmstudio, openai, azure, anthropic, ollama, openrouter)');
|
|
37
|
+
console.log(' LLM_ENDPOINT LLM API endpoint URL');
|
|
38
|
+
console.log(' LLM_MODEL LLM model name');
|
|
39
|
+
console.log(' LLM_API_KEY LLM API key');
|
|
40
|
+
console.log(' GIT_BRANCH Branch name for autofix commits (default: sonar-autofix)');
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log('Environment variables override config file values.');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Handle version
|
|
47
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
48
|
+
console.log('sonar-autofix v0.0.1');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Handle dry-run flag
|
|
53
|
+
const dryRun = args.includes('--dry-run');
|
|
54
|
+
|
|
55
|
+
// Load configuration from file
|
|
56
|
+
let config = {};
|
|
57
|
+
const configIndex = args.indexOf('--config');
|
|
58
|
+
if (configIndex !== -1 && configIndex + 1 < args.length) {
|
|
59
|
+
const configPath = args[configIndex + 1];
|
|
60
|
+
try {
|
|
61
|
+
const configFileContent = fs.readFileSync(path.resolve(configPath), 'utf8');
|
|
62
|
+
config = JSON.parse(configFileContent);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error('❌ Failed to read configuration file:', error.message);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Apply environment variable overrides
|
|
70
|
+
if (process.env.SONAR_HOST || process.env.SONAR_PROJECT || process.env.SONAR_TOKEN) {
|
|
71
|
+
config.sonar = config.sonar || {};
|
|
72
|
+
if (process.env.SONAR_HOST) config.sonar.host = process.env.SONAR_HOST;
|
|
73
|
+
if (process.env.SONAR_PROJECT) config.sonar.project = process.env.SONAR_PROJECT;
|
|
74
|
+
if (process.env.SONAR_TOKEN) config.sonar.token = process.env.SONAR_TOKEN;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (process.env.LLM_PROVIDER || process.env.LLM_ENDPOINT || process.env.LLM_MODEL || process.env.LLM_API_KEY) {
|
|
78
|
+
config.llm = config.llm || {};
|
|
79
|
+
if (process.env.LLM_PROVIDER) config.llm.provider = process.env.LLM_PROVIDER;
|
|
80
|
+
if (process.env.LLM_ENDPOINT) config.llm.endpoint = process.env.LLM_ENDPOINT;
|
|
81
|
+
if (process.env.LLM_MODEL) config.llm.model = process.env.LLM_MODEL;
|
|
82
|
+
if (process.env.LLM_API_KEY) config.llm.apiKey = process.env.LLM_API_KEY;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (process.env.GIT_BRANCH) {
|
|
86
|
+
config.git = config.git || {};
|
|
87
|
+
config.git.branch = process.env.GIT_BRANCH;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Apply dry-run
|
|
91
|
+
if (dryRun) {
|
|
92
|
+
config.dryRun = true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Validate required configuration
|
|
96
|
+
if (!config.sonar?.project) {
|
|
97
|
+
console.error('❌ Missing required configuration: sonar.project (or SONAR_PROJECT env var)');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
if (!config.sonar?.token) {
|
|
101
|
+
console.error('❌ Missing required configuration: sonar.token (or SONAR_TOKEN env var)');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
if (!config.llm?.provider) {
|
|
105
|
+
console.error('❌ Missing required configuration: llm.provider (or LLM_PROVIDER env var)');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Run the core orchestrator
|
|
110
|
+
try {
|
|
111
|
+
const orchestrator = new CoreOrchestrator(config);
|
|
112
|
+
|
|
113
|
+
console.log('🚀 Starting Sonar Autofix...');
|
|
114
|
+
if (dryRun) {
|
|
115
|
+
console.log(' (dry-run mode — no changes will be made)');
|
|
116
|
+
}
|
|
117
|
+
const summary = await orchestrator.run();
|
|
118
|
+
|
|
119
|
+
console.log('✅ Done!');
|
|
120
|
+
return summary;
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error('❌ Error:', error.message);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Run the CLI if this file is executed directly
|
|
128
|
+
if (require.main === module) {
|
|
129
|
+
main();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
module.exports = { main };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sonar-autofix/cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "CLI tool for the Sonar Autofix tool",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"sonar-autofix": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"sonar",
|
|
14
|
+
"autofix",
|
|
15
|
+
"github",
|
|
16
|
+
"cli"
|
|
17
|
+
],
|
|
18
|
+
"author": "Sonar Autofix Team",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@sonar-autofix/core": "^0.0.1"
|
|
22
|
+
}
|
|
23
|
+
}
|