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.
- package/bin/vibecodingmachine.js +124 -0
- package/package.json +3 -2
- package/src/commands/agents-check.js +69 -0
- package/src/commands/auto-direct.js +930 -145
- package/src/commands/auto.js +26 -4
- package/src/commands/ide.js +2 -1
- package/src/commands/requirements.js +23 -27
- package/src/utils/auto-mode.js +4 -1
- package/src/utils/cline-js-handler.js +218 -0
- package/src/utils/config.js +22 -0
- package/src/utils/display-formatters-complete.js +229 -0
- package/src/utils/display-formatters-extracted.js +219 -0
- package/src/utils/display-formatters.js +157 -0
- package/src/utils/feedback-handler.js +143 -0
- package/src/utils/ide-detection-complete.js +126 -0
- package/src/utils/ide-detection-extracted.js +116 -0
- package/src/utils/ide-detection.js +124 -0
- package/src/utils/interactive-backup.js +5664 -0
- package/src/utils/interactive-broken.js +280 -0
- package/src/utils/interactive.js +31 -5534
- package/src/utils/provider-checker.js +410 -0
- package/src/utils/provider-manager.js +251 -0
- package/src/utils/provider-registry.js +18 -9
- package/src/utils/requirement-actions.js +884 -0
- package/src/utils/requirements-navigator.js +585 -0
- package/src/utils/rui-trui-adapter.js +311 -0
- package/src/utils/simple-trui.js +204 -0
- package/src/utils/status-helpers-extracted.js +125 -0
- package/src/utils/status-helpers.js +107 -0
- package/src/utils/trui-debug.js +261 -0
- package/src/utils/trui-feedback.js +133 -0
- package/src/utils/trui-nav-agents.js +119 -0
- package/src/utils/trui-nav-requirements.js +268 -0
- package/src/utils/trui-nav-settings.js +157 -0
- package/src/utils/trui-nav-specifications.js +139 -0
- package/src/utils/trui-navigation.js +303 -0
- package/src/utils/trui-provider-manager.js +182 -0
- package/src/utils/trui-quick-menu.js +365 -0
- package/src/utils/trui-req-actions.js +372 -0
- package/src/utils/trui-req-tree.js +534 -0
- package/src/utils/trui-specifications.js +359 -0
- package/src/utils/trui-text-editor.js +350 -0
- package/src/utils/trui-windsurf.js +336 -0
- package/src/utils/welcome-screen-extracted.js +135 -0
- 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
|
+
};
|