mycontext-cli 0.4.19 ā 1.0.1
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 +14 -11
- package/dist/agents/implementations/BackendDevAgent.d.ts +39 -0
- package/dist/agents/implementations/BackendDevAgent.d.ts.map +1 -0
- package/dist/agents/implementations/BackendDevAgent.js +821 -0
- package/dist/agents/implementations/BackendDevAgent.js.map +1 -0
- package/dist/agents/implementations/CodeGenSubAgent.d.ts +1 -1
- package/dist/agents/implementations/CodeGenSubAgent.d.ts.map +1 -1
- package/dist/agents/implementations/CodeGenSubAgent.js +34 -22
- package/dist/agents/implementations/CodeGenSubAgent.js.map +1 -1
- package/dist/agents/implementations/DocsSubAgent.d.ts +7 -0
- package/dist/agents/implementations/DocsSubAgent.d.ts.map +1 -1
- package/dist/agents/implementations/DocsSubAgent.js +20 -11
- package/dist/agents/implementations/DocsSubAgent.js.map +1 -1
- package/dist/agents/implementations/EnhancementAgent.d.ts +1 -1
- package/dist/agents/implementations/EnhancementAgent.d.ts.map +1 -1
- package/dist/agents/implementations/EnhancementAgent.js +17 -12
- package/dist/agents/implementations/EnhancementAgent.js.map +1 -1
- package/dist/cli.js +191 -39
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts +52 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +740 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/auth.d.ts +19 -26
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +187 -180
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/build-app.d.ts +33 -0
- package/dist/commands/build-app.d.ts.map +1 -0
- package/dist/commands/build-app.js +507 -0
- package/dist/commands/build-app.js.map +1 -0
- package/dist/commands/generate-components.d.ts +2 -0
- package/dist/commands/generate-components.d.ts.map +1 -1
- package/dist/commands/generate-components.js +95 -49
- package/dist/commands/generate-components.js.map +1 -1
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +250 -93
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +86 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +10 -7
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/migrate.d.ts +29 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +485 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/model.d.ts +13 -16
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +86 -320
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/playbooks.d.ts +33 -0
- package/dist/commands/playbooks.d.ts.map +1 -0
- package/dist/commands/playbooks.js +662 -0
- package/dist/commands/playbooks.js.map +1 -0
- package/dist/commands/pricing.d.ts +15 -0
- package/dist/commands/pricing.d.ts.map +1 -0
- package/dist/commands/pricing.js +129 -0
- package/dist/commands/pricing.js.map +1 -0
- package/dist/commands/promote.d.ts +22 -0
- package/dist/commands/promote.d.ts.map +1 -0
- package/dist/commands/promote.js +204 -0
- package/dist/commands/promote.js.map +1 -0
- package/dist/commands/setup.d.ts +5 -18
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +180 -340
- package/dist/commands/setup.js.map +1 -1
- package/dist/config/ai-providers.json +37 -28
- package/dist/config/api.d.ts +9 -0
- package/dist/config/api.d.ts.map +1 -0
- package/dist/config/api.js +25 -0
- package/dist/config/api.js.map +1 -0
- package/dist/config/api.ts +29 -0
- package/dist/config/pricing.json +55 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/apiKeyManager.d.ts.map +1 -1
- package/dist/utils/apiKeyManager.js +7 -0
- package/dist/utils/apiKeyManager.js.map +1 -1
- package/dist/utils/fileSystem.d.ts.map +1 -1
- package/dist/utils/fileSystem.js +3 -1
- package/dist/utils/fileSystem.js.map +1 -1
- package/dist/utils/hostedApiClient.d.ts +32 -0
- package/dist/utils/hostedApiClient.d.ts.map +1 -0
- package/dist/utils/hostedApiClient.js +231 -0
- package/dist/utils/hostedApiClient.js.map +1 -0
- package/dist/utils/hybridAIClient.d.ts +7 -3
- package/dist/utils/hybridAIClient.d.ts.map +1 -1
- package/dist/utils/hybridAIClient.js +103 -27
- package/dist/utils/hybridAIClient.js.map +1 -1
- package/dist/utils/qwenClient.d.ts +22 -0
- package/dist/utils/qwenClient.d.ts.map +1 -0
- package/dist/utils/qwenClient.js +180 -0
- package/dist/utils/qwenClient.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,740 @@
|
|
|
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.AnalyzeCommand = void 0;
|
|
40
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const fs = __importStar(require("fs-extra"));
|
|
43
|
+
const spinner_1 = require("../utils/spinner");
|
|
44
|
+
const hybridAIClient_1 = require("../utils/hybridAIClient");
|
|
45
|
+
const fileSystem_1 = require("../utils/fileSystem");
|
|
46
|
+
class AnalyzeCommand {
|
|
47
|
+
constructor() {
|
|
48
|
+
this.spinner = new spinner_1.EnhancedSpinner("Analyzing project...");
|
|
49
|
+
this.ai = new hybridAIClient_1.HybridAIClient();
|
|
50
|
+
this.fs = new fileSystem_1.FileSystemManager();
|
|
51
|
+
}
|
|
52
|
+
async execute(target, options) {
|
|
53
|
+
const { output = ".mycontext", generateContext = true, includeBrand = true, includeTypes = true, includeComponents = true, verbose = false, } = options;
|
|
54
|
+
console.log(chalk_1.default.blue.bold("š Analyzing Existing Project\n"));
|
|
55
|
+
try {
|
|
56
|
+
// Step 1: Analyze project structure
|
|
57
|
+
this.spinner.start().updateText("Analyzing project structure...");
|
|
58
|
+
const analysis = await this.analyzeProject(target);
|
|
59
|
+
this.spinner.succeed("Project structure analyzed");
|
|
60
|
+
// Step 2: Display analysis results
|
|
61
|
+
this.displayAnalysisResults(analysis);
|
|
62
|
+
// Step 3: Generate context files if requested
|
|
63
|
+
if (generateContext) {
|
|
64
|
+
this.spinner.start().updateText("Generating context files...");
|
|
65
|
+
await this.generateContextFiles(analysis, output, {
|
|
66
|
+
includeBrand,
|
|
67
|
+
includeTypes,
|
|
68
|
+
includeComponents,
|
|
69
|
+
});
|
|
70
|
+
this.spinner.succeed("Context files generated");
|
|
71
|
+
}
|
|
72
|
+
console.log(chalk_1.default.green.bold("\nā
Project analysis completed!"));
|
|
73
|
+
this.printNextSteps(analysis, generateContext);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
this.spinner.fail("Analysis failed");
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async analyzeProject(projectPath) {
|
|
81
|
+
const resolvedPath = path_1.default.resolve(projectPath);
|
|
82
|
+
// Check if it's a valid project
|
|
83
|
+
if (!(await this.isValidProject(resolvedPath))) {
|
|
84
|
+
throw new Error("Not a valid Next.js project");
|
|
85
|
+
}
|
|
86
|
+
// Analyze project structure
|
|
87
|
+
const structure = await this.analyzeStructure(resolvedPath);
|
|
88
|
+
// Analyze components
|
|
89
|
+
const components = await this.analyzeComponents(resolvedPath);
|
|
90
|
+
// Analyze types
|
|
91
|
+
const types = await this.analyzeTypes(resolvedPath);
|
|
92
|
+
// Analyze styling
|
|
93
|
+
const styling = await this.analyzeStyling(resolvedPath);
|
|
94
|
+
// Analyze dependencies
|
|
95
|
+
const dependencies = await this.analyzeDependencies(resolvedPath);
|
|
96
|
+
// Get package.json
|
|
97
|
+
const packageJson = await this.getPackageJson(resolvedPath);
|
|
98
|
+
// Infer project purpose using AI
|
|
99
|
+
const inferredPurpose = await this.inferProjectPurpose(components, types, styling, packageJson);
|
|
100
|
+
// Generate recommendations
|
|
101
|
+
const recommendations = this.generateRecommendations(structure, components, types, styling);
|
|
102
|
+
return {
|
|
103
|
+
projectType: "nextjs",
|
|
104
|
+
framework: "nextjs",
|
|
105
|
+
structure,
|
|
106
|
+
components,
|
|
107
|
+
types,
|
|
108
|
+
styling,
|
|
109
|
+
dependencies,
|
|
110
|
+
packageJson,
|
|
111
|
+
inferredPurpose,
|
|
112
|
+
recommendations,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async isValidProject(projectPath) {
|
|
116
|
+
const packageJsonPath = path_1.default.join(projectPath, "package.json");
|
|
117
|
+
const nextConfigPath = path_1.default.join(projectPath, "next.config.js");
|
|
118
|
+
const nextConfigTsPath = path_1.default.join(projectPath, "next.config.ts");
|
|
119
|
+
const hasPackageJson = await fs.pathExists(packageJsonPath);
|
|
120
|
+
const hasNextConfig = (await fs.pathExists(nextConfigPath)) ||
|
|
121
|
+
(await fs.pathExists(nextConfigTsPath));
|
|
122
|
+
if (!hasPackageJson)
|
|
123
|
+
return false;
|
|
124
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
|
|
125
|
+
const hasNextDependency = packageJson.dependencies?.next || packageJson.devDependencies?.next;
|
|
126
|
+
return hasNextDependency && hasNextConfig;
|
|
127
|
+
}
|
|
128
|
+
async analyzeStructure(projectPath) {
|
|
129
|
+
const srcPath = path_1.default.join(projectPath, "src");
|
|
130
|
+
const appPath = path_1.default.join(srcPath, "app");
|
|
131
|
+
const pagesPath = path_1.default.join(srcPath, "pages");
|
|
132
|
+
const componentsPath = path_1.default.join(srcPath, "components");
|
|
133
|
+
const libPath = path_1.default.join(srcPath, "lib");
|
|
134
|
+
const stylesPath = path_1.default.join(srcPath, "styles");
|
|
135
|
+
return {
|
|
136
|
+
hasAppRouter: await fs.pathExists(appPath),
|
|
137
|
+
hasPagesRouter: await fs.pathExists(pagesPath),
|
|
138
|
+
hasComponents: await fs.pathExists(componentsPath),
|
|
139
|
+
hasLib: await fs.pathExists(libPath),
|
|
140
|
+
hasStyles: await fs.pathExists(stylesPath),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
async analyzeComponents(projectPath) {
|
|
144
|
+
const components = [];
|
|
145
|
+
const srcPath = path_1.default.join(projectPath, "src");
|
|
146
|
+
// Analyze app directory (App Router)
|
|
147
|
+
const appPath = path_1.default.join(srcPath, "app");
|
|
148
|
+
if (await fs.pathExists(appPath)) {
|
|
149
|
+
const appComponents = await this.scanDirectory(appPath, "page", "app");
|
|
150
|
+
components.push(...appComponents);
|
|
151
|
+
}
|
|
152
|
+
// Analyze pages directory (Pages Router)
|
|
153
|
+
const pagesPath = path_1.default.join(srcPath, "pages");
|
|
154
|
+
if (await fs.pathExists(pagesPath)) {
|
|
155
|
+
const pageComponents = await this.scanDirectory(pagesPath, "page", "pages");
|
|
156
|
+
components.push(...pageComponents);
|
|
157
|
+
}
|
|
158
|
+
// Analyze components directory
|
|
159
|
+
const componentsPath = path_1.default.join(srcPath, "components");
|
|
160
|
+
if (await fs.pathExists(componentsPath)) {
|
|
161
|
+
const componentFiles = await this.scanDirectory(componentsPath, "component", "components");
|
|
162
|
+
components.push(...componentFiles);
|
|
163
|
+
}
|
|
164
|
+
return components;
|
|
165
|
+
}
|
|
166
|
+
async scanDirectory(dirPath, type, group) {
|
|
167
|
+
const components = [];
|
|
168
|
+
const scan = async (currentPath, relativePath = "") => {
|
|
169
|
+
const items = await fs.readdir(currentPath);
|
|
170
|
+
for (const item of items) {
|
|
171
|
+
const itemPath = path_1.default.join(currentPath, item);
|
|
172
|
+
const stat = await fs.stat(itemPath);
|
|
173
|
+
if (stat.isDirectory()) {
|
|
174
|
+
await scan(itemPath, path_1.default.join(relativePath, item));
|
|
175
|
+
}
|
|
176
|
+
else if (item.endsWith(".tsx") || item.endsWith(".jsx")) {
|
|
177
|
+
const component = await this.analyzeComponentFile(itemPath, type, group, relativePath);
|
|
178
|
+
if (component) {
|
|
179
|
+
components.push(component);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
await scan(dirPath);
|
|
185
|
+
return components;
|
|
186
|
+
}
|
|
187
|
+
async analyzeComponentFile(filePath, type, group, relativePath) {
|
|
188
|
+
try {
|
|
189
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
190
|
+
const fileName = path_1.default.basename(filePath, path_1.default.extname(filePath));
|
|
191
|
+
// Extract component name
|
|
192
|
+
const componentName = this.extractComponentName(content, fileName);
|
|
193
|
+
// Analyze props
|
|
194
|
+
const props = this.extractProps(content);
|
|
195
|
+
// Analyze dependencies
|
|
196
|
+
const dependencies = this.extractDependencies(content);
|
|
197
|
+
// Analyze complexity
|
|
198
|
+
const complexity = this.calculateComplexity(content);
|
|
199
|
+
// Check for hooks and state
|
|
200
|
+
const hasState = this.hasStateManagement(content);
|
|
201
|
+
const hasEffects = this.hasSideEffects(content);
|
|
202
|
+
// Check if it's client or server component
|
|
203
|
+
const isClient = content.includes("'use client'");
|
|
204
|
+
const isServer = !isClient && type === "component";
|
|
205
|
+
return {
|
|
206
|
+
name: componentName,
|
|
207
|
+
path: filePath,
|
|
208
|
+
type,
|
|
209
|
+
group,
|
|
210
|
+
props,
|
|
211
|
+
dependencies,
|
|
212
|
+
complexity,
|
|
213
|
+
hasState,
|
|
214
|
+
hasEffects,
|
|
215
|
+
isClient,
|
|
216
|
+
isServer,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
console.warn(`Failed to analyze component ${filePath}:`, error);
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
extractComponentName(content, fileName) {
|
|
225
|
+
// Try to extract from function declaration
|
|
226
|
+
const functionMatch = content.match(/function\s+(\w+)/);
|
|
227
|
+
if (functionMatch)
|
|
228
|
+
return functionMatch[1];
|
|
229
|
+
// Try to extract from const declaration
|
|
230
|
+
const constMatch = content.match(/const\s+(\w+)\s*=/);
|
|
231
|
+
if (constMatch)
|
|
232
|
+
return constMatch[1];
|
|
233
|
+
// Try to extract from export default
|
|
234
|
+
const exportMatch = content.match(/export\s+default\s+(\w+)/);
|
|
235
|
+
if (exportMatch)
|
|
236
|
+
return exportMatch[1];
|
|
237
|
+
// Fallback to filename
|
|
238
|
+
return fileName.charAt(0).toUpperCase() + fileName.slice(1);
|
|
239
|
+
}
|
|
240
|
+
extractProps(content) {
|
|
241
|
+
const props = [];
|
|
242
|
+
// Extract from interface/type definitions
|
|
243
|
+
const interfaceMatch = content.match(/interface\s+(\w+)Props\s*\{([^}]+)\}/);
|
|
244
|
+
if (interfaceMatch) {
|
|
245
|
+
const propsContent = interfaceMatch[2];
|
|
246
|
+
const propMatches = propsContent.match(/(\w+)\s*:/g);
|
|
247
|
+
if (propMatches) {
|
|
248
|
+
props.push(...propMatches.map((match) => match.replace(":", "").trim()));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Extract from function parameters
|
|
252
|
+
const functionMatch = content.match(/function\s+\w+\s*\(\s*\{([^}]+)\}/);
|
|
253
|
+
if (functionMatch) {
|
|
254
|
+
const paramsContent = functionMatch[1];
|
|
255
|
+
const paramMatches = paramsContent.match(/(\w+)/g);
|
|
256
|
+
if (paramMatches) {
|
|
257
|
+
props.push(...paramMatches);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return [...new Set(props)];
|
|
261
|
+
}
|
|
262
|
+
extractDependencies(content) {
|
|
263
|
+
const dependencies = [];
|
|
264
|
+
// Extract imports
|
|
265
|
+
const importMatches = content.match(/import\s+.*?\s+from\s+['"]([^'"]+)['"]/g);
|
|
266
|
+
if (importMatches) {
|
|
267
|
+
dependencies.push(...importMatches
|
|
268
|
+
.map((match) => {
|
|
269
|
+
const fromMatch = match.match(/from\s+['"]([^'"]+)['"]/);
|
|
270
|
+
return fromMatch ? fromMatch[1] : "";
|
|
271
|
+
})
|
|
272
|
+
.filter(Boolean));
|
|
273
|
+
}
|
|
274
|
+
return dependencies;
|
|
275
|
+
}
|
|
276
|
+
calculateComplexity(content) {
|
|
277
|
+
let complexity = 0;
|
|
278
|
+
// Count conditional statements
|
|
279
|
+
complexity += (content.match(/\b(if|else|switch|case)\b/g) || []).length;
|
|
280
|
+
// Count loops
|
|
281
|
+
complexity += (content.match(/\b(for|while|do)\b/g) || []).length;
|
|
282
|
+
// Count function calls
|
|
283
|
+
complexity += (content.match(/\w+\(/g) || []).length;
|
|
284
|
+
// Count JSX elements
|
|
285
|
+
complexity += (content.match(/<[A-Z]\w*/g) || []).length;
|
|
286
|
+
return complexity;
|
|
287
|
+
}
|
|
288
|
+
hasStateManagement(content) {
|
|
289
|
+
return (content.includes("useState") ||
|
|
290
|
+
content.includes("useReducer") ||
|
|
291
|
+
content.includes("useContext"));
|
|
292
|
+
}
|
|
293
|
+
hasSideEffects(content) {
|
|
294
|
+
return content.includes("useEffect") || content.includes("useLayoutEffect");
|
|
295
|
+
}
|
|
296
|
+
async analyzeTypes(projectPath) {
|
|
297
|
+
const types = [];
|
|
298
|
+
const srcPath = path_1.default.join(projectPath, "src");
|
|
299
|
+
const scanTypes = async (dirPath) => {
|
|
300
|
+
const items = await fs.readdir(dirPath);
|
|
301
|
+
for (const item of items) {
|
|
302
|
+
const itemPath = path_1.default.join(dirPath, item);
|
|
303
|
+
const stat = await fs.stat(itemPath);
|
|
304
|
+
if (stat.isDirectory()) {
|
|
305
|
+
await scanTypes(itemPath);
|
|
306
|
+
}
|
|
307
|
+
else if (item.endsWith(".ts") || item.endsWith(".tsx")) {
|
|
308
|
+
const fileTypes = await this.extractTypesFromFile(itemPath);
|
|
309
|
+
types.push(...fileTypes);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
await scanTypes(srcPath);
|
|
314
|
+
return types;
|
|
315
|
+
}
|
|
316
|
+
async extractTypesFromFile(filePath) {
|
|
317
|
+
try {
|
|
318
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
319
|
+
const types = [];
|
|
320
|
+
// Extract interfaces
|
|
321
|
+
const interfaceMatches = content.match(/export\s+interface\s+(\w+)\s*\{([^}]+)\}/g);
|
|
322
|
+
if (interfaceMatches) {
|
|
323
|
+
interfaceMatches.forEach((match) => {
|
|
324
|
+
const nameMatch = match.match(/interface\s+(\w+)/);
|
|
325
|
+
const propsMatch = match.match(/\{([^}]+)\}/);
|
|
326
|
+
if (nameMatch) {
|
|
327
|
+
types.push({
|
|
328
|
+
name: nameMatch[1],
|
|
329
|
+
type: "interface",
|
|
330
|
+
path: filePath,
|
|
331
|
+
properties: propsMatch
|
|
332
|
+
? propsMatch[1].split(",").map((p) => p.trim())
|
|
333
|
+
: [],
|
|
334
|
+
isExported: true,
|
|
335
|
+
isGeneric: match.includes("<"),
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
// Extract types
|
|
341
|
+
const typeMatches = content.match(/export\s+type\s+(\w+)\s*=/g);
|
|
342
|
+
if (typeMatches) {
|
|
343
|
+
typeMatches.forEach((match) => {
|
|
344
|
+
const nameMatch = match.match(/type\s+(\w+)/);
|
|
345
|
+
if (nameMatch) {
|
|
346
|
+
types.push({
|
|
347
|
+
name: nameMatch[1],
|
|
348
|
+
type: "type",
|
|
349
|
+
path: filePath,
|
|
350
|
+
properties: [],
|
|
351
|
+
isExported: true,
|
|
352
|
+
isGeneric: match.includes("<"),
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return types;
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
console.warn(`Failed to extract types from ${filePath}:`, error);
|
|
361
|
+
return [];
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
async analyzeStyling(projectPath) {
|
|
365
|
+
const srcPath = path_1.default.join(projectPath, "src");
|
|
366
|
+
const stylesPath = path_1.default.join(srcPath, "styles");
|
|
367
|
+
const appPath = path_1.default.join(srcPath, "app");
|
|
368
|
+
let framework = "vanilla";
|
|
369
|
+
let hasDesignSystem = false;
|
|
370
|
+
const colors = [];
|
|
371
|
+
const fonts = [];
|
|
372
|
+
const spacing = [];
|
|
373
|
+
const breakpoints = [];
|
|
374
|
+
const customProperties = [];
|
|
375
|
+
// Check for Tailwind
|
|
376
|
+
const tailwindConfig = (await fs.pathExists(path_1.default.join(projectPath, "tailwind.config.js"))) ||
|
|
377
|
+
(await fs.pathExists(path_1.default.join(projectPath, "tailwind.config.ts")));
|
|
378
|
+
if (tailwindConfig) {
|
|
379
|
+
framework = "tailwind";
|
|
380
|
+
hasDesignSystem = true;
|
|
381
|
+
}
|
|
382
|
+
// Check for CSS modules
|
|
383
|
+
const cssModules = await this.hasCSSModules(srcPath);
|
|
384
|
+
if (cssModules) {
|
|
385
|
+
framework = "css-modules";
|
|
386
|
+
}
|
|
387
|
+
// Check for styled-components
|
|
388
|
+
const styledComponents = await this.hasStyledComponents(srcPath);
|
|
389
|
+
if (styledComponents) {
|
|
390
|
+
framework = "styled-components";
|
|
391
|
+
}
|
|
392
|
+
// Analyze CSS files
|
|
393
|
+
if (await fs.pathExists(stylesPath)) {
|
|
394
|
+
const cssFiles = await this.findCSSFiles(stylesPath);
|
|
395
|
+
for (const cssFile of cssFiles) {
|
|
396
|
+
const content = await fs.readFile(cssFile, "utf-8");
|
|
397
|
+
colors.push(...this.extractColors(content));
|
|
398
|
+
fonts.push(...this.extractFonts(content));
|
|
399
|
+
spacing.push(...this.extractSpacing(content));
|
|
400
|
+
breakpoints.push(...this.extractBreakpoints(content));
|
|
401
|
+
customProperties.push(...this.extractCustomProperties(content));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return {
|
|
405
|
+
framework,
|
|
406
|
+
hasDesignSystem,
|
|
407
|
+
colors: [...new Set(colors)],
|
|
408
|
+
fonts: [...new Set(fonts)],
|
|
409
|
+
spacing: [...new Set(spacing)],
|
|
410
|
+
breakpoints: [...new Set(breakpoints)],
|
|
411
|
+
customProperties: [...new Set(customProperties)],
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
async hasCSSModules(srcPath) {
|
|
415
|
+
const items = await fs.readdir(srcPath);
|
|
416
|
+
return items.some((item) => item.endsWith(".module.css"));
|
|
417
|
+
}
|
|
418
|
+
async hasStyledComponents(srcPath) {
|
|
419
|
+
const items = await fs.readdir(srcPath);
|
|
420
|
+
return items.some((item) => item.includes("styled"));
|
|
421
|
+
}
|
|
422
|
+
async findCSSFiles(dirPath) {
|
|
423
|
+
const files = [];
|
|
424
|
+
const items = await fs.readdir(dirPath);
|
|
425
|
+
for (const item of items) {
|
|
426
|
+
const itemPath = path_1.default.join(dirPath, item);
|
|
427
|
+
const stat = await fs.stat(itemPath);
|
|
428
|
+
if (stat.isDirectory()) {
|
|
429
|
+
files.push(...(await this.findCSSFiles(itemPath)));
|
|
430
|
+
}
|
|
431
|
+
else if (item.endsWith(".css") ||
|
|
432
|
+
item.endsWith(".scss") ||
|
|
433
|
+
item.endsWith(".sass")) {
|
|
434
|
+
files.push(itemPath);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return files;
|
|
438
|
+
}
|
|
439
|
+
extractColors(content) {
|
|
440
|
+
const colorRegex = /#[0-9a-fA-F]{3,6}|rgb\([^)]+\)|rgba\([^)]+\)|hsl\([^)]+\)|hsla\([^)]+\)/g;
|
|
441
|
+
return content.match(colorRegex) || [];
|
|
442
|
+
}
|
|
443
|
+
extractFonts(content) {
|
|
444
|
+
const fontRegex = /font-family:\s*([^;]+)/g;
|
|
445
|
+
const matches = content.match(fontRegex) || [];
|
|
446
|
+
return matches.map((match) => match.replace("font-family:", "").trim());
|
|
447
|
+
}
|
|
448
|
+
extractSpacing(content) {
|
|
449
|
+
const spacingRegex = /(?:margin|padding|gap):\s*([^;]+)/g;
|
|
450
|
+
const matches = content.match(spacingRegex) || [];
|
|
451
|
+
return matches.map((match) => match.replace(/(?:margin|padding|gap):/, "").trim());
|
|
452
|
+
}
|
|
453
|
+
extractBreakpoints(content) {
|
|
454
|
+
const breakpointRegex = /@media\s+\([^)]+\)/g;
|
|
455
|
+
return content.match(breakpointRegex) || [];
|
|
456
|
+
}
|
|
457
|
+
extractCustomProperties(content) {
|
|
458
|
+
const customPropRegex = /--[a-zA-Z-]+/g;
|
|
459
|
+
return content.match(customPropRegex) || [];
|
|
460
|
+
}
|
|
461
|
+
async analyzeDependencies(projectPath) {
|
|
462
|
+
const packageJsonPath = path_1.default.join(projectPath, "package.json");
|
|
463
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
|
|
464
|
+
const dependencies = Object.keys(packageJson.dependencies || {});
|
|
465
|
+
const devDependencies = Object.keys(packageJson.devDependencies || {});
|
|
466
|
+
return [...dependencies, ...devDependencies];
|
|
467
|
+
}
|
|
468
|
+
async getPackageJson(projectPath) {
|
|
469
|
+
const packageJsonPath = path_1.default.join(projectPath, "package.json");
|
|
470
|
+
return JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
|
|
471
|
+
}
|
|
472
|
+
async inferProjectPurpose(components, types, styling, packageJson) {
|
|
473
|
+
const context = {
|
|
474
|
+
components: components.map((c) => ({
|
|
475
|
+
name: c.name,
|
|
476
|
+
type: c.type,
|
|
477
|
+
group: c.group,
|
|
478
|
+
})),
|
|
479
|
+
types: types.map((t) => ({ name: t.name, type: t.type })),
|
|
480
|
+
styling: styling.framework,
|
|
481
|
+
dependencies: Object.keys(packageJson.dependencies || {}),
|
|
482
|
+
name: packageJson.name,
|
|
483
|
+
description: packageJson.description,
|
|
484
|
+
};
|
|
485
|
+
const prompt = `Analyze this Next.js project and infer its purpose:
|
|
486
|
+
|
|
487
|
+
Project Context:
|
|
488
|
+
${JSON.stringify(context, null, 2)}
|
|
489
|
+
|
|
490
|
+
Based on the components, types, styling, and dependencies, what is this project's main purpose? Provide a brief 2-3 sentence description of what this application does.`;
|
|
491
|
+
try {
|
|
492
|
+
const response = await this.ai.generateText(prompt);
|
|
493
|
+
return response.text.trim();
|
|
494
|
+
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
console.warn("Failed to infer project purpose with AI, using fallback");
|
|
497
|
+
return "A Next.js application with custom components and functionality";
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
generateRecommendations(structure, components, types, styling) {
|
|
501
|
+
const recommendations = [];
|
|
502
|
+
if (!structure.hasComponents) {
|
|
503
|
+
recommendations.push("Consider organizing components in a dedicated src/components directory");
|
|
504
|
+
}
|
|
505
|
+
if (!structure.hasLib) {
|
|
506
|
+
recommendations.push("Consider creating a src/lib directory for utilities and shared functions");
|
|
507
|
+
}
|
|
508
|
+
if (components.length === 0) {
|
|
509
|
+
recommendations.push("No components found - consider creating reusable UI components");
|
|
510
|
+
}
|
|
511
|
+
if (types.length === 0) {
|
|
512
|
+
recommendations.push("Consider adding TypeScript interfaces for better type safety");
|
|
513
|
+
}
|
|
514
|
+
if (styling.framework === "vanilla") {
|
|
515
|
+
recommendations.push("Consider using a CSS framework like Tailwind CSS for better styling");
|
|
516
|
+
}
|
|
517
|
+
return recommendations;
|
|
518
|
+
}
|
|
519
|
+
displayAnalysisResults(analysis) {
|
|
520
|
+
console.log(chalk_1.default.blue.bold("\nš Project Analysis Results"));
|
|
521
|
+
console.log(chalk_1.default.gray("=".repeat(50)));
|
|
522
|
+
console.log(chalk_1.default.yellow("\nšļø Structure:"));
|
|
523
|
+
console.log(chalk_1.default.gray(` ⢠App Router: ${analysis.structure.hasAppRouter ? "ā
" : "ā"}`));
|
|
524
|
+
console.log(chalk_1.default.gray(` ⢠Pages Router: ${analysis.structure.hasPagesRouter ? "ā
" : "ā"}`));
|
|
525
|
+
console.log(chalk_1.default.gray(` ⢠Components: ${analysis.structure.hasComponents ? "ā
" : "ā"}`));
|
|
526
|
+
console.log(chalk_1.default.gray(` ⢠Lib: ${analysis.structure.hasLib ? "ā
" : "ā"}`));
|
|
527
|
+
console.log(chalk_1.default.gray(` ⢠Styles: ${analysis.structure.hasStyles ? "ā
" : "ā"}`));
|
|
528
|
+
console.log(chalk_1.default.yellow("\nš§© Components:"));
|
|
529
|
+
console.log(chalk_1.default.gray(` ⢠Total: ${analysis.components.length}`));
|
|
530
|
+
console.log(chalk_1.default.gray(` ⢠Pages: ${analysis.components.filter((c) => c.type === "page").length}`));
|
|
531
|
+
console.log(chalk_1.default.gray(` ⢠Components: ${analysis.components.filter((c) => c.type === "component").length}`));
|
|
532
|
+
console.log(chalk_1.default.gray(` ⢠Client: ${analysis.components.filter((c) => c.isClient).length}`));
|
|
533
|
+
console.log(chalk_1.default.gray(` ⢠Server: ${analysis.components.filter((c) => c.isServer).length}`));
|
|
534
|
+
console.log(chalk_1.default.yellow("\nš Types:"));
|
|
535
|
+
console.log(chalk_1.default.gray(` ⢠Total: ${analysis.types.length}`));
|
|
536
|
+
console.log(chalk_1.default.gray(` ⢠Interfaces: ${analysis.types.filter((t) => t.type === "interface").length}`));
|
|
537
|
+
console.log(chalk_1.default.gray(` ⢠Types: ${analysis.types.filter((t) => t.type === "type").length}`));
|
|
538
|
+
console.log(chalk_1.default.yellow("\nšØ Styling:"));
|
|
539
|
+
console.log(chalk_1.default.gray(` ⢠Framework: ${analysis.styling.framework}`));
|
|
540
|
+
console.log(chalk_1.default.gray(` ⢠Design System: ${analysis.styling.hasDesignSystem ? "ā
" : "ā"}`));
|
|
541
|
+
console.log(chalk_1.default.gray(` ⢠Colors: ${analysis.styling.colors.length}`));
|
|
542
|
+
console.log(chalk_1.default.gray(` ⢠Fonts: ${analysis.styling.fonts.length}`));
|
|
543
|
+
console.log(chalk_1.default.yellow("\nšÆ Inferred Purpose:"));
|
|
544
|
+
console.log(chalk_1.default.gray(` ${analysis.inferredPurpose}`));
|
|
545
|
+
if (analysis.recommendations.length > 0) {
|
|
546
|
+
console.log(chalk_1.default.yellow("\nš” Recommendations:"));
|
|
547
|
+
analysis.recommendations.forEach((rec) => {
|
|
548
|
+
console.log(chalk_1.default.gray(` ⢠${rec}`));
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async generateContextFiles(analysis, outputDir, options) {
|
|
553
|
+
const contextDir = path_1.default.join(process.cwd(), outputDir);
|
|
554
|
+
await fs.ensureDir(contextDir);
|
|
555
|
+
// Generate PRD
|
|
556
|
+
const prdContent = this.generatePRD(analysis);
|
|
557
|
+
await fs.writeFile(path_1.default.join(contextDir, "01-prd.md"), prdContent);
|
|
558
|
+
// Generate types
|
|
559
|
+
if (options.includeTypes) {
|
|
560
|
+
const typesContent = this.generateTypes(analysis);
|
|
561
|
+
await fs.writeFile(path_1.default.join(contextDir, "02-types.ts"), typesContent);
|
|
562
|
+
}
|
|
563
|
+
// Generate brand guidelines
|
|
564
|
+
if (options.includeBrand) {
|
|
565
|
+
const brandContent = this.generateBrand(analysis);
|
|
566
|
+
await fs.writeFile(path_1.default.join(contextDir, "03-brand.md"), brandContent);
|
|
567
|
+
}
|
|
568
|
+
// Generate component list
|
|
569
|
+
if (options.includeComponents) {
|
|
570
|
+
const componentListContent = this.generateComponentList(analysis);
|
|
571
|
+
await fs.writeFile(path_1.default.join(contextDir, "04-component-list.json"), componentListContent);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
generatePRD(analysis) {
|
|
575
|
+
return `# Product Requirements Document
|
|
576
|
+
|
|
577
|
+
## Project Overview
|
|
578
|
+
**Name:** ${analysis.packageJson.name || "MyContext Project"}
|
|
579
|
+
**Description:** ${analysis.inferredPurpose}
|
|
580
|
+
**Framework:** ${analysis.framework}
|
|
581
|
+
**Analysis Date:** ${new Date().toISOString()}
|
|
582
|
+
|
|
583
|
+
## Current State Analysis
|
|
584
|
+
|
|
585
|
+
### Project Structure
|
|
586
|
+
- **App Router:** ${analysis.structure.hasAppRouter ? "Yes" : "No"}
|
|
587
|
+
- **Pages Router:** ${analysis.structure.hasPagesRouter ? "Yes" : "No"}
|
|
588
|
+
- **Components Directory:** ${analysis.structure.hasComponents ? "Yes" : "No"}
|
|
589
|
+
- **Lib Directory:** ${analysis.structure.hasLib ? "Yes" : "No"}
|
|
590
|
+
|
|
591
|
+
### Components Inventory
|
|
592
|
+
Total Components: ${analysis.components.length}
|
|
593
|
+
|
|
594
|
+
#### Pages (${analysis.components.filter((c) => c.type === "page").length})
|
|
595
|
+
${analysis.components
|
|
596
|
+
.filter((c) => c.type === "page")
|
|
597
|
+
.map((c) => `- ${c.name} (${c.group})`)
|
|
598
|
+
.join("\n")}
|
|
599
|
+
|
|
600
|
+
#### UI Components (${analysis.components.filter((c) => c.type === "component").length})
|
|
601
|
+
${analysis.components
|
|
602
|
+
.filter((c) => c.type === "component")
|
|
603
|
+
.map((c) => `- ${c.name} (${c.group})`)
|
|
604
|
+
.join("\n")}
|
|
605
|
+
|
|
606
|
+
### Type System
|
|
607
|
+
Total Types: ${analysis.types.length}
|
|
608
|
+
|
|
609
|
+
#### Interfaces (${analysis.types.filter((t) => t.type === "interface").length})
|
|
610
|
+
${analysis.types
|
|
611
|
+
.filter((t) => t.type === "interface")
|
|
612
|
+
.map((t) => `- ${t.name}`)
|
|
613
|
+
.join("\n")}
|
|
614
|
+
|
|
615
|
+
#### Type Aliases (${analysis.types.filter((t) => t.type === "type").length})
|
|
616
|
+
${analysis.types
|
|
617
|
+
.filter((t) => t.type === "type")
|
|
618
|
+
.map((t) => `- ${t.name}`)
|
|
619
|
+
.join("\n")}
|
|
620
|
+
|
|
621
|
+
### Styling System
|
|
622
|
+
- **Framework:** ${analysis.styling.framework}
|
|
623
|
+
- **Design System:** ${analysis.styling.hasDesignSystem ? "Yes" : "No"}
|
|
624
|
+
- **Custom Colors:** ${analysis.styling.colors.length}
|
|
625
|
+
- **Custom Fonts:** ${analysis.styling.fonts.length}
|
|
626
|
+
|
|
627
|
+
## Recommendations
|
|
628
|
+
|
|
629
|
+
${analysis.recommendations.map((rec) => `- ${rec}`).join("\n")}
|
|
630
|
+
|
|
631
|
+
## Next Steps
|
|
632
|
+
|
|
633
|
+
1. Review and refine the generated context files
|
|
634
|
+
2. Implement missing server actions and hooks
|
|
635
|
+
3. Enhance component functionality
|
|
636
|
+
4. Improve type safety where needed
|
|
637
|
+
5. Consider implementing a design system
|
|
638
|
+
|
|
639
|
+
## Dependencies
|
|
640
|
+
|
|
641
|
+
${analysis.dependencies.map((dep) => `- ${dep}`).join("\n")}
|
|
642
|
+
`;
|
|
643
|
+
}
|
|
644
|
+
generateTypes(analysis) {
|
|
645
|
+
let content = `// Generated types from existing project analysis
|
|
646
|
+
// Date: ${new Date().toISOString()}
|
|
647
|
+
|
|
648
|
+
`;
|
|
649
|
+
// Generate interfaces from existing types
|
|
650
|
+
analysis.types.forEach((type) => {
|
|
651
|
+
if (type.type === "interface") {
|
|
652
|
+
content += `export interface ${type.name} {\n`;
|
|
653
|
+
type.properties.forEach((prop) => {
|
|
654
|
+
content += ` ${prop};\n`;
|
|
655
|
+
});
|
|
656
|
+
content += `}\n\n`;
|
|
657
|
+
}
|
|
658
|
+
else if (type.type === "type") {
|
|
659
|
+
content += `export type ${type.name} = any; // TODO: Define proper type\n\n`;
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
// Generate component prop interfaces
|
|
663
|
+
analysis.components.forEach((component) => {
|
|
664
|
+
if (component.props.length > 0) {
|
|
665
|
+
content += `export interface ${component.name}Props {\n`;
|
|
666
|
+
component.props.forEach((prop) => {
|
|
667
|
+
content += ` ${prop}: any; // TODO: Define proper type\n`;
|
|
668
|
+
});
|
|
669
|
+
content += `}\n\n`;
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
return content;
|
|
673
|
+
}
|
|
674
|
+
generateBrand(analysis) {
|
|
675
|
+
return `# Brand Guidelines
|
|
676
|
+
|
|
677
|
+
## Color Palette
|
|
678
|
+
${analysis.styling.colors.map((color) => `- ${color}`).join("\n")}
|
|
679
|
+
|
|
680
|
+
## Typography
|
|
681
|
+
${analysis.styling.fonts.map((font) => `- ${font}`).join("\n")}
|
|
682
|
+
|
|
683
|
+
## Spacing System
|
|
684
|
+
${analysis.styling.spacing.map((space) => `- ${space}`).join("\n")}
|
|
685
|
+
|
|
686
|
+
## Breakpoints
|
|
687
|
+
${analysis.styling.breakpoints.map((bp) => `- ${bp}`).join("\n")}
|
|
688
|
+
|
|
689
|
+
## Custom Properties
|
|
690
|
+
${analysis.styling.customProperties.map((prop) => `- ${prop}`).join("\n")}
|
|
691
|
+
|
|
692
|
+
## Design System Status
|
|
693
|
+
- **Framework:** ${analysis.styling.framework}
|
|
694
|
+
- **Has Design System:** ${analysis.styling.hasDesignSystem ? "Yes" : "No"}
|
|
695
|
+
|
|
696
|
+
## Recommendations
|
|
697
|
+
${analysis.styling.framework === "vanilla"
|
|
698
|
+
? "- Consider implementing a design system with consistent tokens"
|
|
699
|
+
: ""}
|
|
700
|
+
${!analysis.styling.hasDesignSystem
|
|
701
|
+
? "- Consider using a design system like Tailwind CSS or Chakra UI"
|
|
702
|
+
: ""}
|
|
703
|
+
`;
|
|
704
|
+
}
|
|
705
|
+
generateComponentList(analysis) {
|
|
706
|
+
const componentList = {
|
|
707
|
+
groups: analysis.components.reduce((acc, component) => {
|
|
708
|
+
const group = component.group || "default";
|
|
709
|
+
if (!acc[group]) {
|
|
710
|
+
acc[group] = [];
|
|
711
|
+
}
|
|
712
|
+
acc[group].push({
|
|
713
|
+
name: component.name,
|
|
714
|
+
description: `${component.type} component`,
|
|
715
|
+
type: component.type,
|
|
716
|
+
priority: "medium",
|
|
717
|
+
dependencies: component.dependencies,
|
|
718
|
+
tags: [component.type, component.isClient ? "client" : "server"],
|
|
719
|
+
});
|
|
720
|
+
return acc;
|
|
721
|
+
}, {}),
|
|
722
|
+
};
|
|
723
|
+
return JSON.stringify(componentList, null, 2);
|
|
724
|
+
}
|
|
725
|
+
printNextSteps(analysis, generateContext) {
|
|
726
|
+
console.log(chalk_1.default.yellow("\nš Next Steps:"));
|
|
727
|
+
if (generateContext) {
|
|
728
|
+
console.log(chalk_1.default.gray("1. Review the generated context files in .mycontext/"));
|
|
729
|
+
console.log(chalk_1.default.gray("2. Update the PRD with your specific requirements"));
|
|
730
|
+
console.log(chalk_1.default.gray("3. Refine the types and interfaces"));
|
|
731
|
+
console.log(chalk_1.default.gray("4. Customize the brand guidelines"));
|
|
732
|
+
}
|
|
733
|
+
console.log(chalk_1.default.gray("5. Run 'mycontext generate context' to enhance the context"));
|
|
734
|
+
console.log(chalk_1.default.gray("6. Run 'mycontext generate components-list' to plan new components"));
|
|
735
|
+
console.log(chalk_1.default.gray("7. Run 'mycontext generate-components' to create new components"));
|
|
736
|
+
console.log(chalk_1.default.gray("8. Use 'mycontext promote' to move components to production"));
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
exports.AnalyzeCommand = AnalyzeCommand;
|
|
740
|
+
//# sourceMappingURL=analyze.js.map
|