vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,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
|
+
};
|