vibecodingmachine-cli 2026.2.26-1739 → 2026.3.9-850
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 -1
- package/bin/commands/agent-commands.js +150 -228
- package/bin/commands/command-aliases.js +68 -0
- package/bin/vibecodingmachine.js +1 -2
- package/package.json +2 -2
- package/src/commands/agents/list.js +71 -115
- package/src/commands/agents-check.js +16 -4
- package/src/commands/analyze-file-sizes.js +1 -1
- package/src/commands/auto-direct/auto-provider-manager.js +290 -0
- package/src/commands/auto-direct/auto-status-display.js +331 -0
- package/src/commands/auto-direct/auto-utils.js +439 -0
- package/src/commands/auto-direct/file-operations.js +110 -0
- package/src/commands/auto-direct/provider-config.js +1 -1
- package/src/commands/auto-direct/provider-manager.js +1 -1
- package/src/commands/auto-direct/status-display.js +1 -1
- package/src/commands/auto-direct/utils.js +24 -18
- package/src/commands/auto-direct-refactored.js +413 -0
- package/src/commands/auto-direct.js +594 -188
- package/src/commands/requirements/commands.js +353 -0
- package/src/commands/requirements/default-handlers.js +272 -0
- package/src/commands/requirements/disable.js +97 -0
- package/src/commands/requirements/enable.js +97 -0
- package/src/commands/requirements/utils.js +194 -0
- package/src/commands/requirements-refactored.js +60 -0
- package/src/commands/requirements.js +38 -771
- package/src/commands/specs/disable.js +96 -0
- package/src/commands/specs/enable.js +96 -0
- package/src/trui/TruiInterface.js +5 -11
- package/src/trui/agents/AgentInterface.js +24 -396
- package/src/trui/agents/handlers/CommandHandler.js +93 -0
- package/src/trui/agents/handlers/ContextManager.js +117 -0
- package/src/trui/agents/handlers/DisplayHandler.js +243 -0
- package/src/trui/agents/handlers/HelpHandler.js +51 -0
- package/src/utils/auth.js +13 -111
- package/src/utils/config.js +5 -1
- package/src/utils/interactive/requirements-navigation.js +17 -15
- package/src/utils/interactive-broken.js +2 -2
- package/src/utils/provider-checker/agent-runner.js +15 -1
- package/src/utils/provider-checker/cli-installer.js +149 -7
- package/src/utils/provider-checker/opencode-checker.js +588 -0
- package/src/utils/provider-checker/provider-validator.js +88 -3
- package/src/utils/provider-checker/time-formatter.js +3 -2
- package/src/utils/provider-manager.js +28 -20
- package/src/utils/provider-registry.js +35 -3
- package/src/utils/requirements-navigator/index.js +94 -0
- package/src/utils/requirements-navigator/input-handler.js +217 -0
- package/src/utils/requirements-navigator/section-loader.js +188 -0
- package/src/utils/requirements-navigator/tree-builder.js +105 -0
- package/src/utils/requirements-navigator/tree-renderer.js +50 -0
- package/src/utils/requirements-navigator.js +2 -583
- package/src/utils/trui-clarifications.js +188 -0
- package/src/utils/trui-feedback.js +54 -1
- package/src/utils/trui-kiro-integration.js +398 -0
- package/src/utils/trui-main-handlers.js +194 -0
- package/src/utils/trui-main-menu.js +235 -0
- package/src/utils/trui-nav-agents.js +178 -25
- package/src/utils/trui-nav-requirements.js +203 -27
- package/src/utils/trui-nav-settings.js +114 -1
- package/src/utils/trui-nav-specifications.js +44 -3
- package/src/utils/trui-navigation-backup.js +603 -0
- package/src/utils/trui-navigation.js +70 -228
- package/src/utils/trui-provider-health.js +274 -0
- package/src/utils/trui-provider-manager.js +376 -0
- package/src/utils/trui-quick-menu.js +25 -1
- package/src/utils/trui-req-actions-backup.js +507 -0
- package/src/utils/trui-req-actions.js +148 -216
- package/src/utils/trui-req-editor.js +170 -0
- package/src/utils/trui-req-file-ops.js +278 -0
- package/src/utils/trui-req-tree-old.js +719 -0
- package/src/utils/trui-req-tree.js +348 -627
- package/src/utils/trui-specifications.js +25 -7
- package/src/utils/trui-windsurf.js +231 -10
- package/src/utils/welcome-screen-extracted.js +2 -2
- package/src/utils/welcome-screen.js +2 -2
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
const {
|
|
9
|
+
getProviderDefinitions,
|
|
10
|
+
getProviderDisplayName,
|
|
11
|
+
getDefaultProviderOrder,
|
|
12
|
+
mergeProviderPreferences
|
|
13
|
+
} = require('../../utils/provider-registry');
|
|
14
|
+
const { getAutoConfig } = require('../../../utils/config');
|
|
15
|
+
const { checkAllProviders } = require('../../utils/provider-checker');
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* CLI list agents command implementation
|
|
@@ -21,28 +23,12 @@ class ListAgentsCommand {
|
|
|
21
23
|
* @param {Object} options - Command options
|
|
22
24
|
*/
|
|
23
25
|
constructor(options = {}) {
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
fileManager: new FileManager()
|
|
27
|
-
});
|
|
28
|
-
this.fileManager = options.fileManager || new FileManager();
|
|
29
|
-
|
|
30
|
-
// Initialize RUI components
|
|
31
|
-
this.agentCommands = new AgentCommands({
|
|
32
|
-
configManager: this.configManager,
|
|
33
|
-
logger: this.logger,
|
|
34
|
-
fileManager: this.fileManager
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
this.responseFormatter = new AgentResponseFormatter({
|
|
38
|
-
defaultFormat: 'table',
|
|
39
|
-
includeTimestamp: true,
|
|
40
|
-
prettyPrint: options.pretty !== false
|
|
41
|
-
});
|
|
26
|
+
this.config = getAutoConfig();
|
|
27
|
+
this.providerPreferences = this.config.providerPreferences || {};
|
|
42
28
|
}
|
|
43
29
|
|
|
44
30
|
/**
|
|
45
|
-
* Execute list agents command using
|
|
31
|
+
* Execute list agents command using provider registry (matches GUI)
|
|
46
32
|
* @param {Object} args - Command arguments
|
|
47
33
|
* @param {Object} options - Command options
|
|
48
34
|
* @returns {Promise<Object>} - Command result
|
|
@@ -57,25 +43,45 @@ class ListAgentsCommand {
|
|
|
57
43
|
} = this.parseArguments(args, options);
|
|
58
44
|
|
|
59
45
|
try {
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
// Get provider definitions (same source as GUI)
|
|
47
|
+
const definitions = getProviderDefinitions();
|
|
48
|
+
const prefs = this.providerPreferences;
|
|
49
|
+
let order = Array.isArray(prefs.order) ? prefs.order.slice() : getDefaultProviderOrder();
|
|
50
|
+
let enabled = { ...prefs.enabled };
|
|
51
|
+
|
|
52
|
+
// Filter agents based on preferences
|
|
53
|
+
let agents = definitions.map(def => ({
|
|
54
|
+
id: def.id,
|
|
55
|
+
name: getProviderDisplayName(def.id),
|
|
56
|
+
description: def.description || '',
|
|
57
|
+
type: def.type || 'unknown',
|
|
58
|
+
enabled: enabled[def.id] !== false,
|
|
59
|
+
category: def.category || 'unknown',
|
|
60
|
+
estimatedSpeed: def.estimatedSpeed || 0
|
|
61
|
+
}));
|
|
62
|
+
|
|
63
|
+
// Apply disabled filter
|
|
64
|
+
if (!includeDisabled) {
|
|
65
|
+
agents = agents.filter(agent => agent.enabled);
|
|
66
|
+
}
|
|
68
67
|
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
// Add status information if requested
|
|
69
|
+
if (includeStatus) {
|
|
70
|
+
const { getProviderCache } = require('../../utils/provider-registry');
|
|
71
|
+
const savedCache = await getProviderCache();
|
|
72
|
+
|
|
73
|
+
agents = agents.map(agent => ({
|
|
74
|
+
...agent,
|
|
75
|
+
installed: savedCache[agent.id]?.installed || false,
|
|
76
|
+
status: savedCache[agent.id]?.installed ?
|
|
77
|
+
(agent.enabled ? 'ENABLED' : 'DISABLED') :
|
|
78
|
+
'NOT_INSTALLED',
|
|
79
|
+
statusDescription: savedCache[agent.id]?.installed ?
|
|
80
|
+
(agent.enabled ? 'Enabled' : 'Disabled') :
|
|
81
|
+
'Not installed'
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
75
84
|
|
|
76
|
-
// Apply additional filtering and sorting
|
|
77
|
-
let agents = formattedResponse.data?.agents || [];
|
|
78
|
-
|
|
79
85
|
// Apply status filter
|
|
80
86
|
if (filterStatus) {
|
|
81
87
|
agents = agents.filter(agent => agent.status === filterStatus);
|
|
@@ -88,9 +94,8 @@ class ListAgentsCommand {
|
|
|
88
94
|
this.outputResults(agents, format, includeStatus);
|
|
89
95
|
|
|
90
96
|
return {
|
|
91
|
-
success:
|
|
97
|
+
success: true,
|
|
92
98
|
agents,
|
|
93
|
-
formatted: formattedResponse,
|
|
94
99
|
count: agents.length,
|
|
95
100
|
message: `Listed ${agents.length} agents`
|
|
96
101
|
};
|
|
@@ -179,24 +184,20 @@ class ListAgentsCommand {
|
|
|
179
184
|
}
|
|
180
185
|
|
|
181
186
|
/**
|
|
182
|
-
*
|
|
183
|
-
* @param {
|
|
184
|
-
* @
|
|
185
|
-
* @returns {Promise<Array>} - Filtered agents
|
|
187
|
+
* Get status description
|
|
188
|
+
* @param {string} status - Status code
|
|
189
|
+
* @returns {string} - Human-readable description
|
|
186
190
|
*/
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
return filteredAgents;
|
|
191
|
+
getStatusDescription(status) {
|
|
192
|
+
const descriptions = {
|
|
193
|
+
'NOT_INSTALLED': 'Not installed',
|
|
194
|
+
'ENABLED': 'Enabled',
|
|
195
|
+
'DISABLED': 'Disabled',
|
|
196
|
+
'ERROR': 'Error occurred',
|
|
197
|
+
'RATE_LIMITED': 'Rate limited'
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
return descriptions[status] || 'Unknown';
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
/**
|
|
@@ -222,52 +223,7 @@ class ListAgentsCommand {
|
|
|
222
223
|
});
|
|
223
224
|
}
|
|
224
225
|
|
|
225
|
-
|
|
226
|
-
* Add status information to agents
|
|
227
|
-
* @param {Array<Object>} agents - Agents to enhance
|
|
228
|
-
* @returns {Promise<Array>} - Agents with status info
|
|
229
|
-
*/
|
|
230
|
-
async addStatusInfo(agents) {
|
|
231
|
-
const agentsWithStatus = [];
|
|
232
|
-
|
|
233
|
-
for (const agent of agents) {
|
|
234
|
-
const status = await this.configManager.getAgentStatus(agent.id);
|
|
235
|
-
|
|
236
|
-
agentsWithStatus.push({
|
|
237
|
-
...agent,
|
|
238
|
-
status: status ? status.status : AgentStatus.NOT_INSTALLED,
|
|
239
|
-
statusDescription: this.getStatusDescription(status ? status.status : AgentStatus.NOT_INSTALLED),
|
|
240
|
-
lastChecked: status ? status.lastChecked : null,
|
|
241
|
-
lastVerified: status ? status.lastVerified : null,
|
|
242
|
-
statusMessage: status ? status.message : '',
|
|
243
|
-
canInstall: agent.enabled && (!status || status.status === AgentStatus.NOT_INSTALLED),
|
|
244
|
-
canVerify: agent.enabled && status && [AgentStatus.INSTALLED, AgentStatus.VERIFIED].includes(status.status)
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return agentsWithStatus;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Get status description
|
|
253
|
-
* @param {string} status - Status code
|
|
254
|
-
* @returns {string} - Human-readable description
|
|
255
|
-
*/
|
|
256
|
-
getStatusDescription(status) {
|
|
257
|
-
const descriptions = {
|
|
258
|
-
[AgentStatus.NOT_INSTALLED]: 'Not installed',
|
|
259
|
-
[AgentStatus.INSTALLING]: 'Installing...',
|
|
260
|
-
[AgentStatus.INSTALLED]: 'Installed (not verified)',
|
|
261
|
-
[AgentStatus.VERIFYING]: 'Verifying...',
|
|
262
|
-
[AgentStatus.VERIFIED]: 'Verified and ready',
|
|
263
|
-
[AgentStatus.ERROR]: 'Error occurred',
|
|
264
|
-
[AgentStatus.RATE_LIMITED]: 'Rate limited',
|
|
265
|
-
[AgentStatus.DISABLED]: 'Disabled'
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
return descriptions[status] || 'Unknown';
|
|
269
|
-
}
|
|
270
|
-
|
|
226
|
+
|
|
271
227
|
/**
|
|
272
228
|
* Output results in specified format
|
|
273
229
|
* @param {Array} agents - Agents to output
|
|
@@ -393,7 +349,7 @@ class ListAgentsCommand {
|
|
|
393
349
|
*/
|
|
394
350
|
showHelp() {
|
|
395
351
|
console.log('\n=== LIST AGENTS COMMAND ===');
|
|
396
|
-
console.log('Description: List all
|
|
352
|
+
console.log('Description: List all available agents (providers)');
|
|
397
353
|
console.log('');
|
|
398
354
|
console.log('Usage: app list agents [options]');
|
|
399
355
|
console.log('');
|
|
@@ -401,15 +357,15 @@ class ListAgentsCommand {
|
|
|
401
357
|
console.log(' --all, -a Include disabled agents');
|
|
402
358
|
console.log(' --no-status Exclude status information');
|
|
403
359
|
console.log(' --format <format> Output format: table, json, csv (default: table)');
|
|
404
|
-
console.log(' --sort <field> Sort by: name, status, type,
|
|
405
|
-
console.log(' --status <status> Filter by status (NOT_INSTALLED,
|
|
360
|
+
console.log(' --sort <field> Sort by: name, status, type, category (default: name)');
|
|
361
|
+
console.log(' --status <status> Filter by status (NOT_INSTALLED, ENABLED, DISABLED, etc.)');
|
|
406
362
|
console.log('');
|
|
407
363
|
console.log('Examples:');
|
|
408
364
|
console.log(' app list agents');
|
|
409
365
|
console.log(' app list agents --all');
|
|
410
366
|
console.log(' app list agents --format json');
|
|
411
367
|
console.log(' app list agents --sort status');
|
|
412
|
-
console.log(' app list agents --status
|
|
368
|
+
console.log(' app list agents --status ENABLED');
|
|
413
369
|
}
|
|
414
370
|
|
|
415
371
|
/**
|
|
@@ -419,14 +375,14 @@ class ListAgentsCommand {
|
|
|
419
375
|
getCommandInfo() {
|
|
420
376
|
return {
|
|
421
377
|
name: 'list-agents',
|
|
422
|
-
description: 'List all
|
|
378
|
+
description: 'List all available agents (providers)',
|
|
423
379
|
usage: 'app list agents [options]',
|
|
424
380
|
examples: [
|
|
425
381
|
'app list agents',
|
|
426
382
|
'app list agents --all',
|
|
427
383
|
'app list agents --format json',
|
|
428
384
|
'app list agents --sort status',
|
|
429
|
-
'app list agents --status
|
|
385
|
+
'app list agents --status ENABLED'
|
|
430
386
|
],
|
|
431
387
|
options: [
|
|
432
388
|
{
|
|
@@ -443,11 +399,11 @@ class ListAgentsCommand {
|
|
|
443
399
|
},
|
|
444
400
|
{
|
|
445
401
|
flag: '--sort <field>',
|
|
446
|
-
description: 'Sort by: name, status, type,
|
|
402
|
+
description: 'Sort by: name, status, type, category (default: name)'
|
|
447
403
|
},
|
|
448
404
|
{
|
|
449
405
|
flag: '--status <status>',
|
|
450
|
-
description: 'Filter by status (NOT_INSTALLED,
|
|
406
|
+
description: 'Filter by status (NOT_INSTALLED, ENABLED, DISABLED, etc.)'
|
|
451
407
|
}
|
|
452
408
|
]
|
|
453
409
|
};
|
|
@@ -8,12 +8,24 @@ const { checkAllProviders, formatCheckedAt } = require('../utils/provider-checke
|
|
|
8
8
|
async function checkAgents(options = {}) {
|
|
9
9
|
const config = await getAutoConfig();
|
|
10
10
|
const definitions = getProviderDefinitions();
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const { getProviderPreferences } = require('../utils/provider-registry');
|
|
12
|
+
const prefs = await getProviderPreferences();
|
|
13
|
+
|
|
14
|
+
// Only check enabled providers unless a specific provider is requested
|
|
15
|
+
let providerIds;
|
|
16
|
+
if (options.enabledOnly && options.enabledAgents) {
|
|
17
|
+
// Use the enabled agents from the provider manager context
|
|
18
|
+
providerIds = definitions.filter(d => options.enabledAgents[d.id] !== false).map(d => d.id);
|
|
19
|
+
} else if (options.provider) {
|
|
20
|
+
providerIds = definitions.filter(d => d.id === options.provider).map(d => d.id);
|
|
21
|
+
} else {
|
|
22
|
+
// Use global enabled preferences
|
|
23
|
+
const prefs = await getProviderPreferences();
|
|
24
|
+
providerIds = definitions.filter(d => prefs.enabled[d.id] !== false).map(d => d.id);
|
|
25
|
+
}
|
|
14
26
|
|
|
15
27
|
if (providerIds.length === 0) {
|
|
16
|
-
console.log(chalk.red(`\n✗
|
|
28
|
+
console.log(chalk.red(`\n✗ No enabled agents to check. Enable agents first.\n`));
|
|
17
29
|
return;
|
|
18
30
|
}
|
|
19
31
|
|
|
@@ -19,7 +19,7 @@ const { StrategyGenerator } = require('@vibecodingmachine/core/src/analysis/stra
|
|
|
19
19
|
const { PriorityCalculator } = require('@vibecodingmachine/core/src/analysis/priority-calculator');
|
|
20
20
|
const { AnalysisReporter } = require('@vibecodingmachine/core/src/analysis/analysis-reporter');
|
|
21
21
|
const { FileAnalysis } = require('@vibecodingmachine/core/src/models/file-analysis');
|
|
22
|
-
const { FileAnalysisCollection } = require('@vibecodingmachine/core/src/models/file-analysis');
|
|
22
|
+
const { FileAnalysisCollection } = require('@vibecodingmachine/core/src/models/file-analysis-collection');
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Analyze file sizes command
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto Mode Provider Management
|
|
3
|
+
*
|
|
4
|
+
* Handles LLM provider configuration and management for auto mode
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const vibecodingmachineCore = require('vibecodingmachine-core');
|
|
8
|
+
const { getProviderPreferences, getProviderDefinition, saveProviderPreferences } = require('../../utils/provider-registry');
|
|
9
|
+
const ProviderManager = require('vibecodingmachine-core/src/ide-integration/provider-manager.cjs');
|
|
10
|
+
const { checkAntigravityRateLimit, handleAntigravityRateLimit } = require('../../utils/antigravity-js-handler');
|
|
11
|
+
const { checkKiroRateLimit, handleKiroRateLimit } = require('../../utils/kiro-js-handler');
|
|
12
|
+
const { checkClineRateLimit, handleClineRateLimit } = require('../../utils/cline-js-handler');
|
|
13
|
+
const { DirectLLMManager } = vibecodingmachineCore;
|
|
14
|
+
|
|
15
|
+
// Shared instances to track rate limits and health across all function calls
|
|
16
|
+
const sharedProviderManager = new ProviderManager();
|
|
17
|
+
const sharedHealthTracker = vibecodingmachineCore.IDEHealthTracker;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Auto-install Cline CLI if not available
|
|
21
|
+
*/
|
|
22
|
+
async function ensureClineInstalled(forceInstall = false) {
|
|
23
|
+
const llm = new DirectLLMManager();
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const isAvailable = await llm.isClineAvailable();
|
|
27
|
+
if (isAvailable && !forceInstall) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log('Installing Cline CLI...');
|
|
32
|
+
const installResult = await llm.installCline();
|
|
33
|
+
|
|
34
|
+
if (installResult.success) {
|
|
35
|
+
console.log('✓ Cline CLI installed successfully');
|
|
36
|
+
return true;
|
|
37
|
+
} else {
|
|
38
|
+
console.error('✗ Failed to install Cline CLI:', installResult.error);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('✗ Error installing Cline CLI:', error.message);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get all available provider configurations
|
|
49
|
+
*/
|
|
50
|
+
async function getAllAvailableProviders() {
|
|
51
|
+
const config = await vibecodingmachineCore.getAutoConfig();
|
|
52
|
+
const prefs = await getProviderPreferences();
|
|
53
|
+
|
|
54
|
+
const providers = [];
|
|
55
|
+
const skipped = [];
|
|
56
|
+
|
|
57
|
+
// Check each provider in configuration
|
|
58
|
+
for (const [providerName, providerConfig] of Object.entries(config.providers || {})) {
|
|
59
|
+
if (!providerConfig.enabled) {
|
|
60
|
+
skipped.push({ provider: providerName, reason: 'disabled' });
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Check if provider is skipped in preferences
|
|
65
|
+
if (prefs.skippedProviders && prefs.skippedProviders.includes(providerName)) {
|
|
66
|
+
skipped.push({ provider: providerName, reason: 'user_skipped' });
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Check provider-specific requirements
|
|
71
|
+
let canUse = true;
|
|
72
|
+
let reason = null;
|
|
73
|
+
|
|
74
|
+
switch (providerName) {
|
|
75
|
+
case 'anthropic':
|
|
76
|
+
if (!providerConfig.apiKey) {
|
|
77
|
+
canUse = false;
|
|
78
|
+
reason = 'missing_api_key';
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
|
|
82
|
+
case 'openai':
|
|
83
|
+
if (!providerConfig.apiKey) {
|
|
84
|
+
canUse = false;
|
|
85
|
+
reason = 'missing_api_key';
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
case 'ollama':
|
|
90
|
+
if (!providerConfig.baseUrl) {
|
|
91
|
+
canUse = false;
|
|
92
|
+
reason = 'missing_base_url';
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
|
|
96
|
+
case 'groq':
|
|
97
|
+
if (!providerConfig.apiKey) {
|
|
98
|
+
canUse = false;
|
|
99
|
+
reason = 'missing_api_key';
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
|
|
103
|
+
case 'bedrock':
|
|
104
|
+
if (!providerConfig.region || !providerConfig.accessKeyId) {
|
|
105
|
+
canUse = false;
|
|
106
|
+
reason = 'missing_credentials';
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (canUse) {
|
|
112
|
+
providers.push({
|
|
113
|
+
name: providerName,
|
|
114
|
+
config: providerConfig,
|
|
115
|
+
definition: await getProviderDefinition(providerName)
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
skipped.push({ provider: providerName, reason });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return { providers, skipped };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Get provider configuration with automatic failover
|
|
127
|
+
*/
|
|
128
|
+
async function getProviderConfig(excludeProvider = null) {
|
|
129
|
+
const config = await vibecodingmachineCore.getAutoConfig();
|
|
130
|
+
const providerManager = sharedProviderManager; // Use shared instance to persist rate limit state
|
|
131
|
+
const { providers, skipped } = await getAllAvailableProviders();
|
|
132
|
+
|
|
133
|
+
// Filter out excluded provider
|
|
134
|
+
const availableProviders = providers.filter(p => p.name !== excludeProvider);
|
|
135
|
+
|
|
136
|
+
if (availableProviders.length === 0) {
|
|
137
|
+
throw new Error('No available providers. Check configuration and API keys.');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Check each provider for rate limits and availability
|
|
141
|
+
for (const provider of availableProviders) {
|
|
142
|
+
const providerName = provider.name;
|
|
143
|
+
|
|
144
|
+
// Check provider-specific rate limits
|
|
145
|
+
let isRateLimited = false;
|
|
146
|
+
let rateLimitInfo = null;
|
|
147
|
+
|
|
148
|
+
switch (providerName) {
|
|
149
|
+
case 'antigravity':
|
|
150
|
+
isRateLimited = checkAntigravityRateLimit(providerManager);
|
|
151
|
+
if (isRateLimited) {
|
|
152
|
+
rateLimitInfo = handleAntigravityRateLimit(providerManager);
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
|
|
156
|
+
case 'kiro':
|
|
157
|
+
isRateLimited = checkKiroRateLimit(providerManager);
|
|
158
|
+
if (isRateLimited) {
|
|
159
|
+
rateLimitInfo = handleKiroRateLimit(providerManager);
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
|
|
163
|
+
case 'cline':
|
|
164
|
+
isRateLimited = checkClineRateLimit(providerManager);
|
|
165
|
+
if (isRateLimited) {
|
|
166
|
+
rateLimitInfo = handleClineRateLimit(providerManager);
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (isRateLimited) {
|
|
172
|
+
console.warn(`Provider ${providerName} is rate limited:`, rateLimitInfo.message);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Check IDE health for provider
|
|
177
|
+
const ideHealth = sharedHealthTracker.getHealth(providerName);
|
|
178
|
+
if (ideHealth && ideHealth.consecutiveFailures >= 3) {
|
|
179
|
+
console.warn(`Provider ${providerName} has ${ideHealth.consecutiveFailures} consecutive failures`);
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Return first available provider
|
|
184
|
+
return {
|
|
185
|
+
provider: providerName,
|
|
186
|
+
config: provider.config,
|
|
187
|
+
definition: provider.definition,
|
|
188
|
+
manager: providerManager
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// If we get here, all providers are rate limited or unhealthy
|
|
193
|
+
const rateLimitedProviders = availableProviders.filter(p => {
|
|
194
|
+
switch (p.name) {
|
|
195
|
+
case 'antigravity': return checkAntigravityRateLimit(providerManager);
|
|
196
|
+
case 'kiro': return checkKiroRateLimit(providerManager);
|
|
197
|
+
case 'cline': return checkClineRateLimit(providerManager);
|
|
198
|
+
default: return false;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
if (rateLimitedProviders.length > 0) {
|
|
203
|
+
const waitTime = Math.max(...rateLimitedProviders.map(p => {
|
|
204
|
+
switch (p.name) {
|
|
205
|
+
case 'antigravity': return handleAntigravityRateLimit(providerManager).waitTime || 60000;
|
|
206
|
+
case 'kiro': return handleKiroRateLimit(providerManager).waitTime || 60000;
|
|
207
|
+
case 'cline': return handleClineRateLimit(providerManager).waitTime || 60000;
|
|
208
|
+
default: return 60000;
|
|
209
|
+
}
|
|
210
|
+
}));
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
action: 'wait',
|
|
214
|
+
waitTime,
|
|
215
|
+
message: `All providers are rate limited. Waiting ${waitTime/1000}s before retry.`
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
throw new Error('All providers are unavailable or unhealthy.');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Handle provider failure and update tracking
|
|
224
|
+
*/
|
|
225
|
+
function handleProviderFailure(providerName, error) {
|
|
226
|
+
sharedHealthTracker.recordFailure(providerName, error);
|
|
227
|
+
|
|
228
|
+
// Mark provider as temporarily skipped if too many failures
|
|
229
|
+
const health = sharedHealthTracker.getHealth(providerName);
|
|
230
|
+
if (health && health.consecutiveFailures >= 3) {
|
|
231
|
+
console.warn(`Provider ${providerName} marked as temporarily unavailable due to failures`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Handle provider success and update tracking
|
|
237
|
+
*/
|
|
238
|
+
function handleProviderSuccess(providerName) {
|
|
239
|
+
sharedHealthTracker.recordSuccess(providerName);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if provider should be skipped due to health issues
|
|
244
|
+
*/
|
|
245
|
+
function shouldSkipProvider(providerName) {
|
|
246
|
+
const health = sharedHealthTracker.getHealth(providerName);
|
|
247
|
+
return health && health.consecutiveFailures >= 3;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Get provider health status
|
|
252
|
+
*/
|
|
253
|
+
function getProviderHealth(providerName) {
|
|
254
|
+
return sharedHealthTracker.getHealth(providerName);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Get all providers health status
|
|
259
|
+
*/
|
|
260
|
+
function getAllProvidersHealth() {
|
|
261
|
+
return sharedHealthTracker.getAllHealth();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Reset provider health tracking
|
|
266
|
+
*/
|
|
267
|
+
function resetProviderHealth(providerName) {
|
|
268
|
+
sharedHealthTracker.reset(providerName);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Listen for consecutive failures to warn user
|
|
272
|
+
sharedHealthTracker.on('consecutive-failures', ({ ideId, count, lastError }) => {
|
|
273
|
+
console.warn(`⚠️ Provider ${ideId} has ${count} consecutive failures`);
|
|
274
|
+
console.warn(` Last error: ${lastError.message}`);
|
|
275
|
+
console.warn(` Consider switching providers or checking configuration`);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
module.exports = {
|
|
279
|
+
ensureClineInstalled,
|
|
280
|
+
getAllAvailableProviders,
|
|
281
|
+
getProviderConfig,
|
|
282
|
+
handleProviderFailure,
|
|
283
|
+
handleProviderSuccess,
|
|
284
|
+
shouldSkipProvider,
|
|
285
|
+
getProviderHealth,
|
|
286
|
+
getAllProvidersHealth,
|
|
287
|
+
resetProviderHealth,
|
|
288
|
+
sharedProviderManager,
|
|
289
|
+
sharedHealthTracker
|
|
290
|
+
};
|