vibecodingmachine-cli 2026.3.14-1537 → 2026.6.17-1956

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 (162) hide show
  1. package/bin/auth/auth-compliance.js +7 -7
  2. package/bin/commands/agent-commands.js +15 -15
  3. package/bin/commands/auto-commands.js +3 -3
  4. package/bin/commands/command-aliases.js +13 -4
  5. package/bin/config/cli-config.js +15 -5
  6. package/bin/update/update-checker.js +5 -5
  7. package/bin/vibecodingmachine.js +2 -2
  8. package/package.json +2 -2
  9. package/src/commands/agents/add.js +5 -5
  10. package/src/commands/agents/check.js +19 -19
  11. package/src/commands/agents/list.js +24 -24
  12. package/src/commands/agents/remove.js +4 -4
  13. package/src/commands/agents-check.js +1 -1
  14. package/src/commands/analyze-file-sizes.js +43 -43
  15. package/src/commands/auto-direct/auto-provider-manager.js +19 -19
  16. package/src/commands/auto-direct/auto-start-phases.js +493 -0
  17. package/src/commands/auto-direct/auto-status-display.js +35 -35
  18. package/src/commands/auto-direct/auto-utils.js +50 -50
  19. package/src/commands/auto-direct/cline-installer.js +56 -0
  20. package/src/commands/auto-direct/code-processor.js +27 -27
  21. package/src/commands/auto-direct/file-scanner.js +19 -19
  22. package/src/commands/auto-direct/ide-completion-waiter.js +485 -0
  23. package/src/commands/auto-direct/ide-fallback-runner.js +226 -0
  24. package/src/commands/auto-direct/ide-provider-runner.js +103 -0
  25. package/src/commands/auto-direct/iteration-handlers.js +189 -0
  26. package/src/commands/auto-direct/iteration-runner.js +485 -0
  27. package/src/commands/auto-direct/provider-config.js +38 -7
  28. package/src/commands/auto-direct/provider-manager.js +132 -6
  29. package/src/commands/auto-direct/requirement-manager.js +169 -104
  30. package/src/commands/auto-direct/requirement-mover.js +350 -0
  31. package/src/commands/auto-direct/spec-handlers.js +155 -0
  32. package/src/commands/auto-direct/spec-ide-runner.js +318 -0
  33. package/src/commands/auto-direct/spec-processing.js +203 -0
  34. package/src/commands/auto-direct/status-display.js +9 -9
  35. package/src/commands/auto-direct/utils.js +83 -1
  36. package/src/commands/auto-direct-refactored.js +1 -413
  37. package/src/commands/auto-direct.js +127 -4119
  38. package/src/commands/auto-execution.js +21 -21
  39. package/src/commands/auto-status-helpers.js +0 -2
  40. package/src/commands/auto.js +22 -22
  41. package/src/commands/check-compliance.js +65 -65
  42. package/src/commands/computers.js +39 -39
  43. package/src/commands/continuous-scan.js +19 -19
  44. package/src/commands/ide.js +4 -4
  45. package/src/commands/locale.js +7 -7
  46. package/src/commands/refactor-file.js +59 -59
  47. package/src/commands/requirements/commands.js +17 -17
  48. package/src/commands/requirements/default-handlers.js +30 -30
  49. package/src/commands/requirements/disable.js +3 -3
  50. package/src/commands/requirements/enable.js +3 -3
  51. package/src/commands/requirements/utils.js +6 -6
  52. package/src/commands/requirements-refactored.js +3 -3
  53. package/src/commands/requirements-remote.js +38 -38
  54. package/src/commands/requirements.js +3 -3
  55. package/src/commands/settings.js +111 -0
  56. package/src/commands/specs/count.js +60 -0
  57. package/src/commands/specs/disable.js +3 -3
  58. package/src/commands/specs/enable.js +3 -3
  59. package/src/commands/status.js +10 -10
  60. package/src/commands/sync.js +25 -25
  61. package/src/commands/timeout.js +35 -35
  62. package/src/trui/TruiInterface.js +2 -2
  63. package/src/trui/agents/AgentInterface.js +4 -4
  64. package/src/trui/agents/handlers/CommandHandler.js +4 -4
  65. package/src/trui/agents/handlers/ContextManager.js +1 -1
  66. package/src/trui/agents/handlers/DisplayHandler.js +11 -11
  67. package/src/trui/agents/handlers/HelpHandler.js +1 -1
  68. package/src/utils/agent-selector.js +6 -6
  69. package/src/utils/antigravity-installer.js +4 -4
  70. package/src/utils/asset-cleanup.js +1 -1
  71. package/src/utils/auth.js +9 -12
  72. package/src/utils/clarification-actions.js +4 -4
  73. package/src/utils/cline-js-handler.js +5 -5
  74. package/src/utils/compliance-check.js +6 -6
  75. package/src/utils/config.js +12 -12
  76. package/src/utils/display-formatters-complete.js +2 -2
  77. package/src/utils/display-formatters-extracted.js +2 -2
  78. package/src/utils/display-formatters.js +2 -2
  79. package/src/utils/feedback-handler.js +2 -2
  80. package/src/utils/first-run.js +7 -7
  81. package/src/utils/ide-detection.js +1 -1
  82. package/src/utils/ide-handlers.js +6 -6
  83. package/src/utils/interactive/clarification-actions.js +3 -3
  84. package/src/utils/interactive/core-ui.js +7 -7
  85. package/src/utils/interactive/file-backup.js +6 -6
  86. package/src/utils/interactive/file-import-export.js +49 -49
  87. package/src/utils/interactive/file-operations.js +3 -3
  88. package/src/utils/interactive/file-validation.js +41 -41
  89. package/src/utils/interactive/interactive-prompts.js +41 -41
  90. package/src/utils/interactive/requirement-actions.js +5 -5
  91. package/src/utils/interactive/requirement-crud.js +4 -4
  92. package/src/utils/interactive/requirements-navigation.js +10 -10
  93. package/src/utils/interactive-broken.js +6 -6
  94. package/src/utils/interactive.js +37 -37
  95. package/src/utils/keyboard-handler.js +4 -4
  96. package/src/utils/prompt-helper.js +6 -6
  97. package/src/utils/provider-checker/agent-checker.js +1 -1
  98. package/src/utils/provider-checker/agent-runner.js +203 -314
  99. package/src/utils/provider-checker/agents-file-lock.js +134 -0
  100. package/src/utils/provider-checker/agents-manager.js +224 -36
  101. package/src/utils/provider-checker/cli-installer.js +28 -28
  102. package/src/utils/provider-checker/cli-utils.js +2 -2
  103. package/src/utils/provider-checker/cursor-approval-clicker.js +108 -0
  104. package/src/utils/provider-checker/format-utils.js +4 -4
  105. package/src/utils/provider-checker/ide-installer-helper.js +96 -0
  106. package/src/utils/provider-checker/ide-manager.js +19 -8
  107. package/src/utils/provider-checker/ide-quota-checker.js +120 -0
  108. package/src/utils/provider-checker/ide-utils.js +2 -2
  109. package/src/utils/provider-checker/node-detector.js +4 -4
  110. package/src/utils/provider-checker/node-utils.js +5 -5
  111. package/src/utils/provider-checker/opencode-checker.js +107 -73
  112. package/src/utils/provider-checker/process-utils.js +1 -1
  113. package/src/utils/provider-checker/provider-validator.js +11 -11
  114. package/src/utils/provider-checker/quota-checker.js +5 -5
  115. package/src/utils/provider-checker/quota-detector.js +5 -5
  116. package/src/utils/provider-checker/requirements-manager.js +6 -6
  117. package/src/utils/provider-checker/test-requirements.js +1 -1
  118. package/src/utils/provider-checker/vscode-approval-clicker.js +328 -0
  119. package/src/utils/provider-checker-new.js +6 -6
  120. package/src/utils/provider-checker.js +6 -6
  121. package/src/utils/provider-checkers/ide-manager.js +13 -13
  122. package/src/utils/provider-checkers/node-executable-finder.js +4 -4
  123. package/src/utils/provider-checkers/provider-checker-core.js +5 -5
  124. package/src/utils/provider-checkers/provider-checker-main.js +17 -17
  125. package/src/utils/provider-registry.js +5 -6
  126. package/src/utils/provider-utils.js +12 -12
  127. package/src/utils/quota-detectors.js +32 -32
  128. package/src/utils/requirement-action-handlers.js +12 -12
  129. package/src/utils/requirement-actions/requirement-operations.js +3 -3
  130. package/src/utils/requirement-actions.js +1 -1
  131. package/src/utils/requirement-file-operations.js +5 -5
  132. package/src/utils/requirement-helpers.js +1 -1
  133. package/src/utils/requirement-management.js +5 -5
  134. package/src/utils/requirement-navigation.js +2 -2
  135. package/src/utils/requirement-organization.js +3 -3
  136. package/src/utils/rui-trui-adapter.js +14 -14
  137. package/src/utils/simple-trui.js +3 -3
  138. package/src/utils/status-helpers-extracted.js +3 -3
  139. package/src/utils/trui-clarifications.js +11 -11
  140. package/src/utils/trui-debug.js +3 -2
  141. package/src/utils/trui-devin.js +217 -0
  142. package/src/utils/trui-feedback.js +7 -7
  143. package/src/utils/trui-kiro-integration.js +34 -34
  144. package/src/utils/trui-main-handlers.js +20 -21
  145. package/src/utils/trui-main-menu.js +19 -19
  146. package/src/utils/trui-nav-agents.js +59 -8
  147. package/src/utils/trui-nav-requirements.js +3 -3
  148. package/src/utils/trui-nav-settings.js +10 -10
  149. package/src/utils/trui-nav-specifications.js +1 -1
  150. package/src/utils/trui-navigation-backup.js +11 -11
  151. package/src/utils/trui-navigation.js +9 -9
  152. package/src/utils/trui-provider-health.js +25 -25
  153. package/src/utils/trui-provider-manager.js +28 -28
  154. package/src/utils/trui-quick-menu.js +2 -2
  155. package/src/utils/trui-req-actions-backup.js +21 -21
  156. package/src/utils/trui-req-actions.js +20 -20
  157. package/src/utils/trui-req-editor.js +10 -10
  158. package/src/utils/trui-req-file-ops.js +3 -3
  159. package/src/utils/trui-req-tree.js +7 -7
  160. package/src/utils/trui-windsurf.js +103 -103
  161. package/src/utils/user-tracking.js +15 -15
  162. package/src/utils/trui-req-tree-old.js +0 -719
