vibecodingmachine-cli 2026.1.29-713 → 2026.2.20-426

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 (46) hide show
  1. package/bin/vibecodingmachine.js +124 -2
  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 +32 -8
  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/first-run.js +5 -8
  16. package/src/utils/ide-detection-complete.js +126 -0
  17. package/src/utils/ide-detection-extracted.js +116 -0
  18. package/src/utils/ide-detection.js +124 -0
  19. package/src/utils/interactive-backup.js +5664 -0
  20. package/src/utils/interactive-broken.js +280 -0
  21. package/src/utils/interactive.js +357 -2367
  22. package/src/utils/provider-checker.js +410 -0
  23. package/src/utils/provider-manager.js +254 -0
  24. package/src/utils/provider-registry.js +18 -9
  25. package/src/utils/requirement-actions.js +884 -0
  26. package/src/utils/requirements-navigator.js +587 -0
  27. package/src/utils/rui-trui-adapter.js +311 -0
  28. package/src/utils/simple-trui.js +204 -0
  29. package/src/utils/status-helpers-extracted.js +125 -0
  30. package/src/utils/status-helpers.js +107 -0
  31. package/src/utils/trui-debug.js +261 -0
  32. package/src/utils/trui-feedback.js +133 -0
  33. package/src/utils/trui-nav-agents.js +119 -0
  34. package/src/utils/trui-nav-requirements.js +268 -0
  35. package/src/utils/trui-nav-settings.js +157 -0
  36. package/src/utils/trui-nav-specifications.js +139 -0
  37. package/src/utils/trui-navigation.js +305 -0
  38. package/src/utils/trui-provider-manager.js +182 -0
  39. package/src/utils/trui-quick-menu.js +370 -0
  40. package/src/utils/trui-req-actions.js +372 -0
  41. package/src/utils/trui-req-tree.js +534 -0
  42. package/src/utils/trui-specifications.js +359 -0
  43. package/src/utils/trui-text-editor.js +350 -0
  44. package/src/utils/trui-windsurf.js +350 -0
  45. package/src/utils/welcome-screen-extracted.js +135 -0
  46. package/src/utils/welcome-screen.js +134 -0
