codereviewerai 1.0.0
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 +336 -0
- package/bin/awesomediagns.js +9 -0
- package/dist/ai/provider.js +157 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/config/manager.js +94 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/wizard.js +89 -0
- package/dist/config/wizard.js.map +1 -0
- package/dist/core/context.js +121 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/reviewer.js +108 -0
- package/dist/core/reviewer.js.map +1 -0
- package/dist/core/watcher.js +75 -0
- package/dist/core/watcher.js.map +1 -0
- package/dist/index.js +102 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/chat.js +88 -0
- package/dist/ui/chat.js.map +1 -0
- package/dist/ui/home.js +54 -0
- package/dist/ui/home.js.map +1 -0
- package/package.json +52 -0
- package/src/ai/provider.ts +170 -0
- package/src/config/manager.ts +120 -0
- package/src/config/wizard.ts +93 -0
- package/src/core/context.ts +139 -0
- package/src/core/reviewer.ts +127 -0
- package/src/core/watcher.ts +86 -0
- package/src/index.ts +109 -0
- package/src/ui/chat.ts +111 -0
- package/src/ui/home.ts +60 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
|
|
2
|
+
██████╗ ██████╗ ██████╗ ███████╗██████╗ ███████╗██╗ ██╗██╗███████╗██╗ ██╗███████╗██████╗
|
|
3
|
+
██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔══██╗██╔════╝██║ ██║██║██╔════╝██║ ██║██╔════╝██╔══██╗
|
|
4
|
+
██║ ██║ ██║██║ ██║█████╗ ██████╔╝█████╗ ██║ ██║██║█████╗ ██║ █╗ ██║█████╗ ██████╔╝
|
|
5
|
+
██║ ██║ ██║██║ ██║██╔══╝ ██╔══██╗██╔══╝ ╚██╗ ██╔╝██║██╔══╝ ██║███╗██║██╔══╝ ██╔══██╗
|
|
6
|
+
╚██████╗╚██████╔╝██████╔╝███████╗██║ ██║███████╗ ╚████╔╝ ██║███████╗╚███╔███╔╝███████╗██║ ██║
|
|
7
|
+
╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═══╝ ╚═╝╚══════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝.ai
|
|
8
|
+
|
|
9
|
+
# 🚀 Code Review CLI
|
|
10
|
+
|
|
11
|
+
> Entertainment • Development • Productivity • A Well Being
|
|
12
|
+
|
|
13
|
+
AI-powered code review tool that helps developers write better code with real-time feedback from Gemini, Claude, or OpenAI.
|
|
14
|
+
|
|
15
|
+
## ✨ Features
|
|
16
|
+
|
|
17
|
+
- 🤖 **Multiple AI Providers**: Choose between Google Gemini, Anthropic Claude, or OpenAI
|
|
18
|
+
- ⚡ **Auto Review Mode**: Automatic code review on file save with smart debouncing
|
|
19
|
+
- 👤 **Manual Review Mode**: Review files on-demand with simple commands
|
|
20
|
+
- 💬 **Interactive Chat**: Ask questions and get code suggestions
|
|
21
|
+
- 🔄 **Git Integration**: Review staged files before commit
|
|
22
|
+
- 📚 **Context Awareness**: Maintains conversation history for better suggestions
|
|
23
|
+
- 🎯 **Configurable Depth**: Quick, standard, or deep analysis modes
|
|
24
|
+
- 📊 **Review History**: Track all your code reviews with scores
|
|
25
|
+
|
|
26
|
+
## 📦 Installation
|
|
27
|
+
|
|
28
|
+
### Prerequisites
|
|
29
|
+
- Node.js 18+
|
|
30
|
+
- npm or yarn
|
|
31
|
+
- Git (optional, for git integration)
|
|
32
|
+
|
|
33
|
+
### Setup Steps
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# 1. Clone or create project directory
|
|
37
|
+
mkdir codereview
|
|
38
|
+
cd codereview
|
|
39
|
+
|
|
40
|
+
# 2. Initialize npm project
|
|
41
|
+
npm init -y
|
|
42
|
+
|
|
43
|
+
# 3. Install dependencies
|
|
44
|
+
npm install commander inquirer@9.2.12 chalk@4.1.2 chalk-animation figlet gradient-string chokidar simple-git axios dotenv conf@11.0.2 ora@5.4.1 boxen@5.1.2 cli-table3 nanospinner
|
|
45
|
+
|
|
46
|
+
# 4. Install dev dependencies
|
|
47
|
+
npm install -D typescript @types/node @types/figlet @types/gradient-string ts-node
|
|
48
|
+
|
|
49
|
+
# 5. Copy all source files to respective directories
|
|
50
|
+
# Copy package.json, tsconfig.json
|
|
51
|
+
# Copy src/ directory with all files
|
|
52
|
+
|
|
53
|
+
# 6. Build the project
|
|
54
|
+
npm run build
|
|
55
|
+
|
|
56
|
+
# 7. Link globally (for development)
|
|
57
|
+
npm link
|
|
58
|
+
|
|
59
|
+
# OR install globally after publishing
|
|
60
|
+
npm install -g codereview
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 🎯 Quick Start
|
|
64
|
+
|
|
65
|
+
### First Time Setup
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Run the configuration wizard
|
|
69
|
+
awd config
|
|
70
|
+
|
|
71
|
+
# Or use long form
|
|
72
|
+
awesomediagns config
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Follow the interactive prompts to:
|
|
76
|
+
1. Select your AI provider (Gemini/Claude/OpenAI)
|
|
77
|
+
2. Enter your API key
|
|
78
|
+
3. Choose your preferred model
|
|
79
|
+
4. Set review mode (Auto/Manual)
|
|
80
|
+
5. Configure advanced settings
|
|
81
|
+
|
|
82
|
+
### Initialize in Your Project
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Navigate to your project
|
|
86
|
+
cd my-project
|
|
87
|
+
|
|
88
|
+
# Initialize AwesomeDiagns
|
|
89
|
+
awd init
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Review Your Code
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Review a specific file
|
|
96
|
+
awd review src/index.js
|
|
97
|
+
|
|
98
|
+
# Review all modified files
|
|
99
|
+
awd review
|
|
100
|
+
|
|
101
|
+
# Review staged files (git)
|
|
102
|
+
awd review --staged
|
|
103
|
+
|
|
104
|
+
# Review all files in project
|
|
105
|
+
awd review --all
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Auto Mode (Watch files)
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Start watching files
|
|
112
|
+
awd watch
|
|
113
|
+
|
|
114
|
+
# Files will be automatically reviewed on save
|
|
115
|
+
# Press Ctrl+C to stop
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Interactive Chat
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Start chat mode
|
|
122
|
+
awd chat
|
|
123
|
+
|
|
124
|
+
# Ask questions like:
|
|
125
|
+
# "How can I optimize this function?"
|
|
126
|
+
# "What's the best way to handle errors in async functions?"
|
|
127
|
+
# "Review my recent changes"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 📋 All Commands
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
awd # Show home screen
|
|
134
|
+
awd init # Initialize in current project
|
|
135
|
+
awd config # Run configuration wizard
|
|
136
|
+
awd config --show # Show current configuration
|
|
137
|
+
awd config --provider # Change AI provider
|
|
138
|
+
awd config --mode # Change review mode
|
|
139
|
+
awd review [file] # Review file(s)
|
|
140
|
+
awd review --all # Review all project files
|
|
141
|
+
awd review --staged # Review staged git files
|
|
142
|
+
awd watch # Start auto-review mode
|
|
143
|
+
awd chat # Interactive chat with AI
|
|
144
|
+
awd status # Show configuration status
|
|
145
|
+
awd history # View review history
|
|
146
|
+
awd history --clear # Clear history
|
|
147
|
+
awd help # Show all commands
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## 🔧 Configuration
|
|
151
|
+
|
|
152
|
+
### Global Configuration
|
|
153
|
+
Stored in: `~/.config/awesomediagns/config.json`
|
|
154
|
+
|
|
155
|
+
Contains:
|
|
156
|
+
- AI provider settings
|
|
157
|
+
- API keys
|
|
158
|
+
- Review preferences
|
|
159
|
+
- Mode settings
|
|
160
|
+
|
|
161
|
+
### Project Configuration
|
|
162
|
+
Stored in: `.awesomediagns/config.json` in your project
|
|
163
|
+
|
|
164
|
+
Contains:
|
|
165
|
+
- Watched file patterns
|
|
166
|
+
- Ignore patterns
|
|
167
|
+
- Git settings
|
|
168
|
+
- Project-specific settings
|
|
169
|
+
|
|
170
|
+
### API Keys
|
|
171
|
+
|
|
172
|
+
#### Google Gemini
|
|
173
|
+
1. Visit: https://makersuite.google.com/app/apikey
|
|
174
|
+
2. Create API key
|
|
175
|
+
3. Free tier available!
|
|
176
|
+
|
|
177
|
+
#### Anthropic Claude
|
|
178
|
+
1. Visit: https://console.anthropic.com/
|
|
179
|
+
2. Create account and get API key
|
|
180
|
+
3. Requires payment method
|
|
181
|
+
|
|
182
|
+
#### OpenAI
|
|
183
|
+
1. Visit: https://platform.openai.com/api-keys
|
|
184
|
+
2. Create API key
|
|
185
|
+
3. Requires payment method
|
|
186
|
+
|
|
187
|
+
## 📁 Project Structure
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
my-project/
|
|
191
|
+
├── .awesomediagns/
|
|
192
|
+
│ ├── config.json # Project config
|
|
193
|
+
│ └── history/
|
|
194
|
+
│ ├── reviews.json # Review history
|
|
195
|
+
│ └── chat.json # Chat history
|
|
196
|
+
├── src/
|
|
197
|
+
└── ...
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 🎨 Customization
|
|
201
|
+
|
|
202
|
+
### Watched File Patterns
|
|
203
|
+
Edit `.awesomediagns/config.json`:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"watchedFiles": [
|
|
208
|
+
"**/*.js",
|
|
209
|
+
"**/*.ts",
|
|
210
|
+
"**/*.jsx",
|
|
211
|
+
"**/*.tsx",
|
|
212
|
+
"**/*.py"
|
|
213
|
+
],
|
|
214
|
+
"ignoredPatterns": [
|
|
215
|
+
"node_modules/**",
|
|
216
|
+
"dist/**",
|
|
217
|
+
"build/**"
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Review Depth
|
|
223
|
+
- **Quick**: Fast scan, critical issues only
|
|
224
|
+
- **Standard**: Balanced review (recommended)
|
|
225
|
+
- **Deep**: Thorough analysis with security, performance, architecture
|
|
226
|
+
|
|
227
|
+
### Auto Save Delay
|
|
228
|
+
Configure delay (1-30 seconds) before auto-review triggers after file save.
|
|
229
|
+
|
|
230
|
+
## 🔒 Privacy & Security
|
|
231
|
+
|
|
232
|
+
- API keys stored locally in config files
|
|
233
|
+
- Code is sent to AI providers for review
|
|
234
|
+
- Conversation history stored locally
|
|
235
|
+
- No data sent to AwesomeDiagns servers (we don't have any!)
|
|
236
|
+
|
|
237
|
+
## 🐛 Troubleshooting
|
|
238
|
+
|
|
239
|
+
### API Key Issues
|
|
240
|
+
```bash
|
|
241
|
+
# Reconfigure provider
|
|
242
|
+
awd config --provider
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Project Not Initialized
|
|
246
|
+
```bash
|
|
247
|
+
# Re-run init
|
|
248
|
+
awd init
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Clear Everything
|
|
252
|
+
```bash
|
|
253
|
+
awd config --reset
|
|
254
|
+
awd history --clear
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## 📝 Examples
|
|
258
|
+
|
|
259
|
+
### Example Review Output
|
|
260
|
+
```
|
|
261
|
+
╭──────────────────────────────────────────╮
|
|
262
|
+
│ 📋 Code Review: index.js │
|
|
263
|
+
│ │
|
|
264
|
+
│ Summary: │
|
|
265
|
+
│ Good code structure. Found 2 issues │
|
|
266
|
+
│ and 3 optimization opportunities. │
|
|
267
|
+
│ │
|
|
268
|
+
│ 🐛 Issues Found: │
|
|
269
|
+
│ 1. Missing error handling │
|
|
270
|
+
│ Line 42 │
|
|
271
|
+
│ 💡 Add try-catch block │
|
|
272
|
+
│ │
|
|
273
|
+
│ ⚡ Optimizations: │
|
|
274
|
+
│ 1. Use async/await instead of .then() │
|
|
275
|
+
│ 2. Cache API responses │
|
|
276
|
+
│ │
|
|
277
|
+
│ Score: 8/10 │
|
|
278
|
+
╰──────────────────────────────────────────╯
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## 🚀 Advanced Usage
|
|
282
|
+
|
|
283
|
+
### Git Hooks Integration
|
|
284
|
+
Coming soon! Pre-commit hooks for automatic review.
|
|
285
|
+
|
|
286
|
+
### VS Code Extension
|
|
287
|
+
Planned for future release.
|
|
288
|
+
|
|
289
|
+
### Team Features
|
|
290
|
+
- Shared configurations
|
|
291
|
+
- Team review standards
|
|
292
|
+
- Custom rules engine
|
|
293
|
+
|
|
294
|
+
## 📄 License
|
|
295
|
+
MIT License
|
|
296
|
+
|
|
297
|
+
Copyright (c) 2026 methreamarnath1
|
|
298
|
+
|
|
299
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
300
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
301
|
+
in the Software without restriction, including without limitation the rights
|
|
302
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
303
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
304
|
+
furnished to do so, subject to the following conditions:
|
|
305
|
+
|
|
306
|
+
The above copyright notice and this permission notice shall be included in all
|
|
307
|
+
copies or substantial portions of the Software.
|
|
308
|
+
|
|
309
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
310
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
311
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
312
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
313
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
314
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
315
|
+
SOFTWARE.
|
|
316
|
+
|
|
317
|
+
## 🤝 Contributing
|
|
318
|
+
|
|
319
|
+
Contributions welcome! Please:
|
|
320
|
+
1. Fork the repo
|
|
321
|
+
2. Create feature branch
|
|
322
|
+
3. Submit pull request
|
|
323
|
+
|
|
324
|
+
## 📞 Support
|
|
325
|
+
|
|
326
|
+
- GitHub Issues: [methreamarnath1]
|
|
327
|
+
- Email: methreamarnath@gamil.com
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
## 🌟 Star Us!
|
|
331
|
+
|
|
332
|
+
If you find this tool helpful, please star the repo!
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
Made with ❤️ for developers who care about code quality
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
export class AIProvider {
|
|
3
|
+
config;
|
|
4
|
+
constructor(configManager) {
|
|
5
|
+
this.config = configManager.getConfig();
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The main function to send code to the AI
|
|
9
|
+
*/
|
|
10
|
+
async reviewCode(code, filePath, context) {
|
|
11
|
+
const prompt = this.buildReviewPrompt(code, filePath, context);
|
|
12
|
+
try {
|
|
13
|
+
switch (this.config.provider) {
|
|
14
|
+
case 'gemini':
|
|
15
|
+
return await this.reviewWithGemini(prompt);
|
|
16
|
+
case 'openai':
|
|
17
|
+
return await this.reviewWithOpenAI(prompt);
|
|
18
|
+
case 'claude':
|
|
19
|
+
return await this.reviewWithClaude(prompt);
|
|
20
|
+
default:
|
|
21
|
+
throw new Error('No AI provider configured. Run "awd init"');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new Error(`AI Request Failed: ${error.response?.data?.error?.message || error.message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Chat with the AI using conversation history
|
|
30
|
+
*/
|
|
31
|
+
async chat(message, history) {
|
|
32
|
+
try {
|
|
33
|
+
switch (this.config.provider) {
|
|
34
|
+
case 'gemini':
|
|
35
|
+
return await this.chatWithGemini(message, history);
|
|
36
|
+
case 'openai':
|
|
37
|
+
return await this.chatWithOpenAI(message, history);
|
|
38
|
+
case 'claude':
|
|
39
|
+
return await this.chatWithClaude(message, history);
|
|
40
|
+
default:
|
|
41
|
+
throw new Error('No AI provider configured. Run "awd init"');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new Error(`AI Chat Failed: ${error.response?.data?.error?.message || error.message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
buildReviewPrompt(code, filePath, context) {
|
|
49
|
+
return `
|
|
50
|
+
You are "codereviewer.ai", an expert senior developer.
|
|
51
|
+
Review the following code for file: ${filePath}
|
|
52
|
+
|
|
53
|
+
CRITERIA:
|
|
54
|
+
1. Identify bugs or security flaws.
|
|
55
|
+
2. Suggest performance optimizations.
|
|
56
|
+
3. Check for best practices and readability.
|
|
57
|
+
|
|
58
|
+
CONTEXT FROM PREVIOUS CHATS:
|
|
59
|
+
${JSON.stringify(context || "None")}
|
|
60
|
+
|
|
61
|
+
CODE TO REVIEW:
|
|
62
|
+
\`\`\`
|
|
63
|
+
${code}
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
RESPONSE FORMAT:
|
|
67
|
+
You MUST respond ONLY with a valid JSON object. Do not include markdown formatting or prose.
|
|
68
|
+
{
|
|
69
|
+
"summary": "Brief overall thought",
|
|
70
|
+
"score": 1-10,
|
|
71
|
+
"issues": [{"line": number, "type": "bug|style|security", "msg": "description", "fix": "suggested code"}],
|
|
72
|
+
"optimizations": ["list of tips"]
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
async reviewWithGemini(prompt) {
|
|
77
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${this.config.apiKey}`;
|
|
78
|
+
const response = await axios.post(url, {
|
|
79
|
+
contents: [{ parts: [{ text: prompt }] }]
|
|
80
|
+
});
|
|
81
|
+
const text = response.data.candidates[0].content.parts[0].text;
|
|
82
|
+
return JSON.parse(this.cleanJSON(text));
|
|
83
|
+
}
|
|
84
|
+
async reviewWithOpenAI(prompt) {
|
|
85
|
+
const response = await axios.post('https://api.openai.com/v1/chat/completions', {
|
|
86
|
+
model: 'gpt-4-turbo-preview',
|
|
87
|
+
messages: [{ role: 'user', content: prompt }],
|
|
88
|
+
response_format: { type: "json_object" }
|
|
89
|
+
}, {
|
|
90
|
+
headers: { Authorization: `Bearer ${this.config.apiKey}` }
|
|
91
|
+
});
|
|
92
|
+
return JSON.parse(response.data.choices[0].message.content);
|
|
93
|
+
}
|
|
94
|
+
async reviewWithClaude(prompt) {
|
|
95
|
+
// Logic for Claude API (Anthropic)
|
|
96
|
+
const response = await axios.post('https://api.anthropic.com/v1/messages', {
|
|
97
|
+
model: 'claude-3-sonnet-20240229',
|
|
98
|
+
max_tokens: 1024,
|
|
99
|
+
messages: [{ role: 'user', content: prompt }]
|
|
100
|
+
}, {
|
|
101
|
+
headers: {
|
|
102
|
+
'x-api-key': this.config.apiKey,
|
|
103
|
+
'anthropic-version': '2023-06-01'
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return JSON.parse(this.cleanJSON(response.data.content[0].text));
|
|
107
|
+
}
|
|
108
|
+
async chatWithGemini(message, history) {
|
|
109
|
+
const prompt = this.buildChatPrompt(message, history);
|
|
110
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${this.config.apiKey}`;
|
|
111
|
+
const response = await axios.post(url, {
|
|
112
|
+
contents: [{ parts: [{ text: prompt }] }]
|
|
113
|
+
});
|
|
114
|
+
return response.data.candidates[0].content.parts[0].text;
|
|
115
|
+
}
|
|
116
|
+
async chatWithOpenAI(message, history) {
|
|
117
|
+
const messages = history.map(h => ({ role: h.role, content: h.content }));
|
|
118
|
+
messages.push({ role: 'user', content: message });
|
|
119
|
+
const response = await axios.post('https://api.openai.com/v1/chat/completions', {
|
|
120
|
+
model: 'gpt-4-turbo-preview',
|
|
121
|
+
messages: messages
|
|
122
|
+
}, {
|
|
123
|
+
headers: { Authorization: `Bearer ${this.config.apiKey}` }
|
|
124
|
+
});
|
|
125
|
+
return response.data.choices[0].message.content;
|
|
126
|
+
}
|
|
127
|
+
async chatWithClaude(message, history) {
|
|
128
|
+
const messages = history.map(h => ({ role: h.role, content: h.content }));
|
|
129
|
+
messages.push({ role: 'user', content: message });
|
|
130
|
+
const response = await axios.post('https://api.anthropic.com/v1/messages', {
|
|
131
|
+
model: 'claude-3-sonnet-20240229',
|
|
132
|
+
max_tokens: 1024,
|
|
133
|
+
messages: messages
|
|
134
|
+
}, {
|
|
135
|
+
headers: {
|
|
136
|
+
'x-api-key': this.config.apiKey,
|
|
137
|
+
'anthropic-version': '2023-06-01'
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
return response.data.content[0].text;
|
|
141
|
+
}
|
|
142
|
+
buildChatPrompt(message, history) {
|
|
143
|
+
let prompt = "You are codereviewer.ai, an expert developer assistant. Help with code-related questions.\n\n";
|
|
144
|
+
for (const msg of history) {
|
|
145
|
+
prompt += `${msg.role}: ${msg.content}\n`;
|
|
146
|
+
}
|
|
147
|
+
prompt += `user: ${message}\nassistant:`;
|
|
148
|
+
return prompt;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Removes Markdown code blocks if the AI accidentally includes them
|
|
152
|
+
*/
|
|
153
|
+
cleanJSON(text) {
|
|
154
|
+
return text.replace(/```json|```/g, "").trim();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/ai/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import Conf from 'conf';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
export class ConfigManager {
|
|
6
|
+
// We cast the Conf instance to allow better flexibility with the 'conf' library versions
|
|
7
|
+
config;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.config = new Conf({
|
|
10
|
+
projectName: 'codereviewerai',
|
|
11
|
+
// Default settings if the user hasn't run 'init'
|
|
12
|
+
defaults: {
|
|
13
|
+
provider: 'gemini',
|
|
14
|
+
apiKey: '',
|
|
15
|
+
model: 'gemini-1.5-pro',
|
|
16
|
+
reviewDepth: 'deep',
|
|
17
|
+
mode: 'manual',
|
|
18
|
+
includeContext: true,
|
|
19
|
+
maxContextMessages: 10
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
isConfigured() {
|
|
24
|
+
const key = this.config.get('apiKey');
|
|
25
|
+
return typeof key === 'string' && key.length > 0;
|
|
26
|
+
}
|
|
27
|
+
// Fixed: Explicitly return AppConfig to ensure UI elements can read keys safely
|
|
28
|
+
getConfig() {
|
|
29
|
+
return this.config.store;
|
|
30
|
+
}
|
|
31
|
+
// Fixed: Standardized update method
|
|
32
|
+
setKey(key, value) {
|
|
33
|
+
this.config.set(key, value);
|
|
34
|
+
}
|
|
35
|
+
// Helper for saving multiple answers from Inquirer at once
|
|
36
|
+
setFullConfig(answers) {
|
|
37
|
+
for (const [key, value] of Object.entries(answers)) {
|
|
38
|
+
this.config.set(key, value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
displayConfig() {
|
|
42
|
+
const store = this.getConfig();
|
|
43
|
+
console.log(chalk.cyan.bold('\n🛠️ Current Configuration:'));
|
|
44
|
+
console.log(`
|
|
45
|
+
${chalk.yellow('Provider:')} ${store.provider}
|
|
46
|
+
${chalk.yellow('Model:')} ${store.model}
|
|
47
|
+
${chalk.yellow('Mode:')} ${store.mode}
|
|
48
|
+
${chalk.yellow('Depth:')} ${store.reviewDepth}
|
|
49
|
+
${chalk.yellow('API Key:')} ${store.apiKey ? '********' + store.apiKey.slice(-4) : chalk.red('Not Set')}
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* LOCAL PROJECT LOGIC
|
|
54
|
+
* This creates the .awesomediagns folder in the CURRENT working directory
|
|
55
|
+
*/
|
|
56
|
+
initProject(projectPath) {
|
|
57
|
+
this.setKey('projectPath', projectPath);
|
|
58
|
+
const localDir = path.join(projectPath, '.awesomediagns');
|
|
59
|
+
const historyDir = path.join(localDir, 'history');
|
|
60
|
+
if (!fs.existsSync(localDir)) {
|
|
61
|
+
fs.mkdirSync(localDir, { recursive: true });
|
|
62
|
+
fs.mkdirSync(historyDir, { recursive: true });
|
|
63
|
+
// Auto-ignore the local metadata from Git
|
|
64
|
+
const gitignore = path.join(projectPath, '.gitignore');
|
|
65
|
+
const ignoreEntry = '\n# AwesomeDiagns metadata\n.awesomediagns/\n';
|
|
66
|
+
if (fs.existsSync(gitignore)) {
|
|
67
|
+
const content = fs.readFileSync(gitignore, 'utf8');
|
|
68
|
+
if (!content.includes('.awesomediagns')) {
|
|
69
|
+
fs.appendFileSync(gitignore, ignoreEntry);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
fs.writeFileSync(gitignore, ignoreEntry);
|
|
74
|
+
}
|
|
75
|
+
console.log(chalk.green('✅ Project initialized with local context folder.'));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Check if the current folder is an AWD project
|
|
79
|
+
isProjectInitialized(currentPath = process.cwd()) {
|
|
80
|
+
return fs.existsSync(path.join(currentPath, '.awesomediagns'));
|
|
81
|
+
}
|
|
82
|
+
// Useful for a fallback to find files if needed
|
|
83
|
+
getProjectConfig() {
|
|
84
|
+
return {
|
|
85
|
+
watchedFiles: ['*.ts', '*.js', '*.jsx', '*.tsx', '*.py', '*.go'],
|
|
86
|
+
ignoredPatterns: ['node_modules', 'dist', '.git']
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
clearConfig() {
|
|
90
|
+
this.config.clear();
|
|
91
|
+
console.log(chalk.red('🗑️ Global configuration wiped.'));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"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"}
|