@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,476 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // VIBECODE AGENT - Decomposition Engine
3
+ // Breaks projects into modules with dependency analysis
4
+ // ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ /**
7
+ * Common module patterns for automatic detection
8
+ */
9
+ const MODULE_PATTERNS = {
10
+ // Core Infrastructure
11
+ core: {
12
+ keywords: ['setup', 'config', 'init', 'base', 'foundation', 'core'],
13
+ priority: 0,
14
+ dependencies: []
15
+ },
16
+
17
+ // Authentication & Authorization
18
+ auth: {
19
+ keywords: ['auth', 'login', 'signup', 'register', 'password', 'oauth', 'jwt', 'session'],
20
+ priority: 1,
21
+ dependencies: ['core']
22
+ },
23
+
24
+ // Database & Data Layer
25
+ database: {
26
+ keywords: ['database', 'db', 'schema', 'model', 'entity', 'migration', 'orm'],
27
+ priority: 1,
28
+ dependencies: ['core']
29
+ },
30
+
31
+ // API Layer
32
+ api: {
33
+ keywords: ['api', 'endpoint', 'route', 'rest', 'graphql', 'controller'],
34
+ priority: 2,
35
+ dependencies: ['core', 'database']
36
+ },
37
+
38
+ // User Management
39
+ users: {
40
+ keywords: ['user', 'profile', 'account', 'member', 'admin'],
41
+ priority: 3,
42
+ dependencies: ['auth', 'database']
43
+ },
44
+
45
+ // Dashboard & Admin
46
+ dashboard: {
47
+ keywords: ['dashboard', 'admin', 'panel', 'analytics', 'stats', 'metrics'],
48
+ priority: 4,
49
+ dependencies: ['auth', 'users']
50
+ },
51
+
52
+ // Billing & Payments
53
+ billing: {
54
+ keywords: ['billing', 'payment', 'stripe', 'subscription', 'pricing', 'checkout', 'invoice'],
55
+ priority: 4,
56
+ dependencies: ['auth', 'users']
57
+ },
58
+
59
+ // Notifications
60
+ notifications: {
61
+ keywords: ['notification', 'email', 'sms', 'push', 'alert', 'message'],
62
+ priority: 4,
63
+ dependencies: ['users']
64
+ },
65
+
66
+ // UI Components
67
+ ui: {
68
+ keywords: ['component', 'button', 'form', 'modal', 'ui', 'layout', 'navigation', 'header', 'footer'],
69
+ priority: 2,
70
+ dependencies: ['core']
71
+ },
72
+
73
+ // Pages & Views
74
+ pages: {
75
+ keywords: ['page', 'view', 'screen', 'landing', 'home', 'about', 'contact'],
76
+ priority: 5,
77
+ dependencies: ['ui']
78
+ },
79
+
80
+ // Testing
81
+ tests: {
82
+ keywords: ['test', 'spec', 'e2e', 'unit', 'integration'],
83
+ priority: 6,
84
+ dependencies: [] // Tests depend on what they test, handled dynamically
85
+ }
86
+ };
87
+
88
+ /**
89
+ * Project type templates for smart decomposition
90
+ */
91
+ const PROJECT_TEMPLATES = {
92
+ 'landing': {
93
+ modules: ['core', 'ui', 'pages'],
94
+ description: 'Simple landing page'
95
+ },
96
+ 'saas': {
97
+ modules: ['core', 'database', 'auth', 'users', 'dashboard', 'billing', 'ui', 'pages'],
98
+ description: 'Full SaaS application'
99
+ },
100
+ 'api': {
101
+ modules: ['core', 'database', 'auth', 'api', 'tests'],
102
+ description: 'REST API backend'
103
+ },
104
+ 'cli': {
105
+ modules: ['core', 'api', 'tests'],
106
+ description: 'Command-line tool'
107
+ },
108
+ 'fullstack': {
109
+ modules: ['core', 'database', 'auth', 'api', 'users', 'ui', 'pages', 'tests'],
110
+ description: 'Full-stack web application'
111
+ }
112
+ };
113
+
114
+ /**
115
+ * Decomposition Engine Class
116
+ * Analyzes project requirements and breaks them into buildable modules
117
+ */
118
+ export class DecompositionEngine {
119
+ constructor() {
120
+ this.modules = [];
121
+ this.dependencyGraph = new Map();
122
+ }
123
+
124
+ /**
125
+ * Analyze description and decompose into modules
126
+ * @param {string} description - Project description
127
+ * @param {object} options - Decomposition options
128
+ * @returns {object} Decomposition result
129
+ */
130
+ async decompose(description, options = {}) {
131
+ const lowerDesc = description.toLowerCase();
132
+
133
+ // Detect project type
134
+ const projectType = this.detectProjectType(lowerDesc);
135
+
136
+ // Get base modules from template
137
+ let detectedModules = projectType
138
+ ? [...PROJECT_TEMPLATES[projectType].modules]
139
+ : ['core'];
140
+
141
+ // Detect additional modules from description
142
+ const additionalModules = this.detectModulesFromDescription(lowerDesc);
143
+
144
+ // Merge modules (avoid duplicates)
145
+ detectedModules = [...new Set([...detectedModules, ...additionalModules])];
146
+
147
+ // Build module objects with metadata
148
+ this.modules = this.buildModuleObjects(detectedModules, description);
149
+
150
+ // Build dependency graph
151
+ this.dependencyGraph = this.buildDependencyGraph(this.modules);
152
+
153
+ // Get build order using topological sort
154
+ const buildOrder = this.topologicalSort();
155
+
156
+ return {
157
+ projectType: projectType || 'custom',
158
+ totalModules: this.modules.length,
159
+ modules: this.modules,
160
+ buildOrder,
161
+ dependencyGraph: this.serializeDependencyGraph(),
162
+ estimatedComplexity: this.estimateComplexity()
163
+ };
164
+ }
165
+
166
+ /**
167
+ * Detect project type from description
168
+ */
169
+ detectProjectType(description) {
170
+ const typeKeywords = {
171
+ landing: ['landing', 'landing page', 'one page', 'single page', 'portfolio'],
172
+ saas: ['saas', 'subscription', 'billing', 'multi-tenant', 'b2b', 'software as a service'],
173
+ api: ['api', 'rest api', 'graphql', 'backend', 'microservice'],
174
+ cli: ['cli', 'command line', 'terminal', 'shell'],
175
+ fullstack: ['fullstack', 'full stack', 'web app', 'web application']
176
+ };
177
+
178
+ for (const [type, keywords] of Object.entries(typeKeywords)) {
179
+ if (keywords.some(kw => description.includes(kw))) {
180
+ return type;
181
+ }
182
+ }
183
+
184
+ // Default heuristics
185
+ if (description.includes('login') || description.includes('auth')) {
186
+ return 'fullstack';
187
+ }
188
+ if (description.includes('page') || description.includes('website')) {
189
+ return 'landing';
190
+ }
191
+
192
+ return null;
193
+ }
194
+
195
+ /**
196
+ * Detect modules from description keywords
197
+ */
198
+ detectModulesFromDescription(description) {
199
+ const detected = [];
200
+
201
+ for (const [moduleName, config] of Object.entries(MODULE_PATTERNS)) {
202
+ const hasKeyword = config.keywords.some(kw => description.includes(kw));
203
+ if (hasKeyword) {
204
+ detected.push(moduleName);
205
+ // Also add dependencies
206
+ detected.push(...config.dependencies);
207
+ }
208
+ }
209
+
210
+ return [...new Set(detected)];
211
+ }
212
+
213
+ /**
214
+ * Build module objects with full metadata
215
+ */
216
+ buildModuleObjects(moduleNames, description) {
217
+ return moduleNames.map(name => {
218
+ const pattern = MODULE_PATTERNS[name] || {
219
+ keywords: [name],
220
+ priority: 5,
221
+ dependencies: ['core']
222
+ };
223
+
224
+ return {
225
+ id: name,
226
+ name: this.formatModuleName(name),
227
+ description: this.generateModuleDescription(name, description),
228
+ priority: pattern.priority,
229
+ dependencies: pattern.dependencies.filter(dep => moduleNames.includes(dep)),
230
+ status: 'pending',
231
+ estimatedSize: this.estimateModuleSize(name),
232
+ files: [],
233
+ buildAttempts: 0,
234
+ errors: []
235
+ };
236
+ });
237
+ }
238
+
239
+ /**
240
+ * Format module name for display
241
+ */
242
+ formatModuleName(name) {
243
+ return name.charAt(0).toUpperCase() + name.slice(1).replace(/-/g, ' ');
244
+ }
245
+
246
+ /**
247
+ * Generate module description based on context
248
+ */
249
+ generateModuleDescription(moduleName, projectDescription) {
250
+ const descriptions = {
251
+ core: 'Project setup, configuration, and base infrastructure',
252
+ auth: 'Authentication system with login, signup, and session management',
253
+ database: 'Database schema, models, and data layer',
254
+ api: 'API endpoints and route handlers',
255
+ users: 'User management, profiles, and account settings',
256
+ dashboard: 'Admin dashboard and analytics views',
257
+ billing: 'Payment processing, subscriptions, and invoicing',
258
+ notifications: 'Email, push, and in-app notification system',
259
+ ui: 'Reusable UI components and design system',
260
+ pages: 'Application pages and views',
261
+ tests: 'Unit, integration, and end-to-end tests'
262
+ };
263
+
264
+ return descriptions[moduleName] || `${this.formatModuleName(moduleName)} module`;
265
+ }
266
+
267
+ /**
268
+ * Estimate module size (small, medium, large)
269
+ */
270
+ estimateModuleSize(moduleName) {
271
+ const largeMods = ['auth', 'billing', 'dashboard', 'api'];
272
+ const mediumMods = ['users', 'database', 'ui', 'pages'];
273
+
274
+ if (largeMods.includes(moduleName)) return 'large';
275
+ if (mediumMods.includes(moduleName)) return 'medium';
276
+ return 'small';
277
+ }
278
+
279
+ /**
280
+ * Build dependency graph as Map
281
+ */
282
+ buildDependencyGraph(modules) {
283
+ const graph = new Map();
284
+
285
+ for (const mod of modules) {
286
+ graph.set(mod.id, {
287
+ module: mod,
288
+ dependsOn: mod.dependencies,
289
+ dependedBy: []
290
+ });
291
+ }
292
+
293
+ // Build reverse dependencies
294
+ for (const mod of modules) {
295
+ for (const dep of mod.dependencies) {
296
+ if (graph.has(dep)) {
297
+ graph.get(dep).dependedBy.push(mod.id);
298
+ }
299
+ }
300
+ }
301
+
302
+ return graph;
303
+ }
304
+
305
+ /**
306
+ * Topological sort for build order
307
+ * Uses Kahn's algorithm
308
+ */
309
+ topologicalSort() {
310
+ const inDegree = new Map();
311
+ const queue = [];
312
+ const result = [];
313
+
314
+ // Initialize in-degrees
315
+ for (const mod of this.modules) {
316
+ inDegree.set(mod.id, mod.dependencies.length);
317
+ if (mod.dependencies.length === 0) {
318
+ queue.push(mod.id);
319
+ }
320
+ }
321
+
322
+ // Process queue
323
+ while (queue.length > 0) {
324
+ const current = queue.shift();
325
+ result.push(current);
326
+
327
+ const node = this.dependencyGraph.get(current);
328
+ if (node) {
329
+ for (const dependent of node.dependedBy) {
330
+ const newDegree = inDegree.get(dependent) - 1;
331
+ inDegree.set(dependent, newDegree);
332
+ if (newDegree === 0) {
333
+ queue.push(dependent);
334
+ }
335
+ }
336
+ }
337
+ }
338
+
339
+ // Check for cycles
340
+ if (result.length !== this.modules.length) {
341
+ console.warn('Circular dependency detected, falling back to priority order');
342
+ return this.modules
343
+ .sort((a, b) => a.priority - b.priority)
344
+ .map(m => m.id);
345
+ }
346
+
347
+ return result;
348
+ }
349
+
350
+ /**
351
+ * Serialize dependency graph for storage
352
+ */
353
+ serializeDependencyGraph() {
354
+ const serialized = {};
355
+ for (const [key, value] of this.dependencyGraph) {
356
+ serialized[key] = {
357
+ dependsOn: value.dependsOn,
358
+ dependedBy: value.dependedBy
359
+ };
360
+ }
361
+ return serialized;
362
+ }
363
+
364
+ /**
365
+ * Estimate overall project complexity
366
+ */
367
+ estimateComplexity() {
368
+ const sizeWeights = { small: 1, medium: 2, large: 3 };
369
+ const totalWeight = this.modules.reduce((sum, mod) => {
370
+ return sum + sizeWeights[mod.estimatedSize];
371
+ }, 0);
372
+
373
+ if (totalWeight <= 5) return 'simple';
374
+ if (totalWeight <= 10) return 'moderate';
375
+ if (totalWeight <= 15) return 'complex';
376
+ return 'enterprise';
377
+ }
378
+
379
+ /**
380
+ * Get module by ID
381
+ */
382
+ getModule(moduleId) {
383
+ return this.modules.find(m => m.id === moduleId);
384
+ }
385
+
386
+ /**
387
+ * Update module status
388
+ */
389
+ updateModuleStatus(moduleId, status, data = {}) {
390
+ const mod = this.getModule(moduleId);
391
+ if (mod) {
392
+ mod.status = status;
393
+ Object.assign(mod, data);
394
+ }
395
+ return mod;
396
+ }
397
+
398
+ /**
399
+ * Check if module can be built (dependencies satisfied)
400
+ */
401
+ canBuildModule(moduleId) {
402
+ const mod = this.getModule(moduleId);
403
+ if (!mod) return false;
404
+
405
+ return mod.dependencies.every(depId => {
406
+ const dep = this.getModule(depId);
407
+ return dep && dep.status === 'completed';
408
+ });
409
+ }
410
+
411
+ /**
412
+ * Get next buildable modules
413
+ */
414
+ getNextBuildableModules() {
415
+ return this.modules.filter(mod =>
416
+ mod.status === 'pending' && this.canBuildModule(mod.id)
417
+ );
418
+ }
419
+
420
+ /**
421
+ * Generate module prompt for Claude Code
422
+ */
423
+ generateModulePrompt(moduleId, context = {}) {
424
+ const mod = this.getModule(moduleId);
425
+ if (!mod) return null;
426
+
427
+ const completedModules = this.modules
428
+ .filter(m => m.status === 'completed')
429
+ .map(m => `- ${m.name}: ${m.files.join(', ')}`)
430
+ .join('\n');
431
+
432
+ return `
433
+ # Module: ${mod.name}
434
+
435
+ ## Description
436
+ ${mod.description}
437
+
438
+ ## Dependencies
439
+ ${mod.dependencies.length > 0
440
+ ? mod.dependencies.map(d => `- ${this.formatModuleName(d)}`).join('\n')
441
+ : 'No dependencies'}
442
+
443
+ ## Already Built
444
+ ${completedModules || 'None yet'}
445
+
446
+ ## Context
447
+ ${context.projectDescription || 'Build this module according to best practices.'}
448
+
449
+ ## Requirements
450
+ - Follow existing code patterns from completed modules
451
+ - Ensure compatibility with dependencies
452
+ - Include necessary exports for dependent modules
453
+ - Add appropriate error handling
454
+
455
+ ## Instructions
456
+ Build the ${mod.name} module. Create all necessary files and ensure they integrate with existing code.
457
+ `;
458
+ }
459
+ }
460
+
461
+ /**
462
+ * Create decomposition engine instance
463
+ */
464
+ export function createDecompositionEngine() {
465
+ return new DecompositionEngine();
466
+ }
467
+
468
+ /**
469
+ * Quick decompose helper
470
+ */
471
+ export async function decomposeProject(description, options = {}) {
472
+ const engine = new DecompositionEngine();
473
+ return engine.decompose(description, options);
474
+ }
475
+
476
+ export { MODULE_PATTERNS, PROJECT_TEMPLATES };