matex-cli 1.2.15 → 1.2.17

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/src/utils/tui.ts CHANGED
@@ -51,7 +51,7 @@ export class TUI {
51
51
  static clear() {
52
52
  process.stdout.write('\x1b[2J\x1b[H');
53
53
  this.drawHeader();
54
- this.drawStatusBar(this.currentStatus);
54
+ this.drawStatusBar(this.currentStatus, true);
55
55
  }
56
56
 
57
57
  /**
@@ -64,34 +64,101 @@ export class TUI {
64
64
 
65
65
  // Move to top
66
66
  process.stdout.write('\x1b[H');
67
- console.log(chalk.bgCyan.black(' '.repeat(padding) + banner + ' '.repeat(width - banner.length - padding)));
68
- console.log(chalk.gray('─'.repeat(width)));
67
+ process.stdout.write(chalk.bgCyan.black(' '.repeat(padding) + banner + ' '.repeat(width - banner.length - padding)) + '\n');
68
+ process.stdout.write(chalk.gray('─'.repeat(width)) + '\n');
69
+ }
70
+
71
+ /**
72
+ * Helper to draw a box with content
73
+ */
74
+ private static drawBox(title: string, color: (s: string) => string, lines: string[], icon: string = '📦') {
75
+ const width = Math.min(process.stdout.columns || 80, 100);
76
+
77
+ console.log();
78
+ const trafficLights = chalk.red('●') + ' ' + chalk.yellow('●') + ' ' + chalk.green('●');
79
+ const displayTitle = ` ${icon} ${title} `;
80
+
81
+ console.log(chalk.gray('┏' + '━'.repeat(width - 2) + '┓'));
82
+ console.log(chalk.gray('┃ ') + trafficLights + ' ' + color(displayTitle).padEnd(width - 4) + chalk.gray(' ┃'));
83
+ console.log(chalk.gray('┣' + '━'.repeat(width - 2) + '┫'));
84
+
85
+ lines.forEach(line => {
86
+ const formattedLine = line.substring(0, width - 6);
87
+ console.log(chalk.gray('┃ ') + chalk.white(formattedLine).padEnd(width - 4) + chalk.gray(' ┃'));
88
+ });
89
+
90
+ console.log(chalk.gray('┗' + '━'.repeat(width - 2) + '┛'));
91
+ console.log();
69
92
  }
70
93
 
71
94
  /**
72
95
  * Draw a real-time status bar at the bottom
73
96
  */
74
- static drawStatusBar(status: string) {
75
- this.currentStatus = status;
97
+ static drawStatusBar(status: string, force: boolean = false) {
76
98
  if (!this.isInitialized) return;
99
+ if (this.currentStatus === status && !force) return;
77
100
 
101
+ this.currentStatus = status;
78
102
  const width = process.stdout.columns || 80;
79
103
  const height = process.stdout.rows || 24;
80
104
 
81
- // Save cursor position
105
+ // Save cursor position using ANSI
82
106
  process.stdout.write('\x1b[s');
83
107
 
84
- // Move to bottom line
85
- process.stdout.write(`\x1b[${height};1H`);
108
+ // Move to absolute bottom row
109
+ readline.cursorTo(process.stdout, 0, height - 1);
86
110
 
87
111
  const cleanStatus = status.substring(0, width - 10);
88
- const bar = ` [⚡] ${cleanStatus} `.padEnd(width);
89
- process.stdout.write(chalk.bgWhite.black(bar));
112
+ const barContent = ` [⚡] ${cleanStatus} `.padEnd(width);
113
+ process.stdout.write(chalk.bgWhite.black(barContent));
90
114
 
91
115
  // Restore cursor position
92
116
  process.stdout.write('\x1b[u');
93
117
  }
94
118
 
119
+ /**
120
+ * Draw a premium code container
121
+ */
122
+ static drawCodeContainer(title: string, lang: string, content: string) {
123
+ const lines = content.split('\n').filter(l => l.trim() || l === '');
124
+ this.drawBox(`${title} (${lang})`, chalk.cyan.bold, lines, '📝');
125
+ }
126
+
127
+ /**
128
+ * Draw a message box for agent dialogue
129
+ */
130
+ static drawMessageContainer(agent: string, message: string) {
131
+ const lines = this.wrapText(message, 90);
132
+ const colorMap: any = {
133
+ 'Ajay Vai': chalk.magenta.bold,
134
+ 'Sunil Dai': chalk.blue.bold,
135
+ 'Sandip Dai': chalk.hex('#FF69B4').bold,
136
+ 'Narayan Dai': chalk.green.bold
137
+ };
138
+ const color = colorMap[agent] || chalk.white.bold;
139
+ this.drawBox(agent, color, lines, '🗣️');
140
+ }
141
+
142
+ /**
143
+ * Wrap text to a specific width
144
+ */
145
+ private static wrapText(text: string, width: number): string[] {
146
+ const words = text.split(' ');
147
+ const lines = [];
148
+ let currentLine = '';
149
+
150
+ words.forEach(word => {
151
+ if ((currentLine + word).length < width) {
152
+ currentLine += (currentLine ? ' ' : '') + word;
153
+ } else {
154
+ lines.push(currentLine);
155
+ currentLine = word;
156
+ }
157
+ });
158
+ if (currentLine) lines.push(currentLine);
159
+ return lines;
160
+ }
161
+
95
162
  /**
96
163
  * Log content into the scrollable area
97
164
  */
@@ -100,9 +167,7 @@ export class TUI {
100
167
  console.log(content);
101
168
  return;
102
169
  }
103
-
104
- // Since we are in an alternative buffer, standard console.log works
105
- // within the viewport between header and footer.
170
+ // Ensure we don't overwrite the status bar
106
171
  console.log(content);
107
172
  }
108
173
  }