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.
- package/bin/auth/auth-compliance.js +7 -7
- package/bin/commands/agent-commands.js +15 -15
- package/bin/commands/auto-commands.js +3 -3
- package/bin/commands/command-aliases.js +13 -4
- package/bin/config/cli-config.js +15 -5
- package/bin/update/update-checker.js +5 -5
- package/bin/vibecodingmachine.js +2 -2
- package/package.json +2 -2
- package/src/commands/agents/add.js +5 -5
- package/src/commands/agents/check.js +19 -19
- package/src/commands/agents/list.js +24 -24
- package/src/commands/agents/remove.js +4 -4
- package/src/commands/agents-check.js +1 -1
- package/src/commands/analyze-file-sizes.js +43 -43
- package/src/commands/auto-direct/auto-provider-manager.js +19 -19
- package/src/commands/auto-direct/auto-start-phases.js +493 -0
- package/src/commands/auto-direct/auto-status-display.js +35 -35
- package/src/commands/auto-direct/auto-utils.js +50 -50
- package/src/commands/auto-direct/cline-installer.js +56 -0
- package/src/commands/auto-direct/code-processor.js +27 -27
- package/src/commands/auto-direct/file-scanner.js +19 -19
- package/src/commands/auto-direct/ide-completion-waiter.js +485 -0
- package/src/commands/auto-direct/ide-fallback-runner.js +226 -0
- package/src/commands/auto-direct/ide-provider-runner.js +103 -0
- package/src/commands/auto-direct/iteration-handlers.js +189 -0
- package/src/commands/auto-direct/iteration-runner.js +485 -0
- package/src/commands/auto-direct/provider-config.js +38 -7
- package/src/commands/auto-direct/provider-manager.js +132 -6
- package/src/commands/auto-direct/requirement-manager.js +169 -104
- package/src/commands/auto-direct/requirement-mover.js +350 -0
- package/src/commands/auto-direct/spec-handlers.js +155 -0
- package/src/commands/auto-direct/spec-ide-runner.js +318 -0
- package/src/commands/auto-direct/spec-processing.js +203 -0
- package/src/commands/auto-direct/status-display.js +9 -9
- package/src/commands/auto-direct/utils.js +83 -1
- package/src/commands/auto-direct-refactored.js +1 -413
- package/src/commands/auto-direct.js +127 -4119
- package/src/commands/auto-execution.js +21 -21
- package/src/commands/auto-status-helpers.js +0 -2
- package/src/commands/auto.js +22 -22
- package/src/commands/check-compliance.js +65 -65
- package/src/commands/computers.js +39 -39
- package/src/commands/continuous-scan.js +19 -19
- package/src/commands/ide.js +4 -4
- package/src/commands/locale.js +7 -7
- package/src/commands/refactor-file.js +59 -59
- package/src/commands/requirements/commands.js +17 -17
- package/src/commands/requirements/default-handlers.js +30 -30
- package/src/commands/requirements/disable.js +3 -3
- package/src/commands/requirements/enable.js +3 -3
- package/src/commands/requirements/utils.js +6 -6
- package/src/commands/requirements-refactored.js +3 -3
- package/src/commands/requirements-remote.js +38 -38
- package/src/commands/requirements.js +3 -3
- package/src/commands/settings.js +111 -0
- package/src/commands/specs/count.js +60 -0
- package/src/commands/specs/disable.js +3 -3
- package/src/commands/specs/enable.js +3 -3
- package/src/commands/status.js +10 -10
- package/src/commands/sync.js +25 -25
- package/src/commands/timeout.js +35 -35
- package/src/trui/TruiInterface.js +2 -2
- package/src/trui/agents/AgentInterface.js +4 -4
- package/src/trui/agents/handlers/CommandHandler.js +4 -4
- package/src/trui/agents/handlers/ContextManager.js +1 -1
- package/src/trui/agents/handlers/DisplayHandler.js +11 -11
- package/src/trui/agents/handlers/HelpHandler.js +1 -1
- package/src/utils/agent-selector.js +6 -6
- package/src/utils/antigravity-installer.js +4 -4
- package/src/utils/asset-cleanup.js +1 -1
- package/src/utils/auth.js +9 -12
- package/src/utils/clarification-actions.js +4 -4
- package/src/utils/cline-js-handler.js +5 -5
- package/src/utils/compliance-check.js +6 -6
- package/src/utils/config.js +12 -12
- package/src/utils/display-formatters-complete.js +2 -2
- package/src/utils/display-formatters-extracted.js +2 -2
- package/src/utils/display-formatters.js +2 -2
- package/src/utils/feedback-handler.js +2 -2
- package/src/utils/first-run.js +7 -7
- package/src/utils/ide-detection.js +1 -1
- package/src/utils/ide-handlers.js +6 -6
- package/src/utils/interactive/clarification-actions.js +3 -3
- package/src/utils/interactive/core-ui.js +7 -7
- package/src/utils/interactive/file-backup.js +6 -6
- package/src/utils/interactive/file-import-export.js +49 -49
- package/src/utils/interactive/file-operations.js +3 -3
- package/src/utils/interactive/file-validation.js +41 -41
- package/src/utils/interactive/interactive-prompts.js +41 -41
- package/src/utils/interactive/requirement-actions.js +5 -5
- package/src/utils/interactive/requirement-crud.js +4 -4
- package/src/utils/interactive/requirements-navigation.js +10 -10
- package/src/utils/interactive-broken.js +6 -6
- package/src/utils/interactive.js +37 -37
- package/src/utils/keyboard-handler.js +4 -4
- package/src/utils/prompt-helper.js +6 -6
- package/src/utils/provider-checker/agent-checker.js +1 -1
- package/src/utils/provider-checker/agent-runner.js +203 -314
- package/src/utils/provider-checker/agents-file-lock.js +134 -0
- package/src/utils/provider-checker/agents-manager.js +224 -36
- package/src/utils/provider-checker/cli-installer.js +28 -28
- package/src/utils/provider-checker/cli-utils.js +2 -2
- package/src/utils/provider-checker/cursor-approval-clicker.js +108 -0
- package/src/utils/provider-checker/format-utils.js +4 -4
- package/src/utils/provider-checker/ide-installer-helper.js +96 -0
- package/src/utils/provider-checker/ide-manager.js +19 -8
- package/src/utils/provider-checker/ide-quota-checker.js +120 -0
- package/src/utils/provider-checker/ide-utils.js +2 -2
- package/src/utils/provider-checker/node-detector.js +4 -4
- package/src/utils/provider-checker/node-utils.js +5 -5
- package/src/utils/provider-checker/opencode-checker.js +107 -73
- package/src/utils/provider-checker/process-utils.js +1 -1
- package/src/utils/provider-checker/provider-validator.js +11 -11
- package/src/utils/provider-checker/quota-checker.js +5 -5
- package/src/utils/provider-checker/quota-detector.js +5 -5
- package/src/utils/provider-checker/requirements-manager.js +6 -6
- package/src/utils/provider-checker/test-requirements.js +1 -1
- package/src/utils/provider-checker/vscode-approval-clicker.js +328 -0
- package/src/utils/provider-checker-new.js +6 -6
- package/src/utils/provider-checker.js +6 -6
- package/src/utils/provider-checkers/ide-manager.js +13 -13
- package/src/utils/provider-checkers/node-executable-finder.js +4 -4
- package/src/utils/provider-checkers/provider-checker-core.js +5 -5
- package/src/utils/provider-checkers/provider-checker-main.js +17 -17
- package/src/utils/provider-registry.js +5 -6
- package/src/utils/provider-utils.js +12 -12
- package/src/utils/quota-detectors.js +32 -32
- package/src/utils/requirement-action-handlers.js +12 -12
- package/src/utils/requirement-actions/requirement-operations.js +3 -3
- package/src/utils/requirement-actions.js +1 -1
- package/src/utils/requirement-file-operations.js +5 -5
- package/src/utils/requirement-helpers.js +1 -1
- package/src/utils/requirement-management.js +5 -5
- package/src/utils/requirement-navigation.js +2 -2
- package/src/utils/requirement-organization.js +3 -3
- package/src/utils/rui-trui-adapter.js +14 -14
- package/src/utils/simple-trui.js +3 -3
- package/src/utils/status-helpers-extracted.js +3 -3
- package/src/utils/trui-clarifications.js +11 -11
- package/src/utils/trui-debug.js +3 -2
- package/src/utils/trui-devin.js +217 -0
- package/src/utils/trui-feedback.js +7 -7
- package/src/utils/trui-kiro-integration.js +34 -34
- package/src/utils/trui-main-handlers.js +20 -21
- package/src/utils/trui-main-menu.js +19 -19
- package/src/utils/trui-nav-agents.js +59 -8
- package/src/utils/trui-nav-requirements.js +3 -3
- package/src/utils/trui-nav-settings.js +10 -10
- package/src/utils/trui-nav-specifications.js +1 -1
- package/src/utils/trui-navigation-backup.js +11 -11
- package/src/utils/trui-navigation.js +9 -9
- package/src/utils/trui-provider-health.js +25 -25
- package/src/utils/trui-provider-manager.js +28 -28
- package/src/utils/trui-quick-menu.js +2 -2
- package/src/utils/trui-req-actions-backup.js +21 -21
- package/src/utils/trui-req-actions.js +20 -20
- package/src/utils/trui-req-editor.js +10 -10
- package/src/utils/trui-req-file-ops.js +3 -3
- package/src/utils/trui-req-tree.js +7 -7
- package/src/utils/trui-windsurf.js +103 -103
- package/src/utils/user-tracking.js +15 -15
- package/src/utils/trui-req-tree-old.js +0 -719
|
@@ -6,13 +6,17 @@ const path = require('path');
|
|
|
6
6
|
const chokidar = require('chokidar');
|
|
7
7
|
|
|
8
8
|
const { NODE_EXECUTABLE } = require('./node-detector');
|
|
9
|
-
const { IDE_INFO, isIDERunning
|
|
9
|
+
const { IDE_INFO, isIDERunning } = require('./ide-manager');
|
|
10
10
|
const { getResultFilePath, getAgentsFilePath, updateAgentStatus, getAgentStatus } = require('./agents-manager');
|
|
11
|
+
const { startVSCodeApprovalClicker } = require('./vscode-approval-clicker');
|
|
12
|
+
const { startCursorApprovalClicker } = require('./cursor-approval-clicker');
|
|
13
|
+
const { checkIDEQuotaLimitAndDone } = require('./ide-quota-checker');
|
|
14
|
+
const { ensureIDEReady } = require('./ide-installer-helper');
|
|
11
15
|
|
|
12
16
|
// Timeout for direct LLM round-trips via auto:direct (ms)
|
|
13
17
|
const DIRECT_TIMEOUT_MS = 60000;
|
|
14
|
-
// Timeout for IDE automation round-trips
|
|
15
|
-
const IDE_TIMEOUT_MS =
|
|
18
|
+
// Timeout for IDE automation round-trips — AI needs time to receive, process, and edit agents.json
|
|
19
|
+
const IDE_TIMEOUT_MS = 360000;
|
|
16
20
|
|
|
17
21
|
const CLI_ENTRY_POINT = path.resolve(path.join(__dirname, '../../../bin/vibecodingmachine.js'));
|
|
18
22
|
|
|
@@ -30,113 +34,21 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
30
34
|
|
|
31
35
|
// Ensure temp dir exists
|
|
32
36
|
fs.mkdirSync(path.dirname(resultFile), { recursive: true });
|
|
33
|
-
// Remove stale result
|
|
37
|
+
// Remove stale result files so we detect a fresh write
|
|
34
38
|
try { fs.unlinkSync(resultFile); } catch { }
|
|
39
|
+
const _homeResultFile = path.join(require('os').homedir(), '.vibecodingmachine', 'temp', 'TEMP_agent_check.txt');
|
|
40
|
+
try { fs.mkdirSync(path.dirname(_homeResultFile), { recursive: true }); } catch { }
|
|
41
|
+
try { fs.unlinkSync(_homeResultFile); } catch { }
|
|
35
42
|
|
|
36
43
|
// For IDE providers: verify the IDE is running/installed, install if needed
|
|
37
44
|
let ideLaunchNote = '';
|
|
38
45
|
if (def.type === 'ide') {
|
|
39
46
|
const info = IDE_INFO[providerId] || IDE_INFO[def.ide] || null;
|
|
40
|
-
if (info && info.process) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (launchSuccess) {
|
|
46
|
-
ideLaunchNote = ` (VCM launched ${info.app})`;
|
|
47
|
-
} else {
|
|
48
|
-
// Failed to launch on macOS - check if installed
|
|
49
|
-
const { IDEInstaller } = require('../../../../electron-app/src/main/ide-installer');
|
|
50
|
-
const installer = new IDEInstaller();
|
|
51
|
-
const ideKey = def.ide || providerId;
|
|
52
|
-
const checkResult = await installer.checkIDEInstallation(ideKey);
|
|
53
|
-
if (!checkResult.installed) {
|
|
54
|
-
return {
|
|
55
|
-
status: 'error',
|
|
56
|
-
message: `${info.app} is not installed. Please download from ${IDEInstaller.IDE_CONFIG[ideKey]?.downloadBrowserUrl || 'its official website'}`,
|
|
57
|
-
checkedAt
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
// Windows: check if installed, install if possible, launch if installed
|
|
63
|
-
else if (process.platform === 'win32') {
|
|
64
|
-
const { IDEInstaller } = require('../../../../electron-app/src/main/ide-installer');
|
|
65
|
-
const installer = new IDEInstaller();
|
|
66
|
-
const ideKey = def.ide || providerId;
|
|
67
|
-
const ideConfig = IDEInstaller.IDE_CONFIG[ideKey];
|
|
68
|
-
|
|
69
|
-
// Check if IDE is installed
|
|
70
|
-
let checkResult = await installer.checkIDEInstallation(ideKey);
|
|
71
|
-
|
|
72
|
-
if (!checkResult.installed) {
|
|
73
|
-
// IDE is not installed - try to install if we have a download URL
|
|
74
|
-
const downloadUrl = ideConfig?.downloadUrl?.[process.platform];
|
|
75
|
-
|
|
76
|
-
if (downloadUrl) {
|
|
77
|
-
// Has a direct download URL - auto-install
|
|
78
|
-
console.log(`[AGENT CHECK] ${info.app || ideKey} not installed, installing...`);
|
|
79
|
-
if (onProgress) onProgress(providerId, 'installing');
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
const installResult = await installer.installIDE(ideKey, (progress) => {
|
|
83
|
-
console.log(`[AGENT CHECK] Installation progress for ${ideKey}: ${progress.progress}% - ${progress.message}`);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
if (!installResult || !installResult.success) {
|
|
87
|
-
console.error(`[AGENT CHECK] Installation failed for ${info.app || ideKey}`);
|
|
88
|
-
return {
|
|
89
|
-
status: 'error',
|
|
90
|
-
message: `Failed to install ${info.app || ideKey}: ${installResult?.error || 'Installation failed'}. Please install manually and try again.`,
|
|
91
|
-
checkedAt
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
console.log(`[AGENT CHECK] ${info.app || ideKey} installed successfully`);
|
|
96
|
-
ideLaunchNote = ` (VCM installed ${info.app || ideKey})`;
|
|
97
|
-
// Re-check that installation succeeded
|
|
98
|
-
await new Promise(r => setTimeout(r, 3000));
|
|
99
|
-
checkResult = await installer.checkIDEInstallation(ideKey);
|
|
100
|
-
} catch (installError) {
|
|
101
|
-
console.error(`[AGENT CHECK] Installation error for ${info.app || ideKey}:`, installError.message);
|
|
102
|
-
return {
|
|
103
|
-
status: 'error',
|
|
104
|
-
message: `Installation failed for ${info.app || ideKey}: ${installError.message}. Please install manually and try again.`,
|
|
105
|
-
checkedAt
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
// No direct download URL - provide browser download link
|
|
110
|
-
const browserUrl = ideConfig?.downloadBrowserUrl || `${ideKey}'s official website`;
|
|
111
|
-
return {
|
|
112
|
-
status: 'error',
|
|
113
|
-
message: `${info.app || ideKey} is not installed. Please download from: ${browserUrl}`,
|
|
114
|
-
checkedAt
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// IDE is now installed (either was already or we just installed it) - launch it if not already running
|
|
120
|
-
if (checkResult.installed) {
|
|
121
|
-
// Check if IDE is already running before attempting to launch
|
|
122
|
-
const isRunning = isIDERunning(info.process);
|
|
123
|
-
if (!isRunning) {
|
|
124
|
-
console.log(`🪟 [AGENT CHECK] ${info.app} not running, attempting to launch...`);
|
|
125
|
-
// Use openIDEApp which will use WindowsAutomationManager
|
|
126
|
-
const launchSuccess = await openIDEApp(info.app, repoPath);
|
|
127
|
-
if (launchSuccess) {
|
|
128
|
-
ideLaunchNote = ideLaunchNote || ` (VCM launched ${info.app})`;
|
|
129
|
-
console.log(`🪟 [AGENT CHECK] Successfully launched ${info.app}`);
|
|
130
|
-
} else {
|
|
131
|
-
console.warn(`🪟 [AGENT CHECK] Could not launch ${info.app}, continuing anyway...`);
|
|
132
|
-
}
|
|
133
|
-
} else {
|
|
134
|
-
console.log(`[AGENT CHECK] ${info.app} is already running, skipping launch`);
|
|
135
|
-
// Give running IDE a moment to be ready
|
|
136
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
47
|
+
if (info && (info.process || info.appPath) && !isIDERunning(info.process, info.appPath)) {
|
|
48
|
+
const ideResult = await ensureIDEReady(providerId, def, repoPath, info, onProgress);
|
|
49
|
+
ideLaunchNote = ideResult.ideLaunchNote;
|
|
50
|
+
if (ideResult.error) {
|
|
51
|
+
return { status: 'error', message: ideResult.error, checkedAt };
|
|
140
52
|
}
|
|
141
53
|
}
|
|
142
54
|
}
|
|
@@ -148,9 +60,13 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
148
60
|
let watcher;
|
|
149
61
|
let requirementsWatcher;
|
|
150
62
|
|
|
63
|
+
// Shared resolved-state object so clicker modules can check it
|
|
64
|
+
const resolvedRef = { resolved: false };
|
|
65
|
+
|
|
151
66
|
async function done(result) {
|
|
152
67
|
if (resolved) return;
|
|
153
68
|
resolved = true;
|
|
69
|
+
resolvedRef.resolved = true;
|
|
154
70
|
try { if (watcher) watcher.close(); } catch { }
|
|
155
71
|
try { if (requirementsWatcher) requirementsWatcher.close(); } catch { }
|
|
156
72
|
clearTimeout(timeout);
|
|
@@ -160,15 +76,14 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
160
76
|
// Update agent status based on result
|
|
161
77
|
try {
|
|
162
78
|
if (result.status === 'success') {
|
|
163
|
-
// Status already set to 'operational' by the IDE agent
|
|
164
79
|
console.log(`[AGENT CHECK] ${providerId} check passed - status is 'operational'`);
|
|
165
80
|
} else if (result.rateLimited) {
|
|
166
|
-
updateAgentStatus(providerId, 'rate_limited', {
|
|
81
|
+
await updateAgentStatus(providerId, 'rate_limited', {
|
|
167
82
|
rateLimitResume: result.rateLimitResume
|
|
168
83
|
});
|
|
169
84
|
console.log(`[AGENT CHECK] Set ${providerId} status to 'rate_limited'`);
|
|
170
85
|
} else {
|
|
171
|
-
updateAgentStatus(providerId, 'error', {
|
|
86
|
+
await updateAgentStatus(providerId, 'error', {
|
|
172
87
|
error: result.message
|
|
173
88
|
});
|
|
174
89
|
console.log(`[AGENT CHECK] Set ${providerId} status to 'error'`);
|
|
@@ -177,7 +92,6 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
177
92
|
console.warn(`[AGENT CHECK] Could not update agent status: ${err.message}`);
|
|
178
93
|
}
|
|
179
94
|
|
|
180
|
-
// Notify UI that check is done
|
|
181
95
|
if (onProgress) {
|
|
182
96
|
const statusMessage = result.status === 'success'
|
|
183
97
|
? 'Check completed successfully'
|
|
@@ -188,68 +102,90 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
188
102
|
resolve(result);
|
|
189
103
|
}
|
|
190
104
|
|
|
105
|
+
// Also watch home-dir fallback path (some IDEs resolve relative paths to ~ not repoPath)
|
|
106
|
+
const homeResultFile = path.join(require('os').homedir(), '.vibecodingmachine', 'temp', 'TEMP_agent_check.txt');
|
|
107
|
+
|
|
191
108
|
function checkResult() {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
109
|
+
for (const f of [resultFile, homeResultFile]) {
|
|
110
|
+
if (!resolved && fs.existsSync(f)) {
|
|
111
|
+
try {
|
|
112
|
+
const content = fs.readFileSync(f, 'utf8');
|
|
113
|
+
if (content.includes('VCM_CHECK_OK')) {
|
|
114
|
+
console.log(`[AGENT CHECK] ${providerId}: VCM_CHECK_OK found in ${f}`);
|
|
115
|
+
if (onProgress) onProgress(providerId, 'response_detected', null, 'Response detected.');
|
|
116
|
+
done({ status: 'success', message: 'End-to-end check passed', checkedAt });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
} catch { }
|
|
120
|
+
}
|
|
200
121
|
}
|
|
201
122
|
}
|
|
202
123
|
|
|
203
|
-
// Watch for result file creation
|
|
204
|
-
watcher = chokidar.watch(resultFile, { persistent: true, ignoreInitial: false, disableGlobbing: true });
|
|
124
|
+
// Watch for result file creation (both repo-path and home-dir fallback)
|
|
125
|
+
watcher = chokidar.watch([resultFile, homeResultFile], { persistent: true, ignoreInitial: false, disableGlobbing: true });
|
|
205
126
|
watcher.on('add', checkResult);
|
|
206
127
|
watcher.on('change', checkResult);
|
|
207
128
|
|
|
208
|
-
// Watch agents.json for status changes to 'operational'
|
|
209
|
-
//
|
|
129
|
+
// Watch agents.json for status changes to 'operational' written AFTER this test started.
|
|
130
|
+
// Guard against stale 'operational' status from a previous test run for this or another agent.
|
|
210
131
|
let debounceTimer = null;
|
|
211
132
|
const agentsFilePath = getAgentsFilePath();
|
|
212
133
|
requirementsWatcher = chokidar.watch(agentsFilePath, { persistent: true, ignoreInitial: true });
|
|
213
134
|
requirementsWatcher.on('change', () => {
|
|
214
|
-
// Clear existing debounce timer
|
|
215
135
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
216
|
-
|
|
217
|
-
// Set new timer (50ms debounce - fast response while avoiding duplicate reads)
|
|
218
136
|
debounceTimer = setTimeout(() => {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
137
|
+
try {
|
|
138
|
+
const agentStatus = getAgentStatus(providerId);
|
|
139
|
+
console.log(`[AGENT CHECK] Current status for ${providerId}: ${agentStatus.status}`);
|
|
140
|
+
const writtenAfterTestStart = agentStatus.lastChecked && new Date(agentStatus.lastChecked) > new Date(checkedAt);
|
|
141
|
+
if (agentStatus.status === 'operational' && writtenAfterTestStart) {
|
|
142
|
+
console.log(`[AGENT CHECK] Detected fresh 'operational' status for ${providerId} (written at ${agentStatus.lastChecked})`);
|
|
143
|
+
if (onProgress) onProgress(providerId, 'response_detected', null, 'Status updated to operational.');
|
|
144
|
+
done({ status: 'success', message: 'Agent updated status to operational', checkedAt });
|
|
145
|
+
} else if (agentStatus.status === 'operational' && !writtenAfterTestStart) {
|
|
146
|
+
console.log(`[AGENT CHECK] Ignoring stale 'operational' for ${providerId} — was set before this test started`);
|
|
147
|
+
}
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.warn(`[AGENT CHECK] Error reading agents.json: ${err.message}`);
|
|
228
150
|
}
|
|
229
|
-
}
|
|
230
|
-
console.warn(`[AGENT CHECK] Error reading agents.json: ${err.message}`);
|
|
231
|
-
}
|
|
232
|
-
}, 50); // End of debounce setTimeout - reduced from 300ms to 50ms for faster response
|
|
151
|
+
}, 50);
|
|
233
152
|
});
|
|
234
153
|
|
|
235
154
|
const timeout = setTimeout(() => {
|
|
236
|
-
// Diagnose: is the IDE process still running?
|
|
237
155
|
let diagnosis = '';
|
|
238
156
|
if (def.type === 'ide') {
|
|
239
157
|
const info = IDE_INFO[providerId] || IDE_INFO[def.ide] || null;
|
|
240
|
-
if (info && info.process) {
|
|
241
|
-
diagnosis = isIDERunning(info.process)
|
|
158
|
+
if (info && (info.process || info.appPath)) {
|
|
159
|
+
diagnosis = isIDERunning(info.process, info.appPath)
|
|
242
160
|
? ` — ${info.app || info.process} is running but did not respond`
|
|
243
161
|
: ` — ${info.app || info.process} is not running`;
|
|
244
162
|
}
|
|
245
163
|
}
|
|
246
164
|
console.warn(`[AGENT CHECK] Timeout for ${providerId} after ${timeoutMs / 1000}s${diagnosis}`);
|
|
247
165
|
|
|
248
|
-
const
|
|
166
|
+
const ideNotRunning = def.type === 'ide' && diagnosis.includes('is not running');
|
|
167
|
+
const failureReason = ideNotRunning
|
|
168
|
+
? `${def.name || providerId} is not running`
|
|
169
|
+
: `${def.name || providerId} did not complete the test file write within ${timeoutMs / 1000}s${diagnosis}`;
|
|
170
|
+
const userAction = ideNotRunning
|
|
171
|
+
? `Open ${def.name || providerId} and try again`
|
|
172
|
+
: `Check that ${def.name || providerId} is logged in, has no quota errors, and can run shell commands`;
|
|
173
|
+
const timeoutResult = { status: 'error', message: `Timeout${ideLaunchNote}${diagnosis}`, checkedAt, failureReason, userAction };
|
|
249
174
|
|
|
250
|
-
// For IDE timeout, also check for quota limit (in output + UI)
|
|
251
175
|
if (def.type === 'ide') {
|
|
252
|
-
|
|
176
|
+
try {
|
|
177
|
+
const { getAgentStatus } = require('./agents-manager');
|
|
178
|
+
const currentStatus = getAgentStatus(providerId);
|
|
179
|
+
if (currentStatus && currentStatus.status === 'operational' &&
|
|
180
|
+
currentStatus.lastChecked && new Date(currentStatus.lastChecked) > new Date(checkedAt)) {
|
|
181
|
+
console.log(`[AGENT CHECK] ${providerId} succeeded after timeout — status is operational`);
|
|
182
|
+
done({ status: 'success', message: 'Agent updated status to operational (post-timeout)', checkedAt });
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
} catch (e) {
|
|
186
|
+
// ignore
|
|
187
|
+
}
|
|
188
|
+
checkIDEQuotaLimitAndDone(providerId, timeoutResult, output, done).catch(err => {
|
|
253
189
|
console.error('[AGENT CHECK] Error in quota check:', err);
|
|
254
190
|
done(timeoutResult);
|
|
255
191
|
});
|
|
@@ -263,38 +199,70 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
263
199
|
if (signal && signal.cancelled) {
|
|
264
200
|
done({ status: 'error', message: 'Check cancelled by user', checkedAt });
|
|
265
201
|
}
|
|
266
|
-
}, 1000);
|
|
202
|
+
}, 1000);
|
|
267
203
|
|
|
268
|
-
// Send initial checking status
|
|
269
204
|
if (onProgress) {
|
|
270
205
|
onProgress(providerId, 'awaiting', null, 'Awaiting response...');
|
|
271
206
|
}
|
|
272
207
|
|
|
273
|
-
// For IDE providers: send connectivity test directly using
|
|
274
|
-
// Don't spawn auto:start since it expects requirements files (which we removed)
|
|
208
|
+
// For IDE providers: send connectivity test directly using platform-specific automation
|
|
275
209
|
if (def.type === 'ide') {
|
|
276
210
|
try {
|
|
277
211
|
const { generateConnectivityTestMessage } = require('./agents-manager');
|
|
278
|
-
const { WindowsAutomationManager } = require('vibecodingmachine-core');
|
|
279
212
|
|
|
280
|
-
|
|
213
|
+
let automation;
|
|
214
|
+
if (process.platform === 'darwin') {
|
|
215
|
+
const { AppleScriptManager } = require('vibecodingmachine-core');
|
|
216
|
+
automation = new AppleScriptManager();
|
|
217
|
+
} else if (process.platform === 'win32') {
|
|
218
|
+
const { WindowsAutomationManager } = require('vibecodingmachine-core');
|
|
219
|
+
automation = new WindowsAutomationManager();
|
|
220
|
+
} else {
|
|
221
|
+
return {
|
|
222
|
+
status: 'error',
|
|
223
|
+
message: `Platform ${process.platform} not supported for IDE automation`,
|
|
224
|
+
checkedAt
|
|
225
|
+
};
|
|
226
|
+
}
|
|
281
227
|
|
|
282
|
-
|
|
283
|
-
|
|
228
|
+
console.log(`[AGENT CHECK] Sending connectivity test directly to ${providerId}`);
|
|
229
|
+
console.log(`[AGENT CHECK] Setting ${providerId} status to 'checking' in agents.json`);
|
|
230
|
+
try {
|
|
231
|
+
await updateAgentStatus(providerId, 'checking');
|
|
232
|
+
console.log(`[AGENT CHECK] Set ${providerId} status to 'checking'`);
|
|
233
|
+
} catch (err) {
|
|
234
|
+
console.warn(`[AGENT CHECK] Could not set agent status: ${err.message}`);
|
|
235
|
+
}
|
|
284
236
|
|
|
285
|
-
|
|
286
|
-
|
|
237
|
+
const testMessage = generateConnectivityTestMessage(def.name || providerId, providerId, repoPath);
|
|
238
|
+
console.log(`[AGENT CHECK] ${providerId}: test message = "${testMessage}"`);
|
|
287
239
|
|
|
288
|
-
// Call the appropriate method based on provider
|
|
289
240
|
let sendResult;
|
|
290
241
|
try {
|
|
291
242
|
switch(providerId.toLowerCase()) {
|
|
292
|
-
case '
|
|
293
|
-
|
|
294
|
-
|
|
243
|
+
case 'devin':
|
|
244
|
+
// Devin is web-based — not automatable via desktop automation
|
|
245
|
+
done({ status: 'error', message: 'Devin is web-based and cannot be tested via desktop automation', checkedAt });
|
|
246
|
+
return;
|
|
295
247
|
case 'cursor':
|
|
296
248
|
sendResult = await automation.sendTextToCursor(testMessage);
|
|
297
249
|
break;
|
|
250
|
+
case 'antigravity':
|
|
251
|
+
sendResult = await automation.sendTextToAntigravity(testMessage);
|
|
252
|
+
break;
|
|
253
|
+
case 'kiro':
|
|
254
|
+
sendResult = await automation.sendTextToKiro(testMessage);
|
|
255
|
+
break;
|
|
256
|
+
case 'vscode':
|
|
257
|
+
case 'github-copilot':
|
|
258
|
+
case 'vscode-copilot-cli':
|
|
259
|
+
case 'amazon-q':
|
|
260
|
+
sendResult = await automation.sendTextToVSCode(testMessage);
|
|
261
|
+
break;
|
|
262
|
+
case 'replit':
|
|
263
|
+
// Replit is browser-based — not automatable via desktop AppleScript
|
|
264
|
+
done({ status: 'error', message: 'Replit is browser-based and cannot be tested via desktop automation', checkedAt });
|
|
265
|
+
return;
|
|
298
266
|
default:
|
|
299
267
|
sendResult = { success: false, error: `No automation method for ${providerId}` };
|
|
300
268
|
}
|
|
@@ -314,7 +282,63 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
314
282
|
console.log(`[AGENT CHECK] Successfully sent connectivity test to ${providerId}`);
|
|
315
283
|
console.log(`[AGENT CHECK] Waiting for IDE to update agents.json status to 'operational'...`);
|
|
316
284
|
|
|
317
|
-
//
|
|
285
|
+
// Antigravity shows "Allow running this command?" approval dialog — auto-approve with "1" + Enter
|
|
286
|
+
if (process.platform === 'darwin' && providerId === 'antigravity') {
|
|
287
|
+
const { spawn: spawnApproval } = require('child_process');
|
|
288
|
+
const tryApproveAntigravity = (attempt) => {
|
|
289
|
+
if (resolved) return;
|
|
290
|
+
console.log(`[AGENT CHECK] Antigravity: pressing "1" to approve command (attempt ${attempt})`);
|
|
291
|
+
const approveScript = `
|
|
292
|
+
tell application "Antigravity" to activate
|
|
293
|
+
delay 0.5
|
|
294
|
+
tell application "System Events"
|
|
295
|
+
tell process "Antigravity"
|
|
296
|
+
keystroke "1"
|
|
297
|
+
delay 0.3
|
|
298
|
+
key code 36
|
|
299
|
+
end tell
|
|
300
|
+
end tell
|
|
301
|
+
`;
|
|
302
|
+
const tmpFile = require('os').tmpdir() + '/antigravity_approve.scpt';
|
|
303
|
+
require('fs').writeFileSync(tmpFile, approveScript);
|
|
304
|
+
const approveChild = spawnApproval('osascript', [tmpFile], { detached: true, stdio: 'ignore' });
|
|
305
|
+
approveChild.unref();
|
|
306
|
+
};
|
|
307
|
+
for (let i = 0; i < 20; i++) {
|
|
308
|
+
setTimeout(() => tryApproveAntigravity(i + 1), 20000 + i * 15000);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// VS Code-based IDEs show "Allow"/"Run" buttons in WebViews — use CGEvent clicker
|
|
313
|
+
if (process.platform === 'darwin' && (providerId === 'github-copilot' || providerId === 'amazon-q' || providerId === 'kiro')) {
|
|
314
|
+
startVSCodeApprovalClicker(providerId, resolvedRef, testMessage);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Cursor shows a "Run" button for terminal commands in agentic mode
|
|
318
|
+
if (process.platform === 'darwin' && providerId === 'cursor') {
|
|
319
|
+
startCursorApprovalClicker(resolvedRef);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Early quota check for cursor
|
|
323
|
+
if (process.platform === 'darwin' && providerId === 'cursor') {
|
|
324
|
+
const earlyCheckDelay = 30000;
|
|
325
|
+
setTimeout(async () => {
|
|
326
|
+
if (resolved) return;
|
|
327
|
+
try {
|
|
328
|
+
let quotaCheck = null;
|
|
329
|
+
if (providerId === 'cursor') {
|
|
330
|
+
quotaCheck = await automation.checkCursorQuotaLimit();
|
|
331
|
+
}
|
|
332
|
+
if (quotaCheck && (quotaCheck.isRateLimited || quotaCheck.hasQuotaWarning)) {
|
|
333
|
+
console.log(`[AGENT CHECK] ${providerId} rate limit detected early`);
|
|
334
|
+
done({ status: 'error', message: `Rate limited: ${quotaCheck.matchedText || quotaCheck.message || 'quota exceeded'}`, checkedAt, rateLimited: true });
|
|
335
|
+
}
|
|
336
|
+
} catch (e) {
|
|
337
|
+
console.log(`[AGENT CHECK] Early rate limit check error for ${providerId}: ${e.message}`);
|
|
338
|
+
}
|
|
339
|
+
}, earlyCheckDelay);
|
|
340
|
+
}
|
|
341
|
+
|
|
318
342
|
return;
|
|
319
343
|
|
|
320
344
|
} catch (err) {
|
|
@@ -324,17 +348,15 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
324
348
|
}
|
|
325
349
|
}
|
|
326
350
|
|
|
327
|
-
// For direct LLM providers:
|
|
351
|
+
// For direct LLM providers: use auto:direct
|
|
328
352
|
let args;
|
|
329
353
|
if (def.type !== 'ide') {
|
|
330
354
|
args = [CLI_ENTRY_POINT, 'auto:direct', '--provider', providerId, '--max-chats', '1'];
|
|
331
355
|
} else {
|
|
332
|
-
// IDE handling moved above - this shouldn't be reached
|
|
333
356
|
done({ status: 'error', message: 'IDE handling logic error', checkedAt });
|
|
334
357
|
return;
|
|
335
358
|
}
|
|
336
359
|
|
|
337
|
-
// Verify CLI entry point exists and is readable
|
|
338
360
|
if (!fs.existsSync(CLI_ENTRY_POINT)) {
|
|
339
361
|
console.error(`[AGENT CHECK] CLI entry point not found: ${CLI_ENTRY_POINT}`);
|
|
340
362
|
done({ status: 'error', message: `CLI entry point not found: ${CLI_ENTRY_POINT}`, checkedAt });
|
|
@@ -349,7 +371,6 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
349
371
|
return;
|
|
350
372
|
}
|
|
351
373
|
|
|
352
|
-
// Verify repo path exists and is accessible
|
|
353
374
|
if (!fs.existsSync(repoPath)) {
|
|
354
375
|
console.error(`[AGENT CHECK] Repository path not found: ${repoPath}`);
|
|
355
376
|
done({ status: 'error', message: `Repository path not found: ${repoPath}`, checkedAt });
|
|
@@ -364,29 +385,24 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
364
385
|
return;
|
|
365
386
|
}
|
|
366
387
|
|
|
367
|
-
// Log the command being executed
|
|
368
388
|
console.log(`[AGENT CHECK] Starting check for ${providerId}`);
|
|
369
389
|
console.log(`[AGENT CHECK] Node Executable: ${NODE_EXECUTABLE}`);
|
|
370
390
|
console.log(`[AGENT CHECK] Args: ${args.join(' ')}`);
|
|
371
391
|
console.log(`[AGENT CHECK] CWD: ${repoPath}`);
|
|
372
392
|
console.log(`[AGENT CHECK] Result file: ${resultFile}`);
|
|
373
393
|
|
|
374
|
-
// Set agent status to 'checking' in agents.json before sending test
|
|
375
394
|
console.log(`[AGENT CHECK] Setting ${providerId} status to 'checking' in agents.json`);
|
|
376
395
|
try {
|
|
377
|
-
updateAgentStatus(providerId, 'checking');
|
|
396
|
+
await updateAgentStatus(providerId, 'checking');
|
|
378
397
|
console.log(`[AGENT CHECK] Set ${providerId} status to 'checking'`);
|
|
379
398
|
} catch (err) {
|
|
380
399
|
console.warn(`[AGENT CHECK] Could not set agent status: ${err.message}`);
|
|
381
400
|
}
|
|
382
401
|
|
|
383
|
-
// Prepare environment - inherit all process.env and add NODE_PATH if needed
|
|
384
402
|
const spawnEnv = {
|
|
385
403
|
...process.env,
|
|
386
|
-
// Set IDE check mode flag so auto-execution knows to use --ide option instead of configured providers
|
|
387
404
|
VCM_IDE_CHECK_MODE: 'true',
|
|
388
405
|
VCM_SKIP_AUTH: 'true',
|
|
389
|
-
// Ensure NODE_PATH includes the monorepo node_modules if it exists
|
|
390
406
|
NODE_PATH: [
|
|
391
407
|
path.join(__dirname, '../../node_modules'),
|
|
392
408
|
path.join(__dirname, '../../../node_modules'),
|
|
@@ -394,13 +410,6 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
394
410
|
].filter(Boolean).join(path.delimiter)
|
|
395
411
|
};
|
|
396
412
|
|
|
397
|
-
// Log the command being executed
|
|
398
|
-
console.log(`[AGENT CHECK] Starting check for ${providerId}`);
|
|
399
|
-
console.log(`[AGENT CHECK] Node Executable: ${NODE_EXECUTABLE}`);
|
|
400
|
-
console.log(`[AGENT CHECK] Args: ${args.join(' ')}`);
|
|
401
|
-
console.log(`[AGENT CHECK] CWD: ${repoPath}`);
|
|
402
|
-
console.log(`[AGENT CHECK] Result file: ${resultFile}`);
|
|
403
|
-
|
|
404
413
|
child = spawn(NODE_EXECUTABLE, args, {
|
|
405
414
|
cwd: repoPath,
|
|
406
415
|
env: spawnEnv,
|
|
@@ -435,13 +444,11 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
435
444
|
console.log(`[AGENT CHECK] ${providerId} process exited with code ${code}`);
|
|
436
445
|
console.log(`[AGENT CHECK] ${providerId} process output: ${output.slice(-500)}`);
|
|
437
446
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
console.log(`[AGENT CHECK]
|
|
441
|
-
console.log(`[AGENT CHECK] Windsurf output analysis:`, output.split('\n').slice(-10));
|
|
447
|
+
if (providerId === 'devin' && code === 8) {
|
|
448
|
+
console.log(`[AGENT CHECK] Devin specific debugging - code 8 often indicates authentication or startup issues`);
|
|
449
|
+
console.log(`[AGENT CHECK] Devin output analysis:`, output.split('\n').slice(-10));
|
|
442
450
|
}
|
|
443
451
|
|
|
444
|
-
// Check for DONE status in output (indicates successful completion)
|
|
445
452
|
if (code === 0 && output.includes('Status: ✅ DONE') && output.includes('Requirement complete')) {
|
|
446
453
|
console.log(`[AGENT CHECK] Detected DONE in console output for ${providerId}`);
|
|
447
454
|
console.log(`[AGENT CHECK] ✅ Test PASSED: Agent reached DONE status - communication verified`);
|
|
@@ -450,9 +457,24 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
450
457
|
return;
|
|
451
458
|
}
|
|
452
459
|
|
|
453
|
-
|
|
460
|
+
if (code === 0 && def.type === 'direct' && (output.includes('No requirements') || output.includes('No more TODO'))) {
|
|
461
|
+
console.log(`[AGENT CHECK] ${providerId} CLI exited cleanly — marking operational`);
|
|
462
|
+
if (onProgress) onProgress(providerId, 'response_detected', null, 'CLI verified operational.');
|
|
463
|
+
done({ status: 'success', message: `${providerId} CLI is operational`, checkedAt });
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
454
467
|
checkResult();
|
|
455
468
|
if (!resolved) {
|
|
469
|
+
// Detect rate-limit / credit-balance conditions — treat as rateLimited, not a config error
|
|
470
|
+
const isRateLimited = /credit balance is too low/i.test(output) ||
|
|
471
|
+
(/rate.?limit/i.test(output) && /no providers available/i.test(output));
|
|
472
|
+
if (isRateLimited) {
|
|
473
|
+
console.log(`[AGENT CHECK] ${providerId} detected as rate-limited via output scan`);
|
|
474
|
+
done({ status: 'error', rateLimited: true, message: 'Rate limited (credit balance low or quota exceeded)', checkedAt });
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
|
|
456
478
|
const tail = output.slice(-300).trim().replace(/\n/g, ' ');
|
|
457
479
|
let codeInfo = '';
|
|
458
480
|
if (code === 4294967295 || code === -1) {
|
|
@@ -468,9 +490,8 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
468
490
|
|
|
469
491
|
const errorResult = { status: 'error', message: `Automation exited (code ${code})${codeInfo}${tail ? ': ' + tail : ''}`, checkedAt };
|
|
470
492
|
|
|
471
|
-
// For IDE providers, check for quota limit (UI + process output)
|
|
472
493
|
if (def.type === 'ide') {
|
|
473
|
-
checkIDEQuotaLimitAndDone(providerId, errorResult).catch(err => {
|
|
494
|
+
checkIDEQuotaLimitAndDone(providerId, errorResult, output, done).catch(err => {
|
|
474
495
|
console.error('[AGENT CHECK] Error in quota check:', err);
|
|
475
496
|
done(errorResult);
|
|
476
497
|
});
|
|
@@ -479,138 +500,6 @@ async function runAgentCheck(providerId, def, repoPath, resultFile, timeoutMs, s
|
|
|
479
500
|
}
|
|
480
501
|
}
|
|
481
502
|
});
|
|
482
|
-
|
|
483
|
-
// Helper function to check IDE quota limits and call done with enriched result
|
|
484
|
-
async function checkIDEQuotaLimitAndDone(providerId, errorResult) {
|
|
485
|
-
const debugLog = (msg) => {
|
|
486
|
-
const timestamp = new Date().toISOString();
|
|
487
|
-
const logLine = `[${timestamp}] ${msg}\n`;
|
|
488
|
-
try {
|
|
489
|
-
fs.appendFileSync(`/tmp/vibe-${providerId}-quota-debug.log`, logLine);
|
|
490
|
-
} catch (_) { }
|
|
491
|
-
console.log(`[AGENT CHECK] ${msg}`);
|
|
492
|
-
};
|
|
493
|
-
|
|
494
|
-
debugLog(`Starting checkIDEQuotaLimitAndDone for ${providerId}`);
|
|
495
|
-
debugLog('errorResult.message: ' + JSON.stringify(errorResult.message).substring(0, 200));
|
|
496
|
-
|
|
497
|
-
try {
|
|
498
|
-
debugLog(`Checking for ${providerId} quota limit...`);
|
|
499
|
-
|
|
500
|
-
// Check process output first for quota error keywords
|
|
501
|
-
const lowerOutput = output.toLowerCase();
|
|
502
|
-
const lowerErrorMsg = errorResult.message.toLowerCase();
|
|
503
|
-
debugLog('Checking process output length: ' + output.length);
|
|
504
|
-
debugLog('Process output sample: ' + output.substring(0, 300));
|
|
505
|
-
|
|
506
|
-
// Check both output and error message for quota keywords
|
|
507
|
-
const quotaKeywords = ['quota', 'rate limit', 'resource_exhausted', 'usage limit', 'model quota', 'limit exceeded', 'spending cap', 'usage cap', 'you\'ve reached your monthly chat messages quota', 'upgrade to copilot pro', 'wait for your allowance to renew'];
|
|
508
|
-
const hasQuotaKeyword = quotaKeywords.some(kw => lowerOutput.includes(kw) || lowerErrorMsg.includes(kw));
|
|
509
|
-
|
|
510
|
-
if (hasQuotaKeyword) {
|
|
511
|
-
debugLog(`🚨 Quota keywords found in process output or message for ${providerId}`);
|
|
512
|
-
errorResult.rateLimited = true;
|
|
513
|
-
errorResult.rateLimitMessage = output || errorResult.message;
|
|
514
|
-
// Set provider-specific rate limit flags for compatibility
|
|
515
|
-
switch (providerId) {
|
|
516
|
-
case 'antigravity':
|
|
517
|
-
errorResult.antigravityRateLimited = true;
|
|
518
|
-
break;
|
|
519
|
-
case 'windsurf':
|
|
520
|
-
errorResult.windsurfRateLimited = true;
|
|
521
|
-
break;
|
|
522
|
-
case 'cursor':
|
|
523
|
-
errorResult.cursorRateLimited = true;
|
|
524
|
-
break;
|
|
525
|
-
case 'github-copilot':
|
|
526
|
-
errorResult.githubCopilotRateLimited = true;
|
|
527
|
-
break;
|
|
528
|
-
}
|
|
529
|
-
debugLog('Set rateLimited to true, calling done()');
|
|
530
|
-
done(errorResult);
|
|
531
|
-
return;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
debugLog(`No quota keywords in process output or message, checking platform-specific UI fallback for ${providerId}`);
|
|
535
|
-
|
|
536
|
-
// Get quota manager based on platform
|
|
537
|
-
let quotaManager = null;
|
|
538
|
-
if (process.platform === 'darwin') {
|
|
539
|
-
const { AppleScriptManager } = require('vibecodingmachine-core');
|
|
540
|
-
quotaManager = new AppleScriptManager();
|
|
541
|
-
} else if (process.platform === 'win32') {
|
|
542
|
-
const { WindowsAutomationManager } = require('vibecodingmachine-core');
|
|
543
|
-
quotaManager = new WindowsAutomationManager();
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// Check platform-specific UI scraping as fallback for IDEs that support it
|
|
547
|
-
if (quotaManager) {
|
|
548
|
-
try {
|
|
549
|
-
let quotaCheck = null;
|
|
550
|
-
|
|
551
|
-
// Use specific quota detection methods for each IDE
|
|
552
|
-
switch (providerId) {
|
|
553
|
-
case 'antigravity':
|
|
554
|
-
quotaCheck = await quotaManager.checkAntigravityQuotaLimit();
|
|
555
|
-
break;
|
|
556
|
-
case 'windsurf':
|
|
557
|
-
quotaCheck = await quotaManager.checkWindsurfQuotaLimit();
|
|
558
|
-
break;
|
|
559
|
-
case 'cursor':
|
|
560
|
-
quotaCheck = await quotaManager.checkCursorQuotaLimit();
|
|
561
|
-
break;
|
|
562
|
-
case 'github-copilot':
|
|
563
|
-
// GitHub Copilot uses the same detection as Cursor (both are VS Code extensions)
|
|
564
|
-
quotaCheck = await quotaManager.checkCursorQuotaLimit();
|
|
565
|
-
break;
|
|
566
|
-
default:
|
|
567
|
-
debugLog(`No specific quota detection method available for ${providerId}`);
|
|
568
|
-
break;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
debugLog(`${providerId} quota check result: ` + JSON.stringify(quotaCheck));
|
|
572
|
-
|
|
573
|
-
if (quotaCheck && (quotaCheck.isRateLimited || quotaCheck.hasQuotaWarning)) {
|
|
574
|
-
debugLog(`🚨 ${providerId} quota limit detected via platform UI check`);
|
|
575
|
-
errorResult.rateLimited = true;
|
|
576
|
-
errorResult.rateLimitMessage = quotaCheck.message || quotaCheck.matchedText || `${providerId} quota limit detected`;
|
|
577
|
-
if (quotaCheck.resumeAt) {
|
|
578
|
-
errorResult.rateLimitResume = quotaCheck.resumeAt;
|
|
579
|
-
}
|
|
580
|
-
// Set provider-specific rate limit flags for compatibility
|
|
581
|
-
switch (providerId) {
|
|
582
|
-
case 'antigravity':
|
|
583
|
-
errorResult.antigravityRateLimited = true;
|
|
584
|
-
break;
|
|
585
|
-
case 'windsurf':
|
|
586
|
-
errorResult.windsurfRateLimited = true;
|
|
587
|
-
break;
|
|
588
|
-
case 'cursor':
|
|
589
|
-
errorResult.cursorRateLimited = true;
|
|
590
|
-
break;
|
|
591
|
-
case 'github-copilot':
|
|
592
|
-
errorResult.githubCopilotRateLimited = true;
|
|
593
|
-
break;
|
|
594
|
-
}
|
|
595
|
-
debugLog('Enriched error result with quota limit');
|
|
596
|
-
} else {
|
|
597
|
-
debugLog(`No rate limit detected for ${providerId}`);
|
|
598
|
-
}
|
|
599
|
-
} catch (appleScriptError) {
|
|
600
|
-
debugLog(`AppleScript quota detection failed for ${providerId}: ${appleScriptError.message}`);
|
|
601
|
-
}
|
|
602
|
-
} else {
|
|
603
|
-
debugLog(`Skipping AppleScript quota detection for ${providerId} on non-macOS platform`);
|
|
604
|
-
}
|
|
605
|
-
} catch (err) {
|
|
606
|
-
debugLog(`Error checking ${providerId} quota: ${err.message}`);
|
|
607
|
-
} finally {
|
|
608
|
-
debugLog('Calling done() with final errorResult');
|
|
609
|
-
debugLog('Final errorResult.rateLimited: ' + errorResult.rateLimited);
|
|
610
|
-
debugLog('Final errorResult.rateLimitMessage: ' + (errorResult.rateLimitMessage ? errorResult.rateLimitMessage.substring(0, 100) : 'none'));
|
|
611
|
-
done(errorResult);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
503
|
});
|
|
615
504
|
}
|
|
616
505
|
|