@nclamvn/vibecode-cli 2.0.0 → 2.2.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 (53) 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 +235 -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 +635 -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/templates.js +397 -0
  28. package/src/commands/test.js +194 -0
  29. package/src/commands/undo.js +281 -0
  30. package/src/commands/watch.js +556 -0
  31. package/src/commands/wizard.js +322 -0
  32. package/src/config/constants.js +5 -1
  33. package/src/config/templates.js +146 -15
  34. package/src/core/backup.js +325 -0
  35. package/src/core/error-analyzer.js +237 -0
  36. package/src/core/fix-generator.js +195 -0
  37. package/src/core/iteration.js +226 -0
  38. package/src/core/learning.js +295 -0
  39. package/src/core/session.js +18 -2
  40. package/src/core/test-runner.js +281 -0
  41. package/src/debug/analyzer.js +329 -0
  42. package/src/debug/evidence.js +228 -0
  43. package/src/debug/fixer.js +348 -0
  44. package/src/debug/image-analyzer.js +304 -0
  45. package/src/debug/index.js +378 -0
  46. package/src/debug/verifier.js +346 -0
  47. package/src/index.js +102 -0
  48. package/src/providers/claude-code.js +12 -7
  49. package/src/templates/index.js +724 -0
  50. package/src/ui/__tests__/error-translator.test.js +390 -0
  51. package/src/ui/dashboard.js +364 -0
  52. package/src/ui/error-translator.js +775 -0
  53. package/src/utils/image.js +222 -0