@@ -0,0 +1,108 @@
1
+ 'use strict';
2
+
3
+ const { spawn } = require('child_process');
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+
7
+ /**
8
+ * Periodically clicks the Run/Allow button in Cursor's agentic composer.
9
+ * Cursor shows a confirmation dialog for terminal commands; this auto-approves it.
10
+ *
11
+ * Returns a cleanup function that stops the interval.
12
+ */
13
+ function startCursorApprovalClicker(resolvedRef) {
14
+ let cursorApprovalAttempt = 0;
15
+ let cursorApprovalInterval;
16
+
17
+ const clickCursorRun = () => {
18
+ if (resolvedRef.resolved) { clearInterval(cursorApprovalInterval); return; }
19
+ cursorApprovalAttempt++;
20
+ console.log(`[AGENT CHECK] Cursor: clicking Run button (attempt ${cursorApprovalAttempt})`);
21
+ const approveScript = `
22
+ tell application "Cursor" to activate
23
+ delay 0.4
24
+ tell application "System Events"
25
+ tell process "Cursor"
26
+ set btnNames to {"Yes, allow", "Yes", "Run", "Allow", "Accept", "Continue"}
27
+ -- Check all windows (dialog may be window 2+)
28
+ set windowCount to count of windows
29
+ repeat with w from 1 to windowCount
30
+ -- Check buttons directly in window
31
+ try
32
+ set winBtns to buttons of window w
33
+ repeat with btn in winBtns
34
+ try
35
+ set btnName to name of btn
36
+ repeat with bName in btnNames
37
+ if btnName contains bName then
38
+ click btn
39
+ return "clicked " & btnName & " in window " & w
40
+ end if
41
+ end repeat
42
+ end try
43
+ end repeat
44
+ end try
45
+ -- Check groups in window
46
+ try
47
+ set allGroups to groups of window w
48
+ repeat with grp in allGroups
49
+ try
50
+ set grpBtns to buttons of grp
51
+ repeat with btn in grpBtns
52
+ try
53
+ set btnName to name of btn
54
+ repeat with bName in btnNames
55
+ if btnName contains bName then
56
+ click btn
57
+ return "clicked " & btnName & " in group"
58
+ end if
59
+ end repeat
60
+ end try
61
+ end repeat
62
+ end try
63
+ end repeat
64
+ end try
65
+ -- Check sheets (modal dialogs)
66
+ try
67
+ set sheetList to sheets of window w
68
+ repeat with s in sheetList
69
+ try
70
+ set sheetBtns to buttons of s
71
+ repeat with btn in sheetBtns
72
+ try
73
+ set btnName to name of btn
74
+ repeat with bName in btnNames
75
+ if btnName contains bName then
76
+ click btn
77
+ return "clicked " & btnName & " in sheet"
78
+ end if
79
+ end repeat
80
+ end try
81
+ end repeat
82
+ end try
83
+ end repeat
84
+ end try
85
+ end repeat
86
+ -- Fallback: try pressing Enter (default button in dialog)
87
+ key code 36
88
+ return "pressed Enter as fallback"
89
+ end tell
90
+ end tell
91
+ `;
92
+ const tmpFile = os.tmpdir() + '/cursor_approve.scpt';
93
+ fs.writeFileSync(tmpFile, approveScript);
94
+ const approveChild = spawn('osascript', [tmpFile], { detached: true, stdio: 'ignore' });
95
+ approveChild.unref();
96
+ };
97
+
98
+ setTimeout(() => {
99
+ if (!resolvedRef.resolved) {
100
+ clickCursorRun();
101
+ cursorApprovalInterval = setInterval(clickCursorRun, 10000);
102
+ }
103
+ }, 20000);
104
+
105
+ return () => clearInterval(cursorApprovalInterval);
106
+ }
107
+
108
+ module.exports = { startCursorApprovalClicker };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Format Utilities Module
3
- *
3
+ *
4
4
  * Contains formatting utilities for dates and other data.
