baseguard 1.0.4 → 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 (84) 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/dist/commands/fix.d.ts.map +1 -1
  12. package/dist/commands/fix.js +5 -1
  13. package/dist/commands/fix.js.map +1 -1
  14. package/dist/core/baseline-checker.d.ts.map +1 -1
  15. package/dist/core/baseline-checker.js +6 -4
  16. package/dist/core/baseline-checker.js.map +1 -1
  17. package/package.json +1 -1
  18. package/src/ai/__tests__/gemini-analyzer.test.ts +0 -181
  19. package/src/ai/agentkit-orchestrator.ts +0 -534
  20. package/src/ai/fix-manager.ts +0 -362
  21. package/src/ai/gemini-analyzer.ts +0 -665
  22. package/src/ai/gemini-code-fixer.ts +0 -539
  23. package/src/ai/index.ts +0 -4
  24. package/src/ai/jules-implementer.ts +0 -504
  25. package/src/ai/unified-code-fixer.ts +0 -347
  26. package/src/commands/automation.ts +0 -344
  27. package/src/commands/check.ts +0 -298
  28. package/src/commands/config.ts +0 -584
  29. package/src/commands/fix.ts +0 -264
  30. package/src/commands/index.ts +0 -7
  31. package/src/commands/init.ts +0 -156
  32. package/src/commands/status.ts +0 -307
  33. package/src/core/api-key-manager.ts +0 -298
  34. package/src/core/baseguard.ts +0 -757
  35. package/src/core/baseline-checker.ts +0 -564
  36. package/src/core/cache-manager.ts +0 -272
  37. package/src/core/configuration-recovery.ts +0 -672
  38. package/src/core/configuration.ts +0 -596
  39. package/src/core/debug-logger.ts +0 -590
  40. package/src/core/directory-filter.ts +0 -421
  41. package/src/core/error-handler.ts +0 -518
  42. package/src/core/file-processor.ts +0 -338
  43. package/src/core/gitignore-manager.ts +0 -169
  44. package/src/core/graceful-degradation-manager.ts +0 -596
  45. package/src/core/index.ts +0 -17
  46. package/src/core/lazy-loader.ts +0 -317
  47. package/src/core/logger.ts +0 -0
  48. package/src/core/memory-manager.ts +0 -290
  49. package/src/core/parser-worker.ts +0 -33
  50. package/src/core/startup-optimizer.ts +0 -246
  51. package/src/core/system-error-handler.ts +0 -755
  52. package/src/git/automation-engine.ts +0 -361
  53. package/src/git/github-manager.ts +0 -190
  54. package/src/git/hook-manager.ts +0 -210
  55. package/src/git/index.ts +0 -4
  56. package/src/index.ts +0 -8
  57. package/src/parsers/feature-validator.ts +0 -559
  58. package/src/parsers/index.ts +0 -8
  59. package/src/parsers/parser-manager.ts +0 -418
  60. package/src/parsers/parser.ts +0 -26
  61. package/src/parsers/react-parser-optimized.ts +0 -161
  62. package/src/parsers/react-parser.ts +0 -359
  63. package/src/parsers/svelte-parser.ts +0 -510
  64. package/src/parsers/vanilla-parser.ts +0 -685
  65. package/src/parsers/vue-parser.ts +0 -476
  66. package/src/types/index.ts +0 -96
  67. package/src/ui/components.ts +0 -567
  68. package/src/ui/help.ts +0 -193
  69. package/src/ui/index.ts +0 -4
  70. package/src/ui/prompts.ts +0 -681
  71. package/src/ui/terminal-header.ts +0 -59
  72. package/tests/e2e/baseguard.e2e.test.ts +0 -516
  73. package/tests/e2e/cross-platform.e2e.test.ts +0 -420
  74. package/tests/e2e/git-integration.e2e.test.ts +0 -487
  75. package/tests/fixtures/react-project/package.json +0 -14
  76. package/tests/fixtures/react-project/src/App.css +0 -76
  77. package/tests/fixtures/react-project/src/App.tsx +0 -77
  78. package/tests/fixtures/svelte-project/package.json +0 -11
  79. package/tests/fixtures/svelte-project/src/App.svelte +0 -369
  80. package/tests/fixtures/vanilla-project/index.html +0 -76
  81. package/tests/fixtures/vanilla-project/script.js +0 -331
  82. package/tests/fixtures/vanilla-project/styles.css +0 -359
  83. package/tests/fixtures/vue-project/package.json +0 -12
  84. package/tests/fixtures/vue-project/src/App.vue +0 -216