@@ -0,0 +1,350 @@
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
+ // Cross-platform process check
48
+ const isWindows = process.platform === 'win32';
49
+ let result;
50
+
51
+ if (isWindows) {
52
+ // Windows: use tasklist
53
+ result = execSync('tasklist /FI "IMAGENAME eq Windsurf.exe" /NH', {
54
+ encoding: 'utf8',
55
+ timeout: 5000
56
+ });
57
+ // Check if Windsurf.exe is in the output
58
+ return result.toLowerCase().includes('windsurf.exe');
59
+ } else {
60
+ // Unix/macOS: use ps and grep
61
+ result = execSync('ps aux | grep -i windsurf | grep -v grep', {
62
+ encoding: 'utf8',
63
+ timeout: 5000
64
+ });
65
+ return result.trim().length > 0;
66
+ }
67
+ } catch (error) {
68
+ debugLogger.warn('Windsurf process check failed', { error: error.message });
69
+ return false;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Check if Cascade/Windsurf is actively typing/working
75
+ */
76
+ checkWindsurfActivity() {
77
+ try {
78
+ // Check for recent file modifications in key directories
79
+ const checkDirs = ['src', 'components', 'pages', 'lib', 'app'];
80
+ let recentActivity = false;
81
+
82
+ for (const dir of checkDirs) {
83
+ const fullPath = path.join(this.projectRoot, dir);
84
+ if (fs.existsSync(fullPath)) {
85
+ const stats = fs.statSync(fullPath);
86
+ const now = Date.now();
87
+ const modifiedTime = stats.mtime.getTime();
88
+
89
+ // If modified in last 30 seconds, consider active
90
+ if (now - modifiedTime < 30000) {
91
+ recentActivity = true;
92
+ break;
93
+ }
94
+ }
95
+ }
96
+
97
+ // Also check for specific Windsurf activity files
98
+ const activityFile = path.join(this.projectRoot, '.windsurf-activity');
99
+ if (fs.existsSync(activityFile)) {
100
+ const activityTime = fs.statSync(activityFile).mtime.getTime();
101
+ if (Date.now() - activityTime < 30000) {
102
+ recentActivity = true;
103
+ }
104
+ }
105
+
106
+ return recentActivity;
107
+ } catch (error) {
108
+ debugLogger.warn('Windsurf activity check failed', { error: error.message });
109
+ return false;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Detect when Windsurf completes work (stops typing)
115
+ */
116
+ detectWorkCompletion() {
117
+ const wasActive = this.isWindsurfActive;
118
+ const isActive = this.checkWindsurfActivity();
119
+
120
+ debugLogger.info('Windsurf activity check', { wasActive, isActive });
121
+
122
+ // Transition from active to inactive = work completed
123
+ if (wasActive && !isActive) {
124
+ this.lastActivity = Date.now();
125
+ debugLogger.info('Windsurf work completed detected');
126
+ return true;
127
+ }
128
+
129
+ this.isWindsurfActive = isActive;
130
+ return false;
131
+ }
132
+
133
+ /**
134
+ * Send "continue with best approach" message
135
+ */
136
+ async sendContinueMessage() {
137
+ try {
138
+ debugLogger.info('Sending continue message to Windsurf');
139
+
140
+ // Use AppleScript manager to actually send text to Windsurf
141
+ const { AppleScriptManager } = require('vibecodingmachine-core');
142
+ const applescriptManager = new AppleScriptManager();
143
+
144
+ debugLogger.info('Using AppleScript manager to send to Windsurf');
145
+ const result = await applescriptManager.sendText('continue with your best approach', 'windsurf');
146
+
147
+ debugLogger.info('AppleScript result', { success: result.success, error: result.error, method: result.method });
148
+
149
+ if (result.success) {
150
+ debugLogger.info('Continue message sent successfully to Windsurf');
151
+ return true;
152
+ } else {
153
+ debugLogger.error('Failed to send continue message to Windsurf', { error: result.error, details: result });
154
+
155
+ // Fallback: create file and notification for manual intervention
156
+ try {
157
+ const continueFile = path.join(this.projectRoot, '.windsurf-continue');
158
+ const message = {
159
+ type: 'continue',
160
+ message: 'continue with your best approach',
161
+ timestamp: Date.now(),
162
+ source: 'vcm-trui',
163
+ fallback_reason: result.error || 'Unknown error',
164
+ applescript_result: result
165
+ };
166
+
167
+ fs.writeFileSync(continueFile, JSON.stringify(message, null, 2));
168
+ debugLogger.info('Fallback: Created continue file for manual intervention');
169
+ } catch (fallbackError) {
170
+ debugLogger.error('Fallback also failed', { error: fallbackError.message });
171
+ }
172
+
173
+ return false;
174
+ }
175
+ } catch (error) {
176
+ debugLogger.error('Failed to send continue message', { error: error.message, stack: error.stack });
177
+ return false;
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Start monitoring Windsurf activity
183
+ */
184
+ startMonitoring() {
185
+ if (this.pollInterval) {
186
+ this.stopMonitoring();
187
+ }
188
+
189
+ debugLogger.info('Starting Windsurf activity monitoring');
190
+ this.isWindsurfActive = this.checkWindsurfActivity();
191
+
192
+ this.pollInterval = setInterval(() => {
193
+ if (this.detectWorkCompletion()) {
194
+ this.sendContinueMessage();
195
+ }
196
+ }, 5000); // Check every 5 seconds
197
+
198
+ // Handle cleanup on exit
199
+ process.on('SIGINT', () => this.stopMonitoring());
200
+ process.on('SIGTERM', () => this.stopMonitoring());
201
+ }
202
+
203
+ /**
204
+ * Stop monitoring Windsurf activity
205
+ */
206
+ stopMonitoring() {
207
+ if (this.pollInterval) {
208
+ clearInterval(this.pollInterval);
209
+ this.pollInterval = null;
210
+ debugLogger.info('Windsurf monitoring stopped');
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Get current status
216
+ */
217
+ getStatus() {
218
+ return {
219
+ isRunning: this.isWindsurfRunning(),
220
+ isActive: this.isWindsurfActive,
221
+ lastActivity: this.lastActivity,
222
+ isMonitoring: this.pollInterval !== null
223
+ };
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Integration manager for VCM + Windsurf workflow
229
+ */
230
+ class VCMWindsurfIntegration {
231
+ constructor() {
232
+ this.detector = new WindsurfDetector();
233
+ this.autoContinueEnabled = true;
234
+ this.continueDelay = 5000; // 5 seconds after completion
235
+ }
236
+
237
+ /**
238
+ * Initialize the integration
239
+ */
240
+ async initialize() {
241
+ debugLogger.info('Initializing VCM-Windsurf integration');
242
+
243
+ // Check if Windsurf is running
244
+ if (!this.detector.isWindsurfRunning()) {
245
+ debugLogger.info('Windsurf not detected, integration disabled');
246
+ return false;
247
+ }
248
+
249
+ // Start monitoring
250
+ this.detector.startMonitoring();
251
+
252
+ // Set up automatic continuation
253
+ if (this.autoContinueEnabled) {
254
+ this.setupAutoContinue();
255
+ }
256
+
257
+ debugLogger.info('VCM-Windsurf integration initialized');
258
+ return true;
259
+ }
260
+
261
+ /**
262
+ * Set up automatic continuation when work is detected as complete
263
+ */
264
+ setupAutoContinue() {
265
+ // This works in conjunction with the detector's polling
266
+ debugLogger.info('Auto-continue enabled', { delay: this.continueDelay });
267
+ }
268
+
269
+ /**
270
+ * Manually trigger continue message
271
+ */
272
+ async manualContinue() {
273
+ debugLogger.info('Manual continue triggered');
274
+ return await this.detector.sendContinueMessage();
275
+ }
276
+
277
+ /**
278
+ * Disable auto-continue
279
+ */
280
+ disableAutoContinue() {
281
+ this.autoContinueEnabled = false;
282
+ debugLogger.info('Auto-continue disabled');
283
+ }
284
+
285
+ /**
286
+ * Enable auto-continue
287
+ */
288
+ enableAutoContinue() {
289
+ this.autoContinueEnabled = true;
290
+ debugLogger.info('Auto-continue enabled');
291
+ }
292
+
293
+ /**
294
+ * Get integration status
295
+ */
296
+ getStatus() {
297
+ return {
298
+ ...this.detector.getStatus(),
299
+ autoContinueEnabled: this.autoContinueEnabled,
300
+ continueDelay: this.continueDelay
301
+ };
302
+ }
303
+
304
+ /**
305
+ * Cleanup resources
306
+ */
307
+ cleanup() {
308
+ this.detector.stopMonitoring();
309
+ debugLogger.info('VCM-Windsurf integration cleaned up');
310
+ }
311
+ }
312
+
313
+ // Global integration instance
314
+ let windsurfIntegration = null;
315
+
316
+ /**
317
+ * Initialize Windsurf integration (call from main menu)
318
+ */
319
+ function initializeWindsurfIntegration() {
320
+ if (!windsurfIntegration) {
321
+ windsurfIntegration = new VCMWindsurfIntegration();
322
+ return windsurfIntegration.initialize();
323
+ }
324
+ return true;
325
+ }
326
+
327
+ /**
328
+ * Get Windsurf integration status
329
+ */
330
+ function getWindsurfStatus() {
331
+ return windsurfIntegration ? windsurfIntegration.getStatus() : null;
332
+ }
333
+
334
+ /**
335
+ * Send manual continue message
336
+ */
337
+ async function sendContinueToWindsurf() {
338
+ if (windsurfIntegration) {
339
+ return await windsurfIntegration.manualContinue();
340
+ }
341
+ return false;
342
+ }
343
+
344
+ module.exports = {
345
+ WindsurfDetector,
346
+ VCMWindsurfIntegration,
347
+ initializeWindsurfIntegration,
348
+ getWindsurfStatus,
349
+ sendContinueToWindsurf
350
+ };
@@ -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
+ };