@nclamvn/vibecode-cli 1.6.0 → 1.8.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 (70) hide show
  1. package/bin/vibecode.js +101 -1
  2. package/docs-site/README.md +41 -0
  3. package/docs-site/blog/2019-05-28-first-blog-post.md +12 -0
  4. package/docs-site/blog/2019-05-29-long-blog-post.md +44 -0
  5. package/docs-site/blog/2021-08-01-mdx-blog-post.mdx +24 -0
  6. package/docs-site/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
  7. package/docs-site/blog/2021-08-26-welcome/index.md +29 -0
  8. package/docs-site/blog/authors.yml +25 -0
  9. package/docs-site/blog/tags.yml +19 -0
  10. package/docs-site/docs/commands/agent.md +162 -0
  11. package/docs-site/docs/commands/assist.md +71 -0
  12. package/docs-site/docs/commands/build.md +53 -0
  13. package/docs-site/docs/commands/config.md +30 -0
  14. package/docs-site/docs/commands/debug.md +173 -0
  15. package/docs-site/docs/commands/doctor.md +34 -0
  16. package/docs-site/docs/commands/go.md +128 -0
  17. package/docs-site/docs/commands/index.md +79 -0
  18. package/docs-site/docs/commands/init.md +42 -0
  19. package/docs-site/docs/commands/learn.md +82 -0
  20. package/docs-site/docs/commands/lock.md +33 -0
  21. package/docs-site/docs/commands/plan.md +29 -0
  22. package/docs-site/docs/commands/review.md +31 -0
  23. package/docs-site/docs/commands/snapshot.md +34 -0
  24. package/docs-site/docs/commands/start.md +32 -0
  25. package/docs-site/docs/commands/status.md +37 -0
  26. package/docs-site/docs/commands/undo.md +83 -0
  27. package/docs-site/docs/configuration.md +72 -0
  28. package/docs-site/docs/faq.md +83 -0
  29. package/docs-site/docs/getting-started.md +119 -0
  30. package/docs-site/docs/guides/agent-mode.md +94 -0
  31. package/docs-site/docs/guides/debug-mode.md +83 -0
  32. package/docs-site/docs/guides/magic-mode.md +107 -0
  33. package/docs-site/docs/installation.md +98 -0
  34. package/docs-site/docs/intro.md +67 -0
  35. package/docs-site/docusaurus.config.ts +141 -0
  36. package/docs-site/package-lock.json +18039 -0
  37. package/docs-site/package.json +48 -0
  38. package/docs-site/sidebars.ts +70 -0
  39. package/docs-site/src/components/HomepageFeatures/index.tsx +72 -0
  40. package/docs-site/src/components/HomepageFeatures/styles.module.css +16 -0
  41. package/docs-site/src/css/custom.css +30 -0
  42. package/docs-site/src/pages/index.module.css +23 -0
  43. package/docs-site/src/pages/index.tsx +44 -0
  44. package/docs-site/src/pages/markdown-page.md +7 -0
  45. package/docs-site/src/theme/Footer/index.tsx +127 -0
  46. package/docs-site/src/theme/Footer/styles.module.css +285 -0
  47. package/docs-site/static/.nojekyll +0 -0
  48. package/docs-site/static/img/docusaurus-social-card.jpg +0 -0
  49. package/docs-site/static/img/docusaurus.png +0 -0
  50. package/docs-site/static/img/favicon.ico +0 -0
  51. package/docs-site/static/img/logo.svg +1 -0
  52. package/docs-site/static/img/undraw_docusaurus_mountain.svg +171 -0
  53. package/docs-site/static/img/undraw_docusaurus_react.svg +170 -0
  54. package/docs-site/static/img/undraw_docusaurus_tree.svg +40 -0
  55. package/docs-site/tsconfig.json +8 -0
  56. package/package.json +2 -1
  57. package/src/commands/ask.js +230 -0
  58. package/src/commands/debug.js +109 -1
  59. package/src/commands/docs.js +167 -0
  60. package/src/commands/git.js +1024 -0
  61. package/src/commands/migrate.js +341 -0
  62. package/src/commands/refactor.js +205 -0
  63. package/src/commands/review.js +126 -1
  64. package/src/commands/security.js +229 -0
  65. package/src/commands/shell.js +486 -0
  66. package/src/commands/test.js +194 -0
  67. package/src/commands/watch.js +556 -0
  68. package/src/debug/image-analyzer.js +304 -0
  69. package/src/index.js +27 -0
  70. package/src/utils/image.js +222 -0
