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.
Files changed (39) hide show
  1. package/README.md +85 -85
  2. package/bin/commands/agent-commands.js +295 -28
  3. package/bin/vibecodingmachine.js +0 -0
  4. package/package.json +2 -2
  5. package/scripts/postinstall.js +161 -161
  6. package/src/commands/auth.js +100 -100
  7. package/src/commands/auto-execution.js +120 -32
  8. package/src/commands/auto-requirement-management.js +9 -9
  9. package/src/commands/auto-status-helpers.js +6 -12
  10. package/src/commands/computers.js +318 -318
  11. package/src/commands/feature.js +123 -123
  12. package/src/commands/locale.js +72 -72
  13. package/src/commands/repo.js +163 -163
  14. package/src/commands/setup.js +93 -93
  15. package/src/commands/sync.js +287 -287
  16. package/src/index.js +5 -5
  17. package/src/utils/agent-selector.js +50 -50
  18. package/src/utils/asset-cleanup.js +60 -60
  19. package/src/utils/auth.js +6 -0
  20. package/src/utils/auto-mode-ansi-ui.js +237 -237
  21. package/src/utils/auto-mode-simple-ui.js +141 -141
  22. package/src/utils/copy-with-progress.js +167 -167
  23. package/src/utils/download-with-progress.js +84 -84
  24. package/src/utils/keyboard-handler.js +153 -153
  25. package/src/utils/kiro-installer.js +178 -178
  26. package/src/utils/logger.js +4 -4
  27. package/src/utils/persistent-header.js +114 -114
  28. package/src/utils/prompt-helper.js +63 -63
  29. package/src/utils/provider-checker/agent-runner.js +110 -31
  30. package/src/utils/provider-checker/ide-manager.js +37 -8
  31. package/src/utils/provider-checker/provider-validator.js +50 -0
  32. package/src/utils/provider-checker/requirements-manager.js +21 -6
  33. package/src/utils/status-card.js +121 -121
  34. package/src/utils/stdout-interceptor.js +127 -127
  35. package/src/utils/trui-main-handlers.js +41 -8
  36. package/src/utils/trui-main-menu.js +10 -3
  37. package/src/utils/trui-nav-agents.js +23 -33
  38. package/src/utils/trui-navigation.js +2 -2
  39. package/src/utils/user-tracking.js +299 -299
@@ -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('agents:')) {
69
- await handleAgentSelection(value, navigation);
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`,