@nclamvn/vibecode-cli 1.3.0 → 1.5.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.
@@ -0,0 +1,325 @@
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 { Orchestrator, createOrchestrator, ORCHESTRATOR_STATES } from './orchestrator.js';
15
+
16
+ /**
17
+ * Vibecode Agent Class
18
+ * Main interface for autonomous project building
19
+ */
20
+ export class VibecodeAgent {
21
+ constructor(options = {}) {
22
+ this.projectPath = options.projectPath || process.cwd();
23
+ this.verbose = options.verbose || false;
24
+
25
+ // Engine instances
26
+ this.decomposition = null;
27
+ this.memory = null;
28
+ this.selfHealing = null;
29
+ this.orchestrator = null;
30
+
31
+ // Agent state
32
+ this.initialized = false;
33
+ this.buildResult = null;
34
+ }
35
+
36
+ /**
37
+ * Initialize the agent and all engines
38
+ */
39
+ async initialize() {
40
+ if (this.initialized) return this;
41
+
42
+ const spinner = ora('Initializing Vibecode Agent...').start();
43
+
44
+ try {
45
+ // Create engine instances
46
+ this.decomposition = createDecompositionEngine();
47
+ this.memory = await createMemoryEngine(this.projectPath);
48
+ this.selfHealing = createSelfHealingEngine(this.memory);
49
+
50
+ this.orchestrator = createOrchestrator({
51
+ projectPath: this.projectPath,
52
+ decompositionEngine: this.decomposition,
53
+ memoryEngine: this.memory,
54
+ selfHealingEngine: this.selfHealing
55
+ });
56
+
57
+ await this.orchestrator.initialize(this.projectPath);
58
+
59
+ // Setup event handlers
60
+ this.setupEventHandlers();
61
+
62
+ this.initialized = true;
63
+ spinner.succeed('Vibecode Agent ready');
64
+
65
+ return this;
66
+ } catch (error) {
67
+ spinner.fail(`Agent initialization failed: ${error.message}`);
68
+ throw error;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Setup event handlers for progress reporting
74
+ */
75
+ setupEventHandlers() {
76
+ if (!this.verbose) return;
77
+
78
+ this.orchestrator.on('state_change', ({ from, to }) => {
79
+ console.log(chalk.gray(` State: ${from} → ${to}`));
80
+ });
81
+
82
+ this.orchestrator.on('module_start', ({ moduleId, module }) => {
83
+ console.log(chalk.cyan(`\n Starting: ${module.name}`));
84
+ });
85
+
86
+ this.orchestrator.on('module_complete', ({ moduleId }) => {
87
+ console.log(chalk.green(` ✓ ${moduleId} complete`));
88
+ });
89
+
90
+ this.orchestrator.on('module_fail', ({ moduleId, error, attempts }) => {
91
+ console.log(chalk.red(` ✗ ${moduleId} failed after ${attempts} attempts`));
92
+ });
93
+
94
+ this.orchestrator.on('healing_start', ({ moduleId }) => {
95
+ console.log(chalk.yellow(` Self-healing ${moduleId}...`));
96
+ });
97
+ }
98
+
99
+ /**
100
+ * Build a project from description
101
+ */
102
+ async build(description, options = {}) {
103
+ if (!this.initialized) {
104
+ await this.initialize();
105
+ }
106
+
107
+ this.showHeader(description);
108
+
109
+ try {
110
+ this.buildResult = await this.orchestrator.build(description, options);
111
+ this.showResults(this.buildResult);
112
+ return this.buildResult;
113
+ } catch (error) {
114
+ console.error(chalk.red(`\nAgent build failed: ${error.message}`));
115
+ throw error;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Show agent header
121
+ */
122
+ showHeader(description) {
123
+ console.log();
124
+ console.log(chalk.magenta('╭' + '─'.repeat(68) + '╮'));
125
+ console.log(chalk.magenta('│') + ' '.repeat(68) + chalk.magenta('│'));
126
+ console.log(chalk.magenta('│') + chalk.bold.white(' 🤖 VIBECODE AGENT') + ' '.repeat(48) + chalk.magenta('│'));
127
+ console.log(chalk.magenta('│') + chalk.gray(' Autonomous Multi-Module Builder') + ' '.repeat(32) + chalk.magenta('│'));
128
+ console.log(chalk.magenta('│') + ' '.repeat(68) + chalk.magenta('│'));
129
+
130
+ const truncDesc = description.length > 60
131
+ ? description.substring(0, 57) + '...'
132
+ : description;
133
+ console.log(chalk.magenta('│') + chalk.gray(` "${truncDesc}"`) + ' '.repeat(Math.max(0, 65 - truncDesc.length)) + chalk.magenta('│'));
134
+ console.log(chalk.magenta('│') + ' '.repeat(68) + chalk.magenta('│'));
135
+ console.log(chalk.magenta('╰' + '─'.repeat(68) + '╯'));
136
+ console.log();
137
+ }
138
+
139
+ /**
140
+ * Show build results
141
+ */
142
+ showResults(result) {
143
+ console.log();
144
+
145
+ if (result.success) {
146
+ console.log(chalk.green('╭' + '─'.repeat(68) + '╮'));
147
+ console.log(chalk.green('│') + ' '.repeat(68) + chalk.green('│'));
148
+ console.log(chalk.green('│') + chalk.bold.white(' ✓ AGENT BUILD COMPLETE') + ' '.repeat(42) + chalk.green('│'));
149
+ } else {
150
+ console.log(chalk.yellow('╭' + '─'.repeat(68) + '╮'));
151
+ console.log(chalk.yellow('│') + ' '.repeat(68) + chalk.yellow('│'));
152
+ console.log(chalk.yellow('│') + chalk.bold.white(' ⚠ AGENT BUILD INCOMPLETE') + ' '.repeat(40) + chalk.yellow('│'));
153
+ }
154
+
155
+ const color = result.success ? chalk.green : chalk.yellow;
156
+
157
+ console.log(color('│') + ' '.repeat(68) + color('│'));
158
+ console.log(color('│') + chalk.white(` 📦 Type: ${result.projectType}`) + ' '.repeat(Math.max(0, 49 - result.projectType.length)) + color('│'));
159
+ console.log(color('│') + chalk.white(` 📊 Complexity: ${result.complexity}`) + ' '.repeat(Math.max(0, 49 - result.complexity.length)) + color('│'));
160
+ console.log(color('│') + chalk.white(` ⏱️ Duration: ${result.duration}`) + ' '.repeat(Math.max(0, 48 - result.duration.length)) + color('│'));
161
+ console.log(color('│') + ' '.repeat(68) + color('│'));
162
+
163
+ // Module stats
164
+ const modStats = `${result.modules.completed}/${result.modules.total} modules`;
165
+ console.log(color('│') + chalk.white(` 📁 Modules: ${modStats}`) + ' '.repeat(Math.max(0, 49 - modStats.length)) + color('│'));
166
+
167
+ if (result.modules.failed > 0) {
168
+ console.log(color('│') + chalk.red(` ❌ Failed: ${result.modules.failed}`) + ' '.repeat(49) + color('│'));
169
+ }
170
+ if (result.modules.skipped > 0) {
171
+ console.log(color('│') + chalk.yellow(` ⏭️ Skipped: ${result.modules.skipped}`) + ' '.repeat(48) + color('│'));
172
+ }
173
+
174
+ // Retries
175
+ if (result.retries.total > 0) {
176
+ console.log(color('│') + chalk.gray(` 🔄 Retries: ${result.retries.total}`) + ' '.repeat(49) + color('│'));
177
+ }
178
+
179
+ console.log(color('│') + ' '.repeat(68) + color('│'));
180
+
181
+ // Completed modules list
182
+ if (result.completedModules.length > 0) {
183
+ console.log(color('│') + chalk.white(' Completed:') + ' '.repeat(54) + color('│'));
184
+ for (const mod of result.completedModules) {
185
+ console.log(color('│') + chalk.green(` ✓ ${mod}`) + ' '.repeat(Math.max(0, 59 - mod.length)) + color('│'));
186
+ }
187
+ }
188
+
189
+ // Failed modules list
190
+ if (result.failedModules.length > 0) {
191
+ console.log(color('│') + ' '.repeat(68) + color('│'));
192
+ console.log(color('│') + chalk.white(' Failed:') + ' '.repeat(57) + color('│'));
193
+ for (const mod of result.failedModules) {
194
+ console.log(color('│') + chalk.red(` ✗ ${mod}`) + ' '.repeat(Math.max(0, 59 - mod.length)) + color('│'));
195
+ }
196
+ }
197
+
198
+ console.log(color('│') + ' '.repeat(68) + color('│'));
199
+ console.log(color('╰' + '─'.repeat(68) + '╯'));
200
+ console.log();
201
+
202
+ // Next steps
203
+ if (result.success) {
204
+ console.log(chalk.gray(' Next steps:'));
205
+ console.log(chalk.gray(' cd ' + path.basename(this.projectPath)));
206
+ console.log(chalk.gray(' npm install'));
207
+ console.log(chalk.gray(' npm start'));
208
+ } else {
209
+ console.log(chalk.gray(' To investigate:'));
210
+ console.log(chalk.gray(' Check .vibecode/agent/orchestrator.log'));
211
+ console.log(chalk.gray(' Check .vibecode/agent/evidence/*.log'));
212
+ }
213
+ console.log();
214
+ }
215
+
216
+ /**
217
+ * Quick build helper
218
+ */
219
+ static async quickBuild(description, options = {}) {
220
+ const agent = new VibecodeAgent(options);
221
+ await agent.initialize();
222
+ return agent.build(description, options);
223
+ }
224
+
225
+ /**
226
+ * Analyze project without building
227
+ */
228
+ async analyze(description) {
229
+ if (!this.initialized) {
230
+ await this.initialize();
231
+ }
232
+
233
+ const decomposition = await this.decomposition.decompose(description);
234
+
235
+ console.log();
236
+ console.log(chalk.cyan('╭' + '─'.repeat(68) + '╮'));
237
+ console.log(chalk.cyan('│') + chalk.bold.white(' 📋 PROJECT ANALYSIS') + ' '.repeat(46) + chalk.cyan('│'));
238
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
239
+ console.log(chalk.cyan('│') + chalk.white(` Type: ${decomposition.projectType}`) + ' '.repeat(Math.max(0, 52 - decomposition.projectType.length)) + chalk.cyan('│'));
240
+ console.log(chalk.cyan('│') + chalk.white(` Complexity: ${decomposition.estimatedComplexity}`) + ' '.repeat(Math.max(0, 52 - decomposition.estimatedComplexity.length)) + chalk.cyan('│'));
241
+ console.log(chalk.cyan('│') + chalk.white(` Modules: ${decomposition.totalModules}`) + ' '.repeat(51) + chalk.cyan('│'));
242
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
243
+ console.log(chalk.cyan('│') + chalk.white(' Build Order:') + ' '.repeat(52) + chalk.cyan('│'));
244
+
245
+ for (let i = 0; i < decomposition.buildOrder.length; i++) {
246
+ const moduleId = decomposition.buildOrder[i];
247
+ const module = decomposition.modules.find(m => m.id === moduleId);
248
+ const line = ` ${i + 1}. ${module?.name || moduleId} (${module?.estimatedSize || 'unknown'})`;
249
+ console.log(chalk.cyan('│') + chalk.gray(line) + ' '.repeat(Math.max(0, 66 - line.length)) + chalk.cyan('│'));
250
+ }
251
+
252
+ console.log(chalk.cyan('│') + ' '.repeat(68) + chalk.cyan('│'));
253
+ console.log(chalk.cyan('╰' + '─'.repeat(68) + '╯'));
254
+ console.log();
255
+
256
+ return decomposition;
257
+ }
258
+
259
+ /**
260
+ * Get agent status
261
+ */
262
+ getStatus() {
263
+ return {
264
+ initialized: this.initialized,
265
+ projectPath: this.projectPath,
266
+ orchestratorState: this.orchestrator?.getState(),
267
+ memoryStats: this.memory?.getStats(),
268
+ healingStats: this.selfHealing?.getStats()
269
+ };
270
+ }
271
+
272
+ /**
273
+ * Export memory report
274
+ */
275
+ async exportReport() {
276
+ if (!this.memory) {
277
+ throw new Error('Agent not initialized');
278
+ }
279
+
280
+ const report = this.memory.exportToMarkdown();
281
+ const reportPath = path.join(this.projectPath, '.vibecode', 'agent', 'report.md');
282
+
283
+ await fs.writeFile(reportPath, report);
284
+ console.log(chalk.green(`Report exported to: ${reportPath}`));
285
+
286
+ return report;
287
+ }
288
+
289
+ /**
290
+ * Clear agent memory
291
+ */
292
+ async clearMemory() {
293
+ if (this.memory) {
294
+ await this.memory.clear();
295
+ console.log(chalk.yellow('Agent memory cleared'));
296
+ }
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Create agent instance
302
+ */
303
+ export function createAgent(options = {}) {
304
+ return new VibecodeAgent(options);
305
+ }
306
+
307
+ /**
308
+ * Quick build function
309
+ */
310
+ export async function agentBuild(description, options = {}) {
311
+ return VibecodeAgent.quickBuild(description, options);
312
+ }
313
+
314
+ // Re-export engines for direct use
315
+ export {
316
+ DecompositionEngine,
317
+ createDecompositionEngine,
318
+ MemoryEngine,
319
+ createMemoryEngine,
320
+ SelfHealingEngine,
321
+ createSelfHealingEngine,
322
+ Orchestrator,
323
+ createOrchestrator,
324
+ ORCHESTRATOR_STATES
325
+ };