@@ -1,347 +0,0 @@
1
- import type { Violation, Analysis, Fix, Configuration } from '../types/index.js';
2
- import { JulesImplementer } from './jules-implementer.js';
3
- import { GeminiCodeFixer } from './gemini-code-fixer.js';
4
- import { APIError, ErrorType } from '../core/error-handler.js';
5
- import { logger } from '../core/debug-logger.js';
6
- import chalk from 'chalk';
7
-
8
- /**
9
- * Unified code fixer that can use either Jules or Gemini based on configuration
10
- */
11
- export class UnifiedCodeFixer {
12
- private config: Configuration;
13
- private julesImplementer?: JulesImplementer;
14
- private geminiCodeFixer?: GeminiCodeFixer;
15
- private categoryLogger: ReturnType<typeof logger.createCategoryLogger>;
16
-
17
- constructor(config: Configuration) {
18
- this.config = config;
19
- this.categoryLogger = logger.createCategoryLogger('unified-code-fixer');
20
-
21
- // Initialize available agents based on API keys
22
- this.initializeAgents();
23
- }
24
-
25
- /**
26
- * Initialize coding agents based on available API keys
27
- */
28
- private initializeAgents(): void {
29
- if (this.config.apiKeys.jules) {
30
- this.julesImplementer = new JulesImplementer(this.config.apiKeys.jules);
31
- this.categoryLogger.debug('Jules implementer initialized');
32
- }
33
-
34
- if (this.config.apiKeys.gemini) {
35
- this.geminiCodeFixer = new GeminiCodeFixer(this.config.apiKeys.gemini);
36
- this.categoryLogger.debug('Gemini code fixer initialized');
37
- }
38
- }
39
-
40
- /**
41
- * Generate a fix using the configured primary agent with fallback
42
- */
43
- async generateFix(violation: Violation, analysis: Analysis): Promise<Fix> {
44
- const primaryAgent = this.config.codingAgent.primary;
45
- const fallbackAgent = this.config.codingAgent.fallback;
46
-
47
- this.categoryLogger.info('Generating fix', {
48
- feature: violation.feature,
49
- primaryAgent,
50
- fallbackAgent
51
- });
52
-
53
- try {
54
- // Try primary agent first
55
- const fix = await this.generateFixWithAgent(violation, analysis, primaryAgent);
56
-
57
- this.categoryLogger.info('Fix generated successfully with primary agent', {
58
- agent: primaryAgent,
59
- confidence: fix.confidence
60
- });
61
-
62
- return fix;
63
-
64
- } catch (primaryError) {
65
- this.categoryLogger.warn('Primary agent failed, trying fallback', {
66
- primaryAgent,
67
- fallbackAgent,
68
- error: primaryError instanceof Error ? primaryError.message : 'Unknown error'
69
- });
70
-
71
- // Try fallback agent if different from primary
72
- if (fallbackAgent !== primaryAgent) {
73
- try {
74
- const fix = await this.generateFixWithAgent(violation, analysis, fallbackAgent);
75
-
76
- this.categoryLogger.info('Fix generated successfully with fallback agent', {
77
- agent: fallbackAgent,
78
- confidence: fix.confidence
79
- });
80
-
81
- // Add note about fallback usage
82
- fix.explanation = `[Generated using ${fallbackAgent} as fallback]\n\n${fix.explanation}`;
83
-
84
- return fix;
85
-
86
- } catch (fallbackError) {
87
- this.categoryLogger.error('Both agents failed', {
88
- primaryError: primaryError instanceof Error ? primaryError.message : 'Unknown error',
89
- fallbackError: fallbackError instanceof Error ? fallbackError.message : 'Unknown error'
90
- });
91
-
92
- throw new Error(`Both coding agents failed. Primary (${primaryAgent}): ${primaryError instanceof Error ? primaryError.message : 'Unknown error'}. Fallback (${fallbackAgent}): ${fallbackError instanceof Error ? fallbackError.message : 'Unknown error'}`);
93
- }
94
- } else {
95
- throw primaryError;
96
- }
97
- }
98
- }
99
-
100
- /**
101
- * Generate fix with specific agent
102
- */
103
- private async generateFixWithAgent(
104
- violation: Violation,
105
- analysis: Analysis,
106
- agent: 'jules' | 'gemini'
107
- ): Promise<Fix> {
108
- switch (agent) {
109
- case 'jules':
110
- return await this.generateFixWithJules(violation, analysis);
111
-
112
- case 'gemini':
113
- return await this.generateFixWithGemini(violation, analysis);
114
-
115
- default:
116
- throw new Error(`Unknown coding agent: ${agent}`);
117
- }
118
- }
119
-
120
- /**
121
- * Generate fix using Jules
122
- */
123
- private async generateFixWithJules(violation: Violation, analysis: Analysis): Promise<Fix> {
124
- if (!this.julesImplementer) {
125
- throw new APIError(
126
- 'Jules API key not configured',
127
- ErrorType.AUTHENTICATION,
128
- {
129
- suggestions: [
130
- 'Run "base config set-keys" to configure Jules API key',
131
- 'Get Jules API key from https://jules.google.com/settings#api',
132
- 'Switch to Gemini agent with "base config coding-agent gemini"'
133
- ]
134
- }
135
- );
136
- }
137
-
138
- // Check if repository is detected for Jules
139
- const isRepoDetected = await this.julesImplementer.isRepositoryDetected();
140
- if (!isRepoDetected) {
141
- throw new APIError(
142
- 'Jules requires a GitHub repository',
143
- ErrorType.CONFIGURATION,
144
- {
145
- suggestions: [
146
- 'Ensure you are in a git repository with GitHub remote',
147
- 'Jules only works with GitHub repositories',
148
- 'Switch to Gemini agent for local files: "base config coding-agent gemini"'
149
- ]
150
- }
151
- );
152
- }
153
-
154
- return await this.julesImplementer.generateFix(violation, analysis);
155
- }
156
-
157
- /**
158
- * Generate fix using Gemini
159
- */
160
- private async generateFixWithGemini(violation: Violation, analysis: Analysis): Promise<Fix> {
161
- if (!this.geminiCodeFixer) {
162
- throw new APIError(
163
- 'Gemini API key not configured',
164
- ErrorType.AUTHENTICATION,
165
- {
166
- suggestions: [
167
- 'Run "base config set-keys" to configure Gemini API key',
168
- 'Get Gemini API key from https://aistudio.google.com',
169
- 'Switch to Jules agent with "base config coding-agent jules"'
170
- ]
171
- }
172
- );
173
- }
174
-
175
- return await this.geminiCodeFixer.generateFix(violation, analysis);
176
- }
177
-
178
- /**
179
- * Generate multiple fix options using available agents
180
- */
181
- async generateFixOptions(violation: Violation, analysis: Analysis): Promise<Fix[]> {
182
- const fixes: Fix[] = [];
183
-
184
- try {
185
- // Try primary agent
186
- const primaryFix = await this.generateFix(violation, analysis);
187
- fixes.push(primaryFix);
188
-
189
- // If primary agent has low confidence, try the other agent for alternatives
190
- if (primaryFix.confidence < 0.7) {
191
- const alternativeAgent = this.config.codingAgent.primary === 'jules' ? 'gemini' : 'jules';
192
-
193
- try {
194
- const alternativeFix = await this.generateFixWithAgent(violation, analysis, alternativeAgent);
195
- alternativeFix.explanation = `[Alternative approach using ${alternativeAgent}]\n\n${alternativeFix.explanation}`;
196
- fixes.push(alternativeFix);
197
-
198
- this.categoryLogger.info('Generated alternative fix', {
199
- primaryAgent: this.config.codingAgent.primary,
200
- alternativeAgent,
201
- primaryConfidence: primaryFix.confidence,
202
- alternativeConfidence: alternativeFix.confidence
203
- });
204
-
205
- } catch (error) {
206
- this.categoryLogger.debug('Alternative agent failed', {
207
- agent: alternativeAgent,
208
- error: error instanceof Error ? error.message : 'Unknown error'
209
- });
210
- }
211
- }
212
-
213
- } catch (error) {
214
- this.categoryLogger.error('Failed to generate fix options', { error });
215
- throw error;
216
- }
217
-
218
- return fixes;
219
- }
220
-
221
- /**
222
- * Get agent capabilities and status
223
- */
224
- async getAgentStatus(): Promise<{
225
- jules: { available: boolean; configured: boolean; repoDetected?: boolean; error?: string };
226
- gemini: { available: boolean; configured: boolean; error?: string };
227
- primary: string;
228
- fallback: string;
229
- }> {
230
- const status = {
231
- jules: { available: false, configured: !!this.config.apiKeys.jules, error: undefined as string | undefined, repoDetected: undefined as boolean | undefined },
232
- gemini: { available: false, configured: !!this.config.apiKeys.gemini, error: undefined as string | undefined },
233
- primary: this.config.codingAgent.primary,
234
- fallback: this.config.codingAgent.fallback
235
- };
236
-
237
- // Test Jules availability
238
- if (this.julesImplementer) {
239
- try {
240
- const connectionTest = await this.julesImplementer.testConnection();
241
- status.jules.available = connectionTest.success;
242
- if (!connectionTest.success) {
243
- status.jules.error = connectionTest.error;
244
- }
245
-
246
- // Check repository detection
247
- status.jules.repoDetected = await this.julesImplementer.isRepositoryDetected();
248
-
249
- } catch (error) {
250
- status.jules.error = error instanceof Error ? error.message : 'Unknown error';
251
- }
252
- }
253
-
254
- // Test Gemini availability
255
- if (this.geminiCodeFixer) {
256
- try {
257
- const connectionTest = await this.geminiCodeFixer.testConnection();
258
- status.gemini.available = connectionTest.success;
259
- if (!connectionTest.success) {
260
- status.gemini.error = connectionTest.error;
261
- }
262
- } catch (error) {
263
- status.gemini.error = error instanceof Error ? error.message : 'Unknown error';
264
- }
265
- }
266
-
267
- return status;
268
- }
269
-
270
- /**
271
- * Show agent comparison and recommendations
272
- */
273
- showAgentComparison(): void {
274
- console.log(chalk.cyan('\n🤖 Coding Agent Comparison\n'));
275
-
276
- console.log(chalk.white('Jules (Google\'s Autonomous Coding Agent):'));
277
- console.log(chalk.green(' ✅ Autonomous operation in cloud VMs'));
278
- console.log(chalk.green(' ✅ Full repository context understanding'));
279
- console.log(chalk.green(' ✅ Asynchronous processing'));
280
- console.log(chalk.green(' ✅ Integrated with GitHub workflows'));
281
- console.log(chalk.red(' ❌ Requires GitHub repository'));
282
- console.log(chalk.red(' ❌ Cannot work with local/uncommitted files'));
283
- console.log(chalk.red(' ❌ Slower (asynchronous processing)'));
284
-
285
- console.log(chalk.white('\nGemini 2.5 Pro (Direct API Integration):'));
286
- console.log(chalk.green(' ✅ Works with any files (GitHub or not)'));
287
- console.log(chalk.green(' ✅ Immediate processing'));
288
- console.log(chalk.green(' ✅ Works with uncommitted/local files'));
289
- console.log(chalk.green(' ✅ Grounded with real-time web search'));
290
- console.log(chalk.yellow(' ⚠️ Requires manual code application'));
291
- console.log(chalk.yellow(' ⚠️ Limited to single-file context'));
292
-
293
- console.log(chalk.cyan('\n💡 Recommendations:'));
294
- console.log(chalk.cyan(' • Use Jules for: GitHub repositories, complex multi-file changes'));
295
- console.log(chalk.cyan(' • Use Gemini for: Local development, quick fixes, non-GitHub projects'));
296
- console.log(chalk.cyan(' • Configure both for maximum flexibility'));
297
- }
298
-
299
- /**
300
- * Switch primary coding agent
301
- */
302
- async switchPrimaryAgent(agent: 'jules' | 'gemini'): Promise<void> {
303
- this.config.codingAgent.primary = agent;
304
- this.categoryLogger.info('Switched primary coding agent', { agent });
305
-
306
- console.log(chalk.green(`✅ Primary coding agent switched to ${agent}`));
307
-
308
- // Show agent-specific setup instructions
309
- if (agent === 'jules' && !this.config.apiKeys.jules) {
310
- console.log(chalk.yellow('\n⚠️ Jules API key not configured'));
311
- console.log(chalk.cyan('Run "base config set-keys" to configure Jules API key'));
312
- } else if (agent === 'gemini' && !this.config.apiKeys.gemini) {
313
- console.log(chalk.yellow('\n⚠️ Gemini API key not configured'));
314
- console.log(chalk.cyan('Run "base config set-keys" to configure Gemini API key'));
315
- }
316
- }
317
-
318
- /**
319
- * Get recommended agent based on current context
320
- */
321
- async getRecommendedAgent(): Promise<{ agent: 'jules' | 'gemini'; reason: string }> {
322
- // Check if we're in a GitHub repository
323
- const isGitHubRepo = this.julesImplementer ? await this.julesImplementer.isRepositoryDetected() : false;
324
-
325
- if (isGitHubRepo && this.config.apiKeys.jules) {
326
- return {
327
- agent: 'jules',
328
- reason: 'GitHub repository detected and Jules is configured'
329
- };
330
- } else if (this.config.apiKeys.gemini) {
331
- return {
332
- agent: 'gemini',
333
- reason: isGitHubRepo ? 'Gemini works with any files including local changes' : 'Not in a GitHub repository, Gemini works with local files'
334
- };
335
- } else if (this.config.apiKeys.jules) {
336
- return {
337
- agent: 'jules',
338
- reason: 'Only Jules is configured'
339
- };
340
- } else {
341
- return {
342
- agent: 'gemini',
343
- reason: 'Default recommendation for local development'
344
- };
345
- }
346
- }
347
- }
@@ -1,344 +0,0 @@
1
- import chalk from 'chalk';
2
- import inquirer from 'inquirer';
3
- import { UIComponents } from '../ui/index.js';
4
- import { ConfigurationManager } from '../core/configuration.js';
5
- import { ErrorHandler } from '../core/error-handler.js';
6
- import { GitHookManager } from '../git/hook-manager.js';
7
- import { AutomationEngine } from '../git/automation-engine.js';
8
- import type { AutomationOptions } from '../types/index.js';
9
-
10
- /**
11
- * Manage git automation and hooks
12
- */
13
- export async function automation(action: string, options?: any): Promise<void> {
14
- try {
15
- switch (action) {
16
- case 'enable':
17
- await enableAutomation(options);
18
- break;
19
- case 'disable':
20
- await disableAutomation();
21
- break;
22
- case 'status':
23
- await showAutomationStatus();
24
- break;
25
- case 'configure':
26
- await configureAutomation();
27
- break;
28
- case 'run':
29
- await runAutomation(options);
30
- break;
31
- default:
32
- await showAutomationHelp();
33
- }
34
- } catch (error) {
35
- const apiError = ErrorHandler.handleAPIError(error);
36
- ErrorHandler.displayError(apiError);
37
-
38
- // Provide specific help for automation command issues
39
- console.log('\n💡 Automation troubleshooting:');
40
- if (action === 'enable') {
41
- UIComponents.showList([
42
- 'Ensure you\'re in a git repository (run "git init" if needed)',
43
- 'Check that you have a package.json file',
44
- 'Verify write permissions for .husky directory',
45
- 'Make sure Husky is installed (npm install husky)'
46
- ]);
47
- } else if (action === 'run') {
48
- UIComponents.showList([
49
- 'This command is typically called by git hooks automatically',
50
- 'Check that BaseGuard configuration exists (.baseguardrc.json)',
51
- 'Verify git hooks are properly installed',
52
- 'Run "base automation status" to check setup'
53
- ]);
54
- } else if (action === 'disable') {
55
- UIComponents.showList([
56
- 'Check file permissions for .husky directory',
57
- 'Verify git repository is properly initialized',
58
- 'Run "base automation status" to check current state'
59
- ]);
60
- } else {
61
- UIComponents.showList([
62
- 'Run "base automation status" to check current setup',
63
- 'Use "base automation --help" to see available commands',
64
- 'Ensure you\'re in a git repository with BaseGuard configured'
65
- ]);
66
- }
67
-
68
- process.exit(1);
69
- }
70
- }
71
-
72
- /**
73
- * Enable automation with optional configuration
74
- */
75
- async function enableAutomation(options?: { trigger?: string; autoFix?: boolean; autoAnalyze?: boolean }): Promise<void> {
76
- console.log(chalk.cyan('🤖 Enabling BaseGuard automation...'));
77
-
78
- const config = await ConfigurationManager.load();
79
- const hookManager = new GitHookManager();
80
-
81
- // Configure automation settings
82
- let trigger: 'pre-commit' | 'pre-push' = config.automation.trigger;
83
- let autoFix = config.automation.autoFix;
84
- let autoAnalyze = config.automation.autoAnalyze;
85
-
86
- // Use provided options or prompt for configuration
87
- if (options?.trigger) {
88
- if (options.trigger === 'pre-commit' || options.trigger === 'pre-push') {
89
- trigger = options.trigger;
90
- } else {
91
- throw new Error('Invalid trigger. Must be "pre-commit" or "pre-push"');
92
- }
93
- } else if (!config.automation.enabled) {
94
- // First time setup - prompt for configuration
95
- const answers = await inquirer.prompt([
96
- {
97
- type: 'list',
98
- name: 'trigger',
99
- message: 'When should BaseGuard check for violations?',
100
- choices: [
101
- { name: 'Before each commit (pre-commit)', value: 'pre-commit' },
102
- { name: 'Before each push (pre-push)', value: 'pre-push' }
103
- ],
104
- default: trigger
105
- },
106
- {
107
- type: 'confirm',
108
- name: 'autoAnalyze',
109
- message: 'Enable automatic AI analysis of violations?',
110
- default: autoAnalyze,
111
- when: () => !!config.apiKeys.gemini
112
- },
113
- {
114
- type: 'confirm',
115
- name: 'autoFix',
116
- message: 'Enable automatic AI fixing of violations?',
117
- default: autoFix,
118
- when: () => !!config.apiKeys.jules && !!config.apiKeys.gemini
119
- }
120
- ]);
121
-
122
- trigger = answers.trigger;
123
- autoAnalyze = answers.autoAnalyze ?? autoAnalyze;
124
- autoFix = answers.autoFix ?? autoFix;
125
- }
126
-
127
- if (options?.autoFix !== undefined) {
128
- autoFix = options.autoFix;
129
- }
130
-
131
- if (options?.autoAnalyze !== undefined) {
132
- autoAnalyze = options.autoAnalyze;
133
- }
134
-
135
- // Update configuration
136
- config.automation.enabled = true;
137
- config.automation.trigger = trigger;
138
- config.automation.autoAnalyze = autoAnalyze;
139
- config.automation.autoFix = autoFix;
140
-
141
- await ConfigurationManager.save(config);
142
-
143
- // Install git hooks
144
- await hookManager.installHooks(trigger);
145
-
146
- UIComponents.showSuccessBox(`Automation enabled with ${trigger} trigger`);
147
-
148
- // Show configuration summary
149
- console.log(chalk.cyan('\n📋 Automation Configuration:'));
150
- console.log(` Trigger: ${chalk.white(trigger)}`);
151
- console.log(` Auto-analyze: ${autoAnalyze ? chalk.green('enabled') : chalk.red('disabled')}`);
152
- console.log(` Auto-fix: ${autoFix ? chalk.green('enabled') : chalk.red('disabled')}`);
153
- console.log(` Block commits: ${config.automation.blockCommit ? chalk.green('enabled') : chalk.red('disabled')}`);
154
-
155
- if (!config.apiKeys.gemini) {
156
- console.log(chalk.yellow('\n⚠️ Gemini API key not configured. Run "base config" to set up AI features.'));
157
- }
158
-
159
- if (!config.apiKeys.jules) {
160
- console.log(chalk.yellow('⚠️ Jules API key not configured. Run "base config" to set up AI fixing.'));
161
- }
162
- }
163
-
164
- /**
165
- * Disable automation
166
- */
167
- async function disableAutomation(): Promise<void> {
168
- console.log(chalk.cyan('🤖 Disabling BaseGuard automation...'));
169
-
170
- const config = await ConfigurationManager.load();
171
- const hookManager = new GitHookManager();
172
-
173
- // Update configuration
174
- config.automation.enabled = false;
175
- await ConfigurationManager.save(config);
176
-
177
- // Uninstall git hooks
178
- await hookManager.uninstallHooks();
179
-
180
- UIComponents.showSuccessBox('Automation disabled');
181
- }
182
-
183
- /**
184
- * Show automation status
185
- */
186
- async function showAutomationStatus(): Promise<void> {
187
- const config = await ConfigurationManager.load();
188
- const hookManager = new GitHookManager();
189
-
190
- console.log(chalk.cyan('🤖 BaseGuard Automation Status\n'));
191
-
192
- // Configuration status
193
- console.log(chalk.white('Configuration:'));
194
- console.log(` Enabled: ${config.automation.enabled ? chalk.green('✓') : chalk.red('✗')}`);
195
- console.log(` Trigger: ${chalk.white(config.automation.trigger)}`);
196
- console.log(` Auto-analyze: ${config.automation.autoAnalyze ? chalk.green('✓') : chalk.red('✗')}`);
197
- console.log(` Auto-fix: ${config.automation.autoFix ? chalk.green('✓') : chalk.red('✗')}`);
198
- console.log(` Block commits: ${config.automation.blockCommit ? chalk.green('✓') : chalk.red('✗')}`);
199
-
200
- // Git hooks status
201
- const hooksInstalled = await hookManager.areHooksInstalled();
202
- const installedHooks = await hookManager.getInstalledHooks();
203
-
204
- console.log(chalk.white('\nGit Hooks:'));
205
- console.log(` Installed: ${hooksInstalled ? chalk.green('✓') : chalk.red('✗')}`);
206
- if (installedHooks.length > 0) {
207
- console.log(` Active hooks: ${chalk.white(installedHooks.join(', '))}`);
208
- }
209
-
210
- // API keys status
211
- console.log(chalk.white('\nAPI Keys:'));
212
- console.log(` Gemini: ${config.apiKeys.gemini ? chalk.green('✓ configured') : chalk.red('✗ not configured')}`);
213
- console.log(` Jules: ${config.apiKeys.jules ? chalk.green('✓ configured') : chalk.red('✗ not configured')}`);
214
-
215
- // Recommendations
216
- if (config.automation.enabled && !hooksInstalled) {
217
- console.log(chalk.yellow('\n⚠️ Automation is enabled but git hooks are not installed. Run "base automation enable" to fix this.'));
218
- }
219
-
220
- if (config.automation.autoAnalyze && !config.apiKeys.gemini) {
221
- console.log(chalk.yellow('⚠️ Auto-analyze is enabled but Gemini API key is not configured.'));
222
- }
223
-
224
- if (config.automation.autoFix && (!config.apiKeys.jules || !config.apiKeys.gemini)) {
225
- console.log(chalk.yellow('⚠️ Auto-fix is enabled but API keys are not configured.'));
226
- }
227
- }
228
-
229
- /**
230
- * Configure automation settings
231
- */
232
- async function configureAutomation(): Promise<void> {
233
- console.log(chalk.cyan('🤖 Configuring BaseGuard automation...\n'));
234
-
235
- const config = await ConfigurationManager.load();
236
- const hookManager = new GitHookManager();
237
-
238
- const answers = await inquirer.prompt([
239
- {
240
- type: 'confirm',
241
- name: 'enabled',
242
- message: 'Enable automation?',
243
- default: config.automation.enabled
244
- },
245
- {
246
- type: 'list',
247
- name: 'trigger',
248
- message: 'When should BaseGuard check for violations?',
249
- choices: [
250
- { name: 'Before each commit (pre-commit)', value: 'pre-commit' },
251
- { name: 'Before each push (pre-push)', value: 'pre-push' }
252
- ],
253
- default: config.automation.trigger,
254
- when: (answers) => answers.enabled
255
- },
256
- {
257
- type: 'confirm',
258
- name: 'autoAnalyze',
259
- message: 'Enable automatic AI analysis of violations?',
260
- default: config.automation.autoAnalyze,
261
- when: (answers) => answers.enabled && !!config.apiKeys.gemini
262
- },
263
- {
264
- type: 'confirm',
265
- name: 'autoFix',
266
- message: 'Enable automatic AI fixing of violations?',
267
- default: config.automation.autoFix,
268
- when: (answers) => answers.enabled && !!config.apiKeys.jules && !!config.apiKeys.gemini
269
- },
270
- {
271
- type: 'confirm',
272
- name: 'blockCommit',
273
- message: 'Block commits when violations are found?',
274
- default: config.automation.blockCommit,
275
- when: (answers) => answers.enabled
276
- }
277
- ]);
278
-
279
- // Update configuration
280
- const oldTrigger = config.automation.trigger;
281
-
282
- config.automation.enabled = answers.enabled ?? config.automation.enabled;
283
- config.automation.trigger = answers.trigger ?? config.automation.trigger;
284
- config.automation.autoAnalyze = answers.autoAnalyze ?? config.automation.autoAnalyze;
285
- config.automation.autoFix = answers.autoFix ?? config.automation.autoFix;
286
- config.automation.blockCommit = answers.blockCommit ?? config.automation.blockCommit;
287
-
288
- await ConfigurationManager.save(config);
289
-
290
- // Update git hooks if needed
291
- if (config.automation.enabled) {
292
- if (oldTrigger !== config.automation.trigger) {
293
- await hookManager.updateHookConfiguration(oldTrigger, config.automation.trigger);
294
- } else {
295
- await hookManager.installHooks(config.automation.trigger);
296
- }
297
- } else {
298
- await hookManager.uninstallHooks();
299
- }
300
-
301
- UIComponents.showSuccessBox('Automation configuration updated');
302
-
303
- // Show updated status
304
- await showAutomationStatus();
305
- }
306
-
307
- /**
308
- * Run automation manually (used by git hooks)
309
- */
310
- async function runAutomation(options: { trigger?: string; strict?: boolean } = {}): Promise<void> {
311
- const trigger = options.trigger as 'pre-commit' | 'pre-push' || 'pre-commit';
312
-
313
- const automationOptions: AutomationOptions = {
314
- trigger,
315
- strict: options.strict
316
- };
317
-
318
- const engine = new AutomationEngine();
319
- await engine.run(automationOptions);
320
- }
321
-
322
- /**
323
- * Show automation help
324
- */
325
- async function showAutomationHelp(): Promise<void> {
326
- console.log(chalk.cyan('🤖 BaseGuard Automation Commands\n'));
327
-
328
- console.log(chalk.white('Usage:'));
329
- console.log(' base automation <command> [options]\n');
330
-
331
- console.log(chalk.white('Commands:'));
332
- console.log(' enable Enable automation with git hooks');
333
- console.log(' disable Disable automation and remove git hooks');
334
- console.log(' status Show current automation status');
335
- console.log(' configure Interactive configuration of automation settings');
336
- console.log(' run Run automation manually (used by git hooks)\n');
337
-
338
- console.log(chalk.white('Examples:'));
339
- console.log(' base automation enable');
340
- console.log(' base automation enable --trigger pre-push');
341
- console.log(' base automation disable');
342
- console.log(' base automation status');
343
- console.log(' base automation configure');
344
- }