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.
@@ -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
+ &quot;associatedIndex&quot;: 0,
99
+ &quot;fromUser&quot;: 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
+ }