mycontext-cli 4.2.23 → 4.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/commands/analyze.d.ts.map +1 -1
  2. package/dist/commands/analyze.js +8 -24
  3. package/dist/commands/analyze.js.map +1 -1
  4. package/dist/commands/generate-components-manifest.d.ts.map +1 -1
  5. package/dist/commands/generate-components-manifest.js +7 -1
  6. package/dist/commands/generate-components-manifest.js.map +1 -1
  7. package/dist/commands/generate-design-prompt.d.ts +3 -0
  8. package/dist/commands/generate-design-prompt.d.ts.map +1 -1
  9. package/dist/commands/generate-design-prompt.js +64 -3
  10. package/dist/commands/generate-design-prompt.js.map +1 -1
  11. package/dist/commands/generate.d.ts +0 -49
  12. package/dist/commands/generate.d.ts.map +1 -1
  13. package/dist/commands/generate.js +28 -756
  14. package/dist/commands/generate.js.map +1 -1
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +80 -74
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/review-context.d.ts.map +1 -1
  19. package/dist/commands/review-context.js +3 -27
  20. package/dist/commands/review-context.js.map +1 -1
  21. package/dist/commands/setup-database.d.ts.map +1 -1
  22. package/dist/commands/setup-database.js +2 -2
  23. package/dist/commands/setup-database.js.map +1 -1
  24. package/dist/commands/setup-instantdb.d.ts.map +1 -1
  25. package/dist/commands/setup-instantdb.js +3 -3
  26. package/dist/commands/setup-instantdb.js.map +1 -1
  27. package/dist/constants/fileNames.d.ts +9 -9
  28. package/dist/constants/fileNames.js +2 -2
  29. package/dist/constants/fileNames.js.map +1 -1
  30. package/dist/doctor/rules/node-rules.d.ts.map +1 -1
  31. package/dist/doctor/rules/node-rules.js +32 -6
  32. package/dist/doctor/rules/node-rules.js.map +1 -1
  33. package/dist/utils/contextExportsImporter.d.ts +3 -0
  34. package/dist/utils/contextExportsImporter.d.ts.map +1 -0
  35. package/dist/utils/contextExportsImporter.js +203 -0
  36. package/dist/utils/contextExportsImporter.js.map +1 -0
  37. package/dist/utils/contextRenderer.d.ts.map +1 -1
  38. package/dist/utils/contextRenderer.js +48 -8
  39. package/dist/utils/contextRenderer.js.map +1 -1
  40. package/package.json +1 -1
@@ -50,6 +50,7 @@ const fs = __importStar(require("fs-extra"));
50
50
  const typeTemplateGenerator_1 = require("../utils/typeTemplateGenerator");
51
51
  const AICore_1 = require("../core/ai/AICore");
52
52
  const contextRenderer_1 = require("../utils/contextRenderer");
53
+ const contextExportsImporter_1 = require("../utils/contextExportsImporter");
53
54
  const ProjectScanner_1 = require("../services/ProjectScanner");
