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
@@ -30,15 +30,15 @@ async function loadProvidersData(navigation) {
30
30
  if (!commandResult.success || !commandResult.data) return null;
31
31
 
32
32
  const providers = commandResult.data;
33
-
33
+
34
34
  // Enhance providers with health information
35
35
  for (const provider of providers) {
36
36
  try {
37
37
  provider.health = await getProviderHealth(provider);
38
38
  } catch (error) {
39
- debugLogger.error('Error getting provider health', {
40
- provider: provider.id,
41
- error: error.message
39
+ debugLogger.error('Error getting provider health', {
40
+ provider: provider.id,
41
+ error: error.message
42
42
  });
43
43
  provider.health = { status: 'error', errors: [error.message] };
44
44
  }
@@ -63,7 +63,7 @@ function buildProviderChoices(providers, preferences = {}) {
63
63
  const isEnabled = preferences.enabled && preferences.enabled[provider.id] !== false;
64
64
  const status = isEnabled ? chalk.green('ENABLED') : chalk.red('DISABLED');
65
65
  const icon = getStatusIcon(isEnabled);
66
-
66
+
67
67
  // Enhanced health information
68
68
  let healthInfo = '';
69
69
  if (provider.health) {
@@ -72,7 +72,7 @@ function buildProviderChoices(providers, preferences = {}) {
72
72
  provider.health.status === 'unhealthy' ? '🔴' :
73
73
  provider.health.status === 'error' ? '❌' : '⚪';
74
74
  healthInfo = ` ${healthIcon}`;
75
-
75
+
76
76
  if (provider.health.responseTime) {
77
77
  const timeColor = provider.health.responseTime < 1000 ? chalk.green :
78
78
  provider.health.responseTime < 3000 ? chalk.yellow : chalk.red;
@@ -101,7 +101,7 @@ function buildProviderChoices(providers, preferences = {}) {
101
101
 
102
102
  const displayName = provider.name || provider.type || provider.id || 'Unknown';
103
103
  const details = [status, healthInfo, quotaInfo, ideInfo].filter(Boolean).join(' ');
104
-
104
+
105
105
  return {
106
106
  type: 'provider',
107
107
  name: `${icon} ${displayName}${details ? ' - ' + details : ''}`,
@@ -127,7 +127,7 @@ async function showProviderManager(navigation) {
127
127
  while (true) {
128
128
  // Build menu items
129
129
  const items = buildProviderChoices(providers, preferences);
130
-
130
+
131
131
  // Add actions
132
132
  items.push({ type: 'blank', name: '', value: 'blank' });
133
133
  items.push({ type: 'action', name: '[Test All Providers]', value: 'test-all' });
@@ -139,7 +139,7 @@ async function showProviderManager(navigation) {
139
139
  const result = await showQuickMenu(items, 0, {
140
140
  extraKeys: (str, key, selectedIndex, context) => {
141
141
  const currentItem = items[selectedIndex];
142
-
142
+
143
143
  // Handle enable/disable with e/d keys
144
144
  if ((str === 'e' || str === 'E') && currentItem && currentItem.value && currentItem.value.startsWith('provider:')) {
145
145
  const providerIndex = parseInt(currentItem.value.substring(9), 10);
@@ -156,12 +156,12 @@ async function showProviderManager(navigation) {
156
156
  // Handle re-ordering with arrow keys when on provider
157
157
  if ((key.name === 'up' || key.name === 'down') && currentItem && currentItem.value && currentItem.value.startsWith('provider:')) {
158
158
  const providerIndex = parseInt(currentItem.value.substring(9), 10);
159
-
159
+
160
160
  if (key.name === 'up' && providerIndex > 0) {
161
161
  context.resolveWith(`provider-move-up:${providerIndex}`);
162
162
  return true;
163
163
  }
164
-
164
+
165
165
  if (key.name === 'down' && providerIndex < providers.length - 1) {
166
166
  context.resolveWith(`provider-move-down:${providerIndex}`);
167
167
  return true;
@@ -228,7 +228,7 @@ async function toggleProvider(provider, enabled, navigation) {
228
228
  providerId: provider.id,
229
229
  enabled
230
230
  });
231
-
231
+
232
232
  if (result.success) {
233
233
  await result.command.execute();
234
234
  console.log(chalk.green(`\n✓ ${provider.name || provider.id} ${enabled ? 'enabled' : 'disabled'}`));
@@ -258,7 +258,7 @@ async function moveProvider(providers, index, direction, navigation) {
258
258
  // Save new order
259
259
  const newOrder = providers.map(p => p.id);
260
260
  const result = navigation.resolver.resolve('update provider-order', { order: newOrder });
261
-
261
+
262
262
  if (result.success) {
263
263
  await result.command.execute();
264
264
  console.log(chalk.green('\n✓ Provider order updated'));
@@ -273,16 +273,16 @@ async function moveProvider(providers, index, direction, navigation) {
273
273
  */
274
274
  async function testAllProviders(providers) {
275
275
  console.log(chalk.cyan('\n🔍 Testing all providers...\n'));
276
-
276
+
277
277
  for (const provider of providers) {
278
278
  console.log(chalk.gray(`Testing ${provider.name || provider.id}...`));
279
-
279
+
280
280
  try {
281
281
  const result = await fetch(`https://api.openai.com/v1/models`, {
282
282
  timeout: 5000,
283
283
  headers: provider.apiKey ? { 'Authorization': `Bearer ${provider.apiKey}` } : {}
284
284
  });
285
-
285
+
286
286
  if (result.ok) {
287
287
  console.log(chalk.green(` ✓ ${provider.name || provider.id} - Connected`));
288
288
  } else {
@@ -292,7 +292,7 @@ async function testAllProviders(providers) {
292
292
  console.log(chalk.red(` ✗ ${provider.name || provider.id} - Error (${err.message})`));
293
293
  }
294
294
  }
295
-
295
+
296
296
  console.log(chalk.gray('\nPress Enter to continue...'));
297
297
  await new Promise(resolve => {
298
298
  process.stdin.once('data', resolve);
@@ -304,7 +304,7 @@ async function testAllProviders(providers) {
304
304
  */
305
305
  async function refreshProviderHealth(providers, navigation) {
306
306
  console.log(chalk.cyan('\n🔄 Refreshing provider health...\n'));
307
-
307
+
308
308
  for (const provider of providers) {
309
309
  try {
310
310
  // Test basic connectivity
@@ -312,7 +312,7 @@ async function refreshProviderHealth(providers, navigation) {
312
312
  timeout: 3000,
313
313
  headers: provider.apiKey ? { 'Authorization': `Bearer ${provider.apiKey}` } : {}
314
314
  });
315
-
315
+
316
316
  if (result.ok) {
317
317
  console.log(chalk.green(` ✓ ${provider.name || provider.id} - Healthy`));
318
318
  } else {
@@ -322,7 +322,7 @@ async function refreshProviderHealth(providers, navigation) {
322
322
  console.log(chalk.red(` ✗ ${provider.name || provider.id} - Unreachable`));
323
323
  }
324
324
  }
325
-
325
+
326
326
  console.log(chalk.gray('\nPress Enter to continue...'));
327
327
  await new Promise(resolve => {
328
328
  process.stdin.once('data', resolve);
@@ -335,33 +335,33 @@ async function refreshProviderHealth(providers, navigation) {
335
335
  async function showKiroIntegrationStatus() {
336
336
  console.clear();
337
337
  console.log(chalk.bold.cyan('🔗 Kiro Integration Status\n'));
338
-
338
+
339
339
  try {
340
340
  const kiroStatus = await getKiroIntegrationStatus();
341
-
341
+
342
342
  console.log(`Status: ${kiroStatus.installed ? chalk.green('Installed') : chalk.red('Not Installed')}`);
343
-
343
+
344
344
  if (kiroStatus.version) {
345
345
  console.log(`Version: ${chalk.white(kiroStatus.version)}`);
346
346
  }
347
-
347
+
348
348
  console.log(`Configured: ${kiroStatus.configured ? chalk.green('Yes') : chalk.yellow('No')}`);
349
-
349
+
350
350
  if (kiroStatus.config) {
351
351
  console.log(`Project: ${chalk.white(kiroStatus.config.project)}`);
352
352
  console.log(`Provider: ${chalk.white(kiroStatus.config.provider)}`);
353
353
  console.log(`Auto-mode: ${kiroStatus.config.autoMode ? chalk.green('Enabled') : chalk.red('Disabled')}`);
354
354
  }
355
-
355
+
356
356
  if (!kiroStatus.installed) {
357
357
  console.log(chalk.yellow('\n💡 Kiro integration enhances provider management with advanced features.'));
358
358
  console.log(chalk.gray('Visit https://github.com/kiro-dev/kiro to install.'));
359
359
  }
360
-
360
+
361
361
  } catch (error) {
362
362
  console.log(chalk.red('Error checking Kiro status: ' + error.message));
363
363
  }
364
-
364
+
365
365
  console.log(chalk.gray('\nPress Enter to continue...'));
366
366
  await new Promise(resolve => {
367
367
  process.stdin.once('data', resolve);
@@ -16,7 +16,7 @@
16
16
 
17
17
  const chalk = require('chalk');
18
18
  const readline = require('readline');
19
- const { debugLogger, perfMonitor, stateTracker, errorHandler } = require('./trui-debug');
19
+ const { debugLogger, perfMonitor, stateTracker } = require('./trui-debug');
20
20
 
21
21
  /**
22
22
  * Convert a zero-based index to a letter shortcut (0→'a', 1→'b', …)
@@ -32,6 +32,7 @@ function indexToLetter(index) {
32
32
  */
33
33
  function stripAnsi(str) {
34
34
  return str.replace(
35
+ // eslint-disable-next-line no-control-regex
35
36
  /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
36
37
  ''
37
38
  );
@@ -131,7 +132,6 @@ function renderMenu(items, selectedIndex, hintText) {
131
132
  letterIndex++;
132
133
  }
133
134
 
134
- const prefix = isSelected ? chalk.cyan('❯ ') : ' ';
135
135
  const raw = `${isSelected ? '❯ ' : ' '}${letter}) ${item.name}`;
136
136
 
137
137
  if (isSelected) {
@@ -153,18 +153,18 @@ async function showRequirementActions(req, sectionKey, onChanged) {
153
153
 
154
154
  if (result.value === 'edit-clarification') {
155
155
  console.log(chalk.gray('\nOpening clarification response editor...'));
156
-
156
+
157
157
  // Create save callback for the requirement
158
158
  const saveCallback = async (updatedReq) => {
159
159
  // Update the requirement in the file
160
160
  const content = await fs.readFile(reqPath, 'utf8');
161
161
  const lines = content.split('\n');
162
-
162
+
163
163
  // Find and replace the requirement section
164
164
  let inRequirement = false;
165
165
  let reqStart = -1;
166
166
  let reqEnd = -1;
167
-
167
+
168
168
  for (let i = 0; i < lines.length; i++) {
169
169
  const line = lines[i];
170
170
  if (line.includes(`## ${req.title}`) || line.includes(`### ${req.title}`)) {
@@ -175,19 +175,19 @@ async function showRequirementActions(req, sectionKey, onChanged) {
175
175
  break;
176
176
  }
177
177
  }
178
-
178
+
179
179
  if (reqEnd === -1) reqEnd = lines.length;
180
-
180
+
181
181
  // Replace the requirement content
182
182
  const newContent = [
183
183
  ...lines.slice(0, reqStart),
184
184
  ...updatedReq.content.split('\n'),
185
185
  ...lines.slice(reqEnd)
186
186
  ].join('\n');
187
-
187
+
188
188
  await fs.writeFile(reqPath, newContent, 'utf8');
189
189
  };
190
-
190
+
191
191
  await editClarificationResponse(req, saveCallback);
192
192
  return true;
193
193
  }
@@ -373,10 +373,10 @@ async function addRequirementFlow() {
373
373
  console.log(chalk.gray('Equivalent: vcm req:add "<title>"\n'));
374
374
 
375
375
  const { createNewRequirement } = require('./trui-req-editor');
376
-
376
+
377
377
  try {
378
378
  const requirement = await createNewRequirement();
379
-
379
+
380
380
  const { getOrCreateRequirementsFilePath, getRequirementsPath } = require('vibecodingmachine-core');
381
381
  const { getRepoPath: _getRepoPath, getEffectiveRepoPath: _getEffectiveRepoPath } = require('./config');
382
382
  const _repoPath = await _getRepoPath();
@@ -436,18 +436,18 @@ async function handleRequirementSelection(index, requirements, navigation) {
436
436
 
437
437
  const req = requirements[index];
438
438
  const sectionKey = navigation.currentSection || 'todo';
439
-
439
+
440
440
  const changed = await showRequirementActions(req, sectionKey, () => {
441
441
  // Refresh callback - the tree will reload
442
442
  });
443
-
443
+
444
444
  return changed;
445
445
  }
446
446
 
447
- module.exports = {
448
- showRequirementActions,
449
- addRequirementFlow,
450
- _moveRequirement,
447
+ module.exports = {
448
+ showRequirementActions,
449
+ addRequirementFlow,
450
+ _moveRequirement,
451
451
  _deleteRequirement,
452
452
  handleRequirementSelection,
453
453
  showBulkSelection,
@@ -461,18 +461,18 @@ async function showBulkSelection(sectionKey, navigation) {
461
461
  console.clear();
462
462
  console.log(chalk.bold.cyan('📋 Bulk Selection\n'));
463
463
  console.log(chalk.gray('Select multiple requirements for bulk operations\n'));
464
-
464
+
465
465
  // Load requirements for the section
466
466
  const data = await navigation.resolver.resolve('list requirements');
467
467
  const result = await data.command.execute();
468
468
  const requirements = result.data.sections[sectionKey] || [];
469
-
469
+
470
470
  if (requirements.length === 0) {
471
471
  console.log(chalk.yellow('No requirements in this section'));
472
472
  await _pause();
473
473
  return;
474
474
  }
475
-
475
+
476
476
  const { selectedItems } = await inquirer.prompt([
477
477
  {
478
478
  type: 'checkbox',
@@ -484,13 +484,13 @@ async function showBulkSelection(sectionKey, navigation) {
484
484
  }))
485
485
  }
486
486
  ]);
487
-
487
+
488
488
  if (selectedItems.length === 0) {
489
489
  console.log(chalk.yellow('No items selected'));
490
490
  await _pause();
491
491
  return;
492
492
  }
493
-
493
+
494
494
  console.log(chalk.green(`\nSelected ${selectedItems.length} item(s)`));
495
495
  await _pause();
496
496
  }
@@ -502,6 +502,6 @@ async function showBulkMove(sectionKey, navigation) {
502
502
  console.clear();
503
503
  console.log(chalk.bold.cyan('🚀 Bulk Move\n'));
504
504
  console.log(chalk.gray('Move multiple requirements to another section\n'));
505
-
505
+
506
506
  await _pause();
507
507
  }
@@ -99,18 +99,18 @@ async function showRequirementActions(req, sectionKey, onChanged) {
99
99
 
100
100
  if (result.value === 'edit-clarification') {
101
101
  console.log(chalk.gray('\nOpening clarification response editor...'));
102
-
102
+
103
103
  // Create save callback for the requirement
104
104
  const saveCallback = async (updatedReq) => {
105
105
  // Update the requirement in the file
106
106
  const content = await fs.readFile(reqPath, 'utf8');
107
107
  const lines = content.split('\n');
108
-
108
+
109
109
  // Find and replace the requirement section
110
110
  let inRequirement = false;
111
111
  let reqStart = -1;
112
112
  let reqEnd = -1;
113
-
113
+
114
114
  for (let i = 0; i < lines.length; i++) {
115
115
  const line = lines[i];
116
116
  if (line.includes(`## ${req.title}`) || line.includes(`### ${req.title}`)) {
@@ -121,19 +121,19 @@ async function showRequirementActions(req, sectionKey, onChanged) {
121
121
  break;
122
122
  }
123
123
  }
124
-
124
+
125
125
  if (reqEnd === -1) reqEnd = lines.length;
126
-
126
+
127
127
  // Replace the requirement content
128
128
  const newContent = [
129
129
  ...lines.slice(0, reqStart),
130
130
  ...updatedReq.content.split('\n'),
131
131
  ...lines.slice(reqEnd)
132
132
  ].join('\n');
133
-
133
+
134
134
  await fs.writeFile(reqPath, newContent, 'utf8');
135
135
  };
136
-
136
+
137
137
  await editClarificationResponse(req, saveCallback);
138
138
  return true;
139
139
  }
@@ -183,18 +183,18 @@ async function showBulkSelection(sectionKey, navigation) {
183
183
  console.clear();
184
184
  console.log(chalk.bold.cyan('📋 Bulk Selection\n'));
185
185
  console.log(chalk.gray('Select multiple requirements for bulk operations\n'));
186
-
186
+
187
187
  // Load requirements for the section
188
188
  const data = await navigation.resolver.resolve('list requirements');
189
189
  const result = await data.command.execute();
190
190
  const requirements = result.data.sections[sectionKey] || [];
191
-
191
+
192
192
  if (requirements.length === 0) {
193
193
  console.log(chalk.yellow('No requirements in this section'));
194
194
  await _pause();
195
195
  return;
196
196
  }
197
-
197
+
198
198
  const { selectedItems } = await inquirer.prompt([
199
199
  {
200
200
  type: 'checkbox',
@@ -206,13 +206,13 @@ async function showBulkSelection(sectionKey, navigation) {
206
206
  }))
207
207
  }
208
208
  ]);
209
-
209
+
210
210
  if (selectedItems.length === 0) {
211
211
  console.log(chalk.yellow('No items selected'));
212
212
  await _pause();
213
213
  return;
214
214
  }
215
-
215
+
216
216
  console.log(chalk.green(`\nSelected ${selectedItems.length} item(s)`));
217
217
  await _pause();
218
218
  }
@@ -224,7 +224,7 @@ async function showBulkMove(sectionKey, navigation) {
224
224
  console.clear();
225
225
  console.log(chalk.bold.cyan('🚀 Bulk Move\n'));
226
226
  console.log(chalk.gray('Move multiple requirements to another section\n'));
227
-
227
+
228
228
  await _pause();
229
229
  }
230
230
 
@@ -239,11 +239,11 @@ async function handleRequirementSelection(index, requirements, navigation) {
239
239
 
240
240
  const req = requirements[index];
241
241
  const sectionKey = navigation.currentSection || 'todo';
242
-
242
+
243
243
  const changed = await showRequirementActions(req, sectionKey, () => {
244
244
  // Refresh callback - the tree will reload
245
245
  });
246
-
246
+
247
247
  return changed;
248
248
  }
249
249
 
@@ -255,10 +255,10 @@ async function addRequirementFlow() {
255
255
  console.log(chalk.gray('Equivalent: vcm req:add "<title>"\n'));
256
256
 
257
257
  const { createNewRequirement } = require('./trui-req-editor');
258
-
258
+
259
259
  try {
260
260
  const requirement = await createNewRequirement();
261
-
261
+
262
262
  const { getOrCreateRequirementsFilePath, getRequirementsPath } = require('vibecodingmachine-core');
263
263
  const { getRepoPath: _getRepoPath, getEffectiveRepoPath: _getEffectiveRepoPath } = require('./config');
264
264
  const _repoPath = await _getRepoPath();
@@ -295,9 +295,9 @@ async function addRequirementFlow() {
295
295
  await _pause();
296
296
  }
297
297
 
298
- module.exports = {
299
- showRequirementActions,
300
- addRequirementFlow,
298
+ module.exports = {
299
+ showRequirementActions,
300
+ addRequirementFlow,
301
301
  handleRequirementSelection,
302
302
  showBulkSelection,
303
303
  showBulkMove
@@ -24,7 +24,7 @@ class RequirementEditor {
24
24
  */
25
25
  async editTitle(currentTitle = '') {
26
26
  debugLogger.info('Starting title edit', { currentTitle });
27
-
27
+
28
28
  console.log(chalk.cyan('\nEdit Requirement Title'));
29
29
  console.log(chalk.gray('Press ESC to cancel, Ctrl+S to save, Enter to finish\n'));
30
30
 
@@ -50,7 +50,7 @@ class RequirementEditor {
50
50
  */
51
51
  async editDescription(currentDescription = '') {
52
52
  debugLogger.info('Starting description edit', { currentDescription });
53
-
53
+
54
54
  console.log(chalk.cyan('\nEdit Requirement Description'));
55
55
  console.log(chalk.gray('Press ESC to cancel, Ctrl+S to save, Enter+Enter to finish\n'));
56
56
  console.log(chalk.gray('Current description:'));
@@ -85,13 +85,13 @@ class RequirementEditor {
85
85
  debugLogger.info('Starting full requirement edit', { requirement });
86
86
 
87
87
  const newTitle = await this.editTitle(requirement.title || '');
88
-
88
+
89
89
  // Ask if user wants to edit description
90
90
  console.log(chalk.gray('\nEdit description? (y/N): '));
91
-
91
+
92
92
  // For now, automatically edit description if it exists or if title was changed
93
93
  const shouldEditDesc = requirement.description || newTitle !== (requirement.title || '');
94
-
94
+
95
95
  if (shouldEditDesc) {
96
96
  const newDescription = await this.editDescription(requirement.description || '');
97
97
  return {
@@ -111,10 +111,10 @@ class RequirementEditor {
111
111
  */
112
112
  async getRequirementTitle(prompt = 'Enter requirement title:') {
113
113
  console.log(chalk.cyan(`\n${prompt}`));
114
-
114
+
115
115
  while (true) {
116
116
  const title = await this.editTitle('');
117
-
117
+
118
118
  if (!title || title.trim().length === 0) {
119
119
  console.log(chalk.red('Title is required. Please enter a title.'));
120
120
  continue;
@@ -135,7 +135,7 @@ class RequirementEditor {
135
135
  async getRequirementDescription(currentDescription = '') {
136
136
  console.log(chalk.cyan('\nEnter requirement description (optional):'));
137
137
  console.log(chalk.gray('Press Enter on empty line to skip description\n'));
138
-
138
+
139
139
  return await this.editDescription(currentDescription);
140
140
  }
141
141
  }
@@ -145,10 +145,10 @@ class RequirementEditor {
145
145
  */
146
146
  async function createNewRequirement() {
147
147
  const editor = new RequirementEditor();
148
-
148
+
149
149
  const title = await editor.getRequirementTitle();
150
150
  const description = await editor.getRequirementDescription();
151
-
151
+
152
152
  return {
153
153
  title,
154
154
  description: description || ''
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  const fs = require('fs-extra');
8
- const {
8
+ const {
9
9
  promoteToVerified,
10
10
  demoteFromVerifiedToTodo,
11
11
  promoteTodoToVerify,
@@ -62,7 +62,7 @@ async function moveRequirement(reqPath, title, sectionKey, direction) {
62
62
  }
63
63
 
64
64
  // Find the target requirement
65
- const targetIndex = reqBlocks.findIndex(block =>
65
+ const targetIndex = reqBlocks.findIndex(block =>
66
66
  block.title === title || block.title.includes(title)
67
67
  );
68
68
  if (targetIndex === -1) return false;
@@ -183,7 +183,7 @@ async function _confirmKeypress(message) {
183
183
  return new Promise(resolve => {
184
184
  const chalk = require('chalk');
185
185
  const readline = require('readline');
186
-
186
+
187
187
  process.stdout.write(message + ' (Y/n/-)\n\n');
188
188
  readline.emitKeypressEvents(process.stdin);
189
189
  if (process.stdin.isTTY && process.stdin.setRawMode) {
@@ -57,7 +57,7 @@ async function loadRequirementsData(navigation) {
57
57
  function buildSectionItems(sections, expandedSections = {}) {
58
58
  const items = [];
59
59
  const total = sections.verified.length + sections['to-verify'].length + sections.todo.length;
60
-
60
+
61
61
  // VERIFIED section
62
62
  const verifiedExpanded = expandedSections.verified || false;
63
63
  const verifiedIcon = verifiedExpanded ? '▼' : '▶';
@@ -98,7 +98,7 @@ function buildRequirementItems(requirements, sectionKey) {
98
98
  return requirements.map((req, index) => {
99
99
  const hasClarification = hasClarificationResponse(req);
100
100
  const clarificationIcon = hasClarification ? ' 💬' : '';
101
-
101
+
102
102
  return {
103
103
  type: 'sub-item',
104
104
  name: ` ${req.title || req.name || 'Untitled'}${clarificationIcon}`,
@@ -124,7 +124,7 @@ async function showRequirementsTree(navigation, expandedSections = {}) {
124
124
  while (true) {
125
125
  // Build menu items
126
126
  const items = [];
127
-
127
+
128
128
  // Add section headers
129
129
  const sectionItems = buildSectionItems(sections, expandedSections);
130
130
  items.push(...sectionItems);
@@ -309,7 +309,7 @@ async function searchRequirements(sections, navigation) {
309
309
 
310
310
  // Display search results
311
311
  console.log(chalk.green(`\nFound ${matches.length} requirement(s) matching "${query}":\n`));
312
-
312
+
313
313
  const result = await showQuickMenu(
314
314
  matches.map((req, index) => ({
315
315
  type: 'search-result',
@@ -322,7 +322,7 @@ async function searchRequirements(sections, navigation) {
322
322
  if (result.value && result.value.startsWith('search-result:')) {
323
323
  const index = parseInt(result.value.substring(13), 10);
324
324
  const selectedReq = matches[index];
325
-
325
+
326
326
  // Show requirement actions for search result
327
327
  const { handleRequirementSelection } = require('./trui-req-actions');
328
328
  await handleRequirementSelection(selectedReq.index, sections[selectedReq.section], navigation);
@@ -403,7 +403,7 @@ async function filterRequirements(sections, navigation) {
403
403
 
404
404
  // Display filtered results
405
405
  console.log(chalk.green(`\nShowing ${filteredReqs.length} requirement(s) - ${filterDescription}\n`));
406
-
406
+
407
407
  const result = await showQuickMenu(
408
408
  filteredReqs.map((req, index) => ({
409
409
  type: 'filtered-result',
@@ -417,7 +417,7 @@ async function filterRequirements(sections, navigation) {
417
417
  const [, type, value, indexStr] = result.value.split(':');
418
418
  const index = parseInt(indexStr, 10);
419
419
  const selectedReq = filteredReqs[index];
420
-
420
+
421
421
  // Show requirement actions for filtered result
422
422
  const { handleRequirementSelection } = require('./trui-req-actions');
423
423
  const sectionKey = type === 'status' ? value : filterValue;