@@ -0,0 +1,194 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // VIBECODE CLI - Test Command
3
+ // Phase K2: AI Test Generation
4
+ // ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ import { spawn } from 'child_process';
7
+ import fs from 'fs/promises';
8
+ import path from 'path';
9
+ import chalk from 'chalk';
10
+ import inquirer from 'inquirer';
11
+
12
+ export async function testCommand(targetPath, options = {}) {
13
+ const cwd = process.cwd();
14
+
15
+ // Generate tests
16
+ if (options.generate) {
17
+ return generateTests(cwd, targetPath, options);
18
+ }
19
+
20
+ // Run tests (pass through to npm test)
21
+ if (options.run) {
22
+ const { exec } = await import('child_process');
23
+ const child = exec('npm test', { cwd });
24
+ child.stdout?.pipe(process.stdout);
25
+ child.stderr?.pipe(process.stderr);
26
+ return new Promise(resolve => child.on('close', resolve));
27
+ }
28
+
29
+ // Coverage
30
+ if (options.coverage) {
31
+ const { exec } = await import('child_process');
32
+ const child = exec('npm run test:coverage || npm test -- --coverage', { cwd });
33
+ child.stdout?.pipe(process.stdout);
34
+ child.stderr?.pipe(process.stderr);
35
+ return new Promise(resolve => child.on('close', resolve));
36
+ }
37
+
38
+ // Default: show menu
39
+ const { action } = await inquirer.prompt([{
40
+ type: 'list',
41
+ name: 'action',
42
+ message: 'Test options:',
43
+ choices: [
44
+ { name: '🧪 Run tests (npm test)', value: 'run' },
45
+ { name: '✨ Generate tests for file/folder', value: 'generate' },
46
+ { name: '📊 Show coverage', value: 'coverage' },
47
+ { name: '👋 Exit', value: 'exit' }
48
+ ]
49
+ }]);
50
+
51
+ if (action === 'run') {
52
+ return testCommand(null, { run: true });
53
+ }
54
+ if (action === 'generate') {
55
+ const { target } = await inquirer.prompt([{
56
+ type: 'input',
57
+ name: 'target',
58
+ message: 'Path to generate tests for:',
59
+ default: 'src/'
60
+ }]);
61
+ return generateTests(cwd, target, options);
62
+ }
63
+ if (action === 'coverage') {
64
+ return testCommand(null, { coverage: true });
65
+ }
66
+ }
67
+
68
+ async function generateTests(cwd, targetPath, options) {
69
+ console.log(chalk.cyan(`
70
+ ╭────────────────────────────────────────────────────────────────────╮
71
+ │ 🧪 TEST GENERATION │
72
+ │ │
73
+ │ Target: ${(targetPath || 'src/').padEnd(52)}│
74
+ │ │
75
+ ╰────────────────────────────────────────────────────────────────────╯
76
+ `));
77
+
78
+ // Detect test framework
79
+ const framework = await detectTestFramework(cwd);
80
+ console.log(chalk.gray(` Test framework: ${framework}\n`));
81
+
82
+ // Get files to generate tests for
83
+ const files = await getFilesToTest(cwd, targetPath || 'src/');
84
+
85
+ if (files.length === 0) {
86
+ console.log(chalk.yellow(' No files found to generate tests for.\n'));
87
+ return;
88
+ }
89
+
90
+ console.log(chalk.gray(` Found ${files.length} files\n`));
91
+
92
+ const prompt = `
93
+ # Test Generation Request
94
+
95
+ ## Project: ${path.basename(cwd)}
96
+ ## Test Framework: ${framework}
97
+
98
+ ## Files to Generate Tests For:
99
+ ${files.map(f => `- ${f}`).join('\n')}
100
+
101
+ ## Instructions:
102
+ 1. Read each source file
103
+ 2. Generate comprehensive tests including:
104
+ - Unit tests for each function/method
105
+ - Edge cases (null, undefined, empty, boundary values)
106
+ - Error handling tests
107
+ - Mock external dependencies
108
+ - Integration tests where appropriate
109
+
110
+ 3. Use ${framework} syntax and conventions
111
+ 4. Follow AAA pattern (Arrange, Act, Assert)
112
+ 5. Add descriptive test names
113
+ 6. Include setup/teardown if needed
114
+
115
+ ## Output:
116
+ Create test files in __tests__/ or *.test.ts/js format.
117
+ For each source file, create corresponding test file.
118
+
119
+ Generate tests now.
120
+ `;
121
+
122
+ const promptFile = path.join(cwd, '.vibecode', 'test-gen-prompt.md');
123
+ await fs.mkdir(path.dirname(promptFile), { recursive: true });
124
+ await fs.writeFile(promptFile, prompt);
125
+
126
+ console.log(chalk.gray(' Generating tests with Claude Code...\n'));
127
+
128
+ await runClaudeCode(prompt, cwd);
129
+
130
+ console.log(chalk.green('\n✅ Tests generated!'));
131
+ console.log(chalk.gray(' Run: npm test\n'));
132
+ }
133
+
134
+ async function detectTestFramework(cwd) {
135
+ try {
136
+ const pkgPath = path.join(cwd, 'package.json');
137
+ const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf-8'));
138
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
139
+
140
+ if (deps.vitest) return 'vitest';
141
+ if (deps.jest) return 'jest';
142
+ if (deps.mocha) return 'mocha';
143
+ if (deps['@testing-library/react']) return 'jest + @testing-library/react';
144
+ if (deps.ava) return 'ava';
145
+ if (deps.tap) return 'tap';
146
+ if (deps.uvu) return 'uvu';
147
+
148
+ return 'jest'; // default
149
+ } catch {
150
+ return 'jest';
151
+ }
152
+ }
153
+
154
+ async function getFilesToTest(cwd, targetPath) {
155
+ const files = [];
156
+ const fullPath = path.join(cwd, targetPath);
157
+
158
+ async function scan(dir) {
159
+ try {
160
+ const entries = await fs.readdir(dir, { withFileTypes: true });
161
+
162
+ for (const entry of entries) {
163
+ if (entry.name.startsWith('.')) continue;
164
+ if (entry.name.includes('.test.') || entry.name.includes('.spec.')) continue;
165
+ if (entry.name === '__tests__') continue;
166
+ if (entry.name === 'node_modules') continue;
167
+ if (entry.name === 'dist' || entry.name === 'build') continue;
168
+
169
+ const entryPath = path.join(dir, entry.name);
170
+
171
+ if (entry.isDirectory()) {
172
+ await scan(entryPath);
173
+ } else if (/\.(js|ts|jsx|tsx)$/.test(entry.name)) {
174
+ files.push(path.relative(cwd, entryPath));
175
+ }
176
+ }
177
+ } catch {}
178
+ }
179
+
180
+ await scan(fullPath);
181
+ return files.slice(0, 20); // Limit
182
+ }
183
+
184
+ async function runClaudeCode(prompt, cwd) {
185
+ return new Promise((resolve) => {
186
+ const child = spawn('claude', ['-p', prompt, '--dangerously-skip-permissions'], {
187
+ cwd,
188
+ stdio: 'inherit'
189
+ });
190
+
191
+ child.on('close', resolve);
192
+ child.on('error', () => resolve());
193
+ });
194
+ }