vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739
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/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct Installer
|
|
3
|
+
*
|
|
4
|
+
* Direct download and install implementation.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const BaseWindowsInstaller = require('./BaseWindowsInstaller');
|
|
9
|
+
const { InstallationType } = require('../InstallationType');
|
|
10
|
+
const fs = require('fs').promises;
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Direct installer class for Windows agents
|
|
16
|
+
*/
|
|
17
|
+
class DirectInstaller extends BaseWindowsInstaller {
|
|
18
|
+
/**
|
|
19
|
+
* Create Direct installer instance
|
|
20
|
+
* @param {Object} config - Installer configuration
|
|
21
|
+
*/
|
|
22
|
+
constructor(config = {}) {
|
|
23
|
+
super({
|
|
24
|
+
type: InstallationType.DIRECT,
|
|
25
|
+
...config
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
this.downloadUrl = config.downloadUrl || '';
|
|
29
|
+
this.installScript = config.installScript || '';
|
|
30
|
+
this.extractPath = config.extractPath || '';
|
|
31
|
+
this.executablePath = config.executablePath || '';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Direct installer is always available (no dependencies)
|
|
36
|
+
* @returns {Promise<boolean>} - Always true
|
|
37
|
+
*/
|
|
38
|
+
async isAvailable() {
|
|
39
|
+
return true; // Direct installation has no external dependencies
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check system requirements for direct installation
|
|
44
|
+
* @returns {Promise<Object>} - Requirements check result
|
|
45
|
+
*/
|
|
46
|
+
async checkRequirements() {
|
|
47
|
+
const requirements = await super.checkRequirements();
|
|
48
|
+
|
|
49
|
+
// Direct installation has minimal requirements
|
|
50
|
+
const directRequirements = [
|
|
51
|
+
{ requirement: 'file-system', met: await this.checkFileSystem() },
|
|
52
|
+
{ requirement: 'internet', met: this.downloadUrl ? await this.checkInternetConnection() : true }
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
directRequirements.forEach(req => {
|
|
56
|
+
requirements.requirements.push(req);
|
|
57
|
+
if (!req.met) {
|
|
58
|
+
requirements.allMet = false;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return requirements;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check if file system is accessible
|
|
67
|
+
* @returns {Promise<boolean>} - True if file system is accessible
|
|
68
|
+
*/
|
|
69
|
+
async checkFileSystem() {
|
|
70
|
+
try {
|
|
71
|
+
const tempDir = os.tmpdir();
|
|
72
|
+
await fs.access(tempDir);
|
|
73
|
+
return true;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (this.logger) {
|
|
76
|
+
await this.logger.debug('File system not accessible', { error: error.message });
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check internet connection
|
|
84
|
+
* @returns {Promise<boolean>} - True if internet is available
|
|
85
|
+
*/
|
|
86
|
+
async checkInternetConnection() {
|
|
87
|
+
try {
|
|
88
|
+
const { execSync } = require('child_process');
|
|
89
|
+
execSync('ping -n 1 google.com', { stdio: 'ignore' });
|
|
90
|
+
return true;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (this.logger) {
|
|
93
|
+
await this.logger.debug('Internet connection check failed', { error: error.message });
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Perform actual installation using direct download
|
|
101
|
+
* @param {boolean} force - Force reinstall
|
|
102
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
103
|
+
* @returns {Promise<Object>} - Installation result
|
|
104
|
+
*/
|
|
105
|
+
async performInstallation(force, timeout) {
|
|
106
|
+
if (this.logger) {
|
|
107
|
+
await this.logger.info('Starting direct installation', {
|
|
108
|
+
downloadUrl: this.downloadUrl,
|
|
109
|
+
command: this.command,
|
|
110
|
+
force
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
let result;
|
|
116
|
+
|
|
117
|
+
if (this.downloadUrl) {
|
|
118
|
+
// Download and install approach
|
|
119
|
+
result = await this.downloadAndInstall(force, timeout);
|
|
120
|
+
} else if (this.command) {
|
|
121
|
+
// Direct command execution approach
|
|
122
|
+
result = await this.executeCommand(this.command, timeout);
|
|
123
|
+
} else {
|
|
124
|
+
throw new Error('Direct installer requires either downloadUrl or command');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (this.logger) {
|
|
128
|
+
await this.logger.info('Direct installation completed', {
|
|
129
|
+
success: result.success,
|
|
130
|
+
exitCode: result.exitCode,
|
|
131
|
+
duration: result.duration
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
success: result.success,
|
|
137
|
+
exitCode: result.exitCode,
|
|
138
|
+
stdout: result.stdout,
|
|
139
|
+
stderr: result.stderr,
|
|
140
|
+
duration: result.duration,
|
|
141
|
+
installer: 'direct'
|
|
142
|
+
};
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (this.logger) {
|
|
145
|
+
await this.logger.error('Direct installation failed', {
|
|
146
|
+
downloadUrl: this.downloadUrl,
|
|
147
|
+
command: this.command,
|
|
148
|
+
error: error.message
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Download and install package
|
|
157
|
+
* @param {boolean} force - Force reinstall
|
|
158
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
159
|
+
* @returns {Promise<Object>} - Installation result
|
|
160
|
+
*/
|
|
161
|
+
async downloadAndInstall(force, timeout) {
|
|
162
|
+
const tempDir = path.join(os.tmpdir(), 'vibe-coding-machine');
|
|
163
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
// Download the file
|
|
167
|
+
const filePath = await this.downloadFile(this.downloadUrl, tempDir);
|
|
168
|
+
|
|
169
|
+
// Install the downloaded file
|
|
170
|
+
const installCommand = await this.buildInstallCommand(filePath, force);
|
|
171
|
+
const result = await this.executeCommand(installCommand, timeout);
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
...result,
|
|
175
|
+
downloadPath: filePath,
|
|
176
|
+
installer: 'direct'
|
|
177
|
+
};
|
|
178
|
+
} finally {
|
|
179
|
+
// Cleanup temp directory
|
|
180
|
+
try {
|
|
181
|
+
await fs.rmdir(tempDir, { recursive: true });
|
|
182
|
+
} catch {
|
|
183
|
+
// Ignore cleanup errors
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Download file from URL
|
|
190
|
+
* @param {string} url - Download URL
|
|
191
|
+
* @param {string} destDir - Destination directory
|
|
192
|
+
* @returns {Promise<string>} - Downloaded file path
|
|
193
|
+
*/
|
|
194
|
+
async downloadFile(url, destDir) {
|
|
195
|
+
const https = require('https');
|
|
196
|
+
const http = require('http');
|
|
197
|
+
const client = url.startsWith('https') ? https : http;
|
|
198
|
+
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
const fileName = path.basename(url) || 'download';
|
|
201
|
+
const filePath = path.join(destDir, fileName);
|
|
202
|
+
const fileStream = fs.createWriteStream(filePath);
|
|
203
|
+
|
|
204
|
+
client.get(url, (response) => {
|
|
205
|
+
if (response.statusCode !== 200) {
|
|
206
|
+
reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
response.pipe(fileStream);
|
|
211
|
+
|
|
212
|
+
fileStream.on('finish', () => {
|
|
213
|
+
fileStream.close();
|
|
214
|
+
resolve(filePath);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
fileStream.on('error', (error) => {
|
|
218
|
+
reject(error);
|
|
219
|
+
});
|
|
220
|
+
}).on('error', (error) => {
|
|
221
|
+
reject(error);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Build install command for downloaded file
|
|
228
|
+
* @param {string} filePath - Downloaded file path
|
|
229
|
+
* @param {boolean} force - Force reinstall
|
|
230
|
+
* @returns {Promise<string>} - Install command
|
|
231
|
+
*/
|
|
232
|
+
async buildInstallCommand(filePath, force) {
|
|
233
|
+
if (this.installScript) {
|
|
234
|
+
// Use custom install script
|
|
235
|
+
return this.installScript.replace('{file}', filePath).replace('{force}', force ? '--force' : '');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Default behavior based on file extension
|
|
239
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
240
|
+
|
|
241
|
+
switch (ext) {
|
|
242
|
+
case '.exe':
|
|
243
|
+
return `"${filePath}" ${force ? '/S' : ''}`; // Silent install if force
|
|
244
|
+
|
|
245
|
+
case '.msi':
|
|
246
|
+
return `msiexec /i "${filePath}" ${force ? '/quiet' : ''}`;
|
|
247
|
+
|
|
248
|
+
case '.zip':
|
|
249
|
+
case '.tar':
|
|
250
|
+
case '.gz':
|
|
251
|
+
return await this.extractAndInstall(filePath, force);
|
|
252
|
+
|
|
253
|
+
case '.ps1':
|
|
254
|
+
return `powershell -ExecutionPolicy Bypass -File "${filePath}" ${force ? '-Force' : ''}`;
|
|
255
|
+
|
|
256
|
+
default:
|
|
257
|
+
return `"${filePath}"`;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Extract and install archive
|
|
263
|
+
* @param {string} archivePath - Archive file path
|
|
264
|
+
* @param {boolean} force - Force reinstall
|
|
265
|
+
* @returns {Promise<string>} - Install command
|
|
266
|
+
*/
|
|
267
|
+
async extractAndInstall(archivePath, force) {
|
|
268
|
+
const extractDir = path.join(path.dirname(archivePath), 'extract');
|
|
269
|
+
await fs.mkdir(extractDir, { recursive: true });
|
|
270
|
+
|
|
271
|
+
// Use built-in Windows tar for .tar files, or assume unzip for .zip
|
|
272
|
+
const ext = path.extname(archivePath).toLowerCase();
|
|
273
|
+
let extractCommand;
|
|
274
|
+
|
|
275
|
+
if (ext === '.zip') {
|
|
276
|
+
extractCommand = `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${extractDir}'"`;
|
|
277
|
+
} else {
|
|
278
|
+
extractCommand = `tar -xf "${archivePath}" -C "${extractDir}"`;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Extract first
|
|
282
|
+
await this.executeCommand(extractCommand, 120000); // 2 minute timeout
|
|
283
|
+
|
|
284
|
+
// Find executable in extracted files
|
|
285
|
+
const files = await fs.readdir(extractDir);
|
|
286
|
+
const executable = files.find(file =>
|
|
287
|
+
file.endsWith('.exe') || file.endsWith('.msi') || file.endsWith('.ps1')
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
if (executable) {
|
|
291
|
+
const executablePath = path.join(extractDir, executable);
|
|
292
|
+
return await this.buildInstallCommand(executablePath, force);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
throw new Error('No executable found in extracted archive');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Perform verification for direct installation
|
|
300
|
+
* @returns {Promise<Object>} - Verification result
|
|
301
|
+
*/
|
|
302
|
+
async performVerification() {
|
|
303
|
+
try {
|
|
304
|
+
if (!this.verificationCommand) {
|
|
305
|
+
return {
|
|
306
|
+
success: false,
|
|
307
|
+
error: 'No verification command specified',
|
|
308
|
+
installer: 'direct'
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const result = await this.executeCommand(this.verificationCommand, 30000);
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
success: result.success,
|
|
316
|
+
exitCode: result.exitCode,
|
|
317
|
+
stdout: result.stdout,
|
|
318
|
+
stderr: result.stderr,
|
|
319
|
+
installer: 'direct',
|
|
320
|
+
verified: result.success
|
|
321
|
+
};
|
|
322
|
+
} catch (error) {
|
|
323
|
+
if (this.logger) {
|
|
324
|
+
await this.logger.error('Direct verification failed', {
|
|
325
|
+
verificationCommand: this.verificationCommand,
|
|
326
|
+
error: error.message
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
throw error;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Get installed version for direct installation
|
|
335
|
+
* @returns {Promise<string|null>} - Version string or null
|
|
336
|
+
*/
|
|
337
|
+
async getInstalledVersion() {
|
|
338
|
+
try {
|
|
339
|
+
if (!this.verificationCommand) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const result = await this.executeCommand(this.verificationCommand, 30000);
|
|
344
|
+
|
|
345
|
+
if (result.success) {
|
|
346
|
+
// Parse version from output
|
|
347
|
+
const lines = result.stdout.split('\n');
|
|
348
|
+
const versionLine = lines.find(line =>
|
|
349
|
+
line.toLowerCase().includes('version') ||
|
|
350
|
+
/\d+\.\d+\.\d+/.test(line)
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
if (versionLine) {
|
|
354
|
+
const match = versionLine.match(/(\d+\.\d+\.\d+)/);
|
|
355
|
+
return match ? match[1] : null;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return null;
|
|
360
|
+
} catch (error) {
|
|
361
|
+
if (this.logger) {
|
|
362
|
+
await this.logger.debug('Failed to get installed version', {
|
|
363
|
+
verificationCommand: this.verificationCommand,
|
|
364
|
+
error: error.message
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Uninstall direct installation
|
|
373
|
+
* @returns {Promise<Object>} - Uninstallation result
|
|
374
|
+
*/
|
|
375
|
+
async uninstall() {
|
|
376
|
+
try {
|
|
377
|
+
if (!this.uninstallCommand) {
|
|
378
|
+
return {
|
|
379
|
+
success: false,
|
|
380
|
+
error: 'No uninstall command specified for direct installer',
|
|
381
|
+
installer: 'direct'
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const result = await this.executeCommand(this.uninstallCommand, 300000); // 5 minute timeout
|
|
386
|
+
|
|
387
|
+
if (this.logger) {
|
|
388
|
+
await this.logger.info('Direct uninstallation completed', {
|
|
389
|
+
uninstallCommand: this.uninstallCommand,
|
|
390
|
+
success: result.success,
|
|
391
|
+
exitCode: result.exitCode,
|
|
392
|
+
duration: result.duration
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
success: result.success,
|
|
398
|
+
exitCode: result.exitCode,
|
|
399
|
+
stdout: result.stdout,
|
|
400
|
+
stderr: result.stderr,
|
|
401
|
+
duration: result.duration,
|
|
402
|
+
installer: 'direct'
|
|
403
|
+
};
|
|
404
|
+
} catch (error) {
|
|
405
|
+
if (this.logger) {
|
|
406
|
+
await this.logger.error('Direct uninstallation failed', {
|
|
407
|
+
uninstallCommand: this.uninstallCommand,
|
|
408
|
+
error: error.message
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Get direct installer specific information
|
|
417
|
+
* @returns {Object} - Direct installer info
|
|
418
|
+
*/
|
|
419
|
+
getInstallerInfo() {
|
|
420
|
+
return {
|
|
421
|
+
...this.getInfo(),
|
|
422
|
+
installer: 'direct',
|
|
423
|
+
supportedPlatforms: ['win32', 'darwin', 'linux'],
|
|
424
|
+
minimumRequirements: ['file system access'],
|
|
425
|
+
supportedArchitectures: ['x64', 'arm64'],
|
|
426
|
+
features: [
|
|
427
|
+
'universal',
|
|
428
|
+
'no dependencies',
|
|
429
|
+
'custom scripts',
|
|
430
|
+
'direct control',
|
|
431
|
+
'download support'
|
|
432
|
+
],
|
|
433
|
+
limitations: [
|
|
434
|
+
'manual updates',
|
|
435
|
+
'verification required',
|
|
436
|
+
'custom implementation',
|
|
437
|
+
'error handling varies'
|
|
438
|
+
]
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
module.exports = DirectInstaller;
|