mycontext-cli 0.1.0

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 (94) hide show
  1. package/README.md +440 -0
  2. package/dist/cli/src/agents/implementations/CodeGenSubAgent.d.ts +43 -0
  3. package/dist/cli/src/agents/implementations/CodeGenSubAgent.d.ts.map +1 -0
  4. package/dist/cli/src/agents/implementations/CodeGenSubAgent.js +1440 -0
  5. package/dist/cli/src/agents/implementations/CodeGenSubAgent.js.map +1 -0
  6. package/dist/cli/src/agents/implementations/DocsSubAgent.d.ts +35 -0
  7. package/dist/cli/src/agents/implementations/DocsSubAgent.d.ts.map +1 -0
  8. package/dist/cli/src/agents/implementations/DocsSubAgent.js +351 -0
  9. package/dist/cli/src/agents/implementations/DocsSubAgent.js.map +1 -0
  10. package/dist/cli/src/agents/implementations/QASubAgent.d.ts +31 -0
  11. package/dist/cli/src/agents/implementations/QASubAgent.d.ts.map +1 -0
  12. package/dist/cli/src/agents/implementations/QASubAgent.js +190 -0
  13. package/dist/cli/src/agents/implementations/QASubAgent.js.map +1 -0
  14. package/dist/cli/src/agents/interfaces/SubAgent.d.ts +157 -0
  15. package/dist/cli/src/agents/interfaces/SubAgent.d.ts.map +1 -0
  16. package/dist/cli/src/agents/interfaces/SubAgent.js +7 -0
  17. package/dist/cli/src/agents/interfaces/SubAgent.js.map +1 -0
  18. package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.d.ts +59 -0
  19. package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.d.ts.map +1 -0
  20. package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.js +305 -0
  21. package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.js.map +1 -0
  22. package/dist/cli/src/agents/personalities/definitions.d.ts +34 -0
  23. package/dist/cli/src/agents/personalities/definitions.d.ts.map +1 -0
  24. package/dist/cli/src/agents/personalities/definitions.js +360 -0
  25. package/dist/cli/src/agents/personalities/definitions.js.map +1 -0
  26. package/dist/cli/src/cli.d.ts +3 -0
  27. package/dist/cli/src/cli.d.ts.map +1 -0
  28. package/dist/cli/src/cli.js +286 -0
  29. package/dist/cli/src/cli.js.map +1 -0
  30. package/dist/cli/src/commands/auth.d.ts +23 -0
  31. package/dist/cli/src/commands/auth.d.ts.map +1 -0
  32. package/dist/cli/src/commands/auth.js +212 -0
  33. package/dist/cli/src/commands/auth.js.map +1 -0
  34. package/dist/cli/src/commands/generate-components.d.ts +28 -0
  35. package/dist/cli/src/commands/generate-components.d.ts.map +1 -0
  36. package/dist/cli/src/commands/generate-components.js +680 -0
  37. package/dist/cli/src/commands/generate-components.js.map +1 -0
  38. package/dist/cli/src/commands/generate.d.ts +108 -0
  39. package/dist/cli/src/commands/generate.d.ts.map +1 -0
  40. package/dist/cli/src/commands/generate.js +1984 -0
  41. package/dist/cli/src/commands/generate.js.map +1 -0
  42. package/dist/cli/src/commands/init.d.ts +13 -0
  43. package/dist/cli/src/commands/init.d.ts.map +1 -0
  44. package/dist/cli/src/commands/init.js +91 -0
  45. package/dist/cli/src/commands/init.js.map +1 -0
  46. package/dist/cli/src/commands/list.d.ts +17 -0
  47. package/dist/cli/src/commands/list.d.ts.map +1 -0
  48. package/dist/cli/src/commands/list.js +209 -0
  49. package/dist/cli/src/commands/list.js.map +1 -0
  50. package/dist/cli/src/commands/preview.d.ts +23 -0
  51. package/dist/cli/src/commands/preview.d.ts.map +1 -0
  52. package/dist/cli/src/commands/preview.js +1200 -0
  53. package/dist/cli/src/commands/preview.js.map +1 -0
  54. package/dist/cli/src/commands/status.d.ts +21 -0
  55. package/dist/cli/src/commands/status.d.ts.map +1 -0
  56. package/dist/cli/src/commands/status.js +287 -0
  57. package/dist/cli/src/commands/status.js.map +1 -0
  58. package/dist/cli/src/commands/validate.d.ts +22 -0
  59. package/dist/cli/src/commands/validate.d.ts.map +1 -0
  60. package/dist/cli/src/commands/validate.js +259 -0
  61. package/dist/cli/src/commands/validate.js.map +1 -0
  62. package/dist/cli/src/types/index.d.ts +152 -0
  63. package/dist/cli/src/types/index.d.ts.map +1 -0
  64. package/dist/cli/src/types/index.js +3 -0
  65. package/dist/cli/src/types/index.js.map +1 -0
  66. package/dist/cli/src/utils/apiKeyManager.d.ts +137 -0
  67. package/dist/cli/src/utils/apiKeyManager.d.ts.map +1 -0
  68. package/dist/cli/src/utils/apiKeyManager.js +471 -0
  69. package/dist/cli/src/utils/apiKeyManager.js.map +1 -0
  70. package/dist/cli/src/utils/errorHandler.d.ts +105 -0
  71. package/dist/cli/src/utils/errorHandler.d.ts.map +1 -0
  72. package/dist/cli/src/utils/errorHandler.js +332 -0
  73. package/dist/cli/src/utils/errorHandler.js.map +1 -0
  74. package/dist/cli/src/utils/fileSystem.d.ts +58 -0
  75. package/dist/cli/src/utils/fileSystem.d.ts.map +1 -0
  76. package/dist/cli/src/utils/fileSystem.js +230 -0
  77. package/dist/cli/src/utils/fileSystem.js.map +1 -0
  78. package/dist/cli/src/utils/githubModels.d.ts +53 -0
  79. package/dist/cli/src/utils/githubModels.d.ts.map +1 -0
  80. package/dist/cli/src/utils/githubModels.js +239 -0
  81. package/dist/cli/src/utils/githubModels.js.map +1 -0
  82. package/dist/cli/src/utils/spinner.d.ts +28 -0
  83. package/dist/cli/src/utils/spinner.d.ts.map +1 -0
  84. package/dist/cli/src/utils/spinner.js +112 -0
  85. package/dist/cli/src/utils/spinner.js.map +1 -0
  86. package/dist/cli/src/utils/xaiClient.d.ts +59 -0
  87. package/dist/cli/src/utils/xaiClient.d.ts.map +1 -0
  88. package/dist/cli/src/utils/xaiClient.js +244 -0
  89. package/dist/cli/src/utils/xaiClient.js.map +1 -0
  90. package/dist/lib/analytics/usage-tracker.d.ts +125 -0
  91. package/dist/lib/analytics/usage-tracker.d.ts.map +1 -0
  92. package/dist/lib/analytics/usage-tracker.js +429 -0
  93. package/dist/lib/analytics/usage-tracker.js.map +1 -0
  94. package/package.json +64 -0
