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,336 @@
1
+ /**
2
+ * Windsurf/Cascade Detection and Integration
3
+ *
4
+ * Detects when Windsurf (Cascade) is done typing and automatically
5
+ * sends "continue with your best approach" messages to keep work flowing.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { execSync } = require('child_process');
11
+ const { debugLogger, perfMonitor } = require('./trui-debug');
12
+
13
+ /**
14
+ * Windsurf/Cascade state detector
15
+ */
16
+ class WindsurfDetector {
17
+ constructor() {
18
+ this.isWindsurfActive = false;
19
+ this.lastActivity = null;
20
+ this.pollInterval = null;
21
+ this.continueThreshold = 30000; // 30 seconds of inactivity
22
+ this.projectRoot = this.findProjectRoot();
23
+ }
24
+
25
+ /**
26
+ * Find the project root directory
27
+ */
28
+ findProjectRoot() {
29
+ let currentDir = process.cwd();
30
+ while (currentDir !== path.dirname(currentDir)) {
31
+ const markerFile = path.join(currentDir, '.windsurf-workspace');
32
+ if (fs.existsSync(markerFile) ||
33
+ fs.existsSync(path.join(currentDir, '.git')) ||
34
+ fs.existsSync(path.join(currentDir, 'package.json'))) {
35
+ return currentDir;
36
+ }
37
+ currentDir = path.dirname(currentDir);
38
+ }
39
+ return process.cwd();
40
+ }
41
+
42
+ /**
43
+ * Check if Windsurf/Cascade is running
44
+ */
45
+ isWindsurfRunning() {
46
+ try {
47
+ // Check for Windsurf processes
48
+ const result = execSync('ps aux | grep -i windsurf | grep -v grep', {
49
+ encoding: 'utf8',
50
+ timeout: 5000
51
+ });
52
+ return result.trim().length > 0;
53
+ } catch (error) {
54
+ debugLogger.warn('Windsurf process check failed', { error: error.message });
55
+ return false;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Check if Cascade/Windsurf is actively typing/working
61
+ */
62
+ checkWindsurfActivity() {
63
+ try {
64
+ // Check for recent file modifications in key directories
65
+ const checkDirs = ['src', 'components', 'pages', 'lib', 'app'];
66
+ let recentActivity = false;
67
+
68
+ for (const dir of checkDirs) {
69
+ const fullPath = path.join(this.projectRoot, dir);
70
+ if (fs.existsSync(fullPath)) {
71
+ const stats = fs.statSync(fullPath);
72
+ const now = Date.now();
73
+ const modifiedTime = stats.mtime.getTime();
74
+
75
+ // If modified in last 30 seconds, consider active
76
+ if (now - modifiedTime < 30000) {
77
+ recentActivity = true;
78
+ break;
79
+ }
80
+ }
81
+ }
82
+
83
+ // Also check for specific Windsurf activity files
84
+ const activityFile = path.join(this.projectRoot, '.windsurf-activity');
85
+ if (fs.existsSync(activityFile)) {
86
+ const activityTime = fs.statSync(activityFile).mtime.getTime();
87
+ if (Date.now() - activityTime < 30000) {
88
+ recentActivity = true;
89
+ }
90
+ }
91
+
92
+ return recentActivity;
93
+ } catch (error) {
94
+ debugLogger.warn('Windsurf activity check failed', { error: error.message });
95
+ return false;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Detect when Windsurf completes work (stops typing)
101
+ */
102
+ detectWorkCompletion() {
103
+ const wasActive = this.isWindsurfActive;
104
+ const isActive = this.checkWindsurfActivity();
105
+
106
+ debugLogger.info('Windsurf activity check', { wasActive, isActive });
107
+
108
+ // Transition from active to inactive = work completed
109
+ if (wasActive && !isActive) {
110
+ this.lastActivity = Date.now();
111
+ debugLogger.info('Windsurf work completed detected');
112
+ return true;
113
+ }
114
+
115
+ this.isWindsurfActive = isActive;
116
+ return false;
117
+ }
118
+
119
+ /**
120
+ * Send "continue with best approach" message
121
+ */
122
+ async sendContinueMessage() {
123
+ try {
124
+ debugLogger.info('Sending continue message to Windsurf');
125
+
126
+ // Use AppleScript manager to actually send text to Windsurf
127
+ const { AppleScriptManager } = require('vibecodingmachine-core');
128
+ const applescriptManager = new AppleScriptManager();
129
+
130
+ debugLogger.info('Using AppleScript manager to send to Windsurf');
131
+ const result = await applescriptManager.sendText('continue with your best approach', 'windsurf');
132
+
133
+ debugLogger.info('AppleScript result', { success: result.success, error: result.error, method: result.method });
134
+
135
+ if (result.success) {
136
+ debugLogger.info('Continue message sent successfully to Windsurf');
137
+ return true;
138
+ } else {
139
+ debugLogger.error('Failed to send continue message to Windsurf', { error: result.error, details: result });
140
+
141
+ // Fallback: create file and notification for manual intervention
142
+ try {
143
+ const continueFile = path.join(this.projectRoot, '.windsurf-continue');
144
+ const message = {
145
+ type: 'continue',
146
+ message: 'continue with your best approach',
147
+ timestamp: Date.now(),
148
+ source: 'vcm-trui',
149
+ fallback_reason: result.error || 'Unknown error',
150
+ applescript_result: result
151
+ };
152
+
153
+ fs.writeFileSync(continueFile, JSON.stringify(message, null, 2));
154
+ debugLogger.info('Fallback: Created continue file for manual intervention');
155
+ } catch (fallbackError) {
156
+ debugLogger.error('Fallback also failed', { error: fallbackError.message });
157
+ }
158
+
159
+ return false;
160
+ }
161
+ } catch (error) {
162
+ debugLogger.error('Failed to send continue message', { error: error.message, stack: error.stack });
163
+ return false;
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Start monitoring Windsurf activity
169
+ */
170
+ startMonitoring() {
171
+ if (this.pollInterval) {
172
+ this.stopMonitoring();
173
+ }
174
+
175
+ debugLogger.info('Starting Windsurf activity monitoring');
176
+ this.isWindsurfActive = this.checkWindsurfActivity();
177
+
178
+ this.pollInterval = setInterval(() => {
179
+ if (this.detectWorkCompletion()) {
180
+ this.sendContinueMessage();
181
+ }
182
+ }, 5000); // Check every 5 seconds
183
+
184
+ // Handle cleanup on exit
185
+ process.on('SIGINT', () => this.stopMonitoring());
186
+ process.on('SIGTERM', () => this.stopMonitoring());
187
+ }
188
+
189
+ /**
190
+ * Stop monitoring Windsurf activity
191
+ */
192
+ stopMonitoring() {
193
+ if (this.pollInterval) {
194
+ clearInterval(this.pollInterval);
195
+ this.pollInterval = null;
196
+ debugLogger.info('Windsurf monitoring stopped');
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Get current status
202
+ */
203
+ getStatus() {
204
+ return {
205
+ isRunning: this.isWindsurfRunning(),
206
+ isActive: this.isWindsurfActive,
207
+ lastActivity: this.lastActivity,
208
+ isMonitoring: this.pollInterval !== null
209
+ };
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Integration manager for VCM + Windsurf workflow
215
+ */
216
+ class VCMWindsurfIntegration {
217
+ constructor() {
218
+ this.detector = new WindsurfDetector();
219
+ this.autoContinueEnabled = true;
220
+ this.continueDelay = 5000; // 5 seconds after completion
221
+ }
222
+
223
+ /**
224
+ * Initialize the integration
225
+ */
226
+ async initialize() {
227
+ debugLogger.info('Initializing VCM-Windsurf integration');
228
+
229
+ // Check if Windsurf is running
230
+ if (!this.detector.isWindsurfRunning()) {
231
+ debugLogger.info('Windsurf not detected, integration disabled');
232
+ return false;
233
+ }
234
+
235
+ // Start monitoring
236
+ this.detector.startMonitoring();
237
+
238
+ // Set up automatic continuation
239
+ if (this.autoContinueEnabled) {
240
+ this.setupAutoContinue();
241
+ }
242
+
243
+ debugLogger.info('VCM-Windsurf integration initialized');
244
+ return true;
245
+ }
246
+
247
+ /**
248
+ * Set up automatic continuation when work is detected as complete
249
+ */
250
+ setupAutoContinue() {
251
+ // This works in conjunction with the detector's polling
252
+ debugLogger.info('Auto-continue enabled', { delay: this.continueDelay });
253
+ }
254
+
255
+ /**
256
+ * Manually trigger continue message
257
+ */
258
+ async manualContinue() {
259
+ debugLogger.info('Manual continue triggered');
260
+ return await this.detector.sendContinueMessage();
261
+ }
262
+
263
+ /**
264
+ * Disable auto-continue
265
+ */
266
+ disableAutoContinue() {
267
+ this.autoContinueEnabled = false;
268
+ debugLogger.info('Auto-continue disabled');
269
+ }
270
+
271
+ /**
272
+ * Enable auto-continue
273
+ */
274
+ enableAutoContinue() {
275
+ this.autoContinueEnabled = true;
276
+ debugLogger.info('Auto-continue enabled');
277
+ }
278
+
279
+ /**
280
+ * Get integration status
281
+ */
282
+ getStatus() {
283
+ return {
284
+ ...this.detector.getStatus(),
285
+ autoContinueEnabled: this.autoContinueEnabled,
286
+ continueDelay: this.continueDelay
287
+ };
288
+ }
289
+
290
+ /**
291
+ * Cleanup resources
292
+ */
293
+ cleanup() {
294
+ this.detector.stopMonitoring();
295
+ debugLogger.info('VCM-Windsurf integration cleaned up');
296
+ }
297
+ }
298
+
299
+ // Global integration instance
300
+ let windsurfIntegration = null;
301
+
302
+ /**
303
+ * Initialize Windsurf integration (call from main menu)
304
+ */
305
+ function initializeWindsurfIntegration() {
306
+ if (!windsurfIntegration) {
307
+ windsurfIntegration = new VCMWindsurfIntegration();
308
+ return windsurfIntegration.initialize();
309
+ }
310
+ return true;
311
+ }
312
+
313
+ /**
314
+ * Get Windsurf integration status
315
+ */
316
+ function getWindsurfStatus() {
317
+ return windsurfIntegration ? windsurfIntegration.getStatus() : null;
318
+ }
319
+
320
+ /**
321
+ * Send manual continue message
322
+ */
323
+ async function sendContinueToWindsurf() {
324
+ if (windsurfIntegration) {
325
+ return await windsurfIntegration.manualContinue();
326
+ }
327
+ return false;
328
+ }
329
+
330
+ module.exports = {
331
+ WindsurfDetector,
332
+ VCMWindsurfIntegration,
333
+ initializeWindsurfIntegration,
334
+ getWindsurfStatus,
335
+ sendContinueToWindsurf
336
+ };
@@ -0,0 +1,135 @@
1
+ const chalk = require('chalk');
2
+ const boxen = require('boxen');
3
+ const { getHostname, requirementsExists, isGitRepo, getCurrentBranch, hasUncommittedChanges, t } = require('vibecodingmachine-core');
4
+ const { checkAutoModeStatus } = require('./auto-mode');
5
+ const { formatIDEName, getAgentDisplayName, formatPath } = require('./display-formatters-extracted');
6
+ const { countRequirements, getSyncStatus, getCurrentProgress } = require('./status-helpers-extracted');
7
+ const pkg = require('../../package.json');
8
+
9
+ async function showWelcomeScreen() {
10
+
11
+
12
+ const repoPath = process.cwd(); // Always use current working directory
13
+ const autoStatus = await checkAutoModeStatus();
14
+ const hostname = getHostname();
15
+
16
+ // Get current IDE from config
17
+ const { getAutoConfig } = require('./config');
18
+ const autoConfig = await getAutoConfig();
19
+
20
+ // Check for requirements file
21
+ const hasRequirements = await requirementsExists();
22
+
23
+ // Count requirements if file exists
24
+ const counts = hasRequirements ? await countRequirements() : null;
25
+
26
+ // Clear the screen using console.clear() for better cross-platform compatibility
27
+ // This ensures proper screen refresh and prevents text overlap
28
+ console.clear();
29
+
30
+ // Get version from package.json
31
+ const version = `v${pkg.version}`;
32
+
33
+ // Display welcome banner with version
34
+ console.log('\n' + boxen(
35
+ chalk.bold.cyan('Vibe Coding Machine!') + '\n' +
36
+ chalk.gray(version) + '\n' +
37
+ chalk.gray(t('banner.tagline')),
38
+ {
39
+ padding: 1,
40
+ margin: 0,
41
+ borderStyle: 'round',
42
+ borderColor: 'cyan'
43
+ }
44
+ ));
45
+
46
+ // Display feedback hint at the top of every screen
47
+ console.log(chalk.gray('💡 Press F for feedback - Share your thoughts anytime'));
48
+
49
+ // Display repository and system info
50
+ console.log();
51
+ console.log(chalk.gray(t('system.repo').padEnd(25)), formatPath(repoPath));
52
+
53
+ // Display git branch if in a git repo
54
+ try {
55
+ const { isGitRepo, getCurrentBranch, hasUncommittedChanges } = require('vibecodingmachine-core');
56
+ if (isGitRepo(repoPath)) {
57
+ const branch = getCurrentBranch(repoPath);
58
+ if (branch) {
59
+ const isDirty = hasUncommittedChanges(repoPath);
60
+ const branchDisplay = isDirty ? `${chalk.cyan(branch)} ${chalk.yellow(t('system.git.status.dirty'))}` : chalk.cyan(branch);
61
+ console.log(chalk.gray(t('system.git.branch').padEnd(25)), branchDisplay);
62
+ }
63
+ }
64
+ } catch (error) {
65
+ // Ignore git display errors
66
+ }
67
+
68
+ console.log(chalk.gray(t('system.computer.name').padEnd(25)), chalk.cyan(hostname));
69
+
70
+ // Display auto mode progress if running
71
+ if (autoStatus.running) {
72
+ console.log(chalk.gray('Chats: '), chalk.cyan(autoStatus.chatCount || 0));
73
+
74
+ // Get current status and requirement from REQUIREMENTS file
75
+ const progress = await getCurrentProgress();
76
+ if (progress) {
77
+ console.log();
78
+ // Display progress in a purple/magenta box similar to UI
79
+ const stageIcons = {
80
+ 'PREPARE': '🔍',
81
+ 'ACT': '⚡',
82
+ 'CLEAN UP': '🧹',
83
+ 'VERIFY': '✅',
84
+ 'DONE': '🎉'
85
+ };
86
+ const icon = stageIcons[progress.status] || '⏳';
87
+ const statusColor = progress.status === 'DONE' ? chalk.green : chalk.magenta;
88
+
89
+ // Truncate requirement text first, THEN apply color to fix box alignment
90
+ const requirementText = progress.requirement ? progress.requirement.substring(0, 60) + (progress.requirement.length > 60 ? '...' : '') : 'No requirement';
91
+
92
+ console.log(boxen(
93
+ statusColor.bold(`${icon} ${progress.status}`) + '\n' +
94
+ chalk.gray(requirementText),
95
+ {
96
+ padding: { left: 1, right: 1, top: 0, bottom: 0 },
97
+ margin: 0,
98
+ borderStyle: 'round',
99
+ borderColor: 'magenta',
100
+ width: 70
101
+ }
102
+ ));
103
+ }
104
+
105
+ // Display recent audit log entries
106
+ const { readAuditLog, getDateStr } = require('vibecodingmachine-core');
107
+ const todayStr = getDateStr();
108
+ const entries = readAuditLog(todayStr);
109
+ if (entries && entries.length > 0) {
110
+ console.log();
111
+ console.log(chalk.gray.bold('Recent Activity:'));
112
+ // Show last 5 entries
113
+ const recentEntries = entries.slice(-5);
114
+ recentEntries.forEach(entry => {
115
+ const time = new Date(entry.timestamp).toLocaleTimeString('en-US', {
116
+ hour: 'numeric',
117
+ minute: '2-digit',
118
+ second: '2-digit',
119
+ hour12: true
120
+ });
121
+ const icon = entry.type === 'auto-mode-start' ? '▶️' :
122
+ entry.type === 'auto-mode-stop' ? '⏹️' :
123
+ entry.type === 'ide-message' ? '💬' : '•';
124
+ console.log(chalk.gray(` ${time} ${icon}`), entry.message || '');
125
+ });
126
+ }
127
+ }
128
+
129
+ console.log();
130
+ }
131
+
132
+ module.exports = {
133
+ showWelcomeScreen
134
+ };
135
+
@@ -0,0 +1,134 @@
1
+ const chalk = require('chalk');
2
+ const boxen = require('boxen');
3
+ const { t, getHostname, requirementsExists, isGitRepo, getCurrentBranch, hasUncommittedChanges, readAuditLog, getDateStr } = require('vibecodingmachine-core');
4
+ const { checkAutoModeStatus } = require('./auto-mode');
5
+ const { getAutoConfig } = require('./config');
6
+ const { formatPath } = require('./display-formatters');
7
+ const { countRequirements, getCurrentProgress } = require('./status-helpers');
8
+
9
+ const pkg = require('../../package.json');
10
+
11
+ /**
12
+ * Display the welcome screen with system information and current status
13
+ */
14
+ async function showWelcomeScreen() {
15
+ const repoPath = process.cwd(); // Always use current working directory
16
+ const autoStatus = await checkAutoModeStatus();
17
+ const hostname = getHostname();
18
+
19
+ // Get current IDE from config
20
+ const autoConfig = await getAutoConfig();
21
+
22
+ // Check for requirements file
23
+ const hasRequirements = await requirementsExists();
24
+
25
+ // Count requirements if file exists
26
+ const counts = hasRequirements ? await countRequirements() : null;
27
+
28
+ // Clear the screen using console.clear() for better cross-platform compatibility
29
+ // This ensures proper screen refresh and prevents text overlap
30
+ console.clear();
31
+
32
+ // Get version from package.json
33
+ const version = `v${pkg.version}`;
34
+
35
+ // Display welcome banner with version
36
+ console.log('\n' + boxen(
37
+ chalk.bold.cyan('Vibe Coding Machine!') + '\n' +
38
+ chalk.gray(version) + '\n' +
39
+ chalk.gray(t('banner.tagline')),
40
+ {
41
+ padding: 1,
42
+ margin: 0,
43
+ borderStyle: 'round',
44
+ borderColor: 'cyan'
45
+ }
46
+ ));
47
+
48
+ // Display feedback hint at the top of every screen
49
+ console.log(chalk.gray('💡 Press F for feedback - Share your thoughts anytime'));
50
+
51
+ // Display repository and system info
52
+ console.log();
53
+ console.log(chalk.gray(t('system.repo').padEnd(25)), formatPath(repoPath));
54
+
55
+ // Display git branch if in a git repo
56
+ try {
57
+ if (isGitRepo(repoPath)) {
58
+ const branch = getCurrentBranch(repoPath);
59
+ if (branch) {
60
+ const isDirty = hasUncommittedChanges(repoPath);
61
+ const branchDisplay = isDirty ? `${chalk.cyan(branch)} ${chalk.yellow(t('system.git.status.dirty'))}` : chalk.cyan(branch);
62
+ console.log(chalk.gray(t('system.git.branch').padEnd(25)), branchDisplay);
63
+ }
64
+ }
65
+ } catch (error) {
66
+ // Ignore git display errors
67
+ }
68
+
69
+ console.log(chalk.gray(t('system.computer.name').padEnd(25)), chalk.cyan(hostname));
70
+
71
+ // Display auto mode progress if running
72
+ if (autoStatus.running) {
73
+ console.log(chalk.gray('Chats: '), chalk.cyan(autoStatus.chatCount || 0));
74
+
75
+ // Get current status and requirement from REQUIREMENTS file
76
+ const progress = await getCurrentProgress();
77
+ if (progress) {
78
+ console.log();
79
+ // Display progress in a purple/magenta box similar to UI
80
+ const stageIcons = {
81
+ 'PREPARE': '🔍',
82
+ 'ACT': '⚡',
83
+ 'CLEAN UP': '🧹',
84
+ 'VERIFY': '✅',
85
+ 'DONE': '🎉'
86
+ };
87
+ const icon = stageIcons[progress.status] || '⏳';
88
+ const statusColor = progress.status === 'DONE' ? chalk.green : chalk.magenta;
89
+
90
+ // Truncate requirement text first, THEN apply color to fix box alignment
91
+ const requirementText = progress.requirement ? progress.requirement.substring(0, 60) + (progress.requirement.length > 60 ? '...' : '') : 'No requirement';
92
+
93
+ console.log(boxen(
94
+ statusColor.bold(`${icon} ${progress.status}`) + '\n' +
95
+ chalk.gray(requirementText),
96
+ {
97
+ padding: { left: 1, right: 1, top: 0, bottom: 0 },
98
+ margin: 0,
99
+ borderStyle: 'round',
100
+ borderColor: 'magenta',
101
+ width: 70
102
+ }
103
+ ));
104
+ }
105
+
106
+ // Display recent audit log entries
107
+ const todayStr = getDateStr();
108
+ const entries = readAuditLog(todayStr);
109
+ if (entries && entries.length > 0) {
110
+ console.log();
111
+ console.log(chalk.gray.bold('Recent Activity:'));
112
+ // Show last 5 entries
113
+ const recentEntries = entries.slice(-5);
114
+ recentEntries.forEach(entry => {
115
+ const time = new Date(entry.timestamp).toLocaleTimeString('en-US', {
116
+ hour: 'numeric',
117
+ minute: '2-digit',
118
+ second: '2-digit',
119
+ hour12: true
120
+ });
121
+ const icon = entry.type === 'auto-mode-start' ? '▶️' :
122
+ entry.type === 'auto-mode-stop' ? '⏹️' :
123
+ entry.type === 'ide-message' ? '💬' : '•';
124
+ console.log(chalk.gray(` ${time} ${icon}`), entry.message || '');
125
+ });
126
+ }
127
+ }
128
+
129
+ console.log();
130
+ }
131
+
132
+ module.exports = {
133
+ showWelcomeScreen
134
+ };