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,392 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const os = require('os');
4
+ const { getRequirementsPath } = require('../repo-helpers.cjs');
5
+ const { logger } = require('../logger.cjs');
6
+ const { DEFAULT_INSTRUCTION_TEXT } = require('./requirement-parser.js');
7
+
8
+ /**
9
+ * Requirement File Operations
10
+ * Handles file-level operations for requirements management
11
+ */
12
+
13
+ /**
14
+ * Get the requirements file path for the current hostname
15
+ * @param {string} repoPath - Repository path (optional)
16
+ * @returns {string} Requirements file path
17
+ */
18
+ function getRequirementsFilePath(repoPath = null) {
19
+ if (repoPath) {
20
+ const hostname = os.hostname();
21
+ return path.join(repoPath, '.vibecodingmachine', `REQUIREMENTS-${hostname}.md`);
22
+ }
23
+
24
+ return getRequirementsPath();
25
+ }
26
+
27
+ /**
28
+ * Check if requirements file exists
29
+ * @param {string} repoPath - Repository path (optional)
30
+ * @returns {boolean} Whether the file exists
31
+ */
32
+ function requirementsFileExists(repoPath = null) {
33
+ const reqPath = getRequirementsFilePath(repoPath);
34
+ return fs.pathExistsSync(reqPath);
35
+ }
36
+
37
+ /**
38
+ * Create requirements file with default structure
39
+ * @param {string} repoPath - Repository path
40
+ * @returns {Promise<boolean>} Success status
41
+ */
42
+ async function createRequirementsFile(repoPath) {
43
+ try {
44
+ const reqPath = getRequirementsFilePath(repoPath);
45
+ const vibecodingmachineDir = path.dirname(reqPath);
46
+
47
+ // Ensure .vibecodingmachine directory exists
48
+ await fs.ensureDir(vibecodingmachineDir);
49
+
50
+ // Check if file already exists
51
+ if (await fs.pathExists(reqPath)) {
52
+ logger.log(`Requirements file already exists: ${reqPath}`);
53
+ return true;
54
+ }
55
+
56
+ // Create default content
57
+ const defaultContent = `# Vibe Coding Machine Requirements
58
+
59
+ ## 🚦 Current Status
60
+
61
+ PREPARE
62
+
63
+ ## 🔨 Current In Progress Requirement
64
+
65
+ *No requirement currently in progress*
66
+
67
+ ## ⏳ Requirements not yet completed
68
+
69
+ - Add your first requirement here
70
+
71
+ ## ✅ Verified by AI screenshot. Needs Human to Verify and move to CHANGELOG
72
+
73
+ *No requirements verified yet*
74
+
75
+ ---
76
+
77
+ ## Instructions
78
+
79
+ ${DEFAULT_INSTRUCTION_TEXT}
80
+
81
+ ## Status Progression
82
+
83
+ Work through these stages in order:
84
+ 1. **PREPARE** - Take screenshots, review code, understand requirements
85
+ 2. **CREATE** - Implement the actual code/functionality
86
+ 3. **CLEAN UP** - Clean up code, remove duplicates, apply best practices
87
+ 4. **VERIFY** - Run automation, take screenshots to verify functionality
88
+ 5. **DONE** - Everything is working perfectly, requirement completed
89
+
90
+ **CRITICAL**: You MUST update the status at each stage and SAVE the file. The VibeCodingMachine app depends on this for autonomous operation.
91
+ `;
92
+
93
+ await fs.writeFile(reqPath, defaultContent, 'utf-8');
94
+ logger.log(`✅ Created requirements file: ${reqPath}`);
95
+ return true;
96
+
97
+ } catch (error) {
98
+ logger.error(`Error creating requirements file: ${error.message}`);
99
+ return false;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Read requirements file content
105
+ * @param {string} repoPath - Repository path (optional)
106
+ * @returns {Promise<string|null>} File content or null if error
107
+ */
108
+ async function readRequirementsFile(repoPath = null) {
109
+ try {
110
+ const reqPath = getRequirementsFilePath(repoPath);
111
+
112
+ if (!(await fs.pathExists(reqPath))) {
113
+ logger.warn(`Requirements file does not exist: ${reqPath}`);
114
+ return null;
115
+ }
116
+
117
+ const content = await fs.readFile(reqPath, 'utf-8');
118
+ return content;
119
+
120
+ } catch (error) {
121
+ logger.error(`Error reading requirements file: ${error.message}`);
122
+ return null;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Write requirements file content
128
+ * @param {string} content - Content to write
129
+ * @param {string} repoPath - Repository path (optional)
130
+ * @returns {Promise<boolean>} Success status
131
+ */
132
+ async function writeRequirementsFile(content, repoPath = null) {
133
+ try {
134
+ const reqPath = getRequirementsFilePath(repoPath);
135
+ const vibecodingmachineDir = path.dirname(reqPath);
136
+
137
+ // Ensure directory exists
138
+ await fs.ensureDir(vibecodingmachineDir);
139
+
140
+ await fs.writeFile(reqPath, content, 'utf-8');
141
+ logger.log(`✅ Wrote requirements file: ${reqPath}`);
142
+ return true;
143
+
144
+ } catch (error) {
145
+ logger.error(`Error writing requirements file: ${error.message}`);
146
+ return false;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Backup requirements file
152
+ * @param {string} repoPath - Repository path (optional)
153
+ * @param {string} suffix - Backup suffix (default: .backup)
154
+ * @returns {Promise<string|null>} Backup file path or null if error
155
+ */
156
+ async function backupRequirementsFile(repoPath = null, suffix = '.backup') {
157
+ try {
158
+ const reqPath = getRequirementsFilePath(repoPath);
159
+ const backupPath = reqPath + suffix;
160
+
161
+ if (!(await fs.pathExists(reqPath))) {
162
+ logger.warn(`Cannot backup non-existent requirements file: ${reqPath}`);
163
+ return null;
164
+ }
165
+
166
+ await fs.copy(reqPath, backupPath);
167
+ logger.log(`✅ Backed up requirements file to: ${backupPath}`);
168
+ return backupPath;
169
+
170
+ } catch (error) {
171
+ logger.error(`Error backing up requirements file: ${error.message}`);
172
+ return null;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Get requirements file statistics
178
+ * @param {string} repoPath - Repository path (optional)
179
+ * @returns {Promise<Object>} File statistics
180
+ */
181
+ async function getRequirementsFileStats(repoPath = null) {
182
+ try {
183
+ const reqPath = getRequirementsFilePath(repoPath);
184
+
185
+ if (!(await fs.pathExists(reqPath))) {
186
+ return {
187
+ exists: false,
188
+ path: reqPath,
189
+ size: 0,
190
+ lines: 0,
191
+ lastModified: null,
192
+ created: null
193
+ };
194
+ }
195
+
196
+ const stats = await fs.stat(reqPath);
197
+ const content = await fs.readFile(reqPath, 'utf-8');
198
+
199
+ return {
200
+ exists: true,
201
+ path: reqPath,
202
+ size: stats.size,
203
+ lines: content.split('\n').length,
204
+ lastModified: stats.mtime,
205
+ created: stats.birthtime || stats.ctime
206
+ };
207
+
208
+ } catch (error) {
209
+ logger.error(`Error getting requirements file stats: ${error.message}`);
210
+ return {
211
+ exists: false,
212
+ path: getRequirementsFilePath(repoPath),
213
+ size: 0,
214
+ lines: 0,
215
+ lastModified: null,
216
+ created: null,
217
+ error: error.message
218
+ };
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Validate requirements file format
224
+ * @param {string} repoPath - Repository path (optional)
225
+ * @returns {Promise<Object>} Validation result
226
+ */
227
+ async function validateRequirementsFile(repoPath = null) {
228
+ try {
229
+ const content = await readRequirementsFile(repoPath);
230
+
231
+ if (!content) {
232
+ return {
233
+ isValid: false,
234
+ errors: ['Requirements file does not exist or cannot be read'],
235
+ warnings: []
236
+ };
237
+ }
238
+
239
+ const result = {
240
+ isValid: true,
241
+ errors: [],
242
+ warnings: []
243
+ };
244
+
245
+ const lines = content.split('\n');
246
+
247
+ // Check for required sections
248
+ const requiredSections = [
249
+ '## 🚦 Current Status',
250
+ '## 🔨 Current In Progress Requirement',
251
+ '## ⏳ Requirements not yet completed',
252
+ '## ✅ Verified by AI screenshot. Needs Human to Verify and move to CHANGELOG'
253
+ ];
254
+
255
+ for (const section of requiredSections) {
256
+ if (!content.includes(section)) {
257
+ result.isValid = false;
258
+ result.errors.push(`Missing required section: ${section}`);
259
+ }
260
+ }
261
+
262
+ // Check for status section content
263
+ if (content.includes('## 🚦 Current Status')) {
264
+ const statusMatch = content.match(/## 🚦 Current Status\s*\n\s*\*\*([A-Z_]+)\*\*/);
265
+ if (!statusMatch) {
266
+ result.isValid = false;
267
+ result.errors.push('Current Status section exists but no status value found');
268
+ }
269
+ }
270
+
271
+ // Check file size
272
+ if (content.length > 100000) { // 100KB
273
+ result.warnings.push('Requirements file is very large, consider archiving old requirements');
274
+ }
275
+
276
+ // Check for common formatting issues
277
+ if (content.includes(' ')) {
278
+ result.warnings.push('File contains double spaces');
279
+ }
280
+
281
+ if (content.includes('\t')) {
282
+ result.warnings.push('File contains tabs (should use spaces)');
283
+ }
284
+
285
+ // Check line endings
286
+ if (content.includes('\r\n')) {
287
+ result.warnings.push('File uses Windows line endings (CRLF)');
288
+ }
289
+
290
+ return result;
291
+
292
+ } catch (error) {
293
+ return {
294
+ isValid: false,
295
+ errors: [`Error validating requirements file: ${error.message}`],
296
+ warnings: []
297
+ };
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Get all requirements files in repository
303
+ * @param {string} repoPath - Repository path
304
+ * @returns {Promise<Array>} Array of requirements file info
305
+ */
306
+ async function getAllRequirementsFiles(repoPath) {
307
+ try {
308
+ const vibecodingmachineDir = path.join(repoPath, '.vibecodingmachine');
309
+
310
+ if (!(await fs.pathExists(vibecodingmachineDir))) {
311
+ return [];
312
+ }
313
+
314
+ const files = await fs.readdir(vibecodingmachineDir);
315
+ const requirementsFiles = [];
316
+
317
+ for (const file of files) {
318
+ if (file.startsWith('REQUIREMENTS-') && file.endsWith('.md')) {
319
+ const filePath = path.join(vibecodingmachineDir, file);
320
+ const stats = await fs.stat(filePath);
321
+ const hostname = file.replace('REQUIREMENTS-', '').replace('.md', '');
322
+
323
+ requirementsFiles.push({
324
+ path: filePath,
325
+ filename: file,
326
+ hostname,
327
+ size: stats.size,
328
+ lastModified: stats.mtime,
329
+ isCurrent: hostname === os.hostname()
330
+ });
331
+ }
332
+ }
333
+
334
+ return requirementsFiles.sort((a, b) => b.lastModified - a.lastModified);
335
+
336
+ } catch (error) {
337
+ logger.error(`Error getting all requirements files: ${error.message}`);
338
+ return [];
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Clean up old backup files
344
+ * @param {string} repoPath - Repository path (optional)
345
+ * @param {number} keepCount - Number of backups to keep (default: 5)
346
+ * @returns {Promise<number>} Number of files cleaned up
347
+ */
348
+ async function cleanupBackupFiles(repoPath = null, keepCount = 5) {
349
+ try {
350
+ const reqPath = getRequirementsFilePath(repoPath);
351
+ const dir = path.dirname(reqPath);
352
+ const baseName = path.basename(reqPath);
353
+
354
+ const files = await fs.readdir(dir);
355
+ const backupFiles = files
356
+ .filter(file => file.startsWith(baseName) && file.includes('.backup'))
357
+ .map(file => ({
358
+ name: file,
359
+ path: path.join(dir, file),
360
+ mtime: fs.statSync(path.join(dir, file)).mtime
361
+ }))
362
+ .sort((a, b) => b.mtime - a.mtime);
363
+
364
+ let cleanedCount = 0;
365
+
366
+ // Keep the most recent backups, delete older ones
367
+ for (let i = keepCount; i < backupFiles.length; i++) {
368
+ await fs.remove(backupFiles[i].path);
369
+ cleanedCount++;
370
+ logger.log(`🗑️ Cleaned up old backup: ${backupFiles[i].name}`);
371
+ }
372
+
373
+ return cleanedCount;
374
+
375
+ } catch (error) {
376
+ logger.error(`Error cleaning up backup files: ${error.message}`);
377
+ return 0;
378
+ }
379
+ }
380
+
381
+ module.exports = {
382
+ getRequirementsFilePath,
383
+ requirementsFileExists,
384
+ createRequirementsFile,
385
+ readRequirementsFile,
386
+ writeRequirementsFile,
387
+ backupRequirementsFile,
388
+ getRequirementsFileStats,
389
+ validateRequirementsFile,
390
+ getAllRequirementsFiles,
391
+ cleanupBackupFiles
392
+ };