vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850
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/package.json +1 -1
- package/src/agents/AgentCheckDiscoveryService.js +180 -0
- package/src/agents/AgentCheckService.js +18 -261
- package/src/agents/AgentCheckStatisticsService.js +195 -0
- package/src/agents/EnvironmentConfigurationManager.js +31 -380
- package/src/agents/InstallationType.js +19 -6
- package/src/agents/SimpleAgentCheckService.js +472 -0
- package/src/agents/config-managers/ConfigUtils.js +72 -0
- package/src/agents/config-managers/DefaultConfig.js +58 -0
- package/src/agents/config-managers/EnvVarLoader.js +66 -0
- package/src/agents/config-managers/FileConfigLoader.js +124 -0
- package/src/agents/config-managers/TypeConverters.js +61 -0
- package/src/agents/config-managers/VariableMappings.js +92 -0
- package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
- package/src/agents/discovery/AgentDiscoveryService.js +29 -403
- package/src/agents/discovery/agent-validator.js +262 -0
- package/src/agents/discovery/discovery-results.js +176 -0
- package/src/agents/discovery/discovery-scanner.js +268 -0
- package/src/agents/discovery/discovery-utils.js +161 -0
- package/src/agents/discovery/executable-analyzer.js +290 -0
- package/src/agents/discovery/history-manager.js +310 -0
- package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
- package/src/agents/verification/ResultAnalyzer.js +30 -431
- package/src/agents/verification/analysis-utils.js +310 -0
- package/src/agents/verification/batch-analyzer.js +440 -0
- package/src/agents/verification/pattern-recognizer.js +369 -0
- package/src/agents/verification/report-generator.js +320 -0
- package/src/agents/verification/test-analyzer.js +290 -0
- package/src/agents/windows/InstallerFactory.js +4 -0
- package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
- package/src/analysis/analysis-engine.js +314 -0
- package/src/analysis/ast-analyzer.js +342 -0
- package/src/analysis/boundary-detector-refactored.js +378 -0
- package/src/analysis/boundary-detector.js +200 -603
- package/src/analysis/boundary-scanner.js +609 -0
- package/src/analysis/boundary-types.js +118 -0
- package/src/analysis/boundary-utils.js +293 -0
- package/src/analysis/deadline-priority-calculator.js +18 -0
- package/src/analysis/detection-methods.js +347 -0
- package/src/analysis/importance-priority-calculator.js +18 -0
- package/src/analysis/priority/factor-calculators.js +204 -0
- package/src/analysis/priority/factor-helpers.js +71 -0
- package/src/analysis/priority/priority-constants.js +73 -0
- package/src/analysis/priority/priority-factor-calculators.js +301 -0
- package/src/analysis/priority/reasons-generator.js +44 -0
- package/src/analysis/priority-calculator.js +15 -580
- package/src/analysis/strategy-generator.js +16 -66
- package/src/analysis/type-priority-calculator.js +18 -0
- package/src/analysis/urgency-priority-calculator.js +18 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
- package/src/commands/disable-requirement.js +60 -0
- package/src/commands/disable-spec.js +60 -0
- package/src/commands/enable-requirement.js +60 -0
- package/src/commands/enable-spec.js +60 -0
- package/src/commands/registry.js +1 -6
- package/src/commands/requirements.js +8 -2
- package/src/ide-integration/applescript-manager.cjs +9 -24
- package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
- package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
- package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
- package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
- package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
- package/src/ide-integration/cdp-manager.js +28 -573
- package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
- package/src/ide-integration/ide-openers/claude-opener.js +171 -0
- package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
- package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
- package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
- package/src/ide-integration/macos-ide-manager.js +20 -582
- package/src/ide-integration/macos-quota-checker.js +164 -0
- package/src/ide-integration/macos-text-sender.js +19 -38
- package/src/ide-integration/provider-manager.cjs +52 -7
- package/src/index.cjs +6 -0
- package/src/index.js +10 -0
- package/src/llm/direct-llm-manager.cjs +501 -0
- package/src/localization/translations/en-part1.js +363 -0
- package/src/localization/translations/en-part2.js +320 -0
- package/src/localization/translations/en.js +4 -687
- package/src/localization/translations/es-part1.js +363 -0
- package/src/localization/translations/es-part2.js +320 -0
- package/src/localization/translations/es.js +4 -688
- package/src/models/file-analysis-collection.js +139 -0
- package/src/models/file-analysis-metrics.js +50 -0
- package/src/models/file-analysis.js +15 -262
- package/src/models/plan-manager.js +410 -0
- package/src/models/refactoring-models.js +380 -0
- package/src/models/refactoring-plan-refactored.js +81 -0
- package/src/models/refactoring-plan.js +2 -663
- package/src/monitoring/alert-system.js +4 -45
- package/src/monitoring/continuous-scan-notifications.js +37 -191
- package/src/monitoring/notification-handlers/base-handler.js +58 -0
- package/src/monitoring/notification-handlers/error-handler.js +36 -0
- package/src/monitoring/notification-handlers/index.js +21 -0
- package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
- package/src/monitoring/notification-handlers/progress-handler.js +48 -0
- package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
- package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
- package/src/provider-registry.js +8 -0
- package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
- package/src/refactoring/boundary/boundary-detector.js +26 -596
- package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
- package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
- package/src/refactoring/boundary/detectors/class-detector.js +247 -0
- package/src/refactoring/boundary/detectors/config-detector.js +270 -0
- package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
- package/src/refactoring/boundary/detectors/function-detector.js +248 -0
- package/src/refactoring/boundary/detectors/module-detector.js +249 -0
- package/src/refactoring/boundary/detectors/object-detector.js +247 -0
- package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
- package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
- package/src/refactoring/circular-dependency-resolver-original.js +16 -76
- package/src/refactoring/code-mover-refactored.js +309 -0
- package/src/refactoring/code-mover.js +48 -355
- package/src/refactoring/execution-status.js +18 -0
- package/src/refactoring/execution-strategies.js +172 -0
- package/src/refactoring/file-splitter-core.js +568 -0
- package/src/refactoring/file-splitter-types.js +136 -0
- package/src/refactoring/file-splitter.js +2 -682
- package/src/refactoring/functionality-validator.js +11 -51
- package/src/refactoring/import-manager-refactored.js +385 -0
- package/src/refactoring/import-manager.js +112 -487
- package/src/refactoring/import-models.js +189 -0
- package/src/refactoring/import-parser.js +306 -0
- package/src/refactoring/move-executor.js +431 -0
- package/src/refactoring/move-utils.js +368 -0
- package/src/refactoring/operation-executor.js +76 -0
- package/src/refactoring/plan-creator.js +36 -0
- package/src/refactoring/plan-executor.js +143 -0
- package/src/refactoring/plan-validator.js +68 -0
- package/src/refactoring/refactoring-executor-result.js +70 -0
- package/src/refactoring/refactoring-executor.js +34 -569
- package/src/refactoring/refactoring-operation.js +94 -0
- package/src/refactoring/refactoring-plan.js +69 -0
- package/src/refactoring/refactoring-rollback.js +22 -527
- package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
- package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
- package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
- package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
- package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
- package/src/refactoring/test-validator.js +32 -448
- package/src/refactoring/validation/baseline-runner.js +71 -0
- package/src/refactoring/validation/report-generator.js +136 -0
- package/src/refactoring/validation/result-comparator.js +92 -0
- package/src/refactoring/validation/test-suite.js +59 -0
- package/src/refactoring/validation/test-validation-result.js +83 -0
- package/src/refactoring/validation/validation-runner.js +95 -0
- package/src/refactoring/validation/validation-status.js +18 -0
- package/src/rui/commands/AgentCommandParser.js +60 -369
- package/src/rui/commands/AgentResponseFormatter.js +7 -47
- package/src/rui/commands/parsers/CommandMapper.js +148 -0
- package/src/rui/commands/parsers/CommandValidator.js +228 -0
- package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
- package/src/rui/commands/parsers/TokenParser.js +69 -0
- package/src/rui/commands/parsers/tokenizer.js +153 -0
- package/src/utils/current-requirement-operations.js +50 -1
- package/src/utils/report-generator.js +18 -514
- package/src/utils/report-generators/analysis-generator.js +115 -0
- package/src/utils/report-generators/base-generator.js +141 -0
- package/src/utils/report-generators/compliance-generator.js +41 -0
- package/src/utils/report-generators/format-handlers.js +185 -0
- package/src/utils/report-generators/refactoring-generator.js +46 -0
- package/src/utils/report-generators/validation-generator.js +63 -0
- package/src/utils/requirement-enable-disable.js +265 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
- package/src/utils/requirement-helpers/requirement-mover.js +88 -1
- package/src/utils/requirement-helpers.js +5 -2
- package/src/utils/smoke-test-cli.js +45 -8
- package/src/utils/specification-enable-disable.js +122 -0
- package/src/utils/specification-helpers.js +30 -4
- package/src/utils/specification-migration.js +5 -5
- package/src/utils/test-comparator.js +118 -0
- package/src/utils/test-config.js +54 -0
- package/src/utils/test-executor.js +133 -0
- package/src/utils/test-parser.js +215 -0
- package/src/utils/test-runner-baseline.js +63 -0
- package/src/utils/test-runner-core.js +98 -0
- package/src/utils/test-runner-report.js +39 -0
- package/src/utils/test-runner-validation.js +71 -0
- package/src/utils/test-runner.js +11 -535
- package/src/validation/comparison-analyzer.js +333 -0
- package/src/validation/compliance-reporter-new.js +282 -0
- package/src/validation/compliance-reporter-refactored.js +344 -0
- package/src/validation/compliance-reporter.js +278 -591
- package/src/validation/compliance-utils.js +278 -0
- package/src/validation/html-generator.js +446 -0
- package/src/validation/metrics/category-calculator.js +137 -0
- package/src/validation/metrics/metrics-helpers.js +155 -0
- package/src/validation/metrics/overview-calculator.js +85 -0
- package/src/validation/metrics/overview-metrics.js +41 -0
- package/src/validation/metrics/quality-calculator.js +166 -0
- package/src/validation/metrics/size-calculator.js +69 -0
- package/src/validation/metrics-calculator.js +27 -551
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Result - Test Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes individual verification test results.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { AgentStatus } = require('../AgentStatus');
|
|
8
|
+
const { VerificationType } = require('../VerificationType');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Determine test result severity
|
|
12
|
+
* @param {Object} testResult - Test result
|
|
13
|
+
* @returns {string} - Severity level
|
|
14
|
+
*/
|
|
15
|
+
function determineSeverity(testResult) {
|
|
16
|
+
if (!testResult.success) {
|
|
17
|
+
if (testResult.error) {
|
|
18
|
+
const error = testResult.error.toLowerCase();
|
|
19
|
+
|
|
20
|
+
if (error.includes('timeout') || error.includes('hang')) {
|
|
21
|
+
return 'high';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (error.includes('permission') || error.includes('access denied')) {
|
|
25
|
+
return 'high';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (error.includes('not found') || error.includes('missing')) {
|
|
29
|
+
return 'medium';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return 'medium';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return 'low';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Categorize test result
|
|
41
|
+
* @param {Object} testResult - Test result
|
|
42
|
+
* @returns {string} - Result category
|
|
43
|
+
*/
|
|
44
|
+
function categorizeResult(testResult) {
|
|
45
|
+
if (!testResult.success) {
|
|
46
|
+
if (testResult.error) {
|
|
47
|
+
const error = testResult.error.toLowerCase();
|
|
48
|
+
|
|
49
|
+
if (error.includes('timeout')) {
|
|
50
|
+
return 'timeout-failure';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (error.includes('permission')) {
|
|
54
|
+
return 'permission-failure';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (error.includes('not found')) {
|
|
58
|
+
return 'dependency-failure';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (error.includes('syntax') || error.includes('parse')) {
|
|
62
|
+
return 'syntax-failure';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return 'unknown-failure';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return 'success';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generate recommendations for test result
|
|
74
|
+
* @param {Object} testResult - Test result
|
|
75
|
+
* @returns {Array} - Recommendations
|
|
76
|
+
*/
|
|
77
|
+
function generateRecommendations(testResult) {
|
|
78
|
+
const recommendations = [];
|
|
79
|
+
|
|
80
|
+
if (!testResult.success) {
|
|
81
|
+
if (testResult.error) {
|
|
82
|
+
const error = testResult.error.toLowerCase();
|
|
83
|
+
|
|
84
|
+
if (error.includes('timeout')) {
|
|
85
|
+
recommendations.push({
|
|
86
|
+
type: 'performance',
|
|
87
|
+
message: 'Increase timeout or optimize test performance',
|
|
88
|
+
priority: 'medium'
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (error.includes('permission')) {
|
|
93
|
+
recommendations.push({
|
|
94
|
+
type: 'permissions',
|
|
95
|
+
message: 'Check file permissions and access rights',
|
|
96
|
+
priority: 'high'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (error.includes('not found')) {
|
|
101
|
+
recommendations.push({
|
|
102
|
+
type: 'dependencies',
|
|
103
|
+
message: 'Install missing dependencies or verify paths',
|
|
104
|
+
priority: 'high'
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (error.includes('syntax')) {
|
|
109
|
+
recommendations.push({
|
|
110
|
+
type: 'code-quality',
|
|
111
|
+
message: 'Fix syntax errors in test code',
|
|
112
|
+
priority: 'high'
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Default recommendation
|
|
118
|
+
if (recommendations.length === 0) {
|
|
119
|
+
recommendations.push({
|
|
120
|
+
type: 'general',
|
|
121
|
+
message: 'Review test configuration and environment',
|
|
122
|
+
priority: 'medium'
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
// Success recommendations
|
|
127
|
+
if (testResult.duration && testResult.duration > 10000) {
|
|
128
|
+
recommendations.push({
|
|
129
|
+
type: 'performance',
|
|
130
|
+
message: 'Consider optimizing test performance',
|
|
131
|
+
priority: 'low'
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return recommendations;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Calculate confidence score for test result
|
|
141
|
+
* @param {Object} testResult - Test result
|
|
142
|
+
* @returns {number} - Confidence score (0-100)
|
|
143
|
+
*/
|
|
144
|
+
function calculateConfidence(testResult) {
|
|
145
|
+
if (!testResult.success) {
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let confidence = 80; // Base confidence for successful tests
|
|
150
|
+
|
|
151
|
+
// Adjust based on test duration
|
|
152
|
+
if (testResult.duration) {
|
|
153
|
+
if (testResult.duration < 1000) {
|
|
154
|
+
confidence += 10; // Very fast test
|
|
155
|
+
} else if (testResult.duration > 30000) {
|
|
156
|
+
confidence -= 10; // Very slow test
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Adjust based on test type
|
|
161
|
+
if (testResult.type === VerificationType.FILE_OPERATION) {
|
|
162
|
+
confidence += 5; // File operations are more reliable
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return Math.min(100, Math.max(0, confidence));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Analyze detailed test information
|
|
170
|
+
* @param {Object} testResult - Test result
|
|
171
|
+
* @returns {Object} - Detailed analysis
|
|
172
|
+
*/
|
|
173
|
+
function analyzeDetails(testResult) {
|
|
174
|
+
const details = {};
|
|
175
|
+
|
|
176
|
+
if (testResult.duration) {
|
|
177
|
+
details.performance = {
|
|
178
|
+
duration: testResult.duration,
|
|
179
|
+
category: categorizePerformance(testResult.duration),
|
|
180
|
+
acceptable: testResult.duration < 30000
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (testResult.type) {
|
|
185
|
+
details.testType = {
|
|
186
|
+
type: testResult.type,
|
|
187
|
+
reliability: getTestTypeReliability(testResult.type)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (testResult.error) {
|
|
192
|
+
details.error = {
|
|
193
|
+
message: testResult.error,
|
|
194
|
+
type: categorizeResult(testResult),
|
|
195
|
+
recoverable: isRecoverableError(testResult.error)
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return details;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Categorize test performance
|
|
204
|
+
* @param {number} duration - Test duration in ms
|
|
205
|
+
* @returns {string} - Performance category
|
|
206
|
+
*/
|
|
207
|
+
function categorizePerformance(duration) {
|
|
208
|
+
if (duration < 1000) {
|
|
209
|
+
return 'excellent';
|
|
210
|
+
} else if (duration < 5000) {
|
|
211
|
+
return 'good';
|
|
212
|
+
} else if (duration < 15000) {
|
|
213
|
+
return 'acceptable';
|
|
214
|
+
} else if (duration < 30000) {
|
|
215
|
+
return 'slow';
|
|
216
|
+
} else {
|
|
217
|
+
return 'very-slow';
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Get test type reliability
|
|
223
|
+
* @param {string} testType - Test type
|
|
224
|
+
* @returns {number} - Reliability score (0-100)
|
|
225
|
+
*/
|
|
226
|
+
function getTestTypeReliability(testType) {
|
|
227
|
+
const reliabilityScores = {
|
|
228
|
+
[VerificationType.FILE_OPERATION]: 95,
|
|
229
|
+
[VerificationType.PROCESS_EXECUTION]: 85,
|
|
230
|
+
[VerificationType.NETWORK_CONNECTION]: 75,
|
|
231
|
+
[VerificationType.API_CALL]: 80,
|
|
232
|
+
[VerificationType.CONFIGURATION_VALIDATION]: 90
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
return reliabilityScores[testType] || 70;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Check if error is recoverable
|
|
240
|
+
* @param {string} error - Error message
|
|
241
|
+
* @returns {boolean} - True if recoverable
|
|
242
|
+
*/
|
|
243
|
+
function isRecoverableError(error) {
|
|
244
|
+
const recoverablePatterns = [
|
|
245
|
+
'timeout',
|
|
246
|
+
'temporary',
|
|
247
|
+
'retry',
|
|
248
|
+
'connection refused',
|
|
249
|
+
'service unavailable'
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
const errorLower = error.toLowerCase();
|
|
253
|
+
return recoverablePatterns.some(pattern => errorLower.includes(pattern));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Analyze single test result
|
|
258
|
+
* @param {Object} testResult - Test result to analyze
|
|
259
|
+
* @param {Object} options - Analysis options
|
|
260
|
+
* @returns {Object} - Analysis result
|
|
261
|
+
*/
|
|
262
|
+
function analyzeTestResult(testResult, options = {}) {
|
|
263
|
+
const analysis = {
|
|
264
|
+
testId: testResult.testId,
|
|
265
|
+
success: testResult.success,
|
|
266
|
+
severity: determineSeverity(testResult),
|
|
267
|
+
category: categorizeResult(testResult),
|
|
268
|
+
recommendations: generateRecommendations(testResult),
|
|
269
|
+
confidence: calculateConfidence(testResult)
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Add detailed analysis if enabled
|
|
273
|
+
if (options.detailedAnalysis) {
|
|
274
|
+
analysis.details = analyzeDetails(testResult);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return analysis;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = {
|
|
281
|
+
determineSeverity,
|
|
282
|
+
categorizeResult,
|
|
283
|
+
generateRecommendations,
|
|
284
|
+
calculateConfidence,
|
|
285
|
+
analyzeDetails,
|
|
286
|
+
categorizePerformance,
|
|
287
|
+
getTestTypeReliability,
|
|
288
|
+
isRecoverableError,
|
|
289
|
+
analyzeTestResult
|
|
290
|
+
};
|
|
@@ -10,6 +10,7 @@ const PowerShellInstaller = require('./PowerShellInstaller');
|
|
|
10
10
|
const NpmInstaller = require('./NpmInstaller');
|
|
11
11
|
const ChocolateyInstaller = require('./ChocolateyInstaller');
|
|
12
12
|
const DirectInstaller = require('./DirectInstaller');
|
|
13
|
+
const VSCodeExtensionInstaller = require('./VSCodeExtensionInstaller');
|
|
13
14
|
const { InstallationType } = require('../InstallationType');
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -45,6 +46,9 @@ class InstallerFactory {
|
|
|
45
46
|
case InstallationType.DIRECT:
|
|
46
47
|
return new DirectInstaller(installerConfig);
|
|
47
48
|
|
|
49
|
+
case InstallationType.VSCODE_EXTENSION:
|
|
50
|
+
return new VSCodeExtensionInstaller(installerConfig);
|
|
51
|
+
|
|
48
52
|
default:
|
|
49
53
|
throw new Error(`Unknown installation type: ${type}`);
|
|
50
54
|
}
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code Extension Installer
|
|
3
|
+
*
|
|
4
|
+
* Installer for VS Code extensions like GitHub Copilot.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const fs = require('fs').promises;
|
|
11
|
+
const BaseWindowsInstaller = require('./BaseWindowsInstaller');
|
|
12
|
+
const { InstallationType } = require('../InstallationType');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* VS Code Extension Installer class
|
|
16
|
+
*/
|
|
17
|
+
class VSCodeExtensionInstaller extends BaseWindowsInstaller {
|
|
18
|
+
/**
|
|
19
|
+
* Create VS Code extension installer
|
|
20
|
+
* @param {Object} config - Installer configuration
|
|
21
|
+
*/
|
|
22
|
+
constructor(config = {}) {
|
|
23
|
+
super({
|
|
24
|
+
type: InstallationType.VSCODE_EXTENSION,
|
|
25
|
+
...config
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
this.extensionId = config.extensionId || '';
|
|
29
|
+
this.config = config;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check if VS Code is available
|
|
34
|
+
* @returns {Promise<boolean>} - True if VS Code is available
|
|
35
|
+
*/
|
|
36
|
+
async checkPrerequisites() {
|
|
37
|
+
try {
|
|
38
|
+
if (this.logger) {
|
|
39
|
+
await this.logger.info('Checking VS Code prerequisites');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check if VS Code CLI is available
|
|
43
|
+
const codeCheck = await this.executeCommand('code --version', { timeout: 10000 });
|
|
44
|
+
|
|
45
|
+
if (!codeCheck.success) {
|
|
46
|
+
if (this.logger) {
|
|
47
|
+
await this.logger.warn('VS Code CLI not found', {
|
|
48
|
+
error: codeCheck.error
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Parse VS Code version
|
|
55
|
+
const versionLines = codeCheck.stdout.trim().split('\n');
|
|
56
|
+
const version = versionLines[0];
|
|
57
|
+
|
|
58
|
+
if (this.logger) {
|
|
59
|
+
await this.logger.info('VS Code found', { version });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return true;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (this.logger) {
|
|
65
|
+
await this.logger.error('Prerequisite check failed', { error: error.message });
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Install VS Code extension
|
|
73
|
+
* @param {Object} agent - Agent configuration
|
|
74
|
+
* @param {Object} options - Installation options
|
|
75
|
+
* @returns {Promise<Object>} - Installation result
|
|
76
|
+
*/
|
|
77
|
+
async install(agent, options = {}) {
|
|
78
|
+
const { force = false, timeout = 120000 } = options;
|
|
79
|
+
|
|
80
|
+
if (this.logger) {
|
|
81
|
+
await this.logger.info('Starting VS Code extension installation', {
|
|
82
|
+
extensionId: this.extensionId,
|
|
83
|
+
agentId: agent.id,
|
|
84
|
+
force
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
// Check prerequisites
|
|
90
|
+
const prereqCheck = await this.checkPrerequisites();
|
|
91
|
+
if (!prereqCheck) {
|
|
92
|
+
throw new Error('VS Code prerequisites not met');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Check if extension is already installed
|
|
96
|
+
if (!force) {
|
|
97
|
+
const installed = await this.checkInstalled();
|
|
98
|
+
if (installed) {
|
|
99
|
+
if (this.logger) {
|
|
100
|
+
await this.logger.info('Extension already installed', { extensionId: this.extensionId });
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
success: true,
|
|
104
|
+
alreadyInstalled: true,
|
|
105
|
+
message: 'Extension already installed'
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Install extension
|
|
111
|
+
const installCommand = `code --install-extension ${this.extensionId}`;
|
|
112
|
+
const installResult = await this.executeCommand(installCommand, { timeout });
|
|
113
|
+
|
|
114
|
+
if (!installResult.success) {
|
|
115
|
+
throw new Error(`Installation failed: ${installResult.error}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Verify installation
|
|
119
|
+
const verificationResult = await this.verify();
|
|
120
|
+
if (!verificationResult.success) {
|
|
121
|
+
throw new Error('Installation verification failed');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (this.logger) {
|
|
125
|
+
await this.logger.info('Extension installed successfully', { extensionId: this.extensionId });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
extensionId: this.extensionId,
|
|
131
|
+
version: verificationResult.version,
|
|
132
|
+
installOutput: installResult.stdout,
|
|
133
|
+
message: 'Extension installed successfully'
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (this.logger) {
|
|
138
|
+
await this.logger.error('Extension installation failed', {
|
|
139
|
+
extensionId: this.extensionId,
|
|
140
|
+
error: error.message
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
success: false,
|
|
146
|
+
error: error.message,
|
|
147
|
+
extensionId: this.extensionId
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Check if extension is installed
|
|
154
|
+
* @returns {Promise<boolean>} - True if installed
|
|
155
|
+
*/
|
|
156
|
+
async checkInstalled() {
|
|
157
|
+
try {
|
|
158
|
+
const checkCommand = `code --list-extensions | grep "${this.extensionId}"`;
|
|
159
|
+
const result = await this.executeCommand(checkCommand, { timeout: 10000 });
|
|
160
|
+
|
|
161
|
+
return result.success && result.stdout.includes(this.extensionId);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (this.logger) {
|
|
164
|
+
await this.logger.warn('Extension check failed', { error: error.message });
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Verify extension installation
|
|
172
|
+
* @returns {Promise<Object>} - Verification result
|
|
173
|
+
*/
|
|
174
|
+
async verify() {
|
|
175
|
+
try {
|
|
176
|
+
const verifyCommand = `code --list-extensions --show-versions | grep "${this.extensionId}"`;
|
|
177
|
+
const result = await this.executeCommand(verifyCommand, { timeout: 10000 });
|
|
178
|
+
|
|
179
|
+
if (!result.success) {
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
error: result.error
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const output = result.stdout.trim();
|
|
187
|
+
if (!output.includes(this.extensionId)) {
|
|
188
|
+
return {
|
|
189
|
+
success: false,
|
|
190
|
+
error: 'Extension not found in installed extensions'
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Parse version from output
|
|
195
|
+
const parts = output.split('\t');
|
|
196
|
+
const version = parts.length > 1 ? parts[1] : 'unknown';
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
success: true,
|
|
200
|
+
version,
|
|
201
|
+
extensionId: this.extensionId,
|
|
202
|
+
verificationOutput: output
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
} catch (error) {
|
|
206
|
+
return {
|
|
207
|
+
success: false,
|
|
208
|
+
error: error.message
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Uninstall extension
|
|
215
|
+
* @param {Object} options - Uninstall options
|
|
216
|
+
* @returns {Promise<Object>} - Uninstall result
|
|
217
|
+
*/
|
|
218
|
+
async uninstall(options = {}) {
|
|
219
|
+
const { timeout = 60000 } = options;
|
|
220
|
+
|
|
221
|
+
if (this.logger) {
|
|
222
|
+
await this.logger.info('Uninstalling VS Code extension', { extensionId: this.extensionId });
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
const uninstallCommand = `code --uninstall-extension ${this.extensionId}`;
|
|
227
|
+
const result = await this.executeCommand(uninstallCommand, { timeout });
|
|
228
|
+
|
|
229
|
+
if (!result.success) {
|
|
230
|
+
throw new Error(`Uninstallation failed: ${result.error}`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (this.logger) {
|
|
234
|
+
await this.logger.info('Extension uninstalled successfully', { extensionId: this.extensionId });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
success: true,
|
|
239
|
+
extensionId: this.extensionId,
|
|
240
|
+
message: 'Extension uninstalled successfully'
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
} catch (error) {
|
|
244
|
+
if (this.logger) {
|
|
245
|
+
await this.logger.error('Extension uninstallation failed', {
|
|
246
|
+
extensionId: this.extensionId,
|
|
247
|
+
error: error.message
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
success: false,
|
|
253
|
+
error: error.message,
|
|
254
|
+
extensionId: this.extensionId
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Update extension
|
|
261
|
+
* @param {Object} options - Update options
|
|
262
|
+
* @returns {Promise<Object>} - Update result
|
|
263
|
+
*/
|
|
264
|
+
async update(options = {}) {
|
|
265
|
+
if (this.logger) {
|
|
266
|
+
await this.logger.info('Updating VS Code extension', { extensionId: this.extensionId });
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// For VS Code extensions, update is the same as install
|
|
270
|
+
return this.install({ ...options, force: true });
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Get extension info
|
|
275
|
+
* @returns {Promise<Object>} - Extension info
|
|
276
|
+
*/
|
|
277
|
+
async getInfo() {
|
|
278
|
+
try {
|
|
279
|
+
const infoCommand = `code --list-extensions --show-versions | grep "${this.extensionId}"`;
|
|
280
|
+
const result = await this.executeCommand(infoCommand, { timeout: 10000 });
|
|
281
|
+
|
|
282
|
+
if (!result.success) {
|
|
283
|
+
return {
|
|
284
|
+
success: false,
|
|
285
|
+
error: result.error
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const output = result.stdout.trim();
|
|
290
|
+
const parts = output.split('\t');
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
success: true,
|
|
294
|
+
extensionId: this.extensionId,
|
|
295
|
+
version: parts.length > 1 ? parts[1] : 'unknown',
|
|
296
|
+
publisher: parts.length > 0 ? parts[0].split('.')[0] : 'unknown',
|
|
297
|
+
name: parts.length > 0 ? parts[0].split('.')[1] : this.extensionId,
|
|
298
|
+
installed: true
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
} catch (error) {
|
|
302
|
+
return {
|
|
303
|
+
success: false,
|
|
304
|
+
error: error.message,
|
|
305
|
+
installed: false
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Configure extension settings
|
|
312
|
+
* @param {Object} settings - Extension settings
|
|
313
|
+
* @returns {Promise<Object>} - Configuration result
|
|
314
|
+
*/
|
|
315
|
+
async configure(settings = {}) {
|
|
316
|
+
try {
|
|
317
|
+
if (this.logger) {
|
|
318
|
+
await this.logger.info('Configuring VS Code extension settings', {
|
|
319
|
+
extensionId: this.extensionId,
|
|
320
|
+
settings: Object.keys(settings)
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Get VS Code user settings path
|
|
325
|
+
const settingsPath = this.getVSCodeSettingsPath();
|
|
326
|
+
|
|
327
|
+
// Read current settings
|
|
328
|
+
let currentSettings = {};
|
|
329
|
+
try {
|
|
330
|
+
const settingsData = await fs.readFile(settingsPath, 'utf8');
|
|
331
|
+
currentSettings = JSON.parse(settingsData);
|
|
332
|
+
} catch (error) {
|
|
333
|
+
// File doesn't exist or is invalid, start with empty settings
|
|
334
|
+
currentSettings = {};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Update settings
|
|
338
|
+
const updatedSettings = {
|
|
339
|
+
...currentSettings,
|
|
340
|
+
...settings
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
// Write updated settings
|
|
344
|
+
await fs.writeFile(settingsPath, JSON.stringify(updatedSettings, null, 2), 'utf8');
|
|
345
|
+
|
|
346
|
+
if (this.logger) {
|
|
347
|
+
await this.logger.info('Extension settings configured successfully');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
success: true,
|
|
352
|
+
settingsPath,
|
|
353
|
+
configuredSettings: Object.keys(settings)
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
} catch (error) {
|
|
357
|
+
if (this.logger) {
|
|
358
|
+
await this.logger.error('Extension configuration failed', { error: error.message });
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return {
|
|
362
|
+
success: false,
|
|
363
|
+
error: error.message
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Get VS Code settings file path
|
|
370
|
+
* @returns {string} - Settings file path
|
|
371
|
+
*/
|
|
372
|
+
getVSCodeSettingsPath() {
|
|
373
|
+
const homedir = require('os').homedir();
|
|
374
|
+
|
|
375
|
+
if (process.platform === 'win32') {
|
|
376
|
+
return path.join(homedir, 'AppData', 'Roaming', 'Code', 'User', 'settings.json');
|
|
377
|
+
} else if (process.platform === 'darwin') {
|
|
378
|
+
return path.join(homedir, 'Library', 'Application Support', 'Code', 'User', 'settings.json');
|
|
379
|
+
} else {
|
|
380
|
+
return path.join(homedir, '.config', 'Code', 'User', 'settings.json');
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Get installer capabilities
|
|
386
|
+
* @returns {Object} - Capabilities
|
|
387
|
+
*/
|
|
388
|
+
getCapabilities() {
|
|
389
|
+
return {
|
|
390
|
+
install: true,
|
|
391
|
+
uninstall: true,
|
|
392
|
+
update: true,
|
|
393
|
+
verify: true,
|
|
394
|
+
configure: true,
|
|
395
|
+
getInfo: true,
|
|
396
|
+
checkInstalled: true,
|
|
397
|
+
supportedPlatforms: ['win32', 'darwin', 'linux'],
|
|
398
|
+
requiresInternet: true,
|
|
399
|
+
requiresVSCode: true
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
module.exports = VSCodeExtensionInstaller;
|