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.
- package/README.md +440 -0
- package/dist/cli/src/agents/implementations/CodeGenSubAgent.d.ts +43 -0
- package/dist/cli/src/agents/implementations/CodeGenSubAgent.d.ts.map +1 -0
- package/dist/cli/src/agents/implementations/CodeGenSubAgent.js +1440 -0
- package/dist/cli/src/agents/implementations/CodeGenSubAgent.js.map +1 -0
- package/dist/cli/src/agents/implementations/DocsSubAgent.d.ts +35 -0
- package/dist/cli/src/agents/implementations/DocsSubAgent.d.ts.map +1 -0
- package/dist/cli/src/agents/implementations/DocsSubAgent.js +351 -0
- package/dist/cli/src/agents/implementations/DocsSubAgent.js.map +1 -0
- package/dist/cli/src/agents/implementations/QASubAgent.d.ts +31 -0
- package/dist/cli/src/agents/implementations/QASubAgent.d.ts.map +1 -0
- package/dist/cli/src/agents/implementations/QASubAgent.js +190 -0
- package/dist/cli/src/agents/implementations/QASubAgent.js.map +1 -0
- package/dist/cli/src/agents/interfaces/SubAgent.d.ts +157 -0
- package/dist/cli/src/agents/interfaces/SubAgent.d.ts.map +1 -0
- package/dist/cli/src/agents/interfaces/SubAgent.js +7 -0
- package/dist/cli/src/agents/interfaces/SubAgent.js.map +1 -0
- package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.d.ts +59 -0
- package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.d.ts.map +1 -0
- package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.js +305 -0
- package/dist/cli/src/agents/orchestrator/SubAgentOrchestrator.js.map +1 -0
- package/dist/cli/src/agents/personalities/definitions.d.ts +34 -0
- package/dist/cli/src/agents/personalities/definitions.d.ts.map +1 -0
- package/dist/cli/src/agents/personalities/definitions.js +360 -0
- package/dist/cli/src/agents/personalities/definitions.js.map +1 -0
- package/dist/cli/src/cli.d.ts +3 -0
- package/dist/cli/src/cli.d.ts.map +1 -0
- package/dist/cli/src/cli.js +286 -0
- package/dist/cli/src/cli.js.map +1 -0
- package/dist/cli/src/commands/auth.d.ts +23 -0
- package/dist/cli/src/commands/auth.d.ts.map +1 -0
- package/dist/cli/src/commands/auth.js +212 -0
- package/dist/cli/src/commands/auth.js.map +1 -0
- package/dist/cli/src/commands/generate-components.d.ts +28 -0
- package/dist/cli/src/commands/generate-components.d.ts.map +1 -0
- package/dist/cli/src/commands/generate-components.js +680 -0
- package/dist/cli/src/commands/generate-components.js.map +1 -0
- package/dist/cli/src/commands/generate.d.ts +108 -0
- package/dist/cli/src/commands/generate.d.ts.map +1 -0
- package/dist/cli/src/commands/generate.js +1984 -0
- package/dist/cli/src/commands/generate.js.map +1 -0
- package/dist/cli/src/commands/init.d.ts +13 -0
- package/dist/cli/src/commands/init.d.ts.map +1 -0
- package/dist/cli/src/commands/init.js +91 -0
- package/dist/cli/src/commands/init.js.map +1 -0
- package/dist/cli/src/commands/list.d.ts +17 -0
- package/dist/cli/src/commands/list.d.ts.map +1 -0
- package/dist/cli/src/commands/list.js +209 -0
- package/dist/cli/src/commands/list.js.map +1 -0
- package/dist/cli/src/commands/preview.d.ts +23 -0
- package/dist/cli/src/commands/preview.d.ts.map +1 -0
- package/dist/cli/src/commands/preview.js +1200 -0
- package/dist/cli/src/commands/preview.js.map +1 -0
- package/dist/cli/src/commands/status.d.ts +21 -0
- package/dist/cli/src/commands/status.d.ts.map +1 -0
- package/dist/cli/src/commands/status.js +287 -0
- package/dist/cli/src/commands/status.js.map +1 -0
- package/dist/cli/src/commands/validate.d.ts +22 -0
- package/dist/cli/src/commands/validate.d.ts.map +1 -0
- package/dist/cli/src/commands/validate.js +259 -0
- package/dist/cli/src/commands/validate.js.map +1 -0
- package/dist/cli/src/types/index.d.ts +152 -0
- package/dist/cli/src/types/index.d.ts.map +1 -0
- package/dist/cli/src/types/index.js +3 -0
- package/dist/cli/src/types/index.js.map +1 -0
- package/dist/cli/src/utils/apiKeyManager.d.ts +137 -0
- package/dist/cli/src/utils/apiKeyManager.d.ts.map +1 -0
- package/dist/cli/src/utils/apiKeyManager.js +471 -0
- package/dist/cli/src/utils/apiKeyManager.js.map +1 -0
- package/dist/cli/src/utils/errorHandler.d.ts +105 -0
- package/dist/cli/src/utils/errorHandler.d.ts.map +1 -0
- package/dist/cli/src/utils/errorHandler.js +332 -0
- package/dist/cli/src/utils/errorHandler.js.map +1 -0
- package/dist/cli/src/utils/fileSystem.d.ts +58 -0
- package/dist/cli/src/utils/fileSystem.d.ts.map +1 -0
- package/dist/cli/src/utils/fileSystem.js +230 -0
- package/dist/cli/src/utils/fileSystem.js.map +1 -0
- package/dist/cli/src/utils/githubModels.d.ts +53 -0
- package/dist/cli/src/utils/githubModels.d.ts.map +1 -0
- package/dist/cli/src/utils/githubModels.js +239 -0
- package/dist/cli/src/utils/githubModels.js.map +1 -0
- package/dist/cli/src/utils/spinner.d.ts +28 -0
- package/dist/cli/src/utils/spinner.d.ts.map +1 -0
- package/dist/cli/src/utils/spinner.js +112 -0
- package/dist/cli/src/utils/spinner.js.map +1 -0
- package/dist/cli/src/utils/xaiClient.d.ts +59 -0
- package/dist/cli/src/utils/xaiClient.d.ts.map +1 -0
- package/dist/cli/src/utils/xaiClient.js +244 -0
- package/dist/cli/src/utils/xaiClient.js.map +1 -0
- package/dist/lib/analytics/usage-tracker.d.ts +125 -0
- package/dist/lib/analytics/usage-tracker.d.ts.map +1 -0
- package/dist/lib/analytics/usage-tracker.js +429 -0
- package/dist/lib/analytics/usage-tracker.js.map +1 -0
- 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
|