vibecodingmachine-cli 2026.1.29-713 → 2026.2.20-423

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 (45) hide show
  1. package/bin/vibecodingmachine.js +124 -0
  2. package/package.json +3 -2
  3. package/src/commands/agents-check.js +69 -0
  4. package/src/commands/auto-direct.js +930 -145
  5. package/src/commands/auto.js +26 -4
  6. package/src/commands/ide.js +2 -1
  7. package/src/commands/requirements.js +23 -27
  8. package/src/utils/auto-mode.js +4 -1
  9. package/src/utils/cline-js-handler.js +218 -0
  10. package/src/utils/config.js +22 -0
  11. package/src/utils/display-formatters-complete.js +229 -0
  12. package/src/utils/display-formatters-extracted.js +219 -0
  13. package/src/utils/display-formatters.js +157 -0
  14. package/src/utils/feedback-handler.js +143 -0
  15. package/src/utils/ide-detection-complete.js +126 -0
  16. package/src/utils/ide-detection-extracted.js +116 -0
  17. package/src/utils/ide-detection.js +124 -0
  18. package/src/utils/interactive-backup.js +5664 -0
  19. package/src/utils/interactive-broken.js +280 -0
  20. package/src/utils/interactive.js +31 -5534
  21. package/src/utils/provider-checker.js +410 -0
  22. package/src/utils/provider-manager.js +251 -0
  23. package/src/utils/provider-registry.js +18 -9
  24. package/src/utils/requirement-actions.js +884 -0
  25. package/src/utils/requirements-navigator.js +585 -0
  26. package/src/utils/rui-trui-adapter.js +311 -0
  27. package/src/utils/simple-trui.js +204 -0
  28. package/src/utils/status-helpers-extracted.js +125 -0
  29. package/src/utils/status-helpers.js +107 -0
  30. package/src/utils/trui-debug.js +261 -0
  31. package/src/utils/trui-feedback.js +133 -0
  32. package/src/utils/trui-nav-agents.js +119 -0
  33. package/src/utils/trui-nav-requirements.js +268 -0
  34. package/src/utils/trui-nav-settings.js +157 -0
  35. package/src/utils/trui-nav-specifications.js +139 -0
  36. package/src/utils/trui-navigation.js +303 -0
  37. package/src/utils/trui-provider-manager.js +182 -0
  38. package/src/utils/trui-quick-menu.js +365 -0
  39. package/src/utils/trui-req-actions.js +372 -0
  40. package/src/utils/trui-req-tree.js +534 -0
  41. package/src/utils/trui-specifications.js +359 -0
  42. package/src/utils/trui-text-editor.js +350 -0
  43. package/src/utils/trui-windsurf.js +336 -0
  44. package/src/utils/welcome-screen-extracted.js +135 -0
  45. package/src/utils/welcome-screen.js +134 -0