54
55
  class GenerateCommand {
55
56
  constructor() {
@@ -461,7 +462,8 @@ Based on this, generate a complete project context including PRD, Technical Spec
461
462
  return await this.getProjectContext();
462
463
  }
463
464
  async generateContext(projectContext, options) {
464
- // If user provided --prd-file, import it as-is and return without AI
465
+ // Canonical behavior: sync Living Brain (context.json) and export markdown views.
466
+ // If user provided --prd-file, treat it as description context for brain generation.
465
467
  try {
466
468
  const prdFile = options.prdFile ||
467
469
  options.prdfile ||
@@ -472,190 +474,12 @@ Based on this, generate a complete project context including PRD, Technical Spec
472
474
  : path_1.default.join(process.cwd(), prdFile);
473
475
  if (await fs.pathExists(abs)) {
474
476
  const content = await fs.readFile(abs, "utf8");
475
- return {
476
- success: true,
477
- content,
478
- provider: "hybrid",
479
- metadata: { imported: true },
480
- };
477
+ projectContext = { ...(projectContext || {}), description: content };
481
478
  }
482
479
  }
483
480
  }
484
481
  catch { }
485
- // Check if PRD already exists and handle accordingly
486
- const projectRoot = this.getProjectRoot();
487
- const prdPath = path_1.default.join(projectRoot, ".mycontext", "01-prd.md");
488
- const existingPRD = await this.checkExistingPRD(prdPath, options);
489
- if (existingPRD.shouldSkip) {
490
- return {
491
- success: true,
492
- content: existingPRD.content || "",
493
- provider: "hybrid",
494
- metadata: { skipped: true, reason: existingPRD.reason },
495
- };
496
- }
497
- // Get active playbook for additional context
498
- const activePlaybook = await this.getActivePlaybook();
499
- // Load existing context files for better PRD generation
500
- const contextContent = await this.loadContextForPRDGeneration();
501
- // Check if we're merging with existing PRD
502
- const isMerging = options.merge && existingPRD.content;
503
- const prompt = [
504
- `[mycontext] Plan: plan → generate → QA → docs → preview (→ checks)`,
505
- isMerging
506
- ? `Refine and enhance the existing PRD based on the following project context:`
507
- : `Create a production-grade PRD based on the following project context:`,
508
- ``,
509
- contextContent,
510
- ``,
511
- ...(isMerging
512
- ? [
513
- `## Existing PRD to Refine:`,
514
- ``,
515
- existingPRD.content,
516
- ``,
517
- `IMPORTANT: You are refining the above existing PRD. Enhance it with the context above while preserving valuable existing content. Merge new insights with existing structure.`,
518
- ]
519
- : [
520
- `IMPORTANT: Generate a PRD that is 100% accurate to the business context provided above. Extract specific requirements, features, and business logic from the context files. Do NOT generate generic fallback content.`,
521
- ]),
522
- "",
523
- // Include playbook context if available
524
- ...(activePlaybook
525
- ? [
526
- "",
527
- "## Proven Process Reference",
528
- `**Active Playbook: ${activePlaybook.title}**`,
529
- `Category: ${activePlaybook.category || "N/A"}`,
530
- `Difficulty: ${activePlaybook.metadata?.difficulty || "N/A"}`,
531
- `Estimated Time: ${activePlaybook.metadata?.estimatedTime || "N/A"}`,
532
- "",
533
- "**Process Guidelines:**",
534
- activePlaybook.content,
535
- "",
536
- "**Important:** Follow the proven patterns and best practices outlined in the playbook above. This will ensure your implementation follows industry standards and proven approaches.",
537
- "",
538
- ]
539
- : []),
540
- "Assume default stack unless user specifies otherwise:",
541
- "- Frontend: Next.js (App Router) with Shadcn UI",
542
- "- Auth/DB/File storage: InstantDB (auth, data, file persistence)",
543
- "- Accessibility: Radix UI principles (keyboard nav, ARIA, focus mgmt)",
544
- "- Testing: Jest + React Testing Library",
545
- "",
546
- "Follow this step-by-step process first, then structure the PRD (avoid generic statements):",
547
- "",
548
- "Process:",
549
- "1) Problem Statement: restate the project description from the user's perspective (who is impacted, what problem exists today, why now)",
550
- "2) Desired Outcomes & Success Metrics: what users want to eliminate/improve/create; define measurable outcomes",
551
- "3) Primary Users & Roles: identify roles and their responsibilities/permissions",
552
- "4) Current State & Pain Points: briefly describe how it works today (or assumptions) and pain points",
553
- "5) Improvement Opportunities: what to eliminate/automate/simplify; list key constraints/assumptions",
554
- "6) Solution Approach & Scope: MVP vs later; boundaries and tradeoffs",
555
- "7) User Journeys & Flows: derive end-to-end flows per role (happy path + alternatives + edge cases)",
556
- "8) Detailed User Stories: action-oriented stories with context and goals",
557
- "9) Acceptance Criteria: Given/When/Then per critical story",
558
- "10) Entity Model & Relationships: core entities and associations",
559
- "11) Information Architecture: pages/routes and the shadcn/ui primitives likely used",
560
- "12) Technical Requirements: SSR/ISR, server actions, data fetching, security, telemetry",
561
- "13) Non-Functional Requirements: performance budgets, accessibility, i18n, reliability",
562
- "14) Risks & Open Questions: what could derail the plan and what needs decisions",
563
- "",
564
- "Then, produce the PRD with the following sections (use exact headers for splitting):",
565
- "Structure the PRD with depth (avoid generic statements):",
566
- "## Requirements",
567
- "1) Overview: goal, non-goals, success metrics",
568
- "2) User Roles & Responsibilities: distinct roles with responsibilities and permissions",
569
- "3) Personas (optional): brief traits that influence UX",
570
- "4) Detailed User Stories: action-oriented; include negative flows and edge cases",
571
- "5) Entity Model & Relationships: main entities and associations",
572
- "",
573
- "## Flows",
574
- "6) User Journeys & Flows: end-to-end scenarios per role (step-by-step)",
575
- "7) Information Architecture: pages/routes, key UI patterns (shadcn components)",
576
- "8) Technical Requirements: SSR/ISR, data fetching, server actions, security, telemetry",
577
- "9) Non-Functional Requirements: performance budgets, accessibility, internationalization",
578
- "10) Acceptance Criteria: Gherkin-style Given/When/Then per critical story",
579
- "11) Risks & Open Questions",
580
- "",
581
- "Include two diagrams in fenced code blocks:",
582
- "- Sequence diagram of a critical flow (e.g., auth → gameplay → result)",
583
- "- (Optional) Flowchart for a user journey",
584
- "",
585
- "```mermaid",
586
- "sequenceDiagram",
587
- " autonumber",
588
- " participant User",
589
- " participant App as Next.js App",
590
- " participant DB as InstantDB",
591
- " User->>App: Perform primary action",
592
- " App->>DB: Persist/fetch data",
593
- " DB-->>App: Data OK",
594
- " App-->>User: Updated UI",
595
- "```",
596
- "",
597
- "Write concretely. Ground content in the provided description. No placeholders.",
598
- ].join("\n");
599
- try {
600
- // Check if user has local AI keys configured
601
- const hasLocalKeys = this.hasLocalAIKeys();
602
- if (hasLocalKeys) {
603
- // Use local AI first (user's own keys)
604
- this.spinner.updateText(`🤖 Generating PRD with ${await this.ai.getActiveProviderName()}...`);
605
- const { text, provider } = await this.ai.generateText(prompt, {
606
- model: options.model || process.env.MYCONTEXT_MODEL,
607
- modelCandidates: this.getModelCandidates(options),
608
- spinnerCallback: (text, resetTimer = false) => {
609
- this.spinner.updateText(text);
610
- if (resetTimer) {
611
- this.spinner.reset();
612
- }
613
- },
614
- });
615
- const cleaned = this.sanitizeMarkdownOutput(text);
616
- return {
617
- success: true,
618
- content: cleaned,
619
- provider: provider,
620
- metadata: {
621
- model: "local",
622
- tokens: cleaned.length / 4,
623
- latency: 1000,
624
- },
625
- };
626
- }
627
- else {
628
- // No local keys - use hosted API (requires authentication)
629
- this.spinner.updateText("🤖 Generating PRD with MyContext AI (hosted)...");
630
- const hostedResult = await this.hostedApi.generateContext("context", prompt, {
631
- model: options.model || "mycontext",
632
- context: projectContext,
633
- });
634
- if (hostedResult.success && hostedResult.data) {
635
- const cleaned = this.sanitizeMarkdownOutput(hostedResult.data);
636
- return {
637
- success: true,
638
- content: cleaned,
639
- provider: "hosted",
640
- metadata: {
641
- model: "mycontext",
642
- tokens: cleaned.length / 4,
643
- latency: 1000,
644
- },
645
- };
646
- }
647
- else {
648
- throw new Error(hostedResult.error || "Hosted API failed");
649
- }
650
- }
651
- }
652
- catch (error) {
653
- return {
654
- success: false,
655
- error: `AI generation failed: ${error instanceof Error ? error.message : "Unknown error"}`,
656
- provider: "hybrid",
657
- };
658
- }
482
+ return await this.generateFullContext(projectContext, options);
659
483
  }
