vibecodingmachine-cli 2026.3.9-907 → 2026.3.10-1548
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/README.md +85 -85
- package/bin/commands/agent-commands.js +295 -28
- package/bin/vibecodingmachine.js +0 -0
- package/package.json +2 -2
- package/scripts/postinstall.js +161 -161
- package/src/commands/auth.js +100 -100
- package/src/commands/auto-execution.js +120 -32
- package/src/commands/auto-requirement-management.js +9 -9
- package/src/commands/auto-status-helpers.js +6 -12
- package/src/commands/computers.js +318 -318
- package/src/commands/feature.js +123 -123
- package/src/commands/locale.js +72 -72
- package/src/commands/repo.js +163 -163
- package/src/commands/setup.js +93 -93
- package/src/commands/sync.js +287 -287
- package/src/index.js +5 -5
- package/src/utils/agent-selector.js +50 -50
- package/src/utils/asset-cleanup.js +60 -60
- package/src/utils/auth.js +6 -0
- package/src/utils/auto-mode-ansi-ui.js +237 -237
- package/src/utils/auto-mode-simple-ui.js +141 -141
- package/src/utils/copy-with-progress.js +167 -167
- package/src/utils/download-with-progress.js +84 -84
- package/src/utils/keyboard-handler.js +153 -153
- package/src/utils/kiro-installer.js +178 -178
- package/src/utils/logger.js +4 -4
- package/src/utils/persistent-header.js +114 -114
- package/src/utils/prompt-helper.js +63 -63
- package/src/utils/provider-checker/agent-runner.js +110 -31
- package/src/utils/provider-checker/ide-manager.js +37 -8
- package/src/utils/provider-checker/provider-validator.js +50 -0
- package/src/utils/provider-checker/requirements-manager.js +21 -6
- package/src/utils/status-card.js +121 -121
- package/src/utils/stdout-interceptor.js +127 -127
- package/src/utils/trui-main-handlers.js +41 -8
- package/src/utils/trui-main-menu.js +10 -3
- package/src/utils/trui-nav-agents.js +23 -33
- package/src/utils/trui-navigation.js +2 -2
- package/src/utils/user-tracking.js +299 -299
package/src/utils/status-card.js
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const boxen = require('boxen');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Render a status card showing current requirement progress
|
|
6
|
-
* Similar to the purple card in the GUI
|
|
7
|
-
* @param {object} status - Current status object
|
|
8
|
-
* @param {string} status.requirement - Current requirement being worked on
|
|
9
|
-
* @param {string} status.step - Current step (PREPARE, ACT, CLEAN UP, VERIFY, DONE)
|
|
10
|
-
* @param {number} status.chatCount - Current chat count
|
|
11
|
-
* @param {number|null} status.maxChats - Maximum chats or null for unlimited
|
|
12
|
-
* @param {number} status.progress - Progress percentage (0-100)
|
|
13
|
-
* @returns {string} Formatted status card
|
|
14
|
-
*/
|
|
15
|
-
function renderStatusCard(status) {
|
|
16
|
-
const {
|
|
17
|
-
requirement = 'No requirement loaded',
|
|
18
|
-
step = 'UNKNOWN',
|
|
19
|
-
chatCount = 0,
|
|
20
|
-
maxChats = null,
|
|
21
|
-
progress = 0
|
|
22
|
-
} = status;
|
|
23
|
-
|
|
24
|
-
// Step color mapping
|
|
25
|
-
const stepColors = {
|
|
26
|
-
'PREPARE': chalk.cyan,
|
|
27
|
-
'ACT': chalk.yellow,
|
|
28
|
-
'CLEAN UP': chalk.magenta,
|
|
29
|
-
'VERIFY': chalk.blue,
|
|
30
|
-
'DONE': chalk.green,
|
|
31
|
-
'UNKNOWN': chalk.gray
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const stepColor = stepColors[step] || chalk.gray;
|
|
35
|
-
|
|
36
|
-
// Progress bar
|
|
37
|
-
const barWidth = 30;
|
|
38
|
-
const filledWidth = Math.round((progress / 100) * barWidth);
|
|
39
|
-
const emptyWidth = barWidth - filledWidth;
|
|
40
|
-
const progressBar = chalk.green('█'.repeat(filledWidth)) + chalk.gray('░'.repeat(emptyWidth));
|
|
41
|
-
|
|
42
|
-
// Chat counter
|
|
43
|
-
const chatDisplay = maxChats
|
|
44
|
-
? `Chat ${chatCount}/${maxChats}`
|
|
45
|
-
: `Chat ${chatCount} (unlimited)`;
|
|
46
|
-
|
|
47
|
-
// Build card content
|
|
48
|
-
const content = [
|
|
49
|
-
chalk.bold('📋 Current Requirement'),
|
|
50
|
-
'',
|
|
51
|
-
chalk.white(requirement.length > 60 ? requirement.substring(0, 57) + '...' : requirement),
|
|
52
|
-
'',
|
|
53
|
-
chalk.bold('🚦 Status: ') + stepColor.bold(step),
|
|
54
|
-
'',
|
|
55
|
-
`${progressBar} ${progress}%`,
|
|
56
|
-
'',
|
|
57
|
-
chalk.gray(chatDisplay)
|
|
58
|
-
].join('\n');
|
|
59
|
-
|
|
60
|
-
// Render with boxen (purple/magenta border like the GUI)
|
|
61
|
-
return boxen(content, {
|
|
62
|
-
padding: 1,
|
|
63
|
-
margin: { top: 0, right: 0, bottom: 1, left: 0 },
|
|
64
|
-
borderStyle: 'round',
|
|
65
|
-
borderColor: 'magenta',
|
|
66
|
-
title: 'Auto Mode Status',
|
|
67
|
-
titleAlignment: 'center',
|
|
68
|
-
width: 80
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Clear the terminal and move cursor to top
|
|
74
|
-
*/
|
|
75
|
-
function clearAndMoveToTop() {
|
|
76
|
-
// ANSI escape codes
|
|
77
|
-
process.stdout.write('\x1B[2J'); // Clear entire screen
|
|
78
|
-
process.stdout.write('\x1B[H'); // Move cursor to home (top-left)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Move cursor up N lines
|
|
83
|
-
* @param {number} lines - Number of lines to move up
|
|
84
|
-
*/
|
|
85
|
-
function moveCursorUp(lines) {
|
|
86
|
-
process.stdout.write(`\x1B[${lines}A`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Save cursor position
|
|
91
|
-
*/
|
|
92
|
-
function saveCursor() {
|
|
93
|
-
process.stdout.write('\x1B[s');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Restore cursor position
|
|
98
|
-
*/
|
|
99
|
-
function restoreCursor() {
|
|
100
|
-
process.stdout.write('\x1B[u');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Render the menu header and status card together
|
|
105
|
-
* @param {string} menuContent - The menu content to display
|
|
106
|
-
* @param {object} status - Status object for the status card
|
|
107
|
-
*/
|
|
108
|
-
function renderHeaderWithStatus(menuContent, status) {
|
|
109
|
-
clearAndMoveToTop();
|
|
110
|
-
console.log(menuContent);
|
|
111
|
-
console.log(renderStatusCard(status));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
module.exports = {
|
|
115
|
-
renderStatusCard,
|
|
116
|
-
clearAndMoveToTop,
|
|
117
|
-
moveCursorUp,
|
|
118
|
-
saveCursor,
|
|
119
|
-
restoreCursor,
|
|
120
|
-
renderHeaderWithStatus
|
|
121
|
-
};
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const boxen = require('boxen');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Render a status card showing current requirement progress
|
|
6
|
+
* Similar to the purple card in the GUI
|
|
7
|
+
* @param {object} status - Current status object
|
|
8
|
+
* @param {string} status.requirement - Current requirement being worked on
|
|
9
|
+
* @param {string} status.step - Current step (PREPARE, ACT, CLEAN UP, VERIFY, DONE)
|
|
10
|
+
* @param {number} status.chatCount - Current chat count
|
|
11
|
+
* @param {number|null} status.maxChats - Maximum chats or null for unlimited
|
|
12
|
+
* @param {number} status.progress - Progress percentage (0-100)
|
|
13
|
+
* @returns {string} Formatted status card
|
|
14
|
+
*/
|
|
15
|
+
function renderStatusCard(status) {
|
|
16
|
+
const {
|
|
17
|
+
requirement = 'No requirement loaded',
|
|
18
|
+
step = 'UNKNOWN',
|
|
19
|
+
chatCount = 0,
|
|
20
|
+
maxChats = null,
|
|
21
|
+
progress = 0
|
|
22
|
+
} = status;
|
|
23
|
+
|
|
24
|
+
// Step color mapping
|
|
25
|
+
const stepColors = {
|
|
26
|
+
'PREPARE': chalk.cyan,
|
|
27
|
+
'ACT': chalk.yellow,
|
|
28
|
+
'CLEAN UP': chalk.magenta,
|
|
29
|
+
'VERIFY': chalk.blue,
|
|
30
|
+
'DONE': chalk.green,
|
|
31
|
+
'UNKNOWN': chalk.gray
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const stepColor = stepColors[step] || chalk.gray;
|
|
35
|
+
|
|
36
|
+
// Progress bar
|
|
37
|
+
const barWidth = 30;
|
|
38
|
+
const filledWidth = Math.round((progress / 100) * barWidth);
|
|
39
|
+
const emptyWidth = barWidth - filledWidth;
|
|
40
|
+
const progressBar = chalk.green('█'.repeat(filledWidth)) + chalk.gray('░'.repeat(emptyWidth));
|
|
41
|
+
|
|
42
|
+
// Chat counter
|
|
43
|
+
const chatDisplay = maxChats
|
|
44
|
+
? `Chat ${chatCount}/${maxChats}`
|
|
45
|
+
: `Chat ${chatCount} (unlimited)`;
|
|
46
|
+
|
|
47
|
+
// Build card content
|
|
48
|
+
const content = [
|
|
49
|
+
chalk.bold('📋 Current Requirement'),
|
|
50
|
+
'',
|
|
51
|
+
chalk.white(requirement.length > 60 ? requirement.substring(0, 57) + '...' : requirement),
|
|
52
|
+
'',
|
|
53
|
+
chalk.bold('🚦 Status: ') + stepColor.bold(step),
|
|
54
|
+
'',
|
|
55
|
+
`${progressBar} ${progress}%`,
|
|
56
|
+
'',
|
|
57
|
+
chalk.gray(chatDisplay)
|
|
58
|
+
].join('\n');
|
|
59
|
+
|
|
60
|
+
// Render with boxen (purple/magenta border like the GUI)
|
|
61
|
+
return boxen(content, {
|
|
62
|
+
padding: 1,
|
|
63
|
+
margin: { top: 0, right: 0, bottom: 1, left: 0 },
|
|
64
|
+
borderStyle: 'round',
|
|
65
|
+
borderColor: 'magenta',
|
|
66
|
+
title: 'Auto Mode Status',
|
|
67
|
+
titleAlignment: 'center',
|
|
68
|
+
width: 80
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Clear the terminal and move cursor to top
|
|
74
|
+
*/
|
|
75
|
+
function clearAndMoveToTop() {
|
|
76
|
+
// ANSI escape codes
|
|
77
|
+
process.stdout.write('\x1B[2J'); // Clear entire screen
|
|
78
|
+
process.stdout.write('\x1B[H'); // Move cursor to home (top-left)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Move cursor up N lines
|
|
83
|
+
* @param {number} lines - Number of lines to move up
|
|
84
|
+
*/
|
|
85
|
+
function moveCursorUp(lines) {
|
|
86
|
+
process.stdout.write(`\x1B[${lines}A`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Save cursor position
|
|
91
|
+
*/
|
|
92
|
+
function saveCursor() {
|
|
93
|
+
process.stdout.write('\x1B[s');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Restore cursor position
|
|
98
|
+
*/
|
|
99
|
+
function restoreCursor() {
|
|
100
|
+
process.stdout.write('\x1B[u');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Render the menu header and status card together
|
|
105
|
+
* @param {string} menuContent - The menu content to display
|
|
106
|
+
* @param {object} status - Status object for the status card
|
|
107
|
+
*/
|
|
108
|
+
function renderHeaderWithStatus(menuContent, status) {
|
|
109
|
+
clearAndMoveToTop();
|
|
110
|
+
console.log(menuContent);
|
|
111
|
+
console.log(renderStatusCard(status));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = {
|
|
115
|
+
renderStatusCard,
|
|
116
|
+
clearAndMoveToTop,
|
|
117
|
+
moveCursorUp,
|
|
118
|
+
saveCursor,
|
|
119
|
+
restoreCursor,
|
|
120
|
+
renderHeaderWithStatus
|
|
121
|
+
};
|
|
@@ -1,127 +1,127 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Intercept stdout and stderr to capture console output
|
|
3
|
-
* Allows routing output to custom handlers (like blessed UI) while optionally preserving original output
|
|
4
|
-
*/
|
|
5
|
-
class StdoutInterceptor {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.originalStdoutWrite = null;
|
|
8
|
-
this.originalStderrWrite = null;
|
|
9
|
-
this.outputHandlers = [];
|
|
10
|
-
this.isIntercepting = false;
|
|
11
|
-
this.buffer = '<span style="color: white;">';
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Add a handler that will receive output
|
|
16
|
-
* @param {function} handler - Function that receives output strings
|
|
17
|
-
*/
|
|
18
|
-
addHandler(handler) {
|
|
19
|
-
this.outputHandlers.push(handler);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Remove a handler
|
|
24
|
-
* @param {function} handler - Handler to remove
|
|
25
|
-
*/
|
|
26
|
-
removeHandler(handler) {
|
|
27
|
-
const index = this.outputHandlers.indexOf(handler);
|
|
28
|
-
if (index > -1) {
|
|
29
|
-
this.outputHandlers.splice(index, 1);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Start intercepting stdout/stderr
|
|
35
|
-
* @param {boolean} passthrough - If true, still write to original stdout/stderr
|
|
36
|
-
*/
|
|
37
|
-
start(passthrough = false) {
|
|
38
|
-
if (this.isIntercepting) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
this.isIntercepting = true;
|
|
43
|
-
|
|
44
|
-
// Save original write functions
|
|
45
|
-
this.originalStdoutWrite = process.stdout.write;
|
|
46
|
-
this.originalStderrWrite = process.stderr.write;
|
|
47
|
-
|
|
48
|
-
// Intercept stdout
|
|
49
|
-
process.stdout.write = (chunk, encoding, callback) => {
|
|
50
|
-
const str = chunk.toString();
|
|
51
|
-
|
|
52
|
-
// Call all registered handlers
|
|
53
|
-
this.outputHandlers.forEach(handler => {
|
|
54
|
-
try {
|
|
55
|
-
handler(str);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
// Silently ignore handler errors to prevent breaking the interceptor
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// Optionally pass through to original stdout
|
|
62
|
-
if (passthrough && this.originalStdoutWrite) {
|
|
63
|
-
return this.originalStdoutWrite.call(process.stdout, chunk, encoding, callback);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// If not passing through, still call the callback if provided
|
|
67
|
-
if (typeof callback === 'function') {
|
|
68
|
-
callback();
|
|
69
|
-
}
|
|
70
|
-
return true;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// Intercept stderr
|
|
74
|
-
process.stderr.write = (chunk, encoding, callback) => {
|
|
75
|
-
const str = chunk.toString();
|
|
76
|
-
|
|
77
|
-
// Call all registered handlers
|
|
78
|
-
this.outputHandlers.forEach(handler => {
|
|
79
|
-
try {
|
|
80
|
-
handler(str);
|
|
81
|
-
} catch (error) {
|
|
82
|
-
// Silently ignore handler errors
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Optionally pass through to original stderr
|
|
87
|
-
if (passthrough && this.originalStderrWrite) {
|
|
88
|
-
return this.originalStderrWrite.call(process.stderr, chunk, encoding, callback);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// If not passing through, still call the callback if provided
|
|
92
|
-
if (typeof callback === 'function') {
|
|
93
|
-
callback();
|
|
94
|
-
}
|
|
95
|
-
return true;
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Stop intercepting and restore original stdout/stderr
|
|
101
|
-
*/
|
|
102
|
-
stop() {
|
|
103
|
-
if (!this.isIntercepting) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (this.originalStdoutWrite) {
|
|
108
|
-
process.stdout.write = this.originalStdoutWrite;
|
|
109
|
-
}
|
|
110
|
-
if (this.originalStderrWrite) {
|
|
111
|
-
process.stderr.write = this.originalStderrWrite;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
this.isIntercepting = false;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Clear all handlers
|
|
119
|
-
*/
|
|
120
|
-
clearHandlers() {
|
|
121
|
-
this.outputHandlers = [];
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
module.exports = {
|
|
126
|
-
StdoutInterceptor
|
|
127
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Intercept stdout and stderr to capture console output
|
|
3
|
+
* Allows routing output to custom handlers (like blessed UI) while optionally preserving original output
|
|
4
|
+
*/
|
|
5
|
+
class StdoutInterceptor {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.originalStdoutWrite = null;
|
|
8
|
+
this.originalStderrWrite = null;
|
|
9
|
+
this.outputHandlers = [];
|
|
10
|
+
this.isIntercepting = false;
|
|
11
|
+
this.buffer = '<span style="color: white;">';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Add a handler that will receive output
|
|
16
|
+
* @param {function} handler - Function that receives output strings
|
|
17
|
+
*/
|
|
18
|
+
addHandler(handler) {
|
|
19
|
+
this.outputHandlers.push(handler);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Remove a handler
|
|
24
|
+
* @param {function} handler - Handler to remove
|
|
25
|
+
*/
|
|
26
|
+
removeHandler(handler) {
|
|
27
|
+
const index = this.outputHandlers.indexOf(handler);
|
|
28
|
+
if (index > -1) {
|
|
29
|
+
this.outputHandlers.splice(index, 1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Start intercepting stdout/stderr
|
|
35
|
+
* @param {boolean} passthrough - If true, still write to original stdout/stderr
|
|
36
|
+
*/
|
|
37
|
+
start(passthrough = false) {
|
|
38
|
+
if (this.isIntercepting) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.isIntercepting = true;
|
|
43
|
+
|
|
44
|
+
// Save original write functions
|
|
45
|
+
this.originalStdoutWrite = process.stdout.write;
|
|
46
|
+
this.originalStderrWrite = process.stderr.write;
|
|
47
|
+
|
|
48
|
+
// Intercept stdout
|
|
49
|
+
process.stdout.write = (chunk, encoding, callback) => {
|
|
50
|
+
const str = chunk.toString();
|
|
51
|
+
|
|
52
|
+
// Call all registered handlers
|
|
53
|
+
this.outputHandlers.forEach(handler => {
|
|
54
|
+
try {
|
|
55
|
+
handler(str);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
// Silently ignore handler errors to prevent breaking the interceptor
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Optionally pass through to original stdout
|
|
62
|
+
if (passthrough && this.originalStdoutWrite) {
|
|
63
|
+
return this.originalStdoutWrite.call(process.stdout, chunk, encoding, callback);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// If not passing through, still call the callback if provided
|
|
67
|
+
if (typeof callback === 'function') {
|
|
68
|
+
callback();
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// Intercept stderr
|
|
74
|
+
process.stderr.write = (chunk, encoding, callback) => {
|
|
75
|
+
const str = chunk.toString();
|
|
76
|
+
|
|
77
|
+
// Call all registered handlers
|
|
78
|
+
this.outputHandlers.forEach(handler => {
|
|
79
|
+
try {
|
|
80
|
+
handler(str);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
// Silently ignore handler errors
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Optionally pass through to original stderr
|
|
87
|
+
if (passthrough && this.originalStderrWrite) {
|
|
88
|
+
return this.originalStderrWrite.call(process.stderr, chunk, encoding, callback);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// If not passing through, still call the callback if provided
|
|
92
|
+
if (typeof callback === 'function') {
|
|
93
|
+
callback();
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Stop intercepting and restore original stdout/stderr
|
|
101
|
+
*/
|
|
102
|
+
stop() {
|
|
103
|
+
if (!this.isIntercepting) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (this.originalStdoutWrite) {
|
|
108
|
+
process.stdout.write = this.originalStdoutWrite;
|
|
109
|
+
}
|
|
110
|
+
if (this.originalStderrWrite) {
|
|
111
|
+
process.stderr.write = this.originalStderrWrite;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
this.isIntercepting = false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Clear all handlers
|
|
119
|
+
*/
|
|
120
|
+
clearHandlers() {
|
|
121
|
+
this.outputHandlers = [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = {
|
|
126
|
+
StdoutInterceptor
|
|
127
|
+
};
|
|
@@ -65,8 +65,14 @@ async function handleMainMenuSelection(result, expandedSections, navigation) {
|
|
|
65
65
|
return { shouldContinue: true };
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if (value.startsWith('
|
|
69
|
-
|
|
68
|
+
if (value.startsWith('agent:')) {
|
|
69
|
+
// Extract agent index from "agent:N"
|
|
70
|
+
const agentIndex = parseInt(value.substring(6), 10);
|
|
71
|
+
const { loadAgentsData } = require('./trui-nav-agents');
|
|
72
|
+
const agentsData = await loadAgentsData(navigation);
|
|
73
|
+
if (agentsData && !isNaN(agentIndex)) {
|
|
74
|
+
await handleAgentAction(agentIndex, agentsData, navigation);
|
|
75
|
+
}
|
|
70
76
|
return { shouldContinue: true };
|
|
71
77
|
}
|
|
72
78
|
|
|
@@ -86,6 +92,11 @@ async function handleMainMenuSelection(result, expandedSections, navigation) {
|
|
|
86
92
|
return { shouldContinue: true };
|
|
87
93
|
}
|
|
88
94
|
|
|
95
|
+
if (value === 'action:check-agents') {
|
|
96
|
+
await handleCheckAgents(navigation);
|
|
97
|
+
return { shouldContinue: true };
|
|
98
|
+
}
|
|
99
|
+
|
|
89
100
|
return { shouldContinue: true };
|
|
90
101
|
}
|
|
91
102
|
|
|
@@ -112,6 +123,22 @@ async function handleWindsurfSelection() {
|
|
|
112
123
|
await inquirer.prompt([{ type: 'input', name: 'c', message: '' }]);
|
|
113
124
|
}
|
|
114
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Handle check agents action
|
|
128
|
+
*/
|
|
129
|
+
async function handleCheckAgents(navigation) {
|
|
130
|
+
console.clear();
|
|
131
|
+
try {
|
|
132
|
+
const { checkAgents } = require('../commands/agents-check');
|
|
133
|
+
await checkAgents();
|
|
134
|
+
await navigation.promptContinue();
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.log(chalk.red(`Error checking agents: ${error.message}`));
|
|
137
|
+
await navigation.promptContinue();
|
|
138
|
+
}
|
|
139
|
+
console.clear();
|
|
140
|
+
}
|
|
141
|
+
|
|
115
142
|
/**
|
|
116
143
|
* Show debug information
|
|
117
144
|
*/
|
|
@@ -153,35 +180,41 @@ async function showDebugInfo() {
|
|
|
153
180
|
function setupMainMenuExtraKeys(items) {
|
|
154
181
|
return (str, key, selectedIndex, context) => {
|
|
155
182
|
const currentItem = items[selectedIndex];
|
|
156
|
-
|
|
183
|
+
|
|
157
184
|
// Handle section expansion with space
|
|
158
185
|
if (key.name === 'space' && currentItem && currentItem.value && currentItem.value.startsWith('section:')) {
|
|
159
186
|
const sectionName = currentItem.value.substring(8);
|
|
160
187
|
context.resolveWith(`section:${sectionName}`);
|
|
161
188
|
return true;
|
|
162
189
|
}
|
|
163
|
-
|
|
190
|
+
|
|
191
|
+
// Handle quick action shortcuts - pressing ! or 1 runs agents check
|
|
192
|
+
if (str === '!' || str === '1') {
|
|
193
|
+
context.resolveWith('action:check-agents');
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
|
|
164
197
|
// Handle quick access keys
|
|
165
198
|
if (str === 'r' || str === 'R') {
|
|
166
199
|
context.resolveWith('section:requirements');
|
|
167
200
|
return true;
|
|
168
201
|
}
|
|
169
|
-
|
|
202
|
+
|
|
170
203
|
if (str === 's' || str === 'S') {
|
|
171
204
|
context.resolveWith('section:settings');
|
|
172
205
|
return true;
|
|
173
206
|
}
|
|
174
|
-
|
|
207
|
+
|
|
175
208
|
if (str === 'p' || str === 'P') {
|
|
176
209
|
context.resolveWith('provider-manager');
|
|
177
210
|
return true;
|
|
178
211
|
}
|
|
179
|
-
|
|
212
|
+
|
|
180
213
|
if (str === 'q' || str === 'Q') {
|
|
181
214
|
context.resolveWith('exit');
|
|
182
215
|
return true;
|
|
183
216
|
}
|
|
184
|
-
|
|
217
|
+
|
|
185
218
|
return false;
|
|
186
219
|
};
|
|
187
220
|
}
|
|
@@ -31,8 +31,10 @@ const {
|
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Build main-menu items array with live status at top + inline accordion sections
|
|
34
|
+
* @param {Object} expandedSections - Map of expanded section IDs
|
|
35
|
+
* @param {Object} navigation - TRUINavigation instance for resolving commands
|
|
34
36
|
*/
|
|
35
|
-
async function buildMainMenuItems(expandedSections) {
|
|
37
|
+
async function buildMainMenuItems(expandedSections, navigation) {
|
|
36
38
|
const items = [];
|
|
37
39
|
|
|
38
40
|
// Status section at top
|
|
@@ -42,6 +44,11 @@ async function buildMainMenuItems(expandedSections) {
|
|
|
42
44
|
// Add blank separator
|
|
43
45
|
items.push({ type: 'blank', name: '', value: 'blank' });
|
|
44
46
|
|
|
47
|
+
// Quick Actions section
|
|
48
|
+
items.push({ type: 'separator', name: chalk.gray(' ── Quick Actions ──'), value: 'separator-quick' });
|
|
49
|
+
items.push({ type: 'action', name: ' ! or 1 - Check Enabled Agents', value: 'action:check-agents' });
|
|
50
|
+
items.push({ type: 'blank', name: '', value: 'blank2' });
|
|
51
|
+
|
|
45
52
|
// Requirements section (always present)
|
|
46
53
|
const requirementsData = await loadRequirementsData();
|
|
47
54
|
const requirementsItems = await buildRequirementsSection(requirementsData, expandedSections);
|
|
@@ -58,7 +65,7 @@ async function buildMainMenuItems(expandedSections) {
|
|
|
58
65
|
items.push(...specificationsItems);
|
|
59
66
|
|
|
60
67
|
// Agents section
|
|
61
|
-
const agentsData = await loadAgentsData();
|
|
68
|
+
const agentsData = await loadAgentsData(navigation);
|
|
62
69
|
const agentsItems = buildAgentsSection(agentsData, expandedSections);
|
|
63
70
|
items.push(...agentsItems);
|
|
64
71
|
|
|
@@ -182,7 +189,7 @@ function buildAgentsSection(agentsData, expandedSections) {
|
|
|
182
189
|
const items = [];
|
|
183
190
|
const isExpanded = expandedSections.agents || false;
|
|
184
191
|
const icon = isExpanded ? '▼' : '▶';
|
|
185
|
-
|
|
192
|
+
|
|
186
193
|
items.push({
|
|
187
194
|
type: 'section',
|
|
188
195
|
name: `${icon} 🤖 Agents`,
|