5
5
  */
6
6
 
@@ -12,18 +12,18 @@ function formatCheckedAt(checkedAt) {
12
12
  if (!checkedAt) return '';
13
13
  const d = new Date(checkedAt);
14
14
  if (isNaN(d.getTime())) return checkedAt;
15
-
15
+
16
16
  const months = [
17
17
  'January', 'February', 'March', 'April', 'May', 'June',
18
18
  'July', 'August', 'September', 'October', 'November', 'December'
19
19
  ];
20
-
20
+
21
21
  const hours = d.getHours();
22
22
  const ampm = hours >= 12 ? 'pm' : 'am';
23
23
  const hour12 = hours % 12 || 12;
24
24
  const minutes = d.getMinutes().toString().padStart(2, '0');
25
25
  const timePart = `${hour12}:${minutes} ${ampm}`;
26
-
26
+
27
27
  return `${months[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()} at ${timePart}`;
28
28
  }
29
29
 
@@ -0,0 +1,96 @@
1
+ 'use strict';
2
+
3
+ const { isIDERunning, openIDEApp } = require('./ide-manager');
4
+
5
+ /**
6
+ * Ensure the IDE is launched/installed before running a connectivity check.
7
+ * Returns { ideLaunchNote, error } — if error is set, the caller should return it immediately.
8
+ */
9
+ async function ensureIDEReady(providerId, def, repoPath, info, onProgress) {
10
+ let ideLaunchNote = '';
11
+
12
+ if (process.platform === 'darwin' && info.app) {
13
+ const launchSuccess = await openIDEApp(info.app, repoPath);
14
+ if (launchSuccess) {
15
+ ideLaunchNote = ` (VCM launched ${info.app})`;
16
+ } else {
17
+ const { IDEInstaller } = require('../../../../electron-app/src/main/ide-installer');
18
+ const installer = new IDEInstaller();
19
+ const ideKey = def.ide || providerId;
20
+ const checkResult = await installer.checkIDEInstallation(ideKey);
21
+ if (!checkResult.installed) {
22
+ return {
23
+ ideLaunchNote,
24
+ error: `${info.app} is not installed. Please download from ${IDEInstaller.IDE_CONFIG[ideKey]?.downloadBrowserUrl || 'its official website'}`
25
+ };
26
+ }
27
+ }
28
+ } else if (process.platform === 'win32') {
29
+ const result = await _ensureIDEReadyWindows(providerId, def, repoPath, info, onProgress);
30
+ ideLaunchNote = result.ideLaunchNote;
31
+ if (result.error) return result;
32
+ }
33
+
34
+ return { ideLaunchNote, error: null };
35
+ }
36
+
37
+ async function _ensureIDEReadyWindows(providerId, def, repoPath, info, onProgress) {
38
+ const { IDEInstaller } = require('../../../../electron-app/src/main/ide-installer');
39
+ const installer = new IDEInstaller();
40
+ const ideKey = def.ide || providerId;
41
+ const ideConfig = IDEInstaller.IDE_CONFIG[ideKey];
42
+ let ideLaunchNote = '';
43
+
44
+ let checkResult = await installer.checkIDEInstallation(ideKey);
45
+
46
+ if (!checkResult.installed) {
47
+ const downloadUrl = ideConfig?.downloadUrl?.[process.platform];
48
+ if (downloadUrl) {
49
+ console.log(`[AGENT CHECK] ${info.app || ideKey} not installed, installing...`);
50
+ if (onProgress) onProgress(providerId, 'installing');
51
+ try {
52
+ const installResult = await installer.installIDE(ideKey, (progress) => {
53
+ console.log(`[AGENT CHECK] Installation progress for ${ideKey}: ${progress.progress}% - ${progress.message}`);
54
+ });
55
+ if (!installResult || !installResult.success) {
56
+ return {
57
+ ideLaunchNote,
58
+ error: `Failed to install ${info.app || ideKey}: ${installResult?.error || 'Installation failed'}. Please install manually and try again.`
59
+ };
60
+ }
61
+ console.log(`[AGENT CHECK] ${info.app || ideKey} installed successfully`);
62
+ ideLaunchNote = ` (VCM installed ${info.app || ideKey})`;
63
+ await new Promise(r => setTimeout(r, 3000));
64
+ checkResult = await installer.checkIDEInstallation(ideKey);
65
+ } catch (installError) {
66
+ return {
67
+ ideLaunchNote,
68
+ error: `Installation failed for ${info.app || ideKey}: ${installError.message}. Please install manually and try again.`
69
+ };
70
+ }
71
+ } else {
72
+ const browserUrl = ideConfig?.downloadBrowserUrl || `${ideKey}'s official website`;
73
+ return { ideLaunchNote, error: `${info.app || ideKey} is not installed. Please download from: ${browserUrl}` };
74
+ }
75
+ }
76
+
77
+ if (checkResult.installed) {
78
+ if (!isIDERunning(info.process, info.appPath)) {
79
+ console.log(`🪟 [AGENT CHECK] ${info.app} not running, attempting to launch...`);
80
+ const launchSuccess = await openIDEApp(info.app, repoPath);
81
+ if (launchSuccess) {
82
+ ideLaunchNote = ideLaunchNote || ` (VCM launched ${info.app})`;
83
+ console.log(`🪟 [AGENT CHECK] Successfully launched ${info.app}`);
84
+ } else {
85
+ console.warn(`🪟 [AGENT CHECK] Could not launch ${info.app}, continuing anyway...`);
86
+ }
87
+ } else {
88
+ console.log(`[AGENT CHECK] ${info.app} is already running, skipping launch`);
89
+ await new Promise(r => setTimeout(r, 2000));
90
+ }
91
+ }
92
+
93
+ return { ideLaunchNote, error: null };
94
+ }
95
+
96
+ module.exports = { ensureIDEReady };
@@ -2,12 +2,12 @@
2
2
 