660
484
  async generateTypes(projectContext, options) {
661
485
  // Check if --from-schema flag is used
@@ -839,7 +663,7 @@ Use the business entities from the context above, not generic types.`;
839
663
  }
840
664
  let contextContent = "";
841
665
  // Load PRD (01-prd.md)
842
- if (context.prd && !this.isTemplatePRD(context.prd)) {
666
+ if (context.prd) {
843
667
  contextContent += `## Project Requirements Document (PRD)\n\n${context.prd}\n\n`;
844
668
  }
845
669
  // Load features (01a-features.md)
@@ -870,7 +694,7 @@ Use the business entities from the context above, not generic types.`;
870
694
  }
871
695
  let contextContent = "";
872
696
  // Load PRD (01-prd.md)
873
- if (context.prd && !this.isTemplatePRD(context.prd)) {
697
+ if (context.prd) {
874
698
  contextContent += `## Project Requirements Document (PRD)\n\n${context.prd}\n\n`;
875
699
  }
876
700
  // Load features (01a-features.md)
@@ -900,10 +724,7 @@ Use the business entities from the context above, not generic types.`;
900
724
  }
901
725
  const existingContent = await fs.readFile(prdPath, "utf8");
902
726
  // Check if it's just a template/placeholder
903
- if (this.isTemplatePRD(existingContent)) {
904
- console.log(chalk_1.default.yellow("⚠️ Existing PRD appears to be a template, will generate new one"));
905
- return { shouldSkip: false };
906
- }
727
+ // Templates are no longer supported: PRD is an export of context.json.
907
728
  // Check for force flag
908
729
  if (options.force) {
909
730
  console.log(chalk_1.default.yellow("🔄 Force flag detected, will overwrite existing PRD"));
@@ -932,7 +753,7 @@ Use the business entities from the context above, not generic types.`;
932
753
  }
933
754
  let contextContent = "";
934
755
  // Load existing PRD if it exists (for refinement)
