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.
Files changed (162) hide show
  1. package/bin/auth/auth-compliance.js +7 -7
  2. package/bin/commands/agent-commands.js +15 -15
  3. package/bin/commands/auto-commands.js +3 -3
  4. package/bin/commands/command-aliases.js +13 -4
  5. package/bin/config/cli-config.js +15 -5
  6. package/bin/update/update-checker.js +5 -5
  7. package/bin/vibecodingmachine.js +2 -2
  8. package/package.json +2 -2
  9. package/src/commands/agents/add.js +5 -5
  10. package/src/commands/agents/check.js +19 -19
  11. package/src/commands/agents/list.js +24 -24
  12. package/src/commands/agents/remove.js +4 -4
  13. package/src/commands/agents-check.js +1 -1
  14. package/src/commands/analyze-file-sizes.js +43 -43
  15. package/src/commands/auto-direct/auto-provider-manager.js +19 -19
  16. package/src/commands/auto-direct/auto-start-phases.js +493 -0
  17. package/src/commands/auto-direct/auto-status-display.js +35 -35
  18. package/src/commands/auto-direct/auto-utils.js +50 -50
  19. package/src/commands/auto-direct/cline-installer.js +56 -0
  20. package/src/commands/auto-direct/code-processor.js +27 -27
  21. package/src/commands/auto-direct/file-scanner.js +19 -19
  22. package/src/commands/auto-direct/ide-completion-waiter.js +485 -0
  23. package/src/commands/auto-direct/ide-fallback-runner.js +226 -0
  24. package/src/commands/auto-direct/ide-provider-runner.js +103 -0
  25. package/src/commands/auto-direct/iteration-handlers.js +189 -0
  26. package/src/commands/auto-direct/iteration-runner.js +485 -0
  27. package/src/commands/auto-direct/provider-config.js +38 -7
  28. package/src/commands/auto-direct/provider-manager.js +132 -6
  29. package/src/commands/auto-direct/requirement-manager.js +169 -104
  30. package/src/commands/auto-direct/requirement-mover.js +350 -0
  31. package/src/commands/auto-direct/spec-handlers.js +155 -0
  32. package/src/commands/auto-direct/spec-ide-runner.js +318 -0
  33. package/src/commands/auto-direct/spec-processing.js +203 -0
  34. package/src/commands/auto-direct/status-display.js +9 -9
  35. package/src/commands/auto-direct/utils.js +83 -1
  36. package/src/commands/auto-direct-refactored.js +1 -413
  37. package/src/commands/auto-direct.js +127 -4119
  38. package/src/commands/auto-execution.js +21 -21
  39. package/src/commands/auto-status-helpers.js +0 -2
  40. package/src/commands/auto.js +22 -22
  41. package/src/commands/check-compliance.js +65 -65
  42. package/src/commands/computers.js +39 -39
  43. package/src/commands/continuous-scan.js +19 -19
  44. package/src/commands/ide.js +4 -4
  45. package/src/commands/locale.js +7 -7
  46. package/src/commands/refactor-file.js +59 -59
  47. package/src/commands/requirements/commands.js +17 -17
  48. package/src/commands/requirements/default-handlers.js +30 -30
  49. package/src/commands/requirements/disable.js +3 -3
  50. package/src/commands/requirements/enable.js +3 -3
  51. package/src/commands/requirements/utils.js +6 -6
  52. package/src/commands/requirements-refactored.js +3 -3
  53. package/src/commands/requirements-remote.js +38 -38
  54. package/src/commands/requirements.js +3 -3
  55. package/src/commands/settings.js +111 -0
  56. package/src/commands/specs/count.js +60 -0
  57. package/src/commands/specs/disable.js +3 -3
  58. package/src/commands/specs/enable.js +3 -3
  59. package/src/commands/status.js +10 -10
  60. package/src/commands/sync.js +25 -25
  61. package/src/commands/timeout.js +35 -35
  62. package/src/trui/TruiInterface.js +2 -2
  63. package/src/trui/agents/AgentInterface.js +4 -4
  64. package/src/trui/agents/handlers/CommandHandler.js +4 -4
  65. package/src/trui/agents/handlers/ContextManager.js +1 -1
  66. package/src/trui/agents/handlers/DisplayHandler.js +11 -11
  67. package/src/trui/agents/handlers/HelpHandler.js +1 -1
  68. package/src/utils/agent-selector.js +6 -6
  69. package/src/utils/antigravity-installer.js +4 -4
  70. package/src/utils/asset-cleanup.js +1 -1
  71. package/src/utils/auth.js +9 -12
  72. package/src/utils/clarification-actions.js +4 -4
  73. package/src/utils/cline-js-handler.js +5 -5
  74. package/src/utils/compliance-check.js +6 -6
  75. package/src/utils/config.js +12 -12
  76. package/src/utils/display-formatters-complete.js +2 -2
  77. package/src/utils/display-formatters-extracted.js +2 -2
  78. package/src/utils/display-formatters.js +2 -2
  79. package/src/utils/feedback-handler.js +2 -2
  80. package/src/utils/first-run.js +7 -7
  81. package/src/utils/ide-detection.js +1 -1
  82. package/src/utils/ide-handlers.js +6 -6
  83. package/src/utils/interactive/clarification-actions.js +3 -3
  84. package/src/utils/interactive/core-ui.js +7 -7
  85. package/src/utils/interactive/file-backup.js +6 -6
  86. package/src/utils/interactive/file-import-export.js +49 -49
  87. package/src/utils/interactive/file-operations.js +3 -3
  88. package/src/utils/interactive/file-validation.js +41 -41
  89. package/src/utils/interactive/interactive-prompts.js +41 -41
  90. package/src/utils/interactive/requirement-actions.js +5 -5
  91. package/src/utils/interactive/requirement-crud.js +4 -4
  92. package/src/utils/interactive/requirements-navigation.js +10 -10
  93. package/src/utils/interactive-broken.js +6 -6
  94. package/src/utils/interactive.js +37 -37
  95. package/src/utils/keyboard-handler.js +4 -4
  96. package/src/utils/prompt-helper.js +6 -6
  97. package/src/utils/provider-checker/agent-checker.js +1 -1
  98. package/src/utils/provider-checker/agent-runner.js +203 -314
  99. package/src/utils/provider-checker/agents-file-lock.js +134 -0
  100. package/src/utils/provider-checker/agents-manager.js +224 -36
  101. package/src/utils/provider-checker/cli-installer.js +28 -28
  102. package/src/utils/provider-checker/cli-utils.js +2 -2
  103. package/src/utils/provider-checker/cursor-approval-clicker.js +108 -0
  104. package/src/utils/provider-checker/format-utils.js +4 -4
  105. package/src/utils/provider-checker/ide-installer-helper.js +96 -0
  106. package/src/utils/provider-checker/ide-manager.js +19 -8
  107. package/src/utils/provider-checker/ide-quota-checker.js +120 -0
  108. package/src/utils/provider-checker/ide-utils.js +2 -2
  109. package/src/utils/provider-checker/node-detector.js +4 -4
  110. package/src/utils/provider-checker/node-utils.js +5 -5
  111. package/src/utils/provider-checker/opencode-checker.js +107 -73
  112. package/src/utils/provider-checker/process-utils.js +1 -1
  113. package/src/utils/provider-checker/provider-validator.js +11 -11
  114. package/src/utils/provider-checker/quota-checker.js +5 -5
  115. package/src/utils/provider-checker/quota-detector.js +5 -5
  116. package/src/utils/provider-checker/requirements-manager.js +6 -6
  117. package/src/utils/provider-checker/test-requirements.js +1 -1
  118. package/src/utils/provider-checker/vscode-approval-clicker.js +328 -0
  119. package/src/utils/provider-checker-new.js +6 -6
  120. package/src/utils/provider-checker.js +6 -6
  121. package/src/utils/provider-checkers/ide-manager.js +13 -13
  122. package/src/utils/provider-checkers/node-executable-finder.js +4 -4
  123. package/src/utils/provider-checkers/provider-checker-core.js +5 -5
  124. package/src/utils/provider-checkers/provider-checker-main.js +17 -17
  125. package/src/utils/provider-registry.js +5 -6
  126. package/src/utils/provider-utils.js +12 -12
  127. package/src/utils/quota-detectors.js +32 -32
  128. package/src/utils/requirement-action-handlers.js +12 -12
  129. package/src/utils/requirement-actions/requirement-operations.js +3 -3
  130. package/src/utils/requirement-actions.js +1 -1
  131. package/src/utils/requirement-file-operations.js +5 -5
  132. package/src/utils/requirement-helpers.js +1 -1
  133. package/src/utils/requirement-management.js +5 -5
  134. package/src/utils/requirement-navigation.js +2 -2
  135. package/src/utils/requirement-organization.js +3 -3
  136. package/src/utils/rui-trui-adapter.js +14 -14
  137. package/src/utils/simple-trui.js +3 -3
  138. package/src/utils/status-helpers-extracted.js +3 -3
  139. package/src/utils/trui-clarifications.js +11 -11
  140. package/src/utils/trui-debug.js +3 -2
  141. package/src/utils/trui-devin.js +217 -0
  142. package/src/utils/trui-feedback.js +7 -7
  143. package/src/utils/trui-kiro-integration.js +34 -34
  144. package/src/utils/trui-main-handlers.js +20 -21
  145. package/src/utils/trui-main-menu.js +19 -19
  146. package/src/utils/trui-nav-agents.js +59 -8
  147. package/src/utils/trui-nav-requirements.js +3 -3
  148. package/src/utils/trui-nav-settings.js +10 -10
  149. package/src/utils/trui-nav-specifications.js +1 -1
  150. package/src/utils/trui-navigation-backup.js +11 -11
  151. package/src/utils/trui-navigation.js +9 -9
  152. package/src/utils/trui-provider-health.js +25 -25
  153. package/src/utils/trui-provider-manager.js +28 -28
  154. package/src/utils/trui-quick-menu.js +2 -2
  155. package/src/utils/trui-req-actions-backup.js +21 -21
  156. package/src/utils/trui-req-actions.js +20 -20
  157. package/src/utils/trui-req-editor.js +10 -10
  158. package/src/utils/trui-req-file-ops.js +3 -3
  159. package/src/utils/trui-req-tree.js +7 -7
  160. package/src/utils/trui-windsurf.js +103 -103
  161. package/src/utils/user-tracking.js +15 -15
  162. 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
- windsurf: { process: 'Windsurf', app: 'Windsurf' },
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
- 'windsurf': 'Windsurf IDE',
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 === 'windsurf') return 'Windsurf IDE Agent';
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,