baseguard 1.0.5 → 1.0.6

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 (80) hide show
  1. package/dist/ai/gemini-analyzer.d.ts.map +1 -1
  2. package/dist/ai/gemini-analyzer.js +1 -1
  3. package/dist/ai/gemini-analyzer.js.map +1 -1
  4. package/dist/ai/gemini-code-fixer.d.ts.map +1 -1
  5. package/dist/ai/gemini-code-fixer.js +2 -7
  6. package/dist/ai/gemini-code-fixer.js.map +1 -1
  7. package/dist/ai/jules-implementer.d.ts +8 -0
  8. package/dist/ai/jules-implementer.d.ts.map +1 -1
  9. package/dist/ai/jules-implementer.js +115 -17
  10. package/dist/ai/jules-implementer.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/ai/__tests__/gemini-analyzer.test.ts +0 -181
  13. package/src/ai/agentkit-orchestrator.ts +0 -534
  14. package/src/ai/fix-manager.ts +0 -362
  15. package/src/ai/gemini-analyzer.ts +0 -665
  16. package/src/ai/gemini-code-fixer.ts +0 -539
  17. package/src/ai/index.ts +0 -4
  18. package/src/ai/jules-implementer.ts +0 -504
  19. package/src/ai/unified-code-fixer.ts +0 -347
  20. package/src/commands/automation.ts +0 -344
  21. package/src/commands/check.ts +0 -298
  22. package/src/commands/config.ts +0 -584
  23. package/src/commands/fix.ts +0 -269
  24. package/src/commands/index.ts +0 -7
  25. package/src/commands/init.ts +0 -156
  26. package/src/commands/status.ts +0 -307
  27. package/src/core/api-key-manager.ts +0 -298
  28. package/src/core/baseguard.ts +0 -757
  29. package/src/core/baseline-checker.ts +0 -566
  30. package/src/core/cache-manager.ts +0 -272
  31. package/src/core/configuration-recovery.ts +0 -672
  32. package/src/core/configuration.ts +0 -596
  33. package/src/core/debug-logger.ts +0 -590
  34. package/src/core/directory-filter.ts +0 -421
  35. package/src/core/error-handler.ts +0 -518
  36. package/src/core/file-processor.ts +0 -338
  37. package/src/core/gitignore-manager.ts +0 -169
  38. package/src/core/graceful-degradation-manager.ts +0 -596
  39. package/src/core/index.ts +0 -17
  40. package/src/core/lazy-loader.ts +0 -317
  41. package/src/core/logger.ts +0 -0
  42. package/src/core/memory-manager.ts +0 -290
  43. package/src/core/parser-worker.ts +0 -33
  44. package/src/core/startup-optimizer.ts +0 -246
  45. package/src/core/system-error-handler.ts +0 -755
  46. package/src/git/automation-engine.ts +0 -361
  47. package/src/git/github-manager.ts +0 -190
  48. package/src/git/hook-manager.ts +0 -210
  49. package/src/git/index.ts +0 -4
  50. package/src/index.ts +0 -8
  51. package/src/parsers/feature-validator.ts +0 -559
  52. package/src/parsers/index.ts +0 -8
  53. package/src/parsers/parser-manager.ts +0 -418
  54. package/src/parsers/parser.ts +0 -26
  55. package/src/parsers/react-parser-optimized.ts +0 -161
  56. package/src/parsers/react-parser.ts +0 -359
  57. package/src/parsers/svelte-parser.ts +0 -510
  58. package/src/parsers/vanilla-parser.ts +0 -685
  59. package/src/parsers/vue-parser.ts +0 -476
  60. package/src/types/index.ts +0 -96
  61. package/src/ui/components.ts +0 -567
  62. package/src/ui/help.ts +0 -193
  63. package/src/ui/index.ts +0 -4
  64. package/src/ui/prompts.ts +0 -681
  65. package/src/ui/terminal-header.ts +0 -59
  66. package/tests/e2e/baseguard.e2e.test.ts +0 -516
  67. package/tests/e2e/cross-platform.e2e.test.ts +0 -420
  68. package/tests/e2e/git-integration.e2e.test.ts +0 -487
  69. package/tests/fixtures/react-project/package.json +0 -14
  70. package/tests/fixtures/react-project/src/App.css +0 -76
  71. package/tests/fixtures/react-project/src/App.tsx +0 -77
  72. package/tests/fixtures/svelte-project/package.json +0 -11
  73. package/tests/fixtures/svelte-project/src/App.svelte +0 -369
  74. package/tests/fixtures/vanilla-project/index.html +0 -76
  75. package/tests/fixtures/vanilla-project/script.js +0 -331
  76. package/tests/fixtures/vanilla-project/styles.css +0 -359
  77. package/tests/fixtures/vue-project/package.json +0 -12
  78. package/tests/fixtures/vue-project/src/App.vue +0 -216
  79. package/tmp-smoke/.baseguard/backups/config-2026-02-19T12-04-11-067Z-auto.json +0 -30
  80. package/tmp-smoke/src/bad.css +0 -3
