error-solution-ai-buddy 0.0.0-stage → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sithija Harshana Jayasinghe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,292 @@
1
- # Temporary Holding Version
1
+ # Error → Solution AI Buddy 🤖
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > AI-powered error explanations directly in your terminal. No context switching!
4
+
5
+ ![Node.js](https://img.shields.io/badge/Node.js-18+-green)
6
+ ![Ollama](https://img.shields.io/badge/AI-Ollama-blue)
7
+ ![License](https://img.shields.io/badge/License-MIT-yellow)
8
+
9
+ ## The Problem
10
+
11
+ You're coding. An error appears. You:
12
+ 1. Copy the error
13
+ 2. Open browser
14
+ 3. Paste into Google/ChatGPT
15
+ 4. Read through results
16
+ 5. Go back to terminal
17
+ 6. Forget what you were doing
18
+
19
+ **That's 5+ context switches. We fix that.**
20
+
21
+ ## The Solution
22
+
23
+ ```bash
24
+ $ errbuddy node app.js
25
+
26
+ TypeError: Cannot read properties of undefined (reading 'map')
27
+ at app.js:12:5
28
+
29
+ ╭─ 🤖 Error Buddy Explanation: ─────────────────────────────────────╮
30
+ │ │
31
+ │ 📘 What is this? │
32
+ │ You tried to use `.map()` on a variable that is undefined. │
33
+ │ │
34
+ │ ❓ Why it happens? │
35
+ │ The data you expected (probably from an API) wasn't available. │
36
+ │ │
37
+ │ ✅ How to fix it: │
38
+ │ Check if the variable exists before calling `.map()`. │
39
+ │ │
40
+ │ 💡 Example: │
41
+ │ if (data) { │
42
+ │ data.map(...) │
43
+ │ } │
44
+ │ │
45
+ ╰────────────────────────────────────────────────────────────────────╯
46
+ ```
47
+
48
+ ## Quick Start
49
+
50
+ ```bash
51
+ npm install -g error-solution-ai-buddy
52
+ errbuddy node app.js
53
+ ```
54
+
55
+ That's it. Errors are explained with built-in pattern matching straight away.
56
+
57
+ ### Turn on AI explanations (optional, free, runs on your machine)
58
+
59
+ errbuddy uses [Ollama](https://ollama.com) to run a small AI model locally, so your code and errors never leave your computer.
60
+
61
+ 1. Install Ollama from https://ollama.com/download
62
+ 2. Download the default model (about 400 MB):
63
+ ```bash
64
+ ollama pull qwen2.5:0.5b
65
+ ```
66
+ 3. Make sure Ollama is running (`ollama serve`, or open the Ollama app)
67
+
68
+ Want better explanations? Use a bigger model: `errbuddy --model llama3.2 node app.js`
69
+
70
+ If Ollama isn't running, errbuddy still works — it falls back to pattern matching.
71
+
72
+ ## Installation & Usage
73
+
74
+ ### 1. Download the Project
75
+ - Clone the repository:
76
+ ```sh
77
+ git clone <your-repo-url>
78
+ ```
79
+
80
+ ### 2. Install Dependencies
81
+ - In the project folder, run:
82
+ ```sh
83
+ npm install
84
+ ```
85
+
86
+ ### 3. Use the CLI Tool
87
+ - Go to the CLI directory:
88
+ ```sh
89
+ cd error-solution-ai-buddy/cli
90
+ npm link
91
+ ```
92
+ - Now you can run the CLI from anywhere:
93
+ ```sh
94
+ errbuddy <your-command>
95
+ # Example:
96
+ errbuddy node test-error.js
97
+ ```
98
+
99
+ ### 4. Use the VS Code Extension
100
+ - Build the extension (if needed):
101
+ ```sh
102
+ cd error-solution-ai-buddy/extension
103
+ npm install
104
+ npm run build
105
+ ```
106
+ - Install the extension in VS Code:
107
+ - Use "Install from VSIX..." if you have a packaged file.
108
+ - Or run:
109
+ ```sh
110
+ code --install-extension <path-to-extension-folder>
111
+ ```
112
+ - Reload VS Code.
113
+
114
+ ### 5. Start Using
115
+ - For CLI: Run commands with `errbuddy` prefix.
116
+ - For extension: Use terminal and Error Buddy commands in VS Code.
117
+ ### Manual Setup
118
+
119
+ #### Step 1: Install Ollama (Optional - for AI features)
120
+
121
+ ```bash
122
+ # Windows: Download from https://ollama.ai
123
+
124
+ # macOS
125
+ brew install ollama
126
+
127
+ # Linux
128
+ curl -fsSL https://ollama.ai/install.sh | sh
129
+ ```
130
+
131
+ ### 2. Start Ollama & Download Model
132
+
133
+ ```bash
134
+ ollama serve # Start the server (keep this running)
135
+ ollama pull llama3.2 # Download the model (~2GB)
136
+ ```
137
+ ### 3. Install Error Buddy
138
+
139
+ ```bash
140
+ # From this directory
141
+ npm install
142
+ npm link # Makes 'errbuddy' available globally
143
+ ```
144
+
145
+ ### 4. Use It!
146
+
147
+ ```bash
148
+ # Instead of: node app.js
149
+ errbuddy node app.js
150
+
151
+ # Instead of: npm start
152
+ errbuddy npm start
153
+
154
+ # Instead of: java MyApp
155
+ errbuddy java MyApp
156
+
157
+ # Instead of: dotnet run
158
+ errbuddy dotnet run
159
+ ```
160
+
161
+ ## Supported Languages
162
+
163
+ | Language | Status | Error Types |
164
+ |----------|--------|-------------|
165
+ | JavaScript/Node.js | ✅ Full | TypeError, ReferenceError, SyntaxError, Module errors |
166
+ | Java | ✅ Full | NullPointer, ArrayIndex, ClassNotFound, Compile errors |
167
+ | C#/.NET | ✅ Full | NullReference, Index, CS errors, Runtime exceptions |
168
+
169
+ ## CLI Options
170
+
171
+ ```bash
172
+ # Disable AI (use pattern matching only)
173
+ errbuddy --no-ai node app.js
174
+
175
+ # Use a different Ollama model
176
+ errbuddy --model codellama node app.js
177
+
178
+ # Force offline mode
179
+ errbuddy --offline node app.js
180
+
181
+ # Show examples
182
+ errbuddy examples
183
+
184
+ # Show configuration
185
+ errbuddy config
186
+ ```
187
+
188
+ ## How It Works
189
+
190
+ ```
191
+ ┌─────────────────────────────────────────┐
192
+ │ You run: errbuddy node app.js │
193
+ └─────────────────────────────────────────┘
194
+ ↓
195
+ ┌─────────────────────────────────────────┐
196
+ │ CLI spawns: node app.js │
197
+ │ • stdout → displayed normally │
198
+ │ • stderr → captured for analysis │
199
+ └─────────────────────────────────────────┘
200
+ ↓
201
+ ┌─────────────────────────────────────────┐
202
+ │ Error Detector │
203
+ │ • Detects language (JS/Java/C#) │
204
+ │ • Extracts error type, file, line │
205
+ └─────────────────────────────────────────┘
206
+ ↓
207
+ ┌─────────────────────────────────────────┐
208
+ │ Ollama AI (local) │
209
+ │ • Receives sanitized error │
210
+ │ • Returns structured explanation │
211
+ └─────────────────────────────────────────┘
212
+ ↓
213
+ ┌─────────────────────────────────────────┐
214
+ │ Pretty Terminal Output │
215
+ │ • WHAT / WHY / FIX / EXAMPLE │
216
+ └─────────────────────────────────────────┘
217
+ ```
218
+
219
+ ## Privacy & Security
220
+
221
+ Your code **never leaves your machine**:
222
+
223
+ - ✅ Ollama runs 100% locally
224
+ - ✅ File paths are stripped before AI processing
225
+ - ✅ No telemetry or analytics
226
+ - ✅ No API keys required
227
+ - ✅ Works completely offline
228
+
229
+ ## Project Structure
230
+
231
+ ```
232
+ error-solution-ai-buddy/
233
+ ├── cli/
234
+ │ ├── index.js # CLI entry point
235
+ │ ├── error-listener.js # Error detection & patterns
236
+ │ └── formatter.js # Terminal output formatting
237
+ ├── backend/
238
+ │ └── src/
239
+ │ ├── ai/
240
+ │ │ └── ollama-service.js # Ollama integration
241
+ │ └── services/
242
+ │ └── history-service.js # Error history (SQLite)
243
+ ├── docs/
244
+ │ ├── architecture.md # System design
245
+ │ ├── decisions.md # Why we made these choices
246
+ │ └── terminal-integration.md
247
+ ├── tests/
248
+ │ └── *.test.js
249
+ ├── package.json
250
+ └── README.md
251
+ ```
252
+
253
+ ## Configuration
254
+
255
+ Configuration is stored in `~/.errbuddy/config.json`:
256
+
257
+ ```json
258
+ {
259
+ "ollamaUrl": "http://localhost:11434",
260
+ "model": "llama3.2",
261
+ "showSpinner": true,
262
+ "saveHistory": true
263
+ }
264
+ ```
265
+
266
+ ## Troubleshooting
267
+
268
+ ### "Ollama not detected"
269
+
270
+ 1. Make sure Ollama is running: `ollama serve`
271
+ 2. Check it's accessible: `curl http://localhost:11434/api/tags`
272
+ 3. Pull a model: `ollama pull qwen2.5:0.5b`
273
+
274
+ ### "AI explanation timed out"
275
+
276
+ - Try a smaller model: `errbuddy --model llama3.2:1b node app.js`
277
+ - Check system resources (Ollama needs ~4GB RAM)
278
+
279
+ ### Command not found after `npm link`
280
+
281
+ - On Windows: Restart your terminal
282
+ - On macOS/Linux: Check your PATH includes npm global bin
283
+
284
+ ## Contributing
285
+
286
+ 1. Fork the repo
287
+ 2. Create a feature branch
288
+ 3. Submit a PR
289
+
290
+ ## License
291
+
292
+ MIT © 2024
@@ -0,0 +1,264 @@
1
+ /**
2
+ * Ollama AI Service - Handles communication with local Ollama server
3
+ *
4
+ * WHY OLLAMA:
5
+ * 1. 100% free - no API keys needed
6
+ * 2. Runs locally - your code never leaves your machine
7
+ * 3. Works offline - no internet required after model download
8
+ * 4. Fast - local inference with no network latency
9
+ *
10
+ * SETUP:
11
+ * 1. Install Ollama: https://ollama.ai
12
+ * 2. Run: ollama pull llama3.2
13
+ * 3. Run: ollama serve
14
+ */
15
+
16
+ /**
17
+ * System prompt for error explanation
18
+ *
19
+ * WHY this structure:
20
+ * - Forces consistent output format
21
+ * - Beginner-friendly language
22
+ * - Prevents hallucinations with explicit rules
23
+ */
24
+ const SYSTEM_PROMPT = `You are an expert programming assistant that explains errors to developers.
25
+
26
+ RULES (VERY IMPORTANT):
27
+ 1. Always respond in this EXACT format:
28
+ WHAT: [Name the specific error code/exception (e.g. "NullPointerException", "CS1061") and what it means]
29
+ WHY: [Explain specifically why this code causes that error]
30
+ FIX: [Clear steps to fix the error]
31
+ EXAMPLE: [Short code example if helpful]
32
+
33
+ 2. Use simple language a junior developer can understand
34
+ 3. Be concise - no long paragraphs
35
+ 4. Do NOT assume frameworks (like Spring, React) unless the error explicitly mentions them
36
+ 5. Focus on the most likely cause first (typos, missing variables, syntax)
37
+ 6. IF suggesting a fix involves installing a new package, ONLY do so if the error is explicitly "Module/Package not found".
38
+ 7. If the error mentions "not a statement" and looks like "variable;", explain that standalone variables are not valid statements.
39
+ 8. Never make up information - if unsure, say so
40
+ 9. Always explicitly mention the error name or code in the "WHAT" section.
41
+
42
+ LANGUAGE-SPECIFIC TIPS:
43
+ - JavaScript: Common issues are undefined/null, async/await, imports
44
+ - Java:
45
+ - "not a statement" often means a standalone variable (e.g. 'x;') which is invalid in Java. It must be an assignment ('x=1;') or method call.
46
+ - Common issues: NullPointer, missing variables, types
47
+ - Avoid suggesting @Autowired unless it's a Spring error
48
+ - C#: Common issues are null reference, missing using, async
49
+
50
+ Remember: Developers are frustrated when they see errors. Be helpful and direct.`;
51
+
52
+ export class AIService {
53
+ constructor(baseUrl = 'http://localhost:11434', model = 'llama3.2') {
54
+ this.baseUrl = baseUrl;
55
+ this.model = model;
56
+ this.timeout = 30000; // 30 second timeout
57
+ }
58
+
59
+ /**
60
+ * Check if Ollama is running and accessible
61
+ */
62
+ async checkConnection() {
63
+ try {
64
+ const controller = new AbortController();
65
+ const timeoutId = setTimeout(() => controller.abort(), 3000);
66
+
67
+ const response = await fetch(`${this.baseUrl}/api/tags`, {
68
+ method: 'GET',
69
+ signal: controller.signal, // 3 second timeout for health check
70
+ }).finally(() => clearTimeout(timeoutId));
71
+
72
+ if (!response.ok) {
73
+ return false;
74
+ }
75
+
76
+ const data = await response.json();
77
+
78
+ // Check if the model we want is available
79
+ const models = data.models || [];
80
+ const modelBaseName = this.model.split(':')[0];
81
+ const hasModel = models.some(m => m.name.startsWith(modelBaseName));
82
+
83
+ if (!hasModel && models.length > 0) {
84
+ // Use first available model as fallback
85
+ this.model = models[0].name;
86
+ }
87
+
88
+ return true;
89
+ } catch (error) {
90
+ return false;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Get explanation for an error from Ollama
96
+ */
97
+ async explainError(errorText, language = 'unknown') {
98
+ const prompt = this.buildPrompt(errorText, language);
99
+
100
+ const controller = new AbortController();
101
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
102
+
103
+ try {
104
+ const response = await fetch(`${this.baseUrl}/api/generate`, {
105
+ method: 'POST',
106
+ headers: {
107
+ 'Content-Type': 'application/json',
108
+ },
109
+ body: JSON.stringify({
110
+ model: this.model,
111
+ prompt: prompt,
112
+ system: SYSTEM_PROMPT,
113
+ stream: false,
114
+ options: {
115
+ temperature: 0.1, // Very low to prevent hallucinations
116
+ top_p: 0.9,
117
+ num_predict: 500, // Limit response length
118
+ }
119
+ }),
120
+ signal: controller.signal,
121
+ }).finally(() => clearTimeout(timeoutId));
122
+
123
+ if (!response.ok) {
124
+ let errorMsg = '';
125
+ try {
126
+ const errorJson = await response.json();
127
+ errorMsg = errorJson.error || JSON.stringify(errorJson);
128
+ } catch {
129
+ errorMsg = await response.text();
130
+ }
131
+
132
+ // Check for memory error
133
+ if (errorMsg.includes('memory')) {
134
+ throw new Error('Not enough RAM. Try: errbuddy --model qwen2.5:0.5b');
135
+ }
136
+ throw new Error(`Ollama returned ${response.status}: ${errorMsg}`);
137
+ }
138
+
139
+ const data = await response.json();
140
+
141
+ // Check for error in response
142
+ if (data.error) {
143
+ throw new Error(data.error);
144
+ }
145
+
146
+ return this.parseResponse(data.response);
147
+ } catch (error) {
148
+ if (error.name === 'TimeoutError' || error.name === 'AbortError') {
149
+ throw new Error('AI explanation timed out. Try a smaller model.');
150
+ }
151
+ throw error;
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Build the prompt for the AI
157
+ */
158
+ buildPrompt(errorText, language) {
159
+ const langName = {
160
+ javascript: 'JavaScript/Node.js',
161
+ java: 'Java',
162
+ csharp: 'C#/.NET',
163
+ unknown: 'programming'
164
+ }[language] || language;
165
+
166
+ return `Explain this ${langName} error to a developer:
167
+
168
+ \`\`\`
169
+ ${errorText}
170
+ \`\`\`
171
+
172
+ Remember to use the format: WHAT, WHY, FIX, EXAMPLE`;
173
+ }
174
+
175
+ /**
176
+ * Parse the AI response into structured format
177
+ */
178
+ parseResponse(response) {
179
+ const result = {
180
+ what: null,
181
+ why: null,
182
+ fix: null,
183
+ example: null,
184
+ raw: response
185
+ };
186
+
187
+ // Try to extract structured parts
188
+ const whatMatch = response.match(/WHAT:\s*(.+?)(?=WHY:|FIX:|EXAMPLE:|$)/is);
189
+ const whyMatch = response.match(/WHY:\s*(.+?)(?=WHAT:|FIX:|EXAMPLE:|$)/is);
190
+ const fixMatch = response.match(/FIX:\s*(.+?)(?=WHAT:|WHY:|EXAMPLE:|$)/is);
191
+ const exampleMatch = response.match(/EXAMPLE:\s*(.+?)(?=WHAT:|WHY:|FIX:|$)/is);
192
+
193
+ if (whatMatch) result.what = whatMatch[1].trim();
194
+ if (whyMatch) result.why = whyMatch[1].trim();
195
+ if (fixMatch) result.fix = fixMatch[1].trim();
196
+ if (exampleMatch) result.example = exampleMatch[1].trim();
197
+
198
+ // If structured parsing failed, try to make sense of the response
199
+ if (!result.what && !result.why && !result.fix) {
200
+ // Split by sentences and assign
201
+ const sentences = response.split(/[.!]\s+/).filter(s => s.trim());
202
+ if (sentences.length >= 1) result.what = sentences[0].trim() + '.';
203
+ if (sentences.length >= 2) result.why = sentences[1].trim() + '.';
204
+ if (sentences.length >= 3) result.fix = sentences.slice(2).join('. ').trim();
205
+ }
206
+
207
+ // Extract code blocks for example
208
+ if (!result.example) {
209
+ const codeMatch = response.match(/```[\w]*\n?([\s\S]+?)```/);
210
+ if (codeMatch) {
211
+ result.example = codeMatch[1].trim();
212
+ }
213
+ }
214
+
215
+ return result;
216
+ }
217
+
218
+ /**
219
+ * Stream explanation (for future use - better UX for long responses)
220
+ * Currently not used but ready for implementation
221
+ */
222
+ async *streamExplanation(errorText, language = 'unknown') {
223
+ const prompt = this.buildPrompt(errorText, language);
224
+
225
+ const response = await fetch(`${this.baseUrl}/api/generate`, {
226
+ method: 'POST',
227
+ headers: {
228
+ 'Content-Type': 'application/json',
229
+ },
230
+ body: JSON.stringify({
231
+ model: this.model,
232
+ prompt: prompt,
233
+ system: SYSTEM_PROMPT,
234
+ stream: true,
235
+ options: {
236
+ temperature: 0.3,
237
+ num_predict: 500,
238
+ }
239
+ }),
240
+ });
241
+
242
+ const reader = response.body.getReader();
243
+ const decoder = new TextDecoder();
244
+
245
+ while (true) {
246
+ const { done, value } = await reader.read();
247
+ if (done) break;
248
+
249
+ const chunk = decoder.decode(value);
250
+ const lines = chunk.split('\n').filter(line => line.trim());
251
+
252
+ for (const line of lines) {
253
+ try {
254
+ const data = JSON.parse(line);
255
+ if (data.response) {
256
+ yield data.response;
257
+ }
258
+ } catch {
259
+ // Ignore JSON parse errors for incomplete chunks
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }