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,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Windows Permission Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles Windows-specific permission operations and elevation.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { exec } = require('child_process');
|
|
9
|
+
const fs = require('fs').promises;
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Windows Permission Handler class
|
|
14
|
+
*/
|
|
15
|
+
class WindowsPermissionHandler {
|
|
16
|
+
/**
|
|
17
|
+
* Create permission handler instance
|
|
18
|
+
* @param {Object} options - Handler options
|
|
19
|
+
*/
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.logger = options.logger || null;
|
|
22
|
+
this.dryRun = options.dryRun || false;
|
|
23
|
+
this.autoElevate = options.autoElevate || false;
|
|
24
|
+
|
|
25
|
+
// Windows-specific constants
|
|
26
|
+
this.isAdmin = this.checkIsAdmin();
|
|
27
|
+
this.platform = os.platform();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if running as administrator
|
|
32
|
+
* @returns {boolean} - Whether running as admin
|
|
33
|
+
*/
|
|
34
|
+
checkIsAdmin() {
|
|
35
|
+
if (this.platform !== 'win32') {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
// Try to read a protected directory
|
|
41
|
+
fs.accessSync('C:\\Windows\\System32\\config', fs.constants.R_OK);
|
|
42
|
+
return true;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Request elevation for operations requiring admin privileges
|
|
50
|
+
* @param {string} operation - Description of operation
|
|
51
|
+
* @param {Function} callback - Function to execute with elevated privileges
|
|
52
|
+
* @returns {Promise<Object>} - Elevation result
|
|
53
|
+
*/
|
|
54
|
+
async requestElevation(operation, callback) {
|
|
55
|
+
if (this.platform !== 'win32') {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
error: 'Windows permission handler only works on Windows',
|
|
59
|
+
elevated: false
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (this.isAdmin) {
|
|
64
|
+
// Already running as admin, execute directly
|
|
65
|
+
try {
|
|
66
|
+
const result = await callback();
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
result,
|
|
70
|
+
elevated: false,
|
|
71
|
+
message: 'Operation completed with existing admin privileges'
|
|
72
|
+
};
|
|
73
|
+
} catch (error) {
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: error.message,
|
|
77
|
+
elevated: false
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!this.autoElevate) {
|
|
83
|
+
return {
|
|
84
|
+
success: false,
|
|
85
|
+
error: 'Admin privileges required but auto-elevation is disabled',
|
|
86
|
+
elevated: false
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Create elevation script
|
|
91
|
+
const scriptContent = this.createElevationScript(operation, callback);
|
|
92
|
+
const scriptPath = await this.writeElevationScript(scriptContent);
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const result = await this.executeElevatedScript(scriptPath);
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
result,
|
|
99
|
+
elevated: true,
|
|
100
|
+
message: 'Operation completed with elevated privileges'
|
|
101
|
+
};
|
|
102
|
+
} catch (error) {
|
|
103
|
+
return {
|
|
104
|
+
success: false,
|
|
105
|
+
error: error.message,
|
|
106
|
+
elevated: true
|
|
107
|
+
};
|
|
108
|
+
} finally {
|
|
109
|
+
// Cleanup script
|
|
110
|
+
await this.cleanupScript(scriptPath);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Create PowerShell elevation script
|
|
116
|
+
* @param {string} operation - Operation description
|
|
117
|
+
* @param {Function} callback - Callback function
|
|
118
|
+
* @returns {string} - PowerShell script content
|
|
119
|
+
*/
|
|
120
|
+
createElevationScript(operation, callback) {
|
|
121
|
+
const callbackString = callback.toString();
|
|
122
|
+
|
|
123
|
+
return `
|
|
124
|
+
# Elevated PowerShell Script for: ${operation}
|
|
125
|
+
param(
|
|
126
|
+
[string]$Operation = "${operation}",
|
|
127
|
+
[string]$Callback = '${callbackString.replace(/'/g, "''")}'
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Check if running as administrator
|
|
131
|
+
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
132
|
+
|
|
133
|
+
if (-not $isAdmin) {
|
|
134
|
+
Write-Host "This script requires administrator privileges."
|
|
135
|
+
exit 1
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
# Execute the callback function
|
|
140
|
+
$result = & ([ScriptBlock]::Create([string]::Concat('return ', $Callback)))
|
|
141
|
+
|
|
142
|
+
# Return result as JSON
|
|
143
|
+
$result | ConvertTo-Json -Depth 10
|
|
144
|
+
exit 0
|
|
145
|
+
} catch {
|
|
146
|
+
Write-Host "Error: $($_.Exception.Message)"
|
|
147
|
+
exit 1
|
|
148
|
+
}
|
|
149
|
+
`.trim();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Write elevation script to temporary file
|
|
154
|
+
* @param {string} scriptContent - Script content
|
|
155
|
+
* @returns {Promise<string>} - Script file path
|
|
156
|
+
*/
|
|
157
|
+
async writeElevationScript(scriptContent) {
|
|
158
|
+
const tempDir = os.tmpdir();
|
|
159
|
+
const scriptName = `elevate-${Date.now()}.ps1`;
|
|
160
|
+
const scriptPath = `${tempDir}\\${scriptName}`;
|
|
161
|
+
|
|
162
|
+
await fs.writeFile(scriptPath, scriptContent, 'utf8');
|
|
163
|
+
|
|
164
|
+
if (this.logger) {
|
|
165
|
+
this.logger.debug('Created elevation script', { scriptPath });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return scriptPath;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Execute elevated script
|
|
173
|
+
* @param {string} scriptPath - Path to script
|
|
174
|
+
* @returns {Promise<Object>} - Execution result
|
|
175
|
+
*/
|
|
176
|
+
async executeElevatedScript(scriptPath) {
|
|
177
|
+
return new Promise((resolve, reject) => {
|
|
178
|
+
const powershell = 'powershell.exe';
|
|
179
|
+
const args = [
|
|
180
|
+
'-ExecutionPolicy', 'Bypass',
|
|
181
|
+
'-WindowStyle', 'Hidden',
|
|
182
|
+
'-File', `"${scriptPath}"`
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
if (this.dryRun) {
|
|
186
|
+
resolve({ message: 'Dry run: would execute elevated script', args });
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const child = exec(`${powershell} ${args.join(' ')}`, {
|
|
191
|
+
cwd: process.cwd(),
|
|
192
|
+
env: { ...process.env }
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
let stdout = '';
|
|
196
|
+
let stderr = '';
|
|
197
|
+
|
|
198
|
+
child.stdout?.on('data', (data) => {
|
|
199
|
+
stdout += data.toString();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
child.stderr?.on('data', (data) => {
|
|
203
|
+
stderr += data.toString();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
child.on('close', (code) => {
|
|
207
|
+
if (code === 0) {
|
|
208
|
+
try {
|
|
209
|
+
const result = JSON.parse(stdout);
|
|
210
|
+
resolve(result);
|
|
211
|
+
} catch (parseError) {
|
|
212
|
+
reject(new Error(`Failed to parse elevated script result: ${parseError.message}`));
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
reject(new Error(`Elevated script failed with code ${code}: ${stderr}`));
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
child.on('error', (error) => {
|
|
220
|
+
reject(new Error(`Failed to execute elevated script: ${error.message}`));
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Cleanup temporary script
|
|
227
|
+
* @param {string} scriptPath - Path to script
|
|
228
|
+
*/
|
|
229
|
+
async cleanupScript(scriptPath) {
|
|
230
|
+
try {
|
|
231
|
+
await fs.unlink(scriptPath);
|
|
232
|
+
|
|
233
|
+
if (this.logger) {
|
|
234
|
+
this.logger.debug('Cleaned up elevation script', { scriptPath });
|
|
235
|
+
}
|
|
236
|
+
} catch (error) {
|
|
237
|
+
if (this.logger) {
|
|
238
|
+
this.logger.warn('Failed to cleanup elevation script', {
|
|
239
|
+
scriptPath,
|
|
240
|
+
error: error.message
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Check file permissions
|
|
248
|
+
* @param {string} filePath - Path to file
|
|
249
|
+
* @returns {Promise<Object>} - Permission information
|
|
250
|
+
*/
|
|
251
|
+
async checkFilePermissions(filePath) {
|
|
252
|
+
const result = {
|
|
253
|
+
exists: false,
|
|
254
|
+
readable: false,
|
|
255
|
+
writable: false,
|
|
256
|
+
executable: false,
|
|
257
|
+
owner: null,
|
|
258
|
+
permissions: null,
|
|
259
|
+
error: null
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
const stats = await fs.stat(filePath);
|
|
264
|
+
result.exists = true;
|
|
265
|
+
result.permissions = stats.mode;
|
|
266
|
+
|
|
267
|
+
// Check read permissions
|
|
268
|
+
await fs.access(filePath, fs.constants.R_OK);
|
|
269
|
+
result.readable = true;
|
|
270
|
+
|
|
271
|
+
// Check write permissions
|
|
272
|
+
await fs.access(filePath, fs.constants.W_OK);
|
|
273
|
+
result.writable = true;
|
|
274
|
+
|
|
275
|
+
// Check execute permissions
|
|
276
|
+
await fs.access(filePath, fs.constants.X_OK);
|
|
277
|
+
result.executable = true;
|
|
278
|
+
|
|
279
|
+
} catch (error) {
|
|
280
|
+
result.error = error.message;
|
|
281
|
+
|
|
282
|
+
// Partial information might still be available
|
|
283
|
+
if (error.code !== 'ENOENT') {
|
|
284
|
+
try {
|
|
285
|
+
const stats = await fs.stat(filePath);
|
|
286
|
+
result.exists = true;
|
|
287
|
+
result.permissions = stats.mode;
|
|
288
|
+
} catch (statError) {
|
|
289
|
+
// No file information available
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Grant file permissions
|
|
299
|
+
* @param {string} filePath - Path to file
|
|
300
|
+
* @param {Object} permissions - Permissions to grant
|
|
301
|
+
* @returns {Promise<Object>} - Grant result
|
|
302
|
+
*/
|
|
303
|
+
async grantFilePermissions(filePath, permissions = {}) {
|
|
304
|
+
const { readable = true, writable = true, executable = false } = permissions;
|
|
305
|
+
|
|
306
|
+
const result = {
|
|
307
|
+
success: false,
|
|
308
|
+
grantedPermissions: [],
|
|
309
|
+
errors: []
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
if (this.platform !== 'win32') {
|
|
313
|
+
result.errors.push('Permission granting only supported on Windows');
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
// Use icacls to modify permissions
|
|
319
|
+
const commands = [];
|
|
320
|
+
|
|
321
|
+
if (readable) {
|
|
322
|
+
commands.push(`icacls "${filePath}" /grant "${process.env.USERNAME || 'Everyone'}":R`);
|
|
323
|
+
result.grantedPermissions.push('read');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (writable) {
|
|
327
|
+
commands.push(`icacls "${filePath}" /grant "${process.env.USERNAME || 'Everyone'}":W`);
|
|
328
|
+
result.grantedPermissions.push('write');
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (executable) {
|
|
332
|
+
commands.push(`icacls "${filePath}" /grant "${process.env.USERNAME || 'Everyone'}":X`);
|
|
333
|
+
result.grantedPermissions.push('execute');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
for (const command of commands) {
|
|
337
|
+
if (this.dryRun) {
|
|
338
|
+
result.grantedPermissions.push('dry-run');
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
await this.executeCommand(command);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
result.success = true;
|
|
346
|
+
|
|
347
|
+
if (this.logger) {
|
|
348
|
+
this.logger.info('Granted file permissions', {
|
|
349
|
+
filePath,
|
|
350
|
+
grantedPermissions: result.grantedPermissions
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
} catch (error) {
|
|
355
|
+
result.errors.push(error.message);
|
|
356
|
+
|
|
357
|
+
if (this.logger) {
|
|
358
|
+
this.logger.error('Failed to grant file permissions', {
|
|
359
|
+
filePath,
|
|
360
|
+
error: error.message
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Check directory permissions
|
|
370
|
+
* @param {string} dirPath - Path to directory
|
|
371
|
+
* @returns {Promise<Object>} - Permission information
|
|
372
|
+
*/
|
|
373
|
+
async checkDirectoryPermissions(dirPath) {
|
|
374
|
+
const result = {
|
|
375
|
+
exists: false,
|
|
376
|
+
readable: false,
|
|
377
|
+
writable: false,
|
|
378
|
+
traversable: false,
|
|
379
|
+
permissions: null,
|
|
380
|
+
error: null
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const stats = await fs.stat(dirPath);
|
|
385
|
+
result.exists = true;
|
|
386
|
+
result.permissions = stats.mode;
|
|
387
|
+
|
|
388
|
+
// Check read permissions
|
|
389
|
+
await fs.access(dirPath, fs.constants.R_OK);
|
|
390
|
+
result.readable = true;
|
|
391
|
+
|
|
392
|
+
// Check write permissions
|
|
393
|
+
await fs.access(dirPath, fs.constants.W_OK);
|
|
394
|
+
result.writable = true;
|
|
395
|
+
|
|
396
|
+
// Check traverse permissions
|
|
397
|
+
await fs.access(dirPath, fs.constants.X_OK);
|
|
398
|
+
result.traversable = true;
|
|
399
|
+
|
|
400
|
+
} catch (error) {
|
|
401
|
+
result.error = error.message;
|
|
402
|
+
|
|
403
|
+
if (error.code !== 'ENOENT') {
|
|
404
|
+
try {
|
|
405
|
+
const stats = await fs.stat(dirPath);
|
|
406
|
+
result.exists = true;
|
|
407
|
+
result.permissions = stats.mode;
|
|
408
|
+
} catch (statError) {
|
|
409
|
+
// No directory information available
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return result;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Execute command with proper error handling
|
|
419
|
+
* @param {string} command - Command to execute
|
|
420
|
+
* @returns {Promise<Object>} - Execution result
|
|
421
|
+
*/
|
|
422
|
+
async executeCommand(command) {
|
|
423
|
+
return new Promise((resolve, reject) => {
|
|
424
|
+
exec(command, (error, stdout, stderr) => {
|
|
425
|
+
if (error) {
|
|
426
|
+
reject(error);
|
|
427
|
+
} else {
|
|
428
|
+
resolve({ stdout, stderr });
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Get permission recommendations
|
|
436
|
+
* @param {string} filePath - Path to analyze
|
|
437
|
+
* @returns {Promise<Object>} - Recommendations
|
|
438
|
+
*/
|
|
439
|
+
async getPermissionRecommendations(filePath) {
|
|
440
|
+
const permissions = await this.checkFilePermissions(filePath);
|
|
441
|
+
const recommendations = {
|
|
442
|
+
needsElevation: false,
|
|
443
|
+
suggestedActions: [],
|
|
444
|
+
warnings: []
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
if (!permissions.exists) {
|
|
448
|
+
recommendations.suggestedActions.push('File does not exist - check path');
|
|
449
|
+
return recommendations;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (!permissions.readable) {
|
|
453
|
+
recommendations.needsElevation = true;
|
|
454
|
+
recommendations.suggestedActions.push('Run as administrator to read file');
|
|
455
|
+
recommendations.warnings.push('File is not readable');
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (!permissions.writable) {
|
|
459
|
+
recommendations.needsElevation = true;
|
|
460
|
+
recommendations.suggestedActions.push('Run as administrator to modify file');
|
|
461
|
+
recommendations.warnings.push('File is not writable');
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Check if file is in protected directory
|
|
465
|
+
const protectedPaths = [
|
|
466
|
+
'C:\\Windows',
|
|
467
|
+
'C:\\Program Files',
|
|
468
|
+
'C:\\Program Files (x86)',
|
|
469
|
+
'C:\\ProgramData'
|
|
470
|
+
];
|
|
471
|
+
|
|
472
|
+
const normalizedPath = filePath.toLowerCase();
|
|
473
|
+
const isInProtectedPath = protectedPaths.some(protected =>
|
|
474
|
+
normalizedPath.startsWith(protected.toLowerCase())
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
if (isInProtectedPath) {
|
|
478
|
+
recommendations.needsElevation = true;
|
|
479
|
+
recommendations.suggestedActions.push('Administrator privileges required for protected directories');
|
|
480
|
+
recommendations.warnings.push('File is in protected system directory');
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return recommendations;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Get current permission status
|
|
488
|
+
* @returns {Object} - Current status
|
|
489
|
+
*/
|
|
490
|
+
getCurrentStatus() {
|
|
491
|
+
return {
|
|
492
|
+
platform: this.platform,
|
|
493
|
+
isAdmin: this.isAdmin,
|
|
494
|
+
autoElevate: this.autoElevate,
|
|
495
|
+
dryRun: this.dryRun,
|
|
496
|
+
username: process.env.USERNAME || 'Unknown',
|
|
497
|
+
canElevate: this.platform === 'win32' && !this.isAdmin
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Configure permission handler
|
|
503
|
+
* @param {Object} config - Configuration options
|
|
504
|
+
*/
|
|
505
|
+
configure(config = {}) {
|
|
506
|
+
if (config.autoElevate !== undefined) this.autoElevate = config.autoElevate;
|
|
507
|
+
if (config.dryRun !== undefined) this.dryRun = config.dryRun;
|
|
508
|
+
|
|
509
|
+
if (this.logger) {
|
|
510
|
+
this.logger.info('Updated permission handler configuration', {
|
|
511
|
+
autoElevate: this.autoElevate,
|
|
512
|
+
dryRun: this.dryRun
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
module.exports = WindowsPermissionHandler;
|