vibecodingmachine-cli 2026.3.10-1812 → 2026.3.14-1528

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 (36) hide show
  1. package/README.md +85 -85
  2. package/bin/vibecodingmachine.js +3 -0
  3. package/package.json +4 -3
  4. package/scripts/postinstall.js +161 -161
  5. package/src/commands/auth.js +100 -100
  6. package/src/commands/auto-direct.js +16 -5
  7. package/src/commands/auto-execution.js +25 -0
  8. package/src/commands/auto-requirement-management.js +8 -8
  9. package/src/commands/auto-status-helpers.js +5 -3
  10. package/src/commands/computers.js +318 -318
  11. package/src/commands/feature.js +123 -123
  12. package/src/commands/locale.js +72 -72
  13. package/src/commands/repo.js +163 -163
  14. package/src/commands/setup.js +93 -93
  15. package/src/commands/sync.js +287 -287
  16. package/src/index.js +5 -5
  17. package/src/utils/agent-selector.js +50 -50
  18. package/src/utils/asset-cleanup.js +60 -60
  19. package/src/utils/auto-mode-ansi-ui.js +237 -237
  20. package/src/utils/auto-mode-simple-ui.js +141 -141
  21. package/src/utils/copy-with-progress.js +167 -167
  22. package/src/utils/download-with-progress.js +84 -84
  23. package/src/utils/keyboard-handler.js +153 -153
  24. package/src/utils/kiro-installer.js +178 -178
  25. package/src/utils/logger.js +4 -4
  26. package/src/utils/persistent-header.js +114 -114
  27. package/src/utils/prompt-helper.js +63 -63
  28. package/src/utils/provider-checker/agent-checker.js +25 -1
  29. package/src/utils/provider-checker/agent-runner.js +115 -37
  30. package/src/utils/provider-checker/agents-manager.js +210 -0
  31. package/src/utils/provider-checker/provider-validator.js +5 -49
  32. package/src/utils/provider-checker/requirements-manager.js +86 -65
  33. package/src/utils/provider-checker/test-requirements.js +25 -17
  34. package/src/utils/status-card.js +121 -121
  35. package/src/utils/stdout-interceptor.js +127 -127
  36. package/src/utils/user-tracking.js +299 -299
