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
|
@@ -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
|
-
|
|
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 === '
|
|
75
|
-
console.log('🪟 [IDE MANAGER] Calling
|
|
76
|
-
result = await manager.
|
|
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
|
-
|
|
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;
|