@@ -1,584 +0,0 @@
1
- import { UIComponents, Prompts } from '../ui/index.js';
2
- import { ConfigurationManager, ApiKeyManager, GitignoreManager } from '../core/index.js';
3
- import { ConfigurationRecovery } from '../core/configuration-recovery.js';
4
- import { ErrorHandler } from '../core/error-handler.js';
5
- import chalk from 'chalk';
6
-
7
- /**
8
- * Manage BaseGuard configuration
9
- */
10
- export async function config(action: string, options?: {
11
- add?: string;
12
- remove?: string;
13
- preset?: string;
14
- file?: string;
15
- format?: string;
16
- backup?: boolean;
17
- interactive?: boolean;
18
- agent?: string;
19
- show?: boolean;
20
- }): Promise<void> {
21
- try {
22
- switch (action) {
23
- case 'show':
24
- await showConfiguration();
25
- break;
26
- case 'list':
27
- await listConfiguration(options?.format);
28
- break;
29
- case 'set-keys':
30
- await setupApiKeys();
31
- break;
32
- case 'targets':
33
- await updateTargets(options);
34
- break;
35
- case 'automation':
36
- await updateAutomation();
37
- break;
38
- case 'update':
39
- await updateConfiguration();
40
- break;
41
- case 'validate':
42
- await validateConfiguration();
43
- break;
44
- case 'security':
45
- await checkSecurity();
46
- break;
47
- case 'backup':
48
- await backupConfiguration();
49
- break;
50
- case 'restore':
51
- await restoreConfiguration(options?.file);
52
- break;
53
- case 'recover':
54
- await recoverConfiguration(options);
55
- break;
56
- case 'coding-agent':
57
- await manageCodingAgent(options);
58
- break;
59
- default:
60
- UIComponents.showErrorBox(`Unknown config action: ${action}`);
61
- showConfigHelp();
62
- process.exit(1);
63
- }
64
-
65
- } catch (error) {
66
- const apiError = ErrorHandler.handleAPIError(error);
67
- ErrorHandler.displayError(apiError);
68
-
69
- // Provide specific help for config command issues
70
- console.log('\nšŸ’” Configuration help:');
71
- if (action === 'set-keys') {
72
- UIComponents.showList([
73
- 'Get Gemini API key from https://aistudio.google.com',
74
- 'Get Jules API key from https://jules.google.com',
75
- 'Ensure API keys are valid and have proper permissions',
76
- 'Check your internet connection for key validation'
77
- ]);
78
- } else if (action === 'targets') {
79
- UIComponents.showList([
80
- 'Use format "browser version" (e.g., "chrome 100")',
81
- 'Available browsers: chrome, safari, firefox, edge',
82
- 'Use "baseline" for Baseline-only support',
83
- 'Check available presets with "base config targets --help"'
84
- ]);
85
- } else if (action === 'validate') {
86
- UIComponents.showList([
87
- 'Check .baseguardrc.json file exists',
88
- 'Verify JSON syntax is correct',
89
- 'Run "base init" to recreate configuration if needed'
90
- ]);
91
- } else {
92
- UIComponents.showList([
93
- 'Run "base config show" to see current configuration',
94
- 'Use "base config --help" to see available commands',
95
- 'Check file permissions in the current directory'
96
- ]);
97
- }
98
-
99
- process.exit(1);
100
- }
101
- }
102
-
103
- async function showConfiguration(): Promise<void> {
104
- const display = await ConfigurationManager.getConfigurationDisplay();
105
-
106
- UIComponents.showConfiguration(display.config);
107
-
108
- // Show security status
109
- if (!display.security.configIgnored) {
110
- UIComponents.showWarningBox('Configuration file is not in .gitignore - API keys may be exposed!');
111
-
112
- if (display.security.recommendations.length > 0) {
113
- console.log('\nSecurity recommendations:');
114
- UIComponents.showList(display.security.recommendations);
115
- }
116
- }
117
-
118
- // Show validation errors if any
119
- if (!display.validation.valid) {
120
- UIComponents.showErrorBox('Configuration validation failed');
121
- UIComponents.showList(display.validation.errors);
122
- }
123
- }
124
-
125
- async function listConfiguration(format?: string): Promise<void> {
126
- const display = await ConfigurationManager.getConfigurationDisplay();
127
-
128
- if (format === 'json') {
129
- // Output as JSON for programmatic use
130
- const output = {
131
- configuration: display.config,
132
- security: display.security,
133
- validation: display.validation,
134
- status: {
135
- configured: display.config.apiKeys.jules !== null || display.config.apiKeys.gemini !== null,
136
- automationEnabled: display.config.automation.enabled,
137
- targetCount: display.config.targets.length
138
- }
139
- };
140
- console.log(JSON.stringify(output, null, 2));
141
- return;
142
- }
143
-
144
- // Default table format
145
- UIComponents.showSectionHeader('BaseGuard Configuration Summary');
146
-
147
- // Configuration overview
148
- console.log('šŸ“‹ Configuration:');
149
- console.log(` Version: ${display.config.version}`);
150
- console.log(` Targets: ${display.config.targets.length} browser(s)`);
151
- console.log(` API Keys: ${display.config.apiKeys.jules ? 'āœ“' : 'āœ—'} Jules, ${display.config.apiKeys.gemini ? 'āœ“' : 'āœ—'} Gemini`);
152
- console.log(` Automation: ${display.config.automation.enabled ? 'āœ“ enabled' : 'āœ— disabled'}`);
153
-
154
- // Browser targets
155
- console.log('\nšŸŽÆ Browser Targets:');
156
- display.config.targets.forEach(target => {
157
- console.log(` • ${target.browser} ${target.minVersion}`);
158
- });
159
-
160
- // Automation settings
161
- console.log('\nšŸ¤– Automation Settings:');
162
- console.log(` Enabled: ${display.config.automation.enabled ? 'āœ“' : 'āœ—'}`);
163
- console.log(` Trigger: ${display.config.automation.trigger}`);
164
- console.log(` Auto-analyze: ${display.config.automation.autoAnalyze ? 'āœ“' : 'āœ—'}`);
165
- console.log(` Auto-fix: ${display.config.automation.autoFix ? 'āœ“' : 'āœ—'}`);
166
- console.log(` Block commits: ${display.config.automation.blockCommit ? 'āœ“' : 'āœ—'}`);
167
-
168
- // Security status
169
- console.log('\nšŸ”’ Security Status:');
170
- console.log(` .gitignore exists: ${display.security.gitignoreExists ? 'āœ“' : 'āœ—'}`);
171
- console.log(` Config file ignored: ${display.security.configIgnored ? 'āœ“' : 'āœ—'}`);
172
-
173
- // Validation status
174
- console.log('\nāœ… Validation Status:');
175
- console.log(` Configuration valid: ${display.validation.valid ? 'āœ“' : 'āœ—'}`);
176
-
177
- // Show warnings/errors
178
- if (!display.security.configIgnored) {
179
- UIComponents.showWarningBox('Configuration file is not in .gitignore - API keys may be exposed!');
180
- }
181
-
182
- if (!display.validation.valid) {
183
- UIComponents.showErrorBox('Configuration validation failed');
184
- UIComponents.showList(display.validation.errors);
185
- }
186
-
187
- if (display.security.recommendations.length > 0) {
188
- console.log('\nšŸ’” Recommendations:');
189
- UIComponents.showList(display.security.recommendations);
190
- }
191
- }
192
-
193
- async function setupApiKeys(): Promise<void> {
194
- const apiKeys = await Prompts.setupApiKeys();
195
-
196
- if (apiKeys.julesApiKey || apiKeys.geminiApiKey) {
197
- await ApiKeyManager.storeApiKeys({
198
- jules: apiKeys.julesApiKey,
199
- gemini: apiKeys.geminiApiKey
200
- });
201
-
202
- UIComponents.showSuccessBox('API keys updated successfully');
203
-
204
- // Show security reminder
205
- const security = await GitignoreManager.isConfigSecure();
206
- if (!security.configIgnored) {
207
- UIComponents.showWarningBox('Remember to add .baseguardrc.json to .gitignore to protect your API keys');
208
- }
209
- } else {
210
- UIComponents.showInfoBox('No API keys were configured');
211
- }
212
- }
213
-
214
- async function updateTargets(options?: { add?: string; remove?: string; preset?: string }): Promise<void> {
215
- if (options?.add) {
216
- // Add a specific browser target
217
- const target = ConfigurationManager.parseBrowserTarget(options.add);
218
- if (!target) {
219
- UIComponents.showErrorBox(`Invalid browser target format: ${options.add}`);
220
- UIComponents.showInfoBox('Format: "browser version" (e.g., "chrome 100", "safari baseline")');
221
- return;
222
- }
223
-
224
- await ConfigurationManager.addBrowserTarget(target);
225
- UIComponents.showSuccessBox(`Added browser target: ${target.browser} ${target.minVersion}`);
226
- return;
227
- }
228
-
229
- if (options?.remove) {
230
- // Remove a specific browser target
231
- await ConfigurationManager.removeBrowserTarget(options.remove);
232
- UIComponents.showSuccessBox(`Removed browser target: ${options.remove}`);
233
- return;
234
- }
235
-
236
- if (options?.preset) {
237
- // Set preset targets
238
- const presetName = options.preset as any;
239
- const availablePresets = ConfigurationManager.getAvailablePresets();
240
-
241
- if (!availablePresets.includes(presetName)) {
242
- UIComponents.showErrorBox(`Invalid preset: ${options.preset}`);
243
- UIComponents.showInfoBox(`Available presets: ${availablePresets.join(', ')}`);
244
- return;
245
- }
246
-
247
- await ConfigurationManager.updateWithPreset(presetName);
248
- UIComponents.showSuccessBox(`Updated to ${presetName} preset`);
249
- UIComponents.showInfoBox(ConfigurationManager.getPresetDescription(presetName));
250
- return;
251
- }
252
-
253
- // Interactive target configuration
254
- const targets = await Prompts.promptCustomTargets();
255
- await ConfigurationManager.updateWithCustomTargets(targets);
256
- UIComponents.showSuccessBox('Browser targets updated successfully');
257
- }
258
-
259
- async function updateAutomation(): Promise<void> {
260
- const automation = await Prompts.promptAutomationSettings();
261
- const config = await ConfigurationManager.load();
262
- config.automation = { ...config.automation, ...automation };
263
- await ConfigurationManager.save(config);
264
- UIComponents.showSuccessBox('Automation settings updated successfully');
265
- }
266
-
267
- async function updateConfiguration(): Promise<void> {
268
- const currentConfig = await ConfigurationManager.load();
269
- const updates = await Prompts.promptConfigUpdate(currentConfig);
270
-
271
- if (Object.keys(updates).length === 0) {
272
- UIComponents.showInfoBox('No changes made');
273
- return;
274
- }
275
-
276
- let config = currentConfig;
277
-
278
- // Apply updates
279
- for (const [key, value] of Object.entries(updates)) {
280
- switch (key) {
281
- case 'targets':
282
- await ConfigurationManager.updateWithCustomTargets(value as any);
283
- config = await ConfigurationManager.load(); // Reload after update
284
- break;
285
- case 'apiKeys': {
286
- const apiKeys = value as any;
287
- if (apiKeys.julesApiKey) config.apiKeys.jules = apiKeys.julesApiKey;
288
- if (apiKeys.geminiApiKey) config.apiKeys.gemini = apiKeys.geminiApiKey;
289
- break;
290
- }
291
- case 'automation':
292
- config.automation = { ...config.automation, ...(value as any) };
293
- break;
294
- }
295
- }
296
-
297
- await ConfigurationManager.save(config);
298
- UIComponents.showSuccessBox('Configuration updated successfully');
299
- }
300
-
301
- async function validateConfiguration(): Promise<void> {
302
- const display = await ConfigurationManager.getConfigurationDisplay();
303
-
304
- if (display.validation.valid) {
305
- UIComponents.showSuccessBox('Configuration is valid');
306
- } else {
307
- UIComponents.showErrorBox('Configuration validation failed');
308
- UIComponents.showList(display.validation.errors);
309
- process.exit(1);
310
- }
311
- }
312
-
313
- async function checkSecurity(): Promise<void> {
314
- const security = await GitignoreManager.isConfigSecure();
315
-
316
- UIComponents.showSectionHeader('Security Status');
317
-
318
- console.log(`āœ“ .gitignore exists: ${security.gitignoreExists ? 'Yes' : 'No'}`);
319
- console.log(`āœ“ Config file ignored: ${security.configIgnored ? 'Yes' : 'No'}`);
320
-
321
- if (security.recommendations.length > 0) {
322
- console.log('\nRecommendations:');
323
- UIComponents.showList(security.recommendations);
324
- } else {
325
- UIComponents.showSuccessBox('Configuration is secure');
326
- }
327
- }
328
-
329
- async function backupConfiguration(): Promise<void> {
330
- try {
331
- const backupFile = await ConfigurationManager.backupConfiguration();
332
- UIComponents.showSuccessBox(`Configuration backed up to: ${backupFile}`);
333
- } catch (error) {
334
- UIComponents.showErrorBox(`Backup failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
335
- process.exit(1);
336
- }
337
- }
338
-
339
- async function restoreConfiguration(backupFile?: string): Promise<void> {
340
- if (!backupFile) {
341
- UIComponents.showErrorBox('Backup file path is required');
342
- console.log('Usage: base config restore --file <backup-file>');
343
- process.exit(1);
344
- }
345
-
346
- try {
347
- await ConfigurationManager.restoreConfiguration(backupFile);
348
- UIComponents.showSuccessBox('Configuration restored successfully');
349
- } catch (error) {
350
- UIComponents.showErrorBox(`Restore failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
351
- process.exit(1);
352
- }
353
- }
354
-
355
- async function recoverConfiguration(options?: { backup?: boolean; interactive?: boolean }): Promise<void> {
356
- try {
357
- console.log(chalk.cyan('šŸ”§ BaseGuard Configuration Recovery\n'));
358
-
359
- if (options?.interactive) {
360
- // Run interactive recovery wizard
361
- await ConfigurationRecovery.runRecoveryWizard();
362
- return;
363
- }
364
-
365
- // Automatic recovery
366
- console.log(chalk.cyan('Attempting automatic configuration recovery...'));
367
-
368
- const recoveryResult = await ConfigurationRecovery.recoverConfiguration({
369
- createBackup: options?.backup ?? true,
370
- validateConfig: true,
371
- migrateVersion: true,
372
- repairCorruption: true,
373
- useDefaults: true
374
- });
375
-
376
- if (recoveryResult.success) {
377
- UIComponents.showSuccessBox('Configuration recovered successfully');
378
-
379
- if (recoveryResult.backupCreated) {
380
- console.log(chalk.dim(`Backup created: ${recoveryResult.backupCreated}`));
381
- }
382
-
383
- if (recoveryResult.warnings.length > 0) {
384
- console.log(chalk.yellow('\nāš ļø Recovery warnings:'));
385
- recoveryResult.warnings.forEach(warning => {
386
- console.log(chalk.yellow(` • ${warning}`));
387
- });
388
- }
389
-
390
- // Show recovered configuration
391
- console.log(chalk.cyan('\nšŸ“‹ Recovered Configuration:'));
392
- if (recoveryResult.config) {
393
- console.log(` Version: ${recoveryResult.config.version}`);
394
- console.log(` Targets: ${recoveryResult.config.targets.length} browser(s)`);
395
- console.log(` API Keys: Jules ${recoveryResult.config.apiKeys.jules ? 'āœ“' : 'āœ—'}, Gemini ${recoveryResult.config.apiKeys.gemini ? 'āœ“' : 'āœ—'}`);
396
- console.log(` Automation: ${recoveryResult.config.automation.enabled ? 'Enabled' : 'Disabled'}`);
397
- }
398
-
399
- } else {
400
- UIComponents.showErrorBox('Configuration recovery failed');
401
-
402
- console.log(chalk.red('\nāŒ Recovery errors:'));
403
- recoveryResult.errors.forEach(error => {
404
- console.log(chalk.red(` • ${error}`));
405
- });
406
-
407
- console.log(chalk.cyan('\nšŸ’” Manual recovery options:'));
408
- console.log(chalk.cyan(' • Run "base config recover --interactive" for guided recovery'));
409
- console.log(chalk.cyan(' • Run "base init" to create a fresh configuration'));
410
- console.log(chalk.cyan(' • Manually edit .baseguardrc.json file'));
411
- console.log(chalk.cyan(' • Restore from backup if available'));
412
-
413
- // Show available backups
414
- const backups = await ConfigurationRecovery.listBackups();
415
- if (backups.length > 0) {
416
- console.log(chalk.cyan('\nšŸ“¦ Available backups:'));
417
- backups.slice(0, 3).forEach(backup => {
418
- console.log(chalk.cyan(` • ${backup.timestamp.toLocaleString()} (${backup.source})`));
419
- });
420
- console.log(chalk.cyan('\n Use "base config restore --file <backup-file>" to restore'));
421
- }
422
-
423
- process.exit(1);
424
- }
425
-
426
- } catch (error) {
427
- UIComponents.showErrorBox(`Recovery process failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
428
-
429
- console.log(chalk.cyan('\nšŸ†˜ Emergency recovery options:'));
430
- console.log(chalk.cyan(' • Delete .baseguardrc.json and run "base init"'));
431
- console.log(chalk.cyan(' • Check file permissions in your project directory'));
432
- console.log(chalk.cyan(' • Run "base diagnostics" for comprehensive troubleshooting'));
433
-
434
- process.exit(1);
435
- }
436
- }
437
-
438
- function showConfigHelp(): void {
439
- UIComponents.showSectionHeader('Configuration Commands');
440
- UIComponents.showList([
441
- 'base config show - Display current configuration',
442
- 'base config list - List configuration summary',
443
- 'base config list --format json - List configuration as JSON',
444
- 'base config set-keys - Set up API keys for AI services',
445
- 'base config targets - Configure browser targets',
446
- 'base config targets --add "chrome 100" - Add browser target',
447
- 'base config targets --remove chrome - Remove browser target',
448
- 'base config targets --preset baseline-widely - Set preset targets',
449
- 'base config automation - Configure git automation',
450
- 'base config update - Interactive configuration update',
451
- 'base config validate - Validate configuration file',
452
- 'base config security - Check configuration security',
453
- 'base config backup - Create configuration backup',
454
- 'base config restore --file <backup> - Restore from backup',
455
- 'base config recover - Attempt automatic configuration recovery',
456
- 'base config recover --interactive - Run interactive recovery wizard',
457
- 'base config coding-agent - Manage coding agent selection (Jules vs Gemini)',
458
- 'base config coding-agent --show - Show current agent configuration',
459
- 'base config coding-agent --agent gemini - Set Gemini as primary agent',
460
- '',
461
- 'Shorthand commands:',
462
- 'base add "chrome 100" - Add browser target',
463
- 'base remove chrome - Remove browser target',
464
- 'base list - List configuration summary'
465
- ]);
466
- }
467
-
468
- async function manageCodingAgent(options?: { agent?: string; show?: boolean }): Promise<void> {
469
- try {
470
- const config = await ConfigurationManager.load();
471
-
472
- if (options?.show) {
473
- // Show current coding agent configuration
474
- console.log(chalk.cyan('šŸ¤– Coding Agent Configuration\n'));
475
- console.log(`Primary Agent: ${chalk.white(config.codingAgent.primary)}`);
476
- console.log(`Fallback Agent: ${chalk.white(config.codingAgent.fallback)}`);
477
-
478
- // Show agent status
479
- const { UnifiedCodeFixer } = await import('../ai/unified-code-fixer.js');
480
- const unifiedFixer = new UnifiedCodeFixer(config);
481
- const status = await unifiedFixer.getAgentStatus();
482
-
483
- console.log(chalk.cyan('\nšŸ“Š Agent Status:'));
484
- console.log(`Jules: ${status.jules.configured ? 'šŸ”‘' : 'āŒ'} configured, ${status.jules.available ? 'āœ…' : 'āŒ'} available`);
485
- if (status.jules.repoDetected !== undefined) {
486
- console.log(` ${status.jules.repoDetected ? 'āœ…' : 'āŒ'} GitHub repository detected`);
487
- }
488
- console.log(`Gemini: ${status.gemini.configured ? 'šŸ”‘' : 'āŒ'} configured, ${status.gemini.available ? 'āœ…' : 'āŒ'} available`);
489
-
490
- // Show comparison
491
- unifiedFixer.showAgentComparison();
492
- return;
493
- }
494
-
495
- if (options?.agent) {
496
- // Set specific agent
497
- const agent = options.agent.toLowerCase();
498
- if (agent !== 'jules' && agent !== 'gemini') {
499
- UIComponents.showErrorBox('Invalid agent. Use "jules" or "gemini"');
500
- return;
501
- }
502
-
503
- config.codingAgent.primary = agent as 'jules' | 'gemini';
504
- await ConfigurationManager.save(config);
505
-
506
- console.log(chalk.green(`āœ… Primary coding agent set to ${agent}`));
507
-
508
- // Show setup instructions if API key is missing
509
- if (agent === 'jules' && !config.apiKeys.jules) {
510
- console.log(chalk.yellow('\nāš ļø Jules API key not configured'));
511
- console.log(chalk.cyan('Get your Jules API key: https://jules.google.com/settings#api'));
512
- console.log(chalk.cyan('Run "base config set-keys" to configure it'));
513
- } else if (agent === 'gemini' && !config.apiKeys.gemini) {
514
- console.log(chalk.yellow('\nāš ļø Gemini API key not configured'));
515
- console.log(chalk.cyan('Get your Gemini API key: https://aistudio.google.com'));
516
- console.log(chalk.cyan('Run "base config set-keys" to configure it'));
517
- }
518
-
519
- return;
520
- }
521
-
522
- // Interactive agent selection
523
- const { UnifiedCodeFixer } = await import('../ai/unified-code-fixer.js');
524
- const unifiedFixer = new UnifiedCodeFixer(config);
525
-
526
- // Show current status
527
- console.log(chalk.cyan('šŸ¤– Current Coding Agent Configuration\n'));
528
- console.log(`Primary: ${config.codingAgent.primary}`);
529
- console.log(`Fallback: ${config.codingAgent.fallback}`);
530
-
531
- // Get recommendation
532
- const recommendation = await unifiedFixer.getRecommendedAgent();
533
- console.log(chalk.cyan(`\nšŸ’” Recommended: ${recommendation.agent}`));
534
- console.log(chalk.dim(` Reason: ${recommendation.reason}`));
535
-
536
- // Interactive selection
537
- const { default: inquirer } = await import('inquirer');
538
- const answers = await inquirer.prompt([
539
- {
540
- type: 'list',
541
- name: 'primary',
542
- message: 'Select primary coding agent:',
543
- choices: [
544
- { name: 'Gemini 2.5 Pro (works with any files, immediate)', value: 'gemini' },
545
- { name: 'Jules (GitHub repos only, autonomous)', value: 'jules' }
546
- ],
547
- default: recommendation.agent
548
- },
549
- {
550
- type: 'list',
551
- name: 'fallback',
552
- message: 'Select fallback coding agent:',
553
- choices: [
554
- { name: 'Gemini 2.5 Pro', value: 'gemini' },
555
- { name: 'Jules', value: 'jules' }
556
- ],
557
- default: 'gemini'
558
- }
559
- ]);
560
-
561
- config.codingAgent.primary = answers.primary;
562
- config.codingAgent.fallback = answers.fallback;
563
-
564
- await ConfigurationManager.save(config);
565
-
566
- console.log(chalk.green('\nāœ… Coding agent configuration updated'));
567
- console.log(`Primary: ${answers.primary}`);
568
- console.log(`Fallback: ${answers.fallback}`);
569
-
570
- // Show next steps
571
- console.log(chalk.cyan('\nšŸ”§ Next Steps:'));
572
- if (!config.apiKeys[answers.primary as keyof typeof config.apiKeys]) {
573
- console.log(chalk.cyan(`• Configure ${answers.primary} API key: "base config set-keys"`));
574
- }
575
- if (answers.primary !== answers.fallback && !config.apiKeys[answers.fallback as keyof typeof config.apiKeys]) {
576
- console.log(chalk.cyan(`• Configure ${answers.fallback} API key for fallback: "base config set-keys"`));
577
- }
578
- console.log(chalk.cyan('• Test with: "base fix --analyze-only"'));
579
-
580
- } catch (error) {
581
- UIComponents.showErrorBox(`Failed to manage coding agent: ${error instanceof Error ? error.message : 'Unknown error'}`);
582
- process.exit(1);
583
- }
584
- }