@@ -0,0 +1,391 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // VIBECODE AGENT - Main Entry Point
3
+ // Autonomous multi-module builder with self-healing
4
+ // ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ import chalk from 'chalk';
7
+ import ora from 'ora';
8
+ import path from 'path';
9
+ import fs from 'fs-extra';
10
+
11
+ import { DecompositionEngine, createDecompositionEngine } from './decomposition.js';
12
+ import { MemoryEngine, createMemoryEngine } from './memory.js';
13
+ import { SelfHealingEngine, createSelfHealingEngine } from './self-healing.js';
14
+ import {
15
+ Orchestrator,
16
+ createOrchestrator,
17
+ ORCHESTRATOR_STATES,
18
+ loadProgress,
19
+ loadDecomposition
20
+ } from './orchestrator.js';
21
+
22
+ /**
23
+ * Vibecode Agent Class
24
+ * Main interface for autonomous project building
25
+ */
26
+ export class VibecodeAgent {
27
+ constructor(options = {}) {
28
+ this.projectPath = options.projectPath || process.cwd();
29
+ this.verbose = options.verbose || false;
30
+
31
+ // Engine instances
32
+ this.decomposition = null;
33
+ this.memory = null;
34
+ this.selfHealing = null;
35
+ this.orchestrator = null;
36
+
37
+ // Agent state
38
+ this.initialized = false;
39
+ this.buildResult = null;
40
+ }
41
+
42
+ /**
43
+ * Initialize the agent and all engines
44
+ */
45
+ async initialize() {
46
+ if (this.initialized) return this;
47
+
48
+ const spinner = ora('Initializing Vibecode Agent...').start();
49
+
50
+ try {
51
+ // Create engine instances
52
+ this.decomposition = createDecompositionEngine();
53
+ this.memory = await createMemoryEngine(this.projectPath);
54
+ this.selfHealing = createSelfHealingEngine(this.memory);
55
+
56
+ this.orchestrator = createOrchestrator({
57
+ projectPath: this.projectPath,
58
+ decompositionEngine: this.decomposition,
59
+ memoryEngine: this.memory,
60
+ selfHealingEngine: this.selfHealing
61
+ });
62
+
63
+ await this.orchestrator.initialize(this.projectPath);
64
+
65
+ // Setup event handlers
66
+ this.setupEventHandlers();
67
+
68
+ this.initialized = true;
69
+ spinner.succeed('Vibecode Agent ready');
70
+
71
+ return this;
72
+ } catch (error) {
73
+ spinner.fail(`Agent initialization failed: ${error.message}`);
74
+ throw error;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Setup event handlers for progress reporting
80
+ */
81
+ setupEventHandlers() {
82
+ if (!this.verbose) return;
83
+
84
+ this.orchestrator.on('state_change', ({ from, to }) => {
85
+ console.log(chalk.gray(` State: ${from} → ${to}`));
86
+ });
87
+
88
+ this.orchestrator.on('module_start', ({ moduleId, module }) => {
89
+ console.log(chalk.cyan(`\n Starting: ${module.name}`));
90
+ });
91
+
92
+ this.orchestrator.on('module_complete', ({ moduleId }) => {
93
+ console.log(chalk.green(` ✓ ${moduleId} complete`));
94
+ });
95
+
96
+ this.orchestrator.on('module_fail', ({ moduleId, error, attempts }) => {
97
+ console.log(chalk.red(` ✗ ${moduleId} failed after ${attempts} attempts`));
98
+ });
99
+
100
+ this.orchestrator.on('healing_start', ({ moduleId }) => {
101
+ console.log(chalk.yellow(` Self-healing ${moduleId}...`));
102
+ });
103
+ }
104
+
105
+ /**
106
+ * Build a project from description
107
+ */
108
+ async build(description, options = {}) {
109
+ if (!this.initialized) {
110
+ await this.initialize();
111
+ }
112
+
113
+ this.showHeader(description);
114
+
115
+ try {
116
+ this.buildResult = await this.orchestrator.build(description, options);
117
+ this.showResults(this.buildResult);
118
+ return this.buildResult;
119
+ } catch (error) {
120
+ console.error(chalk.red(`\nAgent build failed: ${error.message}`));
121
+ throw error;
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Show agent header
127
+ */
128
+ showHeader(description) {
129
+ console.log();
130
+ console.log(chalk.magenta('╭' + '─'.repeat(68) + '╮'));
131
+ console.log(chalk.magenta('│') + ' '.repeat(68) + chalk.magenta('│'));
132
+ console.log(chalk.magenta('│') + chalk.bold.white(' 🤖 VIBECODE AGENT') + ' '.repeat(48) + chalk.magenta('│'));
133
+ console.log(chalk.magenta('│') + chalk.gray(' Autonomous Multi-Module Builder') + ' '.repeat(32) + chalk.magenta('│'));
134
+ console.log(chalk.magenta('│') + ' '.repeat(68) + chalk.magenta('│'));
135
+
136
+ const truncDesc = description.length > 60
137
+ ? description.substring(0, 57) + '...'
138
+ : description;
139
+ console.log(chalk.magenta('│') + chalk.gray(` "${truncDesc}"`) + ' '.repeat(Math.max(0, 65 - truncDesc.length)) + chalk.magenta('│'));
140
+ console.log(chalk.magenta('│') + ' '.repeat(68) + chalk.magenta('│'));
141
+ console.log(chalk.magenta('╰' + '─'.repeat(68) + '╯'));
142
+ console.log();
143
+ }
144
+
145
+ /**
146
+ * Show build results
147
+ */
148
+ showResults(result) {
149
+ console.log();
150
+
151
+ if (result.success) {
152
+ console.log(chalk.green('╭' + '─'.repeat(68) + '╮'));
153
+ console.log(chalk.green('│') + ' '.repeat(68) + chalk.green('│'));
154
+ console.log(chalk.green('│') + chalk.bold.white(' ✓ AGENT BUILD COMPLETE') + ' '.repeat(42) + chalk.green('│'));
155
+ } else {
156
+ console.log(chalk.yellow('╭' + '─'.repeat(68) + '╮'));
157
+ console.log(chalk.yellow('│') + ' '.repeat(68) + chalk.yellow('│'));
158
+ console.log(chalk.yellow('│') + chalk.bold.white(' ⚠ AGENT BUILD INCOMPLETE') + ' '.repeat(40) + chalk.yellow('│'));
159
+ }
160
+
161
+ const color = result.success ? chalk.green : chalk.yellow;
162
+
163
+ console.log(color('│') + ' '.repeat(68) + color('│'));
164
+ console.log(color('│') + chalk.white(` 📦 Type: ${result.projectType}`) + ' '.repeat(Math.max(0, 49 - result.projectType.length)) + color('│'));
165
+ console.log(color('│') + chalk.white(` 📊 Complexity: ${result.complexity}`) + ' '.repeat(Math.max(0, 49 - result.complexity.length)) + color('│'));
166
+ console.log(color('│') + chalk.white(` ⏱️ Duration: ${result.duration}`) + ' '.repeat(Math.max(0, 48 - result.duration.length)) + color('│'));
167
+ console.log(color('│') + ' '.repeat(68) + color('│'));
168
+
169
+ // Module stats
170
+ const modStats = `${result.modules.completed}/${result.modules.total} modules`;
171
+ console.log(color('│') + chalk.white(` 📁 Modules: ${modStats}`) + ' '.repeat(Math.max(0, 49 - modStats.length)) + color('│'));
172
+
173
+ if (result.modules.failed > 0) {
174
+ console.log(color('│') + chalk.red(` ❌ Failed: ${result.modules.failed}`) + ' '.repeat(49) + color('│'));
175
+ }
176
+ if (result.modules.skipped > 0) {
177
+ console.log(color('│') + chalk.yellow(` ⏭️ Skipped: ${result.modules.skipped}`) + ' '.repeat(48) + color('│'));
178
+ }
179
+
180
+ // Retries
181
+ if (result.retries.total > 0) {
182
+ console.log(color('│') + chalk.gray(` 🔄 Retries: ${result.retries.total}`) + ' '.repeat(49) + color('│'));
183
+ }
184
+
185
+ console.log(color('│') + ' '.repeat(68) + color('│'));
186
+
187
+ // Completed modules list
188
+ if (result.completedModules.length > 0) {
189
+ console.log(color('│') + chalk.white(' Completed:') + ' '.repeat(54) + color('│'));
190
+ for (const mod of result.completedModules) {
191
+ console.log(color('│') + chalk.green(` ✓ ${mod}`) + ' '.repeat(Math.max(0, 59 - mod.length)) + color('│'));
192
+ }
193
+ }
194
+
195
+ // Failed modules list
196
+ if (result.failedModules.length > 0) {
197
+ console.log(color('│') + ' '.repeat(68) + color('│'));
198
+ console.log(color('│') + chalk.white(' Failed:') + ' '.repeat(57) + color('│'));
199
+ for (const mod of result.failedModules) {
200
+ console.log(color('│') + chalk.red(` ✗ ${mod}`) + ' '.repeat(Math.max(0, 59 - mod.length)) + color('│'));
201
+ }
202
+ }
203
+
204
+ console.log(color('│') + ' '.repeat(68) + color('│'));
205
+ console.log(color('╰' + '─'.repeat(68) + '╯'));
206
+ console.log();
207
+
208
+ // Next steps
209
+ if (result.success) {
210
+ console.log(chalk.gray(' Next steps:'));
211
+ console.log(chalk.gray(' cd ' + path.basename(this.projectPath)));
212
+ console.log(chalk.gray(' npm install'));
213
+ console.log(chalk.gray(' npm start'));
214
+ } else {
215
+ console.log(chalk.gray(' To investigate:'));
216
+ console.log(chalk.gray(' Check .vibecode/agent/orchestrator.log'));
217
+ console.log(chalk.gray(' Check .vibecode/agent/evidence/*.log'));
218
+ }
219
+ console.log();
220
+ }
221
+
222
+ /**
223
+ * Resume a previously interrupted build
224
+ */
225
+ async resume(options = {}) {
226
+ if (!this.initialized) {
227
+ await this.initialize();
228
+ }
229
+
230
+ // Load progress to show header
231
+ const progress = await loadProgress(this.projectPath);
232
+ if (!progress) {
233
+ console.log(chalk.yellow('\n📭 No previous session found.\n'));
234
+ console.log(chalk.gray(' Start new build: vibecode agent "description" --new\n'));
235
+ return null;
236
+ }
237
+
238
+ this.showResumeHeader(progress, options);
239
+
240
+ try {
241
+ this.buildResult = await this.orchestrator.resumeBuild(options);
242
+ this.showResults(this.buildResult);
243
+ return this.buildResult;
244
+ } catch (error) {
245
+ console.error(chalk.red(`\nAgent resume failed: ${error.message}`));
246
+ throw error;
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Show resume header
252
+ */
253
+ showResumeHeader(progress, options) {
254
+ const fromModule = options.fromModule !== undefined
255
+ ? options.fromModule + 1
256
+ : progress.currentModule + 1;
257
+ const totalModules = progress.totalModules;
258
+ const completed = progress.completedModules?.length || progress.currentModule || 0;
259
+
260
+ console.log();
261
+ console.log(chalk.cyan('╭' + '─'.repeat(68) + '╮'));
262
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
263
+ console.log(chalk.cyan('│') + chalk.bold.white(' 🔄 RESUMING AGENT') + ' '.repeat(48) + chalk.cyan('│'));
264
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
265
+
266
+ const projectLine = ` Project: ${progress.projectName}`;
267
+ console.log(chalk.cyan('│') + chalk.white(projectLine) + ' '.repeat(Math.max(0, 66 - projectLine.length)) + chalk.cyan('│'));
268
+
269
+ const progressLine = ` Progress: ${completed}/${totalModules} modules completed`;
270
+ console.log(chalk.cyan('│') + chalk.white(progressLine) + ' '.repeat(Math.max(0, 66 - progressLine.length)) + chalk.cyan('│'));
271
+
272
+ const resumeLine = ` Resuming from module ${fromModule}`;
273
+ console.log(chalk.cyan('│') + chalk.yellow(resumeLine) + ' '.repeat(Math.max(0, 66 - resumeLine.length)) + chalk.cyan('│'));
274
+
275
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
276
+ console.log(chalk.cyan('╰' + '─'.repeat(68) + '╯'));
277
+ console.log();
278
+ }
279
+
280
+ /**
281
+ * Quick build helper
282
+ */
283
+ static async quickBuild(description, options = {}) {
284
+ const agent = new VibecodeAgent(options);
285
+ await agent.initialize();
286
+ return agent.build(description, options);
287
+ }
288
+
289
+ /**
290
+ * Analyze project without building
291
+ */
292
+ async analyze(description) {
293
+ if (!this.initialized) {
294
+ await this.initialize();
295
+ }
296
+
297
+ const decomposition = await this.decomposition.decompose(description);
298
+
299
+ console.log();
300
+ console.log(chalk.cyan('╭' + '─'.repeat(68) + '╮'));
301
+ console.log(chalk.cyan('│') + chalk.bold.white(' 📋 PROJECT ANALYSIS') + ' '.repeat(46) + chalk.cyan('│'));
302
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
303
+ console.log(chalk.cyan('│') + chalk.white(` Type: ${decomposition.projectType}`) + ' '.repeat(Math.max(0, 52 - decomposition.projectType.length)) + chalk.cyan('│'));
304
+ console.log(chalk.cyan('│') + chalk.white(` Complexity: ${decomposition.estimatedComplexity}`) + ' '.repeat(Math.max(0, 52 - decomposition.estimatedComplexity.length)) + chalk.cyan('│'));
305
+ console.log(chalk.cyan('│') + chalk.white(` Modules: ${decomposition.totalModules}`) + ' '.repeat(51) + chalk.cyan('│'));
306
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
307
+ console.log(chalk.cyan('│') + chalk.white(' Build Order:') + ' '.repeat(52) + chalk.cyan('│'));
308
+
309
+ for (let i = 0; i < decomposition.buildOrder.length; i++) {
310
+ const moduleId = decomposition.buildOrder[i];
311
+ const module = decomposition.modules.find(m => m.id === moduleId);
312
+ const line = ` ${i + 1}. ${module?.name || moduleId} (${module?.estimatedSize || 'unknown'})`;
313
+ console.log(chalk.cyan('│') + chalk.gray(line) + ' '.repeat(Math.max(0, 66 - line.length)) + chalk.cyan('│'));
314
+ }
315
+
316
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
317
+ console.log(chalk.cyan('╰' + '─'.repeat(68) + '╯'));
318
+ console.log();
319
+
320
+ return decomposition;
321
+ }
322
+
323
+ /**
324
+ * Get agent status
325
+ */
326
+ getStatus() {
327
+ return {
328
+ initialized: this.initialized,
329
+ projectPath: this.projectPath,
330
+ orchestratorState: this.orchestrator?.getState(),
331
+ memoryStats: this.memory?.getStats(),
332
+ healingStats: this.selfHealing?.getStats()
333
+ };
334
+ }
335
+
336
+ /**
337
+ * Export memory report
338
+ */
339
+ async exportReport() {
340
+ if (!this.memory) {
341
+ throw new Error('Agent not initialized');
342
+ }
343
+
344
+ const report = this.memory.exportToMarkdown();
345
+ const reportPath = path.join(this.projectPath, '.vibecode', 'agent', 'report.md');
346
+
347
+ await fs.writeFile(reportPath, report);
348
+ console.log(chalk.green(`Report exported to: ${reportPath}`));
349
+
350
+ return report;
351
+ }
352
+
353
+ /**
354
+ * Clear agent memory
355
+ */
356
+ async clearMemory() {
357
+ if (this.memory) {
358
+ await this.memory.clear();
359
+ console.log(chalk.yellow('Agent memory cleared'));
360
+ }
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Create agent instance
366
+ */
367
+ export function createAgent(options = {}) {
368
+ return new VibecodeAgent(options);
369
+ }
370
+
371
+ /**
372
+ * Quick build function
373
+ */
374
+ export async function agentBuild(description, options = {}) {
375
+ return VibecodeAgent.quickBuild(description, options);
376
+ }
377
+
378
+ // Re-export engines for direct use
379
+ export {
380
+ DecompositionEngine,
381
+ createDecompositionEngine,
382
+ MemoryEngine,
383
+ createMemoryEngine,
384
+ SelfHealingEngine,
385
+ createSelfHealingEngine,
386
+ Orchestrator,
387
+ createOrchestrator,
388
+ ORCHESTRATOR_STATES,
389
+ loadProgress,
390
+ loadDecomposition
391
+ };