@@ -1,100 +1,100 @@
1
- const chalk = require('chalk');
2
- const auth = require('../utils/auth');
3
- const { t, errorReporter } = require('vibecodingmachine-core');
4
-
5
- /**
6
- * Login command
7
- * @param {Object} options - Command options
8
- * @param {boolean} options.headless - Force headless mode (manual URL paste)
9
- */
10
- async function login(options = {}) {
11
- try {
12
- // Check if already authenticated
13
- const isAuth = await auth.isAuthenticated();
14
- if (isAuth) {
15
- const profile = await auth.getUserProfile();
16
- console.log(chalk.green(`\nāœ“ ${t('auth.login.already', { email: chalk.bold(profile.email) })}`));
17
- return;
18
- }
19
-
20
- // Start login flow (auto-detects headless or use explicit flag)
21
- const result = await auth.login({ headless: options.headless });
22
-
23
- // After successful authentication, start interactive mode
24
- if (result) {
25
- console.log(chalk.cyan(`\nšŸš€ ${t('auth.starting.interactive')}\n`));
26
- const { startInteractive } = require('../utils/interactive');
27
- await startInteractive();
28
- }
29
- } catch (error) {
30
- console.error(chalk.red(`\nāœ— ${t('auth.login.failed')}:`), error.message);
31
- await errorReporter.reportError(error, {
32
- command: 'auth:login',
33
- headless: options.headless
34
- });
35
- process.exit(1);
36
- }
37
- }
38
-
39
- /**
40
- * Logout command
41
- */
42
- async function logout() {
43
- try {
44
- await auth.logout();
45
- console.log(chalk.green(`\nāœ“ ${t('auth.logout.success')}`));
46
- } catch (error) {
47
- console.error(chalk.red(`\nāœ— ${t('auth.logout.failed')}:`), error.message);
48
- process.exit(1);
49
- }
50
- }
51
-
52
- /**
53
- * Status command
54
- */
55
- async function status() {
56
- try {
57
- const isAuth = await auth.isAuthenticated();
58
-
59
- if (!isAuth) {
60
- console.log(chalk.yellow(`\n${t('auth.not.authenticated')}`));
61
- console.log(t('auth.run.login', { command: chalk.cyan('vcm auth:login') }));
62
- return;
63
- }
64
-
65
- const profile = await auth.getUserProfile();
66
-
67
- // Get usage stats
68
- const canRun = await auth.canRunAutoMode();
69
-
70
- console.log(chalk.bold(`\nšŸ‘¤ ${t('profile.name')}:`));
71
- console.log(` ${t('profile.name')}: ${profile.name}`);
72
- console.log(` ${t('profile.email')}: ${profile.email}`);
73
- console.log(` ${t('profile.tier')}: ${profile.tier === 'premium' ? chalk.green(t('profile.tier.premium')) : t('profile.tier.free')}`);
74
-
75
- console.log(chalk.bold(`\nšŸ“Š ${t('profile.usage')}:`));
76
- if (canRun.features && canRun.features.unlimitedIterations) {
77
- console.log(` ${t('profile.daily.usage')}: ${canRun.todayUsage} ${t('profile.iterations')}`);
78
- console.log(` ${t('profile.limit')}: ${chalk.green(t('profile.unlimited'))}`);
79
- } else {
80
- const limitColor = canRun.todayUsage >= canRun.maxIterations ? chalk.red : chalk.green;
81
- console.log(` ${t('profile.daily.usage')}: ${limitColor(`${canRun.todayUsage}/${canRun.maxIterations}`)} ${t('profile.iterations')}`);
82
- }
83
-
84
- if (!canRun.canRun) {
85
- console.log(chalk.red(`\nāš ļø ${t('quota.exceeded.warning', { reason: canRun.reason })}`));
86
- if (profile.tier !== 'premium') {
87
- console.log(chalk.gray(t('profile.upgrade.suggestion')));
88
- }
89
- }
90
-
91
- } catch (error) {
92
- console.error(chalk.red(`\nāœ— ${t('status.check.failed')}:`), error.message);
93
- }
94
- }
95
-
96
- module.exports = {
97
- login,
98
- logout,
99
- status
100
- };
1
+ const chalk = require('chalk');
2
+ const auth = require('../utils/auth');
3
+ const { t, errorReporter } = require('vibecodingmachine-core');
4
+
5
+ /**
6
+ * Login command
7
+ * @param {Object} options - Command options
8
+ * @param {boolean} options.headless - Force headless mode (manual URL paste)
9
+ */
10
+ async function login(options = {}) {
11
+ try {
12
+ // Check if already authenticated
13
+ const isAuth = await auth.isAuthenticated();
14
+ if (isAuth) {
15
+ const profile = await auth.getUserProfile();
16
+ console.log(chalk.green(`\nāœ“ ${t('auth.login.already', { email: chalk.bold(profile.email) })}`));
17
+ return;
18
+ }
19
+
20
+ // Start login flow (auto-detects headless or use explicit flag)
21
+ const result = await auth.login({ headless: options.headless });
22
+
23
+ // After successful authentication, start interactive mode
24
+ if (result) {
25
+ console.log(chalk.cyan(`\nšŸš€ ${t('auth.starting.interactive')}\n`));
26
+ const { startInteractive } = require('../utils/interactive');
27
+ await startInteractive();
28
+ }
29
+ } catch (error) {
30
+ console.error(chalk.red(`\nāœ— ${t('auth.login.failed')}:`), error.message);
31
+ await errorReporter.reportError(error, {
32
+ command: 'auth:login',
33
+ headless: options.headless
34
+ });
35
+ process.exit(1);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Logout command
41
+ */
42
+ async function logout() {
43
+ try {
44
+ await auth.logout();
45
+ console.log(chalk.green(`\nāœ“ ${t('auth.logout.success')}`));
46
+ } catch (error) {
47
+ console.error(chalk.red(`\nāœ— ${t('auth.logout.failed')}:`), error.message);
48
+ process.exit(1);
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Status command
54
+ */
55
+ async function status() {
56
+ try {
57
+ const isAuth = await auth.isAuthenticated();
58
+
59
+ if (!isAuth) {
60
+ console.log(chalk.yellow(`\n${t('auth.not.authenticated')}`));
61
+ console.log(t('auth.run.login', { command: chalk.cyan('vcm auth:login') }));
62
+ return;
63
+ }
64
+
65
+ const profile = await auth.getUserProfile();
66
+
67
+ // Get usage stats
68
+ const canRun = await auth.canRunAutoMode();
69
+
70
+ console.log(chalk.bold(`\nšŸ‘¤ ${t('profile.name')}:`));
71
+ console.log(` ${t('profile.name')}: ${profile.name}`);
72
+ console.log(` ${t('profile.email')}: ${profile.email}`);
73
+ console.log(` ${t('profile.tier')}: ${profile.tier === 'premium' ? chalk.green(t('profile.tier.premium')) : t('profile.tier.free')}`);
74
+
75
+ console.log(chalk.bold(`\nšŸ“Š ${t('profile.usage')}:`));
76
+ if (canRun.features && canRun.features.unlimitedIterations) {
77
+ console.log(` ${t('profile.daily.usage')}: ${canRun.todayUsage} ${t('profile.iterations')}`);
78
+ console.log(` ${t('profile.limit')}: ${chalk.green(t('profile.unlimited'))}`);
79
+ } else {
80
+ const limitColor = canRun.todayUsage >= canRun.maxIterations ? chalk.red : chalk.green;
81
+ console.log(` ${t('profile.daily.usage')}: ${limitColor(`${canRun.todayUsage}/${canRun.maxIterations}`)} ${t('profile.iterations')}`);
82
+ }
83
+
84
+ if (!canRun.canRun) {
85
+ console.log(chalk.red(`\nāš ļø ${t('quota.exceeded.warning', { reason: canRun.reason })}`));
86
+ if (profile.tier !== 'premium') {
87
+ console.log(chalk.gray(t('profile.upgrade.suggestion')));
88
+ }
89
+ }
90
+
91
+ } catch (error) {
92
+ console.error(chalk.red(`\nāœ— ${t('status.check.failed')}:`), error.message);
93
+ }
94
+ }
95
+
96
+ module.exports = {
97
+ login,
98
+ logout,
99
+ status
100
+ };
@@ -2771,14 +2771,25 @@ async function runSpecIdeIteration(spec, taskText, taskLine, providerConfig) {
2771
2771
  instruction = `Read AGENTS.md and INSTRUCTIONS.md in the repo root for workflow guidelines. Read ${spec.path}/spec.md. ${planPromptNote}Run speckit workflow: (1) read spec.md, (2) generate plan.md, (3) generate tasks.md, (4) implement all tasks. Check off each task as you complete it. Report progress as "X/Y tasks (Z%) complete" after each task. When ALL tasks are done, create a status file at ${spec.path}/.vcm-status.json with content {"completion": 100, "status": "WAITING"} to signal completion to VCM.`;
2772
2772
  }
2773
2773
 
2774
- // Send the spec instruction to the IDE via AppleScript.
2775
- // Uses the shared AppleScriptManager with detached execution for proper timing.
2774
+ // Send the spec instruction to the IDE via platform-specific automation.
2775
+ // Uses the appropriate automation manager for the current platform.
2776
2776
  console.log(chalk.cyan(`šŸ“¤ Sending spec instruction to ${providerConfig.displayName}...\n`));
2777
2777
 
2778
2778
  if (ideType === 'windsurf') {
2779
2779
  try {
2780
- const appleScriptManager = new AppleScriptManager();
2781
- const sendResult = await appleScriptManager.sendText(instruction, 'windsurf');
2780
+ let sendResult;
2781
+
2782
+ // Use platform-specific automation
2783
+ if (process.platform === 'win32') {
2784
+ // Use Windows automation on Windows
2785
+ const { WindowsAutomationManager } = require('vibecodingmachine-core');
2786
+ const windowsManager = new WindowsAutomationManager();
2787
+ sendResult = await windowsManager.sendTextToWindsurf(instruction);
2788
+ } else {
2789
+ // Use AppleScript on macOS
2790
+ const appleScriptManager = new AppleScriptManager();
2791
+ sendResult = await appleScriptManager.sendText(instruction, 'windsurf');
2792
+ }
2782
2793
 
2783
2794
  if (sendResult && sendResult.success) {
2784
2795
  console.log(chalk.green(`āœ“ Spec instruction sent to ${providerConfig.displayName}`));
@@ -2789,7 +2800,7 @@ async function runSpecIdeIteration(spec, taskText, taskLine, providerConfig) {
2789
2800
  return { success: false, error: sendResult?.error || 'Unknown error' };
2790
2801
  }
2791
2802
  } catch (err) {
2792
- console.log(chalk.red(`āœ— AppleScript error: ${err.message}`));
2803
+ console.log(chalk.red(`āœ— Automation error: ${err.message}`));
2793
2804
  return { success: false, error: err.message };
2794
2805
  }
2795
2806
  } else {
@@ -307,10 +307,29 @@ async function executeCreateStage(repoPath, currentTitle) {
307
307
  }
308
308
 
309
309
  // Send to IDE using Windows automation
310
+ console.log(chalk.cyan('šŸ“ Text being sent to IDE:'));
311
+ console.log(chalk.gray('='.repeat(60)));
312
+ console.log(requirementText.trim());
313
+ console.log(chalk.gray('='.repeat(60)));
314
+
310
315
  try {
311
316
  const { WindowsAutomationManager } = require('vibecodingmachine-core');
312
317
  const manager = new WindowsAutomationManager();
313
318
  const result = await manager.sendTextToWindsurf(requirementText.trim());
319
+
320
+ // Check for rate limit
321
+ if (result.rateLimited) {
322
+ console.log(chalk.yellow(`āš ļø Rate limit detected!`));
323
+ console.log(chalk.yellow(`ā° Cascade will reset in: ${result.resetTime}`));
324
+ console.log(chalk.yellow(`šŸ’” Please wait and try again after the rate limit resets.`));
325
+ return {
326
+ success: false,
327
+ rateLimited: true,
328
+ resetTime: result.resetTime,
329
+ error: `Windsurf Cascade rate limit reached. Resets in: ${result.resetTime}`
330
+ };
331
+ }
332
+
314
333
  console.log(chalk.green(`āœ… Sent to IDE: ${result.success ? 'success' : 'failed'}`));
315
334
  } catch (error) {
316
335
  console.error(chalk.red(`āŒ Failed to send to IDE: ${error.message}`));
@@ -318,6 +337,12 @@ async function executeCreateStage(repoPath, currentTitle) {
318
337
 
319
338
  // Give IDE time to process
320
339
  await new Promise(resolve => setTimeout(resolve, 5000));
340
+
341
+ // CRITICAL: In IDE check mode, DO NOT auto-progress to CLEAN_UP
342
+ // We must wait for manual [DONE] detection from the IDE agent
343
+ console.log(chalk.blue('ā³ Waiting for IDE to update status to [DONE]...'));
344
+ console.log(chalk.gray(' The agent-runner will watch for status changes'));
345
+ return { success: true, stopAutoProgression: true };
321
346
  } else {
322
347
  // This would integrate with the AI provider to implement the requirement
323
348
  // For now, we'll simulate the implementation
@@ -65,29 +65,29 @@ async function getCurrentRequirementDetails(repoPath) {
65
65
  const content = await fs.readFile(reqPath, 'utf8');
66
66
  const lines = content.split('\n');
67
67
 
68
- // Find the "ā³ Requirements not yet completed" section (first item is current in-progress)
69
- let pendingSectionIndex = -1;
68
+ // Find the "## Requirements" section (first item is current in-progress)
69
+ let requirementsSectionIndex = -1;
70
70
  for (let i = 0; i < lines.length; i++) {
71
- if (lines[i].includes('ā³ Requirements not yet completed')) {
72
- pendingSectionIndex = i;
71
+ if (lines[i].includes('## Requirements')) {
72
+ requirementsSectionIndex = i;
73
73
  break;
74
74
  }
75
75
  }
76
76
 
77
- if (pendingSectionIndex === -1) {
77
+ if (requirementsSectionIndex === -1) {
78
78
  return { title: 'No current requirement found', status: 'UNKNOWN' };
79
79
  }
80
80
 
81
81
  // Look for the first requirement after the section header (current in-progress item)
82
- for (let i = pendingSectionIndex + 1; i < lines.length; i++) {
82
+ for (let i = requirementsSectionIndex + 1; i < lines.length; i++) {
83
83
  const line = lines[i].trim();
84
84
  if (line.startsWith('- ')) {
85
85
  const title = line.substring(2).trim();
86
86
 
87
- // Look for status in the next few lines
87
+ // Look for status in the next few lines (supports both formats)
88
88
  let status = 'UNKNOWN';
89
89
  for (let j = i + 1; j < Math.min(i + 10, lines.length); j++) {
90
- if (lines[j].includes('🚦 Current Status')) {
90
+ if (lines[j].includes('🚦 Status:') || lines[j].includes('🚦 Current Status:')) {
91
91
  const statusMatch = lines[j].match(/\[([A-Z_]+)\]/);
92
92
  if (statusMatch) {
93
93
  status = statusMatch[1];
@@ -80,11 +80,13 @@ async function updateRequirementsStatus(repoPath, newStatus, responseText) {
80
80
  let content = await fs.readFile(reqPath, 'utf8');
81
81
  const lines = content.split('\n');
82
82
 
83
- // Find the status line and update it
83
+ // Find the status line and update it (supports both old and new formats)
84
84
  let statusUpdated = false;
85
85
  for (let i = 0; i < lines.length; i++) {
86
- if (lines[i].includes('🚦 Current Status')) {
87
- lines[i] = `🚦 Current Status: [${newStatus}]`;
86
+ if (lines[i].includes('🚦 Status:') || lines[i].includes('🚦 Current Status:')) {
87
+ // Use the same format that was found
88
+ const prefix = lines[i].includes('🚦 Status:') ? '🚦 Status:' : '🚦 Current Status:';
89
+ lines[i] = `${prefix} [${newStatus}]`;
88
90
  statusUpdated = true;
89
91
  break;
90
92
  }