vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642
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,602 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Configuration Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages environment variable support for agent configuration.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs').promises;
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Environment Configuration Manager class
|
|
14
|
+
*/
|
|
15
|
+
class EnvironmentConfigurationManager {
|
|
16
|
+
/**
|
|
17
|
+
* Create environment configuration manager instance
|
|
18
|
+
* @param {Object} options - Manager options
|
|
19
|
+
*/
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.logger = options.logger || null;
|
|
22
|
+
this.prefix = options.prefix || 'VIBECODINGMACHINE_';
|
|
23
|
+
this.configFile = options.configFile || null;
|
|
24
|
+
this.overrideFile = options.overrideFile || path.join(os.homedir(), '.vibecodingmachine', 'env.json');
|
|
25
|
+
this.caseSensitive = options.caseSensitive !== false; // Default to case sensitive
|
|
26
|
+
|
|
27
|
+
// Environment variable mappings
|
|
28
|
+
this.variableMappings = {
|
|
29
|
+
// Installation settings
|
|
30
|
+
'INSTALL_TIMEOUT': 'installation.timeout',
|
|
31
|
+
'MAX_CONCURRENT_INSTALLATIONS': 'installation.maxConcurrent',
|
|
32
|
+
'RETRY_ATTEMPTS': 'installation.retryAttempts',
|
|
33
|
+
'RETRY_DELAY': 'installation.retryDelay',
|
|
34
|
+
'AUTO_ELEVATE': 'installation.autoElevate',
|
|
35
|
+
|
|
36
|
+
// Logging settings
|
|
37
|
+
'LOG_LEVEL': 'logging.level',
|
|
38
|
+
'LOG_FILE': 'logging.file',
|
|
39
|
+
'LOG_FORMAT': 'logging.format',
|
|
40
|
+
'VERBOSE_LOGGING': 'logging.verbose',
|
|
41
|
+
|
|
42
|
+
// Cache settings
|
|
43
|
+
'CACHE_DIR': 'cache.directory',
|
|
44
|
+
'CACHE_SIZE': 'cache.maxSize',
|
|
45
|
+
'CACHE_TTL': 'cache.ttl',
|
|
46
|
+
|
|
47
|
+
// Network settings
|
|
48
|
+
'HTTP_TIMEOUT': 'network.timeout',
|
|
49
|
+
'HTTP_PROXY': 'network.proxy',
|
|
50
|
+
'HTTP_USER_AGENT': 'network.userAgent',
|
|
51
|
+
'RATE_LIMIT_DELAY': 'network.rateLimitDelay',
|
|
52
|
+
|
|
53
|
+
// Security settings
|
|
54
|
+
'SECURITY_STRICT_MODE': 'security.strictMode',
|
|
55
|
+
'SECURITY_MAX_FILE_SIZE': 'security.maxFileSize',
|
|
56
|
+
'SECURITY_ALLOWED_EXTENSIONS': 'security.allowedExtensions',
|
|
57
|
+
|
|
58
|
+
// Performance settings
|
|
59
|
+
'PERFORMANCE_MONITORING': 'performance.monitoring',
|
|
60
|
+
'PERFORMANCE_METRICS_FILE': 'performance.metricsFile',
|
|
61
|
+
'PERFORMANCE_FLUSH_INTERVAL': 'performance.flushInterval',
|
|
62
|
+
|
|
63
|
+
// Agent settings
|
|
64
|
+
'DEFAULT_AGENTS_FILE': 'agents.defaultFile',
|
|
65
|
+
'AGENT_DISCOVERY_ENABLED': 'agents.discoveryEnabled',
|
|
66
|
+
'AGENT_AUTO_UPDATE': 'agents.autoUpdate'
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Type conversion functions
|
|
70
|
+
this.typeConverters = {
|
|
71
|
+
'boolean': (value) => {
|
|
72
|
+
if (typeof value === 'boolean') return value;
|
|
73
|
+
const str = String(value).toLowerCase();
|
|
74
|
+
return str === 'true' || str === '1' || str === 'yes' || str === 'on';
|
|
75
|
+
},
|
|
76
|
+
'number': (value) => {
|
|
77
|
+
const num = Number(value);
|
|
78
|
+
return isNaN(num) ? 0 : num;
|
|
79
|
+
},
|
|
80
|
+
'string': (value) => String(value),
|
|
81
|
+
'array': (value) => {
|
|
82
|
+
if (Array.isArray(value)) return value;
|
|
83
|
+
const str = String(value);
|
|
84
|
+
try {
|
|
85
|
+
return JSON.parse(str);
|
|
86
|
+
} catch {
|
|
87
|
+
return str.split(',').map(s => s.trim()).filter(s => s);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
'object': (value) => {
|
|
91
|
+
if (typeof value === 'object' && value !== null) return value;
|
|
92
|
+
const str = String(value);
|
|
93
|
+
try {
|
|
94
|
+
return JSON.parse(str);
|
|
95
|
+
} catch {
|
|
96
|
+
return {};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Default configuration schema
|
|
102
|
+
this.defaultConfig = {
|
|
103
|
+
installation: {
|
|
104
|
+
timeout: 300000,
|
|
105
|
+
maxConcurrent: 2,
|
|
106
|
+
retryAttempts: 3,
|
|
107
|
+
retryDelay: 5000,
|
|
108
|
+
autoElevate: false
|
|
109
|
+
},
|
|
110
|
+
logging: {
|
|
111
|
+
level: 'info',
|
|
112
|
+
file: null,
|
|
113
|
+
format: 'json',
|
|
114
|
+
verbose: false
|
|
115
|
+
},
|
|
116
|
+
cache: {
|
|
117
|
+
directory: './cache',
|
|
118
|
+
maxSize: 100 * 1024 * 1024, // 100MB
|
|
119
|
+
ttl: 3600000 // 1 hour
|
|
120
|
+
},
|
|
121
|
+
network: {
|
|
122
|
+
timeout: 30000,
|
|
123
|
+
proxy: null,
|
|
124
|
+
userAgent: null,
|
|
125
|
+
rateLimitDelay: 1000
|
|
126
|
+
},
|
|
127
|
+
security: {
|
|
128
|
+
strictMode: true,
|
|
129
|
+
maxFileSize: 100 * 1024 * 1024, // 100MB
|
|
130
|
+
allowedExtensions: ['.exe', '.msi', '.zip', '.tar', '.gz']
|
|
131
|
+
},
|
|
132
|
+
performance: {
|
|
133
|
+
monitoring: true,
|
|
134
|
+
metricsFile: null,
|
|
135
|
+
flushInterval: 60000
|
|
136
|
+
},
|
|
137
|
+
agents: {
|
|
138
|
+
defaultFile: './config/agents.json',
|
|
139
|
+
discoveryEnabled: true,
|
|
140
|
+
autoUpdate: false
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Load configuration from environment variables and files
|
|
147
|
+
* @returns {Promise<Object>} - Loaded configuration
|
|
148
|
+
*/
|
|
149
|
+
async loadConfiguration() {
|
|
150
|
+
const config = JSON.parse(JSON.stringify(this.defaultConfig)); // Deep clone
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
// Load from override file first
|
|
154
|
+
const overrideConfig = await this.loadOverrideFile();
|
|
155
|
+
this.mergeConfig(config, overrideConfig);
|
|
156
|
+
|
|
157
|
+
// Load from environment variables
|
|
158
|
+
const envConfig = this.loadEnvironmentVariables();
|
|
159
|
+
this.mergeConfig(config, envConfig);
|
|
160
|
+
|
|
161
|
+
// Load from specified config file
|
|
162
|
+
if (this.configFile) {
|
|
163
|
+
const fileConfig = await this.loadConfigFile(this.configFile);
|
|
164
|
+
this.mergeConfig(config, fileConfig);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (this.logger) {
|
|
168
|
+
this.logger.info('Configuration loaded successfully', {
|
|
169
|
+
sources: ['override file', 'environment variables', 'config file'].filter(Boolean),
|
|
170
|
+
configKeys: Object.keys(config)
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (this.logger) {
|
|
176
|
+
this.logger.error('Failed to load configuration', { error: error.message });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Return default configuration on error
|
|
180
|
+
return JSON.parse(JSON.stringify(this.defaultConfig));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return config;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Load configuration from override file
|
|
188
|
+
* @returns {Promise<Object>} - Override configuration
|
|
189
|
+
*/
|
|
190
|
+
async loadOverrideFile() {
|
|
191
|
+
try {
|
|
192
|
+
const exists = await fs.access(this.overrideFile).then(() => true).catch(() => false);
|
|
193
|
+
if (!exists) return {};
|
|
194
|
+
|
|
195
|
+
const content = await fs.readFile(this.overrideFile, 'utf8');
|
|
196
|
+
const config = JSON.parse(content);
|
|
197
|
+
|
|
198
|
+
if (this.logger) {
|
|
199
|
+
this.logger.debug('Loaded override file configuration', {
|
|
200
|
+
file: this.overrideFile,
|
|
201
|
+
keys: Object.keys(config)
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return config;
|
|
206
|
+
} catch (error) {
|
|
207
|
+
if (this.logger) {
|
|
208
|
+
this.logger.warn('Failed to load override file', {
|
|
209
|
+
file: this.overrideFile,
|
|
210
|
+
error: error.message
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return {};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Load configuration from environment variables
|
|
219
|
+
* @returns {Object} - Environment configuration
|
|
220
|
+
*/
|
|
221
|
+
loadEnvironmentVariables() {
|
|
222
|
+
const config = {};
|
|
223
|
+
|
|
224
|
+
for (const [envVar, configPath] of Object.entries(this.variableMappings)) {
|
|
225
|
+
const fullEnvVar = this.prefix + envVar;
|
|
226
|
+
const value = process.env[fullEnvVar];
|
|
227
|
+
|
|
228
|
+
if (value !== undefined) {
|
|
229
|
+
this.setNestedValue(config, configPath, value);
|
|
230
|
+
|
|
231
|
+
if (this.logger) {
|
|
232
|
+
this.logger.debug('Loaded environment variable', {
|
|
233
|
+
variable: fullEnvVar,
|
|
234
|
+
configPath,
|
|
235
|
+
value
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return config;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Load configuration from file
|
|
246
|
+
* @param {string} filePath - Path to config file
|
|
247
|
+
* @returns {Promise<Object>} - File configuration
|
|
248
|
+
*/
|
|
249
|
+
async loadConfigFile(filePath) {
|
|
250
|
+
try {
|
|
251
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
252
|
+
const config = JSON.parse(content);
|
|
253
|
+
|
|
254
|
+
if (this.logger) {
|
|
255
|
+
this.logger.debug('Loaded config file', {
|
|
256
|
+
file: filePath,
|
|
257
|
+
keys: Object.keys(config)
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return config;
|
|
262
|
+
} catch (error) {
|
|
263
|
+
if (this.logger) {
|
|
264
|
+
this.logger.warn('Failed to load config file', {
|
|
265
|
+
file: filePath,
|
|
266
|
+
error: error.message
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return {};
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Save configuration to override file
|
|
275
|
+
* @param {Object} config - Configuration to save
|
|
276
|
+
* @returns {Promise<Object>} - Save result
|
|
277
|
+
*/
|
|
278
|
+
async saveConfiguration(config) {
|
|
279
|
+
const result = {
|
|
280
|
+
success: false,
|
|
281
|
+
error: null,
|
|
282
|
+
filePath: this.overrideFile
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
// Ensure directory exists
|
|
287
|
+
const dir = path.dirname(this.overrideFile);
|
|
288
|
+
await fs.mkdir(dir, { recursive: true });
|
|
289
|
+
|
|
290
|
+
// Save configuration
|
|
291
|
+
const content = JSON.stringify(config, null, 2);
|
|
292
|
+
await fs.writeFile(this.overrideFile, content, 'utf8');
|
|
293
|
+
|
|
294
|
+
result.success = true;
|
|
295
|
+
|
|
296
|
+
if (this.logger) {
|
|
297
|
+
this.logger.info('Configuration saved successfully', {
|
|
298
|
+
file: this.overrideFile,
|
|
299
|
+
keys: Object.keys(config)
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
} catch (error) {
|
|
304
|
+
result.error = error.message;
|
|
305
|
+
|
|
306
|
+
if (this.logger) {
|
|
307
|
+
this.logger.error('Failed to save configuration', {
|
|
308
|
+
file: this.overrideFile,
|
|
309
|
+
error: error.message
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Set configuration value
|
|
319
|
+
* @param {string} key - Configuration key
|
|
320
|
+
* @param {*} value - Configuration value
|
|
321
|
+
* @param {string} type - Value type
|
|
322
|
+
* @returns {Promise<Object>} - Set result
|
|
323
|
+
*/
|
|
324
|
+
async setConfigurationValue(key, value, type = 'string') {
|
|
325
|
+
const result = {
|
|
326
|
+
success: false,
|
|
327
|
+
error: null,
|
|
328
|
+
previousValue: null
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
// Load current configuration
|
|
333
|
+
const config = await this.loadConfiguration();
|
|
334
|
+
result.previousValue = this.getNestedValue(config, key);
|
|
335
|
+
|
|
336
|
+
// Convert value type
|
|
337
|
+
const convertedValue = this.typeConverters[type] ?
|
|
338
|
+
this.typeConverters[type](value) : value;
|
|
339
|
+
|
|
340
|
+
// Set new value
|
|
341
|
+
this.setNestedValue(config, key, convertedValue);
|
|
342
|
+
|
|
343
|
+
// Save configuration
|
|
344
|
+
const saveResult = await this.saveConfiguration(config);
|
|
345
|
+
result.success = saveResult.success;
|
|
346
|
+
result.error = saveResult.error;
|
|
347
|
+
|
|
348
|
+
if (this.logger) {
|
|
349
|
+
this.logger.info('Configuration value set', {
|
|
350
|
+
key,
|
|
351
|
+
value: convertedValue,
|
|
352
|
+
type,
|
|
353
|
+
previousValue: result.previousValue
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
} catch (error) {
|
|
358
|
+
result.error = error.message;
|
|
359
|
+
|
|
360
|
+
if (this.logger) {
|
|
361
|
+
this.logger.error('Failed to set configuration value', {
|
|
362
|
+
key,
|
|
363
|
+
value,
|
|
364
|
+
error: error.message
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return result;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Get configuration value
|
|
374
|
+
* @param {string} key - Configuration key
|
|
375
|
+
* @param {*} defaultValue - Default value
|
|
376
|
+
* @returns {Promise<*>} - Configuration value
|
|
377
|
+
*/
|
|
378
|
+
async getConfigurationValue(key, defaultValue = null) {
|
|
379
|
+
try {
|
|
380
|
+
const config = await this.loadConfiguration();
|
|
381
|
+
const value = this.getNestedValue(config, key);
|
|
382
|
+
return value !== undefined ? value : defaultValue;
|
|
383
|
+
} catch (error) {
|
|
384
|
+
if (this.logger) {
|
|
385
|
+
this.logger.error('Failed to get configuration value', {
|
|
386
|
+
key,
|
|
387
|
+
error: error.message
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
return defaultValue;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Set nested configuration value
|
|
396
|
+
* @param {Object} obj - Target object
|
|
397
|
+
* @param {string} path - Dot-separated path
|
|
398
|
+
* @param {*} value - Value to set
|
|
399
|
+
*/
|
|
400
|
+
setNestedValue(obj, path, value) {
|
|
401
|
+
const keys = path.split('.');
|
|
402
|
+
let current = obj;
|
|
403
|
+
|
|
404
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
405
|
+
const key = keys[i];
|
|
406
|
+
if (!(key in current) || typeof current[key] !== 'object') {
|
|
407
|
+
current[key] = {};
|
|
408
|
+
}
|
|
409
|
+
current = current[key];
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
current[keys[keys.length - 1]] = value;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Get nested configuration value
|
|
417
|
+
* @param {Object} obj - Source object
|
|
418
|
+
* @param {string} path - Dot-separated path
|
|
419
|
+
* @returns {*} - Configuration value
|
|
420
|
+
*/
|
|
421
|
+
getNestedValue(obj, path) {
|
|
422
|
+
const keys = path.split('.');
|
|
423
|
+
let current = obj;
|
|
424
|
+
|
|
425
|
+
for (const key of keys) {
|
|
426
|
+
if (current && typeof current === 'object' && key in current) {
|
|
427
|
+
current = current[key];
|
|
428
|
+
} else {
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return current;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Merge configuration objects
|
|
438
|
+
* @param {Object} target - Target object
|
|
439
|
+
* @param {Object} source - Source object
|
|
440
|
+
*/
|
|
441
|
+
mergeConfig(target, source) {
|
|
442
|
+
this.deepMerge(target, source);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Deep merge objects
|
|
447
|
+
* @param {Object} target - Target object
|
|
448
|
+
* @param {Object} source - Source object
|
|
449
|
+
*/
|
|
450
|
+
deepMerge(target, source) {
|
|
451
|
+
for (const key in source) {
|
|
452
|
+
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
453
|
+
if (!target[key] || typeof target[key] !== 'object') {
|
|
454
|
+
target[key] = {};
|
|
455
|
+
}
|
|
456
|
+
this.deepMerge(target[key], source[key]);
|
|
457
|
+
} else {
|
|
458
|
+
target[key] = source[key];
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Get environment variable documentation
|
|
465
|
+
* @returns {Object} - Environment variable documentation
|
|
466
|
+
*/
|
|
467
|
+
getEnvironmentVariableDocumentation() {
|
|
468
|
+
const docs = {};
|
|
469
|
+
|
|
470
|
+
for (const [envVar, configPath] of Object.entries(this.variableMappings)) {
|
|
471
|
+
const fullEnvVar = this.prefix + envVar;
|
|
472
|
+
const defaultValue = this.getNestedValue(this.defaultConfig, configPath);
|
|
473
|
+
|
|
474
|
+
docs[fullEnvVar] = {
|
|
475
|
+
configPath,
|
|
476
|
+
description: this.getVariableDescription(envVar),
|
|
477
|
+
defaultValue,
|
|
478
|
+
type: this.getVariableType(configPath, defaultValue)
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return docs;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Get variable description
|
|
487
|
+
* @param {string} envVar - Environment variable name
|
|
488
|
+
* @returns {string} - Description
|
|
489
|
+
*/
|
|
490
|
+
getVariableDescription(envVar) {
|
|
491
|
+
const descriptions = {
|
|
492
|
+
'INSTALL_TIMEOUT': 'Installation timeout in milliseconds',
|
|
493
|
+
'MAX_CONCURRENT_INSTALLATIONS': 'Maximum concurrent installations',
|
|
494
|
+
'RETRY_ATTEMPTS': 'Number of retry attempts for failed operations',
|
|
495
|
+
'RETRY_DELAY': 'Delay between retry attempts in milliseconds',
|
|
496
|
+
'AUTO_ELEVATE': 'Automatically request administrator privileges',
|
|
497
|
+
'LOG_LEVEL': 'Logging level (error, warn, info, debug)',
|
|
498
|
+
'LOG_FILE': 'Path to log file',
|
|
499
|
+
'LOG_FORMAT': 'Log format (json, text)',
|
|
500
|
+
'VERBOSE_LOGGING': 'Enable verbose logging',
|
|
501
|
+
'CACHE_DIR': 'Cache directory path',
|
|
502
|
+
'CACHE_SIZE': 'Maximum cache size in bytes',
|
|
503
|
+
'CACHE_TTL': 'Cache time-to-live in milliseconds',
|
|
504
|
+
'HTTP_TIMEOUT': 'HTTP request timeout in milliseconds',
|
|
505
|
+
'HTTP_PROXY': 'HTTP proxy URL',
|
|
506
|
+
'HTTP_USER_AGENT': 'HTTP user agent string',
|
|
507
|
+
'RATE_LIMIT_DELAY': 'Delay for rate limiting in milliseconds',
|
|
508
|
+
'SECURITY_STRICT_MODE': 'Enable strict security mode',
|
|
509
|
+
'SECURITY_MAX_FILE_SIZE': 'Maximum allowed file size in bytes',
|
|
510
|
+
'SECURITY_ALLOWED_EXTENSIONS': 'Comma-separated list of allowed file extensions',
|
|
511
|
+
'PERFORMANCE_MONITORING': 'Enable performance monitoring',
|
|
512
|
+
'PERFORMANCE_METRICS_FILE': 'Path to performance metrics file',
|
|
513
|
+
'PERFORMANCE_FLUSH_INTERVAL': 'Performance metrics flush interval in milliseconds',
|
|
514
|
+
'DEFAULT_AGENTS_FILE': 'Path to default agents configuration file',
|
|
515
|
+
'AGENT_DISCOVERY_ENABLED': 'Enable automatic agent discovery',
|
|
516
|
+
'AGENT_AUTO_UPDATE': 'Enable automatic agent updates'
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
return descriptions[envVar] || 'Configuration variable';
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Get variable type
|
|
524
|
+
* @param {string} configPath - Configuration path
|
|
525
|
+
* @param {*} defaultValue - Default value
|
|
526
|
+
* @returns {string} - Variable type
|
|
527
|
+
*/
|
|
528
|
+
getVariableType(configPath, defaultValue) {
|
|
529
|
+
if (typeof defaultValue === 'boolean') return 'boolean';
|
|
530
|
+
if (typeof defaultValue === 'number') return 'number';
|
|
531
|
+
if (Array.isArray(defaultValue)) return 'array';
|
|
532
|
+
if (typeof defaultValue === 'object' && defaultValue !== null) return 'object';
|
|
533
|
+
return 'string';
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Export configuration to environment file
|
|
538
|
+
* @param {string} filePath - Export file path
|
|
539
|
+
* @returns {Promise<Object>} - Export result
|
|
540
|
+
*/
|
|
541
|
+
async exportToEnvironmentFile(filePath) {
|
|
542
|
+
const result = {
|
|
543
|
+
success: false,
|
|
544
|
+
error: null,
|
|
545
|
+
filePath
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
try {
|
|
549
|
+
const config = await this.loadConfiguration();
|
|
550
|
+
const envVars = [];
|
|
551
|
+
|
|
552
|
+
for (const [envVar, configPath] of Object.entries(this.variableMappings)) {
|
|
553
|
+
const value = this.getNestedValue(config, configPath);
|
|
554
|
+
if (value !== undefined && value !== this.getNestedValue(this.defaultConfig, configPath)) {
|
|
555
|
+
const fullEnvVar = this.prefix + envVar;
|
|
556
|
+
envVars.push(`${fullEnvVar}=${JSON.stringify(value)}`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
const content = envVars.join('\n');
|
|
561
|
+
await fs.writeFile(filePath, content, 'utf8');
|
|
562
|
+
|
|
563
|
+
result.success = true;
|
|
564
|
+
|
|
565
|
+
if (this.logger) {
|
|
566
|
+
this.logger.info('Configuration exported to environment file', {
|
|
567
|
+
filePath,
|
|
568
|
+
variableCount: envVars.length
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
} catch (error) {
|
|
573
|
+
result.error = error.message;
|
|
574
|
+
|
|
575
|
+
if (this.logger) {
|
|
576
|
+
this.logger.error('Failed to export configuration', {
|
|
577
|
+
filePath,
|
|
578
|
+
error: error.message
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return result;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Get current configuration
|
|
588
|
+
* @returns {Object} - Current configuration
|
|
589
|
+
*/
|
|
590
|
+
getCurrentConfiguration() {
|
|
591
|
+
return {
|
|
592
|
+
prefix: this.prefix,
|
|
593
|
+
configFile: this.configFile,
|
|
594
|
+
overrideFile: this.overrideFile,
|
|
595
|
+
caseSensitive: this.caseSensitive,
|
|
596
|
+
variableCount: Object.keys(this.variableMappings).length,
|
|
597
|
+
supportedVariables: Object.keys(this.variableMappings).map(v => this.prefix + v)
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
module.exports = EnvironmentConfigurationManager;
|