vibecodingmachine-cli 2026.2.26-1739 → 2026.3.9-1621

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/bin/auth/auth-compliance.js +7 -1
  2. package/bin/commands/agent-commands.js +150 -228
  3. package/bin/commands/command-aliases.js +68 -0
  4. package/bin/vibecodingmachine.js +1 -2
  5. package/package.json +2 -2
  6. package/src/commands/agents/list.js +71 -115
  7. package/src/commands/agents-check.js +16 -4
  8. package/src/commands/analyze-file-sizes.js +1 -1
  9. package/src/commands/auto-direct/auto-provider-manager.js +290 -0
  10. package/src/commands/auto-direct/auto-status-display.js +331 -0
  11. package/src/commands/auto-direct/auto-utils.js +439 -0
  12. package/src/commands/auto-direct/file-operations.js +110 -0
  13. package/src/commands/auto-direct/provider-config.js +1 -1
  14. package/src/commands/auto-direct/provider-manager.js +1 -1
  15. package/src/commands/auto-direct/status-display.js +1 -1
  16. package/src/commands/auto-direct/utils.js +24 -18
  17. package/src/commands/auto-direct-refactored.js +413 -0
  18. package/src/commands/auto-direct.js +594 -188
  19. package/src/commands/requirements/commands.js +353 -0
  20. package/src/commands/requirements/default-handlers.js +272 -0
  21. package/src/commands/requirements/disable.js +97 -0
  22. package/src/commands/requirements/enable.js +97 -0
  23. package/src/commands/requirements/utils.js +194 -0
  24. package/src/commands/requirements-refactored.js +60 -0
  25. package/src/commands/requirements.js +38 -771
  26. package/src/commands/specs/disable.js +96 -0
  27. package/src/commands/specs/enable.js +96 -0
  28. package/src/trui/TruiInterface.js +5 -11
  29. package/src/trui/agents/AgentInterface.js +24 -396
  30. package/src/trui/agents/handlers/CommandHandler.js +93 -0
  31. package/src/trui/agents/handlers/ContextManager.js +117 -0
  32. package/src/trui/agents/handlers/DisplayHandler.js +243 -0
  33. package/src/trui/agents/handlers/HelpHandler.js +51 -0
  34. package/src/utils/auth.js +13 -111
  35. package/src/utils/config.js +5 -1
  36. package/src/utils/interactive/requirements-navigation.js +17 -15
  37. package/src/utils/interactive-broken.js +2 -2
  38. package/src/utils/provider-checker/agent-runner.js +15 -1
  39. package/src/utils/provider-checker/cli-installer.js +149 -7
  40. package/src/utils/provider-checker/opencode-checker.js +588 -0
  41. package/src/utils/provider-checker/provider-validator.js +88 -3
  42. package/src/utils/provider-checker/time-formatter.js +3 -2
  43. package/src/utils/provider-manager.js +28 -20
  44. package/src/utils/provider-registry.js +35 -3
  45. package/src/utils/requirements-navigator/index.js +94 -0
  46. package/src/utils/requirements-navigator/input-handler.js +217 -0
  47. package/src/utils/requirements-navigator/section-loader.js +188 -0
  48. package/src/utils/requirements-navigator/tree-builder.js +105 -0
  49. package/src/utils/requirements-navigator/tree-renderer.js +50 -0
  50. package/src/utils/requirements-navigator.js +2 -583
  51. package/src/utils/trui-clarifications.js +188 -0
  52. package/src/utils/trui-feedback.js +54 -1
  53. package/src/utils/trui-kiro-integration.js +398 -0
  54. package/src/utils/trui-main-handlers.js +194 -0
  55. package/src/utils/trui-main-menu.js +235 -0
  56. package/src/utils/trui-nav-agents.js +178 -25
  57. package/src/utils/trui-nav-requirements.js +203 -27
  58. package/src/utils/trui-nav-settings.js +114 -1
  59. package/src/utils/trui-nav-specifications.js +44 -3
  60. package/src/utils/trui-navigation-backup.js +603 -0
  61. package/src/utils/trui-navigation.js +70 -228
  62. package/src/utils/trui-provider-health.js +274 -0
  63. package/src/utils/trui-provider-manager.js +376 -0
  64. package/src/utils/trui-quick-menu.js +25 -1
  65. package/src/utils/trui-req-actions-backup.js +507 -0
  66. package/src/utils/trui-req-actions.js +148 -216
  67. package/src/utils/trui-req-editor.js +170 -0
  68. package/src/utils/trui-req-file-ops.js +278 -0
  69. package/src/utils/trui-req-tree-old.js +719 -0
  70. package/src/utils/trui-req-tree.js +348 -627
  71. package/src/utils/trui-specifications.js +25 -7
  72. package/src/utils/trui-windsurf.js +231 -10
  73. package/src/utils/welcome-screen-extracted.js +2 -2
  74. package/src/utils/welcome-screen.js +2 -2
