mycontext-cli 4.2.25 → 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.
@@ -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)
@@ -4023,6 +3844,16 @@ ${isEcommerce
4023
3844
  catch (e) {
4024
3845
  // ignore
4025
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
+ }
4026
3857
  let prompt = "";
4027
3858
  if (existingContext && existingContext.prd && Object.keys(existingContext.prd).length > 0) {
4028
3859
  prompt = `
@@ -4203,564 +4034,6 @@ INSTRUCTIONS:
4203
4034
  // Default to current working directory
4204
4035
  return cwd;
4205
4036
  }
4206
- /**
4207
- * Generate A/B/C/D context files (Features, User Flows, Edge Cases, Technical Specs)
4208
- */
4209
- async generateContextFiles(projectContext, options) {
4210
- // Ensure we're using the project root, not a nested .mycontext directory
4211
- const projectRoot = this.getProjectRoot();
4212
- const contextDir = path_1.default.join(projectRoot, ".mycontext");
4213
- // Ensure .mycontext directory exists
4214
- await fs.ensureDir(contextDir);
4215
- // Check if context files already exist
4216
- const existingFiles = await this.checkExistingContextFiles(contextDir);
4217
- if (existingFiles.length > 0 && !options.force) {
4218
- return {
4219
- success: false,
4220
- error: `Context files already exist: ${existingFiles.join(", ")}. Use --force to overwrite.`,
4221
- provider: "system",
4222
- metadata: { model: "system", tokens: 0, latency: 0 },
4223
- };
4224
- }
4225
- // Get context from PRD if it exists, otherwise use description
4226
- const contextContent = await this.getContextForGeneration(contextDir, projectContext.description);
4227
- try {
4228
- // Generate each context file using the PRD content as context
4229
- console.log("[GenerateCommand] Generating features file...");
4230
- await this.generateFeaturesFile(contextDir, contextContent);
4231
- console.log("[GenerateCommand] Generating user flows file...");
4232
- await this.generateUserFlowsFile(contextDir, contextContent);
4233
- console.log("[GenerateCommand] Generating edge cases file...");
4234
- await this.generateEdgeCasesFile(contextDir, contextContent);
4235
- console.log("[GenerateCommand] Generating technical specs file...");
4236
- await this.generateTechnicalSpecsFile(contextDir, contextContent);
4237
- return {
4238
- success: true,
4239
- content: "Context files generated successfully",
4240
- provider: "hybrid",
4241
- metadata: { model: "hybrid", tokens: 0, latency: 0 },
4242
- };
4243
- }
4244
- catch (error) {
4245
- return {
4246
- success: false,
4247
- error: `Context file generation failed: ${error instanceof Error ? error.message : String(error)}`,
4248
- provider: "system",
4249
- metadata: { model: "system", tokens: 0, latency: 0 },
4250
- };
4251
- }
4252
- }
4253
- async checkExistingContextFiles(contextDir) {
4254
- const files = [
4255
- "01a-features.md",
4256
- "01b-user-flows.md",
4257
- "01c-edge-cases.md",
4258
- "01d-technical-specs.md",
4259
- ];
4260
- const existingFiles = [];
4261
- for (const file of files) {
4262
- if (await fs.pathExists(path_1.default.join(contextDir, file))) {
4263
- existingFiles.push(file);
4264
- }
4265
- }
4266
- return existingFiles;
4267
- }
4268
- async generateFeaturesFile(contextDir, contextContent) {
4269
- const prompt = this.buildFeaturesPrompt(contextContent);
4270
- try {
4271
- // Add timeout to prevent infinite loops
4272
- const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("AI generation timeout")), 30000) // 30 second timeout
4273
- );
4274
- const responsePromise = this.ai.generateText(prompt, {
4275
- temperature: 0.7,
4276
- maxTokens: 2000,
4277
- });
4278
- const response = (await Promise.race([
4279
- responsePromise,
4280
- timeoutPromise,
4281
- ]));
4282
- // Check if response is valid
4283
- if (!response || !response.text || response.text.trim().length < 50) {
4284
- throw new Error("AI response too short or invalid");
4285
- }
4286
- const content = this.formatFeaturesContent(response.text);
4287
- await fs.writeFile(path_1.default.join(contextDir, "01a-features.md"), content);
4288
- }
4289
- catch (error) {
4290
- console.log(chalk_1.default.red("❌ AI generation failed for features"));
4291
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4292
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4293
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4294
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4295
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4296
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4297
- throw new Error("AI generation failed - retry when conditions improve");
4298
- }
4299
- }
4300
- async generateUserFlowsFile(contextDir, contextContent) {
4301
- const prompt = this.buildUserFlowsPrompt(contextContent);
4302
- try {
4303
- const response = await this.ai.generateText(prompt, {
4304
- temperature: 0.7,
4305
- maxTokens: 2000,
4306
- });
4307
- const content = this.formatUserFlowsContent(response.text);
4308
- await fs.writeFile(path_1.default.join(contextDir, "01b-user-flows.md"), content);
4309
- }
4310
- catch (error) {
4311
- console.log(chalk_1.default.red("❌ AI generation failed for user flows"));
4312
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4313
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4314
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4315
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4316
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4317
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4318
- throw new Error("AI generation failed - retry when conditions improve");
4319
- }
4320
- }
4321
- async generateEdgeCasesFile(contextDir, contextContent) {
4322
- const prompt = this.buildEdgeCasesPrompt(contextContent);
4323
- try {
4324
- const response = await this.ai.generateText(prompt, {
4325
- temperature: 0.7,
4326
- maxTokens: 2000,
4327
- });
4328
- const content = this.formatEdgeCasesContent(response.text);
4329
- await fs.writeFile(path_1.default.join(contextDir, "01c-edge-cases.md"), content);
4330
- }
4331
- catch (error) {
4332
- console.log(chalk_1.default.red("❌ AI generation failed for edge cases"));
4333
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4334
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4335
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4336
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4337
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4338
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4339
- throw new Error("AI generation failed - retry when conditions improve");
4340
- }
4341
- }
4342
- async generateTechnicalSpecsFile(contextDir, contextContent) {
4343
- const prompt = this.buildTechnicalSpecsPrompt(contextContent);
4344
- try {
4345
- const response = await this.ai.generateText(prompt, {
4346
- temperature: 0.7,
4347
- maxTokens: 2000,
4348
- });
4349
- const content = this.formatTechnicalSpecsContent(response.text);
4350
- await fs.writeFile(path_1.default.join(contextDir, "01d-technical-specs.md"), content);
4351
- }
4352
- catch (error) {
4353
- console.log(chalk_1.default.red("❌ AI generation failed for technical specs"));
4354
- console.log(chalk_1.default.yellow("💡 MyContext requires 100% accuracy - no fallbacks"));
4355
- console.log(chalk_1.default.blue("🔄 Retry options:"));
4356
- console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
4357
- console.log(chalk_1.default.gray(" 2. Use a different AI provider"));
4358
- console.log(chalk_1.default.gray(" 3. Check your API key configuration"));
4359
- console.log(chalk_1.default.gray(" 4. Try again later with: mycontext generate context --full"));
4360
- throw new Error("AI generation failed - retry when conditions improve");
4361
- }
4362
- }
4363
- buildFeaturesPrompt(contextContent) {
4364
- return `You are a product manager creating a comprehensive features document for a web application.
4365
-
4366
- ${contextContent
4367
- ? `Project Context (from PRD): ${contextContent}`
4368
- : "Generate features for a modern web application."}
4369
-
4370
- Create a detailed features document that includes:
4371
-
4372
- 1. **Core Features** - Primary functionality that defines the product
4373
- 2. **User Features** - Features that directly benefit end users
4374
- 3. **Admin Features** - Administrative and management capabilities
4375
- 4. **Technical Features** - Backend, API, and infrastructure features
4376
- 5. **Integration Features** - Third-party integrations and APIs
4377
- 6. **Security Features** - Authentication, authorization, and data protection
4378
- 7. **Performance Features** - Optimization and scalability features
4379
- 8. **Accessibility Features** - WCAG compliance and inclusive design
4380
-
4381
- For each feature, include:
4382
- - Feature name and description
4383
- - User value proposition
4384
- - Acceptance criteria
4385
- - Priority level (High/Medium/Low)
4386
- - Dependencies on other features
4387
-
4388
- Format the output as a well-structured markdown document with clear sections and bullet points.`;
4389
- }
4390
- buildUserFlowsPrompt(contextContent) {
4391
- return `You are a UX designer creating comprehensive user flow documentation for a web application.
4392
-
4393
- ${contextContent
4394
- ? `Project Context (from PRD): ${contextContent}`
4395
- : "Generate user flows for a modern web application."}
4396
-
4397
- Create detailed user flow documentation that includes:
4398
-
4399
- 1. **Primary User Journeys** - Main user paths through the application
4400
- 2. **Authentication Flows** - Login, signup, password reset, etc.
4401
- 3. **Core Feature Flows** - How users interact with main features
4402
- 4. **Error Handling Flows** - What happens when things go wrong
4403
- 5. **Admin/Management Flows** - Administrative user journeys
4404
- 6. **Mobile vs Desktop Flows** - Responsive design considerations
4405
- 7. **Accessibility Flows** - Screen reader and keyboard navigation paths
4406
-
4407
- For each flow, include:
4408
- - Flow name and description
4409
- - Step-by-step user actions
4410
- - System responses and feedback
4411
- - Decision points and branches
4412
- - Error states and recovery
4413
- - Success criteria
4414
-
4415
- Format the output as a well-structured markdown document with clear sections, numbered steps, and flow diagrams in text format.`;
4416
- }
4417
- buildEdgeCasesPrompt(contextContent) {
4418
- return `You are a QA engineer creating comprehensive edge cases and error scenarios documentation for a web application.
4419
-
4420
- ${contextContent
4421
- ? `Project Context (from PRD): ${contextContent}`
4422
- : "Generate edge cases for a modern web application."}
4423
-
4424
- Create detailed edge cases documentation that includes:
4425
-
4426
- 1. **Input Validation Edge Cases** - Invalid, malformed, or extreme input scenarios
4427
- 2. **Network Edge Cases** - Offline, slow connections, timeouts, API failures
4428
- 3. **Browser Edge Cases** - Different browsers, versions, disabled features
4429
- 4. **Device Edge Cases** - Mobile, tablet, desktop, different screen sizes
4430
- 5. **Data Edge Cases** - Empty data, large datasets, concurrent modifications
4431
- 6. **Security Edge Cases** - Injection attacks, XSS, CSRF, unauthorized access
4432
- 7. **Performance Edge Cases** - High load, memory constraints, slow operations
4433
- 8. **Accessibility Edge Cases** - Screen readers, keyboard-only navigation, high contrast
4434
- 9. **Integration Edge Cases** - Third-party service failures, API changes
4435
- 10. **Business Logic Edge Cases** - Boundary conditions, race conditions
4436
-
4437
- For each edge case, include:
4438
- - Scenario description
4439
- - Expected behavior
4440
- - Potential impact
4441
- - Mitigation strategies
4442
- - Testing approach
4443
-
4444
- Format the output as a well-structured markdown document with clear sections and detailed scenarios.`;
4445
- }
4446
- buildTechnicalSpecsPrompt(contextContent) {
4447
- return `You are a technical architect creating comprehensive technical specifications for a web application.
4448
-
4449
- ${contextContent
4450
- ? `Project Context (from PRD): ${contextContent}`
4451
- : "Generate technical specs for a modern web application."}
4452
-
4453
- Create detailed technical specifications that include:
4454
-
4455
- 1. **Architecture Overview** - System design, components, and relationships
4456
- 2. **Technology Stack** - Frontend, backend, database, deployment technologies
4457
- 3. **API Specifications** - Endpoints, request/response formats, authentication
4458
- 4. **Database Design** - Schema, relationships, indexing, data flow
4459
- 5. **Security Requirements** - Authentication, authorization, data protection
4460
- 6. **Performance Requirements** - Response times, throughput, scalability
4461
- 7. **Deployment Architecture** - Infrastructure, CI/CD, monitoring
4462
- 8. **Integration Requirements** - Third-party services, APIs, webhooks
4463
- 9. **Development Standards** - Code style, testing, documentation
4464
- 10. **Monitoring and Logging** - Error tracking, analytics, performance monitoring
4465
-
4466
- For each specification, include:
4467
- - Requirement description
4468
- - Technical approach
4469
- - Implementation details
4470
- - Dependencies
4471
- - Success criteria
4472
-
4473
- Format the output as a well-structured markdown document with clear sections and technical details.`;
4474
- }
4475
- formatFeaturesContent(response) {
4476
- return `# Product Features
4477
-
4478
- ${response}
4479
-
4480
- ---
4481
- *Generated by MyContext CLI - AI-powered component generation platform*
4482
- *Last updated: ${new Date().toISOString()}*
4483
- `;
4484
- }
4485
- formatUserFlowsContent(response) {
4486
- return `# User Flows
4487
-
4488
- ${response}
4489
-
4490
- ---
4491
- *Generated by MyContext CLI - AI-powered component generation platform*
4492
- *Last updated: ${new Date().toISOString()}*
4493
- `;
4494
- }
4495
- formatEdgeCasesContent(response) {
4496
- return `# Edge Cases and Error Scenarios
4497
-
4498
- ${response}
4499
-
4500
- ---
4501
- *Generated by MyContext CLI - AI-powered component generation platform*
4502
- *Last updated: ${new Date().toISOString()}*
4503
- `;
4504
- }
4505
- formatTechnicalSpecsContent(response) {
4506
- return `# Technical Specifications
4507
-
4508
- ${response}
4509
-
4510
- ---
4511
- *Generated by MyContext CLI - AI-powered component generation platform*
4512
- *Last updated: ${new Date().toISOString()}*
4513
- `;
4514
- }
4515
- /**
4516
- * Get context content for generation - prefer PRD over description
4517
- */
4518
- async getContextForGeneration(contextDir, fallbackDescription) {
4519
- // First, try to read from 01-prd.md
4520
- const prdPath = path_1.default.join(contextDir, "01-prd.md");
4521
- if (await fs.pathExists(prdPath)) {
4522
- try {
4523
- const prdContent = await fs.readFile(prdPath, "utf8");
4524
- // Check if PRD is just a template/starter sample
4525
- if (this.isTemplatePRD(prdContent)) {
4526
- console.log(chalk_1.default.yellow("⚠️ PRD appears to be a template, not using as context"));
4527
- }
4528
- else {
4529
- console.log(chalk_1.default.blue("📖 Using existing PRD as context for context files generation"));
4530
- return prdContent;
4531
- }
4532
- }
4533
- catch (error) {
4534
- console.log(chalk_1.default.yellow("⚠️ Could not read PRD file, falling back to description"));
4535
- }
4536
- }
4537
- // Fallback to description if no PRD exists
4538
- if (fallbackDescription) {
4539
- console.log(chalk_1.default.blue("📝 Using project description as context"));
4540
- return fallbackDescription;
4541
- }
4542
- // No context available - ask user
4543
- console.log(chalk_1.default.red("❌ No PRD or description found!"));
4544
- console.log(chalk_1.default.yellow("Please provide context by either:"));
4545
- console.log(chalk_1.default.gray(" 1. Run 'mycontext generate context' first to create a PRD"));
4546
- console.log(chalk_1.default.gray(" 2. Use --description flag: mycontext generate-context-files --description 'Your project'"));
4547
- console.log(chalk_1.default.gray(" 3. Create a PRD file manually at .mycontext/01-prd.md"));
4548
- throw new Error("No context available for generation. Please provide a PRD or description.");
4549
- }
4550
- /**
4551
- * Check if PRD content is just a template/starter sample
4552
- */
4553
- isTemplatePRD(content) {
4554
- const templateIndicators = [
4555
- "MyContext project",
4556
- "Replace this with your actual project description",
4557
- "TODO: Add your project details",
4558
- "This is a template",
4559
- "Sample project",
4560
- "Example project",
4561
- "Your project description here",
4562
- "Project Name: [Your Project Name]",
4563
- "Description: [Your project description]",
4564
- "## Project Overview\n\n[Add your project overview here]",
4565
- "## Requirements\n\n[Add your requirements here]",
4566
- "## Features\n\n[Add your features here]",
4567
- "## Technical Specifications\n\n[Add your technical specs here]",
4568
- ];
4569
- // Check if content contains multiple template indicators
4570
- const templateMatches = templateIndicators.filter((indicator) => content.toLowerCase().includes(indicator.toLowerCase()));
4571
- // If more than 2 template indicators are found, it's likely a template
4572
- if (templateMatches.length >= 2) {
4573
- return true;
4574
- }
4575
- // Check if content is very short (likely a template)
4576
- // BUT NOT if it's just a success message from context generation
4577
- if (content.includes("Full context generated successfully") ||
4578
- content.includes("context generated successfully")) {
4579
- return false; // This is not a template, it's a success message
4580
- }
4581
- if (content.trim().length < 200) {
4582
- return true;
4583
- }
4584
- // Check if content is mostly placeholder text
4585
- const placeholderRatio = (content.match(/\[.*?\]/g) || []).length /
4586
- (content.split(" ").length || 1);
4587
- if (placeholderRatio > 0.1) {
4588
- // More than 10% placeholders
4589
- return true;
4590
- }
4591
- return false;
4592
- }
4593
- /**
4594
- * REMOVED: Dangerous fallback method that compromises accuracy
4595
- * MyContext requires 100% accuracy - no fallbacks allowed
4596
- */
4597
- extractFeaturesFromPRD_DISABLED(prdContent) {
4598
- if (!prdContent) {
4599
- return `# Product Features
4600
-
4601
- ## Core Features
4602
-
4603
- *No features available - PRD content not found*
4604
-
4605
- ---
4606
- *Generated by MyContext CLI - AI-powered component generation platform*
4607
- *Last updated: ${new Date().toISOString()}*
4608
- `;
4609
- }
4610
- // Extract features from PRD content
4611
- const features = this.extractSectionFromPRD(prdContent, [
4612
- "Core Features",
4613
- "Features",
4614
- "Key Features",
4615
- "Main Features",
4616
- ]);
4617
- return `# Product Features
4618
-
4619
- ${features ||
4620
- "## Core Features\n\n*Features will be extracted from PRD content*"}
4621
-
4622
- ---
4623
- *Generated by MyContext CLI - AI-powered component generation platform*
4624
- *Last updated: ${new Date().toISOString()}*
4625
- `;
4626
- }
4627
- /**
4628
- * REMOVED: Dangerous fallback method that compromises accuracy
4629
- * MyContext requires 100% accuracy - no fallbacks allowed
4630
- */
4631
- extractUserFlowsFromPRD_DISABLED(prdContent) {
4632
- if (!prdContent) {
4633
- return `# User Flows
4634
-
4635
- ## User Journey
4636
-
4637
- *No user flows available - PRD content not found*
4638
-
4639
- ---
4640
- *Generated by MyContext CLI - AI-powered component generation platform*
4641
- *Last updated: ${new Date().toISOString()}*
4642
- `;
4643
- }
4644
- // Extract user flows from PRD content
4645
- const userFlows = this.extractSectionFromPRD(prdContent, [
4646
- "User Roles",
4647
- "User Journey",
4648
- "User Flows",
4649
- "Workflow",
4650
- ]);
4651
- return `# User Flows
4652
-
4653
- ${userFlows ||
4654
- "## User Journey\n\n*User flows will be extracted from PRD content*"}
4655
-
4656
- ---
4657
- *Generated by MyContext CLI - AI-powered component generation platform*
4658
- *Last updated: ${new Date().toISOString()}*
4659
- `;
4660
- }
4661
- /**
4662
- * REMOVED: Dangerous fallback method that compromises accuracy
4663
- * MyContext requires 100% accuracy - no fallbacks allowed
4664
- */
4665
- extractEdgeCasesFromPRD_DISABLED(prdContent) {
4666
- if (!prdContent) {
4667
- return `# Edge Cases and Error Scenarios
4668
-
4669
- ## Error Handling
4670
-
4671
- *No edge cases available - PRD content not found*
4672
-
4673
- ---
4674
- *Generated by MyContext CLI - AI-powered component generation platform*
4675
- *Last updated: ${new Date().toISOString()}*
4676
- `;
4677
- }
4678
- // Extract edge cases from PRD content
4679
- const edgeCases = this.extractSectionFromPRD(prdContent, [
4680
- "Risk Mitigation",
4681
- "Edge Cases",
4682
- "Error Scenarios",
4683
- "Troubleshooting",
4684
- ]);
4685
- return `# Edge Cases and Error Scenarios
4686
-
4687
- ${edgeCases ||
4688
- "## Error Handling\n\n*Edge cases will be extracted from PRD content*"}
4689
-
4690
- ---
4691
- *Generated by MyContext CLI - AI-powered component generation platform*
4692
- *Last updated: ${new Date().toISOString()}*
4693
- `;
4694
- }
4695
- /**
4696
- * REMOVED: Dangerous fallback method that compromises accuracy
4697
- * MyContext requires 100% accuracy - no fallbacks allowed
4698
- */
4699
- extractTechnicalSpecsFromPRD_DISABLED(prdContent) {
4700
- if (!prdContent) {
4701
- return `# Technical Specifications
4702
-
4703
- ## Architecture
4704
-
4705
- *No technical specs available - PRD content not found*
4706
-
4707
- ---
4708
- *Generated by MyContext CLI - AI-powered component generation platform*
4709
- *Last updated: ${new Date().toISOString()}*
4710
- `;
4711
- }
4712
- // Extract technical specs from PRD content
4713
- const techSpecs = this.extractSectionFromPRD(prdContent, [
4714
- "Technical Architecture",
4715
- "Technical Specifications",
4716
- "Architecture",
4717
- "Technology Stack",
4718
- ]);
4719
- return `# Technical Specifications
4720
-
4721
- ${techSpecs ||
4722
- "## Architecture\n\n*Technical specifications will be extracted from PRD content*"}
4723
-
4724
- ---
4725
- *Generated by MyContext CLI - AI-powered component generation platform*
4726
- *Last updated: ${new Date().toISOString()}*
4727
- `;
4728
- }
4729
- /**
4730
- * Extract a section from PRD content by looking for common section headers
4731
- */
4732
- extractSectionFromPRD(prdContent, sectionHeaders) {
4733
- const lines = prdContent.split("\n");
4734
- let inSection = false;
4735
- let sectionContent = [];
4736
- let currentSection = "";
4737
- for (const line of lines) {
4738
- const trimmedLine = line.trim();
4739
- // Check if this line starts a section we're looking for
4740
- if (sectionHeaders.some((header) => trimmedLine.toLowerCase().includes(header.toLowerCase()) &&
4741
- (trimmedLine.startsWith("#") ||
4742
- trimmedLine.startsWith("##") ||
4743
- trimmedLine.startsWith("###")))) {
4744
- if (inSection) {
4745
- // We found a new section, stop collecting the previous one
4746
- break;
4747
- }
4748
- inSection = true;
4749
- currentSection = trimmedLine;
4750
- sectionContent.push(line);
4751
- continue;
4752
- }
4753
- if (inSection) {
4754
- // Check if we hit another major section (starts with # or ##)
4755
- if (trimmedLine.startsWith("#") &&
4756
- !trimmedLine.includes(currentSection)) {
4757
- break;
4758
- }
4759
- sectionContent.push(line);
4760
- }
4761
- }
4762
- return sectionContent.join("\n").trim();
4763
- }
4764
4037
  }
4765
4038
  exports.GenerateCommand = GenerateCommand;
4766
4039
  //# sourceMappingURL=generate.js.map