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.
Files changed (202) hide show
  1. package/README.md +240 -0
  2. package/package.json +10 -2
  3. package/src/agents/Agent.js +300 -0
  4. package/src/agents/AgentAdditionService.js +311 -0
  5. package/src/agents/AgentCheckService.js +690 -0
  6. package/src/agents/AgentInstallationService.js +140 -0
  7. package/src/agents/AgentSetupService.js +467 -0
  8. package/src/agents/AgentStatus.js +183 -0
  9. package/src/agents/AgentVerificationService.js +634 -0
  10. package/src/agents/ConfigurationSchemaValidator.js +543 -0
  11. package/src/agents/EnvironmentConfigurationManager.js +602 -0
  12. package/src/agents/InstallationErrorHandler.js +372 -0
  13. package/src/agents/InstallationLog.js +363 -0
  14. package/src/agents/InstallationMethod.js +510 -0
  15. package/src/agents/InstallationOrchestrator.js +352 -0
  16. package/src/agents/InstallationProgressReporter.js +372 -0
  17. package/src/agents/InstallationRetryManager.js +322 -0
  18. package/src/agents/InstallationType.js +254 -0
  19. package/src/agents/OperationTypes.js +310 -0
  20. package/src/agents/PerformanceMetricsCollector.js +493 -0
  21. package/src/agents/SecurityValidationService.js +534 -0
  22. package/src/agents/VerificationTest.js +354 -0
  23. package/src/agents/VerificationType.js +226 -0
  24. package/src/agents/WindowsPermissionHandler.js +518 -0
  25. package/src/agents/config/AgentConfigManager.js +393 -0
  26. package/src/agents/config/AgentDefaultsRegistry.js +373 -0
  27. package/src/agents/config/ConfigValidator.js +281 -0
  28. package/src/agents/discovery/AgentDiscoveryService.js +707 -0
  29. package/src/agents/logging/AgentLogger.js +511 -0
  30. package/src/agents/status/AgentStatusManager.js +481 -0
  31. package/src/agents/storage/FileManager.js +454 -0
  32. package/src/agents/verification/AgentCommunicationTester.js +474 -0
  33. package/src/agents/verification/BaseVerifier.js +430 -0
  34. package/src/agents/verification/CommandVerifier.js +480 -0
  35. package/src/agents/verification/FileOperationVerifier.js +453 -0
  36. package/src/agents/verification/ResultAnalyzer.js +707 -0
  37. package/src/agents/verification/TestRequirementManager.js +495 -0
  38. package/src/agents/verification/VerificationRunner.js +433 -0
  39. package/src/agents/windows/BaseWindowsInstaller.js +441 -0
  40. package/src/agents/windows/ChocolateyInstaller.js +509 -0
  41. package/src/agents/windows/DirectInstaller.js +443 -0
  42. package/src/agents/windows/InstallerFactory.js +391 -0
  43. package/src/agents/windows/NpmInstaller.js +505 -0
  44. package/src/agents/windows/PowerShellInstaller.js +458 -0
  45. package/src/agents/windows/WinGetInstaller.js +390 -0
  46. package/src/analysis/analysis-reporter.js +132 -0
  47. package/src/analysis/boundary-detector.js +712 -0
  48. package/src/analysis/categorizer.js +340 -0
  49. package/src/analysis/codebase-scanner.js +384 -0
  50. package/src/analysis/line-counter.js +513 -0
  51. package/src/analysis/priority-calculator.js +679 -0
  52. package/src/analysis/report/analysis-report.js +250 -0
  53. package/src/analysis/report/package-analyzer.js +278 -0
  54. package/src/analysis/report/recommendation-generator.js +382 -0
  55. package/src/analysis/report/statistics-generator.js +515 -0
  56. package/src/analysis/reports/analysis-report-model.js +101 -0
  57. package/src/analysis/reports/recommendation-generator.js +283 -0
  58. package/src/analysis/reports/report-generators.js +191 -0
  59. package/src/analysis/reports/statistics-calculator.js +231 -0
  60. package/src/analysis/reports/trend-analyzer.js +219 -0
  61. package/src/analysis/strategy-generator.js +814 -0
  62. package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
  63. package/src/config/refactoring-config.js +307 -0
  64. package/src/health-tracking/json-storage.js +38 -2
  65. package/src/ide-integration/applescript-manager-core.js +233 -0
  66. package/src/ide-integration/applescript-manager.cjs +357 -28
  67. package/src/ide-integration/applescript-manager.js +89 -3599
  68. package/src/ide-integration/cdp-manager.js +306 -0
  69. package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
  70. package/src/ide-integration/continuation-handler.js +337 -0
  71. package/src/ide-integration/ide-status-checker.js +292 -0
  72. package/src/ide-integration/macos-ide-manager.js +627 -0
  73. package/src/ide-integration/macos-text-sender.js +528 -0
  74. package/src/ide-integration/response-reader.js +548 -0
  75. package/src/ide-integration/windows-automation-manager.js +121 -0
  76. package/src/ide-integration/windows-ide-manager.js +373 -0
  77. package/src/index.cjs +25 -3
  78. package/src/index.js +15 -1
  79. package/src/llm/direct-llm-manager.cjs +90 -2
  80. package/src/models/compliance-report.js +538 -0
  81. package/src/models/file-analysis.js +681 -0
  82. package/src/models/refactoring-plan.js +770 -0
  83. package/src/monitoring/alert-system.js +834 -0
  84. package/src/monitoring/compliance-progress-tracker.js +437 -0
  85. package/src/monitoring/continuous-scan-notifications.js +661 -0
  86. package/src/monitoring/continuous-scanner.js +279 -0
  87. package/src/monitoring/file-monitor/file-analyzer.js +262 -0
  88. package/src/monitoring/file-monitor/file-monitor.js +237 -0
  89. package/src/monitoring/file-monitor/watcher.js +194 -0
  90. package/src/monitoring/file-monitor.js +17 -0
  91. package/src/monitoring/notification-manager.js +437 -0
  92. package/src/monitoring/scanner-core.js +368 -0
  93. package/src/monitoring/scanner-events.js +214 -0
  94. package/src/monitoring/violation-notification-system.js +515 -0
  95. package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
  96. package/src/refactoring/boundaries/extraction-result.js +285 -0
  97. package/src/refactoring/boundaries/extraction-strategies.js +392 -0
  98. package/src/refactoring/boundaries/module-boundary.js +209 -0
  99. package/src/refactoring/boundary/boundary-detector.js +741 -0
  100. package/src/refactoring/boundary/boundary-types.js +405 -0
  101. package/src/refactoring/boundary/extraction-strategies.js +554 -0
  102. package/src/refactoring/boundary-extraction-result.js +77 -0
  103. package/src/refactoring/boundary-extraction-strategies.js +330 -0
  104. package/src/refactoring/boundary-extractor.js +384 -0
  105. package/src/refactoring/boundary-types.js +46 -0
  106. package/src/refactoring/circular/circular-dependency.js +88 -0
  107. package/src/refactoring/circular/cycle-detection.js +147 -0
  108. package/src/refactoring/circular/dependency-node.js +82 -0
  109. package/src/refactoring/circular/dependency-result.js +107 -0
  110. package/src/refactoring/circular/dependency-types.js +58 -0
  111. package/src/refactoring/circular/graph-builder.js +213 -0
  112. package/src/refactoring/circular/resolution-strategy.js +72 -0
  113. package/src/refactoring/circular/strategy-generator.js +229 -0
  114. package/src/refactoring/circular-dependency-resolver-original.js +809 -0
  115. package/src/refactoring/circular-dependency-resolver.js +200 -0
  116. package/src/refactoring/code-mover.js +761 -0
  117. package/src/refactoring/file-splitter.js +696 -0
  118. package/src/refactoring/functionality-validator.js +816 -0
  119. package/src/refactoring/import-manager.js +774 -0
  120. package/src/refactoring/module-boundary.js +107 -0
  121. package/src/refactoring/refactoring-executor.js +672 -0
  122. package/src/refactoring/refactoring-rollback.js +614 -0
  123. package/src/refactoring/test-validator.js +631 -0
  124. package/src/requirement-management/default-requirement-manager.js +321 -0
  125. package/src/requirement-management/requirement-file-parser.js +159 -0
  126. package/src/requirement-management/requirement-sequencer.js +221 -0
  127. package/src/rui/commands/AgentCommandParser.js +600 -0
  128. package/src/rui/commands/AgentCommands.js +487 -0
  129. package/src/rui/commands/AgentResponseFormatter.js +832 -0
  130. package/src/scripts/verify-full-compliance.js +269 -0
  131. package/src/sync/sync-engine-core.js +1 -0
  132. package/src/sync/sync-engine-remote-handlers.js +135 -0
  133. package/src/task-generation/automated-task-generator.js +351 -0
  134. package/src/task-generation/prioritizer.js +287 -0
  135. package/src/task-generation/task-list-updater.js +215 -0
  136. package/src/task-generation/task-management-integration.js +480 -0
  137. package/src/task-generation/task-manager-integration.js +270 -0
  138. package/src/task-generation/violation-task-generator.js +474 -0
  139. package/src/task-management/continuous-scan-integration.js +342 -0
  140. package/src/timeout-management/index.js +12 -3
  141. package/src/timeout-management/response-time-tracker.js +167 -0
  142. package/src/timeout-management/timeout-calculator.js +159 -0
  143. package/src/timeout-management/timeout-config-manager.js +172 -0
  144. package/src/utils/ast-analyzer.js +417 -0
  145. package/src/utils/current-requirement-manager.js +276 -0
  146. package/src/utils/current-requirement-operations.js +472 -0
  147. package/src/utils/dependency-mapper.js +456 -0
  148. package/src/utils/download-with-progress.js +4 -2
  149. package/src/utils/electron-update-checker.js +4 -1
  150. package/src/utils/file-size-analyzer.js +272 -0
  151. package/src/utils/import-updater.js +280 -0
  152. package/src/utils/refactoring-tools.js +512 -0
  153. package/src/utils/report-generator.js +569 -0
  154. package/src/utils/reports/report-analysis.js +218 -0
  155. package/src/utils/reports/report-types.js +55 -0
  156. package/src/utils/reports/summary-generators.js +102 -0
  157. package/src/utils/requirement-file-management.js +157 -0
  158. package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
  159. package/src/utils/requirement-helpers/requirement-mover.js +414 -0
  160. package/src/utils/requirement-helpers/requirement-parser.js +326 -0
  161. package/src/utils/requirement-helpers/requirement-status.js +320 -0
  162. package/src/utils/requirement-helpers-new.js +55 -0
  163. package/src/utils/requirement-helpers-refactored.js +367 -0
  164. package/src/utils/requirement-helpers.js +291 -1191
  165. package/src/utils/requirement-movement-operations.js +450 -0
  166. package/src/utils/requirement-movement.js +312 -0
  167. package/src/utils/requirement-parsing-helpers.js +56 -0
  168. package/src/utils/requirement-statistics.js +200 -0
  169. package/src/utils/requirement-text-utils.js +58 -0
  170. package/src/utils/rollback/rollback-handlers.js +125 -0
  171. package/src/utils/rollback/rollback-operation.js +63 -0
  172. package/src/utils/rollback/rollback-recorder.js +166 -0
  173. package/src/utils/rollback/rollback-state-manager.js +175 -0
  174. package/src/utils/rollback/rollback-types.js +33 -0
  175. package/src/utils/rollback/rollback-utils.js +110 -0
  176. package/src/utils/rollback-manager-original.js +569 -0
  177. package/src/utils/rollback-manager.js +202 -0
  178. package/src/utils/smoke-test-cli.js +362 -0
  179. package/src/utils/smoke-test-gui.js +351 -0
  180. package/src/utils/smoke-test-orchestrator.js +321 -0
  181. package/src/utils/smoke-test-runner.js +60 -0
  182. package/src/utils/smoke-test-web.js +347 -0
  183. package/src/utils/specification-helpers.js +39 -13
  184. package/src/utils/specification-migration.js +97 -0
  185. package/src/utils/test-runner.js +579 -0
  186. package/src/utils/validation-framework.js +518 -0
  187. package/src/validation/compliance-analyzer.js +197 -0
  188. package/src/validation/compliance-report-generator.js +343 -0
  189. package/src/validation/compliance-reporter.js +711 -0
  190. package/src/validation/compliance-rules.js +127 -0
  191. package/src/validation/constitution-validator-new.js +196 -0
  192. package/src/validation/constitution-validator.js +17 -0
  193. package/src/validation/file-validators.js +170 -0
  194. package/src/validation/line-limit/file-analyzer.js +201 -0
  195. package/src/validation/line-limit/line-limit-validator.js +208 -0
  196. package/src/validation/line-limit/validation-result.js +144 -0
  197. package/src/validation/line-limit-core.js +225 -0
  198. package/src/validation/line-limit-reporter.js +134 -0
  199. package/src/validation/line-limit-result.js +125 -0
  200. package/src/validation/line-limit-validator.js +41 -0
  201. package/src/validation/metrics-calculator.js +660 -0
  202. 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;