vibecodingmachine-cli 2026.3.14-1537 → 2026.6.17-1956
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/bin/auth/auth-compliance.js +7 -7
- package/bin/commands/agent-commands.js +15 -15
- package/bin/commands/auto-commands.js +3 -3
- package/bin/commands/command-aliases.js +13 -4
- package/bin/config/cli-config.js +15 -5
- package/bin/update/update-checker.js +5 -5
- package/bin/vibecodingmachine.js +2 -2
- package/package.json +2 -2
- package/src/commands/agents/add.js +5 -5
- package/src/commands/agents/check.js +19 -19
- package/src/commands/agents/list.js +24 -24
- package/src/commands/agents/remove.js +4 -4
- package/src/commands/agents-check.js +1 -1
- package/src/commands/analyze-file-sizes.js +43 -43
- package/src/commands/auto-direct/auto-provider-manager.js +19 -19
- package/src/commands/auto-direct/auto-start-phases.js +493 -0
- package/src/commands/auto-direct/auto-status-display.js +35 -35
- package/src/commands/auto-direct/auto-utils.js +50 -50
- package/src/commands/auto-direct/cline-installer.js +56 -0
- package/src/commands/auto-direct/code-processor.js +27 -27
- package/src/commands/auto-direct/file-scanner.js +19 -19
- package/src/commands/auto-direct/ide-completion-waiter.js +485 -0
- package/src/commands/auto-direct/ide-fallback-runner.js +226 -0
- package/src/commands/auto-direct/ide-provider-runner.js +103 -0
- package/src/commands/auto-direct/iteration-handlers.js +189 -0
- package/src/commands/auto-direct/iteration-runner.js +485 -0
- package/src/commands/auto-direct/provider-config.js +38 -7
- package/src/commands/auto-direct/provider-manager.js +132 -6
- package/src/commands/auto-direct/requirement-manager.js +169 -104
- package/src/commands/auto-direct/requirement-mover.js +350 -0
- package/src/commands/auto-direct/spec-handlers.js +155 -0
- package/src/commands/auto-direct/spec-ide-runner.js +318 -0
- package/src/commands/auto-direct/spec-processing.js +203 -0
- package/src/commands/auto-direct/status-display.js +9 -9
- package/src/commands/auto-direct/utils.js +83 -1
- package/src/commands/auto-direct-refactored.js +1 -413
- package/src/commands/auto-direct.js +127 -4119
- package/src/commands/auto-execution.js +21 -21
- package/src/commands/auto-status-helpers.js +0 -2
- package/src/commands/auto.js +22 -22
- package/src/commands/check-compliance.js +65 -65
- package/src/commands/computers.js +39 -39
- package/src/commands/continuous-scan.js +19 -19
- package/src/commands/ide.js +4 -4
- package/src/commands/locale.js +7 -7
- package/src/commands/refactor-file.js +59 -59
- package/src/commands/requirements/commands.js +17 -17
- package/src/commands/requirements/default-handlers.js +30 -30
- package/src/commands/requirements/disable.js +3 -3
- package/src/commands/requirements/enable.js +3 -3
- package/src/commands/requirements/utils.js +6 -6
- package/src/commands/requirements-refactored.js +3 -3
- package/src/commands/requirements-remote.js +38 -38
- package/src/commands/requirements.js +3 -3
- package/src/commands/settings.js +111 -0
- package/src/commands/specs/count.js +60 -0
- package/src/commands/specs/disable.js +3 -3
- package/src/commands/specs/enable.js +3 -3
- package/src/commands/status.js +10 -10
- package/src/commands/sync.js +25 -25
- package/src/commands/timeout.js +35 -35
- package/src/trui/TruiInterface.js +2 -2
- package/src/trui/agents/AgentInterface.js +4 -4
- package/src/trui/agents/handlers/CommandHandler.js +4 -4
- package/src/trui/agents/handlers/ContextManager.js +1 -1
- package/src/trui/agents/handlers/DisplayHandler.js +11 -11
- package/src/trui/agents/handlers/HelpHandler.js +1 -1
- package/src/utils/agent-selector.js +6 -6
- package/src/utils/antigravity-installer.js +4 -4
- package/src/utils/asset-cleanup.js +1 -1
- package/src/utils/auth.js +9 -12
- package/src/utils/clarification-actions.js +4 -4
- package/src/utils/cline-js-handler.js +5 -5
- package/src/utils/compliance-check.js +6 -6
- package/src/utils/config.js +12 -12
- package/src/utils/display-formatters-complete.js +2 -2
- package/src/utils/display-formatters-extracted.js +2 -2
- package/src/utils/display-formatters.js +2 -2
- package/src/utils/feedback-handler.js +2 -2
- package/src/utils/first-run.js +7 -7
- package/src/utils/ide-detection.js +1 -1
- package/src/utils/ide-handlers.js +6 -6
- package/src/utils/interactive/clarification-actions.js +3 -3
- package/src/utils/interactive/core-ui.js +7 -7
- package/src/utils/interactive/file-backup.js +6 -6
- package/src/utils/interactive/file-import-export.js +49 -49
- package/src/utils/interactive/file-operations.js +3 -3
- package/src/utils/interactive/file-validation.js +41 -41
- package/src/utils/interactive/interactive-prompts.js +41 -41
- package/src/utils/interactive/requirement-actions.js +5 -5
- package/src/utils/interactive/requirement-crud.js +4 -4
- package/src/utils/interactive/requirements-navigation.js +10 -10
- package/src/utils/interactive-broken.js +6 -6
- package/src/utils/interactive.js +37 -37
- package/src/utils/keyboard-handler.js +4 -4
- package/src/utils/prompt-helper.js +6 -6
- package/src/utils/provider-checker/agent-checker.js +1 -1
- package/src/utils/provider-checker/agent-runner.js +203 -314
- package/src/utils/provider-checker/agents-file-lock.js +134 -0
- package/src/utils/provider-checker/agents-manager.js +224 -36
- package/src/utils/provider-checker/cli-installer.js +28 -28
- package/src/utils/provider-checker/cli-utils.js +2 -2
- package/src/utils/provider-checker/cursor-approval-clicker.js +108 -0
- package/src/utils/provider-checker/format-utils.js +4 -4
- package/src/utils/provider-checker/ide-installer-helper.js +96 -0
- package/src/utils/provider-checker/ide-manager.js +19 -8
- package/src/utils/provider-checker/ide-quota-checker.js +120 -0
- package/src/utils/provider-checker/ide-utils.js +2 -2
- package/src/utils/provider-checker/node-detector.js +4 -4
- package/src/utils/provider-checker/node-utils.js +5 -5
- package/src/utils/provider-checker/opencode-checker.js +107 -73
- package/src/utils/provider-checker/process-utils.js +1 -1
- package/src/utils/provider-checker/provider-validator.js +11 -11
- package/src/utils/provider-checker/quota-checker.js +5 -5
- package/src/utils/provider-checker/quota-detector.js +5 -5
- package/src/utils/provider-checker/requirements-manager.js +6 -6
- package/src/utils/provider-checker/test-requirements.js +1 -1
- package/src/utils/provider-checker/vscode-approval-clicker.js +328 -0
- package/src/utils/provider-checker-new.js +6 -6
- package/src/utils/provider-checker.js +6 -6
- package/src/utils/provider-checkers/ide-manager.js +13 -13
- package/src/utils/provider-checkers/node-executable-finder.js +4 -4
- package/src/utils/provider-checkers/provider-checker-core.js +5 -5
- package/src/utils/provider-checkers/provider-checker-main.js +17 -17
- package/src/utils/provider-registry.js +5 -6
- package/src/utils/provider-utils.js +12 -12
- package/src/utils/quota-detectors.js +32 -32
- package/src/utils/requirement-action-handlers.js +12 -12
- package/src/utils/requirement-actions/requirement-operations.js +3 -3
- package/src/utils/requirement-actions.js +1 -1
- package/src/utils/requirement-file-operations.js +5 -5
- package/src/utils/requirement-helpers.js +1 -1
- package/src/utils/requirement-management.js +5 -5
- package/src/utils/requirement-navigation.js +2 -2
- package/src/utils/requirement-organization.js +3 -3
- package/src/utils/rui-trui-adapter.js +14 -14
- package/src/utils/simple-trui.js +3 -3
- package/src/utils/status-helpers-extracted.js +3 -3
- package/src/utils/trui-clarifications.js +11 -11
- package/src/utils/trui-debug.js +3 -2
- package/src/utils/trui-devin.js +217 -0
- package/src/utils/trui-feedback.js +7 -7
- package/src/utils/trui-kiro-integration.js +34 -34
- package/src/utils/trui-main-handlers.js +20 -21
- package/src/utils/trui-main-menu.js +19 -19
- package/src/utils/trui-nav-agents.js +59 -8
- package/src/utils/trui-nav-requirements.js +3 -3
- package/src/utils/trui-nav-settings.js +10 -10
- package/src/utils/trui-nav-specifications.js +1 -1
- package/src/utils/trui-navigation-backup.js +11 -11
- package/src/utils/trui-navigation.js +9 -9
- package/src/utils/trui-provider-health.js +25 -25
- package/src/utils/trui-provider-manager.js +28 -28
- package/src/utils/trui-quick-menu.js +2 -2
- package/src/utils/trui-req-actions-backup.js +21 -21
- package/src/utils/trui-req-actions.js +20 -20
- package/src/utils/trui-req-editor.js +10 -10
- package/src/utils/trui-req-file-ops.js +3 -3
- package/src/utils/trui-req-tree.js +7 -7
- package/src/utils/trui-windsurf.js +103 -103
- package/src/utils/user-tracking.js +15 -15
- package/src/utils/trui-req-tree-old.js +0 -719
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* IDE Handlers Module
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Handles IDE-specific operations like checking if IDEs are running, launching IDEs, and IDE installation.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ const path = require('path');
|
|
|
12
12
|
* IDE information mapping
|
|
13
13
|
*/
|
|
14
14
|
const IDE_INFO = {
|
|
15
|
-
|
|
15
|
+
devin: { process: 'Devin', app: 'Devin' },
|
|
16
16
|
cursor: { process: 'Cursor', app: 'Cursor' },
|
|
17
17
|
antigravity: { process: 'Antigravity', app: 'Antigravity' },
|
|
18
18
|
kiro: { process: 'Kiro', app: 'Kiro' },
|
|
@@ -83,7 +83,7 @@ async function checkAndLaunchIDE(providerId, def, repoPath) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
let ideLaunchNote = '';
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
if (!isIDERunning(info.process)) {
|
|
88
88
|
// macOS: launch the app if not running
|
|
89
89
|
if (process.platform === 'darwin' && info.app) {
|
|
@@ -117,7 +117,7 @@ async function checkAndLaunchIDE(providerId, def, repoPath) {
|
|
|
117
117
|
if (!checkResult.installed) {
|
|
118
118
|
// IDE is not installed - try to install if we have a download URL
|
|
119
119
|
const downloadUrl = ideConfig?.downloadUrl?.[process.platform];
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
if (downloadUrl) {
|
|
122
122
|
console.log(`[AGENT CHECK] Installing ${ideKey}...`);
|
|
123
123
|
try {
|
|
@@ -161,7 +161,7 @@ async function checkAndLaunchIDE(providerId, def, repoPath) {
|
|
|
161
161
|
const { IDEInstaller } = require('../../../electron-app/src/main/ide-installer');
|
|
162
162
|
const installer = new IDEInstaller();
|
|
163
163
|
const ideKey = def.ide || providerId;
|
|
164
|
-
|
|
164
|
+
|
|
165
165
|
try {
|
|
166
166
|
const checkResult = await installer.checkIDEInstallation(ideKey);
|
|
167
167
|
if (!checkResult.installed) {
|
|
@@ -170,7 +170,7 @@ async function checkAndLaunchIDE(providerId, def, repoPath) {
|
|
|
170
170
|
error: `${ideKey} is not installed`
|
|
171
171
|
};
|
|
172
172
|
}
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
const launchSuccess = await installer.launchIDE(ideKey, repoPath);
|
|
175
175
|
if (launchSuccess) {
|
|
176
176
|
ideLaunchNote = ` (VCM launched ${ideKey})`;
|
|
@@ -25,7 +25,7 @@ async function editClarificationResponses(req, tree) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
console.log(chalk.blue(`\n📝 Editing responses for: ${req.title}\n`));
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
if (responses.length > 0) {
|
|
30
30
|
console.log(chalk.yellow('Current responses:'));
|
|
31
31
|
responses.forEach((resp, idx) => console.log(chalk.gray(` ${idx + 1}. ${resp}`)));
|
|
@@ -158,7 +158,7 @@ async function moveClarificationToTodo(req, tree) {
|
|
|
158
158
|
while (insertIndex < lines.length && lines[insertIndex].trim() === '') {
|
|
159
159
|
insertIndex++;
|
|
160
160
|
}
|
|
161
|
-
|
|
161
|
+
|
|
162
162
|
// Insert the requirement
|
|
163
163
|
lines.splice(insertIndex, 0, ...requirementLines);
|
|
164
164
|
}
|
|
@@ -326,7 +326,7 @@ async function moveRequirementToRecycled(reqPath, requirementTitle, fromSection,
|
|
|
326
326
|
while (insertIndex < lines.length && lines[insertIndex].trim() === '') {
|
|
327
327
|
insertIndex++;
|
|
328
328
|
}
|
|
329
|
-
|
|
329
|
+
|
|
330
330
|
if (requirementLines) {
|
|
331
331
|
lines.splice(insertIndex, 0, ...requirementLines);
|
|
332
332
|
} else {
|
|
@@ -73,7 +73,7 @@ function formatIDEName(ide) {
|
|
|
73
73
|
'cline': 'Cline CLI',
|
|
74
74
|
'continue': 'Continue CLI',
|
|
75
75
|
'cursor': 'Cursor IDE',
|
|
76
|
-
'
|
|
76
|
+
'devin': 'Devin AI',
|
|
77
77
|
'vscode': 'VS Code',
|
|
78
78
|
'replit': 'Replit',
|
|
79
79
|
'github-copilot': 'GitHub Copilot',
|
|
@@ -119,7 +119,7 @@ function getCurrentAIProvider(ide) {
|
|
|
119
119
|
function getAgentDisplayName(agentType) {
|
|
120
120
|
// IDE-based agents
|
|
121
121
|
if (agentType === 'cursor') return 'Cursor IDE Agent';
|
|
122
|
-
if (agentType === '
|
|
122
|
+
if (agentType === 'devin') return 'Devin AI Agent';
|
|
123
123
|
if (agentType === 'vscode') return 'VS Code Agent';
|
|
124
124
|
if (agentType === 'claude-code') return 'Claude Code CLI';
|
|
125
125
|
if (agentType === 'aider') return 'Aider CLI';
|
|
@@ -176,11 +176,11 @@ async function countRequirements() {
|
|
|
176
176
|
async function getRepoPath() {
|
|
177
177
|
const { checkVibeCodingMachineExists } = require('vibecodingmachine-core');
|
|
178
178
|
const repoPath = process.cwd();
|
|
179
|
-
|
|
179
|
+
|
|
180
180
|
if (!await checkVibeCodingMachineExists(repoPath)) {
|
|
181
181
|
throw new Error('Not in a Vibe Coding Machine repository');
|
|
182
182
|
}
|
|
183
|
-
|
|
183
|
+
|
|
184
184
|
return repoPath;
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -200,14 +200,14 @@ async function getCurrentProgress() {
|
|
|
200
200
|
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
201
201
|
const reqPath = await getRequirementsPath();
|
|
202
202
|
const fs = require('fs-extra');
|
|
203
|
-
|
|
203
|
+
|
|
204
204
|
if (!await fs.pathExists(reqPath)) {
|
|
205
205
|
return { stage: 'NOT_STARTED', progress: 0 };
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
const content = await fs.readFile(reqPath, 'utf8');
|
|
209
209
|
const stageMatch = content.match(/## 🚦 Current Status\s*\n\s*\n(.+)/);
|
|
210
|
-
|
|
210
|
+
|
|
211
211
|
if (stageMatch) {
|
|
212
212
|
const stage = stageMatch[1].trim();
|
|
213
213
|
const progress = getProgressPercentage(stage);
|
|
@@ -230,7 +230,7 @@ function getProgressPercentage(stage) {
|
|
|
230
230
|
'VERIFY': 90,
|
|
231
231
|
'DONE': 100
|
|
232
232
|
};
|
|
233
|
-
|
|
233
|
+
|
|
234
234
|
return stageProgress[stage] || 0;
|
|
235
235
|
}
|
|
236
236
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* File Backup Operations
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Handles backup creation, restoration, and management for requirements files
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -100,7 +100,7 @@ async function listBackups(filePath, options = {}) {
|
|
|
100
100
|
try {
|
|
101
101
|
const backupDir = options.backupDir || path.join(path.dirname(filePath), '.backups');
|
|
102
102
|
const fileName = path.basename(filePath);
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
// Check if backup directory exists
|
|
105
105
|
const dirExists = await fs.access(backupDir).then(() => true).catch(() => false);
|
|
106
106
|
if (!dirExists) {
|
|
@@ -177,14 +177,14 @@ async function cleanupOldBackups(filePath, options = {}) {
|
|
|
177
177
|
|
|
178
178
|
// Determine which backups to delete
|
|
179
179
|
const backupsToDelete = [];
|
|
180
|
-
|
|
180
|
+
|
|
181
181
|
if (olderThan) {
|
|
182
182
|
// Delete backups older than specified date
|
|
183
|
-
const cutoffDate = typeof olderThan === 'number'
|
|
183
|
+
const cutoffDate = typeof olderThan === 'number'
|
|
184
184
|
? new Date(Date.now() - olderThan * 24 * 60 * 60 * 1000) // days
|
|
185
185
|
: new Date(olderThan);
|
|
186
|
-
|
|
187
|
-
backupsToDelete.push(...backups.filter(backup =>
|
|
186
|
+
|
|
187
|
+
backupsToDelete.push(...backups.filter(backup =>
|
|
188
188
|
new Date(backup.timestamp) < cutoffDate
|
|
189
189
|
));
|
|
190
190
|
} else {
|
|
@@ -9,12 +9,12 @@ const path = require('path');
|
|
|
9
9
|
async function exportRequirements(format = 'json') {
|
|
10
10
|
const reqPath = await getRequirementsPath();
|
|
11
11
|
const stats = await getRequirementsStats();
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
if (!stats) {
|
|
14
14
|
console.error(chalk.red('❌ Could not read requirements file'));
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
const exportData = {
|
|
19
19
|
exportedAt: new Date().toISOString(),
|
|
20
20
|
stats,
|
|
@@ -25,16 +25,16 @@ async function exportRequirements(format = 'json') {
|
|
|
25
25
|
recycled: []
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
try {
|
|
30
30
|
const content = await fs.readFile(reqPath, 'utf8');
|
|
31
31
|
const lines = content.split('\n');
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
let currentSection = null;
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
for (const line of lines) {
|
|
36
36
|
const trimmed = line.trim();
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
if (trimmed.includes('Requirements not yet completed')) {
|
|
39
39
|
currentSection = 'todo';
|
|
40
40
|
} else if (trimmed.includes('Verified by AI screenshot')) {
|
|
@@ -47,36 +47,36 @@ async function exportRequirements(format = 'json') {
|
|
|
47
47
|
exportData.requirements[currentSection].push(trimmed.substring(2));
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
let fileName;
|
|
52
52
|
let exportContent;
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
switch (format.toLowerCase()) {
|
|
55
55
|
case 'json':
|
|
56
56
|
fileName = `requirements-export-${Date.now()}.json`;
|
|
57
57
|
exportContent = JSON.stringify(exportData, null, 2);
|
|
58
58
|
break;
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
case 'csv':
|
|
61
61
|
fileName = `requirements-export-${Date.now()}.csv`;
|
|
62
62
|
exportContent = convertToCSV(exportData);
|
|
63
63
|
break;
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
case 'txt':
|
|
66
66
|
fileName = `requirements-export-${Date.now()}.txt`;
|
|
67
67
|
exportContent = convertToText(exportData);
|
|
68
68
|
break;
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
default:
|
|
71
71
|
console.error(chalk.red('❌ Unsupported export format'));
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
const exportPath = path.join(path.dirname(reqPath), fileName);
|
|
76
76
|
await fs.writeFile(exportPath, exportContent);
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
console.log(chalk.green(`✅ Requirements exported to: ${exportPath}`));
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
} catch (error) {
|
|
81
81
|
console.error(chalk.red('❌ Error exporting requirements:'), error.message);
|
|
82
82
|
}
|
|
@@ -84,13 +84,13 @@ async function exportRequirements(format = 'json') {
|
|
|
84
84
|
|
|
85
85
|
function convertToCSV(data) {
|
|
86
86
|
const csvLines = ['Section,Requirement,ExportedAt'];
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
Object.entries(data.requirements).forEach(([section, requirements]) => {
|
|
89
89
|
requirements.forEach(req => {
|
|
90
90
|
csvLines.push(`"${section}","${req.replace(/"/g, '""')}","${data.exportedAt}"`);
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
return csvLines.join('\n');
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -98,7 +98,7 @@ function convertToText(data) {
|
|
|
98
98
|
let text = `Requirements Export\n`;
|
|
99
99
|
text += `Exported at: ${data.exportedAt}\n`;
|
|
100
100
|
text += `Total requirements: ${data.stats.totalRequirements}\n\n`;
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
Object.entries(data.requirements).forEach(([section, requirements]) => {
|
|
103
103
|
if (requirements.length > 0) {
|
|
104
104
|
text += `${section.toUpperCase()} (${requirements.length}):\n`;
|
|
@@ -108,7 +108,7 @@ function convertToText(data) {
|
|
|
108
108
|
text += '\n';
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
return text;
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -120,17 +120,17 @@ async function importRequirements(importPath) {
|
|
|
120
120
|
console.error(chalk.red('❌ Import file not found'));
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
try {
|
|
125
125
|
const ext = path.extname(importPath).toLowerCase();
|
|
126
126
|
let requirements = [];
|
|
127
|
-
|
|
127
|
+
|
|
128
128
|
switch (ext) {
|
|
129
129
|
case '.json':
|
|
130
130
|
const data = await fs.readJson(importPath);
|
|
131
131
|
requirements = Object.values(data.requirements).flat();
|
|
132
132
|
break;
|
|
133
|
-
|
|
133
|
+
|
|
134
134
|
case '.csv':
|
|
135
135
|
const csvContent = await fs.readFile(importPath, 'utf8');
|
|
136
136
|
const lines = csvContent.split('\n');
|
|
@@ -142,7 +142,7 @@ async function importRequirements(importPath) {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
break;
|
|
145
|
-
|
|
145
|
+
|
|
146
146
|
case '.txt':
|
|
147
147
|
const txtContent = await fs.readFile(importPath, 'utf8');
|
|
148
148
|
const txtLines = txtContent.split('\n');
|
|
@@ -153,49 +153,49 @@ async function importRequirements(importPath) {
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
break;
|
|
156
|
-
|
|
156
|
+
|
|
157
157
|
default:
|
|
158
158
|
console.error(chalk.red('❌ Unsupported import format'));
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
161
|
-
|
|
161
|
+
|
|
162
162
|
if (requirements.length === 0) {
|
|
163
163
|
console.log(chalk.yellow('⚠️ No requirements found in import file'));
|
|
164
164
|
return;
|
|
165
165
|
}
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
console.log(chalk.green(`✅ Found ${requirements.length} requirements to import`));
|
|
168
|
-
|
|
168
|
+
|
|
169
169
|
const reqPath = await getRequirementsPath();
|
|
170
170
|
const content = await fs.readFile(reqPath, 'utf8');
|
|
171
171
|
const lines = content.split('\n');
|
|
172
|
-
|
|
172
|
+
|
|
173
173
|
// Find TODO section
|
|
174
174
|
const todoIndex = lines.findIndex(line => line.includes('Requirements not yet completed'));
|
|
175
175
|
if (todoIndex === -1) {
|
|
176
176
|
console.error(chalk.red('❌ TODO section not found in requirements file'));
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
179
|
-
|
|
179
|
+
|
|
180
180
|
// Insert requirements at the end of TODO section
|
|
181
181
|
let insertIndex = todoIndex + 1;
|
|
182
182
|
while (insertIndex < lines.length && !lines[insertIndex].startsWith('##') && lines[insertIndex].trim() !== '') {
|
|
183
183
|
insertIndex++;
|
|
184
184
|
}
|
|
185
|
-
|
|
185
|
+
|
|
186
186
|
// Add a blank line if needed
|
|
187
187
|
if (insertIndex < lines.length && lines[insertIndex].trim() !== '') {
|
|
188
188
|
lines.splice(insertIndex, 0, '');
|
|
189
189
|
insertIndex++;
|
|
190
190
|
}
|
|
191
|
-
|
|
191
|
+
|
|
192
192
|
// Add imported requirements
|
|
193
193
|
const importedRequirements = requirements.map(req => `- ${req}`);
|
|
194
194
|
lines.splice(insertIndex, 0, ...importedRequirements);
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
await fs.writeFile(reqPath, lines.join('\n'));
|
|
197
197
|
console.log(chalk.green(`✅ Imported ${requirements.length} requirements`));
|
|
198
|
-
|
|
198
|
+
|
|
199
199
|
} catch (error) {
|
|
200
200
|
console.error(chalk.red('❌ Error importing requirements:'), error.message);
|
|
201
201
|
}
|
|
@@ -215,16 +215,16 @@ async function getRequirementsStats() {
|
|
|
215
215
|
async function exportFilteredRequirements(filters = {}) {
|
|
216
216
|
const reqPath = await getRequirementsPath();
|
|
217
217
|
const stats = await getRequirementsStats();
|
|
218
|
-
|
|
218
|
+
|
|
219
219
|
if (!stats) {
|
|
220
220
|
console.error(chalk.red('❌ Could not read requirements file'));
|
|
221
221
|
return;
|
|
222
222
|
}
|
|
223
|
-
|
|
223
|
+
|
|
224
224
|
try {
|
|
225
225
|
const content = await fs.readFile(reqPath, 'utf8');
|
|
226
226
|
const lines = content.split('\n');
|
|
227
|
-
|
|
227
|
+
|
|
228
228
|
const filteredData = {
|
|
229
229
|
exportedAt: new Date().toISOString(),
|
|
230
230
|
filters,
|
|
@@ -235,12 +235,12 @@ async function exportFilteredRequirements(filters = {}) {
|
|
|
235
235
|
recycled: []
|
|
236
236
|
}
|
|
237
237
|
};
|
|
238
|
-
|
|
238
|
+
|
|
239
239
|
let currentSection = null;
|
|
240
|
-
|
|
240
|
+
|
|
241
241
|
for (const line of lines) {
|
|
242
242
|
const trimmed = line.trim();
|
|
243
|
-
|
|
243
|
+
|
|
244
244
|
if (trimmed.includes('Requirements not yet completed')) {
|
|
245
245
|
currentSection = 'todo';
|
|
246
246
|
} else if (trimmed.includes('Verified by AI screenshot')) {
|
|
@@ -251,45 +251,45 @@ async function exportFilteredRequirements(filters = {}) {
|
|
|
251
251
|
currentSection = 'recycled';
|
|
252
252
|
} else if (trimmed.startsWith('- ')) {
|
|
253
253
|
const requirement = trimmed.substring(2);
|
|
254
|
-
|
|
254
|
+
|
|
255
255
|
// Apply filters
|
|
256
256
|
let includeRequirement = true;
|
|
257
|
-
|
|
257
|
+
|
|
258
258
|
if (filters.section && filters.section !== currentSection) {
|
|
259
259
|
includeRequirement = false;
|
|
260
260
|
}
|
|
261
|
-
|
|
261
|
+
|
|
262
262
|
if (filters.keyword && !requirement.toLowerCase().includes(filters.keyword.toLowerCase())) {
|
|
263
263
|
includeRequirement = false;
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
|
|
266
266
|
if (filters.minLength && requirement.length < filters.minLength) {
|
|
267
267
|
includeRequirement = false;
|
|
268
268
|
}
|
|
269
|
-
|
|
269
|
+
|
|
270
270
|
if (filters.maxLength && requirement.length > filters.maxLength) {
|
|
271
271
|
includeRequirement = false;
|
|
272
272
|
}
|
|
273
|
-
|
|
273
|
+
|
|
274
274
|
if (includeRequirement) {
|
|
275
275
|
filteredData.requirements[currentSection].push(requirement);
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
|
-
|
|
279
|
+
|
|
280
280
|
// Count total filtered requirements
|
|
281
281
|
const totalFiltered = Object.values(filteredData.requirements).reduce((sum, reqs) => sum + reqs.length, 0);
|
|
282
|
-
|
|
282
|
+
|
|
283
283
|
console.log(chalk.green(`✅ Exported ${totalFiltered} filtered requirements`));
|
|
284
|
-
|
|
284
|
+
|
|
285
285
|
// Export as JSON by default for filtered exports
|
|
286
286
|
const fileName = `requirements-filtered-export-${Date.now()}.json`;
|
|
287
287
|
const exportPath = path.join(path.dirname(reqPath), fileName);
|
|
288
288
|
const exportContent = JSON.stringify(filteredData, null, 2);
|
|
289
|
-
|
|
289
|
+
|
|
290
290
|
await fs.writeFile(exportPath, exportContent);
|
|
291
291
|
console.log(chalk.green(`✅ Filtered export saved to: ${exportPath}`));
|
|
292
|
-
|
|
292
|
+
|
|
293
293
|
} catch (error) {
|
|
294
294
|
console.error(chalk.red('❌ Error exporting filtered requirements:'), error.message);
|
|
295
295
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* File Operations - Orchestrates file I/O operations
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* This module coordinates between backup, validation, and import/export operations.
|
|
5
5
|
* It serves as the main entry point for file-related operations.
|
|
6
6
|
*/
|
|
@@ -35,13 +35,13 @@ module.exports = {
|
|
|
35
35
|
restoreFromBackup,
|
|
36
36
|
listBackups,
|
|
37
37
|
cleanupOldBackups,
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
// Validation operations
|
|
40
40
|
validateRequirementsFile,
|
|
41
41
|
getRequirementsStats,
|
|
42
42
|
checkDuplicateRequirements,
|
|
43
43
|
checkOrphanedResponses,
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
// Import/Export operations
|
|
46
46
|
exportRequirements,
|
|
47
47
|
importRequirements,
|