@@ -0,0 +1,1200 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.PreviewCommand = void 0;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const spinner_1 = require("../utils/spinner");
42
+ const fileSystem_1 = require("../utils/fileSystem");
43
+ const fs = __importStar(require("fs-extra"));
44
+ const path = __importStar(require("path"));
45
+ const child_process_1 = require("child_process");
46
+ const util_1 = require("util");
47
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
48
+ class PreviewCommand {
49
+ constructor() {
50
+ this.fs = new fileSystem_1.FileSystemManager();
51
+ }
52
+ async execute(target, options) {
53
+ const spinner = new spinner_1.EnhancedSpinner("Preparing preview...");
54
+ try {
55
+ console.log(chalk_1.default.blue.bold("🎨 MyContext Preview\n"));
56
+ // Determine preview type
57
+ const previewType = options.type || target;
58
+ switch (previewType) {
59
+ case "brand":
60
+ await this.previewBrand(options, spinner);
61
+ break;
62
+ case "components":
63
+ await this.previewComponents(options, spinner);
64
+ break;
65
+ case "generated":
66
+ await this.previewGeneratedComponents(target, options, spinner);
67
+ break;
68
+ default:
69
+ // If it's not a known type, treat it as a group name
70
+ await this.previewGroup(target, options, spinner);
71
+ break;
72
+ }
73
+ }
74
+ catch (error) {
75
+ spinner.error({ text: "Preview failed" });
76
+ throw error;
77
+ }
78
+ }
79
+ async previewBrand(options, spinner) {
80
+ spinner.updateText("Reading branding guidelines...");
81
+ // Check if branding file exists
82
+ const brandingPath = "context/branding.md";
83
+ if (!(await this.fs.exists(brandingPath))) {
84
+ throw new Error('No branding file found. Run "mycontext generate brand" first.');
85
+ }
86
+ const brandingContent = await this.fs.readFile(brandingPath);
87
+ spinner.updateText("Generating brand preview...");
88
+ // Generate HTML preview
89
+ const htmlContent = this.generateBrandPreviewHTML(brandingContent);
90
+ // Create preview directory
91
+ const previewDir = "preview";
92
+ await this.fs.ensureDir(previewDir);
93
+ // Write HTML file
94
+ const htmlPath = path.join(previewDir, "brand-preview.html");
95
+ await this.fs.writeFile(htmlPath, htmlContent);
96
+ spinner.success({ text: "Brand preview generated successfully!" });
97
+ console.log(chalk_1.default.green("\n✅ Brand Preview Ready:"));
98
+ console.log(chalk_1.default.gray(` 📄 ${htmlPath}`));
99
+ // Open in browser if requested
100
+ if (options.open !== false) {
101
+ await this.openInBrowser(htmlPath);
102
+ }
103
+ else {
104
+ console.log(chalk_1.default.blue("\n🌐 To view the preview:"));
105
+ console.log(chalk_1.default.gray(` open ${htmlPath}`));
106
+ }
107
+ }
108
+ async previewComponents(options, spinner) {
109
+ spinner.updateText("Reading component list...");
110
+ // Check if component list exists
111
+ const componentListPath = "context/component-list.json";
112
+ if (!(await this.fs.exists(componentListPath))) {
113
+ throw new Error('No component list found. Run "mycontext generate components-list" first.');
114
+ }
115
+ const componentListContent = await this.fs.readFile(componentListPath);
116
+ const componentList = JSON.parse(componentListContent);
117
+ spinner.updateText("Generating component preview...");
118
+ // Generate HTML preview
119
+ const htmlContent = this.generateComponentPreviewHTML(componentList);
120
+ // Create preview directory
121
+ const previewDir = "preview";
122
+ await this.fs.ensureDir(previewDir);
123
+ // Write HTML file
124
+ const htmlPath = path.join(previewDir, "components-preview.html");
125
+ await this.fs.writeFile(htmlPath, htmlContent);
126
+ spinner.success({ text: "Component preview generated successfully!" });
127
+ console.log(chalk_1.default.green("\n✅ Component Preview Ready:"));
128
+ console.log(chalk_1.default.gray(` 📄 ${htmlPath}`));
129
+ // Show component summary
130
+ if (componentList.groups) {
131
+ console.log(chalk_1.default.blue("\n📋 Component Groups:"));
132
+ componentList.groups.forEach((group) => {
133
+ console.log(chalk_1.default.gray(` • ${group.name} (${group.components?.length || 0} components)`));
134
+ });
135
+ }
136
+ // Open in browser if requested
137
+ if (options.open !== false) {
138
+ await this.openInBrowser(htmlPath);
139
+ }
140
+ else {
141
+ console.log(chalk_1.default.blue("\n🌐 To view the preview:"));
142
+ console.log(chalk_1.default.gray(` open ${htmlPath}`));
143
+ }
144
+ }
145
+ async previewGeneratedComponents(target, options, spinner) {
146
+ spinner.updateText("Reading generated components...");
147
+ // Check if components directory exists
148
+ const componentsDir = "components";
149
+ if (!(await this.fs.exists(componentsDir))) {
150
+ throw new Error('No generated components found. Run "mycontext generate-components" first.');
151
+ }
152
+ // If target is specified, preview specific group
153
+ if (target && target !== "generated") {
154
+ const groupDir = path.join(componentsDir, target.toLowerCase());
155
+ if (!(await this.fs.exists(groupDir))) {
156
+ throw new Error(`Generated component group '${target}' not found.`);
157
+ }
158
+ const pagePath = path.join(groupDir, "page.tsx");
159
+ if (await this.fs.exists(pagePath)) {
160
+ spinner.success({
161
+ text: `Generated ${target} components preview ready!`,
162
+ });
163
+ console.log(chalk_1.default.green("\n✅ Generated Components Preview Ready:"));
164
+ console.log(chalk_1.default.gray(` 📄 ${pagePath}`));
165
+ console.log(chalk_1.default.blue("\n🌐 To view the preview:"));
166
+ console.log(chalk_1.default.gray(` # In a Next.js app, navigate to /components/${target.toLowerCase()}`));
167
+ console.log(chalk_1.default.gray(` # Or copy the page.tsx content to your app`));
168
+ return;
169
+ }
170
+ }
171
+ // List all generated component groups
172
+ const groups = await this.listGeneratedGroups(componentsDir);
173
+ spinner.success({ text: "Generated components overview ready!" });
174
+ console.log(chalk_1.default.green("\n✅ Generated Component Groups:"));
175
+ groups.forEach((group) => {
176
+ console.log(chalk_1.default.gray(` • ${group.name} (${group.components.length} components)`));
177
+ console.log(chalk_1.default.gray(` 📄 ${group.pagePath}`));
178
+ });
179
+ console.log(chalk_1.default.blue("\n🌐 To preview a specific group:"));
180
+ console.log(chalk_1.default.gray(` mycontext preview generated <group-name>`));
181
+ }
182
+ async listGeneratedGroups(componentsDir) {
183
+ const groups = [];
184
+ const items = await fs.readdir(componentsDir);
185
+ for (const item of items) {
186
+ const itemPath = path.join(componentsDir, item);
187
+ const stats = await fs.stat(itemPath);
188
+ if (stats.isDirectory()) {
189
+ const pagePath = path.join(itemPath, "page.tsx");
190
+ const indexPath = path.join(itemPath, "index.ts");
191
+ if ((await this.fs.exists(pagePath)) &&
192
+ (await this.fs.exists(indexPath))) {
193
+ const indexContent = await this.fs.readFile(indexPath);
194
+ const componentMatches = indexContent.match(/export \{ ([^}]+) \} from/g);
195
+ const components = componentMatches ? componentMatches.length : 0;
196
+ groups.push({
197
+ name: item,
198
+ components: Array.from({ length: components }, (_, i) => `Component${i + 1}`),
199
+ pagePath,
200
+ });
201
+ }
202
+ }
203
+ }
204
+ return groups;
205
+ }
206
+ async previewGroup(groupName, options, spinner) {
207
+ spinner.updateText(`Reading ${groupName} components...`);
208
+ // Check if component list exists
209
+ const componentListPath = "context/component-list.json";
210
+ if (!(await this.fs.exists(componentListPath))) {
211
+ throw new Error('No component list found. Run "mycontext generate components-list" first.');
212
+ }
213
+ const componentListContent = await this.fs.readFile(componentListPath);
214
+ const componentList = JSON.parse(componentListContent);
215
+ // Find the specific group
216
+ const group = componentList.groups?.find((g) => g.name.toLowerCase() === groupName.toLowerCase());
217
+ if (!group) {
218
+ throw new Error(`Group "${groupName}" not found in component list.`);
219
+ }
220
+ spinner.updateText(`Generating ${groupName} preview...`);
221
+ // Generate HTML preview for specific group
222
+ const htmlContent = this.generateGroupPreviewHTML(group);
223
+ // Create preview directory
224
+ const previewDir = "preview";
225
+ await this.fs.ensureDir(previewDir);
226
+ // Write HTML file
227
+ const htmlPath = path.join(previewDir, `${groupName.toLowerCase()}-preview.html`);
228
+ await this.fs.writeFile(htmlPath, htmlContent);
229
+ spinner.success({ text: `${groupName} preview generated successfully!` });
230
+ console.log(chalk_1.default.green(`\n✅ ${groupName} Preview Ready:`));
231
+ console.log(chalk_1.default.gray(` 📄 ${htmlPath}`));
232
+ // Show component summary
233
+ console.log(chalk_1.default.blue(`\n📋 ${groupName} Components:`));
234
+ group.components?.forEach((component) => {
235
+ console.log(chalk_1.default.gray(` • ${component.name} (${component.type})`));
236
+ });
237
+ // Open in browser if requested
238
+ if (options.open !== false) {
239
+ await this.openInBrowser(htmlPath);
240
+ }
241
+ else {
242
+ console.log(chalk_1.default.blue("\n🌐 To view the preview:"));
243
+ console.log(chalk_1.default.gray(` open ${htmlPath}`));
244
+ }
245
+ }
246
+ generateBrandPreviewHTML(brandingContent) {
247
+ // Extract color information from branding content
248
+ const colors = this.extractColorsFromBranding(brandingContent);
249
+ const typography = this.extractTypographyFromBranding(brandingContent);
250
+ return `<!DOCTYPE html>
251
+ <html lang="en">
252
+ <head>
253
+ <meta charset="UTF-8">
254
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
255
+ <title>MyContext Brand Preview</title>
256
+ <link rel="preconnect" href="https://fonts.googleapis.com">
257
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
258
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
259
+ <style>
260
+ * {
261
+ margin: 0;
262
+ padding: 0;
263
+ box-sizing: border-box;
264
+ }
265
+
266
+ body {
267
+ font-family: 'Inter', system-ui, sans-serif;
268
+ line-height: 1.6;
269
+ color: #111827;
270
+ background: #f9fafb;
271
+ }
272
+
273
+ .container {
274
+ max-width: 1200px;
275
+ margin: 0 auto;
276
+ padding: 2rem;
277
+ }
278
+
279
+ .header {
280
+ text-align: center;
281
+ margin-bottom: 3rem;
282
+ }
283
+
284
+ .header h1 {
285
+ font-size: 2.5rem;
286
+ font-weight: 700;
287
+ color: #3B82F6;
288
+ margin-bottom: 0.5rem;
289
+ }
290
+
291
+ .header p {
292
+ font-size: 1.125rem;
293
+ color: #6B7280;
294
+ }
295
+
296
+ .section {
297
+ background: white;
298
+ border-radius: 12px;
299
+ padding: 2rem;
300
+ margin-bottom: 2rem;
301
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
302
+ }
303
+
304
+ .section h2 {
305
+ font-size: 1.5rem;
306
+ font-weight: 600;
307
+ margin-bottom: 1.5rem;
308
+ color: #111827;
309
+ }
310
+
311
+ .color-grid {
312
+ display: grid;
313
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
314
+ gap: 1rem;
315
+ margin-bottom: 2rem;
316
+ }
317
+
318
+ .color-card {
319
+ border-radius: 8px;
320
+ padding: 1rem;
321
+ text-align: center;
322
+ color: white;
323
+ font-weight: 500;
324
+ }
325
+
326
+ .color-card.light {
327
+ color: #111827;
328
+ border: 1px solid #e5e7eb;
329
+ }
330
+
331
+ .color-name {
332
+ font-size: 0.875rem;
333
+ margin-bottom: 0.25rem;
334
+ opacity: 0.9;
335
+ }
336
+
337
+ .color-value {
338
+ font-size: 1rem;
339
+ font-weight: 600;
340
+ }
341
+
342
+ .typography-demo {
343
+ margin-bottom: 2rem;
344
+ }
345
+
346
+ .typography-demo h1 {
347
+ font-size: 3rem;
348
+ font-weight: 700;
349
+ margin-bottom: 1rem;
350
+ }
351
+
352
+ .typography-demo h2 {
353
+ font-size: 2.25rem;
354
+ font-weight: 600;
355
+ margin-bottom: 1rem;
356
+ }
357
+
358
+ .typography-demo h3 {
359
+ font-size: 1.875rem;
360
+ font-weight: 600;
361
+ margin-bottom: 1rem;
362
+ }
363
+
364
+ .typography-demo p {
365
+ font-size: 1.125rem;
366
+ margin-bottom: 1rem;
367
+ }
368
+
369
+ .typography-demo .small {
370
+ font-size: 0.875rem;
371
+ color: #6B7280;
372
+ }
373
+
374
+ .component-patterns {
375
+ display: grid;
376
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
377
+ gap: 1.5rem;
378
+ }
379
+
380
+ .pattern-card {
381
+ border: 1px solid #e5e7eb;
382
+ border-radius: 8px;
383
+ padding: 1.5rem;
384
+ background: white;
385
+ }
386
+
387
+ .pattern-card h3 {
388
+ font-size: 1.25rem;
389
+ font-weight: 600;
390
+ margin-bottom: 1rem;
391
+ }
392
+
393
+ .button-demo {
394
+ display: flex;
395
+ gap: 1rem;
396
+ flex-wrap: wrap;
397
+ margin-bottom: 1rem;
398
+ }
399
+
400
+ .btn {
401
+ padding: 0.5rem 1rem;
402
+ border-radius: 6px;
403
+ border: none;
404
+ font-weight: 500;
405
+ cursor: pointer;
406
+ transition: all 0.15s ease-in-out;
407
+ }
408
+
409
+ .btn-primary {
410
+ background: #3B82F6;
411
+ color: white;
412
+ }
413
+
414
+ .btn-primary:hover {
415
+ background: #1D4ED8;
416
+ }
417
+
418
+ .btn-secondary {
419
+ background: #6B7280;
420
+ color: white;
421
+ }
422
+
423
+ .btn-secondary:hover {
424
+ background: #374151;
425
+ }
426
+
427
+ .btn-success {
428
+ background: #10B981;
429
+ color: white;
430
+ }
431
+
432
+ .btn-success:hover {
433
+ background: #059669;
434
+ }
435
+
436
+ .input-demo {
437
+ width: 100%;
438
+ padding: 0.75rem;
439
+ border: 1px solid #d1d5db;
440
+ border-radius: 6px;
441
+ font-size: 1rem;
442
+ margin-bottom: 1rem;
443
+ }
444
+
445
+ .input-demo:focus {
446
+ outline: none;
447
+ border-color: #3B82F6;
448
+ box-shadow: 0 0 0 3px rgb(59 130 246 / 0.1);
449
+ }
450
+
451
+ .spacing-demo {
452
+ display: flex;
453
+ align-items: center;
454
+ gap: 1rem;
455
+ margin-bottom: 1rem;
456
+ }
457
+
458
+ .spacing-box {
459
+ background: #3B82F6;
460
+ border-radius: 4px;
461
+ }
462
+
463
+ .spacing-1 { width: 4px; height: 4px; }
464
+ .spacing-2 { width: 8px; height: 8px; }
465
+ .spacing-4 { width: 16px; height: 16px; }
466
+ .spacing-6 { width: 24px; height: 24px; }
467
+ .spacing-8 { width: 32px; height: 32px; }
468
+
469
+ .footer {
470
+ text-align: center;
471
+ margin-top: 3rem;
472
+ padding: 2rem;
473
+ color: #6B7280;
474
+ border-top: 1px solid #e5e7eb;
475
+ }
476
+ </style>
477
+ </head>
478
+ <body>
479
+ <div class="container">
480
+ <div class="header">
481
+ <h1>Brand Preview</h1>
482
+ <p>Visual representation of your project's design system</p>
483
+ </div>
484
+
485
+ <div class="section">
486
+ <h2>Color Palette</h2>
487
+ <div class="color-grid">
488
+ <div class="color-card" style="background: #3B82F6;">
489
+ <div class="color-name">Primary Blue</div>
490
+ <div class="color-value">#3B82F6</div>
491
+ </div>
492
+ <div class="color-card" style="background: #1D4ED8;">
493
+ <div class="color-name">Primary Dark</div>
494
+ <div class="color-value">#1D4ED8</div>
495
+ </div>
496
+ <div class="color-card" style="background: #93C5FD;">
497
+ <div class="color-name">Primary Light</div>
498
+ <div class="color-value">#93C5FD</div>
499
+ </div>
500
+ <div class="color-card" style="background: #6B7280;">
501
+ <div class="color-name">Secondary Gray</div>
502
+ <div class="color-value">#6B7280</div>
503
+ </div>
504
+ <div class="color-card" style="background: #10B981;">
505
+ <div class="color-name">Success Green</div>
506
+ <div class="color-value">#10B981</div>
507
+ </div>
508
+ <div class="color-card" style="background: #F59E0B;">
509
+ <div class="color-name">Warning Yellow</div>
510
+ <div class="color-value">#F59E0B</div>
511
+ </div>
512
+ <div class="color-card" style="background: #EF4444;">
513
+ <div class="color-name">Error Red</div>
514
+ <div class="color-value">#EF4444</div>
515
+ </div>
516
+ <div class="color-card light" style="background: #FFFFFF;">
517
+ <div class="color-name">Background</div>
518
+ <div class="color-value">#FFFFFF</div>
519
+ </div>
520
+ <div class="color-card light" style="background: #F9FAFB;">
521
+ <div class="color-name">Surface</div>
522
+ <div class="color-value">#F9FAFB</div>
523
+ </div>
524
+ </div>
525
+ </div>
526
+
527
+ <div class="section">
528
+ <h2>Typography</h2>
529
+ <div class="typography-demo">
530
+ <h1>Heading 1 - 3rem (48px)</h1>
531
+ <h2>Heading 2 - 2.25rem (36px)</h2>
532
+ <h3>Heading 3 - 1.875rem (30px)</h3>
533
+ <p>Body text - 1.125rem (18px) - This is how regular body text appears in your design system. It should be readable and comfortable to read.</p>
534
+ <p class="small">Small text - 0.875rem (14px) - This is used for secondary information, captions, and less important text.</p>
535
+ </div>
536
+ </div>
537
+
538
+ <div class="section">
539
+ <h2>Component Patterns</h2>
540
+ <div class="component-patterns">
541
+ <div class="pattern-card">
542
+ <h3>Buttons</h3>
543
+ <div class="button-demo">
544
+ <button class="btn btn-primary">Primary Button</button>
545
+ <button class="btn btn-secondary">Secondary Button</button>
546
+ <button class="btn btn-success">Success Button</button>
547
+ </div>
548
+ </div>
549
+
550
+ <div class="pattern-card">
551
+ <h3>Form Elements</h3>
552
+ <input type="text" class="input-demo" placeholder="Enter your text here...">
553
+ <input type="email" class="input-demo" placeholder="Enter your email...">
554
+ </div>
555
+
556
+ <div class="pattern-card">
557
+ <h3>Spacing Scale</h3>
558
+ <div class="spacing-demo">
559
+ <span>1:</span>
560
+ <div class="spacing-box spacing-1"></div>
561
+ <span>2:</span>
562
+ <div class="spacing-box spacing-2"></div>
563
+ <span>4:</span>
564
+ <div class="spacing-box spacing-4"></div>
565
+ <span>6:</span>
566
+ <div class="spacing-box spacing-6"></div>
567
+ <span>8:</span>
568
+ <div class="spacing-box spacing-8"></div>
569
+ </div>
570
+ </div>
571
+ </div>
572
+ </div>
573
+
574
+ <div class="section">
575
+ <h2>Design Principles</h2>
576
+ <ul style="list-style: none; padding: 0;">
577
+ <li style="padding: 0.5rem 0; border-bottom: 1px solid #e5e7eb;">
578
+ <strong>Accessibility First:</strong> WCAG 2.1 AA compliance with high contrast ratios
579
+ </li>
580
+ <li style="padding: 0.5rem 0; border-bottom: 1px solid #e5e7eb;">
581
+ <strong>Mobile-First Responsive:</strong> Touch-friendly targets and responsive typography
582
+ </li>
583
+ <li style="padding: 0.5rem 0; border-bottom: 1px solid #e5e7eb;">
584
+ <strong>Consistency & Predictability:</strong> Unified visual language and interaction patterns
585
+ </li>
586
+ <li style="padding: 0.5rem 0;">
587
+ <strong>Performance & Efficiency:</strong> Optimized for fast loading and minimal bundle size
588
+ </li>
589
+ </ul>
590
+ </div>
591
+ </div>
592
+
593
+ <div class="footer">
594
+ <p>Generated by MyContext CLI • ${new Date().toLocaleDateString()}</p>
595
+ </div>
596
+ </body>
597
+ </html>`;
598
+ }
599
+ generateComponentPreviewHTML(componentList) {
600
+ const { project, groups, metadata } = componentList;
601
+ let componentsHTML = "";
602
+ if (groups && Array.isArray(groups)) {
603
+ groups.forEach((group) => {
604
+ componentsHTML += `
605
+ <div class="group">
606
+ <h3>${group.name}</h3>
607
+ <p class="group-description">${group.description}</p>
608
+ <div class="components-grid">
609
+ `;
610
+ if (group.components && Array.isArray(group.components)) {
611
+ group.components.forEach((component) => {
612
+ componentsHTML += `
613
+ <div class="component-card">
614
+ <h4>${component.name}</h4>
615
+ <p>${component.description}</p>
616
+ <div class="component-meta">
617
+ <span class="type">${component.type}</span>
618
+ <span class="priority">${component.priority}</span>
619
+ </div>
620
+ <div class="user-stories">
621
+ <strong>User Stories:</strong>
622
+ <ul>
623
+ ${component.userStories
624
+ ?.map((story) => `<li>${story}</li>`)
625
+ .join("") || "<li>No user stories defined</li>"}
626
+ </ul>
627
+ </div>
628
+ <div class="action-functions">
629
+ <strong>Action Functions:</strong>
630
+ <div class="function-tags">
631
+ ${component.actionFunctions
632
+ ?.map((func) => `<span class="function-tag">${func}</span>`)
633
+ .join("") ||
634
+ '<span class="no-functions">No action functions defined</span>'}
635
+ </div>
636
+ </div>
637
+ </div>
638
+ `;
639
+ });
640
+ }
641
+ componentsHTML += `
642
+ </div>
643
+ </div>
644
+ `;
645
+ });
646
+ }
647
+ return `<!DOCTYPE html>
648
+ <html lang="en">
649
+ <head>
650
+ <meta charset="UTF-8">
651
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
652
+ <title>Component Preview - ${project?.name || "MyContext Project"}</title>
653
+ <link rel="preconnect" href="https://fonts.googleapis.com">
654
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
655
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
656
+ <style>
657
+ * {
658
+ margin: 0;
659
+ padding: 0;
660
+ box-sizing: border-box;
661
+ }
662
+
663
+ body {
664
+ font-family: 'Inter', system-ui, sans-serif;
665
+ line-height: 1.6;
666
+ color: #111827;
667
+ background: #f9fafb;
668
+ }
669
+
670
+ .container {
671
+ max-width: 1400px;
672
+ margin: 0 auto;
673
+ padding: 2rem;
674
+ }
675
+
676
+ .header {
677
+ text-align: center;
678
+ margin-bottom: 3rem;
679
+ }
680
+
681
+ .header h1 {
682
+ font-size: 2.5rem;
683
+ font-weight: 700;
684
+ color: #3B82F6;
685
+ margin-bottom: 0.5rem;
686
+ }
687
+
688
+ .header p {
689
+ font-size: 1.125rem;
690
+ color: #6B7280;
691
+ margin-bottom: 1rem;
692
+ }
693
+
694
+ .summary {
695
+ display: flex;
696
+ justify-content: center;
697
+ gap: 2rem;
698
+ margin-bottom: 2rem;
699
+ }
700
+
701
+ .summary-item {
702
+ text-align: center;
703
+ padding: 1rem;
704
+ background: white;
705
+ border-radius: 8px;
706
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
707
+ }
708
+
709
+ .summary-number {
710
+ font-size: 2rem;
711
+ font-weight: 700;
712
+ color: #3B82F6;
713
+ }
714
+
715
+ .summary-label {
716
+ font-size: 0.875rem;
717
+ color: #6B7280;
718
+ text-transform: uppercase;
719
+ letter-spacing: 0.05em;
720
+ }
721
+
722
+ .group {
723
+ background: white;
724
+ border-radius: 12px;
725
+ padding: 2rem;
726
+ margin-bottom: 2rem;
727
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
728
+ }
729
+
730
+ .group h3 {
731
+ font-size: 1.5rem;
732
+ font-weight: 600;
733
+ margin-bottom: 0.5rem;
734
+ color: #111827;
735
+ }
736
+
737
+ .group-description {
738
+ color: #6B7280;
739
+ margin-bottom: 1.5rem;
740
+ }
741
+
742
+ .components-grid {
743
+ display: grid;
744
+ grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
745
+ gap: 1.5rem;
746
+ }
747
+
748
+ .component-card {
749
+ border: 1px solid #e5e7eb;
750
+ border-radius: 8px;
751
+ padding: 1.5rem;
752
+ background: #f9fafb;
753
+ }
754
+
755
+ .component-card h4 {
756
+ font-size: 1.25rem;
757
+ font-weight: 600;
758
+ margin-bottom: 0.5rem;
759
+ color: #111827;
760
+ }
761
+
762
+ .component-card p {
763
+ color: #6B7280;
764
+ margin-bottom: 1rem;
765
+ }
766
+
767
+ .component-meta {
768
+ display: flex;
769
+ gap: 0.5rem;
770
+ margin-bottom: 1rem;
771
+ }
772
+
773
+ .type, .priority {
774
+ padding: 0.25rem 0.5rem;
775
+ border-radius: 4px;
776
+ font-size: 0.75rem;
777
+ font-weight: 500;
778
+ text-transform: uppercase;
779
+ }
780
+
781
+ .type {
782
+ background: #dbeafe;
783
+ color: #1e40af;
784
+ }
785
+
786
+ .priority {
787
+ background: #fef3c7;
788
+ color: #92400e;
789
+ }
790
+
791
+ .user-stories {
792
+ margin-bottom: 1rem;
793
+ }
794
+
795
+ .user-stories strong {
796
+ display: block;
797
+ margin-bottom: 0.5rem;
798
+ color: #111827;
799
+ }
800
+
801
+ .user-stories ul {
802
+ list-style: none;
803
+ padding-left: 0;
804
+ }
805
+
806
+ .user-stories li {
807
+ padding: 0.25rem 0;
808
+ font-size: 0.875rem;
809
+ color: #6B7280;
810
+ border-left: 3px solid #3B82F6;
811
+ padding-left: 0.75rem;
812
+ margin-bottom: 0.25rem;
813
+ }
814
+
815
+ .action-functions {
816
+ margin-bottom: 1rem;
817
+ }
818
+
819
+ .action-functions strong {
820
+ display: block;
821
+ margin-bottom: 0.5rem;
822
+ color: #111827;
823
+ }
824
+
825
+ .function-tags {
826
+ display: flex;
827
+ flex-wrap: wrap;
828
+ gap: 0.5rem;
829
+ }
830
+
831
+ .function-tag {
832
+ background: #3B82F6;
833
+ color: white;
834
+ padding: 0.25rem 0.5rem;
835
+ border-radius: 4px;
836
+ font-size: 0.75rem;
837
+ font-weight: 500;
838
+ font-family: 'JetBrains Mono', monospace;
839
+ }
840
+
841
+ .no-functions {
842
+ color: #9ca3af;
843
+ font-style: italic;
844
+ }
845
+
846
+ .footer {
847
+ text-align: center;
848
+ margin-top: 3rem;
849
+ padding: 2rem;
850
+ color: #6B7280;
851
+ border-top: 1px solid #e5e7eb;
852
+ }
853
+ </style>
854
+ </head>
855
+ <body>
856
+ <div class="container">
857
+ <div class="header">
858
+ <h1>Component Preview</h1>
859
+ <p>${project?.description || "AI-powered component generation platform"}</p>
860
+ <div class="summary">
861
+ <div class="summary-item">
862
+ <div class="summary-number">${metadata?.totalComponents || 0}</div>
863
+ <div class="summary-label">Components</div>
864
+ </div>
865
+ <div class="summary-item">
866
+ <div class="summary-number">${metadata?.totalGroups || 0}</div>
867
+ <div class="summary-label">Groups</div>
868
+ </div>
869
+ <div class="summary-item">
870
+ <div class="summary-number">${metadata?.version || "1.0.0"}</div>
871
+ <div class="summary-label">Version</div>
872
+ </div>
873
+ </div>
874
+ </div>
875
+
876
+ ${componentsHTML}
877
+ </div>
878
+
879
+ <div class="footer">
880
+ <p>Generated by MyContext CLI • ${new Date().toLocaleDateString()}</p>
881
+ </div>
882
+ </body>
883
+ </html>`;
884
+ }
885
+ generateGroupPreviewHTML(group) {
886
+ let componentsHTML = "";
887
+ if (group.components && Array.isArray(group.components)) {
888
+ group.components.forEach((component) => {
889
+ componentsHTML += `
890
+ <div class="component-card">
891
+ <h4>${component.name}</h4>
892
+ <p>${component.description}</p>
893
+ <div class="component-meta">
894
+ <span class="type">${component.type}</span>
895
+ <span class="priority">${component.priority}</span>
896
+ </div>
897
+ <div class="user-stories">
898
+ <strong>User Stories:</strong>
899
+ <ul>
900
+ ${component.userStories
901
+ ?.map((story) => `<li>${story}</li>`)
902
+ .join("") || "<li>No user stories defined</li>"}
903
+ </ul>
904
+ </div>
905
+ <div class="action-functions">
906
+ <strong>Action Functions:</strong>
907
+ <div class="function-tags">
908
+ ${component.actionFunctions
909
+ ?.map((func) => `<span class="function-tag">${func}</span>`)
910
+ .join("") ||
911
+ '<span class="no-functions">No action functions defined</span>'}
912
+ </div>
913
+ </div>
914
+ </div>
915
+ `;
916
+ });
917
+ }
918
+ return `<!DOCTYPE html>
919
+ <html lang="en">
920
+ <head>
921
+ <meta charset="UTF-8">
922
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
923
+ <title>${group.name} Preview - MyContext Project</title>
924
+ <link rel="preconnect" href="https://fonts.googleapis.com">
925
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
926
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
927
+ <style>
928
+ * {
929
+ margin: 0;
930
+ padding: 0;
931
+ box-sizing: border-box;
932
+ }
933
+
934
+ body {
935
+ font-family: 'Inter', system-ui, sans-serif;
936
+ line-height: 1.6;
937
+ color: #111827;
938
+ background: #f9fafb;
939
+ }
940
+
941
+ .container {
942
+ max-width: 1200px;
943
+ margin: 0 auto;
944
+ padding: 2rem;
945
+ }
946
+
947
+ .header {
948
+ text-align: center;
949
+ margin-bottom: 3rem;
950
+ }
951
+
952
+ .header h1 {
953
+ font-size: 2.5rem;
954
+ font-weight: 700;
955
+ color: #3B82F6;
956
+ margin-bottom: 0.5rem;
957
+ }
958
+
959
+ .header p {
960
+ font-size: 1.125rem;
961
+ color: #6B7280;
962
+ margin-bottom: 1rem;
963
+ }
964
+
965
+ .group-info {
966
+ background: white;
967
+ border-radius: 12px;
968
+ padding: 2rem;
969
+ margin-bottom: 2rem;
970
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
971
+ text-align: center;
972
+ }
973
+
974
+ .group-info h2 {
975
+ font-size: 1.5rem;
976
+ font-weight: 600;
977
+ margin-bottom: 0.5rem;
978
+ color: #111827;
979
+ }
980
+
981
+ .group-info p {
982
+ color: #6B7280;
983
+ margin-bottom: 1rem;
984
+ }
985
+
986
+ .group-stats {
987
+ display: flex;
988
+ justify-content: center;
989
+ gap: 2rem;
990
+ }
991
+
992
+ .stat-item {
993
+ text-align: center;
994
+ }
995
+
996
+ .stat-number {
997
+ font-size: 1.5rem;
998
+ font-weight: 700;
999
+ color: #3B82F6;
1000
+ }
1001
+
1002
+ .stat-label {
1003
+ font-size: 0.875rem;
1004
+ color: #6B7280;
1005
+ text-transform: uppercase;
1006
+ letter-spacing: 0.05em;
1007
+ }
1008
+
1009
+ .components-grid {
1010
+ display: grid;
1011
+ grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
1012
+ gap: 1.5rem;
1013
+ }
1014
+
1015
+ .component-card {
1016
+ border: 1px solid #e5e7eb;
1017
+ border-radius: 8px;
1018
+ padding: 1.5rem;
1019
+ background: white;
1020
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
1021
+ }
1022
+
1023
+ .component-card h4 {
1024
+ font-size: 1.25rem;
1025
+ font-weight: 600;
1026
+ margin-bottom: 0.5rem;
1027
+ color: #111827;
1028
+ }
1029
+
1030
+ .component-card p {
1031
+ color: #6B7280;
1032
+ margin-bottom: 1rem;
1033
+ }
1034
+
1035
+ .component-meta {
1036
+ display: flex;
1037
+ gap: 0.5rem;
1038
+ margin-bottom: 1rem;
1039
+ }
1040
+
1041
+ .type, .priority {
1042
+ padding: 0.25rem 0.5rem;
1043
+ border-radius: 4px;
1044
+ font-size: 0.75rem;
1045
+ font-weight: 500;
1046
+ text-transform: uppercase;
1047
+ }
1048
+
1049
+ .type {
1050
+ background: #dbeafe;
1051
+ color: #1e40af;
1052
+ }
1053
+
1054
+ .priority {
1055
+ background: #fef3c7;
1056
+ color: #92400e;
1057
+ }
1058
+
1059
+ .user-stories {
1060
+ margin-bottom: 1rem;
1061
+ }
1062
+
1063
+ .user-stories strong {
1064
+ display: block;
1065
+ margin-bottom: 0.5rem;
1066
+ color: #111827;
1067
+ }
1068
+
1069
+ .user-stories ul {
1070
+ list-style: none;
1071
+ padding-left: 0;
1072
+ }
1073
+
1074
+ .user-stories li {
1075
+ padding: 0.25rem 0;
1076
+ font-size: 0.875rem;
1077
+ color: #6B7280;
1078
+ border-left: 3px solid #3B82F6;
1079
+ padding-left: 0.75rem;
1080
+ margin-bottom: 0.25rem;
1081
+ }
1082
+
1083
+ .action-functions {
1084
+ margin-bottom: 1rem;
1085
+ }
1086
+
1087
+ .action-functions strong {
1088
+ display: block;
1089
+ margin-bottom: 0.5rem;
1090
+ color: #111827;
1091
+ }
1092
+
1093
+ .function-tags {
1094
+ display: flex;
1095
+ flex-wrap: wrap;
1096
+ gap: 0.5rem;
1097
+ }
1098
+
1099
+ .function-tag {
1100
+ background: #3B82F6;
1101
+ color: white;
1102
+ padding: 0.25rem 0.5rem;
1103
+ border-radius: 4px;
1104
+ font-size: 0.75rem;
1105
+ font-weight: 500;
1106
+ font-family: 'JetBrains Mono', monospace;
1107
+ }
1108
+
1109
+ .no-functions {
1110
+ color: #9ca3af;
1111
+ font-style: italic;
1112
+ }
1113
+
1114
+ .footer {
1115
+ text-align: center;
1116
+ margin-top: 3rem;
1117
+ padding: 2rem;
1118
+ color: #6B7280;
1119
+ border-top: 1px solid #e5e7eb;
1120
+ }
1121
+ </style>
1122
+ </head>
1123
+ <body>
1124
+ <div class="container">
1125
+ <div class="header">
1126
+ <h1>${group.name} Preview</h1>
1127
+ <p>Component group overview and details</p>
1128
+ </div>
1129
+
1130
+ <div class="group-info">
1131
+ <h2>${group.name}</h2>
1132
+ <p>${group.description}</p>
1133
+ <div class="group-stats">
1134
+ <div class="stat-item">
1135
+ <div class="stat-number">${group.components?.length || 0}</div>
1136
+ <div class="stat-label">Components</div>
1137
+ </div>
1138
+ <div class="stat-item">
1139
+ <div class="stat-number">${group.priority}</div>
1140
+ <div class="stat-label">Priority</div>
1141
+ </div>
1142
+ </div>
1143
+ </div>
1144
+
1145
+ <div class="components-grid">
1146
+ ${componentsHTML}
1147
+ </div>
1148
+ </div>
1149
+
1150
+ <div class="footer">
1151
+ <p>Generated by MyContext CLI • ${new Date().toLocaleDateString()}</p>
1152
+ </div>
1153
+ </body>
1154
+ </html>`;
1155
+ }
1156
+ extractColorsFromBranding(content) {
1157
+ // Simple color extraction - in a real implementation, this would be more sophisticated
1158
+ const colors = {};
1159
+ // Extract primary colors
1160
+ const primaryMatch = content.match(/Primary.*?#([A-Fa-f0-9]{6})/);
1161
+ if (primaryMatch) {
1162
+ colors.primary = `#${primaryMatch[1]}`;
1163
+ }
1164
+ return colors;
1165
+ }
1166
+ extractTypographyFromBranding(content) {
1167
+ // Simple typography extraction
1168
+ const typography = {};
1169
+ const fontMatch = content.match(/Font Family.*?:\s*(.+)/);
1170
+ if (fontMatch) {
1171
+ typography.fontFamily = fontMatch[1].trim();
1172
+ }
1173
+ return typography;
1174
+ }
1175
+ async openInBrowser(filePath) {
1176
+ try {
1177
+ const platform = process.platform;
1178
+ let command;
1179
+ switch (platform) {
1180
+ case "darwin":
1181
+ command = `open "${filePath}"`;
1182
+ break;
1183
+ case "win32":
1184
+ command = `start "${filePath}"`;
1185
+ break;
1186
+ default:
1187
+ command = `xdg-open "${filePath}"`;
1188
+ break;
1189
+ }
1190
+ await execAsync(command);
1191
+ console.log(chalk_1.default.blue("\n🌐 Opening preview in browser..."));
1192
+ }
1193
+ catch (error) {
1194
+ console.log(chalk_1.default.yellow("\n⚠️ Could not open browser automatically."));
1195
+ console.log(chalk_1.default.gray(` Please open: ${filePath}`));
1196
+ }
1197
+ }
1198
+ }
1199
+ exports.PreviewCommand = PreviewCommand;
1200
+ //# sourceMappingURL=preview.js.map