@@ -0,0 +1,311 @@
1
+ /**
2
+ * RUI TRUI Adapter
3
+ * Adapts the TRUI interface to use the RUI pattern
4
+ */
5
+
6
+ const { RUICommandRegistry, RUICommandResolver, ListAgentsCommand, ListRequirementsCommand, ListSettingsCommand } = require('vibecodingmachine-core');
7
+
8
+ class RUITRUIAdapter {
9
+ constructor() {
10
+ this.resolver = null;
11
+ }
12
+
13
+ /**
14
+ * Initialize the adapter
15
+ */
16
+ initialize() {
17
+ // Create registry and register commands
18
+ const registry = new RUICommandRegistry();
19
+ const agentsCmd = new ListAgentsCommand();
20
+ const reqsCmd = new ListRequirementsCommand();
21
+ const settingsCmd = new ListSettingsCommand();
22
+
23
+ registry.register(agentsCmd);
24
+ registry.register(reqsCmd);
25
+ registry.register(settingsCmd);
26
+
27
+ // Store registry on the adapter — RUICommandResolver uses a module-level
28
+ // singleton registry internally, so this.resolver.registry is undefined.
29
+ this.registry = registry;
30
+ this.resolver = new RUICommandResolver(registry);
31
+ }
32
+
33
+ /**
34
+ * Build menu items based on RUI commands
35
+ * @returns {Promise<Array>} Array of menu items
36
+ */
37
+ async buildMenuItems() {
38
+ if (!this.resolver) {
39
+ this.initialize();
40
+ }
41
+
42
+ const items = [];
43
+
44
+ // Get all available verbs and resources
45
+ const verbs = ['GET', 'POST', 'PUT', 'DELETE'];
46
+ const resources = ['agents', 'requirements', 'settings'];
47
+
48
+ // Add status information (similar to existing implementation)
49
+ await this.addStatusItems(items);
50
+
51
+ // Add separator
52
+ items.push({ type: 'blank', name: '', value: 'blank' });
53
+
54
+ // Build RUI-based menu structure
55
+ for (const verb of verbs) {
56
+ const verbItem = {
57
+ type: 'category',
58
+ name: this.getVerbDisplayName(verb),
59
+ value: `category:${verb}`,
60
+ children: []
61
+ };
62
+
63
+ for (const resource of resources) {
64
+ const command = `${verb} ${resource}`;
65
+ const resolution = this.resolver.resolve(command);
66
+
67
+ if (resolution.success) {
68
+ verbItem.children.push({
69
+ type: 'action',
70
+ name: this.getResourceDisplayName(resource),
71
+ value: command,
72
+ description: resolution.command.description,
73
+ shortcuts: resolution.command.shortcuts
74
+ });
75
+ }
76
+ }
77
+
78
+ if (verbItem.children.length > 0) {
79
+ items.push(verbItem);
80
+ }
81
+ }
82
+
83
+ // Add system commands
84
+ items.push({ type: 'blank', name: '', value: 'blank' });
85
+ items.push({ type: 'action', name: 'Help', value: 'help' });
86
+ items.push({ type: 'action', name: 'Exit', value: 'exit' });
87
+
88
+ return items;
89
+ }
90
+
91
+ /**
92
+ * Add status items to menu
93
+ * @param {Array} items - Menu items array to modify
94
+ */
95
+ async addStatusItems(items) {
96
+ // Auto Mode status
97
+ let autoStatus = { running: false };
98
+ try {
99
+ const { checkAutoModeStatus } = require('./auto-mode');
100
+ autoStatus = await checkAutoModeStatus();
101
+ } catch (_) {}
102
+
103
+ if (autoStatus.running) {
104
+ items.push({
105
+ type: 'setting',
106
+ name: `Auto Mode: Running ✓`,
107
+ value: 'setting:auto'
108
+ });
109
+ } else {
110
+ items.push({
111
+ type: 'setting',
112
+ name: `Auto Mode: Stopped ○`,
113
+ value: 'setting:auto'
114
+ });
115
+ }
116
+
117
+ // Requirements summary
118
+ try {
119
+ const { countRequirements, getSyncStatus, getAgentConnectivityStatus } = require('./status-helpers-extracted');
120
+ const counts = await countRequirements();
121
+ if (counts) {
122
+ const total = (counts.todoCount || 0) + (counts.toVerifyCount || 0) + (counts.verifiedCount || 0);
123
+ const pct = n => total > 0 ? Math.round((n / total) * 100) : 0;
124
+
125
+ const reqLine = `Requirements: ${counts.todoCount} (${pct(counts.todoCount)}% todo), ` +
126
+ `${counts.toVerifyCount} (${pct(counts.toVerifyCount)}% verify), ` +
127
+ `${counts.verifiedCount} (${pct(counts.verifiedCount)}% done)`;
128
+
129
+ items.push({ type: 'setting', name: reqLine, value: 'setting:requirements' });
130
+ }
131
+ } catch (_) {}
132
+ }
133
+
134
+ /**
135
+ * Get display name for verb
136
+ * @param {string} verb - Verb name
137
+ * @returns {string} Display name
138
+ */
139
+ getVerbDisplayName(verb) {
140
+ const displayNames = {
141
+ 'GET': 'Lists (GET)',
142
+ 'POST': 'Create (POST)',
143
+ 'PUT': 'Update (PUT)',
144
+ 'DELETE': 'Delete (DELETE)'
145
+ };
146
+ return displayNames[verb] || verb;
147
+ }
148
+
149
+ /**
150
+ * Get display name for resource
151
+ * @param {string} resource - Resource name
152
+ * @returns {string} Display name
153
+ */
154
+ getResourceDisplayName(resource) {
155
+ const displayNames = {
156
+ 'agents': 'Agents',
157
+ 'requirements': 'Requirements (reqs)',
158
+ 'settings': 'Settings'
159
+ };
160
+ return displayNames[resource] || resource;
161
+ }
162
+
163
+ /**
164
+ * Handle menu action using RUI pattern
165
+ * @param {string} action - Action value from menu
166
+ * @returns {Promise<Object>} Action result
167
+ */
168
+ async handleAction(action) {
169
+ if (!this.resolver) {
170
+ this.initialize();
171
+ }
172
+
173
+ // Handle special actions
174
+ if (action === 'help') {
175
+ return await this.showHelp();
176
+ }
177
+
178
+ if (action === 'exit') {
179
+ return { action: 'exit' };
180
+ }
181
+
182
+ if (action.startsWith('setting:')) {
183
+ return await this.handleSettingAction(action);
184
+ }
185
+
186
+ if (action.startsWith('category:')) {
187
+ return await this.handleCategoryAction(action);
188
+ }
189
+
190
+ // Handle RUI commands
191
+ const resolution = this.resolver.resolve(action);
192
+
193
+ if (!resolution.success) {
194
+ return {
195
+ success: false,
196
+ error: resolution.error,
197
+ suggestions: resolution.suggestions
198
+ };
199
+ }
200
+
201
+ try {
202
+ const result = await resolution.command.execute();
203
+ return {
204
+ success: true,
205
+ data: result.data,
206
+ command: action,
207
+ executionTime: result.executionTime
208
+ };
209
+ } catch (error) {
210
+ return {
211
+ success: false,
212
+ error: error.message,
213
+ command: action
214
+ };
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Show help information
220
+ * @returns {Promise<Object>} Help result
221
+ */
222
+ async showHelp() {
223
+ const commands = (this.registry.getAll || this.registry.getAllCommands).call(this.registry);
224
+ const helpText = commands.map(cmd => {
225
+ const shortcuts = cmd.shortcuts.length > 0 ? ` (${cmd.shortcuts.join(', ')})` : '';
226
+ return `${cmd.verb} ${cmd.resource}${shortcuts} - ${cmd.description}`;
227
+ }).join('\n');
228
+
229
+ return {
230
+ success: true,
231
+ data: {
232
+ type: 'help',
233
+ content: helpText
234
+ }
235
+ };
236
+ }
237
+
238
+ /**
239
+ * Handle setting actions
240
+ * @param {string} action - Setting action
241
+ * @returns {Promise<Object>} Setting result
242
+ */
243
+ async handleSettingAction(action) {
244
+ switch (action) {
245
+ case 'setting:auto':
246
+ try {
247
+ const { checkAutoModeStatus, stopAutoMode } = require('./auto-mode');
248
+ const status = await checkAutoModeStatus();
249
+ if (status.running) {
250
+ await stopAutoMode('manual');
251
+ return {
252
+ success: true,
253
+ message: 'Auto mode stopped'
254
+ };
255
+ } else {
256
+ return {
257
+ success: true,
258
+ message: 'To start auto mode, use: app POST auto-mode'
259
+ };
260
+ }
261
+ } catch (error) {
262
+ return {
263
+ success: false,
264
+ error: error.message
265
+ };
266
+ }
267
+
268
+ default:
269
+ return {
270
+ success: false,
271
+ error: `Unknown setting action: ${action}`
272
+ };
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Handle category actions (show category details)
278
+ * @param {string} action - Category action
279
+ * @returns {Promise<Object>} Category result
280
+ */
281
+ async handleCategoryAction(action) {
282
+ const verb = action.replace('category:', '');
283
+ // getByVerb returns full command objects; extract resource names
284
+ const commands = this.registry.getByVerb ? this.registry.getByVerb(verb) : [];
285
+ const resources = commands.map(c => c.resource);
286
+
287
+ return {
288
+ success: true,
289
+ data: {
290
+ type: 'category',
291
+ verb: verb,
292
+ resources: resources
293
+ }
294
+ };
295
+ }
296
+
297
+ /**
298
+ * Get equivalent command for display
299
+ * @param {string} action - Action value
300
+ * @returns {string} Equivalent command
301
+ */
302
+ getEquivalentCommand(action) {
303
+ if (action.startsWith('setting:') || action.startsWith('category:') ||
304
+ action === 'help' || action === 'exit') {
305
+ return action;
306
+ }
307
+ return action;
308
+ }
309
+ }
310
+
311
+ module.exports = RUITRUIAdapter;
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Simple TRUI Interface
3
+ * Basic implementation for testing
4
+ */
5
+
6
+ const inquirer = require('inquirer');
7
+ const chalk = require('chalk');
8
+ const boxen = require('boxen');
9
+
10
+ class SimpleTRUI {
11
+ constructor() {
12
+ this.currentView = 'main';
13
+ }
14
+
15
+ async start() {
16
+ console.clear();
17
+ this.showWelcome();
18
+ await this.showMainMenu();
19
+ }
20
+
21
+ showWelcome() {
22
+ const welcome = boxen(
23
+ chalk.cyan.bold('🎯 Vibe Coding Machine - TRUI Interface\n\n') +
24
+ chalk.white('Text REST UI - Navigate with REST-based commands\n') +
25
+ chalk.gray('Type "help" for available commands or "quit" to exit\n'),
26
+ {
27
+ padding: 1,
28
+ margin: 1,
29
+ borderStyle: 'round',
30
+ borderColor: 'cyan'
31
+ }
32
+ );
33
+ console.log(welcome);
34
+ }
35
+
36
+ async showMainMenu() {
37
+ while (true) {
38
+ const { action } = await inquirer.prompt([
39
+ {
40
+ type: 'list',
41
+ name: 'action',
42
+ message: chalk.cyan('📍 Navigate to:'),
43
+ choices: [
44
+ { name: '🤖 Agents', value: 'agents' },
45
+ { name: '📋 Requirements', value: 'requirements' },
46
+ { name: '⚙️ Settings', value: 'settings' },
47
+ { name: '❓ Help', value: 'help' },
48
+ { name: '🚪 Exit', value: 'quit' }
49
+ ],
50
+ pageSize: 10
51
+ }
52
+ ]);
53
+
54
+ if (action === 'quit') {
55
+ console.log(chalk.yellow('👋 Goodbye!'));
56
+ process.exit(0);
57
+ }
58
+
59
+ await this.handleAction(action);
60
+ }
61
+ }
62
+
63
+ async handleAction(action) {
64
+ switch (action) {
65
+ case 'agents':
66
+ await this.showAgentsMenu();
67
+ break;
68
+ case 'requirements':
69
+ await this.showRequirementsMenu();
70
+ break;
71
+ case 'settings':
72
+ await this.showSettingsMenu();
73
+ break;
74
+ case 'help':
75
+ this.showHelp();
76
+ break;
77
+ }
78
+ }
79
+
80
+ async showAgentsMenu() {
81
+ console.log(chalk.blue('\n🤖 Agents Management\n'));
82
+
83
+ const { action } = await inquirer.prompt([
84
+ {
85
+ type: 'list',
86
+ name: 'action',
87
+ message: 'Choose action:',
88
+ choices: [
89
+ { name: '📝 List Agents', value: 'list' },
90
+ { name: '⬅️ Back', value: 'back' }
91
+ ]
92
+ }
93
+ ]);
94
+
95
+ if (action === 'list') {
96
+ this.showAgentsList();
97
+ }
98
+ }
99
+
100
+ async showRequirementsMenu() {
101
+ console.log(chalk.blue('\n📋 Requirements Management\n'));
102
+
103
+ const { action } = await inquirer.prompt([
104
+ {
105
+ type: 'list',
106
+ name: 'action',
107
+ message: 'Choose action:',
108
+ choices: [
109
+ { name: '📝 List Requirements', value: 'list' },
110
+ { name: '⬅️ Back', value: 'back' }
111
+ ]
112
+ }
113
+ ]);
114
+
115
+ if (action === 'list') {
116
+ this.showRequirementsList();
117
+ }
118
+ }
119
+
120
+ async showSettingsMenu() {
121
+ console.log(chalk.blue('\n⚙️ Settings Management\n'));
122
+
123
+ const { action } = await inquirer.prompt([
124
+ {
125
+ type: 'list',
126
+ name: 'action',
127
+ message: 'Choose action:',
128
+ choices: [
129
+ { name: '📝 List Settings', value: 'list' },
130
+ { name: '⬅️ Back', value: 'back' }
131
+ ]
132
+ }
133
+ ]);
134
+
135
+ if (action === 'list') {
136
+ this.showSettingsList();
137
+ }
138
+ }
139
+
140
+ showAgentsList() {
141
+ const agents = [
142
+ { id: 'cursor-cli', name: 'Cursor CLI Agent', status: 'enabled' },
143
+ { id: 'claude-code', name: 'Claude Code Agent', status: 'disabled' },
144
+ { id: 'vscode', name: 'VS Code Agent', status: 'enabled' }
145
+ ];
146
+
147
+ console.log(chalk.green('\n📋 Available Agents:\n'));
148
+ agents.forEach(agent => {
149
+ const status = agent.status === 'enabled' ? chalk.green('✓') : chalk.red('✗');
150
+ console.log(` ${status} ${agent.name} (${agent.id})`);
151
+ });
152
+ console.log('');
153
+ }
154
+
155
+ showRequirementsList() {
156
+ const requirements = [
157
+ { id: 'REQ-001', title: 'Implement RUI Pattern', status: 'in-progress' },
158
+ { id: 'REQ-002', title: 'Fix Test Suite', status: 'pending' },
159
+ { id: 'REQ-003', title: 'Update Documentation', status: 'completed' }
160
+ ];
161
+
162
+ console.log(chalk.green('\n📋 Requirements:\n'));
163
+ requirements.forEach(req => {
164
+ const status = req.status === 'completed' ? chalk.green('✓') :
165
+ req.status === 'in-progress' ? chalk.yellow('⟳') : chalk.gray('○');
166
+ console.log(` ${status} ${req.id}: ${req.title}`);
167
+ });
168
+ console.log('');
169
+ }
170
+
171
+ showSettingsList() {
172
+ const settings = [
173
+ { key: 'auto-start', value: 'enabled', description: 'Auto-start mode' },
174
+ { key: 'timeout', value: '30000', description: 'Command timeout (ms)' },
175
+ { key: 'debug', value: 'false', description: 'Debug mode' }
176
+ ];
177
+
178
+ console.log(chalk.green('\n⚙️ Current Settings:\n'));
179
+ settings.forEach(setting => {
180
+ console.log(` ${setting.key}: ${setting.value} (${setting.description})`);
181
+ });
182
+ console.log('');
183
+ }
184
+
185
+ showHelp() {
186
+ const help = [
187
+ { command: 'list agents', description: 'List all available agents' },
188
+ { command: 'list requirements', description: 'List all requirements' },
189
+ { command: 'list settings', description: 'Show current settings' },
190
+ { command: 'help', description: 'Show this help message' },
191
+ { command: 'quit', description: 'Exit the application' }
192
+ ];
193
+
194
+ console.log(chalk.blue('\n❓ Available Commands:\n'));
195
+ help.forEach(cmd => {
196
+ console.log(` ${chalk.cyan(cmd.command)} - ${cmd.description}`);
197
+ });
198
+ console.log('');
199
+ console.log(chalk.gray('💡 This is a simplified TRUI interface for testing purposes.'));
200
+ console.log('');
201
+ }
202
+ }
203
+
204
+ module.exports = { SimpleTRUI };
@@ -0,0 +1,125 @@
1
+ const fs = require('fs-extra');
2
+ const { getRepoPath, getRequirementsPath } = require('vibecodingmachine-core');
3
+
4
+ async function countRequirements() {
5
+ try {
6
+ const { getProjectRequirementStats } = require('vibecodingmachine-core');
7
+ const repoPath = await getRepoPath();
8
+ return await getProjectRequirementStats(repoPath);
9
+ } catch (error) {
10
+ return null;
11
+ }
12
+ }
13
+
14
+ async function getSyncStatus() {
15
+ try {
16
+ const SyncEngine = require('vibecodingmachine-core/src/sync/sync-engine');
17
+ const syncEngine = new SyncEngine();
18
+ await syncEngine.initialize();
19
+ const status = syncEngine.getStatus();
20
+ syncEngine.stop();
21
+
22
+ if (!status.isOnline && status.queuedChanges > 0) {
23
+ return `[Offline: ${status.queuedChanges} queued]`;
24
+ } else if (!status.isOnline) {
25
+ return '[Offline]';
26
+ } else if (status.isSyncing) {
27
+ return '[Syncing...]';
28
+ } else if (status.lastSyncTime) {
29
+ const timeSinceSync = Date.now() - status.lastSyncTime;
30
+ const minutesAgo = Math.floor(timeSinceSync / (1000 * 60));
31
+ if (minutesAgo < 1) {
32
+ return '[Sync: ✓ just now]';
33
+ } else if (minutesAgo < 60) {
34
+ return `[Sync: ✓ ${minutesAgo}m ago]`;
35
+ } else {
36
+ const hoursAgo = Math.floor(minutesAgo / 60);
37
+ return `[Sync: ✓ ${hoursAgo}h ago]`;
38
+ }
39
+ } else {
40
+ return '[Never synced]';
41
+ }
42
+ } catch (error) {
43
+ return '[Sync unavailable]';
44
+ }
45
+ }
46
+
47
+ async function getCurrentProgress() {
48
+ try {
49
+ const { getRequirementsPath } = require('vibecodingmachine-core');
50
+ const reqPath = await getRequirementsPath();
51
+
52
+ if (!reqPath || !await fs.pathExists(reqPath)) {
53
+ return null;
54
+ }
55
+
56
+ const content = await fs.readFile(reqPath, 'utf8');
57
+ const lines = content.split('\n');
58
+
59
+ let requirement = null;
60
+ let inTodoSection = false;
61
+
62
+ for (let i = 0; i < lines.length; i++) {
63
+ const line = lines[i];
64
+
65
+ // Find TODO section
66
+ if (line.includes('## ⏳ Requirements not yet completed') || line.includes('## Requirements not yet completed')) {
67
+ inTodoSection = true;
68
+ continue;
69
+ }
70
+
71
+ // Exit TODO section when we hit another section
72
+ if (inTodoSection && line.trim().startsWith('##')) {
73
+ break;
74
+ }
75
+
76
+ // Find first TODO requirement
77
+ if (inTodoSection) {
78
+ const trimmed = line.trim();
79
+ if (trimmed.startsWith('- ') || trimmed.startsWith('* ')) {
80
+ requirement = trimmed.substring(2); // Remove "- " or "* " prefix
81
+ break;
82
+ }
83
+ }
84
+ }
85
+
86
+ return requirement ? { status: 'PREPARE', requirement } : null;
87
+ } catch (error) {
88
+ return null;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Get agent connectivity status for display
94
+ * @returns {string} - Formatted agent connectivity status
95
+ */
96
+ async function getAgentConnectivityStatus() {
97
+ try {
98
+ const { checkAllProviders } = require('./provider-checker');
99
+ const result = await checkAllProviders();
100
+
101
+ if (!result || !result.results) {
102
+ return '[Agents unavailable]';
103
+ }
104
+
105
+ const total = Object.keys(result.results).length;
106
+ const reachable = Object.values(result.results).filter(r => r.status === 'success').length;
107
+
108
+ if (reachable === total) {
109
+ return `[Agents: ✓ ${reachable}/${total}]`;
110
+ } else if (reachable > 0) {
111
+ return `[Agents: ⚠️ ${reachable}/${total}]`;
112
+ } else {
113
+ return `[Agents: ✗ 0/${total}]`;
114
+ }
115
+ } catch (error) {
116
+ return '[Agents unavailable]';
117
+ }
118
+ }
119
+
120
+ module.exports = {
121
+ countRequirements,
122
+ getSyncStatus,
123
+ getCurrentProgress,
124
+ getAgentConnectivityStatus
125
+ };