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,125 @@
1
+ /**
2
+ * Rollback Handlers
3
+ *
4
+ * Contains the actual rollback execution logic for different operation types.
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { ROLLBACK_TYPES } = require('./rollback-types');
10
+ const { RollbackUtils } = require('./rollback-utils');
11
+
12
+ /**
13
+ * Rollback execution handlers
14
+ */
15
+ class RollbackHandlers {
16
+ /**
17
+ * Rollback file update
18
+ */
19
+ static async rollbackFileUpdate(operation) {
20
+ if (!operation.backupPath || !fs.existsSync(operation.backupPath)) {
21
+ throw new Error(`Backup not found for file update: ${operation.targetPath}`);
22
+ }
23
+
24
+ // Restore original file
25
+ fs.copyFileSync(operation.backupPath, operation.targetPath);
26
+ }
27
+
28
+ /**
29
+ * Rollback file creation
30
+ */
31
+ static async rollbackFileCreate(operation) {
32
+ if (fs.existsSync(operation.targetPath)) {
33
+ fs.unlinkSync(operation.targetPath);
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Rollback file deletion
39
+ */
40
+ static async rollbackFileDelete(operation) {
41
+ if (!operation.backupPath || !fs.existsSync(operation.backupPath)) {
42
+ throw new Error(`Backup not found for file deletion: ${operation.targetPath}`);
43
+ }
44
+
45
+ // Ensure target directory exists
46
+ const targetDir = path.dirname(operation.targetPath);
47
+ if (!fs.existsSync(targetDir)) {
48
+ fs.mkdirSync(targetDir, { recursive: true });
49
+ }
50
+
51
+ // Restore deleted file
52
+ fs.copyFileSync(operation.backupPath, operation.targetPath);
53
+ }
54
+
55
+ /**
56
+ * Rollback file move
57
+ */
58
+ static async rollbackFileMove(operation) {
59
+ const originalPath = operation.metadata.originalPath;
60
+
61
+ if (fs.existsSync(operation.targetPath)) {
62
+ // Move file back to original location
63
+ fs.renameSync(operation.targetPath, originalPath);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Rollback directory creation
69
+ */
70
+ static async rollbackDirectoryCreate(operation) {
71
+ if (fs.existsSync(operation.targetPath)) {
72
+ fs.rmSync(operation.targetPath, { recursive: true, force: true });
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Rollback directory deletion
78
+ */
79
+ static async rollbackDirectoryDelete(operation) {
80
+ if (!operation.backupPath || !fs.existsSync(operation.backupPath)) {
81
+ throw new Error(`Backup not found for directory deletion: ${operation.targetPath}`);
82
+ }
83
+
84
+ // Restore deleted directory
85
+ RollbackUtils.copyDirectory(operation.backupPath, operation.targetPath);
86
+ }
87
+
88
+ /**
89
+ * Rollback a single operation by type
90
+ */
91
+ static async rollbackOperation(operation) {
92
+ if (operation.rollbackExecuted) {
93
+ throw new Error(`Operation already rolled back: ${operation.id}`);
94
+ }
95
+
96
+ switch (operation.type) {
97
+ case ROLLBACK_TYPES.FILE_UPDATE:
98
+ await RollbackHandlers.rollbackFileUpdate(operation);
99
+ break;
100
+ case ROLLBACK_TYPES.FILE_CREATE:
101
+ await RollbackHandlers.rollbackFileCreate(operation);
102
+ break;
103
+ case ROLLBACK_TYPES.FILE_DELETE:
104
+ await RollbackHandlers.rollbackFileDelete(operation);
105
+ break;
106
+ case ROLLBACK_TYPES.FILE_MOVE:
107
+ await RollbackHandlers.rollbackFileMove(operation);
108
+ break;
109
+ case ROLLBACK_TYPES.DIRECTORY_CREATE:
110
+ await RollbackHandlers.rollbackDirectoryCreate(operation);
111
+ break;
112
+ case ROLLBACK_TYPES.DIRECTORY_DELETE:
113
+ await RollbackHandlers.rollbackDirectoryDelete(operation);
114
+ break;
115
+ default:
116
+ throw new Error(`Unknown rollback operation type: ${operation.type}`);
117
+ }
118
+
119
+ operation.rollback();
120
+ }
121
+ }
122
+
123
+ module.exports = {
124
+ RollbackHandlers
125
+ };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Rollback Operation
3
+ *
4
+ * Represents a single rollback operation with metadata and state tracking.
5
+ */
6
+
7
+ const crypto = require('crypto');
8
+
9
+ /**
10
+ * Rollback operation class
11
+ */
12
+ class RollbackOperation {
13
+ constructor(type, targetPath, backupPath = null, metadata = {}) {
14
+ this.id = this.generateId();
15
+ this.type = type;
16
+ this.targetPath = targetPath;
17
+ this.backupPath = backupPath;
18
+ this.metadata = metadata;
19
+ this.timestamp = new Date().toISOString();
20
+ this.executed = false;
21
+ this.rollbackExecuted = false;
22
+ }
23
+
24
+ generateId() {
25
+ return crypto.randomBytes(16).toString('hex');
26
+ }
27
+
28
+ execute() {
29
+ this.executed = true;
30
+ this.executionTime = new Date().toISOString();
31
+ }
32
+
33
+ rollback() {
34
+ this.rollbackExecuted = true;
35
+ this.rollbackTime = new Date().toISOString();
36
+ }
37
+
38
+ /**
39
+ * Check if operation can be rolled back
40
+ */
41
+ canRollback() {
42
+ return this.executed && !this.rollbackExecuted;
43
+ }
44
+
45
+ /**
46
+ * Get operation summary
47
+ */
48
+ getSummary() {
49
+ return {
50
+ id: this.id,
51
+ type: this.type,
52
+ targetPath: this.targetPath,
53
+ timestamp: this.timestamp,
54
+ executed: this.executed,
55
+ rollbackExecuted: this.rollbackExecuted,
56
+ hasBackup: !!this.backupPath
57
+ };
58
+ }
59
+ }
60
+
61
+ module.exports = {
62
+ RollbackOperation
63
+ };
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Rollback Recorder
3
+ *
4
+ * Handles recording of operations for potential rollback.
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const crypto = require('crypto');
10
+ const { RollbackOperation } = require('./rollback-operation');
11
+ const { ROLLBACK_TYPES } = require('./rollback-types');
12
+ const { RollbackUtils } = require('./rollback-utils');
13
+
14
+ /**
15
+ * Rollback recording functionality
16
+ */
17
+ class RollbackRecorder {
18
+ constructor(backupDir, sessionId) {
19
+ this.backupDir = backupDir;
20
+ this.sessionId = sessionId;
21
+ }
22
+
23
+ /**
24
+ * Get session backup directory
25
+ */
26
+ getSessionBackupDir() {
27
+ return path.join(this.backupDir, this.sessionId);
28
+ }
29
+
30
+ /**
31
+ * Create backup of a file before modification
32
+ */
33
+ backupFile(filePath) {
34
+ if (!fs.existsSync(filePath)) {
35
+ throw new Error(`File not found for backup: ${filePath}`);
36
+ }
37
+
38
+ const backupPath = RollbackUtils.getBackupPath(this.getSessionBackupDir(), filePath);
39
+ RollbackUtils.safeCopyFile(filePath, backupPath);
40
+
41
+ const metadata = RollbackUtils.getFileMetadata(filePath);
42
+
43
+ const operation = new RollbackOperation(
44
+ ROLLBACK_TYPES.FILE_UPDATE,
45
+ filePath,
46
+ backupPath,
47
+ {
48
+ originalSize: metadata.size,
49
+ originalModified: metadata.modified
50
+ }
51
+ );
52
+
53
+ return operation;
54
+ }
55
+
56
+ /**
57
+ * Record file creation
58
+ */
59
+ recordFileCreation(filePath) {
60
+ const metadata = RollbackUtils.getFileMetadata(filePath);
61
+
62
+ const operation = new RollbackOperation(
63
+ ROLLBACK_TYPES.FILE_CREATE,
64
+ filePath,
65
+ null,
66
+ {
67
+ createdTime: metadata.modified
68
+ }
69
+ );
70
+
71
+ return operation;
72
+ }
73
+
74
+ /**
75
+ * Record file deletion (with backup)
76
+ */
77
+ recordFileDeletion(filePath) {
78
+ let backupPath = null;
79
+
80
+ if (fs.existsSync(filePath)) {
81
+ backupPath = RollbackUtils.getBackupPath(this.getSessionBackupDir(), filePath);
82
+ RollbackUtils.safeCopyFile(filePath, backupPath);
83
+ }
84
+
85
+ const metadata = RollbackUtils.getFileMetadata(filePath);
86
+
87
+ const operation = new RollbackOperation(
88
+ ROLLBACK_TYPES.FILE_DELETE,
89
+ filePath,
90
+ backupPath,
91
+ {
92
+ originalSize: metadata.size,
93
+ originalModified: metadata.modified
94
+ }
95
+ );
96
+
97
+ return operation;
98
+ }
99
+
100
+ /**
101
+ * Record file move/rename
102
+ */
103
+ recordFileMove(oldPath, newPath) {
104
+ const backupPath = RollbackUtils.getBackupPath(this.getSessionBackupDir(), oldPath);
105
+
106
+ if (fs.existsSync(oldPath)) {
107
+ RollbackUtils.safeCopyFile(oldPath, backupPath);
108
+ }
109
+
110
+ const operation = new RollbackOperation(
111
+ ROLLBACK_TYPES.FILE_MOVE,
112
+ newPath,
113
+ backupPath,
114
+ {
115
+ originalPath: oldPath,
116
+ newPath: newPath
117
+ }
118
+ );
119
+
120
+ return operation;
121
+ }
122
+
123
+ /**
124
+ * Record directory creation
125
+ */
126
+ recordDirectoryCreation(dirPath) {
127
+ const metadata = RollbackUtils.getFileMetadata(dirPath);
128
+
129
+ const operation = new RollbackOperation(
130
+ ROLLBACK_TYPES.DIRECTORY_CREATE,
131
+ dirPath,
132
+ null,
133
+ {
134
+ createdTime: metadata.modified
135
+ }
136
+ );
137
+
138
+ return operation;
139
+ }
140
+
141
+ /**
142
+ * Record directory deletion (with backup)
143
+ */
144
+ recordDirectoryDeletion(dirPath) {
145
+ const backupPath = RollbackUtils.getBackupPath(this.getSessionBackupDir(), dirPath);
146
+
147
+ if (fs.existsSync(dirPath)) {
148
+ RollbackUtils.copyDirectory(dirPath, backupPath);
149
+ }
150
+
151
+ const operation = new RollbackOperation(
152
+ ROLLBACK_TYPES.DIRECTORY_DELETE,
153
+ dirPath,
154
+ backupPath,
155
+ {
156
+ originalPath: dirPath
157
+ }
158
+ );
159
+
160
+ return operation;
161
+ }
162
+ }
163
+
164
+ module.exports = {
165
+ RollbackRecorder
166
+ };
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Rollback State Manager
3
+ *
4
+ * Handles state persistence, session management, and cleanup operations.
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const crypto = require('crypto');
10
+ const { RollbackOperation } = require('./rollback-operation');
11
+ const { DEFAULT_CLEANUP_AGE } = require('./rollback-types');
12
+ const { RollbackUtils } = require('./rollback-utils');
13
+
14
+ /**
15
+ * Rollback state management
16
+ */
17
+ class RollbackStateManager {
18
+ constructor(backupDir) {
19
+ this.backupDir = backupDir;
20
+ }
21
+
22
+ /**
23
+ * Generate unique session ID
24
+ */
25
+ generateSessionId() {
26
+ return `session_${Date.now()}_${crypto.randomBytes(8).toString('hex')}`;
27
+ }
28
+
29
+ /**
30
+ * Ensure backup directory exists
31
+ */
32
+ ensureBackupDirectory(sessionId) {
33
+ if (!fs.existsSync(this.backupDir)) {
34
+ fs.mkdirSync(this.backupDir, { recursive: true });
35
+ }
36
+
37
+ const sessionDir = path.join(this.backupDir, sessionId);
38
+ RollbackUtils.ensureDirectory(sessionDir);
39
+
40
+ return sessionDir;
41
+ }
42
+
43
+ /**
44
+ * Save rollback state to file
45
+ */
46
+ saveState(sessionId, operations, summary) {
47
+ const sessionDir = path.join(this.backupDir, sessionId);
48
+ const stateFile = path.join(sessionDir, 'rollback-state.json');
49
+
50
+ const state = {
51
+ sessionId,
52
+ operations,
53
+ summary,
54
+ savedAt: new Date().toISOString()
55
+ };
56
+
57
+ fs.writeFileSync(stateFile, JSON.stringify(state, null, 2));
58
+ return stateFile;
59
+ }
60
+
61
+ /**
62
+ * Load rollback state from file
63
+ */
64
+ loadState(sessionId) {
65
+ const sessionDir = path.join(this.backupDir, sessionId);
66
+ const stateFile = path.join(sessionDir, 'rollback-state.json');
67
+
68
+ if (!fs.existsSync(stateFile)) {
69
+ throw new Error(`Rollback state not found: ${sessionId}`);
70
+ }
71
+
72
+ const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
73
+ const operations = state.operations.map(op => Object.assign(new RollbackOperation(), op));
74
+
75
+ return {
76
+ ...state,
77
+ operations
78
+ };
79
+ }
80
+
81
+ /**
82
+ * List available rollback sessions
83
+ */
84
+ listSessions() {
85
+ if (!fs.existsSync(this.backupDir)) {
86
+ return [];
87
+ }
88
+
89
+ const sessions = [];
90
+ const entries = fs.readdirSync(this.backupDir, { withFileTypes: true });
91
+
92
+ for (const entry of entries) {
93
+ if (entry.isDirectory() && entry.name.startsWith('session_')) {
94
+ const sessionDir = path.join(this.backupDir, entry.name);
95
+ const stateFile = path.join(sessionDir, 'rollback-state.json');
96
+
97
+ if (fs.existsSync(stateFile)) {
98
+ try {
99
+ const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
100
+ sessions.push({
101
+ sessionId: state.sessionId,
102
+ operationCount: state.operations.length,
103
+ createdAt: entry.name.replace('session_', '').split('_')[0],
104
+ summary: state.summary
105
+ });
106
+ } catch (error) {
107
+ // Skip invalid sessions
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ return sessions.sort((a, b) => b.createdAt - a.createdAt);
114
+ }
115
+
116
+ /**
117
+ * Cleanup old backup sessions
118
+ */
119
+ cleanup(maxAge = DEFAULT_CLEANUP_AGE) {
120
+ const sessions = this.listSessions();
121
+ const now = Date.now();
122
+ let cleaned = 0;
123
+
124
+ for (const session of sessions) {
125
+ const sessionAge = now - parseInt(session.createdAt);
126
+ if (sessionAge > maxAge) {
127
+ const sessionDir = path.join(this.backupDir, session.sessionId);
128
+ fs.rmSync(sessionDir, { recursive: true, force: true });
129
+ cleaned++;
130
+ }
131
+ }
132
+
133
+ return cleaned;
134
+ }
135
+
136
+ /**
137
+ * Get backup size for a session
138
+ */
139
+ getBackupSize(sessionId) {
140
+ const sessionDir = path.join(this.backupDir, sessionId);
141
+ if (!fs.existsSync(sessionDir)) {
142
+ return 0;
143
+ }
144
+
145
+ return RollbackUtils.getDirectorySize(sessionDir);
146
+ }
147
+
148
+ /**
149
+ * Generate operation summary
150
+ */
151
+ generateSummary(sessionId, operations) {
152
+ const summary = {
153
+ sessionId,
154
+ totalOperations: operations.length,
155
+ executedOperations: operations.filter(op => op.executed).length,
156
+ rollbackOperations: operations.filter(op => op.rollbackExecuted).length,
157
+ byType: {},
158
+ backupDirectory: path.join(this.backupDir, sessionId)
159
+ };
160
+
161
+ // Count operations by type
162
+ for (const operation of operations) {
163
+ if (!summary.byType[operation.type]) {
164
+ summary.byType[operation.type] = 0;
165
+ }
166
+ summary.byType[operation.type]++;
167
+ }
168
+
169
+ return summary;
170
+ }
171
+ }
172
+
173
+ module.exports = {
174
+ RollbackStateManager
175
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Rollback Types and Constants
3
+ *
4
+ * Defines operation types and shared constants for rollback functionality.
5
+ */
6
+
7
+ /**
8
+ * Rollback operation types
9
+ */
10
+ const ROLLBACK_TYPES = {
11
+ FILE_CREATE: 'file_create',
12
+ FILE_UPDATE: 'file_update',
13
+ FILE_DELETE: 'file_delete',
14
+ FILE_MOVE: 'file_move',
15
+ DIRECTORY_CREATE: 'directory_create',
16
+ DIRECTORY_DELETE: 'directory_delete'
17
+ };
18
+
19
+ /**
20
+ * Default backup directory name
21
+ */
22
+ const DEFAULT_BACKUP_DIR = '.refactoring-backups';
23
+
24
+ /**
25
+ * Default cleanup age (7 days in milliseconds)
26
+ */
27
+ const DEFAULT_CLEANUP_AGE = 7 * 24 * 60 * 60 * 1000;
28
+
29
+ module.exports = {
30
+ ROLLBACK_TYPES,
31
+ DEFAULT_BACKUP_DIR,
32
+ DEFAULT_CLEANUP_AGE
33
+ };
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Rollback Utilities
3
+ *
4
+ * Utility functions for backup operations, directory management, and file operations.
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ /**
11
+ * Rollback utility functions
12
+ */
13
+ class RollbackUtils {
14
+ /**
15
+ * Copy directory recursively
16
+ */
17
+ static copyDirectory(src, dest) {
18
+ if (!fs.existsSync(dest)) {
19
+ fs.mkdirSync(dest, { recursive: true });
20
+ }
21
+
22
+ const entries = fs.readdirSync(src, { withFileTypes: true });
23
+
24
+ for (const entry of entries) {
25
+ const srcPath = path.join(src, entry.name);
26
+ const destPath = path.join(dest, entry.name);
27
+
28
+ if (entry.isDirectory()) {
29
+ RollbackUtils.copyDirectory(srcPath, destPath);
30
+ } else {
31
+ fs.copyFileSync(srcPath, destPath);
32
+ }
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Get directory size recursively
38
+ */
39
+ static getDirectorySize(dirPath) {
40
+ let totalSize = 0;
41
+
42
+ try {
43
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
44
+
45
+ for (const entry of entries) {
46
+ const fullPath = path.join(dirPath, entry.name);
47
+
48
+ if (entry.isDirectory()) {
49
+ totalSize += RollbackUtils.getDirectorySize(fullPath);
50
+ } else {
51
+ totalSize += fs.statSync(fullPath).size;
52
+ }
53
+ }
54
+ } catch (error) {
55
+ // Directory might not exist or be inaccessible
56
+ }
57
+
58
+ return totalSize;
59
+ }
60
+
61
+ /**
62
+ * Ensure directory exists
63
+ */
64
+ static ensureDirectory(dirPath) {
65
+ if (!fs.existsSync(dirPath)) {
66
+ fs.mkdirSync(dirPath, { recursive: true });
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Safe file copy with directory creation
72
+ */
73
+ static safeCopyFile(src, dest) {
74
+ const destDir = path.dirname(dest);
75
+ RollbackUtils.ensureDirectory(destDir);
76
+ fs.copyFileSync(src, dest);
77
+ }
78
+
79
+ /**
80
+ * Generate backup path for a file
81
+ */
82
+ static getBackupPath(baseDir, filePath) {
83
+ const relativePath = path.relative(process.cwd(), filePath);
84
+ return path.join(baseDir, relativePath);
85
+ }
86
+
87
+ /**
88
+ * Get file metadata
89
+ */
90
+ static getFileMetadata(filePath) {
91
+ if (!fs.existsSync(filePath)) {
92
+ return {
93
+ size: 0,
94
+ modified: null,
95
+ exists: false
96
+ };
97
+ }
98
+
99
+ const stats = fs.statSync(filePath);
100
+ return {
101
+ size: stats.size,
102
+ modified: stats.mtime.toISOString(),
103
+ exists: true
104
+ };
105
+ }
106
+ }
107
+
108
+ module.exports = {
109
+ RollbackUtils
110
+ };