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,414 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const {
|
|
4
|
+
addTryAgainPrefix,
|
|
5
|
+
parseRequirementLine,
|
|
6
|
+
findRequirementBlock,
|
|
7
|
+
findAllRequirementsInSection
|
|
8
|
+
} = require('./requirement-parser.js');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Requirement Movement Operations
|
|
12
|
+
* Handles moving requirements between different sections
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Promote requirement from TO VERIFY section to CHANGELOG.md
|
|
17
|
+
* @param {string} reqPath - Path to requirements file
|
|
18
|
+
* @param {string} requirementTitle - Title of requirement to move
|
|
19
|
+
* @returns {Promise<boolean>} Success status
|
|
20
|
+
*/
|
|
21
|
+
async function promoteToVerified(reqPath, requirementTitle) {
|
|
22
|
+
try {
|
|
23
|
+
const content = await fs.readFile(reqPath, 'utf-8');
|
|
24
|
+
const lines = content.split('\n');
|
|
25
|
+
|
|
26
|
+
// Find the requirement in TO VERIFY section
|
|
27
|
+
const requirement = findRequirementBlock(lines, requirementTitle, 'verify');
|
|
28
|
+
|
|
29
|
+
if (!requirement) {
|
|
30
|
+
console.error(`Requirement "${requirementTitle}" not found in TO VERIFY section`);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Remove requirement from TO VERIFY section
|
|
35
|
+
lines.splice(requirement.startIndex, requirement.endIndex - requirement.startIndex);
|
|
36
|
+
|
|
37
|
+
// Add to CHANGELOG.md
|
|
38
|
+
const allnightDir = path.dirname(reqPath);
|
|
39
|
+
const repoRoot = path.dirname(allnightDir);
|
|
40
|
+
const changelogPath = path.join(repoRoot, 'CHANGELOG.md');
|
|
41
|
+
const timestamp = new Date().toISOString().split('T')[0];
|
|
42
|
+
const changelogEntry = `- ${requirement.title} (${timestamp})`;
|
|
43
|
+
|
|
44
|
+
let changelogContent = '';
|
|
45
|
+
if (await fs.pathExists(changelogPath)) {
|
|
46
|
+
changelogContent = await fs.readFile(changelogPath, 'utf-8');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Add entry to CHANGELOG.md (at the top, after any header)
|
|
50
|
+
const changelogLines = changelogContent.split('\n');
|
|
51
|
+
let insertIndex = 0;
|
|
52
|
+
|
|
53
|
+
// Skip header lines (lines starting with #)
|
|
54
|
+
for (let i = 0; i < changelogLines.length; i++) {
|
|
55
|
+
if (changelogLines[i].startsWith('#')) {
|
|
56
|
+
insertIndex = i + 1;
|
|
57
|
+
} else {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
changelogLines.splice(insertIndex, 0, changelogEntry);
|
|
63
|
+
await fs.writeFile(changelogPath, changelogLines.join('\n'), 'utf-8');
|
|
64
|
+
|
|
65
|
+
// Write updated requirements file
|
|
66
|
+
await fs.writeFile(reqPath, lines.join('\n'), 'utf-8');
|
|
67
|
+
|
|
68
|
+
console.log(`✅ Promoted "${requirementTitle}" to CHANGELOG.md`);
|
|
69
|
+
return true;
|
|
70
|
+
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(`Error promoting requirement to verified: ${error.message}`);
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Demote requirement from CHANGELOG.md back to TODO section
|
|
79
|
+
* @param {string} reqPath - Path to requirements file
|
|
80
|
+
* @param {string} requirementTitle - Title of requirement to move
|
|
81
|
+
* @returns {Promise<boolean>} Success status
|
|
82
|
+
*/
|
|
83
|
+
async function demoteFromVerifiedToTodo(reqPath, requirementTitle) {
|
|
84
|
+
try {
|
|
85
|
+
// CHANGELOG.md should be at repository root, not in .vibecodingmachine directory
|
|
86
|
+
const allnightDir = path.dirname(reqPath); // .vibecodingmachine directory
|
|
87
|
+
const repoRoot = path.dirname(allnightDir); // repository root (one level up)
|
|
88
|
+
const changelogPath = path.join(repoRoot, 'CHANGELOG.md');
|
|
89
|
+
|
|
90
|
+
if (!(await fs.pathExists(changelogPath))) {
|
|
91
|
+
console.error('CHANGELOG.md not found');
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let changelogContent = await fs.readFile(changelogPath, 'utf-8');
|
|
96
|
+
const changelogLines = changelogContent.split('\n');
|
|
97
|
+
const updatedChangelogLines = [];
|
|
98
|
+
let requirementToMove = null;
|
|
99
|
+
|
|
100
|
+
for (const line of changelogLines) {
|
|
101
|
+
if (line.startsWith('- ')) {
|
|
102
|
+
const lineText = parseRequirementLine(line);
|
|
103
|
+
// Extract title part (before timestamp in parentheses)
|
|
104
|
+
const titleMatch = lineText.match(/^(.+?)\s*\([\d-]+\)$/);
|
|
105
|
+
const lineTitle = titleMatch ? titleMatch[1] : lineText;
|
|
106
|
+
|
|
107
|
+
// Check if this line matches the requirement title
|
|
108
|
+
if (lineTitle === requirementTitle || lineTitle.includes(requirementTitle) || requirementTitle.includes(lineTitle)) {
|
|
109
|
+
requirementToMove = lineTitle;
|
|
110
|
+
// Skip this line (don't add to updated changelog)
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
updatedChangelogLines.push(line);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!requirementToMove) {
|
|
118
|
+
console.error(`Requirement "${requirementTitle}" not found in CHANGELOG.md`);
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
await fs.writeFile(changelogPath, updatedChangelogLines.join('\n'), 'utf-8');
|
|
123
|
+
|
|
124
|
+
// Add back to requirements file TODO section
|
|
125
|
+
const content = await fs.readFile(reqPath, 'utf-8');
|
|
126
|
+
const lines = content.split('\n');
|
|
127
|
+
const updatedLines = [];
|
|
128
|
+
let foundTodoSection = false;
|
|
129
|
+
|
|
130
|
+
for (let i = 0; i < lines.length; i++) {
|
|
131
|
+
const line = lines[i];
|
|
132
|
+
|
|
133
|
+
if (line.includes('## ⏳ Requirements not yet completed')) {
|
|
134
|
+
foundTodoSection = true;
|
|
135
|
+
updatedLines.push(line);
|
|
136
|
+
const requirementText = addTryAgainPrefix(requirementToMove);
|
|
137
|
+
updatedLines.push(`- ${requirementText}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
updatedLines.push(line);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// If TODO section not found, create it
|
|
145
|
+
if (!foundTodoSection) {
|
|
146
|
+
updatedLines.push('## ⏳ Requirements not yet completed');
|
|
147
|
+
const requirementText = addTryAgainPrefix(requirementToMove);
|
|
148
|
+
updatedLines.push(`- ${requirementText}`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
await fs.writeFile(reqPath, updatedLines.join('\n'), 'utf-8');
|
|
152
|
+
|
|
153
|
+
console.log(`✅ Demoted "${requirementTitle}" from CHANGELOG.md to TODO`);
|
|
154
|
+
return true;
|
|
155
|
+
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.error(`Error demoting requirement from verified: ${error.message}`);
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Promote requirement from TODO section to TO VERIFY section
|
|
164
|
+
* @param {string} reqPath - Path to requirements file
|
|
165
|
+
* @param {string} requirementTitle - Title of requirement to move
|
|
166
|
+
* @returns {Promise<boolean>} Success status
|
|
167
|
+
*/
|
|
168
|
+
async function promoteTodoToVerify(reqPath, requirementTitle) {
|
|
169
|
+
try {
|
|
170
|
+
const content = await fs.readFile(reqPath, 'utf-8');
|
|
171
|
+
const lines = content.split('\n');
|
|
172
|
+
|
|
173
|
+
// Find the requirement in TODO section
|
|
174
|
+
const requirement = findRequirementBlock(lines, requirementTitle, 'todo');
|
|
175
|
+
|
|
176
|
+
if (!requirement) {
|
|
177
|
+
console.error(`Requirement "${requirementTitle}" not found in TODO section`);
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Remove requirement from TODO section
|
|
182
|
+
lines.splice(requirement.startIndex, requirement.endIndex - requirement.startIndex);
|
|
183
|
+
|
|
184
|
+
// Find TO VERIFY section and add requirement there
|
|
185
|
+
let verifySectionIndex = -1;
|
|
186
|
+
for (let i = 0; i < lines.length; i++) {
|
|
187
|
+
const line = lines[i];
|
|
188
|
+
if (line.includes('## ✅ Verified by AI screenshot. Needs Human to Verify and move to CHANGELOG')) {
|
|
189
|
+
verifySectionIndex = i;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (verifySectionIndex === -1) {
|
|
195
|
+
// Create TO VERIFY section if it doesn't exist
|
|
196
|
+
verifySectionIndex = lines.length;
|
|
197
|
+
lines.push('## ✅ Verified by AI screenshot. Needs Human to Verify and move to CHANGELOG');
|
|
198
|
+
lines.push('');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Insert requirement after the TO VERIFY header
|
|
202
|
+
lines.splice(verifySectionIndex + 1, 0, '');
|
|
203
|
+
lines.splice(verifySectionIndex + 2, 0, `### ${requirement.title}`);
|
|
204
|
+
|
|
205
|
+
// Add requirement content
|
|
206
|
+
const requirementContent = requirement.content.split('\n');
|
|
207
|
+
for (const contentLine of requirementContent) {
|
|
208
|
+
lines.splice(verifySectionIndex + 3, 0, contentLine);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
await fs.writeFile(reqPath, lines.join('\n'), 'utf-8');
|
|
212
|
+
|
|
213
|
+
console.log(`✅ Promoted "${requirementTitle}" from TODO to TO VERIFY`);
|
|
214
|
+
return true;
|
|
215
|
+
|
|
216
|
+
} catch (error) {
|
|
217
|
+
console.error(`Error promoting requirement to verify: ${error.message}`);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Move requirement from TO VERIFY section back to TODO section
|
|
224
|
+
* @param {string} reqPath - Path to requirements file
|
|
225
|
+
* @param {string} requirementTitle - Title of requirement to move
|
|
226
|
+
* @returns {Promise<boolean>} Success status
|
|
227
|
+
*/
|
|
228
|
+
async function demoteFromVerifyToTodo(reqPath, requirementTitle) {
|
|
229
|
+
try {
|
|
230
|
+
const content = await fs.readFile(reqPath, 'utf-8');
|
|
231
|
+
const lines = content.split('\n');
|
|
232
|
+
|
|
233
|
+
// Find the requirement in TO VERIFY section
|
|
234
|
+
const requirement = findRequirementBlock(lines, requirementTitle, 'verify');
|
|
235
|
+
|
|
236
|
+
if (!requirement) {
|
|
237
|
+
console.error(`Requirement "${requirementTitle}" not found in TO VERIFY section`);
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Remove requirement from TO VERIFY section
|
|
242
|
+
lines.splice(requirement.startIndex, requirement.endIndex - requirement.startIndex);
|
|
243
|
+
|
|
244
|
+
// Find TODO section and add requirement there
|
|
245
|
+
let todoSectionIndex = -1;
|
|
246
|
+
for (let i = 0; i < lines.length; i++) {
|
|
247
|
+
const line = lines[i];
|
|
248
|
+
if (line.includes('## ⏳ Requirements not yet completed')) {
|
|
249
|
+
todoSectionIndex = i;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (todoSectionIndex === -1) {
|
|
255
|
+
// Create TODO section if it doesn't exist
|
|
256
|
+
todoSectionIndex = lines.length;
|
|
257
|
+
lines.push('## ⏳ Requirements not yet completed');
|
|
258
|
+
lines.push('');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Insert requirement after the TODO header
|
|
262
|
+
lines.splice(todoSectionIndex + 1, 0, '');
|
|
263
|
+
lines.splice(todoSectionIndex + 2, 0, `### ${requirement.title}`);
|
|
264
|
+
|
|
265
|
+
// Add requirement content
|
|
266
|
+
const requirementContent = requirement.content.split('\n');
|
|
267
|
+
for (const contentLine of requirementContent) {
|
|
268
|
+
lines.splice(todoSectionIndex + 3, 0, contentLine);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
await fs.writeFile(reqPath, lines.join('\n'), 'utf-8');
|
|
272
|
+
|
|
273
|
+
console.log(`✅ Demoted "${requirementTitle}" from TO VERIFY to TODO`);
|
|
274
|
+
return true;
|
|
275
|
+
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.error(`Error demoting requirement from verify: ${error.message}`);
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Move requirement to current in-progress section
|
|
284
|
+
* @param {string} reqPath - Path to requirements file
|
|
285
|
+
* @param {string} requirementTitle - Title of requirement to move
|
|
286
|
+
* @returns {Promise<boolean>} Success status
|
|
287
|
+
*/
|
|
288
|
+
async function moveToCurrent(reqPath, requirementTitle) {
|
|
289
|
+
try {
|
|
290
|
+
const content = await fs.readFile(reqPath, 'utf-8');
|
|
291
|
+
const lines = content.split('\n');
|
|
292
|
+
|
|
293
|
+
// Find the requirement in any section (prefer TODO first)
|
|
294
|
+
let requirement = findRequirementBlock(lines, requirementTitle, 'todo');
|
|
295
|
+
let sourceSection = 'todo';
|
|
296
|
+
|
|
297
|
+
if (!requirement) {
|
|
298
|
+
requirement = findRequirementBlock(lines, requirementTitle, 'verify');
|
|
299
|
+
sourceSection = 'verify';
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (!requirement) {
|
|
303
|
+
console.error(`Requirement "${requirementTitle}" not found in any section`);
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Remove requirement from source section
|
|
308
|
+
lines.splice(requirement.startIndex, requirement.endIndex - requirement.startIndex);
|
|
309
|
+
|
|
310
|
+
// Find or create current section
|
|
311
|
+
let currentSectionIndex = -1;
|
|
312
|
+
for (let i = 0; i < lines.length; i++) {
|
|
313
|
+
const line = lines[i];
|
|
314
|
+
if (line.includes('## 🔨 Current In Progress Requirement')) {
|
|
315
|
+
currentSectionIndex = i;
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (currentSectionIndex === -1) {
|
|
321
|
+
// Create current section if it doesn't exist
|
|
322
|
+
currentSectionIndex = lines.length;
|
|
323
|
+
lines.push('## 🔨 Current In Progress Requirement');
|
|
324
|
+
lines.push('');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Clear any existing current requirement
|
|
328
|
+
const currentRequirements = findAllRequirementsInSection(lines, 'current');
|
|
329
|
+
for (const existingReq of currentRequirements) {
|
|
330
|
+
lines.splice(existingReq.startIndex, existingReq.endIndex - existingReq.startIndex);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Insert requirement as current
|
|
334
|
+
lines.splice(currentSectionIndex + 1, 0, '');
|
|
335
|
+
lines.splice(currentSectionIndex + 2, 0, `### ${requirement.title}`);
|
|
336
|
+
|
|
337
|
+
// Add requirement content
|
|
338
|
+
const requirementContent = requirement.content.split('\n');
|
|
339
|
+
for (const contentLine of requirementContent) {
|
|
340
|
+
lines.splice(currentSectionIndex + 3, 0, contentLine);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
await fs.writeFile(reqPath, lines.join('\n'), 'utf-8');
|
|
344
|
+
|
|
345
|
+
console.log(`✅ Moved "${requirementTitle}" to current in-progress (from ${sourceSection})`);
|
|
346
|
+
return true;
|
|
347
|
+
|
|
348
|
+
} catch (error) {
|
|
349
|
+
console.error(`Error moving requirement to current: ${error.message}`);
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Get all requirements in a section
|
|
356
|
+
* @param {string} reqPath - Path to requirements file
|
|
357
|
+
* @param {string} sectionType - Type of section ('todo', 'verify', 'current')
|
|
358
|
+
* @returns {Promise<Array>} Array of requirement objects
|
|
359
|
+
*/
|
|
360
|
+
async function getRequirementsInSection(reqPath, sectionType = 'todo') {
|
|
361
|
+
try {
|
|
362
|
+
const content = await fs.readFile(reqPath, 'utf-8');
|
|
363
|
+
const lines = content.split('\n');
|
|
364
|
+
|
|
365
|
+
return findAllRequirementsInSection(lines, sectionType);
|
|
366
|
+
} catch (error) {
|
|
367
|
+
console.error(`Error getting requirements in ${sectionType} section: ${error.message}`);
|
|
368
|
+
return [];
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Get requirement statistics
|
|
374
|
+
* @param {string} reqPath - Path to requirements file
|
|
375
|
+
* @returns {Promise<Object>} Statistics object
|
|
376
|
+
*/
|
|
377
|
+
async function getRequirementStatistics(reqPath) {
|
|
378
|
+
try {
|
|
379
|
+
const todoRequirements = await getRequirementsInSection(reqPath, 'todo');
|
|
380
|
+
const verifyRequirements = await getRequirementsInSection(reqPath, 'verify');
|
|
381
|
+
const currentRequirements = await getRequirementsInSection(reqPath, 'current');
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
todo: todoRequirements.length,
|
|
385
|
+
verify: verifyRequirements.length,
|
|
386
|
+
current: currentRequirements.length,
|
|
387
|
+
total: todoRequirements.length + verifyRequirements.length + currentRequirements.length,
|
|
388
|
+
sections: {
|
|
389
|
+
todo: todoRequirements.map(req => ({ title: req.title, contentLength: req.content.length })),
|
|
390
|
+
verify: verifyRequirements.map(req => ({ title: req.title, contentLength: req.content.length })),
|
|
391
|
+
current: currentRequirements.map(req => ({ title: req.title, contentLength: req.content.length }))
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
} catch (error) {
|
|
395
|
+
console.error(`Error getting requirement statistics: ${error.message}`);
|
|
396
|
+
return {
|
|
397
|
+
todo: 0,
|
|
398
|
+
verify: 0,
|
|
399
|
+
current: 0,
|
|
400
|
+
total: 0,
|
|
401
|
+
sections: { todo: [], verify: [], current: [] }
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
module.exports = {
|
|
407
|
+
promoteToVerified,
|
|
408
|
+
demoteFromVerifiedToTodo,
|
|
409
|
+
promoteTodoToVerify,
|
|
410
|
+
demoteFromVerifyToTodo,
|
|
411
|
+
moveToCurrent,
|
|
412
|
+
getRequirementsInSection,
|
|
413
|
+
getRequirementStatistics
|
|
414
|
+
};
|