@nclamvn/vibecode-cli 2.0.0 → 2.1.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.
Files changed (51) hide show
  1. package/.vibecode/learning/fixes.json +1 -0
  2. package/.vibecode/learning/preferences.json +1 -0
  3. package/README.md +310 -49
  4. package/SESSION_NOTES.md +154 -0
  5. package/bin/vibecode.js +212 -2
  6. package/package.json +5 -2
  7. package/src/agent/decomposition.js +476 -0
  8. package/src/agent/index.js +391 -0
  9. package/src/agent/memory.js +542 -0
  10. package/src/agent/orchestrator.js +917 -0
  11. package/src/agent/self-healing.js +516 -0
  12. package/src/commands/agent.js +349 -0
  13. package/src/commands/ask.js +230 -0
  14. package/src/commands/assist.js +413 -0
  15. package/src/commands/build.js +345 -4
  16. package/src/commands/debug.js +565 -0
  17. package/src/commands/docs.js +167 -0
  18. package/src/commands/git.js +1024 -0
  19. package/src/commands/go.js +387 -0
  20. package/src/commands/learn.js +294 -0
  21. package/src/commands/migrate.js +341 -0
  22. package/src/commands/plan.js +8 -2
  23. package/src/commands/refactor.js +205 -0
  24. package/src/commands/review.js +126 -1
  25. package/src/commands/security.js +229 -0
  26. package/src/commands/shell.js +486 -0
  27. package/src/commands/test.js +194 -0
  28. package/src/commands/undo.js +281 -0
  29. package/src/commands/watch.js +556 -0
  30. package/src/commands/wizard.js +322 -0
  31. package/src/config/constants.js +5 -1
  32. package/src/config/templates.js +146 -15
  33. package/src/core/backup.js +325 -0
  34. package/src/core/error-analyzer.js +237 -0
  35. package/src/core/fix-generator.js +195 -0
  36. package/src/core/iteration.js +226 -0
  37. package/src/core/learning.js +295 -0
  38. package/src/core/session.js +18 -2
  39. package/src/core/test-runner.js +281 -0
  40. package/src/debug/analyzer.js +329 -0
  41. package/src/debug/evidence.js +228 -0
  42. package/src/debug/fixer.js +348 -0
  43. package/src/debug/image-analyzer.js +304 -0
  44. package/src/debug/index.js +378 -0
  45. package/src/debug/verifier.js +346 -0
  46. package/src/index.js +89 -0
  47. package/src/providers/claude-code.js +12 -7
  48. package/src/ui/__tests__/error-translator.test.js +390 -0
  49. package/src/ui/dashboard.js +364 -0
  50. package/src/ui/error-translator.js +775 -0
  51. package/src/utils/image.js +222 -0
