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,472 @@
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-file-management');
7
+ const { getProjectRequirementStats } = require('./requirement-statistics');
8
+
9
+ /**
10
+ * Current requirement management operations
11
+ */
12
+
13
+ // Shared function to move to next requirement (used by both IPC and auto mode)
14
+ let isMovingToNextRequirement = false; // Prevent duplicate calls
15
+ let lastMoveTime = 0; // Track when last move happened
16
+
17
+ /**
18
+ * Get current requirement being worked on
19
+ * @param {string} repoPath - Repository path
20
+ * @returns {Promise<string>} Current requirement text
21
+ */
22
+ async function getCurrentRequirement(repoPath) {
23
+ try {
24
+ const rPath = repoPath || process.cwd();
25
+ // Get the requirements file path (create if doesn't exist)
26
+ const { getOrCreateRequirementsFilePath } = require('./requirement-file-management');
27
+ const requirementsFilePath = await getOrCreateRequirementsFilePath(rPath);
28
+
29
+ // Read the requirements file content
30
+ const content = await fs.readFile(requirementsFilePath, 'utf8');
31
+ const lines = content.split('\n');
32
+
33
+ // Look for the current in progress requirement
34
+ for (let i = 0; i < lines.length; i++) {
35
+ if (lines[i].includes('## 🔨 Current In Progress Requirement')) {
36
+ // Look for the next requirement line
37
+ for (let j = i + 1; j < lines.length; j++) {
38
+ if (lines[j].trim().startsWith('- ')) {
39
+ let requirementText = lines[j].substring(2).trim();
40
+
41
+ // Extract the requirement title (remove FAILED prefix if present)
42
+ if (requirementText.startsWith('FAILED ')) {
43
+ const failedMatch = requirementText.match(/^FAILED \d+ TIMES?: (.+)$/);
44
+ if (failedMatch) {
45
+ requirementText = failedMatch[1];
46
+ }
47
+ }
48
+
49
+ // Extract just the title part (before the colon)
50
+ const colonIndex = requirementText.indexOf(':');
51
+ if (colonIndex !== -1) {
52
+ requirementText = requirementText.substring(0, colonIndex).trim();
53
+ }
54
+
55
+ // Remove markdown formatting
56
+ requirementText = requirementText.replace(/\*\*/g, '');
57
+
58
+ return `Working on: ${requirementText}`;
59
+ }
60
+ }
61
+ break;
62
+ }
63
+ }
64
+
65
+ return DEFAULT_INSTRUCTION_TEXT;
66
+ } catch (error) {
67
+ logger.error('❌ Error getting current requirement:', error);
68
+ return DEFAULT_INSTRUCTION_TEXT;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Check if the current requirement status is DONE
74
+ * @param {string} repoPath - Repository path
75
+ * @returns {Promise<boolean>} True if status is DONE
76
+ */
77
+ async function isCurrentRequirementDone(repoPath) {
78
+ try {
79
+ const rPath = repoPath || process.cwd();
80
+ const hostname = os.hostname();
81
+
82
+ // Use shared logic to find the file
83
+ const requirementsFilePath = await getRequirementsPath(rPath, hostname);
84
+
85
+ if (!requirementsFilePath || !(await fs.pathExists(requirementsFilePath))) {
86
+ return false;
87
+ }
88
+
89
+ // Read the requirements file content
90
+ const content = await fs.readFile(requirementsFilePath, 'utf8');
91
+ const lines = content.split('\n');
92
+
93
+ // First pass: check if "Current Status" section contains DONE
94
+ let inStatusSection = false;
95
+ for (let i = 0; i < lines.length; i++) {
96
+ const line = lines[i].trim();
97
+
98
+ if (line.includes('## 🚦 Current Status')) {
99
+ inStatusSection = true;
100
+ continue;
101
+ }
102
+
103
+ // If we're in the status section
104
+ if (inStatusSection) {
105
+ // Hit another section header, exit
106
+ if (line.startsWith('##')) {
107
+ break;
108
+ }
109
+
110
+ // Check if this line contains DONE (case-insensitive, exact word match)
111
+ if (line) {
112
+ const upperLine = line.toUpperCase();
113
+ // Match DONE as a standalone word or at the start of the line
114
+ if (upperLine === 'DONE' || upperLine.startsWith('DONE:') || upperLine.startsWith('DONE ')) {
115
+ logger.log('✅ DONE status detected in Current Status section:', line);
116
+ return true;
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ // Second pass: check if "Current In Progress Requirement" section is empty
123
+ let inCurrentSection = false;
124
+ let foundRequirement = false;
125
+ for (let i = 0; i < lines.length; i++) {
126
+ const line = lines[i].trim();
127
+
128
+ if (line.includes('## 🔨 Current In Progress Requirement')) {
129
+ inCurrentSection = true;
130
+ continue;
131
+ }
132
+
133
+ // If we're in the current section and hit another section header, exit
134
+ if (inCurrentSection && line.startsWith('##')) {
135
+ // If section was empty (no requirement found), it's done
136
+ if (!foundRequirement) {
137
+ logger.log('✅ Current requirement section is empty - considering as done');
138
+ return true;
139
+ }
140
+ break;
141
+ }
142
+
143
+ // Track if we found a requirement in the current section
144
+ if (inCurrentSection && line.startsWith('- ')) {
145
+ foundRequirement = true;
146
+ }
147
+ }
148
+
149
+ // If we found a requirement but no DONE status, it's not done yet
150
+ if (foundRequirement) {
151
+ logger.log('❌ Found requirement but status is not DONE');
152
+ return false;
153
+ }
154
+
155
+ // Default: not done
156
+ return false;
157
+ } catch (error) {
158
+ logger.error('❌ Error checking requirement status:', error);
159
+ return false;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Move to next requirement
165
+ * @param {string} repoPath - Repository path
166
+ * @returns {Promise<Object>} Result with success status and next requirement info
167
+ */
168
+ async function moveToNextRequirement(repoPath) {
169
+ const now = Date.now();
170
+ const rPath = repoPath || process.cwd();
171
+
172
+ // Prevent duplicate calls within 5 seconds
173
+ if (isMovingToNextRequirement || (now - lastMoveTime < 5000)) {
174
+ logger.log('⚠️ moveToNextRequirement already in progress or called too recently, skipping duplicate call');
175
+ return { success: false, error: 'Already moving to next requirement or called too recently' };
176
+ }
177
+
178
+ isMovingToNextRequirement = true;
179
+ lastMoveTime = now;
180
+
181
+ try {
182
+ logger.log('🔄 Moving to next requirement');
183
+
184
+ const hostname = os.hostname();
185
+ // Use shared logic
186
+ const requirementsFilePath = await getRequirementsPath(rPath, hostname);
187
+
188
+ if (!requirementsFilePath || !(await fs.pathExists(requirementsFilePath))) {
189
+ return { success: false, error: 'Requirements file not found' };
190
+ }
191
+
192
+ // Get auto mode config to check skipDisabled setting
193
+ let skipDisabled = false;
194
+ try {
195
+ const { getAutoConfig } = require('../../../cli/src/utils/config');
196
+ const autoConfig = await getAutoConfig();
197
+ skipDisabled = autoConfig.skipDisabled || false;
198
+ } catch (error) {
199
+ // If CLI config is not available, default to false
200
+ logger.log('⚠️ Could not get auto config, using skipDisabled = false');
201
+ }
202
+
203
+ // Read current content
204
+ const content = await fs.readFile(requirementsFilePath, 'utf8');
205
+ const lines = content.split('\n');
206
+
207
+ // Extract current requirement and remove from "Current In Progress"
208
+ let currentRequirement = null;
209
+ let inCurrentSection = false;
210
+ for (let i = 0; i < lines.length; i++) {
211
+ if (lines[i].includes('## 🔨 Current In Progress Requirement')) {
212
+ inCurrentSection = true;
213
+ continue;
214
+ }
215
+ if (inCurrentSection && lines[i].trim().startsWith('- ')) {
216
+ currentRequirement = lines[i].substring(2).trim();
217
+ break;
218
+ }
219
+ if (inCurrentSection && lines[i].trim().startsWith('##')) {
220
+ break;
221
+ }
222
+ }
223
+
224
+ // Get first non-disabled requirement from "Requirements not yet completed"
225
+ let nextRequirement = null;
226
+ let inNotYetCompleted = false;
227
+ for (let i = 0; i < lines.length; i++) {
228
+ if (lines[i].includes('## ⏳ Requirements not yet completed')) {
229
+ inNotYetCompleted = true;
230
+ continue;
231
+ }
232
+ if (inNotYetCompleted && lines[i].trim().startsWith('- ')) {
233
+ const requirementText = lines[i].substring(2).trim();
234
+
235
+ // Check if requirement is disabled (starts with 'DISABLED:')
236
+ const isDisabled = requirementText.startsWith('DISABLED:');
237
+
238
+ // Skip disabled requirements if skipDisabled is enabled
239
+ if (skipDisabled && isDisabled) {
240
+ logger.log(`⏭️ Skipping disabled requirement: ${requirementText}`);
241
+ continue;
242
+ }
243
+
244
+ nextRequirement = requirementText;
245
+ break;
246
+ }
247
+ if (inNotYetCompleted && lines[i].trim().startsWith('##')) {
248
+ break;
249
+ }
250
+ }
251
+
252
+ if (!nextRequirement) {
253
+ return { success: false, error: 'No more requirements to process' };
254
+ }
255
+
256
+ // Count requirements in "not yet completed" (before moving)
257
+ let totalRequirementsNotYetCompleted = 0;
258
+ inNotYetCompleted = false;
259
+ for (const line of lines) {
260
+ if (line.includes('## ⏳ Requirements not yet completed')) {
261
+ inNotYetCompleted = true;
262
+ continue;
263
+ }
264
+ if (inNotYetCompleted && line.trim().startsWith('##')) {
265
+ break;
266
+ }
267
+ if (inNotYetCompleted && line.trim().startsWith('- ')) {
268
+ const requirementText = line.substring(2).trim();
269
+ const isDisabled = requirementText.startsWith('DISABLED:');
270
+
271
+ // Don't count disabled requirements if skipDisabled is enabled
272
+ if (!skipDisabled || !isDisabled) {
273
+ totalRequirementsNotYetCompleted++;
274
+ }
275
+ }
276
+ }
277
+
278
+ // Count completed requirements in "Verified by AI" section
279
+ let completedCount = 0;
280
+ let inVerifiedSection = false;
281
+ for (const line of lines) {
282
+ if (line.includes('## ✅ Verified by AI screenshot')) {
283
+ inVerifiedSection = true;
284
+ continue;
285
+ }
286
+ if (inVerifiedSection && line.trim().startsWith('##')) {
287
+ break;
288
+ }
289
+ if (inVerifiedSection && line.trim().startsWith('- ')) {
290
+ completedCount++;
291
+ }
292
+ }
293
+
294
+ // Update the file: move current to "Verified by AI", move next to "Current In Progress"
295
+ const updatedLines = [];
296
+ inCurrentSection = false;
297
+ inNotYetCompleted = false;
298
+ inVerifiedSection = false;
299
+ let addedCurrentToVerified = false;
300
+ let addedNextToCurrent = false;
301
+ let removedNextFromNotYetCompleted = false;
302
+
303
+ for (let i = 0; i < lines.length; i++) {
304
+ const line = lines[i];
305
+
306
+ // Handle "Current In Progress Requirement" section
307
+ if (line.includes('## 🔨 Current In Progress Requirement')) {
308
+ inCurrentSection = true;
309
+ updatedLines.push(line);
310
+ updatedLines.push('');
311
+ updatedLines.push(`- ${nextRequirement}`);
312
+ updatedLines.push('');
313
+ addedNextToCurrent = true;
314
+ continue;
315
+ }
316
+
317
+ // Skip old current requirement and any text in the current section
318
+ if (inCurrentSection && !line.trim().startsWith('##')) {
319
+ // Skip lines until we hit the next section header
320
+ continue;
321
+ }
322
+ if (inCurrentSection && line.trim().startsWith('##')) {
323
+ inCurrentSection = false;
324
+ // Don't continue - we want to process this section header
325
+ }
326
+
327
+ // Handle "Current Status" section
328
+ if (line.includes('## 🚦 Current Status')) {
329
+ updatedLines.push(line);
330
+ updatedLines.push('');
331
+ updatedLines.push('PREPARE');
332
+ updatedLines.push('');
333
+
334
+ // Skip all old status lines until we hit the next section
335
+ let j = i + 1;
336
+ while (j < lines.length && !lines[j].trim().startsWith('##')) {
337
+ j++;
338
+ }
339
+ i = j - 1; // Set i to the line before the next section (loop will increment)
340
+ continue;
341
+ }
342
+
343
+ // Handle "Requirements not yet completed" section
344
+ if (line.includes('## ⏳ Requirements not yet completed')) {
345
+ inNotYetCompleted = true;
346
+ updatedLines.push(line);
347
+ continue;
348
+ }
349
+
350
+ // Remove the next requirement from "not yet completed"
351
+ if (inNotYetCompleted && line.trim().startsWith('- ') && !removedNextFromNotYetCompleted) {
352
+ const requirementText = line.substring(2).trim();
353
+ if (requirementText === nextRequirement) {
354
+ inNotYetCompleted = false;
355
+ removedNextFromNotYetCompleted = true;
356
+ continue; // Skip this line
357
+ }
358
+ }
359
+
360
+ // Handle "Verified by AI" section
361
+ if (line.includes('## ✅ Verified by AI screenshot')) {
362
+ inNotYetCompleted = false;
363
+ if (currentRequirement && !addedCurrentToVerified) {
364
+ // Check if this requirement is already in the verified section
365
+ const requirementAlreadyExists = updatedLines.some(existingLine =>
366
+ existingLine.includes(currentRequirement) && existingLine.trim().startsWith('- ')
367
+ );
368
+
369
+ if (!requirementAlreadyExists) {
370
+ updatedLines.push(line);
371
+ updatedLines.push('');
372
+ // Don't add date prefix - just add the requirement as-is to avoid nesting
373
+ updatedLines.push(`- ${currentRequirement}`);
374
+ updatedLines.push('');
375
+ addedCurrentToVerified = true;
376
+ continue;
377
+ } else {
378
+ logger.log(`⚠️ Requirement "${currentRequirement}" already exists in verified section, skipping duplicate`);
379
+ addedCurrentToVerified = true;
380
+ }
381
+ }
382
+ updatedLines.push(line);
383
+ continue;
384
+ }
385
+
386
+ updatedLines.push(line);
387
+ }
388
+
389
+ // Write updated content
390
+ await fs.writeFile(requirementsFilePath, updatedLines.join('\n'), 'utf8');
391
+
392
+ // Calculate current number:
393
+ // - We just completed 1 requirement (moved to "Verified by AI")
394
+ // - completedCount already includes previously completed requirements
395
+ // - So current number = completedCount + 1 (the one we just completed) + 1 (the new current one)
396
+ // - Which simplifies to: completedCount + 2
397
+ const currentNumber = completedCount + 2; // +1 for the one we just completed, +1 for the new current one we're starting
398
+
399
+ // Total requirements = completedCount + 1 (current) + totalRequirementsNotYetCompleted
400
+ const totalRequirements = completedCount + 1 + totalRequirementsNotYetCompleted;
401
+
402
+ logger.log(`✅ Moved to next requirement: ${nextRequirement}`);
403
+ logger.log(`📊 Progress: ${currentNumber}/${totalRequirements} (completed: ${completedCount + 1}, remaining: ${totalRequirementsNotYetCompleted - 1})`);
404
+ logger.log(`📝 Moved to requirement: ${nextRequirement}`);
405
+
406
+ return {
407
+ success: true,
408
+ nextRequirement: nextRequirement,
409
+ currentNumber: currentNumber,
410
+ totalRemaining: totalRequirementsNotYetCompleted - 1
411
+ };
412
+ } catch (error) {
413
+ logger.error('❌ Error moving to next requirement:', error);
414
+ return { success: false, error: error.message };
415
+ } finally {
416
+ // Always reset the flag, even if there was an error
417
+ isMovingToNextRequirement = false;
418
+ }
419
+ }
420
+
421
+ /**
422
+ * Get current requirement name only (without "Working on:" prefix)
423
+ * @param {string} repoPath - Repository path
424
+ * @returns {Promise<string|null>} Current requirement name or null
425
+ */
426
+ async function getCurrentRequirementName(repoPath) {
427
+ try {
428
+ const rPath = repoPath || process.cwd();
429
+ const hostname = os.hostname();
430
+
431
+ const requirementsFilePath = await getRequirementsPath(rPath, hostname);
432
+
433
+ if (!requirementsFilePath || !(await fs.pathExists(requirementsFilePath))) {
434
+ return null;
435
+ }
436
+
437
+ // Read the requirements file content
438
+ const content = await fs.readFile(requirementsFilePath, 'utf8');
439
+ const lines = content.split('\n');
440
+
441
+ // Look for the current in progress requirement
442
+ for (let i = 0; i < lines.length; i++) {
443
+ if (lines[i].includes('## 🔨 Current In Progress Requirement')) {
444
+ // Look for the next requirement line
445
+ for (let j = i + 1; j < lines.length; j++) {
446
+ if (lines[j].trim().startsWith('- ')) {
447
+ let requirementText = lines[j].substring(2).trim();
448
+
449
+ // Remove markdown formatting (bold **)
450
+ requirementText = requirementText.replace(/\*\*/g, '');
451
+
452
+ // Return the full requirement text without any prefix
453
+ return requirementText;
454
+ }
455
+ }
456
+ break;
457
+ }
458
+ }
459
+
460
+ return null;
461
+ } catch (error) {
462
+ logger.error('❌ Error getting current requirement name:', error);
463
+ return null;
464
+ }
465
+ }
466
+
467
+ module.exports = {
468
+ getCurrentRequirement,
469
+ isCurrentRequirementDone,
470
+ moveToNextRequirement,
471
+ getCurrentRequirementName
472
+ };