codebakers 2.3.8 → 2.5.3
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/AUDIT_REPORT.md +138 -0
- package/dist/{advisors-GGUCFS4E.js → advisors-RWRTSJRR.js} +1 -1
- package/dist/{chunk-YUSDTJD6.js → chunk-D44U3IEA.js} +3 -3
- package/dist/{chunk-ND6T4UDY.js → chunk-LANM5XQW.js} +4 -4
- package/dist/index.js +813 -318
- package/dist/{prd-AIEY63YY.js → prd-RYITSL6Q.js} +1 -1
- package/package.json +1 -1
- package/src/commands/advisors.ts +3 -3
- package/src/commands/build.ts +13 -8
- package/src/commands/check.ts +1 -1
- package/src/commands/code.ts +3 -3
- package/src/commands/deploy.ts +5 -5
- package/src/commands/design.ts +1 -1
- package/src/commands/generate.ts +1 -1
- package/src/commands/init.ts +90 -40
- package/src/commands/integrate.ts +1 -1
- package/src/commands/migrate.ts +1 -1
- package/src/commands/prd-maker.ts +4 -3
- package/src/commands/prd.ts +4 -4
- package/src/commands/security.ts +1 -1
- package/src/commands/status.ts +1 -1
- package/src/commands/website.ts +176 -93
- package/src/index.ts +54 -42
- package/src/utils/display.ts +338 -0
- package/src/utils/files.ts +1 -1
- package/src/utils/ui.ts +441 -0
- package/src/utils/voice.ts +1 -1
package/src/utils/ui.ts
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import gradient from 'gradient-string';
|
|
3
|
+
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// COLOR PALETTE
|
|
6
|
+
// ============================================================================
|
|
7
|
+
|
|
8
|
+
const colors = {
|
|
9
|
+
primary: chalk.hex('#ff6b6b'), // Red (matches logo)
|
|
10
|
+
secondary: chalk.hex('#4ecdc4'), // Teal
|
|
11
|
+
accent: chalk.hex('#ffe66d'), // Yellow
|
|
12
|
+
success: chalk.hex('#7ee787'), // Green
|
|
13
|
+
error: chalk.hex('#f85149'), // Red error
|
|
14
|
+
warning: chalk.hex('#d29922'), // Orange
|
|
15
|
+
muted: chalk.hex('#6e7681'), // Gray
|
|
16
|
+
white: chalk.hex('#ffffff'),
|
|
17
|
+
dim: chalk.dim,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Gradient for headers
|
|
21
|
+
const headerGradient = gradient(['#ff6b6b', '#ff8e53', '#ffb347']);
|
|
22
|
+
const successGradient = gradient(['#7ee787', '#4ecdc4']);
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// ASCII ART LOGO
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
export function showLogo(): void {
|
|
29
|
+
console.log('');
|
|
30
|
+
console.log(headerGradient(' ╔═══════════════════════════════════════════════════════════════╗'));
|
|
31
|
+
console.log(headerGradient(' ║ ║'));
|
|
32
|
+
console.log(headerGradient(' ║') + colors.white(' 🍞 C O D E B A K E R S ') + headerGradient('║'));
|
|
33
|
+
console.log(headerGradient(' ║ ║'));
|
|
34
|
+
console.log(headerGradient(' ║') + colors.muted(' AI Dev Team That Follows The Rules ') + headerGradient('║'));
|
|
35
|
+
console.log(headerGradient(' ║ ║'));
|
|
36
|
+
console.log(headerGradient(' ╚═══════════════════════════════════════════════════════════════╝'));
|
|
37
|
+
console.log('');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function showMiniLogo(): void {
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log(headerGradient(' ╔═══════════════════════════════════════════════════════════════╗'));
|
|
43
|
+
console.log(headerGradient(' ║') + colors.white(' 🍞 CODEBAKERS ') + headerGradient('║'));
|
|
44
|
+
console.log(headerGradient(' ╚═══════════════════════════════════════════════════════════════╝'));
|
|
45
|
+
console.log('');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// BOXES AND CONTAINERS
|
|
50
|
+
// ============================================================================
|
|
51
|
+
|
|
52
|
+
export function box(content: string[], style: 'default' | 'success' | 'error' | 'warning' = 'default'): void {
|
|
53
|
+
const borderColor = {
|
|
54
|
+
default: colors.muted,
|
|
55
|
+
success: colors.success,
|
|
56
|
+
error: colors.error,
|
|
57
|
+
warning: colors.warning,
|
|
58
|
+
}[style];
|
|
59
|
+
|
|
60
|
+
const maxLen = Math.max(...content.map(l => stripAnsi(l).length), 50);
|
|
61
|
+
const width = maxLen + 4;
|
|
62
|
+
|
|
63
|
+
const top = borderColor(' ╭' + '─'.repeat(width) + '╮');
|
|
64
|
+
const bottom = borderColor(' ╰' + '─'.repeat(width) + '╯');
|
|
65
|
+
|
|
66
|
+
console.log(top);
|
|
67
|
+
content.forEach(line => {
|
|
68
|
+
const stripped = stripAnsi(line);
|
|
69
|
+
const padding = width - stripped.length - 2;
|
|
70
|
+
console.log(borderColor(' │') + ' ' + line + ' '.repeat(Math.max(0, padding)) + borderColor('│'));
|
|
71
|
+
});
|
|
72
|
+
console.log(bottom);
|
|
73
|
+
console.log('');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function doubleBox(content: string[], style: 'default' | 'success' | 'error' = 'default'): void {
|
|
77
|
+
const borderColor = {
|
|
78
|
+
default: colors.primary,
|
|
79
|
+
success: colors.success,
|
|
80
|
+
error: colors.error,
|
|
81
|
+
}[style];
|
|
82
|
+
|
|
83
|
+
const maxLen = Math.max(...content.map(l => stripAnsi(l).length), 50);
|
|
84
|
+
const width = maxLen + 4;
|
|
85
|
+
|
|
86
|
+
const top = borderColor(' ╔' + '═'.repeat(width) + '╗');
|
|
87
|
+
const bottom = borderColor(' ╚' + '═'.repeat(width) + '╝');
|
|
88
|
+
|
|
89
|
+
console.log(top);
|
|
90
|
+
content.forEach(line => {
|
|
91
|
+
const stripped = stripAnsi(line);
|
|
92
|
+
const padding = width - stripped.length - 2;
|
|
93
|
+
console.log(borderColor(' ║') + ' ' + line + ' '.repeat(Math.max(0, padding)) + borderColor('║'));
|
|
94
|
+
});
|
|
95
|
+
console.log(bottom);
|
|
96
|
+
console.log('');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// SECTION HEADERS
|
|
101
|
+
// ============================================================================
|
|
102
|
+
|
|
103
|
+
export function sectionHeader(title: string): void {
|
|
104
|
+
const line = '━'.repeat(60);
|
|
105
|
+
console.log('');
|
|
106
|
+
console.log(colors.muted(` ${line}`));
|
|
107
|
+
console.log(colors.white(` ${title.toUpperCase()}`));
|
|
108
|
+
console.log(colors.muted(` ${line}`));
|
|
109
|
+
console.log('');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function subHeader(title: string): void {
|
|
113
|
+
console.log('');
|
|
114
|
+
console.log(colors.white(` ${title}`));
|
|
115
|
+
console.log(colors.muted(` ${'─'.repeat(title.length + 4)}`));
|
|
116
|
+
console.log('');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ============================================================================
|
|
120
|
+
// MENU DISPLAY
|
|
121
|
+
// ============================================================================
|
|
122
|
+
|
|
123
|
+
interface MenuItem {
|
|
124
|
+
key: string;
|
|
125
|
+
icon: string;
|
|
126
|
+
label: string;
|
|
127
|
+
description: string;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function showMenu(items: MenuItem[]): void {
|
|
131
|
+
console.log('');
|
|
132
|
+
|
|
133
|
+
items.forEach((item, i) => {
|
|
134
|
+
const num = colors.primary(` ${item.key} `);
|
|
135
|
+
const icon = `${item.icon} `;
|
|
136
|
+
const label = colors.white(item.label.padEnd(18));
|
|
137
|
+
const desc = colors.muted(item.description);
|
|
138
|
+
console.log(`${num} ${icon} ${label} ${desc}`);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
console.log('');
|
|
142
|
+
console.log(colors.muted(' ─'.repeat(30)));
|
|
143
|
+
console.log('');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function showMenuCards(items: MenuItem[]): void {
|
|
147
|
+
console.log('');
|
|
148
|
+
|
|
149
|
+
// Top border
|
|
150
|
+
console.log(colors.muted(' ┌─────────────────────────────────────────────────────────────┐'));
|
|
151
|
+
|
|
152
|
+
items.forEach((item, i) => {
|
|
153
|
+
const num = colors.primary(item.key);
|
|
154
|
+
const icon = item.icon;
|
|
155
|
+
const label = colors.white(item.label.padEnd(20));
|
|
156
|
+
const desc = colors.muted(item.description.substring(0, 30).padEnd(30));
|
|
157
|
+
console.log(colors.muted(' │') + ` ${num} ${icon} ${label} ${desc}` + colors.muted('│'));
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Bottom border
|
|
161
|
+
console.log(colors.muted(' └─────────────────────────────────────────────────────────────┘'));
|
|
162
|
+
console.log('');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// PROGRESS DISPLAY
|
|
167
|
+
// ============================================================================
|
|
168
|
+
|
|
169
|
+
interface ProgressStep {
|
|
170
|
+
name: string;
|
|
171
|
+
status: 'pending' | 'running' | 'done' | 'error' | 'skipped';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function showProgress(title: string, subtitle: string, steps: ProgressStep[], percent: number): void {
|
|
175
|
+
// Clear screen and redraw (for animation)
|
|
176
|
+
console.log('');
|
|
177
|
+
|
|
178
|
+
// Header box
|
|
179
|
+
box([
|
|
180
|
+
colors.primary('🌐 ' + title.toUpperCase()),
|
|
181
|
+
'',
|
|
182
|
+
colors.white(subtitle),
|
|
183
|
+
]);
|
|
184
|
+
|
|
185
|
+
// Section header
|
|
186
|
+
console.log(colors.muted(' PROGRESS'));
|
|
187
|
+
console.log(colors.muted(' ' + '━'.repeat(58)));
|
|
188
|
+
console.log('');
|
|
189
|
+
|
|
190
|
+
// Steps
|
|
191
|
+
steps.forEach(step => {
|
|
192
|
+
const icon = {
|
|
193
|
+
pending: colors.muted('○'),
|
|
194
|
+
running: colors.primary('●'),
|
|
195
|
+
done: colors.success('✓'),
|
|
196
|
+
error: colors.error('✗'),
|
|
197
|
+
skipped: colors.warning('⊘'),
|
|
198
|
+
}[step.status];
|
|
199
|
+
|
|
200
|
+
const labelColor = {
|
|
201
|
+
pending: colors.muted,
|
|
202
|
+
running: colors.white,
|
|
203
|
+
done: colors.success,
|
|
204
|
+
error: colors.error,
|
|
205
|
+
skipped: colors.warning,
|
|
206
|
+
}[step.status];
|
|
207
|
+
|
|
208
|
+
const suffix = step.status === 'running' ? colors.muted(' ...') : '';
|
|
209
|
+
console.log(` ${icon} ${labelColor(step.name)}${suffix}`);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
console.log('');
|
|
213
|
+
|
|
214
|
+
// Progress bar
|
|
215
|
+
const barWidth = 50;
|
|
216
|
+
const filled = Math.round((percent / 100) * barWidth);
|
|
217
|
+
const empty = barWidth - filled;
|
|
218
|
+
const bar = colors.success('█'.repeat(filled)) + colors.muted('░'.repeat(empty));
|
|
219
|
+
console.log(` ${bar} ${colors.white(percent + '%')}`);
|
|
220
|
+
|
|
221
|
+
console.log('');
|
|
222
|
+
console.log(colors.muted(' ' + '━'.repeat(58)));
|
|
223
|
+
console.log('');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ============================================================================
|
|
227
|
+
// SUCCESS / ERROR DISPLAY
|
|
228
|
+
// ============================================================================
|
|
229
|
+
|
|
230
|
+
interface SuccessDetails {
|
|
231
|
+
title: string;
|
|
232
|
+
message?: string;
|
|
233
|
+
stats?: { label: string; value: string }[];
|
|
234
|
+
nextSteps?: string[];
|
|
235
|
+
command?: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function showSuccessScreen(details: SuccessDetails): void {
|
|
239
|
+
console.log('');
|
|
240
|
+
|
|
241
|
+
// Success header
|
|
242
|
+
console.log(colors.success(' ╔═══════════════════════════════════════════════════════════════╗'));
|
|
243
|
+
console.log(colors.success(' ║ ║'));
|
|
244
|
+
console.log(colors.success(' ║') + successGradient(' ✅ SUCCESS ') + colors.success('║'));
|
|
245
|
+
console.log(colors.success(' ║ ║'));
|
|
246
|
+
console.log(colors.success(' ║') + colors.white(' ' + details.title.padEnd(60)) + colors.success('║'));
|
|
247
|
+
|
|
248
|
+
if (details.message) {
|
|
249
|
+
console.log(colors.success(' ║') + colors.muted(' ' + details.message.substring(0, 60).padEnd(60)) + colors.success('║'));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
console.log(colors.success(' ║ ║'));
|
|
253
|
+
|
|
254
|
+
// Stats
|
|
255
|
+
if (details.stats && details.stats.length > 0) {
|
|
256
|
+
console.log(colors.success(' ║') + colors.muted(' ┌─────────────────────────────────────────────────────────┐ ') + colors.success('║'));
|
|
257
|
+
details.stats.forEach(stat => {
|
|
258
|
+
const line = ` │ ${stat.label.padEnd(14)} ${colors.white(stat.value.padEnd(40))}│ `;
|
|
259
|
+
console.log(colors.success(' ║') + colors.muted(line) + colors.success('║'));
|
|
260
|
+
});
|
|
261
|
+
console.log(colors.success(' ║') + colors.muted(' └─────────────────────────────────────────────────────────┘ ') + colors.success('║'));
|
|
262
|
+
console.log(colors.success(' ║ ║'));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Next steps
|
|
266
|
+
if (details.nextSteps && details.nextSteps.length > 0) {
|
|
267
|
+
console.log(colors.success(' ║') + colors.white(' NEXT STEPS ') + colors.success('║'));
|
|
268
|
+
console.log(colors.success(' ║') + colors.muted(' ─────────────────────────────────────────────────────────') + colors.success('║'));
|
|
269
|
+
details.nextSteps.forEach(step => {
|
|
270
|
+
console.log(colors.success(' ║') + colors.secondary(' ' + step.padEnd(60)) + colors.success('║'));
|
|
271
|
+
});
|
|
272
|
+
console.log(colors.success(' ║ ║'));
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Quick command
|
|
276
|
+
if (details.command) {
|
|
277
|
+
console.log(colors.success(' ║') + colors.muted(' Quick start: ') + colors.white(details.command.padEnd(44)) + colors.success('║'));
|
|
278
|
+
console.log(colors.success(' ║ ║'));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
console.log(colors.success(' ╚═══════════════════════════════════════════════════════════════╝'));
|
|
282
|
+
console.log('');
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
interface ErrorDetails {
|
|
286
|
+
title: string;
|
|
287
|
+
message: string;
|
|
288
|
+
fixes?: string[];
|
|
289
|
+
command?: string;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function showErrorScreen(details: ErrorDetails): void {
|
|
293
|
+
console.log('');
|
|
294
|
+
|
|
295
|
+
// Error header
|
|
296
|
+
console.log(colors.error(' ╔═══════════════════════════════════════════════════════════════╗'));
|
|
297
|
+
console.log(colors.error(' ║ ║'));
|
|
298
|
+
console.log(colors.error(' ║ ❌ ERROR ║'));
|
|
299
|
+
console.log(colors.error(' ║ ║'));
|
|
300
|
+
console.log(colors.error(' ║') + colors.white(' ' + details.title.padEnd(60)) + colors.error('║'));
|
|
301
|
+
console.log(colors.error(' ║ ║'));
|
|
302
|
+
|
|
303
|
+
// Details box
|
|
304
|
+
console.log(colors.error(' ║') + colors.muted(' ┌─────────────────────────────────────────────────────────┐ ') + colors.error('║'));
|
|
305
|
+
console.log(colors.error(' ║') + colors.muted(' │') + colors.white(' WHAT HAPPENED ') + colors.muted('│ ') + colors.error('║'));
|
|
306
|
+
|
|
307
|
+
// Word wrap the message
|
|
308
|
+
const words = details.message.split(' ');
|
|
309
|
+
let line = '';
|
|
310
|
+
words.forEach(word => {
|
|
311
|
+
if ((line + ' ' + word).length > 55) {
|
|
312
|
+
console.log(colors.error(' ║') + colors.muted(' │') + colors.muted(' ' + line.padEnd(56)) + colors.muted('│ ') + colors.error('║'));
|
|
313
|
+
line = word;
|
|
314
|
+
} else {
|
|
315
|
+
line = line ? line + ' ' + word : word;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
if (line) {
|
|
319
|
+
console.log(colors.error(' ║') + colors.muted(' │') + colors.muted(' ' + line.padEnd(56)) + colors.muted('│ ') + colors.error('║'));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
console.log(colors.error(' ║') + colors.muted(' │ │ ') + colors.error('║'));
|
|
323
|
+
|
|
324
|
+
// Fixes
|
|
325
|
+
if (details.fixes && details.fixes.length > 0) {
|
|
326
|
+
console.log(colors.error(' ║') + colors.muted(' │') + colors.white(' POSSIBLE FIXES ') + colors.muted('│ ') + colors.error('║'));
|
|
327
|
+
details.fixes.forEach((fix, i) => {
|
|
328
|
+
const fixText = ` ${i + 1}. ${fix}`.substring(0, 56).padEnd(56);
|
|
329
|
+
console.log(colors.error(' ║') + colors.muted(' │') + colors.muted(fixText) + colors.muted('│ ') + colors.error('║'));
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
console.log(colors.error(' ║') + colors.muted(' └─────────────────────────────────────────────────────────┘ ') + colors.error('║'));
|
|
334
|
+
|
|
335
|
+
// Command suggestion
|
|
336
|
+
if (details.command) {
|
|
337
|
+
console.log(colors.error(' ║ ║'));
|
|
338
|
+
console.log(colors.error(' ║') + colors.muted(' Try: ') + colors.secondary(details.command.padEnd(53)) + colors.error('║'));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
console.log(colors.error(' ║ ║'));
|
|
342
|
+
console.log(colors.error(' ╚═══════════════════════════════════════════════════════════════╝'));
|
|
343
|
+
console.log('');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// ============================================================================
|
|
347
|
+
// FILE LIST
|
|
348
|
+
// ============================================================================
|
|
349
|
+
|
|
350
|
+
export function showFileTree(title: string, files: string[]): void {
|
|
351
|
+
console.log('');
|
|
352
|
+
console.log(colors.white(` 📁 ${title}`));
|
|
353
|
+
console.log('');
|
|
354
|
+
|
|
355
|
+
files.forEach((file, i) => {
|
|
356
|
+
const isLast = i === files.length - 1;
|
|
357
|
+
const prefix = isLast ? '└──' : '├──';
|
|
358
|
+
const icon = getFileIcon(file);
|
|
359
|
+
console.log(colors.muted(` ${prefix} `) + icon + ' ' + colors.white(file));
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
console.log('');
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function getFileIcon(filename: string): string {
|
|
366
|
+
const ext = filename.split('.').pop()?.toLowerCase();
|
|
367
|
+
const icons: Record<string, string> = {
|
|
368
|
+
'tsx': '⚛️ ',
|
|
369
|
+
'ts': '📘',
|
|
370
|
+
'js': '📒',
|
|
371
|
+
'jsx': '⚛️ ',
|
|
372
|
+
'css': '🎨',
|
|
373
|
+
'json': '📋',
|
|
374
|
+
'md': '📝',
|
|
375
|
+
'html': '🌐',
|
|
376
|
+
'env': '🔐',
|
|
377
|
+
};
|
|
378
|
+
return icons[ext || ''] || '📄';
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// ============================================================================
|
|
382
|
+
// STATS DISPLAY
|
|
383
|
+
// ============================================================================
|
|
384
|
+
|
|
385
|
+
export function showStats(stats: { label: string; value: string; icon?: string }[]): void {
|
|
386
|
+
console.log('');
|
|
387
|
+
stats.forEach(stat => {
|
|
388
|
+
const icon = stat.icon ? stat.icon + ' ' : '';
|
|
389
|
+
console.log(colors.muted(` ${icon}${stat.label}: `) + colors.white(stat.value));
|
|
390
|
+
});
|
|
391
|
+
console.log('');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// ============================================================================
|
|
395
|
+
// DIVIDERS
|
|
396
|
+
// ============================================================================
|
|
397
|
+
|
|
398
|
+
export function divider(): void {
|
|
399
|
+
console.log('');
|
|
400
|
+
console.log(colors.muted(' ' + '─'.repeat(60)));
|
|
401
|
+
console.log('');
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export function thinDivider(): void {
|
|
405
|
+
console.log(colors.muted(' ' + '·'.repeat(60)));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// ============================================================================
|
|
409
|
+
// WELCOME SCREEN
|
|
410
|
+
// ============================================================================
|
|
411
|
+
|
|
412
|
+
export function showWelcome(version: string): void {
|
|
413
|
+
console.clear();
|
|
414
|
+
showLogo();
|
|
415
|
+
|
|
416
|
+
console.log(colors.muted(` v${version}`));
|
|
417
|
+
console.log('');
|
|
418
|
+
|
|
419
|
+
showMenuCards([
|
|
420
|
+
{ key: '1', icon: '🌐', label: 'Build a Website', description: 'Create a complete site' },
|
|
421
|
+
{ key: '2', icon: '💻', label: 'Code with AI', description: 'Add features, fix bugs' },
|
|
422
|
+
{ key: '3', icon: '🚀', label: 'Deploy', description: 'Ship to production' },
|
|
423
|
+
{ key: '4', icon: '📋', label: 'Create PRD', description: 'Plan your project' },
|
|
424
|
+
{ key: '5', icon: '🏗️ ', label: 'Init Project', description: 'Start a new project' },
|
|
425
|
+
{ key: '6', icon: '⚙️ ', label: 'Settings', description: 'Configure services' },
|
|
426
|
+
]);
|
|
427
|
+
|
|
428
|
+
console.log(colors.muted(' Type a number or command, then press Enter'));
|
|
429
|
+
console.log('');
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// ============================================================================
|
|
433
|
+
// HELPERS
|
|
434
|
+
// ============================================================================
|
|
435
|
+
|
|
436
|
+
function stripAnsi(str: string): string {
|
|
437
|
+
return str.replace(/\x1B\[[0-9;]*[mGKH]/g, '');
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Export colors for use elsewhere
|
|
441
|
+
export { colors, headerGradient, successGradient };
|