@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,322 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // VIBECODE CLI - Interactive Wizard
3
+ // Phase H1: Smart Defaults - No args = Interactive menu
4
+ // ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ import inquirer from 'inquirer';
7
+ import chalk from 'chalk';
8
+ import { VERSION } from '../config/constants.js';
9
+
10
+ /**
11
+ * Wizard Command - Interactive menu when no args provided
12
+ *
13
+ * Usage:
14
+ * vibecode (no args) → Shows interactive menu
15
+ */
16
+ export async function wizardCommand() {
17
+ // Show welcome banner
18
+ console.log(chalk.cyan(`
19
+ ╭────────────────────────────────────────────────────────────────────╮
20
+ │ │
21
+ │ 🏗️ VIBECODE v${VERSION.padEnd(43)}│
22
+ │ Build Software with Discipline │
23
+ │ │
24
+ ╰────────────────────────────────────────────────────────────────────╯
25
+ `));
26
+
27
+ const { action } = await inquirer.prompt([
28
+ {
29
+ type: 'list',
30
+ name: 'action',
31
+ message: 'Bạn muốn làm gì hôm nay?',
32
+ choices: [
33
+ { name: '🚀 Tạo project mới nhanh', value: 'go' },
34
+ { name: '🤖 Build project phức tạp (nhiều modules)', value: 'agent' },
35
+ { name: '🔍 Debug/fix lỗi', value: 'debug' },
36
+ { name: '🤝 Trợ giúp từ AI', value: 'assist' },
37
+ new inquirer.Separator(),
38
+ { name: '📊 Xem trạng thái project hiện tại', value: 'status' },
39
+ { name: '⚙️ Cài đặt', value: 'config' },
40
+ { name: '📁 Khởi tạo workspace mới', value: 'init' },
41
+ new inquirer.Separator(),
42
+ { name: '❓ Xem trợ giúp', value: 'help' },
43
+ { name: '👋 Thoát', value: 'exit' }
44
+ ]
45
+ }
46
+ ]);
47
+
48
+ switch (action) {
49
+ case 'go':
50
+ await handleGo();
51
+ break;
52
+ case 'agent':
53
+ await handleAgent();
54
+ break;
55
+ case 'debug':
56
+ await handleDebug();
57
+ break;
58
+ case 'assist':
59
+ await handleAssist();
60
+ break;
61
+ case 'status':
62
+ await handleStatus();
63
+ break;
64
+ case 'config':
65
+ await handleConfig();
66
+ break;
67
+ case 'init':
68
+ await handleInit();
69
+ break;
70
+ case 'help':
71
+ showHelp();
72
+ break;
73
+ case 'exit':
74
+ console.log(chalk.cyan('\n👋 Hẹn gặp lại!\n'));
75
+ process.exit(0);
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Handle Go command with prompts
81
+ */
82
+ async function handleGo() {
83
+ const { goCommand } = await import('./go.js');
84
+
85
+ const { description } = await inquirer.prompt([
86
+ {
87
+ type: 'input',
88
+ name: 'description',
89
+ message: 'Mô tả project bạn muốn tạo:',
90
+ validate: (input) => input.length > 5 || 'Vui lòng mô tả chi tiết hơn (ít nhất 6 ký tự)'
91
+ }
92
+ ]);
93
+
94
+ const { template } = await inquirer.prompt([
95
+ {
96
+ type: 'list',
97
+ name: 'template',
98
+ message: 'Chọn template (hoặc để trống):',
99
+ choices: [
100
+ { name: '🎨 Không dùng template (tự do)', value: null },
101
+ { name: '🌐 Landing page', value: 'landing' },
102
+ { name: '💼 SaaS application', value: 'saas' },
103
+ { name: '⌨️ CLI tool', value: 'cli' },
104
+ { name: '🔌 REST API', value: 'api' }
105
+ ]
106
+ }
107
+ ]);
108
+
109
+ const { confirm } = await inquirer.prompt([
110
+ {
111
+ type: 'confirm',
112
+ name: 'confirm',
113
+ message: `Tạo project: "${description}"${template ? ` (template: ${template})` : ''}?`,
114
+ default: true
115
+ }
116
+ ]);
117
+
118
+ if (confirm) {
119
+ const options = {};
120
+ if (template) options.template = template;
121
+ await goCommand(description, options);
122
+ } else {
123
+ console.log(chalk.gray('\n✗ Đã huỷ.\n'));
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Handle Agent command with prompts
129
+ */
130
+ async function handleAgent() {
131
+ const { agentCommand } = await import('./agent.js');
132
+
133
+ const { description } = await inquirer.prompt([
134
+ {
135
+ type: 'input',
136
+ name: 'description',
137
+ message: 'Mô tả project phức tạp (VD: SaaS với auth, billing, dashboard):',
138
+ validate: (input) => input.length > 10 || 'Vui lòng mô tả chi tiết hơn (ít nhất 11 ký tự)'
139
+ }
140
+ ]);
141
+
142
+ const { createNew } = await inquirer.prompt([
143
+ {
144
+ type: 'confirm',
145
+ name: 'createNew',
146
+ message: 'Tạo thư mục project mới?',
147
+ default: true
148
+ }
149
+ ]);
150
+
151
+ const { verbose } = await inquirer.prompt([
152
+ {
153
+ type: 'confirm',
154
+ name: 'verbose',
155
+ message: 'Hiển thị chi tiết quá trình build?',
156
+ default: false
157
+ }
158
+ ]);
159
+
160
+ console.log(chalk.blue('\n🤖 Bắt đầu Agent Mode...\n'));
161
+ await agentCommand(description, { new: createNew, verbose });
162
+ }
163
+
164
+ /**
165
+ * Handle Debug command
166
+ */
167
+ async function handleDebug() {
168
+ const { debugCommand } = await import('./debug.js');
169
+
170
+ const { mode } = await inquirer.prompt([
171
+ {
172
+ type: 'list',
173
+ name: 'mode',
174
+ message: 'Chọn chế độ debug:',
175
+ choices: [
176
+ { name: '🔄 Interactive - Debug trực tiếp', value: 'interactive' },
177
+ { name: '🔍 Auto-scan - Tự động tìm và fix lỗi', value: 'auto' },
178
+ { name: '📝 Mô tả lỗi', value: 'describe' }
179
+ ]
180
+ }
181
+ ]);
182
+
183
+ if (mode === 'interactive') {
184
+ await debugCommand([], { interactive: true });
185
+ } else if (mode === 'auto') {
186
+ await debugCommand([], { auto: true });
187
+ } else {
188
+ const { description } = await inquirer.prompt([
189
+ {
190
+ type: 'input',
191
+ name: 'description',
192
+ message: 'Mô tả lỗi bạn gặp phải:',
193
+ validate: (input) => input.length > 5 || 'Vui lòng mô tả chi tiết hơn'
194
+ }
195
+ ]);
196
+ await debugCommand([description], {});
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Handle Assist command
202
+ */
203
+ async function handleAssist() {
204
+ const { assistCommand } = await import('./assist.js');
205
+
206
+ const { hasPrompt } = await inquirer.prompt([
207
+ {
208
+ type: 'confirm',
209
+ name: 'hasPrompt',
210
+ message: 'Bạn có câu hỏi cụ thể không?',
211
+ default: false
212
+ }
213
+ ]);
214
+
215
+ if (hasPrompt) {
216
+ const { prompt } = await inquirer.prompt([
217
+ {
218
+ type: 'input',
219
+ name: 'prompt',
220
+ message: 'Nhập câu hỏi của bạn:',
221
+ validate: (input) => input.length > 3 || 'Vui lòng nhập câu hỏi'
222
+ }
223
+ ]);
224
+ await assistCommand([prompt], {});
225
+ } else {
226
+ await assistCommand([], {});
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Handle Status command
232
+ */
233
+ async function handleStatus() {
234
+ const { statusCommand } = await import('./status.js');
235
+ await statusCommand({});
236
+ }
237
+
238
+ /**
239
+ * Handle Config command
240
+ */
241
+ async function handleConfig() {
242
+ const { configCommand } = await import('./config.js');
243
+
244
+ const { action } = await inquirer.prompt([
245
+ {
246
+ type: 'list',
247
+ name: 'action',
248
+ message: 'Cài đặt:',
249
+ choices: [
250
+ { name: '👀 Xem cài đặt hiện tại', value: 'show' },
251
+ { name: '🔧 Thay đổi provider', value: 'provider' }
252
+ ]
253
+ }
254
+ ]);
255
+
256
+ if (action === 'show') {
257
+ await configCommand({ show: true });
258
+ } else {
259
+ const { provider } = await inquirer.prompt([
260
+ {
261
+ type: 'list',
262
+ name: 'provider',
263
+ message: 'Chọn AI provider:',
264
+ choices: [
265
+ { name: 'Claude Code (mặc định)', value: 'claude-code' }
266
+ ]
267
+ }
268
+ ]);
269
+ await configCommand({ provider });
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Handle Init command
275
+ */
276
+ async function handleInit() {
277
+ const { initCommand } = await import('./init.js');
278
+
279
+ const { confirm } = await inquirer.prompt([
280
+ {
281
+ type: 'confirm',
282
+ name: 'confirm',
283
+ message: `Khởi tạo Vibecode workspace tại ${process.cwd()}?`,
284
+ default: true
285
+ }
286
+ ]);
287
+
288
+ if (confirm) {
289
+ await initCommand({});
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Show help text
295
+ */
296
+ function showHelp() {
297
+ console.log(chalk.white(`
298
+ 📚 VIBECODE COMMANDS
299
+
300
+ ${chalk.cyan('Workflow cơ bản:')}
301
+ vibecode init Khởi tạo workspace
302
+ vibecode start Bắt đầu intake → blueprint → contract
303
+ vibecode lock Khoá contract
304
+ vibecode plan Tạo execution plan
305
+ vibecode build Build với AI
306
+ vibecode review Kiểm tra kết quả
307
+ vibecode snapshot Tạo release
308
+
309
+ ${chalk.cyan('Power commands:')}
310
+ vibecode go "..." Một lệnh, tạo cả project
311
+ vibecode agent "..." Build project phức tạp tự động
312
+ vibecode debug Debug thông minh 9 bước
313
+ vibecode assist Trợ giúp trực tiếp từ AI
314
+
315
+ ${chalk.cyan('Khác:')}
316
+ vibecode status Xem trạng thái
317
+ vibecode config Cài đặt
318
+ vibecode doctor Kiểm tra health
319
+
320
+ 📖 Chi tiết: ${chalk.yellow('vibecode <command> --help')}
321
+ `));
322
+ }
@@ -3,7 +3,11 @@
3
3
  // Spec Hash: 0fe43335f5a325e3279a079ce616c052
4
4
  // ═══════════════════════════════════════════════════════════════════════════════
5
5
 
6
- export const VERSION = '2.0.0';
6
+ import { createRequire } from 'module';
7
+ const require = createRequire(import.meta.url);
8
+ const pkg = require('../../package.json');
9
+
10
+ export const VERSION = pkg.version;
7
11
  export const SPEC_HASH = '0fe43335f5a325e3279a079ce616c052';
8
12
 
9
13
  // ─────────────────────────────────────────────────────────────────────────────
@@ -124,11 +124,39 @@ src/
124
124
  }
125
125
 
126
126
  /**
127
- * Get contract template
127
+ * Get contract template with content extracted from intake and blueprint
128
128
  */
129
- export function getContractTemplate(projectName, sessionId) {
129
+ export function getContractTemplate(projectName, sessionId, intakeContent = '', blueprintContent = '') {
130
130
  const timestamp = new Date().toISOString();
131
131
 
132
+ // Extract goal from intake (look for "Mô tả dự án" section)
133
+ let goal = extractSection(intakeContent, '## 🎯 Mô tả dự án', '---') ||
134
+ extractSection(intakeContent, '## Mô tả dự án', '---') ||
135
+ '[Define your clear, specific goal here]';
136
+
137
+ // Extract tech stack from blueprint
138
+ let techStack = extractSection(blueprintContent, '## 💻 Tech Stack', '---') || '';
139
+
140
+ // Extract architecture from blueprint
141
+ let architecture = extractSection(blueprintContent, '## 📐 Architecture', '---') || '';
142
+
143
+ // Extract file structure from blueprint
144
+ let fileStructure = extractSection(blueprintContent, '## 📁 File Structure', '---') || '';
145
+
146
+ // Generate deliverables from goal and architecture
147
+ const deliverables = generateDeliverablesFromContent(goal, techStack, architecture);
148
+
149
+ // Generate acceptance criteria from deliverables
150
+ const acceptanceCriteria = generateAcceptanceCriteria(deliverables);
151
+
152
+ // Generate in-scope items
153
+ const inScopeItems = deliverables.map(d => `- [ ] ${d.item}`).join('\n');
154
+
155
+ // Generate deliverables table
156
+ const deliverablesTable = deliverables.map((d, i) =>
157
+ `| ${i + 1} | ${d.item} | ${d.description} | ⬜ |`
158
+ ).join('\n');
159
+
132
160
  return `# 📜 CONTRACT: ${projectName}
133
161
 
134
162
  ## Session: ${sessionId}
@@ -140,22 +168,21 @@ export function getContractTemplate(projectName, sessionId) {
140
168
 
141
169
  ## 🎯 Goal
142
170
 
143
- [Define your clear, specific goal here]
171
+ ${goal.trim()}
144
172
 
145
173
  ---
146
174
 
147
175
  ## ✅ In-Scope
148
176
 
149
- - [ ] [Deliverable 1]
150
- - [ ] [Deliverable 2]
151
- - [ ] [Deliverable 3]
177
+ ${inScopeItems || '- [ ] [Deliverable 1]\n- [ ] [Deliverable 2]\n- [ ] [Deliverable 3]'}
152
178
 
153
179
  ---
154
180
 
155
181
  ## ❌ Out-of-Scope
156
182
 
157
- - [What is NOT included]
158
- - [Explicitly excluded items]
183
+ - Features not mentioned in goal
184
+ - Additional integrations not specified
185
+ - Performance optimization beyond MVP
159
186
 
160
187
  ---
161
188
 
@@ -163,14 +190,13 @@ export function getContractTemplate(projectName, sessionId) {
163
190
 
164
191
  | # | Item | Description | Status |
165
192
  |---|------|-------------|--------|
166
- | 1 | [Item] | [Description] | ⬜ |
193
+ ${deliverablesTable || '| 1 | [Item] | [Description] | ⬜ |'}
167
194
 
168
195
  ---
169
196
 
170
197
  ## ✔️ Acceptance Criteria
171
198
 
172
- - [ ] [Criterion 1]
173
- - [ ] [Criterion 2]
199
+ ${acceptanceCriteria || '- [ ] [Criterion 1]\n- [ ] [Criterion 2]'}
174
200
 
175
201
  ---
176
202
 
@@ -178,13 +204,17 @@ export function getContractTemplate(projectName, sessionId) {
178
204
 
179
205
  | Risk | Mitigation |
180
206
  |------|------------|
181
- | [Risk] | [Mitigation] |
207
+ | Dependencies unavailable | Use alternative packages |
208
+ | Scope creep | Strict contract adherence |
182
209
 
183
210
  ---
184
211
 
185
212
  ## 🔙 Rollback Plan
186
213
 
187
- [Define rollback strategy]
214
+ If build fails:
215
+ 1. Revert to last stable commit
216
+ 2. Review contract requirements
217
+ 3. Rebuild with corrections
188
218
 
189
219
  ---
190
220
 
@@ -193,6 +223,91 @@ export function getContractTemplate(projectName, sessionId) {
193
223
  `;
194
224
  }
195
225
 
226
+ /**
227
+ * Extract a section from markdown content
228
+ */
229
+ function extractSection(content, startMarker, endMarker) {
230
+ if (!content) return null;
231
+
232
+ const startIndex = content.indexOf(startMarker);
233
+ if (startIndex === -1) return null;
234
+
235
+ const contentStart = startIndex + startMarker.length;
236
+ const endIndex = content.indexOf(endMarker, contentStart);
237
+
238
+ if (endIndex === -1) {
239
+ return content.substring(contentStart).trim();
240
+ }
241
+
242
+ return content.substring(contentStart, endIndex).trim();
243
+ }
244
+
245
+ /**
246
+ * Generate deliverables from content analysis
247
+ */
248
+ function generateDeliverablesFromContent(goal, techStack, architecture) {
249
+ const deliverables = [];
250
+
251
+ // Parse goal for keywords to generate deliverables
252
+ const goalLower = goal.toLowerCase();
253
+
254
+ // Common patterns
255
+ if (goalLower.includes('landing page') || goalLower.includes('website')) {
256
+ deliverables.push({ item: 'Landing Page', description: 'Main landing page with hero section' });
257
+ deliverables.push({ item: 'Responsive Design', description: 'Mobile-friendly layout' });
258
+ }
259
+
260
+ if (goalLower.includes('cli') || goalLower.includes('command')) {
261
+ deliverables.push({ item: 'CLI Commands', description: 'Core command implementations' });
262
+ deliverables.push({ item: 'Help System', description: 'Command help and documentation' });
263
+ }
264
+
265
+ if (goalLower.includes('api') || goalLower.includes('backend')) {
266
+ deliverables.push({ item: 'API Endpoints', description: 'REST/GraphQL endpoints' });
267
+ deliverables.push({ item: 'Data Models', description: 'Database models and schemas' });
268
+ }
269
+
270
+ if (goalLower.includes('auth') || goalLower.includes('login')) {
271
+ deliverables.push({ item: 'Authentication', description: 'User login/logout flow' });
272
+ }
273
+
274
+ if (goalLower.includes('dashboard') || goalLower.includes('admin')) {
275
+ deliverables.push({ item: 'Dashboard UI', description: 'Admin dashboard interface' });
276
+ }
277
+
278
+ // Always include core deliverables if none detected
279
+ if (deliverables.length === 0) {
280
+ deliverables.push({ item: 'Core Implementation', description: 'Main functionality as described' });
281
+ deliverables.push({ item: 'UI/UX', description: 'User interface implementation' });
282
+ deliverables.push({ item: 'Documentation', description: 'Usage documentation' });
283
+ }
284
+
285
+ // Add testing if not already included
286
+ if (!deliverables.some(d => d.item.toLowerCase().includes('test'))) {
287
+ deliverables.push({ item: 'Testing', description: 'Basic functionality tests' });
288
+ }
289
+
290
+ return deliverables;
291
+ }
292
+
293
+ /**
294
+ * Generate acceptance criteria from deliverables
295
+ */
296
+ function generateAcceptanceCriteria(deliverables) {
297
+ if (!deliverables || deliverables.length === 0) {
298
+ return '- [ ] All features work as expected\n- [ ] No console errors\n- [ ] Documentation complete';
299
+ }
300
+
301
+ const criteria = deliverables.map(d =>
302
+ `- [ ] ${d.item} is complete and functional`
303
+ );
304
+
305
+ criteria.push('- [ ] No console errors or warnings');
306
+ criteria.push('- [ ] Code is clean and documented');
307
+
308
+ return criteria.join('\n');
309
+ }
310
+
196
311
  /**
197
312
  * Get plan template
198
313
  */
@@ -260,9 +375,13 @@ ${deliverables}
260
375
  /**
261
376
  * Get coder pack template - instructions for AI coder
262
377
  */
263
- export function getCoderPackTemplate(projectName, sessionId, specHash, contractContent, blueprintContent) {
378
+ export function getCoderPackTemplate(projectName, sessionId, specHash, contractContent, blueprintContent, intakeContent = '') {
264
379
  const timestamp = new Date().toISOString();
265
380
 
381
+ // Extract the goal from intake for quick reference
382
+ const goalMatch = intakeContent.match(/## 🎯 Mô tả dự án\s*([\s\S]*?)(?=---|##|$)/);
383
+ const projectGoal = goalMatch ? goalMatch[1].trim() : 'See contract for details';
384
+
266
385
  return `# 🏗️ CODER PACK: ${projectName}
267
386
 
268
387
  ## Session: ${sessionId}
@@ -283,6 +402,12 @@ You are the **Thợ (Builder)**. Your job is to execute the locked contract exac
283
402
 
284
403
  ---
285
404
 
405
+ ## 🎯 PROJECT GOAL (Quick Reference)
406
+
407
+ ${projectGoal}
408
+
409
+ ---
410
+
286
411
  ## 📜 CONTRACT (LOCKED)
287
412
 
288
413
  ${contractContent}
@@ -291,7 +416,13 @@ ${contractContent}
291
416
 
292
417
  ## 📘 BLUEPRINT REFERENCE
293
418
 
294
- ${blueprintContent}
419
+ ${blueprintContent || '[No blueprint provided - follow contract specifications]'}
420
+
421
+ ---
422
+
423
+ ## 📥 ORIGINAL INTAKE
424
+
425
+ ${intakeContent || '[No intake provided]'}
295
426
 
296
427
  ---
297
428