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,504 +0,0 @@
1
- import type { Violation, Analysis, Fix, JulesSession, JulesActivity } from '../types/index.js';
2
- import { GitHubManager } from '../git/github-manager.js';
3
- import { FixManager } from './fix-manager.js';
4
- import { ErrorHandler, APIError, ErrorType } from '../core/error-handler.js';
5
- import chalk from 'chalk';
6
-
7
- /**
8
- * Jules AI implementer for autonomous code fixing
9
- * Note: Jules requires GitHub repositories and cannot work with local files
10
- */
11
- export class JulesImplementer {
12
- private apiKey: string;
13
- private baseUrl = 'https://jules.googleapis.com/v1alpha';
14
- private githubManager: GitHubManager;
15
- private fixManager: FixManager;
16
-
17
- constructor(apiKey: string) {
18
- this.apiKey = apiKey;
19
- this.githubManager = new GitHubManager();
20
- this.fixManager = new FixManager();
21
- }
22
-
23
- /**
24
- * Generate a fix using Jules AI
25
- */
26
- async generateFix(violation: Violation, analysis: Analysis, repoSource?: string): Promise<Fix> {
27
- const context = ErrorHandler.createContext('jules_fix_generation', {
28
- feature: violation.feature,
29
- file: violation.file,
30
- browser: violation.browser
31
- });
32
-
33
- try {
34
- // Get repository source if not provided
35
- const source = repoSource || await this.githubManager.getCurrentSourceIdentifier();
36
-
37
- // Create a session for this specific fix with retry logic
38
- const session = await ErrorHandler.withRetry(
39
- () => this.createSession(violation, analysis, source),
40
- {
41
- maxRetries: 2,
42
- retryableErrors: [ErrorType.NETWORK, ErrorType.TIMEOUT, ErrorType.RATE_LIMIT, ErrorType.SERVER_ERROR]
43
- }
44
- );
45
-
46
- // Monitor session activities until completion
47
- const activities = await this.waitForCompletion(session.id);
48
-
49
- // Extract the generated code changes
50
- const fix = await this.extractFix(session.id, activities, violation, analysis);
51
-
52
- return fix;
53
- } catch (error) {
54
- const apiError = ErrorHandler.handleAPIError(error, context);
55
-
56
- // Log error for debugging
57
- console.error('Jules fix generation failed:', {
58
- feature: violation.feature,
59
- error: apiError.message,
60
- type: apiError.type
61
- });
62
-
63
- // Re-throw with proper error handling
64
- throw apiError;
65
- }
66
- }
67
-
68
- /**
69
- * Create a Jules session for fixing
70
- */
71
- private async createSession(violation: Violation, analysis: Analysis, source: string): Promise<JulesSession> {
72
- const prompt = this.buildFixPrompt(violation, analysis);
73
-
74
- const response = await fetch(`${this.baseUrl}/sessions`, {
75
- method: 'POST',
76
- headers: {
77
- 'Content-Type': 'application/json',
78
- 'X-Goog-Api-Key': this.apiKey
79
- },
80
- body: JSON.stringify({
81
- prompt: prompt,
82
- sourceContext: {
83
- source: source, // e.g., "sources/github/user/repo"
84
- githubRepoContext: {
85
- startingBranch: "main"
86
- }
87
- },
88
- title: `Fix ${violation.feature} compatibility in ${violation.file}`,
89
- requirePlanApproval: false // Auto-approve for BaseGuard automation
90
- })
91
- });
92
-
93
- if (!response.ok) {
94
- const errorText = await response.text();
95
- const error = new Error(`Jules API error: ${response.status} ${response.statusText} - ${errorText}`);
96
- (error as any).response = response;
97
- throw error;
98
- }
99
-
100
- const sessionData = await response.json();
101
-
102
- // Validate session response
103
- ErrorHandler.validateAPIResponse(sessionData, ['id']);
104
-
105
- return sessionData;
106
- }
107
-
108
- /**
109
- * Wait for Jules session completion
110
- */
111
- private async waitForCompletion(sessionId: string): Promise<JulesActivity[]> {
112
- let attempts = 0;
113
- const maxAttempts = 30; // 5 minutes max (10 seconds * 30)
114
-
115
- while (attempts < maxAttempts) {
116
- const activities = await this.getActivities(sessionId);
117
- const lastActivity = activities[activities.length - 1];
118
-
119
- // Check if session is complete
120
- if (lastActivity && this.isCompletionActivity(lastActivity)) {
121
- return activities;
122
- }
123
-
124
- // Check for failure states
125
- if (lastActivity && this.isFailureActivity(lastActivity)) {
126
- throw new Error(`Jules session failed: ${JSON.stringify(lastActivity)}`);
127
- }
128
-
129
- // Wait 10 seconds before checking again
130
- await new Promise(resolve => setTimeout(resolve, 10000));
131
- attempts++;
132
- }
133
-
134
- throw new Error('Jules session timed out after 5 minutes');
135
- }
136
-
137
- private isCompletionActivity(activity: any): boolean {
138
- return (
139
- activity?.type === 'sessionCompleted' ||
140
- activity?.type === 'agent_finished' ||
141
- activity?.status === 'completed' ||
142
- Boolean(activity?.sessionCompleted)
143
- );
144
- }
145
-
146
- private isFailureActivity(activity: any): boolean {
147
- return (
148
- activity?.type === 'sessionFailed' ||
149
- activity?.status === 'failed' ||
150
- activity?.status === 'error' ||
151
- Boolean(activity?.sessionFailed)
152
- );
153
- }
154
-
155
- /**
156
- * Get activities for a Jules session
157
- */
158
- private async getActivities(sessionId: string): Promise<JulesActivity[]> {
159
- const response = await fetch(`${this.baseUrl}/sessions/${sessionId}/activities`, {
160
- headers: {
161
- 'X-Goog-Api-Key': this.apiKey
162
- }
163
- });
164
-
165
- if (!response.ok) {
166
- const error = new Error(`Failed to get activities: ${response.status} ${response.statusText}`);
167
- (error as any).response = response;
168
- throw error;
169
- }
170
-
171
- const data = await response.json();
172
-
173
- // Validate response structure
174
- if (!data || typeof data !== 'object') {
175
- throw new APIError(
176
- 'Invalid activities response from Jules API',
177
- ErrorType.VALIDATION,
178
- {
179
- suggestions: [
180
- 'Check Jules API service status',
181
- 'Verify session ID is valid',
182
- 'Try the request again'
183
- ]
184
- }
185
- );
186
- }
187
-
188
- return data.activities || [];
189
- }
190
-
191
- /**
192
- * Extract fix from completed Jules session
193
- */
194
- private async extractFix(sessionId: string, activities: JulesActivity[], violation: Violation, analysis: Analysis): Promise<Fix> {
195
- // Get the final session state to extract code changes
196
- const sessionResponse = await fetch(`${this.baseUrl}/sessions/${sessionId}`, {
197
- headers: {
198
- 'X-Goog-Api-Key': this.apiKey
199
- }
200
- });
201
-
202
- if (!sessionResponse.ok) {
203
- throw new Error(`Failed to get session details: ${sessionResponse.status}`);
204
- }
205
-
206
- const sessionData = await sessionResponse.json();
207
-
208
- // Prefer official Jules patch artifact when available
209
- const patch = this.extractPatchFromActivities(activities, sessionData);
210
- const codeChanges = this.extractCodeChanges(activities, sessionData);
211
- const finalPatch = patch || this.generateUnifiedDiff(violation.file, codeChanges);
212
-
213
- return {
214
- violation,
215
- analysis,
216
- patch: finalPatch,
217
- explanation: this.generateFixExplanation(violation, analysis, codeChanges),
218
- filePath: violation.file,
219
- preview: this.generatePreview(codeChanges, finalPatch),
220
- confidence: 0.8, // Jules confidence score
221
- testable: true
222
- };
223
- }
224
-
225
- private extractPatchFromActivities(activities: JulesActivity[], sessionData: any): string {
226
- const activityPatch = activities
227
- .map((activity: any) =>
228
- activity?.changeSet?.gitPatch?.unidiffPatch ||
229
- activity?.changeSet?.gitPatch?.patch ||
230
- activity?.gitPatch?.unidiffPatch ||
231
- activity?.gitPatch?.patch
232
- )
233
- .find((patch: string | undefined) => typeof patch === 'string' && patch.length > 0);
234
-
235
- if (activityPatch) {
236
- return activityPatch;
237
- }
238
-
239
- return (
240
- sessionData?.changeSet?.gitPatch?.unidiffPatch ||
241
- sessionData?.changeSet?.gitPatch?.patch ||
242
- sessionData?.latestChangeSet?.gitPatch?.unidiffPatch ||
243
- sessionData?.latestChangeSet?.gitPatch?.patch ||
244
- ''
245
- );
246
- }
247
-
248
- /**
249
- * Extract code changes from Jules activities and session data
250
- */
251
- private extractCodeChanges(activities: JulesActivity[], sessionData: any): { original: string; modified: string } {
252
- // Look for code changes in activities
253
- const codeActivity = activities.find(activity =>
254
- activity.type === 'code_change' || activity.type === 'file_edit'
255
- );
256
-
257
- if (codeActivity) {
258
- // Extract from activity data (implementation depends on Jules API response format)
259
- return {
260
- original: sessionData.originalCode || '',
261
- modified: sessionData.modifiedCode || ''
262
- };
263
- }
264
-
265
- // Fallback: extract from session data
266
- return {
267
- original: sessionData.originalCode || '',
268
- modified: sessionData.modifiedCode || ''
269
- };
270
- }
271
-
272
- /**
273
- * Generate unified diff patch
274
- */
275
- private generateUnifiedDiff(filePath: string, changes: { original: string; modified: string }): string {
276
- const originalLines = changes.original.split('\n');
277
- const modifiedLines = changes.modified.split('\n');
278
-
279
- // Simple diff generation (in production, use a proper diff library)
280
- let patch = `--- a/${filePath}\n+++ b/${filePath}\n`;
281
-
282
- // Find differences and generate patch format
283
- for (let i = 0; i < Math.max(originalLines.length, modifiedLines.length); i++) {
284
- const originalLine = originalLines[i] || '';
285
- const modifiedLine = modifiedLines[i] || '';
286
-
287
- if (originalLine !== modifiedLine) {
288
- if (originalLine) {
289
- patch += `-${originalLine}\n`;
290
- }
291
- if (modifiedLine) {
292
- patch += `+${modifiedLine}\n`;
293
- }
294
- }
295
- }
296
-
297
- return patch;
298
- }
299
-
300
- /**
301
- * Generate fix explanation
302
- */
303
- private generateFixExplanation(violation: Violation, analysis: Analysis, _changes: { original: string; modified: string }): string {
304
- return `Fixed ${violation.feature} compatibility issue in ${violation.file}:\n\n` +
305
- `- Added progressive enhancement using ${analysis.fixStrategy}\n` +
306
- `- Implemented fallback for ${violation.browser} ${violation.required}\n` +
307
- `- Applied best practices: ${analysis.bestPractices.join(', ')}\n\n` +
308
- `This fix ensures the feature works across all target browsers while maintaining the original functionality.`;
309
- }
310
-
311
- /**
312
- * Generate human-readable preview
313
- */
314
- private generatePreview(changes: { original: string; modified: string }, patch: string): string {
315
- if (patch) {
316
- return patch.split('\n').slice(0, 40).join('\n');
317
- }
318
-
319
- const originalLines = changes.original.split('\n');
320
- const modifiedLines = changes.modified.split('\n');
321
-
322
- let preview = 'Changes:\n';
323
-
324
- for (let i = 0; i < Math.max(originalLines.length, modifiedLines.length); i++) {
325
- const originalLine = originalLines[i];
326
- const modifiedLine = modifiedLines[i];
327
-
328
- if (originalLine !== modifiedLine) {
329
- if (originalLine) {
330
- preview += `- ${originalLine}\n`;
331
- }
332
- if (modifiedLine) {
333
- preview += `+ ${modifiedLine}\n`;
334
- }
335
- }
336
- }
337
-
338
- return preview;
339
- }
340
-
341
- /**
342
- * Build fix prompt for Jules
343
- */
344
- private buildFixPrompt(violation: Violation, analysis: Analysis): string {
345
- return `Fix browser compatibility issue in ${violation.file}:
346
-
347
- ISSUE:
348
- - Feature: ${violation.feature} (line ${violation.line})
349
- - Unsupported in: ${violation.browser} ${violation.required}
350
- - Baseline Status: ${violation.baselineStatus}
351
- - Current code: ${violation.context}
352
-
353
- ANALYSIS:
354
- ${analysis.plainEnglish}
355
-
356
- FIX STRATEGY:
357
- ${analysis.fixStrategy}
358
-
359
- REQUIREMENTS:
360
- 1. Implement progressive enhancement using @supports for CSS features
361
- 2. Use feature detection for JavaScript APIs
362
- 3. Add appropriate fallbacks for older browsers
363
- 4. Preserve all original functionality
364
- 5. Follow best practices: ${analysis.bestPractices.join(', ')}
365
- 6. Ensure the fix works in ${violation.browser} ${violation.required} and newer versions
366
-
367
- Please fix this compatibility issue while maintaining the existing functionality. The fix should be production-ready and follow web standards.`;
368
- }
369
-
370
- /**
371
- * Test Jules API connectivity
372
- */
373
- async testConnection(): Promise<{ success: boolean; error?: string; errorType?: ErrorType }> {
374
- try {
375
- const response = await fetch(`${this.baseUrl}/sessions`, {
376
- method: 'GET',
377
- headers: {
378
- 'X-Goog-Api-Key': this.apiKey
379
- }
380
- });
381
-
382
- if (response.ok || response.status === 404) {
383
- // 404 is acceptable for sessions endpoint when no sessions exist
384
- return { success: true };
385
- } else {
386
- const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
387
- (error as any).response = response;
388
- throw error;
389
- }
390
- } catch (error) {
391
- const apiError = ErrorHandler.handleAPIError(error);
392
-
393
- return {
394
- success: false,
395
- error: apiError.message,
396
- errorType: apiError.type
397
- };
398
- }
399
- }
400
-
401
- /**
402
- * Get repository source identifier (GitHub integration is handled on Jules dashboard)
403
- */
404
- async getRepositorySource(): Promise<string> {
405
- return await this.githubManager.getSourceIdentifier();
406
- }
407
-
408
- /**
409
- * Check if repository information is available (GitHub integration is handled on Jules dashboard)
410
- */
411
- async isRepositoryDetected(): Promise<boolean> {
412
- return await this.githubManager.isJulesIntegrationSetup();
413
- }
414
-
415
- /**
416
- * Verify GitHub connection and permissions
417
- */
418
- async verifyGitHubConnection(): Promise<boolean> {
419
- return await this.githubManager.verifyGitHubConnection();
420
- }
421
-
422
- /**
423
- * Get repository information
424
- */
425
- getRepositoryInfo(): { owner: string | null; name: string | null } {
426
- return this.githubManager.getRepositoryInfo();
427
- }
428
-
429
- /**
430
- * Get current source identifier
431
- */
432
- async getSourceIdentifier(): Promise<string> {
433
- return await this.githubManager.getCurrentSourceIdentifier();
434
- }
435
-
436
- /**
437
- * Generate and apply fixes with interactive preview
438
- */
439
- async generateAndApplyFixes(violations: Violation[], analyses: Analysis[]): Promise<{ applied: Fix[]; skipped: Fix[]; failed: { fix: Fix; error: string }[] }> {
440
- const fixes: Fix[] = [];
441
-
442
- // Generate fixes for each violation
443
- for (let i = 0; i < violations.length; i++) {
444
- const violation = violations[i];
445
- const analysis = analyses[i];
446
-
447
- if (!violation || !analysis) {
448
- console.log(chalk.red(`āŒ Missing violation or analysis data for index ${i}`));
449
- continue;
450
- }
451
-
452
- try {
453
- console.log(chalk.cyan(`\nšŸ”§ Generating fix ${i + 1}/${violations.length} for ${violation.feature}...`));
454
- const fix = await this.generateFix(violation, analysis);
455
- fixes.push(fix);
456
- } catch (error) {
457
- console.log(chalk.red(`āŒ Failed to generate fix for ${violation.feature}: ${error instanceof Error ? error.message : 'Unknown error'}`));
458
- }
459
- }
460
-
461
- if (fixes.length === 0) {
462
- console.log(chalk.yellow('āš ļø No fixes were generated'));
463
- return { applied: [], skipped: [], failed: [] };
464
- }
465
-
466
- // Apply fixes with interactive preview
467
- return await this.fixManager.applyFixes(fixes);
468
- }
469
-
470
- /**
471
- * Preview a single fix
472
- */
473
- async previewFix(fix: Fix): Promise<string> {
474
- return await this.fixManager.generatePreview(fix);
475
- }
476
-
477
- /**
478
- * Apply a single fix
479
- */
480
- async applySingleFix(fix: Fix): Promise<void> {
481
- await this.fixManager.applyFix(fix);
482
- }
483
-
484
- /**
485
- * Rollback applied fixes
486
- */
487
- async rollbackFix(filePath: string): Promise<void> {
488
- await this.fixManager.rollbackFix(filePath);
489
- }
490
-
491
- /**
492
- * Rollback all applied fixes
493
- */
494
- async rollbackAllFixes(): Promise<void> {
495
- await this.fixManager.rollbackAllFixes();
496
- }
497
-
498
- /**
499
- * Get list of applied fixes
500
- */
501
- getAppliedFixes(): string[] {
502
- return this.fixManager.getAppliedFixes();
503
- }
504
- }