@@ -0,0 +1,376 @@
1
+ /**
2
+ * TRUI Provider Manager
3
+ *
4
+ * Advanced provider management with health metrics, quota checking, IDE detection
5
+ * Enable/disable providers and re-order them.
6
+ */
7
+
8
+ const chalk = require('chalk');
9
+ const { showQuickMenu } = require('./trui-quick-menu');
10
+ const { debugLogger } = require('./trui-debug');
11
+ const { getProviderHealth, formatHealthDisplay } = require('./trui-provider-health');
12
+ const { getKiroIntegrationStatus } = require('./trui-kiro-integration');
13
+
14
+ /**
15
+ * Get provider status icon
16
+ */
17
+ function getStatusIcon(enabled) {
18
+ return enabled ? '🟢' : 'šŸ”“';
19
+ }
20
+
21
+ /**
22
+ * Load providers data via RUI resolver with health checks
23
+ */
24
+ async function loadProvidersData(navigation) {
25
+ try {
26
+ const result = navigation.resolver.resolve('list providers');
27
+ if (!result.success) return null;
28
+
29
+ const commandResult = await result.command.execute();
30
+ if (!commandResult.success || !commandResult.data) return null;
31
+
32
+ const providers = commandResult.data;
33
+
34
+ // Enhance providers with health information
35
+ for (const provider of providers) {
36
+ try {
37
+ provider.health = await getProviderHealth(provider);
38
+ } catch (error) {
39
+ debugLogger.error('Error getting provider health', {
40
+ provider: provider.id,
41
+ error: error.message
42
+ });
43
+ provider.health = { status: 'error', errors: [error.message] };
44
+ }
45
+ }
46
+
47
+ return providers;
48
+ } catch (err) {
49
+ debugLogger.error('Error loading providers data', { error: err.message });
50
+ return null;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Build provider choice items with enhanced health and quota info
56
+ */
57
+ function buildProviderChoices(providers, preferences = {}) {
58
+ if (!providers || !providers.length) {
59
+ return [{ name: chalk.gray(' (no providers found)'), value: 'noop' }];
60
+ }
61
+
62
+ return providers.map((provider, index) => {
63
+ const isEnabled = preferences.enabled && preferences.enabled[provider.id] !== false;
64
+ const status = isEnabled ? chalk.green('ENABLED') : chalk.red('DISABLED');
65
+ const icon = getStatusIcon(isEnabled);
66
+
67
+ // Enhanced health information
68
+ let healthInfo = '';
69
+ if (provider.health) {
70
+ const healthIcon = provider.health.status === 'healthy' ? '🟢' :
71
+ provider.health.status === 'degraded' ? '🟔' :
72
+ provider.health.status === 'unhealthy' ? 'šŸ”“' :
73
+ provider.health.status === 'error' ? 'āŒ' : '⚪';
74
+ healthInfo = ` ${healthIcon}`;
75
+
76
+ if (provider.health.responseTime) {
77
+ const timeColor = provider.health.responseTime < 1000 ? chalk.green :
78
+ provider.health.responseTime < 3000 ? chalk.yellow : chalk.red;
79
+ healthInfo += ` ${timeColor(provider.health.responseTime + 'ms')}`;
80
+ }
81
+ }
82
+
83
+ // Enhanced quota information
84
+ let quotaInfo = '';
85
+ if (provider.health && provider.health.quota) {
86
+ const quota = provider.health.quota;
87
+ const percentage = Math.round((quota.used / quota.limit) * 100);
88
+ const color = percentage >= 90 ? chalk.red : percentage >= 75 ? chalk.yellow : chalk.green;
89
+ quotaInfo = ` ${color(quota.used + '/' + quota.limit)}`;
90
+ }
91
+
92
+ // Enhanced IDE detection
93
+ let ideInfo = '';
94
+ if (provider.health && provider.health.ideDetection) {
95
+ const ideCount = Object.values(provider.health.ideDetection)
96
+ .filter(ide => ide.installed).length;
97
+ if (ideCount > 0) {
98
+ ideInfo = ` šŸ’»${ideCount}`;
99
+ }
100
+ }
101
+
102
+ const displayName = provider.name || provider.type || provider.id || 'Unknown';
103
+ const details = [status, healthInfo, quotaInfo, ideInfo].filter(Boolean).join(' ');
104
+
105
+ return {
106
+ type: 'provider',
107
+ name: `${icon} ${displayName}${details ? ' - ' + details : ''}`,
108
+ value: `provider:${index}`
109
+ };
110
+ });
111
+ }
112
+
113
+ /**
114
+ * Show provider manager with full functionality
115
+ */
116
+ async function showProviderManager(navigation) {
117
+ debugLogger.info('showProviderManager called');
118
+
119
+ const data = await loadProvidersData(navigation);
120
+ if (!data || !data.providers) {
121
+ console.log(chalk.yellow('No providers data available'));
122
+ return;
123
+ }
124
+
125
+ const { providers, preferences } = data;
126
+
127
+ while (true) {
128
+ // Build menu items
129
+ const items = buildProviderChoices(providers, preferences);
130
+
131
+ // Add actions
132
+ items.push({ type: 'blank', name: '', value: 'blank' });
133
+ items.push({ type: 'action', name: '[Test All Providers]', value: 'test-all' });
134
+ items.push({ type: 'action', name: '[Refresh Health Status]', value: 'refresh-health' });
135
+ items.push({ type: 'action', name: '[Kiro Integration]', value: 'kiro-status' });
136
+ items.push({ type: 'action', name: 'Exit', value: 'exit' });
137
+
138
+ // Show menu with extra keys for provider actions
139
+ const result = await showQuickMenu(items, 0, {
140
+ extraKeys: (str, key, selectedIndex, context) => {
141
+ const currentItem = items[selectedIndex];
142
+
143
+ // Handle enable/disable with e/d keys
144
+ if ((str === 'e' || str === 'E') && currentItem && currentItem.value && currentItem.value.startsWith('provider:')) {
145
+ const providerIndex = parseInt(currentItem.value.substring(9), 10);
146
+ context.resolveWith(`provider-enable:${providerIndex}`);
147
+ return true;
148
+ }
149
+
150
+ if ((str === 'd' || str === 'D') && currentItem && currentItem.value && currentItem.value.startsWith('provider:')) {
151
+ const providerIndex = parseInt(currentItem.value.substring(9), 10);
152
+ context.resolveWith(`provider-disable:${providerIndex}`);
153
+ return true;
154
+ }
155
+
156
+ // Handle re-ordering with arrow keys when on provider
157
+ if ((key.name === 'up' || key.name === 'down') && currentItem && currentItem.value && currentItem.value.startsWith('provider:')) {
158
+ const providerIndex = parseInt(currentItem.value.substring(9), 10);
159
+
160
+ if (key.name === 'up' && providerIndex > 0) {
161
+ context.resolveWith(`provider-move-up:${providerIndex}`);
162
+ return true;
163
+ }
164
+
165
+ if (key.name === 'down' && providerIndex < providers.length - 1) {
166
+ context.resolveWith(`provider-move-down:${providerIndex}`);
167
+ return true;
168
+ }
169
+ }
170
+
171
+ return false;
172
+ },
173
+ hintText: 'e/d=enable/disable ↑↓=re-order Enter=details ←=back'
174
+ });
175
+
176
+ // Handle actions
177
+ if (result.value === 'test-all') {
178
+ await testAllProviders(providers);
179
+ continue;
180
+ }
181
+
182
+ if (result.value === 'refresh-health') {
183
+ await refreshProviderHealth(providers, navigation);
184
+ continue;
185
+ }
186
+
187
+ if (result.value === 'kiro-status') {
188
+ await showKiroIntegrationStatus();
189
+ continue;
190
+ }
191
+
192
+ if (result.value.startsWith('provider-enable:')) {
193
+ const providerIndex = parseInt(result.value.substring(16), 10);
194
+ await toggleProvider(providers[providerIndex], true, navigation);
195
+ continue;
196
+ }
197
+
198
+ if (result.value.startsWith('provider-disable:')) {
199
+ const providerIndex = parseInt(result.value.substring(17), 10);
200
+ await toggleProvider(providers[providerIndex], false, navigation);
201
+ continue;
202
+ }
203
+
204
+ if (result.value.startsWith('provider-move-up:')) {
205
+ const providerIndex = parseInt(result.value.substring(18), 10);
206
+ await moveProvider(providers, providerIndex, 'up', navigation);
207
+ continue;
208
+ }
209
+
210
+ if (result.value.startsWith('provider-move-down:')) {
211
+ const providerIndex = parseInt(result.value.substring(20), 10);
212
+ await moveProvider(providers, providerIndex, 'down', navigation);
213
+ continue;
214
+ }
215
+
216
+ if (result.value === '__cancel__') {
217
+ break;
218
+ }
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Toggle provider enabled/disabled status
224
+ */
225
+ async function toggleProvider(provider, enabled, navigation) {
226
+ try {
227
+ const result = navigation.resolver.resolve('update provider', {
228
+ providerId: provider.id,
229
+ enabled
230
+ });
231
+
232
+ if (result.success) {
233
+ await result.command.execute();
234
+ console.log(chalk.green(`\nāœ“ ${provider.name || provider.id} ${enabled ? 'enabled' : 'disabled'}`));
235
+ }
236
+ } catch (err) {
237
+ console.log(chalk.red(`Error toggling provider: ${err.message}`));
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Move provider up/down in order
243
+ */
244
+ async function moveProvider(providers, index, direction, navigation) {
245
+ if (direction === 'up' && index > 0) {
246
+ // Swap with previous
247
+ const temp = providers[index - 1];
248
+ providers[index - 1] = providers[index];
249
+ providers[index] = temp;
250
+ } else if (direction === 'down' && index < providers.length - 1) {
251
+ // Swap with next
252
+ const temp = providers[index + 1];
253
+ providers[index + 1] = providers[index];
254
+ providers[index] = temp;
255
+ }
256
+
257
+ try {
258
+ // Save new order
259
+ const newOrder = providers.map(p => p.id);
260
+ const result = navigation.resolver.resolve('update provider-order', { order: newOrder });
261
+
262
+ if (result.success) {
263
+ await result.command.execute();
264
+ console.log(chalk.green('\nāœ“ Provider order updated'));
265
+ }
266
+ } catch (err) {
267
+ console.log(chalk.red(`Error updating provider order: ${err.message}`));
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Test connectivity of all providers
273
+ */
274
+ async function testAllProviders(providers) {
275
+ console.log(chalk.cyan('\nšŸ” Testing all providers...\n'));
276
+
277
+ for (const provider of providers) {
278
+ console.log(chalk.gray(`Testing ${provider.name || provider.id}...`));
279
+
280
+ try {
281
+ const result = await fetch(`https://api.openai.com/v1/models`, {
282
+ timeout: 5000,
283
+ headers: provider.apiKey ? { 'Authorization': `Bearer ${provider.apiKey}` } : {}
284
+ });
285
+
286
+ if (result.ok) {
287
+ console.log(chalk.green(` āœ“ ${provider.name || provider.id} - Connected`));
288
+ } else {
289
+ console.log(chalk.red(` āœ— ${provider.name || provider.id} - Failed (${result.status})`));
290
+ }
291
+ } catch (err) {
292
+ console.log(chalk.red(` āœ— ${provider.name || provider.id} - Error (${err.message})`));
293
+ }
294
+ }
295
+
296
+ console.log(chalk.gray('\nPress Enter to continue...'));
297
+ await new Promise(resolve => {
298
+ process.stdin.once('data', resolve);
299
+ });
300
+ }
301
+
302
+ /**
303
+ * Refresh provider health status
304
+ */
305
+ async function refreshProviderHealth(providers, navigation) {
306
+ console.log(chalk.cyan('\nšŸ”„ Refreshing provider health...\n'));
307
+
308
+ for (const provider of providers) {
309
+ try {
310
+ // Test basic connectivity
311
+ const result = await fetch(`https://api.openai.com/v1/models`, {
312
+ timeout: 3000,
313
+ headers: provider.apiKey ? { 'Authorization': `Bearer ${provider.apiKey}` } : {}
314
+ });
315
+
316
+ if (result.ok) {
317
+ console.log(chalk.green(` āœ“ ${provider.name || provider.id} - Healthy`));
318
+ } else {
319
+ console.log(chalk.yellow(` ⚠ ${provider.name || provider.id} - Limited (${result.status})`));
320
+ }
321
+ } catch (err) {
322
+ console.log(chalk.red(` āœ— ${provider.name || provider.id} - Unreachable`));
323
+ }
324
+ }
325
+
326
+ console.log(chalk.gray('\nPress Enter to continue...'));
327
+ await new Promise(resolve => {
328
+ process.stdin.once('data', resolve);
329
+ });
330
+ }
331
+
332
+ /**
333
+ * Show Kiro integration status
334
+ */
335
+ async function showKiroIntegrationStatus() {
336
+ console.clear();
337
+ console.log(chalk.bold.cyan('šŸ”— Kiro Integration Status\n'));
338
+
339
+ try {
340
+ const kiroStatus = await getKiroIntegrationStatus();
341
+
342
+ console.log(`Status: ${kiroStatus.installed ? chalk.green('Installed') : chalk.red('Not Installed')}`);
343
+
344
+ if (kiroStatus.version) {
345
+ console.log(`Version: ${chalk.white(kiroStatus.version)}`);
346
+ }
347
+
348
+ console.log(`Configured: ${kiroStatus.configured ? chalk.green('Yes') : chalk.yellow('No')}`);
349
+
350
+ if (kiroStatus.config) {
351
+ console.log(`Project: ${chalk.white(kiroStatus.config.project)}`);
352
+ console.log(`Provider: ${chalk.white(kiroStatus.config.provider)}`);
353
+ console.log(`Auto-mode: ${kiroStatus.config.autoMode ? chalk.green('Enabled') : chalk.red('Disabled')}`);
354
+ }
355
+
356
+ if (!kiroStatus.installed) {
357
+ console.log(chalk.yellow('\nšŸ’” Kiro integration enhances provider management with advanced features.'));
358
+ console.log(chalk.gray('Visit https://github.com/kiro-dev/kiro to install.'));
359
+ }
360
+
361
+ } catch (error) {
362
+ console.log(chalk.red('Error checking Kiro status: ' + error.message));
363
+ }
364
+
365
+ console.log(chalk.gray('\nPress Enter to continue...'));
366
+ await new Promise(resolve => {
367
+ process.stdin.once('data', resolve);
368
+ });
369
+ }
370
+
371
+ module.exports = {
372
+ showProviderManager,
373
+ loadProvidersData,
374
+ buildProviderChoices,
375
+ showKiroIntegrationStatus
376
+ };
@@ -55,7 +55,7 @@ function getVisualLineCount(text) {
55
55
  * Determine whether an item can receive keyboard focus
56
56
  */
57
57
  function isSelectable(item) {
58
- return item.type !== 'blank' && item.type !== 'info';
58
+ return item.type !== 'blank' && item.type !== 'info' && item.type !== 'separator';
59
59
  }
60
60
 
61
61
  /**
@@ -88,6 +88,27 @@ function renderMenu(items, selectedIndex, hintText) {
88
88
  return;
89
89
  }
90
90
 
91
+ // 'separator' type: gray text header, not selectable
92
+ if (item.type === 'separator') {
93
+ output = chalk.gray(` ${item.name}`);
94
+ process.stdout.write(output + '\n');
95
+ linesPrinted += getVisualLineCount(` ${item.name}`);
96
+ return;
97
+ }
98
+
99
+ // 'sub-item' type: selectable sub-items with arrow navigation, no letter shortcuts
100
+ if (item.type === 'sub-item') {
101
+ const raw = `${isSelected ? 'āÆ ' : ' '}${item.name}`;
102
+ if (isSelected) {
103
+ output = chalk.cyan(`āÆ ${item.name}`);
104
+ } else {
105
+ output = ` ${item.name}`;
106
+ }
107
+ process.stdout.write(output + '\n');
108
+ linesPrinted += getVisualLineCount(raw);
109
+ return;
110
+ }
111
+
91
112
  // 'header' type: no letter, but IS selectable (focusable with ↑↓, Enter returns value)
92
113
  if (item.type === 'header') {
93
114
  const raw = `${isSelected ? 'āÆ ' : ' '}${item.name}`;
@@ -194,6 +215,9 @@ function showQuickMenu(items, initialSelectedIndex = 0, options = {}) {
194
215
  // Move cursor back up to start of menu and clear downward
195
216
  readline.moveCursor(process.stdout, 0, -lastLinesPrinted);
196
217
  readline.clearScreenDown(process.stdout);
218
+ } else {
219
+ // On first render, clear from current position down to ensure clean start
220
+ readline.clearScreenDown(process.stdout);
197
221
  }
198
222
  lastLinesPrinted = renderMenu(items, selectedIndex, hintText);
199
223
  isFirstRender = false;