baseguard 1.0.0 ā 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.baseguardrc.example.json +64 -0
- package/.eslintrc.json +1 -1
- package/CHANGELOG.md +196 -0
- package/DEPLOYMENT.md +625 -0
- package/DEPLOYMENT_CHECKLIST.md +239 -0
- package/DEPLOYMENT_SUMMARY_v1.0.2.md +202 -0
- package/QUICK_START.md +134 -0
- package/README.md +447 -52
- package/RELEASE_NOTES_v1.0.2.md +434 -0
- package/bin/base.js +155 -36
- package/dist/ai/agentkit-orchestrator.d.ts +116 -0
- package/dist/ai/agentkit-orchestrator.d.ts.map +1 -0
- package/dist/ai/agentkit-orchestrator.js +417 -0
- package/dist/ai/agentkit-orchestrator.js.map +1 -0
- package/dist/ai/gemini-code-fixer.d.ts +85 -0
- package/dist/ai/gemini-code-fixer.d.ts.map +1 -0
- package/dist/ai/gemini-code-fixer.js +452 -0
- package/dist/ai/gemini-code-fixer.js.map +1 -0
- package/dist/ai/jules-implementer.d.ts +5 -4
- package/dist/ai/jules-implementer.d.ts.map +1 -1
- package/dist/ai/jules-implementer.js +6 -5
- package/dist/ai/jules-implementer.js.map +1 -1
- package/dist/ai/unified-code-fixer.d.ts +69 -0
- package/dist/ai/unified-code-fixer.d.ts.map +1 -0
- package/dist/ai/unified-code-fixer.js +289 -0
- package/dist/ai/unified-code-fixer.js.map +1 -0
- package/dist/commands/check.d.ts +3 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +166 -34
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +183 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +89 -91
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +16 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/status.d.ts +14 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +254 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/baseguard.d.ts +47 -5
- package/dist/core/baseguard.d.ts.map +1 -1
- package/dist/core/baseguard.js +506 -52
- package/dist/core/baseguard.js.map +1 -1
- package/dist/core/cache-manager.d.ts.map +1 -1
- package/dist/core/cache-manager.js +3 -1
- package/dist/core/cache-manager.js.map +1 -1
- package/dist/core/configuration-recovery.d.ts +116 -0
- package/dist/core/configuration-recovery.d.ts.map +1 -0
- package/dist/core/configuration-recovery.js +552 -0
- package/dist/core/configuration-recovery.js.map +1 -0
- package/dist/core/configuration.d.ts +4 -0
- package/dist/core/configuration.d.ts.map +1 -1
- package/dist/core/configuration.js +35 -0
- package/dist/core/configuration.js.map +1 -1
- package/dist/core/debug-logger.d.ts +181 -0
- package/dist/core/debug-logger.d.ts.map +1 -0
- package/dist/core/debug-logger.js +479 -0
- package/dist/core/debug-logger.js.map +1 -0
- package/dist/core/file-processor.d.ts.map +1 -1
- package/dist/core/file-processor.js +8 -2
- package/dist/core/file-processor.js.map +1 -1
- package/dist/core/graceful-degradation-manager.d.ts +123 -0
- package/dist/core/graceful-degradation-manager.d.ts.map +1 -0
- package/dist/core/graceful-degradation-manager.js +512 -0
- package/dist/core/graceful-degradation-manager.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/logger.d.ts +1 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +2 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/memory-manager.d.ts +84 -0
- package/dist/core/memory-manager.d.ts.map +1 -1
- package/dist/core/memory-manager.js +236 -1
- package/dist/core/memory-manager.js.map +1 -1
- package/dist/core/startup-optimizer.d.ts +12 -0
- package/dist/core/startup-optimizer.d.ts.map +1 -1
- package/dist/core/startup-optimizer.js +60 -0
- package/dist/core/startup-optimizer.js.map +1 -1
- package/dist/core/system-error-handler.d.ts +65 -0
- package/dist/core/system-error-handler.d.ts.map +1 -0
- package/dist/core/system-error-handler.js +646 -0
- package/dist/core/system-error-handler.js.map +1 -0
- package/dist/git/github-manager.d.ts +5 -16
- package/dist/git/github-manager.d.ts.map +1 -1
- package/dist/git/github-manager.js +6 -61
- package/dist/git/github-manager.js.map +1 -1
- package/dist/parsers/react-parser-optimized.d.ts +16 -0
- package/dist/parsers/react-parser-optimized.d.ts.map +1 -0
- package/dist/parsers/react-parser-optimized.js +147 -0
- package/dist/parsers/react-parser-optimized.js.map +1 -0
- package/dist/parsers/react-parser.d.ts.map +1 -1
- package/dist/parsers/react-parser.js +17 -15
- package/dist/parsers/react-parser.js.map +1 -1
- package/dist/parsers/svelte-parser.d.ts.map +1 -1
- package/dist/parsers/svelte-parser.js +7 -3
- package/dist/parsers/svelte-parser.js.map +1 -1
- package/dist/parsers/vanilla-parser.d.ts.map +1 -1
- package/dist/parsers/vanilla-parser.js +7 -3
- package/dist/parsers/vanilla-parser.js.map +1 -1
- package/dist/parsers/vue-parser.d.ts +18 -0
- package/dist/parsers/vue-parser.d.ts.map +1 -1
- package/dist/parsers/vue-parser.js +387 -1
- package/dist/parsers/vue-parser.js.map +1 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/ui/help.js +1 -1
- package/dist/ui/help.js.map +1 -1
- package/dist/ui/prompts.d.ts +7 -4
- package/dist/ui/prompts.d.ts.map +1 -1
- package/dist/ui/prompts.js +48 -55
- package/dist/ui/prompts.js.map +1 -1
- package/package.json +30 -5
- package/src/ai/__tests__/gemini-analyzer.test.ts +2 -2
- package/src/ai/agentkit-orchestrator.ts +534 -0
- package/src/ai/gemini-code-fixer.ts +540 -0
- package/src/ai/jules-implementer.ts +6 -5
- package/src/ai/unified-code-fixer.ts +347 -0
- package/src/commands/config.ts +218 -0
- package/src/commands/fix.ts +98 -94
- package/src/commands/index.ts +2 -1
- package/src/commands/init.ts +16 -2
- package/src/commands/status.ts +307 -0
- package/src/core/baseguard.ts +36 -22
- package/src/core/cache-manager.ts +4 -2
- package/src/core/configuration-recovery.ts +3 -6
- package/src/core/configuration.ts +37 -0
- package/src/core/debug-logger.ts +2 -2
- package/src/core/file-processor.ts +10 -3
- package/src/core/index.ts +5 -1
- package/src/core/memory-manager.ts +4 -3
- package/src/core/startup-optimizer.ts +70 -0
- package/src/core/system-error-handler.ts +9 -5
- package/src/git/github-manager.ts +11 -79
- package/src/parsers/react-parser.ts +2 -2
- package/src/parsers/svelte-parser.ts +13 -9
- package/src/parsers/vanilla-parser.ts +18 -14
- package/src/parsers/vue-parser.ts +20 -14
- package/src/types/index.ts +4 -0
- package/src/ui/help.ts +1 -1
- package/src/ui/prompts.ts +54 -61
- package/test-build.js +41 -0
- package/tests/e2e/git-integration.e2e.test.ts +1 -1
- package/tsconfig.json +0 -1
- package/vitest.config.ts +4 -2
package/src/core/baseguard.ts
CHANGED
|
@@ -16,11 +16,11 @@ import chalk from 'chalk';
|
|
|
16
16
|
*/
|
|
17
17
|
export class BaseGuard {
|
|
18
18
|
private config: Configuration;
|
|
19
|
-
private parserManager
|
|
20
|
-
private baselineChecker
|
|
21
|
-
private fileProcessor
|
|
22
|
-
private directoryFilter
|
|
23
|
-
private cacheManager
|
|
19
|
+
private parserManager!: ParserManager;
|
|
20
|
+
private baselineChecker!: BaselineChecker;
|
|
21
|
+
private fileProcessor!: FileProcessor;
|
|
22
|
+
private directoryFilter!: DirectoryFilter;
|
|
23
|
+
private cacheManager!: CacheManager;
|
|
24
24
|
private categoryLogger: ReturnType<typeof logger.createCategoryLogger>;
|
|
25
25
|
private initialized = false;
|
|
26
26
|
|
|
@@ -28,8 +28,10 @@ export class BaseGuard {
|
|
|
28
28
|
this.config = config;
|
|
29
29
|
this.categoryLogger = logger.createCategoryLogger('baseguard');
|
|
30
30
|
|
|
31
|
-
// Initialize with error handling
|
|
32
|
-
this.initializeComponents()
|
|
31
|
+
// Initialize with error handling (async initialization)
|
|
32
|
+
this.initializeComponents().catch(error => {
|
|
33
|
+
this.categoryLogger.error('Failed to initialize BaseGuard', { error });
|
|
34
|
+
});
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -43,9 +45,9 @@ export class BaseGuard {
|
|
|
43
45
|
await GracefulDegradationManager.initialize();
|
|
44
46
|
|
|
45
47
|
// Initialize components with error handling
|
|
46
|
-
await SystemErrorHandler.handleGracefully(
|
|
48
|
+
this.cacheManager = await SystemErrorHandler.handleGracefully(
|
|
47
49
|
async () => {
|
|
48
|
-
|
|
50
|
+
return new CacheManager({
|
|
49
51
|
maxCacheSize: parseInt(process.env.BASEGUARD_CACHE_SIZE || '2000'),
|
|
50
52
|
cacheValidityMs: 10 * 60 * 1000 // 10 minutes
|
|
51
53
|
});
|
|
@@ -54,17 +56,17 @@ export class BaseGuard {
|
|
|
54
56
|
{ operation: 'cache_manager_init' }
|
|
55
57
|
);
|
|
56
58
|
|
|
57
|
-
await SystemErrorHandler.handleGracefully(
|
|
59
|
+
this.parserManager = await SystemErrorHandler.handleGracefully(
|
|
58
60
|
async () => {
|
|
59
|
-
|
|
61
|
+
return new ParserManager();
|
|
60
62
|
},
|
|
61
63
|
new ParserManager(),
|
|
62
64
|
{ operation: 'parser_manager_init' }
|
|
63
65
|
);
|
|
64
66
|
|
|
65
|
-
await SystemErrorHandler.handleGracefully(
|
|
67
|
+
this.baselineChecker = await SystemErrorHandler.handleGracefully(
|
|
66
68
|
async () => {
|
|
67
|
-
|
|
69
|
+
return new BaselineChecker();
|
|
68
70
|
},
|
|
69
71
|
new BaselineChecker(),
|
|
70
72
|
{ operation: 'baseline_checker_init' }
|
|
@@ -73,9 +75,9 @@ export class BaseGuard {
|
|
|
73
75
|
const maxWorkers = parseInt(process.env.BASEGUARD_MAX_WORKERS || '8');
|
|
74
76
|
const maxFiles = parseInt(process.env.BASEGUARD_MAX_FILES || '5000');
|
|
75
77
|
|
|
76
|
-
await SystemErrorHandler.handleGracefully(
|
|
78
|
+
this.fileProcessor = await SystemErrorHandler.handleGracefully(
|
|
77
79
|
async () => {
|
|
78
|
-
|
|
80
|
+
return new FileProcessor({
|
|
79
81
|
maxWorkers,
|
|
80
82
|
cacheManager: this.cacheManager
|
|
81
83
|
});
|
|
@@ -84,9 +86,9 @@ export class BaseGuard {
|
|
|
84
86
|
{ operation: 'file_processor_init' }
|
|
85
87
|
);
|
|
86
88
|
|
|
87
|
-
await SystemErrorHandler.handleGracefully(
|
|
89
|
+
this.directoryFilter = await SystemErrorHandler.handleGracefully(
|
|
88
90
|
async () => {
|
|
89
|
-
|
|
91
|
+
return new DirectoryFilter({
|
|
90
92
|
maxDepth: 8,
|
|
91
93
|
maxFiles
|
|
92
94
|
});
|
|
@@ -167,7 +169,7 @@ export class BaseGuard {
|
|
|
167
169
|
try {
|
|
168
170
|
const compatibilityResult = await SystemErrorHandler.handleGracefully(
|
|
169
171
|
() => this.baselineChecker.checkCompatibility(feature, this.config.targets),
|
|
170
|
-
{ violations: [] }, // fallback result
|
|
172
|
+
{ violations: [], featureData: null }, // fallback result
|
|
171
173
|
{
|
|
172
174
|
operation: 'check_compatibility',
|
|
173
175
|
file: feature.file,
|
|
@@ -340,7 +342,10 @@ export class BaseGuard {
|
|
|
340
342
|
try {
|
|
341
343
|
// Cleanup file processor
|
|
342
344
|
await SystemErrorHandler.handleGracefully(
|
|
343
|
-
() =>
|
|
345
|
+
async () => {
|
|
346
|
+
await this.fileProcessor.cleanup();
|
|
347
|
+
return undefined;
|
|
348
|
+
},
|
|
344
349
|
undefined,
|
|
345
350
|
{ operation: 'file_processor_cleanup' },
|
|
346
351
|
{ logError: false, showWarning: false }
|
|
@@ -348,7 +353,10 @@ export class BaseGuard {
|
|
|
348
353
|
|
|
349
354
|
// Clear caches
|
|
350
355
|
await SystemErrorHandler.handleGracefully(
|
|
351
|
-
() =>
|
|
356
|
+
async () => {
|
|
357
|
+
this.cacheManager.clearAll();
|
|
358
|
+
return undefined;
|
|
359
|
+
},
|
|
352
360
|
undefined,
|
|
353
361
|
{ operation: 'cache_cleanup' },
|
|
354
362
|
{ logError: false, showWarning: false }
|
|
@@ -356,7 +364,10 @@ export class BaseGuard {
|
|
|
356
364
|
|
|
357
365
|
// Cleanup graceful degradation manager
|
|
358
366
|
await SystemErrorHandler.handleGracefully(
|
|
359
|
-
() =>
|
|
367
|
+
async () => {
|
|
368
|
+
await GracefulDegradationManager.cleanupCache();
|
|
369
|
+
return undefined;
|
|
370
|
+
},
|
|
360
371
|
undefined,
|
|
361
372
|
{ operation: 'degradation_cleanup' },
|
|
362
373
|
{ logError: false, showWarning: false }
|
|
@@ -364,7 +375,10 @@ export class BaseGuard {
|
|
|
364
375
|
|
|
365
376
|
// Cleanup old logs
|
|
366
377
|
await SystemErrorHandler.handleGracefully(
|
|
367
|
-
() =>
|
|
378
|
+
async () => {
|
|
379
|
+
await logger.cleanupOldLogs();
|
|
380
|
+
return undefined;
|
|
381
|
+
},
|
|
368
382
|
undefined,
|
|
369
383
|
{ operation: 'log_cleanup' },
|
|
370
384
|
{ logError: false, showWarning: false }
|
|
@@ -28,8 +28,10 @@ export class LRUCache<K, V> {
|
|
|
28
28
|
this.cache.delete(key);
|
|
29
29
|
} else if (this.cache.size >= this.maxSize) {
|
|
30
30
|
// Remove least recently used (first item)
|
|
31
|
-
const firstKey = this.cache.keys().next().value;
|
|
32
|
-
|
|
31
|
+
const firstKey = this.cache.keys().next().value as K;
|
|
32
|
+
if (firstKey !== undefined) {
|
|
33
|
+
this.cache.delete(firstKey);
|
|
34
|
+
}
|
|
33
35
|
}
|
|
34
36
|
this.cache.set(key, value);
|
|
35
37
|
}
|
|
@@ -131,9 +131,8 @@ export class ConfigurationRecovery {
|
|
|
131
131
|
// Step 6: Final validation and save
|
|
132
132
|
if (currentConfig) {
|
|
133
133
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
currentConfig as Configuration;
|
|
134
|
+
// Use the public migrateConfiguration method instead
|
|
135
|
+
const finalConfig = ConfigurationManager.migrateConfiguration(currentConfig);
|
|
137
136
|
|
|
138
137
|
await ConfigurationManager.save(finalConfig);
|
|
139
138
|
result.config = finalConfig;
|
|
@@ -454,9 +453,7 @@ export class ConfigurationRecovery {
|
|
|
454
453
|
}
|
|
455
454
|
|
|
456
455
|
// Perform migration
|
|
457
|
-
const migratedConfig = ConfigurationManager.migrateConfiguration
|
|
458
|
-
ConfigurationManager.migrateConfiguration(config) :
|
|
459
|
-
config;
|
|
456
|
+
const migratedConfig = ConfigurationManager.migrateConfiguration(config);
|
|
460
457
|
|
|
461
458
|
return {
|
|
462
459
|
migrated: true,
|
|
@@ -77,6 +77,10 @@ export class ConfigurationManager {
|
|
|
77
77
|
jules: null,
|
|
78
78
|
gemini: null
|
|
79
79
|
},
|
|
80
|
+
codingAgent: {
|
|
81
|
+
primary: 'gemini', // 'jules' or 'gemini'
|
|
82
|
+
fallback: 'gemini' // fallback when primary fails
|
|
83
|
+
},
|
|
80
84
|
automation: {
|
|
81
85
|
enabled: false,
|
|
82
86
|
trigger: 'pre-commit',
|
|
@@ -119,6 +123,10 @@ export class ConfigurationManager {
|
|
|
119
123
|
jules: config.apiKeys?.jules || null,
|
|
120
124
|
gemini: config.apiKeys?.gemini || null
|
|
121
125
|
},
|
|
126
|
+
codingAgent: {
|
|
127
|
+
primary: this.validateCodingAgent(config.codingAgent?.primary) || defaultConfig.codingAgent.primary,
|
|
128
|
+
fallback: this.validateCodingAgent(config.codingAgent?.fallback) || defaultConfig.codingAgent.fallback
|
|
129
|
+
},
|
|
122
130
|
automation: {
|
|
123
131
|
enabled: config.automation?.enabled ?? defaultConfig.automation.enabled,
|
|
124
132
|
trigger: this.validateTrigger(config.automation?.trigger) || defaultConfig.automation.trigger,
|
|
@@ -194,6 +202,16 @@ export class ConfigurationManager {
|
|
|
194
202
|
return null;
|
|
195
203
|
}
|
|
196
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Validate coding agent selection
|
|
207
|
+
*/
|
|
208
|
+
private static validateCodingAgent(agent: any): 'jules' | 'gemini' | null {
|
|
209
|
+
if (agent === 'jules' || agent === 'gemini') {
|
|
210
|
+
return agent;
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
197
215
|
/**
|
|
198
216
|
* Parse browser target string (e.g., "chrome 100", "safari baseline")
|
|
199
217
|
*/
|
|
@@ -437,6 +455,18 @@ export class ConfigurationManager {
|
|
|
437
455
|
}
|
|
438
456
|
}
|
|
439
457
|
|
|
458
|
+
// Validate coding agent
|
|
459
|
+
if (!config.codingAgent || typeof config.codingAgent !== 'object') {
|
|
460
|
+
errors.push('Coding agent configuration must be an object');
|
|
461
|
+
} else {
|
|
462
|
+
if (config.codingAgent.primary !== 'jules' && config.codingAgent.primary !== 'gemini') {
|
|
463
|
+
errors.push('Primary coding agent must be "jules" or "gemini"');
|
|
464
|
+
}
|
|
465
|
+
if (config.codingAgent.fallback !== 'jules' && config.codingAgent.fallback !== 'gemini') {
|
|
466
|
+
errors.push('Fallback coding agent must be "jules" or "gemini"');
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
440
470
|
// Validate automation
|
|
441
471
|
if (!config.automation || typeof config.automation !== 'object') {
|
|
442
472
|
errors.push('Automation configuration must be an object');
|
|
@@ -481,6 +511,13 @@ export class ConfigurationManager {
|
|
|
481
511
|
migratedConfig.apiKeys.gemini = config.apiKeys.gemini || null;
|
|
482
512
|
}
|
|
483
513
|
|
|
514
|
+
if (config.codingAgent) {
|
|
515
|
+
migratedConfig.codingAgent = {
|
|
516
|
+
primary: this.validateCodingAgent(config.codingAgent.primary) || 'gemini',
|
|
517
|
+
fallback: this.validateCodingAgent(config.codingAgent.fallback) || 'gemini'
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
|
|
484
521
|
if (config.automation) {
|
|
485
522
|
migratedConfig.automation = {
|
|
486
523
|
...migratedConfig.automation,
|
package/src/core/debug-logger.ts
CHANGED
|
@@ -130,8 +130,8 @@ export class DebugLogger {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
this.currentSession.endTime = new Date();
|
|
133
|
-
this.currentSession.
|
|
134
|
-
|
|
133
|
+
const duration = this.currentSession.endTime.getTime() - this.currentSession.startTime.getTime();
|
|
134
|
+
this.currentSession.summary.performance.totalDuration = duration;
|
|
135
135
|
|
|
136
136
|
this.info('session', `Debug session ended: ${this.currentSession.id}`);
|
|
137
137
|
|
|
@@ -103,12 +103,15 @@ export class FileProcessor {
|
|
|
103
103
|
);
|
|
104
104
|
|
|
105
105
|
batchResults.forEach((result, index) => {
|
|
106
|
+
const task = batch[index];
|
|
107
|
+
if (!task) return;
|
|
108
|
+
|
|
106
109
|
if (result.status === 'fulfilled') {
|
|
107
110
|
allFeatures.push(...result.value);
|
|
108
111
|
// Cache the result
|
|
109
|
-
this.cacheManager.setCachedParseResult(
|
|
112
|
+
this.cacheManager.setCachedParseResult(task.filePath, result.value);
|
|
110
113
|
} else {
|
|
111
|
-
console.warn(`Failed to process ${
|
|
114
|
+
console.warn(`Failed to process ${task.filePath}: ${result.reason}`);
|
|
112
115
|
}
|
|
113
116
|
});
|
|
114
117
|
|
|
@@ -222,7 +225,11 @@ export class FileProcessor {
|
|
|
222
225
|
/**
|
|
223
226
|
* Assign task to worker
|
|
224
227
|
*/
|
|
225
|
-
private async assignTaskToWorker(worker: Worker, task: WorkerTask): Promise<void> {
|
|
228
|
+
private async assignTaskToWorker(worker: Worker | undefined, task: WorkerTask): Promise<void> {
|
|
229
|
+
if (!worker) {
|
|
230
|
+
throw new Error('Worker is not available');
|
|
231
|
+
}
|
|
232
|
+
|
|
226
233
|
return new Promise((resolve) => {
|
|
227
234
|
const timeout = setTimeout(() => {
|
|
228
235
|
console.warn(`Worker task ${task.id} timed out`);
|
package/src/core/index.ts
CHANGED
|
@@ -10,4 +10,8 @@ export { FileProcessor } from './file-processor.js';
|
|
|
10
10
|
export { DirectoryFilter } from './directory-filter.js';
|
|
11
11
|
export { LazyLoader } from './lazy-loader.js';
|
|
12
12
|
export { MemoryManager } from './memory-manager.js';
|
|
13
|
-
export { StartupOptimizer } from './startup-optimizer.js';
|
|
13
|
+
export { StartupOptimizer } from './startup-optimizer.js';
|
|
14
|
+
export { SystemErrorHandler } from './system-error-handler.js';
|
|
15
|
+
export { GracefulDegradationManager } from './graceful-degradation-manager.js';
|
|
16
|
+
export { ConfigurationRecovery } from './configuration-recovery.js';
|
|
17
|
+
export { logger, DebugLogger } from './debug-logger.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createReadStream } from 'fs';
|
|
2
2
|
import { createInterface } from 'readline';
|
|
3
3
|
|
|
4
|
-
//
|
|
4
|
+
// Use Node.js built-in gc type
|
|
5
5
|
declare global {
|
|
6
|
-
var gc:
|
|
6
|
+
var gc: NodeJS.GCFunction | undefined;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -291,4 +291,5 @@ class ViolationTracker {
|
|
|
291
291
|
this.violations.clear();
|
|
292
292
|
this.fileIndex.clear();
|
|
293
293
|
this.nextFileId = 0;
|
|
294
|
-
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
@@ -170,4 +170,74 @@ export class StartupOptimizer {
|
|
|
170
170
|
recommendations
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Optimize memory usage by reducing object overhead
|
|
176
|
+
*/
|
|
177
|
+
static optimizeMemoryUsage(): void {
|
|
178
|
+
// Enable V8 memory optimizations if available
|
|
179
|
+
if (process.env.NODE_ENV !== 'development') {
|
|
180
|
+
// Set V8 flags for better memory management
|
|
181
|
+
process.env.NODE_OPTIONS = (process.env.NODE_OPTIONS || '') + ' --max-old-space-size=512 --optimize-for-size';
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Setup memory monitoring
|
|
185
|
+
if (global.gc) {
|
|
186
|
+
setInterval(() => {
|
|
187
|
+
const usage = process.memoryUsage();
|
|
188
|
+
const heapUsedMB = usage.heapUsed / 1024 / 1024;
|
|
189
|
+
|
|
190
|
+
// Force GC if memory usage is high
|
|
191
|
+
if (heapUsedMB > 100 && global.gc) {
|
|
192
|
+
global.gc();
|
|
193
|
+
}
|
|
194
|
+
}, 30000);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Reduce startup time by deferring non-critical operations
|
|
200
|
+
*/
|
|
201
|
+
static async deferNonCriticalOperations(): Promise<void> {
|
|
202
|
+
// Defer heavy operations until after startup
|
|
203
|
+
setTimeout(async () => {
|
|
204
|
+
try {
|
|
205
|
+
// Preload remaining dependencies
|
|
206
|
+
const { LazyLoader } = await import('./lazy-loader.js');
|
|
207
|
+
LazyLoader.preloadCommon();
|
|
208
|
+
|
|
209
|
+
// Initialize caches
|
|
210
|
+
const { CacheManager } = await import('./cache-manager.js');
|
|
211
|
+
// Cache initialization would happen here
|
|
212
|
+
|
|
213
|
+
// Cleanup old logs
|
|
214
|
+
const { logger } = await import('./debug-logger.js');
|
|
215
|
+
logger.cleanupOldLogs().catch(() => {});
|
|
216
|
+
} catch (error) {
|
|
217
|
+
// Ignore errors in deferred operations
|
|
218
|
+
}
|
|
219
|
+
}, 100); // Defer by 100ms
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Optimize startup by preloading critical dependencies
|
|
224
|
+
*/
|
|
225
|
+
static async optimizeStartup(): Promise<void> {
|
|
226
|
+
// Start loading critical dependencies in background
|
|
227
|
+
const { LazyLoader } = await import('./lazy-loader.js');
|
|
228
|
+
|
|
229
|
+
const criticalLoads = [
|
|
230
|
+
LazyLoader.getWebFeatures().catch(() => {}),
|
|
231
|
+
LazyLoader.getBabelParser().catch(() => {})
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
// Don't wait for all to complete, just start the process
|
|
235
|
+
Promise.all(criticalLoads);
|
|
236
|
+
|
|
237
|
+
// Setup memory optimizations
|
|
238
|
+
this.optimizeMemoryUsage();
|
|
239
|
+
|
|
240
|
+
// Defer non-critical operations
|
|
241
|
+
this.deferNonCriticalOperations();
|
|
242
|
+
}
|
|
173
243
|
}
|
|
@@ -30,8 +30,12 @@ export class SystemError extends Error {
|
|
|
30
30
|
super(message);
|
|
31
31
|
this.name = 'SystemError';
|
|
32
32
|
this.context = {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
operation: context?.operation || 'unknown',
|
|
34
|
+
file: context?.file,
|
|
35
|
+
line: context?.line,
|
|
36
|
+
details: context?.details,
|
|
37
|
+
timestamp: new Date(),
|
|
38
|
+
userId: context?.userId
|
|
35
39
|
};
|
|
36
40
|
}
|
|
37
41
|
}
|
|
@@ -110,7 +114,7 @@ export class SystemErrorHandler {
|
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
if (showWarning) {
|
|
113
|
-
console.warn(chalk.yellow(`ā ļø ${context.operation} failed: ${error.message}`));
|
|
117
|
+
console.warn(chalk.yellow(`ā ļø ${context.operation} failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
// Attempt recovery if enabled
|
|
@@ -254,7 +258,7 @@ export class SystemErrorHandler {
|
|
|
254
258
|
return true;
|
|
255
259
|
}
|
|
256
260
|
} catch (recoveryError) {
|
|
257
|
-
console.log(chalk.dim(` Recovery failed: ${recoveryError.message}`));
|
|
261
|
+
console.log(chalk.dim(` Recovery failed: ${recoveryError instanceof Error ? recoveryError.message : 'Unknown error'}`));
|
|
258
262
|
}
|
|
259
263
|
}
|
|
260
264
|
|
|
@@ -414,7 +418,7 @@ export class SystemErrorHandler {
|
|
|
414
418
|
await fs.writeFile(logPath, JSON.stringify(logData, null, 2));
|
|
415
419
|
console.log(chalk.dim(`Error log saved to: ${logPath}`));
|
|
416
420
|
} catch (writeError) {
|
|
417
|
-
console.warn(chalk.yellow(`Failed to save error log: ${writeError.message}`));
|
|
421
|
+
console.warn(chalk.yellow(`Failed to save error log: ${writeError instanceof Error ? writeError.message : 'Unknown error'}`));
|
|
418
422
|
}
|
|
419
423
|
}
|
|
420
424
|
|
|
@@ -2,44 +2,21 @@ import { execSync } from 'child_process';
|
|
|
2
2
|
import { existsSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* GitHub repository manager for Jules integration
|
|
9
|
+
* Note: GitHub app installation should be done on the Jules dashboard, not here
|
|
9
10
|
*/
|
|
10
11
|
export class GitHubManager {
|
|
11
12
|
private repoOwner: string | null = null;
|
|
12
13
|
private repoName: string | null = null;
|
|
13
14
|
private sourceIdentifier: string | null = null;
|
|
14
15
|
|
|
15
|
-
/**
|
|
16
|
-
* Guide user through Jules GitHub app installation
|
|
17
|
-
*/
|
|
18
|
-
async setupJulesGitHubIntegration(): Promise<string> {
|
|
19
|
-
console.log(chalk.cyan('\nš Setting up Jules GitHub Integration\n'));
|
|
20
|
-
|
|
21
|
-
// Step 1: Check if we're in a git repository
|
|
22
|
-
if (!this.isGitRepository()) {
|
|
23
|
-
throw new Error('Not in a git repository. Please run this command from within a git repository.');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Step 2: Get repository information
|
|
27
|
-
await this.detectRepositoryInfo();
|
|
28
|
-
|
|
29
|
-
// Step 3: Guide user through GitHub app installation
|
|
30
|
-
await this.guideGitHubAppInstallation();
|
|
31
|
-
|
|
32
|
-
// Step 4: Verify connection and get source identifier
|
|
33
|
-
const sourceId = await this.getSourceIdentifier();
|
|
34
|
-
|
|
35
|
-
console.log(chalk.green('ā
Jules GitHub integration setup complete!'));
|
|
36
|
-
return sourceId;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
16
|
/**
|
|
40
17
|
* Check if current directory is a git repository
|
|
41
18
|
*/
|
|
42
|
-
|
|
19
|
+
isGitRepository(): boolean {
|
|
43
20
|
try {
|
|
44
21
|
execSync('git rev-parse --git-dir', { stdio: 'ignore' });
|
|
45
22
|
return true;
|
|
@@ -51,7 +28,7 @@ export class GitHubManager {
|
|
|
51
28
|
/**
|
|
52
29
|
* Detect repository owner and name from git remote
|
|
53
30
|
*/
|
|
54
|
-
|
|
31
|
+
async detectRepositoryInfo(): Promise<void> {
|
|
55
32
|
try {
|
|
56
33
|
const remoteUrl = execSync('git config --get remote.origin.url', { encoding: 'utf8' }).trim();
|
|
57
34
|
|
|
@@ -71,59 +48,16 @@ export class GitHubManager {
|
|
|
71
48
|
}
|
|
72
49
|
}
|
|
73
50
|
|
|
74
|
-
/**
|
|
75
|
-
* Guide user through GitHub app installation process
|
|
76
|
-
*/
|
|
77
|
-
private async guideGitHubAppInstallation(): Promise<void> {
|
|
78
|
-
console.log(chalk.yellow('\nš Jules GitHub App Installation Steps:\n'));
|
|
79
|
-
|
|
80
|
-
console.log('1. Opening Jules GitHub app installation page...');
|
|
81
|
-
|
|
82
|
-
// Open Jules GitHub app installation URL
|
|
83
|
-
const installUrl = 'https://github.com/apps/jules-ai';
|
|
84
|
-
await open(installUrl);
|
|
85
|
-
|
|
86
|
-
console.log(chalk.dim(` ${installUrl}`));
|
|
87
|
-
|
|
88
|
-
console.log('\n2. Follow these steps in your browser:');
|
|
89
|
-
console.log(' ⢠Click "Install" on the Jules app page');
|
|
90
|
-
console.log(' ⢠Select your repository or organization');
|
|
91
|
-
console.log(` ⢠Grant access to ${this.repoOwner}/${this.repoName}`);
|
|
92
|
-
console.log(' ⢠Complete the installation process');
|
|
93
|
-
|
|
94
|
-
console.log('\n3. After installation:');
|
|
95
|
-
console.log(' ⢠Return to this terminal');
|
|
96
|
-
console.log(' ⢠The setup will continue automatically');
|
|
97
|
-
|
|
98
|
-
// Wait for user confirmation
|
|
99
|
-
await this.waitForUserConfirmation();
|
|
100
|
-
}
|
|
101
51
|
|
|
102
|
-
/**
|
|
103
|
-
* Wait for user to confirm GitHub app installation
|
|
104
|
-
*/
|
|
105
|
-
private async waitForUserConfirmation(): Promise<void> {
|
|
106
|
-
const { default: inquirer } = await import('inquirer');
|
|
107
|
-
|
|
108
|
-
const { confirmed } = await inquirer.prompt([
|
|
109
|
-
{
|
|
110
|
-
type: 'confirm',
|
|
111
|
-
name: 'confirmed',
|
|
112
|
-
message: 'Have you completed the Jules GitHub app installation?',
|
|
113
|
-
default: false
|
|
114
|
-
}
|
|
115
|
-
]);
|
|
116
|
-
|
|
117
|
-
if (!confirmed) {
|
|
118
|
-
console.log(chalk.yellow('\nPlease complete the GitHub app installation and run this command again.'));
|
|
119
|
-
process.exit(0);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
52
|
|
|
123
53
|
/**
|
|
124
54
|
* Get source identifier for Jules API
|
|
125
55
|
*/
|
|
126
|
-
|
|
56
|
+
async getSourceIdentifier(): Promise<string> {
|
|
57
|
+
if (!this.repoOwner || !this.repoName) {
|
|
58
|
+
await this.detectRepositoryInfo();
|
|
59
|
+
}
|
|
60
|
+
|
|
127
61
|
if (!this.repoOwner || !this.repoName) {
|
|
128
62
|
throw new Error('Repository information not available');
|
|
129
63
|
}
|
|
@@ -131,8 +65,6 @@ export class GitHubManager {
|
|
|
131
65
|
// Generate source identifier in the format expected by Jules
|
|
132
66
|
this.sourceIdentifier = `sources/github/${this.repoOwner}/${this.repoName}`;
|
|
133
67
|
|
|
134
|
-
console.log(chalk.blue(`š Source identifier: ${this.sourceIdentifier}`));
|
|
135
|
-
|
|
136
68
|
return this.sourceIdentifier;
|
|
137
69
|
}
|
|
138
70
|
|
|
@@ -174,7 +106,7 @@ export class GitHubManager {
|
|
|
174
106
|
}
|
|
175
107
|
|
|
176
108
|
/**
|
|
177
|
-
* Check if
|
|
109
|
+
* Check if we can detect repository information (GitHub integration is handled on Jules dashboard)
|
|
178
110
|
*/
|
|
179
111
|
async isJulesIntegrationSetup(): Promise<boolean> {
|
|
180
112
|
try {
|
|
@@ -183,7 +115,7 @@ export class GitHubManager {
|
|
|
183
115
|
}
|
|
184
116
|
|
|
185
117
|
await this.detectRepositoryInfo();
|
|
186
|
-
return
|
|
118
|
+
return this.repoOwner !== null && this.repoName !== null;
|
|
187
119
|
} catch {
|
|
188
120
|
return false;
|
|
189
121
|
}
|
|
@@ -278,7 +278,7 @@ export class ReactParser extends Parser {
|
|
|
278
278
|
const features: DetectedFeature[] = [];
|
|
279
279
|
|
|
280
280
|
// Check if this is likely a style object (has CSS-like properties)
|
|
281
|
-
const hasStyleProps = node.properties.some(prop => {
|
|
281
|
+
const hasStyleProps = node.properties.some((prop: any) => {
|
|
282
282
|
if (t.isObjectProperty(prop) && (t.isIdentifier(prop.key) || t.isStringLiteral(prop.key))) {
|
|
283
283
|
const key = t.isIdentifier(prop.key) ? prop.key.name : prop.key.value;
|
|
284
284
|
return this.CSS_PROPERTIES.has(key) || key.includes('-') || key.startsWith('--');
|
|
@@ -290,7 +290,7 @@ export class ReactParser extends Parser {
|
|
|
290
290
|
return features;
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
-
node.properties.forEach(prop => {
|
|
293
|
+
node.properties.forEach((prop: any) => {
|
|
294
294
|
if (t.isObjectProperty(prop)) {
|
|
295
295
|
let key = '';
|
|
296
296
|
if (t.isIdentifier(prop.key)) {
|