mycontext-cli 1.0.29 → 1.0.35
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 +19 -10
- package/dist/cli.js +5 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/generate-context-files.d.ts +8 -0
- package/dist/commands/generate-context-files.d.ts.map +1 -1
- package/dist/commands/generate-context-files.js +97 -22
- package/dist/commands/generate-context-files.js.map +1 -1
- package/dist/commands/generate.d.ts +51 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +550 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/config/ai-providers.json +7 -7
- package/dist/utils/hybridAIClient.d.ts.map +1 -1
- package/dist/utils/hybridAIClient.js +45 -56
- package/dist/utils/hybridAIClient.js.map +1 -1
- package/package.json +1 -1
|
@@ -79,7 +79,19 @@ class GenerateCommand {
|
|
|
79
79
|
let result;
|
|
80
80
|
switch (type) {
|
|
81
81
|
case "context":
|
|
82
|
-
|
|
82
|
+
// Check if user wants full context generation (PRD + A/B/C/D files)
|
|
83
|
+
if (options.full) {
|
|
84
|
+
// Generate both PRD and A/B/C/D files
|
|
85
|
+
result = await this.generateFullContext(projectContext, options);
|
|
86
|
+
}
|
|
87
|
+
else if (options.filesOnly) {
|
|
88
|
+
// Generate only A/B/C/D files (requires existing PRD)
|
|
89
|
+
result = await this.generateContextFiles(projectContext, options);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Default: Generate only PRD
|
|
93
|
+
result = await this.generateContext(projectContext, options);
|
|
94
|
+
}
|
|
83
95
|
break;
|
|
84
96
|
case "types":
|
|
85
97
|
result = await this.generateTypes(projectContext, options);
|
|
@@ -3156,6 +3168,543 @@ ${isEcommerce
|
|
|
3156
3168
|
}
|
|
3157
3169
|
return undefined;
|
|
3158
3170
|
}
|
|
3171
|
+
/**
|
|
3172
|
+
* Generate full context (PRD + A/B/C/D files)
|
|
3173
|
+
*/
|
|
3174
|
+
async generateFullContext(projectContext, options) {
|
|
3175
|
+
console.log(chalk_1.default.blue("🚀 Generating Full Context (PRD + A/B/C/D files)"));
|
|
3176
|
+
// First generate the PRD
|
|
3177
|
+
const prdResult = await this.generateContext(projectContext, options);
|
|
3178
|
+
if (!prdResult.success) {
|
|
3179
|
+
return prdResult;
|
|
3180
|
+
}
|
|
3181
|
+
// Then generate the A/B/C/D files
|
|
3182
|
+
const contextFilesResult = await this.generateContextFiles(projectContext, options);
|
|
3183
|
+
if (!contextFilesResult.success) {
|
|
3184
|
+
return contextFilesResult;
|
|
3185
|
+
}
|
|
3186
|
+
return {
|
|
3187
|
+
success: true,
|
|
3188
|
+
content: "Full context generated successfully (PRD + A/B/C/D files)",
|
|
3189
|
+
provider: "hybrid",
|
|
3190
|
+
metadata: { model: "hybrid", tokens: 0, latency: 0 },
|
|
3191
|
+
};
|
|
3192
|
+
}
|
|
3193
|
+
/**
|
|
3194
|
+
* Generate A/B/C/D context files (Features, User Flows, Edge Cases, Technical Specs)
|
|
3195
|
+
*/
|
|
3196
|
+
async generateContextFiles(projectContext, options) {
|
|
3197
|
+
const contextDir = path_1.default.join(process.cwd(), ".mycontext");
|
|
3198
|
+
// Ensure .mycontext directory exists
|
|
3199
|
+
await fs.ensureDir(contextDir);
|
|
3200
|
+
// Check if context files already exist
|
|
3201
|
+
const existingFiles = await this.checkExistingContextFiles(contextDir);
|
|
3202
|
+
if (existingFiles.length > 0 && !options.force) {
|
|
3203
|
+
return {
|
|
3204
|
+
success: false,
|
|
3205
|
+
error: `Context files already exist: ${existingFiles.join(", ")}. Use --force to overwrite.`,
|
|
3206
|
+
provider: "system",
|
|
3207
|
+
metadata: { model: "system", tokens: 0, latency: 0 },
|
|
3208
|
+
};
|
|
3209
|
+
}
|
|
3210
|
+
// Get context from PRD if it exists, otherwise use description
|
|
3211
|
+
const contextContent = await this.getContextForGeneration(contextDir, projectContext.description);
|
|
3212
|
+
try {
|
|
3213
|
+
// Generate each context file using the PRD content as context
|
|
3214
|
+
await this.generateFeaturesFile(contextDir, contextContent);
|
|
3215
|
+
await this.generateUserFlowsFile(contextDir, contextContent);
|
|
3216
|
+
await this.generateEdgeCasesFile(contextDir, contextContent);
|
|
3217
|
+
await this.generateTechnicalSpecsFile(contextDir, contextContent);
|
|
3218
|
+
return {
|
|
3219
|
+
success: true,
|
|
3220
|
+
content: "Context files generated successfully",
|
|
3221
|
+
provider: "hybrid",
|
|
3222
|
+
metadata: { model: "hybrid", tokens: 0, latency: 0 },
|
|
3223
|
+
};
|
|
3224
|
+
}
|
|
3225
|
+
catch (error) {
|
|
3226
|
+
return {
|
|
3227
|
+
success: false,
|
|
3228
|
+
error: `Context file generation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
3229
|
+
provider: "system",
|
|
3230
|
+
metadata: { model: "system", tokens: 0, latency: 0 },
|
|
3231
|
+
};
|
|
3232
|
+
}
|
|
3233
|
+
}
|
|
3234
|
+
async checkExistingContextFiles(contextDir) {
|
|
3235
|
+
const files = [
|
|
3236
|
+
"01a-features.md",
|
|
3237
|
+
"01b-user-flows.md",
|
|
3238
|
+
"01c-edge-cases.md",
|
|
3239
|
+
"01d-technical-specs.md",
|
|
3240
|
+
];
|
|
3241
|
+
const existingFiles = [];
|
|
3242
|
+
for (const file of files) {
|
|
3243
|
+
if (await fs.pathExists(path_1.default.join(contextDir, file))) {
|
|
3244
|
+
existingFiles.push(file);
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
return existingFiles;
|
|
3248
|
+
}
|
|
3249
|
+
async generateFeaturesFile(contextDir, contextContent) {
|
|
3250
|
+
const prompt = this.buildFeaturesPrompt(contextContent);
|
|
3251
|
+
try {
|
|
3252
|
+
// Add timeout to prevent infinite loops
|
|
3253
|
+
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("AI generation timeout")), 30000) // 30 second timeout
|
|
3254
|
+
);
|
|
3255
|
+
const responsePromise = this.ai.generateText(prompt, {
|
|
3256
|
+
temperature: 0.7,
|
|
3257
|
+
maxTokens: 2000,
|
|
3258
|
+
});
|
|
3259
|
+
const response = (await Promise.race([
|
|
3260
|
+
responsePromise,
|
|
3261
|
+
timeoutPromise,
|
|
3262
|
+
]));
|
|
3263
|
+
// Check if response is valid
|
|
3264
|
+
if (!response || !response.text || response.text.trim().length < 50) {
|
|
3265
|
+
throw new Error("AI response too short or invalid");
|
|
3266
|
+
}
|
|
3267
|
+
const content = this.formatFeaturesContent(response.text);
|
|
3268
|
+
await fs.writeFile(path_1.default.join(contextDir, "01a-features.md"), content);
|
|
3269
|
+
}
|
|
3270
|
+
catch (error) {
|
|
3271
|
+
console.log(chalk_1.default.yellow("⚠️ AI generation failed, using PRD content as fallback"));
|
|
3272
|
+
// Fallback: Extract features from PRD content
|
|
3273
|
+
const fallbackContent = this.extractFeaturesFromPRD(contextContent);
|
|
3274
|
+
await fs.writeFile(path_1.default.join(contextDir, "01a-features.md"), fallbackContent);
|
|
3275
|
+
}
|
|
3276
|
+
}
|
|
3277
|
+
async generateUserFlowsFile(contextDir, contextContent) {
|
|
3278
|
+
const prompt = this.buildUserFlowsPrompt(contextContent);
|
|
3279
|
+
try {
|
|
3280
|
+
const response = await this.ai.generateText(prompt, {
|
|
3281
|
+
temperature: 0.7,
|
|
3282
|
+
maxTokens: 2000,
|
|
3283
|
+
});
|
|
3284
|
+
const content = this.formatUserFlowsContent(response.text);
|
|
3285
|
+
await fs.writeFile(path_1.default.join(contextDir, "01b-user-flows.md"), content);
|
|
3286
|
+
}
|
|
3287
|
+
catch (error) {
|
|
3288
|
+
console.log(chalk_1.default.yellow("⚠️ AI generation failed, using PRD content as fallback"));
|
|
3289
|
+
// Fallback: Extract user flows from PRD content
|
|
3290
|
+
const fallbackContent = this.extractUserFlowsFromPRD(contextContent);
|
|
3291
|
+
await fs.writeFile(path_1.default.join(contextDir, "01b-user-flows.md"), fallbackContent);
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
async generateEdgeCasesFile(contextDir, contextContent) {
|
|
3295
|
+
const prompt = this.buildEdgeCasesPrompt(contextContent);
|
|
3296
|
+
try {
|
|
3297
|
+
const response = await this.ai.generateText(prompt, {
|
|
3298
|
+
temperature: 0.7,
|
|
3299
|
+
maxTokens: 2000,
|
|
3300
|
+
});
|
|
3301
|
+
const content = this.formatEdgeCasesContent(response.text);
|
|
3302
|
+
await fs.writeFile(path_1.default.join(contextDir, "01c-edge-cases.md"), content);
|
|
3303
|
+
}
|
|
3304
|
+
catch (error) {
|
|
3305
|
+
console.log(chalk_1.default.yellow("⚠️ AI generation failed, using PRD content as fallback"));
|
|
3306
|
+
// Fallback: Extract edge cases from PRD content
|
|
3307
|
+
const fallbackContent = this.extractEdgeCasesFromPRD(contextContent);
|
|
3308
|
+
await fs.writeFile(path_1.default.join(contextDir, "01c-edge-cases.md"), fallbackContent);
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
async generateTechnicalSpecsFile(contextDir, contextContent) {
|
|
3312
|
+
const prompt = this.buildTechnicalSpecsPrompt(contextContent);
|
|
3313
|
+
try {
|
|
3314
|
+
const response = await this.ai.generateText(prompt, {
|
|
3315
|
+
temperature: 0.7,
|
|
3316
|
+
maxTokens: 2000,
|
|
3317
|
+
});
|
|
3318
|
+
const content = this.formatTechnicalSpecsContent(response.text);
|
|
3319
|
+
await fs.writeFile(path_1.default.join(contextDir, "01d-technical-specs.md"), content);
|
|
3320
|
+
}
|
|
3321
|
+
catch (error) {
|
|
3322
|
+
console.log(chalk_1.default.yellow("⚠️ AI generation failed, using PRD content as fallback"));
|
|
3323
|
+
// Fallback: Extract technical specs from PRD content
|
|
3324
|
+
const fallbackContent = this.extractTechnicalSpecsFromPRD(contextContent);
|
|
3325
|
+
await fs.writeFile(path_1.default.join(contextDir, "01d-technical-specs.md"), fallbackContent);
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
buildFeaturesPrompt(contextContent) {
|
|
3329
|
+
return `You are a product manager creating a comprehensive features document for a web application.
|
|
3330
|
+
|
|
3331
|
+
${contextContent ? `Project Context (from PRD): ${contextContent}` : "Generate features for a modern web application."}
|
|
3332
|
+
|
|
3333
|
+
Create a detailed features document that includes:
|
|
3334
|
+
|
|
3335
|
+
1. **Core Features** - Primary functionality that defines the product
|
|
3336
|
+
2. **User Features** - Features that directly benefit end users
|
|
3337
|
+
3. **Admin Features** - Administrative and management capabilities
|
|
3338
|
+
4. **Technical Features** - Backend, API, and infrastructure features
|
|
3339
|
+
5. **Integration Features** - Third-party integrations and APIs
|
|
3340
|
+
6. **Security Features** - Authentication, authorization, and data protection
|
|
3341
|
+
7. **Performance Features** - Optimization and scalability features
|
|
3342
|
+
8. **Accessibility Features** - WCAG compliance and inclusive design
|
|
3343
|
+
|
|
3344
|
+
For each feature, include:
|
|
3345
|
+
- Feature name and description
|
|
3346
|
+
- User value proposition
|
|
3347
|
+
- Acceptance criteria
|
|
3348
|
+
- Priority level (High/Medium/Low)
|
|
3349
|
+
- Dependencies on other features
|
|
3350
|
+
|
|
3351
|
+
Format the output as a well-structured markdown document with clear sections and bullet points.`;
|
|
3352
|
+
}
|
|
3353
|
+
buildUserFlowsPrompt(contextContent) {
|
|
3354
|
+
return `You are a UX designer creating comprehensive user flow documentation for a web application.
|
|
3355
|
+
|
|
3356
|
+
${contextContent ? `Project Context (from PRD): ${contextContent}` : "Generate user flows for a modern web application."}
|
|
3357
|
+
|
|
3358
|
+
Create detailed user flow documentation that includes:
|
|
3359
|
+
|
|
3360
|
+
1. **Primary User Journeys** - Main user paths through the application
|
|
3361
|
+
2. **Authentication Flows** - Login, signup, password reset, etc.
|
|
3362
|
+
3. **Core Feature Flows** - How users interact with main features
|
|
3363
|
+
4. **Error Handling Flows** - What happens when things go wrong
|
|
3364
|
+
5. **Admin/Management Flows** - Administrative user journeys
|
|
3365
|
+
6. **Mobile vs Desktop Flows** - Responsive design considerations
|
|
3366
|
+
7. **Accessibility Flows** - Screen reader and keyboard navigation paths
|
|
3367
|
+
|
|
3368
|
+
For each flow, include:
|
|
3369
|
+
- Flow name and description
|
|
3370
|
+
- Step-by-step user actions
|
|
3371
|
+
- System responses and feedback
|
|
3372
|
+
- Decision points and branches
|
|
3373
|
+
- Error states and recovery
|
|
3374
|
+
- Success criteria
|
|
3375
|
+
|
|
3376
|
+
Format the output as a well-structured markdown document with clear sections, numbered steps, and flow diagrams in text format.`;
|
|
3377
|
+
}
|
|
3378
|
+
buildEdgeCasesPrompt(contextContent) {
|
|
3379
|
+
return `You are a QA engineer creating comprehensive edge cases and error scenarios documentation for a web application.
|
|
3380
|
+
|
|
3381
|
+
${contextContent ? `Project Context (from PRD): ${contextContent}` : "Generate edge cases for a modern web application."}
|
|
3382
|
+
|
|
3383
|
+
Create detailed edge cases documentation that includes:
|
|
3384
|
+
|
|
3385
|
+
1. **Input Validation Edge Cases** - Invalid, malformed, or extreme input scenarios
|
|
3386
|
+
2. **Network Edge Cases** - Offline, slow connections, timeouts, API failures
|
|
3387
|
+
3. **Browser Edge Cases** - Different browsers, versions, disabled features
|
|
3388
|
+
4. **Device Edge Cases** - Mobile, tablet, desktop, different screen sizes
|
|
3389
|
+
5. **Data Edge Cases** - Empty data, large datasets, concurrent modifications
|
|
3390
|
+
6. **Security Edge Cases** - Injection attacks, XSS, CSRF, unauthorized access
|
|
3391
|
+
7. **Performance Edge Cases** - High load, memory constraints, slow operations
|
|
3392
|
+
8. **Accessibility Edge Cases** - Screen readers, keyboard-only navigation, high contrast
|
|
3393
|
+
9. **Integration Edge Cases** - Third-party service failures, API changes
|
|
3394
|
+
10. **Business Logic Edge Cases** - Boundary conditions, race conditions
|
|
3395
|
+
|
|
3396
|
+
For each edge case, include:
|
|
3397
|
+
- Scenario description
|
|
3398
|
+
- Expected behavior
|
|
3399
|
+
- Potential impact
|
|
3400
|
+
- Mitigation strategies
|
|
3401
|
+
- Testing approach
|
|
3402
|
+
|
|
3403
|
+
Format the output as a well-structured markdown document with clear sections and detailed scenarios.`;
|
|
3404
|
+
}
|
|
3405
|
+
buildTechnicalSpecsPrompt(contextContent) {
|
|
3406
|
+
return `You are a technical architect creating comprehensive technical specifications for a web application.
|
|
3407
|
+
|
|
3408
|
+
${contextContent ? `Project Context (from PRD): ${contextContent}` : "Generate technical specs for a modern web application."}
|
|
3409
|
+
|
|
3410
|
+
Create detailed technical specifications that include:
|
|
3411
|
+
|
|
3412
|
+
1. **Architecture Overview** - System design, components, and relationships
|
|
3413
|
+
2. **Technology Stack** - Frontend, backend, database, deployment technologies
|
|
3414
|
+
3. **API Specifications** - Endpoints, request/response formats, authentication
|
|
3415
|
+
4. **Database Design** - Schema, relationships, indexing, data flow
|
|
3416
|
+
5. **Security Requirements** - Authentication, authorization, data protection
|
|
3417
|
+
6. **Performance Requirements** - Response times, throughput, scalability
|
|
3418
|
+
7. **Deployment Architecture** - Infrastructure, CI/CD, monitoring
|
|
3419
|
+
8. **Integration Requirements** - Third-party services, APIs, webhooks
|
|
3420
|
+
9. **Development Standards** - Code style, testing, documentation
|
|
3421
|
+
10. **Monitoring and Logging** - Error tracking, analytics, performance monitoring
|
|
3422
|
+
|
|
3423
|
+
For each specification, include:
|
|
3424
|
+
- Requirement description
|
|
3425
|
+
- Technical approach
|
|
3426
|
+
- Implementation details
|
|
3427
|
+
- Dependencies
|
|
3428
|
+
- Success criteria
|
|
3429
|
+
|
|
3430
|
+
Format the output as a well-structured markdown document with clear sections and technical details.`;
|
|
3431
|
+
}
|
|
3432
|
+
formatFeaturesContent(response) {
|
|
3433
|
+
return `# Product Features
|
|
3434
|
+
|
|
3435
|
+
${response}
|
|
3436
|
+
|
|
3437
|
+
---
|
|
3438
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3439
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3440
|
+
`;
|
|
3441
|
+
}
|
|
3442
|
+
formatUserFlowsContent(response) {
|
|
3443
|
+
return `# User Flows
|
|
3444
|
+
|
|
3445
|
+
${response}
|
|
3446
|
+
|
|
3447
|
+
---
|
|
3448
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3449
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3450
|
+
`;
|
|
3451
|
+
}
|
|
3452
|
+
formatEdgeCasesContent(response) {
|
|
3453
|
+
return `# Edge Cases and Error Scenarios
|
|
3454
|
+
|
|
3455
|
+
${response}
|
|
3456
|
+
|
|
3457
|
+
---
|
|
3458
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3459
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3460
|
+
`;
|
|
3461
|
+
}
|
|
3462
|
+
formatTechnicalSpecsContent(response) {
|
|
3463
|
+
return `# Technical Specifications
|
|
3464
|
+
|
|
3465
|
+
${response}
|
|
3466
|
+
|
|
3467
|
+
---
|
|
3468
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3469
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3470
|
+
`;
|
|
3471
|
+
}
|
|
3472
|
+
/**
|
|
3473
|
+
* Get context content for generation - prefer PRD over description
|
|
3474
|
+
*/
|
|
3475
|
+
async getContextForGeneration(contextDir, fallbackDescription) {
|
|
3476
|
+
// First, try to read from 01-prd.md
|
|
3477
|
+
const prdPath = path_1.default.join(contextDir, "01-prd.md");
|
|
3478
|
+
if (await fs.pathExists(prdPath)) {
|
|
3479
|
+
try {
|
|
3480
|
+
const prdContent = await fs.readFile(prdPath, "utf8");
|
|
3481
|
+
// Check if PRD is just a template/starter sample
|
|
3482
|
+
if (this.isTemplatePRD(prdContent)) {
|
|
3483
|
+
console.log(chalk_1.default.yellow("⚠️ PRD appears to be a template, not using as context"));
|
|
3484
|
+
}
|
|
3485
|
+
else {
|
|
3486
|
+
console.log(chalk_1.default.blue("📖 Using existing PRD as context for context files generation"));
|
|
3487
|
+
return prdContent;
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
catch (error) {
|
|
3491
|
+
console.log(chalk_1.default.yellow("⚠️ Could not read PRD file, falling back to description"));
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
// Fallback to description if no PRD exists
|
|
3495
|
+
if (fallbackDescription) {
|
|
3496
|
+
console.log(chalk_1.default.blue("📝 Using project description as context"));
|
|
3497
|
+
return fallbackDescription;
|
|
3498
|
+
}
|
|
3499
|
+
// No context available - ask user
|
|
3500
|
+
console.log(chalk_1.default.red("❌ No PRD or description found!"));
|
|
3501
|
+
console.log(chalk_1.default.yellow("Please provide context by either:"));
|
|
3502
|
+
console.log(chalk_1.default.gray(" 1. Run 'mycontext generate context' first to create a PRD"));
|
|
3503
|
+
console.log(chalk_1.default.gray(" 2. Use --description flag: mycontext generate-context-files --description 'Your project'"));
|
|
3504
|
+
console.log(chalk_1.default.gray(" 3. Create a PRD file manually at .mycontext/01-prd.md"));
|
|
3505
|
+
throw new Error("No context available for generation. Please provide a PRD or description.");
|
|
3506
|
+
}
|
|
3507
|
+
/**
|
|
3508
|
+
* Check if PRD content is just a template/starter sample
|
|
3509
|
+
*/
|
|
3510
|
+
isTemplatePRD(content) {
|
|
3511
|
+
const templateIndicators = [
|
|
3512
|
+
"MyContext project",
|
|
3513
|
+
"Replace this with your actual project description",
|
|
3514
|
+
"TODO: Add your project details",
|
|
3515
|
+
"This is a template",
|
|
3516
|
+
"Sample project",
|
|
3517
|
+
"Example project",
|
|
3518
|
+
"Your project description here",
|
|
3519
|
+
"Project Name: [Your Project Name]",
|
|
3520
|
+
"Description: [Your project description]",
|
|
3521
|
+
"## Project Overview\n\n[Add your project overview here]",
|
|
3522
|
+
"## Requirements\n\n[Add your requirements here]",
|
|
3523
|
+
"## Features\n\n[Add your features here]",
|
|
3524
|
+
"## Technical Specifications\n\n[Add your technical specs here]",
|
|
3525
|
+
];
|
|
3526
|
+
// Check if content contains multiple template indicators
|
|
3527
|
+
const templateMatches = templateIndicators.filter((indicator) => content.toLowerCase().includes(indicator.toLowerCase()));
|
|
3528
|
+
// If more than 2 template indicators are found, it's likely a template
|
|
3529
|
+
if (templateMatches.length >= 2) {
|
|
3530
|
+
return true;
|
|
3531
|
+
}
|
|
3532
|
+
// Check if content is very short (likely a template)
|
|
3533
|
+
if (content.trim().length < 200) {
|
|
3534
|
+
return true;
|
|
3535
|
+
}
|
|
3536
|
+
// Check if content is mostly placeholder text
|
|
3537
|
+
const placeholderRatio = (content.match(/\[.*?\]/g) || []).length /
|
|
3538
|
+
(content.split(" ").length || 1);
|
|
3539
|
+
if (placeholderRatio > 0.1) {
|
|
3540
|
+
// More than 10% placeholders
|
|
3541
|
+
return true;
|
|
3542
|
+
}
|
|
3543
|
+
return false;
|
|
3544
|
+
}
|
|
3545
|
+
/**
|
|
3546
|
+
* Extract features from PRD content as fallback
|
|
3547
|
+
*/
|
|
3548
|
+
extractFeaturesFromPRD(prdContent) {
|
|
3549
|
+
if (!prdContent) {
|
|
3550
|
+
return `# Product Features
|
|
3551
|
+
|
|
3552
|
+
## Core Features
|
|
3553
|
+
|
|
3554
|
+
*No features available - PRD content not found*
|
|
3555
|
+
|
|
3556
|
+
---
|
|
3557
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3558
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3559
|
+
`;
|
|
3560
|
+
}
|
|
3561
|
+
// Extract features from PRD content
|
|
3562
|
+
const features = this.extractSectionFromPRD(prdContent, [
|
|
3563
|
+
"Core Features",
|
|
3564
|
+
"Features",
|
|
3565
|
+
"Key Features",
|
|
3566
|
+
"Main Features",
|
|
3567
|
+
]);
|
|
3568
|
+
return `# Product Features
|
|
3569
|
+
|
|
3570
|
+
${features || "## Core Features\n\n*Features will be extracted from PRD content*"}
|
|
3571
|
+
|
|
3572
|
+
---
|
|
3573
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3574
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3575
|
+
`;
|
|
3576
|
+
}
|
|
3577
|
+
/**
|
|
3578
|
+
* Extract user flows from PRD content as fallback
|
|
3579
|
+
*/
|
|
3580
|
+
extractUserFlowsFromPRD(prdContent) {
|
|
3581
|
+
if (!prdContent) {
|
|
3582
|
+
return `# User Flows
|
|
3583
|
+
|
|
3584
|
+
## User Journey
|
|
3585
|
+
|
|
3586
|
+
*No user flows available - PRD content not found*
|
|
3587
|
+
|
|
3588
|
+
---
|
|
3589
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3590
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3591
|
+
`;
|
|
3592
|
+
}
|
|
3593
|
+
// Extract user flows from PRD content
|
|
3594
|
+
const userFlows = this.extractSectionFromPRD(prdContent, [
|
|
3595
|
+
"User Roles",
|
|
3596
|
+
"User Journey",
|
|
3597
|
+
"User Flows",
|
|
3598
|
+
"Workflow",
|
|
3599
|
+
]);
|
|
3600
|
+
return `# User Flows
|
|
3601
|
+
|
|
3602
|
+
${userFlows || "## User Journey\n\n*User flows will be extracted from PRD content*"}
|
|
3603
|
+
|
|
3604
|
+
---
|
|
3605
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3606
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3607
|
+
`;
|
|
3608
|
+
}
|
|
3609
|
+
/**
|
|
3610
|
+
* Extract edge cases from PRD content as fallback
|
|
3611
|
+
*/
|
|
3612
|
+
extractEdgeCasesFromPRD(prdContent) {
|
|
3613
|
+
if (!prdContent) {
|
|
3614
|
+
return `# Edge Cases and Error Scenarios
|
|
3615
|
+
|
|
3616
|
+
## Error Handling
|
|
3617
|
+
|
|
3618
|
+
*No edge cases available - PRD content not found*
|
|
3619
|
+
|
|
3620
|
+
---
|
|
3621
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3622
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3623
|
+
`;
|
|
3624
|
+
}
|
|
3625
|
+
// Extract edge cases from PRD content
|
|
3626
|
+
const edgeCases = this.extractSectionFromPRD(prdContent, [
|
|
3627
|
+
"Risk Mitigation",
|
|
3628
|
+
"Edge Cases",
|
|
3629
|
+
"Error Scenarios",
|
|
3630
|
+
"Troubleshooting",
|
|
3631
|
+
]);
|
|
3632
|
+
return `# Edge Cases and Error Scenarios
|
|
3633
|
+
|
|
3634
|
+
${edgeCases || "## Error Handling\n\n*Edge cases will be extracted from PRD content*"}
|
|
3635
|
+
|
|
3636
|
+
---
|
|
3637
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3638
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3639
|
+
`;
|
|
3640
|
+
}
|
|
3641
|
+
/**
|
|
3642
|
+
* Extract technical specs from PRD content as fallback
|
|
3643
|
+
*/
|
|
3644
|
+
extractTechnicalSpecsFromPRD(prdContent) {
|
|
3645
|
+
if (!prdContent) {
|
|
3646
|
+
return `# Technical Specifications
|
|
3647
|
+
|
|
3648
|
+
## Architecture
|
|
3649
|
+
|
|
3650
|
+
*No technical specs available - PRD content not found*
|
|
3651
|
+
|
|
3652
|
+
---
|
|
3653
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3654
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3655
|
+
`;
|
|
3656
|
+
}
|
|
3657
|
+
// Extract technical specs from PRD content
|
|
3658
|
+
const techSpecs = this.extractSectionFromPRD(prdContent, [
|
|
3659
|
+
"Technical Architecture",
|
|
3660
|
+
"Technical Specifications",
|
|
3661
|
+
"Architecture",
|
|
3662
|
+
"Technology Stack",
|
|
3663
|
+
]);
|
|
3664
|
+
return `# Technical Specifications
|
|
3665
|
+
|
|
3666
|
+
${techSpecs || "## Architecture\n\n*Technical specifications will be extracted from PRD content*"}
|
|
3667
|
+
|
|
3668
|
+
---
|
|
3669
|
+
*Generated by MyContext CLI - AI-powered component generation platform*
|
|
3670
|
+
*Last updated: ${new Date().toISOString()}*
|
|
3671
|
+
`;
|
|
3672
|
+
}
|
|
3673
|
+
/**
|
|
3674
|
+
* Extract a section from PRD content by looking for common section headers
|
|
3675
|
+
*/
|
|
3676
|
+
extractSectionFromPRD(prdContent, sectionHeaders) {
|
|
3677
|
+
const lines = prdContent.split("\n");
|
|
3678
|
+
let inSection = false;
|
|
3679
|
+
let sectionContent = [];
|
|
3680
|
+
let currentSection = "";
|
|
3681
|
+
for (const line of lines) {
|
|
3682
|
+
const trimmedLine = line.trim();
|
|
3683
|
+
// Check if this line starts a section we're looking for
|
|
3684
|
+
if (sectionHeaders.some((header) => trimmedLine.toLowerCase().includes(header.toLowerCase()) &&
|
|
3685
|
+
(trimmedLine.startsWith("#") ||
|
|
3686
|
+
trimmedLine.startsWith("##") ||
|
|
3687
|
+
trimmedLine.startsWith("###")))) {
|
|
3688
|
+
if (inSection) {
|
|
3689
|
+
// We found a new section, stop collecting the previous one
|
|
3690
|
+
break;
|
|
3691
|
+
}
|
|
3692
|
+
inSection = true;
|
|
3693
|
+
currentSection = trimmedLine;
|
|
3694
|
+
sectionContent.push(line);
|
|
3695
|
+
continue;
|
|
3696
|
+
}
|
|
3697
|
+
if (inSection) {
|
|
3698
|
+
// Check if we hit another major section (starts with # or ##)
|
|
3699
|
+
if (trimmedLine.startsWith("#") &&
|
|
3700
|
+
!trimmedLine.includes(currentSection)) {
|
|
3701
|
+
break;
|
|
3702
|
+
}
|
|
3703
|
+
sectionContent.push(line);
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
return sectionContent.join("\n").trim();
|
|
3707
|
+
}
|
|
3159
3708
|
}
|
|
3160
3709
|
exports.GenerateCommand = GenerateCommand;
|
|
3161
3710
|
//# sourceMappingURL=generate.js.map
|