@@ -0,0 +1,390 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // VIBECODE CLI - Error Translator Test Suite
3
+ // Comprehensive tests for pattern matching
4
+ // ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ import { translateError, getErrorCategory } from '../error-translator.js';
7
+
8
+ /**
9
+ * Test cases for error translation
10
+ * Each test case has:
11
+ * - input: The error string to translate
12
+ * - expectedTitle: Expected Vietnamese title (partial match)
13
+ * - expectedCategory: Expected category
14
+ */
15
+ const TEST_CASES = [
16
+ // ─────────────────────────────────────────────────────────────────────────────
17
+ // TypeError - undefined property (CRITICAL: Must handle both quote types)
18
+ // ─────────────────────────────────────────────────────────────────────────────
19
+ {
20
+ input: 'TypeError: Cannot read properties of undefined (reading "call")',
21
+ expectedTitle: 'Biến chưa được định nghĩa',
22
+ expectedCategory: 'RUNTIME'
23
+ },
24
+ {
25
+ input: "TypeError: Cannot read properties of undefined (reading 'map')",
26
+ expectedTitle: 'Biến chưa được định nghĩa',
27
+ expectedCategory: 'RUNTIME'
28
+ },
29
+ {
30
+ input: 'Cannot read property "foo" of undefined',
31
+ expectedTitle: 'Biến chưa được định nghĩa',
32
+ expectedCategory: 'RUNTIME'
33
+ },
34
+ {
35
+ input: 'Cannot read properties of null (reading "bar")',
36
+ expectedTitle: 'Biến là null',
37
+ expectedCategory: 'RUNTIME'
38
+ },
39
+
40
+ // ─────────────────────────────────────────────────────────────────────────────
41
+ // Module not found
42
+ // ─────────────────────────────────────────────────────────────────────────────
43
+ {
44
+ input: "Cannot find module 'react'",
45
+ expectedTitle: 'Không tìm thấy module',
46
+ expectedCategory: 'MODULE'
47
+ },
48
+ {
49
+ input: 'Error: Cannot find module "@/components/Button"',
50
+ expectedTitle: 'Không tìm thấy module',
51
+ expectedCategory: 'MODULE'
52
+ },
53
+ {
54
+ input: "Module not found: Can't resolve 'lodash'",
55
+ expectedTitle: 'Module không tìm thấy khi build',
56
+ expectedCategory: 'BUILD'
57
+ },
58
+
59
+ // ─────────────────────────────────────────────────────────────────────────────
60
+ // Syntax errors
61
+ // ─────────────────────────────────────────────────────────────────────────────
62
+ {
63
+ input: 'SyntaxError: Unexpected token }',
64
+ expectedTitle: 'Lỗi cú pháp',
65
+ expectedCategory: 'SYNTAX'
66
+ },
67
+ {
68
+ input: 'SyntaxError: Unexpected end of input',
69
+ expectedTitle: 'Lỗi cú pháp - Thiếu đóng ngoặc',
70
+ expectedCategory: 'SYNTAX'
71
+ },
72
+
73
+ // ─────────────────────────────────────────────────────────────────────────────
74
+ // Reference errors
75
+ // ─────────────────────────────────────────────────────────────────────────────
76
+ {
77
+ input: 'ReferenceError: foo is not defined',
78
+ expectedTitle: 'Biến chưa được khai báo',
79
+ expectedCategory: 'REFERENCE'
80
+ },
81
+
82
+ // ─────────────────────────────────────────────────────────────────────────────
83
+ // Type errors - function
84
+ // ─────────────────────────────────────────────────────────────────────────────
85
+ {
86
+ input: 'TypeError: callback is not a function',
87
+ expectedTitle: 'Không phải hàm',
88
+ expectedCategory: 'TYPE'
89
+ },
90
+ {
91
+ input: 'TypeError: arr is not iterable',
92
+ expectedTitle: 'Không thể lặp qua dữ liệu',
93
+ expectedCategory: 'TYPE'
94
+ },
95
+
96
+ // ─────────────────────────────────────────────────────────────────────────────
97
+ // File system errors
98
+ // ─────────────────────────────────────────────────────────────────────────────
99
+ {
100
+ input: "ENOENT: no such file or directory, open '/path/to/file.js'",
101
+ expectedTitle: 'File không tồn tại',
102
+ expectedCategory: 'FILE'
103
+ },
104
+ {
105
+ input: 'ENOENT: no such file or directory /path/to/file.js',
106
+ expectedTitle: 'File không tồn tại',
107
+ expectedCategory: 'FILE'
108
+ },
109
+ {
110
+ input: 'Error: ENOENT',
111
+ expectedTitle: 'File không tồn tại',
112
+ expectedCategory: 'FILE'
113
+ },
114
+ {
115
+ input: 'EACCES: permission denied',
116
+ expectedTitle: 'Không có quyền truy cập',
117
+ expectedCategory: 'PERMISSION'
118
+ },
119
+
120
+ // ─────────────────────────────────────────────────────────────────────────────
121
+ // Network errors
122
+ // ─────────────────────────────────────────────────────────────────────────────
123
+ {
124
+ input: 'EADDRINUSE: address already in use :::3000',
125
+ expectedTitle: 'Port đang được sử dụng',
126
+ expectedCategory: 'NETWORK'
127
+ },
128
+ {
129
+ input: 'ECONNREFUSED 127.0.0.1:3000',
130
+ expectedTitle: 'Không thể kết nối',
131
+ expectedCategory: 'NETWORK'
132
+ },
133
+
134
+ // ─────────────────────────────────────────────────────────────────────────────
135
+ // NPM errors
136
+ // ─────────────────────────────────────────────────────────────────────────────
137
+ {
138
+ input: 'npm ERR! code ERESOLVE',
139
+ expectedTitle: 'Xung đột phiên bản dependency',
140
+ expectedCategory: 'NPM'
141
+ },
142
+ {
143
+ input: 'npm ERR! ERESOLVE could not resolve',
144
+ expectedTitle: 'Xung đột phiên bản dependency',
145
+ expectedCategory: 'NPM'
146
+ },
147
+ {
148
+ input: 'npm ERR! code E404',
149
+ expectedTitle: 'Lỗi npm registry',
150
+ expectedCategory: 'NPM'
151
+ },
152
+ {
153
+ input: 'npm ERR! peer dependency missing',
154
+ expectedTitle: 'Thiếu peer dependency',
155
+ expectedCategory: 'NPM'
156
+ },
157
+
158
+ // ─────────────────────────────────────────────────────────────────────────────
159
+ // Next.js / React errors
160
+ // ─────────────────────────────────────────────────────────────────────────────
161
+ {
162
+ input: 'Functions cannot be passed directly to Client Components',
163
+ expectedTitle: 'Lỗi Server/Client Component (Next.js)',
164
+ expectedCategory: 'NEXTJS'
165
+ },
166
+ {
167
+ input: 'Hydration failed because the initial UI does not match',
168
+ expectedTitle: 'Lỗi Hydration (React/Next.js)',
169
+ expectedCategory: 'REACT'
170
+ },
171
+ {
172
+ input: 'Text content does not match server-rendered HTML',
173
+ expectedTitle: 'Lỗi Hydration (React/Next.js)',
174
+ expectedCategory: 'REACT'
175
+ },
176
+ {
177
+ input: 'Invalid hook call. Hooks can only be called inside',
178
+ expectedTitle: 'Lỗi React Hook',
179
+ expectedCategory: 'REACT'
180
+ },
181
+
182
+ // ─────────────────────────────────────────────────────────────────────────────
183
+ // TypeScript errors
184
+ // ─────────────────────────────────────────────────────────────────────────────
185
+ {
186
+ input: "error TS2339: Property 'foo' does not exist on type 'Bar'",
187
+ expectedTitle: 'Lỗi TypeScript (TS2339)',
188
+ expectedCategory: 'TYPESCRIPT'
189
+ },
190
+ {
191
+ input: "Type 'string' is not assignable to type 'number'",
192
+ expectedTitle: 'Lỗi TypeScript - Type không khớp',
193
+ expectedCategory: 'TYPESCRIPT'
194
+ },
195
+ {
196
+ input: "Property 'onClick' does not exist on type 'IntrinsicAttributes'",
197
+ expectedTitle: 'Lỗi TypeScript - Property không tồn tại',
198
+ expectedCategory: 'TYPESCRIPT'
199
+ },
200
+ {
201
+ input: "Argument of type 'string' is not assignable to parameter",
202
+ expectedTitle: 'Lỗi TypeScript - Argument không khớp',
203
+ expectedCategory: 'TYPESCRIPT'
204
+ },
205
+
206
+ // ─────────────────────────────────────────────────────────────────────────────
207
+ // Database errors
208
+ // ─────────────────────────────────────────────────────────────────────────────
209
+ {
210
+ input: 'PrismaClientKnownRequestError: P2002',
211
+ expectedTitle: 'Lỗi Prisma Database',
212
+ expectedCategory: 'DATABASE'
213
+ },
214
+ {
215
+ input: "Invalid `prisma.user.findMany()` invocation",
216
+ expectedTitle: 'Lỗi Prisma Query',
217
+ expectedCategory: 'DATABASE'
218
+ },
219
+ {
220
+ input: 'ER_ACCESS_DENIED_ERROR: Access denied for user',
221
+ expectedTitle: 'Lỗi truy cập Database',
222
+ expectedCategory: 'DATABASE'
223
+ },
224
+ {
225
+ input: 'SQLITE_ERROR: no such table: users',
226
+ expectedTitle: 'Lỗi SQLite',
227
+ expectedCategory: 'DATABASE'
228
+ },
229
+ {
230
+ input: 'ECONNREFUSED 127.0.0.1:5432',
231
+ expectedTitle: 'Database không chạy',
232
+ expectedCategory: 'DATABASE'
233
+ },
234
+
235
+ // ─────────────────────────────────────────────────────────────────────────────
236
+ // Git errors
237
+ // ─────────────────────────────────────────────────────────────────────────────
238
+ {
239
+ input: 'fatal: not a git repository',
240
+ expectedTitle: 'Không phải Git repository',
241
+ expectedCategory: 'GIT'
242
+ },
243
+ {
244
+ input: 'error: failed to push some refs',
245
+ expectedTitle: 'Không thể push lên remote',
246
+ expectedCategory: 'GIT'
247
+ },
248
+ {
249
+ input: 'CONFLICT (content): Merge conflict in src/app.js',
250
+ expectedTitle: 'Git Merge Conflict',
251
+ expectedCategory: 'GIT'
252
+ },
253
+
254
+ // ─────────────────────────────────────────────────────────────────────────────
255
+ // Build errors
256
+ // ─────────────────────────────────────────────────────────────────────────────
257
+ {
258
+ input: 'Module build failed (from ./node_modules/babel-loader)',
259
+ expectedTitle: 'Build module thất bại',
260
+ expectedCategory: 'BUILD'
261
+ },
262
+
263
+ // ─────────────────────────────────────────────────────────────────────────────
264
+ // Memory errors
265
+ // ─────────────────────────────────────────────────────────────────────────────
266
+ {
267
+ input: 'FATAL ERROR: JavaScript heap out of memory',
268
+ expectedTitle: 'Hết bộ nhớ',
269
+ expectedCategory: 'MEMORY'
270
+ },
271
+ {
272
+ input: 'RangeError: Maximum call stack size exceeded',
273
+ expectedTitle: 'Stack Overflow',
274
+ expectedCategory: 'RUNTIME'
275
+ }
276
+ ];
277
+
278
+ /**
279
+ * Run all tests
280
+ */
281
+ export function runTests(options = {}) {
282
+ const verbose = options.verbose || false;
283
+ let passed = 0;
284
+ let failed = 0;
285
+ const failures = [];
286
+
287
+ console.log('\n═══════════════════════════════════════════════════════════════');
288
+ console.log(' 🧪 ERROR TRANSLATOR TEST SUITE');
289
+ console.log('═══════════════════════════════════════════════════════════════\n');
290
+
291
+ for (const testCase of TEST_CASES) {
292
+ const result = translateError(testCase.input);
293
+ const category = getErrorCategory(testCase.input);
294
+
295
+ // Check if title matches (partial match for flexibility)
296
+ const titleMatch = result.title === testCase.expectedTitle ||
297
+ result.title.includes(testCase.expectedTitle) ||
298
+ testCase.expectedTitle.includes(result.title);
299
+ const categoryMatch = category === testCase.expectedCategory;
300
+
301
+ if (titleMatch && categoryMatch) {
302
+ passed++;
303
+ if (verbose) {
304
+ console.log(` ✅ ${testCase.input.substring(0, 50)}...`);
305
+ console.log(` → ${result.title} (${category})`);
306
+ } else {
307
+ console.log(` ✅ ${result.title}`);
308
+ }
309
+ } else {
310
+ failed++;
311
+ failures.push({
312
+ input: testCase.input,
313
+ expected: { title: testCase.expectedTitle, category: testCase.expectedCategory },
314
+ actual: { title: result.title, category }
315
+ });
316
+ console.log(` ❌ ${testCase.input.substring(0, 50)}...`);
317
+ console.log(` Expected: ${testCase.expectedTitle} (${testCase.expectedCategory})`);
318
+ console.log(` Actual: ${result.title} (${category})`);
319
+ }
320
+ }
321
+
322
+ console.log('\n───────────────────────────────────────────────────────────────');
323
+ console.log(` 📊 Results: ${passed}/${TEST_CASES.length} passed (${(passed/TEST_CASES.length*100).toFixed(1)}%)`);
324
+ console.log('───────────────────────────────────────────────────────────────\n');
325
+
326
+ if (failures.length > 0) {
327
+ console.log(' ❌ Failures Summary:');
328
+ for (const f of failures) {
329
+ console.log(` • ${f.input.substring(0, 50)}...`);
330
+ console.log(` Expected: ${f.expected.title}`);
331
+ console.log(` Got: ${f.actual.title}`);
332
+ }
333
+ console.log('');
334
+ }
335
+
336
+ // Return results
337
+ return {
338
+ passed,
339
+ failed,
340
+ total: TEST_CASES.length,
341
+ success: failed === 0,
342
+ failures
343
+ };
344
+ }
345
+
346
+ /**
347
+ * Debug a specific error pattern
348
+ */
349
+ export function debugError(errorString) {
350
+ console.log('\n═══════════════════════════════════════════════════════════════');
351
+ console.log(' 🔍 DEBUG MODE');
352
+ console.log('═══════════════════════════════════════════════════════════════\n');
353
+
354
+ const result = translateError(errorString, { debug: true });
355
+
356
+ console.log('\n───────────────────────────────────────────────────────────────');
357
+ console.log(' Result:');
358
+ console.log(` Title: ${result.title}`);
359
+ console.log(` Category: ${result.category}`);
360
+ console.log(` Description: ${result.description}`);
361
+ console.log('───────────────────────────────────────────────────────────────\n');
362
+
363
+ return result;
364
+ }
365
+
366
+ // Run if executed directly
367
+ const args = process.argv.slice(2);
368
+
369
+ if (args.includes('--debug')) {
370
+ const errorIndex = args.indexOf('--debug') + 1;
371
+ const errorString = args[errorIndex] || 'TypeError: Cannot read properties of undefined (reading "test")';
372
+ debugError(errorString);
373
+ } else if (args.includes('--help')) {
374
+ console.log(`
375
+ Usage: node error-translator.test.js [options]
376
+
377
+ Options:
378
+ --verbose Show detailed output for each test
379
+ --debug <error> Debug a specific error string
380
+ --help Show this help message
381
+
382
+ Examples:
383
+ node error-translator.test.js
384
+ node error-translator.test.js --verbose
385
+ node error-translator.test.js --debug "TypeError: foo is not a function"
386
+ `);
387
+ } else {
388
+ const result = runTests({ verbose: args.includes('--verbose') });
389
+ process.exit(result.success ? 0 : 1);
390
+ }