935
- if (context.prd && !this.isTemplatePRD(context.prd)) {
756
+ if (context.prd) {
936
757
  contextContent += `## Existing Project Requirements Document (PRD)\n\n${context.prd}\n\n`;
937
758
  }
938
759
  // Load features (01a-features.md)
@@ -2268,12 +2089,12 @@ Make the CSS immediately usable - no placeholders, actual working values!`;
2268
2089
  console.log(chalk_1.default.gray(" • Component list"));
2269
2090
  console.log(chalk_1.default.gray(" • Project structure"));
2270
2091
  console.log(chalk_1.default.blue("\n➡️ Recommended Next Steps:"));
2271
- console.log(chalk_1.default.cyan(" 1. Generate components:"));
2272
- console.log(chalk_1.default.white(" mycontext generate-components all --with-tests"));
2273
- console.log(chalk_1.default.cyan(" 2. Preview at hosted Studio:"));
2274
- console.log(chalk_1.default.white(" https://studio.mycontext.app"));
2275
- console.log(chalk_1.default.cyan(" 3. Build complete app:"));
2276
- console.log(chalk_1.default.white(" mycontext build-app --interactive"));
2092
+ console.log(chalk_1.default.cyan(" 1. Generate Design Prompt (Command Chain):"));
2093
+ console.log(chalk_1.default.white(" mycontext gdp\n"));
2094
+ console.log(chalk_1.default.cyan(" 2. Generate Components (from Spec):"));
2095
+ console.log(chalk_1.default.white(" mycontext generate-components all --with-tests\n"));
2096
+ console.log(chalk_1.default.cyan(" 3. Preview at hosted Studio:"));
2097
+ console.log(chalk_1.default.white(" https://studio.mycontext.app\n"));
2277
2098
  // Show additional next steps from NextStepsSuggester
2278
2099
  const { NextStepsSuggester } = await Promise.resolve().then(() => __importStar(require("../utils/nextStepsSuggester")));
2279
2100
  const workflowContext = await NextStepsSuggester.getWorkflowContext();
@@ -2335,15 +2156,14 @@ Make the CSS immediately usable - no placeholders, actual working values!`;
2335
2156
  async showNextSteps(type, options) {
2336
2157
  const suggestions = this.getContextualSuggestions(type);
2337
2158
  if (suggestions.length > 0) {
2338
- console.log("\n💡 Next Steps:");
2159
+ console.log(chalk_1.default.blue("\n🎯 Next Steps:"));
2339
2160
  suggestions.forEach((step, index) => {
2340
- console.log(` ${index + 1}. ${step.description}`);
2341
- console.log(` ${step.command}`);
2161
+ console.log(chalk_1.default.yellow(` ${index + 1}. ${step.description}:`));
2162
+ console.log(chalk_1.default.cyan(` ${step.command}\n`));
2342
2163
  if (step.optional) {
2343
2164
  console.log(` ${chalk_1.default.gray("(optional)")}`);
2344
2165
  }
2345
2166
  });
2346
- console.log(""); // Empty line for spacing
2347
2167
  }
2348
2168
  }
2349
2169
  getContextualSuggestions(type) {
@@ -4024,6 +3844,16 @@ ${isEcommerce
4024
3844
  catch (e) {
4025
3845
  // ignore
4026
3846
  }
3847
+ // Optional: import manual edits from exported markdown back into the brain
3848
+ // (best-effort, only when explicitly requested)
3849
+ if (existingContext && options.importExports) {
3850
+ try {
3851
+ existingContext = await (0, contextExportsImporter_1.importContextExports)(path_1.default.join(projectRoot, ".mycontext"), existingContext);
3852
+ }
3853
+ catch {
3854
+ // ignore import failures
3855
+ }
3856
+ }
4027
3857
  let prompt = "";
4028
3858
  if (existingContext && existingContext.prd && Object.keys(existingContext.prd).length > 0) {
4029
3859
  prompt = `
@@ -4204,564 +4034,6 @@ INSTRUCTIONS:
4204
4034
  // Default to current working directory
4205
4035
  return cwd;
4206
4036
  }
4207
- /**
4208
- * Generate A/B/C/D context files (Features, User Flows, Edge Cases, Technical Specs)
4209
- */
4210
- async generateContextFiles(projectContext, options) {
4211
- // Ensure we're using the project root, not a nested .mycontext directory
4212
- const projectRoot = this.getProjectRoot();
4213
- const contextDir = path_1.default.join(projectRoot, ".mycontext");
4214
- // Ensure .mycontext directory exists
4215
- await fs.ensureDir(contextDir);
4216
- // Check if context files already exist
4217
- const existingFiles = await this.checkExistingContextFiles(contextDir);
4218
- if (existingFiles.length > 0 && !options.force) {
4219
- return {
4220
- success: false,
4221
- error: `Context files already exist: ${existingFiles.join(", ")}. Use --force to overwrite.`,
4222
- provider: "system",
4223
- metadata: { model: "system", tokens: 0, latency: 0 },
4224
- };
4225
- }
4226
- // Get context from PRD if it exists, otherwise use description
4227
- const contextContent = await this.getContextForGeneration(contextDir, projectContext.description);
4228
- try {
4229
- // Generate each context file using the PRD content as context
4230
- console.log("[GenerateCommand] Generating features file...");
4231
- await this.generateFeaturesFile(contextDir, contextContent);
4232
- console.log("[GenerateCommand] Generating user flows file...");
4233
- await this.generateUserFlowsFile(contextDir, contextContent);
4234
- console.log("[GenerateCommand] Generating edge cases file...");
4235
- await this.generateEdgeCasesFile(contextDir, contextContent);
4236
- console.log("[GenerateCommand] Generating technical specs file...");
4237
- await this.generateTechnicalSpecsFile(contextDir, contextContent);
4238
- return {
4239
- success: true,
4240
- content: "Context files generated successfully",
4241
- provider: "hybrid",
4242
- metadata: { model: "hybrid", tokens: 0, latency: 0 },
4243
- };
4244
- }
4245
- catch (error) {
4246
- return {
4247
- success: false,
4248
- error: `Context file generation failed: ${error instanceof Error ? error.message : String(error)}`,
4249
- provider: "system",
4250
- metadata: { model: "system", tokens: 0, latency: 0 },
4251
- };
4252
- }
4253
- }
4254
- async checkExistingContextFiles(contextDir) {
4255
- const files = [
4256
- "01a-features.md",
4257
- "01b-user-flows.md",
4258
- "01c-edge-cases.md",
4259
- "01d-technical-specs.md",
4260
- ];
4261
- const existingFiles = [];
4262
- for (const file of files) {
4263
- if (await fs.pathExists(path_1.default.join(contextDir, file))) {
4264
- existingFiles.push(file);
4265
- }
4266
- }
4267
- return existingFiles;
4268
- }
4269
- async generateFeaturesFile(contextDir, contextContent) {
4270
- const prompt = this.buildFeaturesPrompt(contextContent);
4271
- try {
4272
- // Add timeout to prevent infinite loops
4273
- const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("AI generation timeout")), 30000) // 30 second timeout
4274
- );
4275
- const responsePromise = this.ai.generateText(prompt, {
4276
- temperature: 0.7,
4277
- maxTokens: 2000,
4278
- });
4279
- const response = (await Promise.race([
4280
- responsePromise,
4281
- timeoutPromise,
4282
- ]));
4283
- // Check if response is valid
4284
- if (!response || !response.text || response.text.trim().length < 50) {
4285
- throw new Error("AI response too short or invalid");
4286
- }
4287
- const content = this.formatFeaturesContent(response.text);
4288
- await fs.writeFile(path_1.default.join(contextDir, "01a-features.md"), content);
4289
- }
4290
- catch (error) {
4291
- console.log(chalk_1.default.red("❌ AI generation failed for features"));
4292
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4293
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4294
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4295
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4296
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4297
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4298
- throw new Error("AI generation failed - retry when conditions improve");
4299
- }
4300
- }
4301
- async generateUserFlowsFile(contextDir, contextContent) {
4302
- const prompt = this.buildUserFlowsPrompt(contextContent);
4303
- try {
4304
- const response = await this.ai.generateText(prompt, {
4305
- temperature: 0.7,
4306
- maxTokens: 2000,
4307
- });
4308
- const content = this.formatUserFlowsContent(response.text);
4309
- await fs.writeFile(path_1.default.join(contextDir, "01b-user-flows.md"), content);
4310
- }
4311
- catch (error) {
4312
- console.log(chalk_1.default.red("❌ AI generation failed for user flows"));
4313
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4314
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4315
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4316
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4317
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4318
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4319
- throw new Error("AI generation failed - retry when conditions improve");
4320
- }
4321
- }
4322
- async generateEdgeCasesFile(contextDir, contextContent) {
4323
- const prompt = this.buildEdgeCasesPrompt(contextContent);
4324
- try {
4325
- const response = await this.ai.generateText(prompt, {
4326
- temperature: 0.7,
4327
- maxTokens: 2000,
4328
- });
4329
- const content = this.formatEdgeCasesContent(response.text);
4330
- await fs.writeFile(path_1.default.join(contextDir, "01c-edge-cases.md"), content);
4331
- }
4332
- catch (error) {
4333
- console.log(chalk_1.default.red("❌ AI generation failed for edge cases"));
4334
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4335
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4336
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4337
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4338
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4339
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4340
- throw new Error("AI generation failed - retry when conditions improve");
4341
- }
4342
- }
4343
- async generateTechnicalSpecsFile(contextDir, contextContent) {
4344
- const prompt = this.buildTechnicalSpecsPrompt(contextContent);
4345
- try {
4346
- const response = await this.ai.generateText(prompt, {
4347
- temperature: 0.7,
4348
- maxTokens: 2000,
4349
- });
4350
- const content = this.formatTechnicalSpecsContent(response.text);
4351
- await fs.writeFile(path_1.default.join(contextDir, "01d-technical-specs.md"), content);
4352
- }
4353
- catch (error) {
4354
- console.log(chalk_1.default.red("❌ AI generation failed for technical specs"));
4355
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4356
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4357
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4358
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4359
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4360
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4361
- throw new Error("AI generation failed - retry when conditions improve");
4362
- }
4363
- }
4364
- buildFeaturesPrompt(contextContent) {
4365
- return `You are a product manager creating a comprehensive features document for a web application.
4366
-
4367
- ${contextContent
4368
- ? `Project Context (from PRD): ${contextContent}`
4369
- : "Generate features for a modern web application."}
4370
-
4371
- Create a detailed features document that includes:
4372
-
4373
- 1. **Core Features** - Primary functionality that defines the product
4374
- 2. **User Features** - Features that directly benefit end users
4375
- 3. **Admin Features** - Administrative and management capabilities
4376
- 4. **Technical Features** - Backend, API, and infrastructure features
4377
- 5. **Integration Features** - Third-party integrations and APIs
4378
- 6. **Security Features** - Authentication, authorization, and data protection
4379
- 7. **Performance Features** - Optimization and scalability features
4380
- 8. **Accessibility Features** - WCAG compliance and inclusive design
4381
-
4382
- For each feature, include:
4383
- - Feature name and description
4384
- - User value proposition
4385
- - Acceptance criteria
4386
- - Priority level (High/Medium/Low)
4387
- - Dependencies on other features
4388
-
4389
- Format the output as a well-structured markdown document with clear sections and bullet points.`;
4390
- }
4391
- buildUserFlowsPrompt(contextContent) {
4392
- return `You are a UX designer creating comprehensive user flow documentation for a web application.
4393
-
4394
- ${contextContent
4395
- ? `Project Context (from PRD): ${contextContent}`
4396
- : "Generate user flows for a modern web application."}
4397
-
4398
- Create detailed user flow documentation that includes:
4399
-
4400
- 1. **Primary User Journeys** - Main user paths through the application
4401
- 2. **Authentication Flows** - Login, signup, password reset, etc.
4402
- 3. **Core Feature Flows** - How users interact with main features
4403
- 4. **Error Handling Flows** - What happens when things go wrong
4404
- 5. **Admin/Management Flows** - Administrative user journeys
4405
- 6. **Mobile vs Desktop Flows** - Responsive design considerations
4406
- 7. **Accessibility Flows** - Screen reader and keyboard navigation paths
4407
-
4408
- For each flow, include:
4409
- - Flow name and description
4410
- - Step-by-step user actions
4411
- - System responses and feedback
4412
- - Decision points and branches
4413
- - Error states and recovery
4414
- - Success criteria
4415
-
4416
- Format the output as a well-structured markdown document with clear sections, numbered steps, and flow diagrams in text format.`;
4417
- }
4418
- buildEdgeCasesPrompt(contextContent) {
4419
- return `You are a QA engineer creating comprehensive edge cases and error scenarios documentation for a web application.
4420
-
4421
- ${contextContent
4422
- ? `Project Context (from PRD): ${contextContent}`
4423
- : "Generate edge cases for a modern web application."}
4424
-
4425
- Create detailed edge cases documentation that includes:
4426
-
4427
- 1. **Input Validation Edge Cases** - Invalid, malformed, or extreme input scenarios
4428
- 2. **Network Edge Cases** - Offline, slow connections, timeouts, API failures
4429
- 3. **Browser Edge Cases** - Different browsers, versions, disabled features
4430
- 4. **Device Edge Cases** - Mobile, tablet, desktop, different screen sizes
4431
- 5. **Data Edge Cases** - Empty data, large datasets, concurrent modifications
4432
- 6. **Security Edge Cases** - Injection attacks, XSS, CSRF, unauthorized access
4433
- 7. **Performance Edge Cases** - High load, memory constraints, slow operations
4434
- 8. **Accessibility Edge Cases** - Screen readers, keyboard-only navigation, high contrast
4435
- 9. **Integration Edge Cases** - Third-party service failures, API changes
4436
- 10. **Business Logic Edge Cases** - Boundary conditions, race conditions
4437
-
4438
- For each edge case, include:
4439
- - Scenario description
4440
- - Expected behavior
4441
- - Potential impact
4442
- - Mitigation strategies
4443
- - Testing approach
4444
-
4445
- Format the output as a well-structured markdown document with clear sections and detailed scenarios.`;
4446
- }
4447
- buildTechnicalSpecsPrompt(contextContent) {
4448
- return `You are a technical architect creating comprehensive technical specifications for a web application.
4449
-
4450
- ${contextContent
4451
- ? `Project Context (from PRD): ${contextContent}`
4452
- : "Generate technical specs for a modern web application."}
4453
-
4454
- Create detailed technical specifications that include:
4455
-
4456
- 1. **Architecture Overview** - System design, components, and relationships
4457
- 2. **Technology Stack** - Frontend, backend, database, deployment technologies
4458
- 3. **API Specifications** - Endpoints, request/response formats, authentication
4459
- 4. **Database Design** - Schema, relationships, indexing, data flow
4460
- 5. **Security Requirements** - Authentication, authorization, data protection
4461
- 6. **Performance Requirements** - Response times, throughput, scalability
4462
- 7. **Deployment Architecture** - Infrastructure, CI/CD, monitoring
4463
- 8. **Integration Requirements** - Third-party services, APIs, webhooks
4464
- 9. **Development Standards** - Code style, testing, documentation
4465
- 10. **Monitoring and Logging** - Error tracking, analytics, performance monitoring
4466
-
4467
- For each specification, include:
4468
- - Requirement description
4469
- - Technical approach
4470
- - Implementation details
4471
- - Dependencies
4472
- - Success criteria
4473
-
4474
- Format the output as a well-structured markdown document with clear sections and technical details.`;
4475
- }
4476
- formatFeaturesContent(response) {
4477
- return `# Product Features
4478
-
4479
- ${response}
4480
-
4481
- ---
4482
- *Generated by MyContext CLI - AI-powered component generation platform*
4483
- *Last updated: ${new Date().toISOString()}*
4484
- `;
4485
- }
4486
- formatUserFlowsContent(response) {
4487
- return `# User Flows
4488
-
4489
- ${response}
4490
-
4491
- ---
4492
- *Generated by MyContext CLI - AI-powered component generation platform*
4493
- *Last updated: ${new Date().toISOString()}*
4494
- `;
4495
- }
4496
- formatEdgeCasesContent(response) {
4497
- return `# Edge Cases and Error Scenarios
4498
-
4499
- ${response}
4500
-
4501
- ---
4502
- *Generated by MyContext CLI - AI-powered component generation platform*
4503
- *Last updated: ${new Date().toISOString()}*
4504
- `;
4505
- }
4506
- formatTechnicalSpecsContent(response) {
4507
- return `# Technical Specifications
4508
-
4509
- ${response}
4510
-
4511
- ---
4512
- *Generated by MyContext CLI - AI-powered component generation platform*
4513
- *Last updated: ${new Date().toISOString()}*
4514
- `;
4515
- }
4516
- /**
4517
- * Get context content for generation - prefer PRD over description
4518
- */
4519
- async getContextForGeneration(contextDir, fallbackDescription) {
4520
- // First, try to read from 01-prd.md
4521
- const prdPath = path_1.default.join(contextDir, "01-prd.md");
4522
- if (await fs.pathExists(prdPath)) {
4523
- try {
4524
- const prdContent = await fs.readFile(prdPath, "utf8");
4525
- // Check if PRD is just a template/starter sample
4526
- if (this.isTemplatePRD(prdContent)) {
4527
- console.log(chalk_1.default.yellow("⚠️ PRD appears to be a template, not using as context"));
4528
- }
4529
- else {
4530
- console.log(chalk_1.default.blue("📖 Using existing PRD as context for context files generation"));
4531
- return prdContent;
4532
- }
4533
- }
4534
- catch (error) {
4535
- console.log(chalk_1.default.yellow("⚠️ Could not read PRD file, falling back to description"));
4536
- }
4537
- }
4538
- // Fallback to description if no PRD exists
4539
- if (fallbackDescription) {
4540
- console.log(chalk_1.default.blue("📝 Using project description as context"));
4541
- return fallbackDescription;
4542
- }
4543
- // No context available - ask user
4544
- console.log(chalk_1.default.red("❌ No PRD or description found!"));
4545
- console.log(chalk_1.default.yellow("Please provide context by either:"));
4546
- console.log(chalk_1.default.gray(" 1. Run 'mycontext generate context' first to create a PRD"));
4547
- console.log(chalk_1.default.gray(" 2. Use --description flag: mycontext generate-context-files --description 'Your project'"));
4548
- console.log(chalk_1.default.gray(" 3. Create a PRD file manually at .mycontext/01-prd.md"));
4549
- throw new Error("No context available for generation. Please provide a PRD or description.");
4550
- }
4551
- /**
4552
- * Check if PRD content is just a template/starter sample
4553
- */
4554
- isTemplatePRD(content) {
4555
- const templateIndicators = [
4556
- "MyContext project",
4557
- "Replace this with your actual project description",
4558
- "TODO: Add your project details",
4559
- "This is a template",
4560
- "Sample project",
4561
- "Example project",
4562
- "Your project description here",
4563
- "Project Name: [Your Project Name]",
4564
- "Description: [Your project description]",
4565
- "## Project Overview\n\n[Add your project overview here]",
4566
- "## Requirements\n\n[Add your requirements here]",
4567
- "## Features\n\n[Add your features here]",
4568
- "## Technical Specifications\n\n[Add your technical specs here]",
4569
- ];
4570
- // Check if content contains multiple template indicators
4571
- const templateMatches = templateIndicators.filter((indicator) => content.toLowerCase().includes(indicator.toLowerCase()));
4572
- // If more than 2 template indicators are found, it's likely a template
4573
- if (templateMatches.length >= 2) {
4574
- return true;
4575
- }
4576
- // Check if content is very short (likely a template)
4577
- // BUT NOT if it's just a success message from context generation
4578
- if (content.includes("Full context generated successfully") ||
4579
- content.includes("context generated successfully")) {
4580
- return false; // This is not a template, it's a success message
4581
- }
4582
- if (content.trim().length < 200) {
4583
- return true;
4584
- }
4585
- // Check if content is mostly placeholder text
4586
- const placeholderRatio = (content.match(/\[.*?\]/g) || []).length /
4587
- (content.split(" ").length || 1);
4588
- if (placeholderRatio > 0.1) {
4589
- // More than 10% placeholders
4590
- return true;
4591
- }
4592
- return false;
4593
- }
4594
- /**
4595
- * REMOVED: Dangerous fallback method that compromises accuracy
4596
- * MyContext requires 100% accuracy - no fallbacks allowed
4597
- */
4598
- extractFeaturesFromPRD_DISABLED(prdContent) {
4599
- if (!prdContent) {
4600
- return `# Product Features
4601
-
4602
- ## Core Features
4603
-
4604
- *No features available - PRD content not found*
4605
-
4606
- ---
4607
- *Generated by MyContext CLI - AI-powered component generation platform*
4608
- *Last updated: ${new Date().toISOString()}*
4609
- `;
4610
- }
4611
- // Extract features from PRD content
4612
- const features = this.extractSectionFromPRD(prdContent, [
4613
- "Core Features",
4614
- "Features",
4615
- "Key Features",
4616
- "Main Features",
4617
- ]);
4618
- return `# Product Features
4619
-
4620
- ${features ||
4621
- "## Core Features\n\n*Features will be extracted from PRD content*"}
4622
-
4623
- ---
4624
- *Generated by MyContext CLI - AI-powered component generation platform*
4625
- *Last updated: ${new Date().toISOString()}*
4626
- `;
4627
- }
4628
- /**
4629
- * REMOVED: Dangerous fallback method that compromises accuracy
4630
- * MyContext requires 100% accuracy - no fallbacks allowed
4631
- */
4632
- extractUserFlowsFromPRD_DISABLED(prdContent) {
4633
- if (!prdContent) {
4634
- return `# User Flows
4635
-
4636
- ## User Journey
4637
-
4638
- *No user flows available - PRD content not found*
4639
-
4640
- ---
4641
- *Generated by MyContext CLI - AI-powered component generation platform*
4642
- *Last updated: ${new Date().toISOString()}*
4643
- `;
4644
- }
4645
- // Extract user flows from PRD content
4646
- const userFlows = this.extractSectionFromPRD(prdContent, [
4647
- "User Roles",
4648
- "User Journey",
4649
- "User Flows",
4650
- "Workflow",
4651
- ]);
4652
- return `# User Flows
4653
-
4654
- ${userFlows ||
4655
- "## User Journey\n\n*User flows will be extracted from PRD content*"}
4656
-
4657
- ---
4658
- *Generated by MyContext CLI - AI-powered component generation platform*
4659
- *Last updated: ${new Date().toISOString()}*
4660
- `;
4661
- }
4662
- /**
4663
- * REMOVED: Dangerous fallback method that compromises accuracy
4664
- * MyContext requires 100% accuracy - no fallbacks allowed
4665
- */
4666
- extractEdgeCasesFromPRD_DISABLED(prdContent) {
4667
- if (!prdContent) {
4668
- return `# Edge Cases and Error Scenarios
4669
-
4670
- ## Error Handling
4671
-
4672
- *No edge cases available - PRD content not found*
4673
-
4674
- ---
4675
- *Generated by MyContext CLI - AI-powered component generation platform*
4676
- *Last updated: ${new Date().toISOString()}*
4677
- `;
4678
- }
4679
- // Extract edge cases from PRD content
4680
- const edgeCases = this.extractSectionFromPRD(prdContent, [
4681
- "Risk Mitigation",
4682
- "Edge Cases",
4683
- "Error Scenarios",
4684
- "Troubleshooting",
4685
- ]);
4686
- return `# Edge Cases and Error Scenarios
4687
-
4688
- ${edgeCases ||
4689
- "## Error Handling\n\n*Edge cases will be extracted from PRD content*"}
4690
-
4691
- ---
4692
- *Generated by MyContext CLI - AI-powered component generation platform*
4693
- *Last updated: ${new Date().toISOString()}*
4694
- `;
4695
- }
4696
- /**
4697
- * REMOVED: Dangerous fallback method that compromises accuracy
4698
- * MyContext requires 100% accuracy - no fallbacks allowed
4699
- */
4700
- extractTechnicalSpecsFromPRD_DISABLED(prdContent) {
4701
- if (!prdContent) {
4702
- return `# Technical Specifications
4703
-
4704
- ## Architecture
4705
-
4706
- *No technical specs available - PRD content not found*
4707
-
4708
- ---
4709
- *Generated by MyContext CLI - AI-powered component generation platform*
4710
- *Last updated: ${new Date().toISOString()}*
4711
- `;
4712
- }
4713
- // Extract technical specs from PRD content
4714
- const techSpecs = this.extractSectionFromPRD(prdContent, [
4715
- "Technical Architecture",
4716
- "Technical Specifications",
4717
- "Architecture",
4718
- "Technology Stack",
4719
- ]);
4720
- return `# Technical Specifications
4721
-
4722
- ${techSpecs ||
4723
- "## Architecture\n\n*Technical specifications will be extracted from PRD content*"}
4724
-
4725
- ---
4726
- *Generated by MyContext CLI - AI-powered component generation platform*
4727
- *Last updated: ${new Date().toISOString()}*
4728
- `;
4729
- }
4730
- /**
4731
- * Extract a section from PRD content by looking for common section headers
4732
- */
4733
- extractSectionFromPRD(prdContent, sectionHeaders) {
4734
- const lines = prdContent.split("\n");
4735
- let inSection = false;
4736
- let sectionContent = [];
4737
- let currentSection = "";
4738
- for (const line of lines) {
4739
- const trimmedLine = line.trim();
4740
- // Check if this line starts a section we're looking for
4741
- if (sectionHeaders.some((header) => trimmedLine.toLowerCase().includes(header.toLowerCase()) &&
4742
- (trimmedLine.startsWith("#") ||
4743
- trimmedLine.startsWith("##") ||
4744
- trimmedLine.startsWith("###")))) {
4745
- if (inSection) {
4746
- // We found a new section, stop collecting the previous one
4747
- break;
4748
- }
4749
- inSection = true;
4750
- currentSection = trimmedLine;
4751
- sectionContent.push(line);
4752
- continue;
4753
- }
4754
- if (inSection) {
4755
- // Check if we hit another major section (starts with # or ##)
4756
- if (trimmedLine.startsWith("#") &&
4757
- !trimmedLine.includes(currentSection)) {
4758
- break;
4759
- }
4760
- sectionContent.push(line);
4761
- }
4762
- }
4763
- return sectionContent.join("\n").trim();
4764
- }
4765
4037
  }
4766
4038
  exports.GenerateCommand = GenerateCommand;
4767
4039
  //# sourceMappingURL=generate.js.map