3
3
  const { execSync } = require('child_process');
4
4
 
5
- // Map provider id → { process: process name for tasklist/pgrep, app: app name for opening }
5
+ // Map provider id → { process: process name for tasklist/pgrep, app: app name for opening, appPath: macOS .app path for ps-based detection }
6
6
  const IDE_INFO = {
7
- windsurf: { process: 'Windsurf', app: 'Windsurf' },
7
+ devin: { process: 'Devin', app: 'Devin' },
8
8
  cursor: { process: 'Cursor', app: 'Cursor' },
9
9
  antigravity: { process: 'Antigravity', app: 'Antigravity' },
10
- kiro: { process: 'Kiro', app: 'Kiro' },
10
+ kiro: { process: 'Kiro', app: 'Kiro', appPath: '/Applications/Kiro.app' },
11
11
  'github-copilot': { process: 'Code', app: 'Visual Studio Code' },
12
12
  'amazon-q': { process: 'Code', app: 'Visual Studio Code' },
13
13
  cline: { process: 'Code', app: 'Visual Studio Code' },
@@ -17,11 +17,22 @@ const IDE_INFO = {
17
17
 
18
18
  /**
19
19
  * Returns true if the IDE process is currently running.
20
+ * @param {string} processName - process name for pgrep/tasklist
21
+ * @param {string|null} appPath - optional macOS .app path for ps-based detection (e.g. Kiro which runs as Electron)
20
22
  */
21
- function isIDERunning(processName) {
22
- if (!processName) return false;
23
+ function isIDERunning(processName, appPath = null) {
24
+ if (!processName && !appPath) return false;
23
25
 
24
26
  if (process.platform === 'darwin') {
27
+ // If an appPath is provided, detect via ps (handles apps that run as generic process names like Electron)
28
+ if (appPath) {
29
+ try {
30
+ const result = execSync(`ps aux | grep -v grep | grep "${appPath}" | head -1`, { encoding: 'utf8' });
31
+ return result.trim().length > 0;
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
25
36
  // macOS: use pgrep
26
37
  try {
27
38
  execSync(`pgrep -x "${processName}"`, { stdio: 'ignore' });
@@ -71,9 +82,9 @@ async function openIDEApp(appName, repoPath) {
71
82
 
72
83
  // Map app name to the appropriate method
73
84
  let result;
74
- if (appName === 'Windsurf') {
75
- console.log('🪟 [IDE MANAGER] Calling openWindsurf()...');
76
- result = await manager.openWindsurf(repoPath);
85
+ if (appName === 'Devin') {
86
+ console.log('🪟 [IDE MANAGER] Calling openDevin()...');
87
+ result = await manager.openDevin(repoPath);
77
88
  } else if (appName === 'Cursor') {
78
89
  console.log('🪟 [IDE MANAGER] Calling openCursorNative()...');
79
90
  result = await manager.openCursorNative(repoPath);
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+
5
+ const QUOTA_KEYWORDS = [
6
+ 'quota', 'rate limit', 'resource_exhausted', 'usage limit', 'model quota',
7
+ 'limit exceeded', 'spending cap', 'usage cap',
8
+ 'you\'ve reached your monthly chat messages quota',
9
+ 'upgrade to copilot pro', 'wait for your allowance to renew',
10
+ 'high demand', 'permission denied: we\'re currently facing'
11
+ ];
12
+
13
+ /**
14
+ * Check for IDE quota/rate-limit signals and call done() with an enriched result.
15
+ * Checks process output first, then falls back to platform-specific UI scraping.
16
+ */
17
+ async function checkIDEQuotaLimitAndDone(providerId, errorResult, output, done) {
18
+ const debugLog = (msg) => {
19
+ const timestamp = new Date().toISOString();
20
+ const logLine = `[${timestamp}] ${msg}\n`;
21
+ try {
22
+ fs.appendFileSync(`/tmp/vibe-${providerId}-quota-debug.log`, logLine);
23
+ } catch (_) { }
24
+ console.log(`[AGENT CHECK] ${msg}`);
25
+ };
26
+
27
+ debugLog(`Starting checkIDEQuotaLimitAndDone for ${providerId}`);
28
+ debugLog('errorResult.message: ' + JSON.stringify(errorResult.message).substring(0, 200));
29
+
30
+ try {
31
+ const lowerOutput = output.toLowerCase();
32
+ const lowerErrorMsg = errorResult.message.toLowerCase();
33
+ debugLog('Checking process output length: ' + output.length);
34
+ debugLog('Process output sample: ' + output.substring(0, 300));
35
+
36
+ const hasQuotaKeyword = QUOTA_KEYWORDS.some(kw => lowerOutput.includes(kw) || lowerErrorMsg.includes(kw));
37
+
38
+ if (hasQuotaKeyword) {
39
+ debugLog(`🚨 Quota keywords found in process output or message for ${providerId}`);
40
+ errorResult.rateLimited = true;
41
+ errorResult.rateLimitMessage = output || errorResult.message;
42
+ _setProviderRateLimitFlag(providerId, errorResult);
43
+ debugLog('Set rateLimited to true, calling done()');
44
+ done(errorResult);
45
+ return;
46
+ }
47
+
48
+ debugLog(`No quota keywords in process output or message, checking platform-specific UI fallback for ${providerId}`);
49
+
50
+ let quotaManager = null;
51
+ if (process.platform === 'darwin') {
52
+ const { AppleScriptManager } = require('vibecodingmachine-core');
53
+ quotaManager = new AppleScriptManager();
54
+ } else if (process.platform === 'win32') {
55
+ const { WindowsAutomationManager } = require('vibecodingmachine-core');
56
+ quotaManager = new WindowsAutomationManager();
57
+ }
58
+
59
+ if (quotaManager) {
60
+ try {
61
+ let quotaCheck = null;
62
+
63
+ switch (providerId) {
64
+ case 'antigravity':
65
+ quotaCheck = await quotaManager.checkAntigravityQuotaLimit();
66
+ break;
67
+ case 'devin':
68
+ quotaCheck = await quotaManager.checkDevinRateLimit?.();
69
+ break;
70
+ case 'cursor':
71
+ quotaCheck = await quotaManager.checkCursorQuotaLimit();
72
+ break;
73
+ case 'github-copilot':
74
+ quotaCheck = await quotaManager.checkCursorQuotaLimit();
75
+ break;
76
+ default:
77
+ debugLog(`No specific quota detection method available for ${providerId}`);
78
+ break;
79
+ }
80
+
81
+ debugLog(`${providerId} quota check result: ` + JSON.stringify(quotaCheck));
82
+
83
+ if (quotaCheck && (quotaCheck.isRateLimited || quotaCheck.hasQuotaWarning)) {
84
+ debugLog(`🚨 ${providerId} quota limit detected via platform UI check`);
85
+ errorResult.rateLimited = true;
86
+ errorResult.rateLimitMessage = quotaCheck.message || quotaCheck.matchedText || `${providerId} quota limit detected`;
87
+ if (quotaCheck.resumeAt) {
88
+ errorResult.rateLimitResume = quotaCheck.resumeAt;
89
+ }
90
+ _setProviderRateLimitFlag(providerId, errorResult);
91
+ debugLog('Enriched error result with quota limit');
92
+ } else {
93
+ debugLog(`No rate limit detected for ${providerId}`);
94
+ }
95
+ } catch (appleScriptError) {
96
+ debugLog(`AppleScript quota detection failed for ${providerId}: ${appleScriptError.message}`);
97
+ }
98
+ } else {
99
+ debugLog(`Skipping AppleScript quota detection for ${providerId} on non-macOS platform`);
100
+ }
101
+ } catch (err) {
102
+ debugLog(`Error checking ${providerId} quota: ${err.message}`);
103
+ } finally {
104
+ debugLog('Calling done() with final errorResult');
105
+ debugLog('Final errorResult.rateLimited: ' + errorResult.rateLimited);
106
+ debugLog('Final errorResult.rateLimitMessage: ' + (errorResult.rateLimitMessage ? errorResult.rateLimitMessage.substring(0, 100) : 'none'));
107
+ done(errorResult);
108
+ }
109
+ }
110
+
111
+ function _setProviderRateLimitFlag(providerId, errorResult) {
112
+ switch (providerId) {
113
+ case 'antigravity': errorResult.antigravityRateLimited = true; break;
114
+ case 'devin': errorResult.devinRateLimited = true; break;
115
+ case 'cursor': errorResult.cursorRateLimited = true; break;
116
+ case 'github-copilot': errorResult.githubCopilotRateLimited = true; break;
117
+ }
118
+ }
119
+
120
+ module.exports = { checkIDEQuotaLimitAndDone };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * IDE Utilities Module
3
- *
3
+ *
4
4
  * Contains IDE process detection and launching utilities.
5
5
  */
6
6
 
@@ -8,7 +8,7 @@ const { execSync } = require('child_process');
8
8
 
9
9
  // Map provider id → { process: process name for tasklist/pgrep, app: app name for opening }
10
10
  const IDE_INFO = {
11
- windsurf: { process: 'Windsurf', app: 'Windsurf' },
11
+ devin: { process: 'Devin', app: 'Devin' },
12
12
  cursor: { process: 'Cursor', app: 'Cursor' },
13
13
  antigravity: { process: 'Antigravity', app: 'Antigravity' },
14
14
  'vscode': { process: 'Code', app: 'Visual Studio Code' },
@@ -13,7 +13,7 @@ function getNodeExecutable() {
13
13
  if (process.env.NODE_BINARY_PATH) {
14
14
  return process.env.NODE_BINARY_PATH;
15
15
  }
16
-
16
+
17
17
  // Try to find node in PATH
18
18
  try {
19
19
  const nodeCmd = process.platform === 'win32' ? 'where node' : 'which node';
@@ -22,7 +22,7 @@ function getNodeExecutable() {
22
22
  return nodePath;
23
23
  }
24
24
  } catch (_) {}
25
-
25
+
26
26
  // Fallback: try common node installation paths
27
27
  const commonPaths = process.platform === 'win32'
28
28
  ? [
@@ -36,13 +36,13 @@ function getNodeExecutable() {
36
36
  '/usr/local/bin/node',
37
37
  '/opt/homebrew/bin/node'
38
38
  ];
39
-
39
+
40
40
  for (const nodePath of commonPaths) {
41
41
  if (nodePath && fs.existsSync(nodePath)) {
42
42
  return nodePath;
43
43
  }
44
44
  }
45
-
45
+
46
46
  // Last resort: use process.execPath (might be electron but worth trying)
47
47
  console.warn('[AGENT CHECK] Could not find node executable, falling back to process.execPath');
48
48
  return process.execPath;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Node Utilities Module
3
- *
3
+ *
4
4
  * Contains Node.js executable detection and related utilities.
5
5
  */
6
6
 
@@ -17,7 +17,7 @@ function getNodeExecutable() {
17
17
  if (process.env.NODE_BINARY_PATH) {
18
18
  return process.env.NODE_BINARY_PATH;
19
19
  }
20
-
20
+
21
21
  // Try to find node in PATH
22
22
  try {
23
23
  const nodeCmd = process.platform === 'win32' ? 'where node' : 'which node';
@@ -26,7 +26,7 @@ function getNodeExecutable() {
26
26
  return nodePath;
27
27
  }
28
28
  } catch (_) {}
29
-
29
+
30
30
  // Fallback: try common node installation paths
31
31
  const commonPaths = process.platform === 'win32'
32
32
  ? [
@@ -40,13 +40,13 @@ function getNodeExecutable() {
40
40
  '/usr/local/bin/node',
41
41
  '/opt/homebrew/bin/node'
42
42
  ];
43
-
43
+
44
44
  for (const nodePath of commonPaths) {
45
45
  if (nodePath && fs.existsSync(nodePath)) {
46
46
  return nodePath;
47
47
  }
48
48
  }
49
-
49
+
50
50
  // Last resort: use process.execPath (might be electron but worth trying)
51
51
  console.warn('[AGENT CHECK] Could not find node executable, falling back to process.execPath');
52
52
  return process.execPath;