"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LandingPageOrchestrator = exports.STAGE_ORDER = void 0;
const path = __importStar(require("path"));
const fs = __importStar(require("fs-extra"));
const chalk_1 = __importDefault(require("chalk"));
const child_process_1 = require("child_process");
const util_1 = require("util");
const AICore_1 = require("../core/ai/AICore");
const execAsync = (0, util_1.promisify)(child_process_1.exec);
exports.STAGE_ORDER = {
    "INIT": 0,
    "BASELINE_CHECK": 1,
    "CONTEXT_GENERATED": 2,
    "NARRATIVE_GENERATED": 3,
    "SECTION_MANIFEST_GENERATED": 4,
    "COMPONENT_INVENTORY_GENERATED": 5,
    "PRIMITIVE_MAPPING_GENERATED": 6,
    "CONTENT_SCHEMA_GENERATED": 7,
    "SKELETON_GENERATED": 8,
    "CONTENT_POPULATED": 9,
    "SECTION_VALIDATED": 10,
    "CLASSNAME_REFINED": 11,
    "FINAL_VALIDATED": 12,
    "SELF_HEALED": 13
};
class LandingPageOrchestrator {
    constructor(projectPath, outputDir, verbose = false, fresh = false) {
        this.projectPath = projectPath;
        this.outputDir = outputDir;
        this.verbose = verbose;
        this.aiCore = AICore_1.AICore.getInstance({
            fallbackEnabled: true,
            workingDirectory: projectPath,
        });
        this.state = { stage: "INIT", report: [] };
        if (fresh) {
            this.clearStateSync();
        }
        else {
            this.loadStateSync();
        }
    }
    loadStateSync() {
        const statePath = path.join(this.projectPath, ".mycontext/landing-page/state.json");
        if (fs.existsSync(statePath)) {
            try {
                const savedState = fs.readJsonSync(statePath);
                this.state = {
                    stage: savedState.stage || "INIT",
                    baselineCheck: savedState.baselineCheck,
                    projectContext: savedState.projectContext,
                    narrative: savedState.narrative,
                    sectionManifest: savedState.sectionManifest,
                    componentInventory: savedState.componentInventory,
                    primitiveMapping: savedState.primitiveMapping,
                    contentSchema: savedState.contentSchema,
                    pageManifest: savedState.pageManifest,
                    skeletons: savedState.skeletons,
                    validatedSections: savedState.validatedSections ? new Set(savedState.validatedSections) : undefined,
                    report: savedState.report || []
                };
                if (this.verbose) {
                    console.log(chalk_1.default.blue(`   [State] Loaded pipeline state: ${this.state.stage}`));
                }
                return;
            }
            catch (e) {
                // Fall back to reading files individually
            }
        }
        // Fallback: load individual files
        const baselineCheckPath = path.join(this.projectPath, ".mycontext/landing-page/baseline-check.json");
        const contextPath = path.join(this.projectPath, ".mycontext/landing-page/project-context.json");
        const narrativePath = path.join(this.projectPath, ".mycontext/landing-page/narrative.json");
        const sectionManifestPath = path.join(this.projectPath, ".mycontext/landing-page/section-manifest.json");
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/landing-page-manifest.json");
        if (fs.existsSync(baselineCheckPath)) {
            try {
                this.state.baselineCheck = fs.readJsonSync(baselineCheckPath);
                this.state.stage = "BASELINE_CHECK";
            }
            catch { }
        }
        if (fs.existsSync(contextPath)) {
            try {
                this.state.projectContext = fs.readJsonSync(contextPath);
                this.state.stage = "CONTEXT_GENERATED";
            }
            catch { }
        }
        if (fs.existsSync(narrativePath)) {
            try {
                this.state.narrative = fs.readJsonSync(narrativePath);
                this.state.stage = "NARRATIVE_GENERATED";
            }
            catch { }
        }
        if (fs.existsSync(sectionManifestPath)) {
            try {
                this.state.sectionManifest = fs.readJsonSync(sectionManifestPath);
                this.state.stage = "SECTION_MANIFEST_GENERATED";
            }
            catch { }
        }
        // Legacy support: old MANIFEST_GENERATED stage is now split into multiple stages
        // If old manifest exists, we can't reliably determine which new stage we're at
        // Users should use fresh mode for new pipeline
    }
    clearStateSync() {
        try {
            const dirPath = path.join(this.projectPath, ".mycontext/landing-page");
            if (fs.existsSync(dirPath)) {
                fs.removeSync(dirPath);
            }
            if (this.verbose) {
                console.log(chalk_1.default.yellow("   [State] Cleared existing stage manifests for a fresh run."));
            }
        }
        catch { }
    }
    async saveState() {
        const statePath = path.join(this.projectPath, ".mycontext/landing-page/state.json");
        await fs.ensureDir(path.dirname(statePath));
        await fs.writeJSON(statePath, this.state, { spaces: 2 });
    }
    isStageCompleted(stage) {
        return exports.STAGE_ORDER[this.state.stage] >= exports.STAGE_ORDER[stage];
    }
    cleanJsonString(str) {
        let clean = str.trim();
        if (clean.startsWith("```json")) {
            clean = clean.replace(/^```json\s*/m, "").replace(/\s*```$/m, "");
        }
        else if (clean.startsWith("```")) {
            clean = clean.replace(/^```\s*/m, "").replace(/\s*```$/m, "");
        }
        return clean;
    }
    /**
     * Stage 1: Baseline Check - Verify shadcn/ui installation
     */
    async performBaselineCheck() {
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/baseline-check.json");
        if (await fs.pathExists(manifestPath)) {
            console.log(chalk_1.default.gray("   → [Stage 1] Loading existing baseline-check.json from disk..."));
            const parsed = await fs.readJSON(manifestPath);
            this.state.baselineCheck = parsed;
            this.state.stage = "BASELINE_CHECK";
            await this.saveState();
            return parsed;
        }
        console.log(chalk_1.default.gray("   → [Stage 1] Verifying shadcn/ui baseline..."));
        // Core primitives required for landing pages
        const corePrimitives = [
            "button",
            "card",
            "badge",
            "input",
            "label",
            "dialog",
            "navigation-menu",
            "separator"
        ];
        const result = {
            shadcnInstalled: false,
            componentsUiExists: false,
            componentsJsonExists: false,
            pathAliasConfigured: false,
            installedPrimitives: [],
            missingPrimitives: []
        };
        // Check if components/ui directory exists
        const uiDir = path.join(this.projectPath, "components/ui");
        result.componentsUiExists = await fs.pathExists(uiDir);
        // Check if components.json exists
        const componentsJsonPath = path.join(this.projectPath, "components.json");
        result.componentsJsonExists = await fs.pathExists(componentsJsonPath);
        // Check TypeScript config for path alias
        const tsconfigPath = path.join(this.projectPath, "tsconfig.json");
        if (await fs.pathExists(tsconfigPath)) {
            try {
                const tsconfigContent = await fs.readFile(tsconfigPath, "utf-8");
                const tsconfig = JSON.parse(tsconfigContent);
                const paths = tsconfig?.compilerOptions?.paths;
                result.pathAliasConfigured =
                    paths &&
                        (paths["@/*"] || paths["@/components/*"] || paths["~/components/*"]);
            }
            catch { }
        }
        // List installed primitives
        if (result.componentsUiExists) {
            try {
                const files = await fs.readdir(uiDir);
                result.installedPrimitives = files
                    .filter(f => f.endsWith(".tsx") || f.endsWith(".ts"))
                    .map(f => f.replace(/\.(tsx|ts)$/, ""));
            }
            catch { }
        }
        // Identify missing core primitives
        result.missingPrimitives = corePrimitives.filter(primitive => !result.installedPrimitives.includes(primitive));
        // shadcn is considered installed if components.json exists and ui directory exists
        result.shadcnInstalled = result.componentsJsonExists && result.componentsUiExists;
        // Save result
        await fs.ensureDir(path.dirname(manifestPath));
        await fs.writeJSON(manifestPath, result, { spaces: 2 });
        this.state.baselineCheck = result;
        this.state.stage = "BASELINE_CHECK";
        await this.saveState();
        // Report findings
        if (result.shadcnInstalled) {
            console.log(chalk_1.default.green(`   ✓ shadcn/ui is installed`));
            console.log(chalk_1.default.gray(`   ✓ Found ${result.installedPrimitives.length} components`));
            if (result.missingPrimitives.length > 0) {
                console.log(chalk_1.default.yellow(`   ⚠ Missing ${result.missingPrimitives.length} core primitives: ${result.missingPrimitives.join(", ")}`));
            }
        }
        else {
            console.log(chalk_1.default.red(`   ✗ shadcn/ui is NOT installed`));
            if (!result.componentsJsonExists) {
                console.log(chalk_1.default.yellow(`   → Run: npx shadcn@latest init`));
            }
        }
        return result;
    }
    /**
     * Stage 2: Generate Project Context Manifest
     */
    async generateProjectContext() {
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/project-context.json");
        if (await fs.pathExists(manifestPath)) {
            console.log(chalk_1.default.gray("   → [Stage 2] Loading existing project-context.json from disk..."));
            const parsed = await fs.readJSON(manifestPath);
            this.state.projectContext = parsed;
            this.state.stage = "CONTEXT_GENERATED";
            await this.saveState();
            return parsed;
        }
        console.log(chalk_1.default.gray("   → [Stage 2] Reading project specifications (README.md, PRD, context.json)..."));
        let readme = await this.safeReadFile("README.md");
        if (readme && readme.length > 3000) {
            readme = readme.substring(0, 3000) + "\n... [TRUNCATED] ...";
        }
        let prd = await this.safeReadFile(".mycontext/01-prd.md") || await this.safeReadFile("context/01-prd.md");
        if (prd && prd.length > 3000) {
            prd = prd.substring(0, 3000) + "\n... [TRUNCATED] ...";
        }
        const livingBrainRaw = await this.safeReadFile(".mycontext/context.json");
        let livingBrain = "";
        if (livingBrainRaw) {
            try {
                const parsed = JSON.parse(livingBrainRaw);
                const subset = {
                    project: parsed.project,
                    prd: parsed.prd,
                    capabilities: parsed.capabilities,
                    brain: parsed.brain,
                    functional_summary: parsed.phases?.functional_summary || parsed.functional_summary
                };
                livingBrain = JSON.stringify(subset, null, 2);
            }
            catch (e) {
                // Fallback to truncated raw string if JSON parsing fails
                livingBrain = livingBrainRaw.length > 3000
                    ? livingBrainRaw.substring(0, 3000) + "\n... [TRUNCATED] ..."
                    : livingBrainRaw;
            }
        }
        console.log(chalk_1.default.gray("   → [Stage 2] Invoking AI strategist to compile Project Context..."));
        const prompt = `You are a product strategist. Extract and generate a ProjectContext JSON manifest based on these project assets:

---
README:
${readme}
---
PRD:
${prd}
---
Living Brain Context:
${livingBrain}
---

Generate a JSON object matching this TypeScript interface exactly:
\`\`\`ts
interface ProjectContext {
  productSummary: string; // High-level product summary
  audience: string[]; // Target personas/audience
  coreProblem: string; // The primary pain point solved
  valuePromise: string; // Unique value proposition (UVP)
  workflows: string[]; // Core product workflows/features
  positioning: string; // Market positioning statement
  constraints: string[]; // Technical / brand constraints
}
\`\`\`

Return ONLY raw JSON. Do not include markdown code block backticks.`;
        const response = await this.aiCore.generateText(prompt, { temperature: 0.2, maxTokens: 1000 });
        const parsed = JSON.parse(this.cleanJsonString(response));
        await fs.ensureDir(path.dirname(manifestPath));
        await fs.writeJSON(manifestPath, parsed, { spaces: 2 });
        this.state.projectContext = parsed;
        this.state.stage = "CONTEXT_GENERATED";
        await this.saveState();
        return parsed;
    }
    /**
     * Stage 2: Generate Narrative Manifest
     */
    async generateNarrative(context) {
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/narrative.json");
        if (await fs.pathExists(manifestPath)) {
            console.log(chalk_1.default.gray("   → [Stage 3] Loading existing narrative.json from disk..."));
            const parsed = await fs.readJSON(manifestPath);
            this.state.narrative = parsed;
            this.state.stage = "NARRATIVE_GENERATED";
            await this.saveState();
            return parsed;
        }
        const ctx = context || this.state.projectContext;
        if (!ctx)
            throw new Error("Project Context is required to generate narrative");
        console.log(chalk_1.default.gray("   → [Stage 3] Drafting high-conversion storyline via AI copywriter..."));
        const prompt = `You are a high-conversion copywriter. Create a NarrativeManifest JSON for the product described below:

Project Context:
${JSON.stringify(ctx, null, 2)}

Define the story logic before any layout is planned. Generate a JSON object matching this TypeScript interface:
\`\`\`ts
interface NarrativeManifest {
  hook: string; // The opening hook that addresses the visitor immediately
  tension: string; // The core tension/pain point the target audience faces
  transformation: string; // The transformation promised once the product is used
  trustStrategy: string; // How trust will be built (e.g. proof, stats, logic)
  objectionHandling: string[]; // Key objections handled
  CTAIntent: string; // The intent/action of the primary call-to-action
}
\`\`\`

Return ONLY raw JSON.`;
        const response = await this.aiCore.generateText(prompt, { temperature: 0.3, maxTokens: 1000 });
        const parsed = JSON.parse(this.cleanJsonString(response));
        await fs.ensureDir(path.dirname(manifestPath));
        await fs.writeJSON(manifestPath, parsed, { spaces: 2 });
        this.state.narrative = parsed;
        this.state.stage = "NARRATIVE_GENERATED";
        await this.saveState();
        return parsed;
    }
    /**
     * Stage 4: Generate Section Manifest (sections with semantic intent only)
     */
    async generateSectionManifest(narrative) {
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/section-manifest.json");
        if (await fs.pathExists(manifestPath)) {
            console.log(chalk_1.default.gray("   → [Stage 4] Loading existing section-manifest.json from disk..."));
            const parsed = await fs.readJSON(manifestPath);
            this.state.sectionManifest = parsed;
            this.state.stage = "SECTION_MANIFEST_GENERATED";
            await this.saveState();
            return parsed;
        }
        const nar = narrative || this.state.narrative;
        if (!nar)
            throw new Error("Narrative Manifest is required to generate section manifest");
        console.log(chalk_1.default.gray("   → [Stage 4] Defining page sections with semantic intent..."));
        const prompt = `You are a UX Architect. Based on the narrative below, define the SECTIONS needed for this landing page.

Narrative:
${JSON.stringify(nar, null, 2)}

Define sections with semantic intent ONLY. Do NOT specify components or styling yet.

Return a JSON object matching this interface:
\`\`\`ts
interface Section {
  id: string; // e.g. "hero", "features", "workflow", "faq", "cta", "footer"
  name: string; // Capitalized name e.g. "HeroSection"
  type: string; // e.g. "hero" | "grid" | "workflow" | "pricing" | "cta" | "footer"
  purpose: string; // Crucial objective of this section
  contentRequired: string[]; // Specific copy/topics required in this section
}

interface SectionManifest {
  sections: Section[];
  layoutIntent: string; // High-level layout philosophy (e.g. "Single-column modern SaaS", "Two-column with sidebar")
}
\`\`\`

Return ONLY raw JSON.`;
        const response = await this.aiCore.generateText(prompt, { temperature: 0.2, maxTokens: 1200 });
        const parsed = JSON.parse(this.cleanJsonString(response));
        await fs.ensureDir(path.dirname(manifestPath));
        await fs.writeJSON(manifestPath, parsed, { spaces: 2 });
        this.state.sectionManifest = parsed;
        this.state.stage = "SECTION_MANIFEST_GENERATED";
        await this.saveState();
        return parsed;
    }
    /**
     * Stage 5: Generate Component Inventory (abstract UI patterns, not specific components)
     */
    async generateComponentInventory(sectionManifest) {
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/component-inventory.json");
        if (await fs.pathExists(manifestPath)) {
            console.log(chalk_1.default.gray("   → [Stage 5] Loading existing component-inventory.json from disk..."));
            const parsed = await fs.readJSON(manifestPath);
            this.state.componentInventory = parsed;
            this.state.stage = "COMPONENT_INVENTORY_GENERATED";
            await this.saveState();
            return parsed;
        }
        const sectManifest = sectionManifest || this.state.sectionManifest;
        if (!sectManifest)
            throw new Error("Section Manifest is required to generate component inventory");
        console.log(chalk_1.default.gray("   → [Stage 5] Identifying abstract UI patterns needed..."));
        const prompt = `You are a UI Pattern Analyst. Based on the sections below, identify the ABSTRACT UI PATTERNS needed.

Sections:
${JSON.stringify(sectManifest.sections, null, 2)}

For each section, identify what UI patterns are needed (NOT specific component names yet).

Examples of abstract patterns:
- "Primary call-to-action button"
- "Feature card with icon and description"
- "Navigation menu with dropdown support"
- "Testimonial card with avatar and quote"
- "Email input with submit button"

Return a JSON object matching this interface:
\`\`\`ts
interface ComponentInventory {
  patterns: Array<{
    id: string; // Unique ID
    patternName: string; // Abstract pattern name
    purpose: string; // What this pattern does
    usedInSections: string[]; // Section IDs where this pattern appears
  }>;
}
\`\`\`

Return ONLY raw JSON.`;
        const response = await this.aiCore.generateText(prompt, { temperature: 0.2, maxTokens: 1500 });
        const parsed = JSON.parse(this.cleanJsonString(response));
        await fs.ensureDir(path.dirname(manifestPath));
        await fs.writeJSON(manifestPath, parsed, { spaces: 2 });
        this.state.componentInventory = parsed;
        this.state.stage = "COMPONENT_INVENTORY_GENERATED";
        await this.saveState();
        return parsed;
    }
    /**
     * Stage 6: Generate Primitive Mapping (map UI patterns to shadcn components)
     */
    async generatePrimitiveMapping(componentInventory) {
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/primitive-mapping.json");
        if (await fs.pathExists(manifestPath)) {
            console.log(chalk_1.default.gray("   → [Stage 6] Loading existing primitive-mapping.json from disk..."));
            const parsed = await fs.readJSON(manifestPath);
            this.state.primitiveMapping = parsed;
            this.state.stage = "PRIMITIVE_MAPPING_GENERATED";
            await this.saveState();
            return parsed;
        }
        const inventory = componentInventory || this.state.componentInventory;
        if (!inventory)
            throw new Error("Component Inventory is required to generate primitive mapping");
        // Check baseline first
        if (!this.state.baselineCheck) {
            throw new Error("Baseline check must be performed before primitive mapping");
        }
        const baselineCheck = this.state.baselineCheck;
        if (!baselineCheck.shadcnInstalled) {
            throw new Error("shadcn/ui is not installed. Run baseline check and install shadcn first.");
        }
        console.log(chalk_1.default.gray("   → [Stage 6] Mapping UI patterns to shadcn/Radix primitives..."));
        const { recommendComponentsForSection, getComponentByName } = await Promise.resolve().then(() => __importStar(require("./shadcn-primitive-catalog")));
        const mappings = [];
        for (const pattern of inventory.patterns) {
            // Use the catalog to recommend components for this pattern
            const recommendations = await recommendComponentsForSection(pattern.purpose);
            const shadcnComponents = [];
            const radixPrimitives = [];
            for (const rec of recommendations) {
                shadcnComponents.push(rec.name);
                if (rec.radixPrimitives) {
                    radixPrimitives.push(...rec.radixPrimitives);
                }
            }
            // Verify components are installed
            const verified = shadcnComponents.every(comp => baselineCheck.installedPrimitives.includes(comp));
            mappings.push({
                patternId: pattern.id,
                shadcnComponents,
                radixPrimitives: [...new Set(radixPrimitives)], // Remove duplicates
                verified
            });
        }
        const result = { mappings };
        await fs.ensureDir(path.dirname(manifestPath));
        await fs.writeJSON(manifestPath, result, { spaces: 2 });
        this.state.primitiveMapping = result;
        this.state.stage = "PRIMITIVE_MAPPING_GENERATED";
        await this.saveState();
        // Report unverified mappings
        const unverified = mappings.filter(m => !m.verified);
        if (unverified.length > 0) {
            console.log(chalk_1.default.yellow(`   ⚠ ${unverified.length} mappings use components not yet installed:`));
            unverified.forEach(m => {
                const missing = m.shadcnComponents.filter(c => !baselineCheck.installedPrimitives.includes(c));
                console.log(chalk_1.default.yellow(`     → Pattern ${m.patternId}: missing ${missing.join(", ")}`));
            });
        }
        else {
            console.log(chalk_1.default.green(`   ✓ All ${mappings.length} patterns mapped to installed components`));
        }
        return result;
    }
    /**
     * DEPRECATED: Generate Landing Page Manifest (Old Pipeline)
     *
     * NOTE: This method combines Section Manifest + Component Inventory + Primitive Mapping
     * into a single step. It's kept for backward compatibility but new code should use
     * the split stages: generateSectionManifest → generateComponentInventory → generatePrimitiveMapping
     *
     * WARNING: This method is deprecated and does not update pipeline stage tracking.
     * Use the new split methods for proper stage progression.
     */
    async generatePageManifest(narrative) {
        console.log(chalk_1.default.yellow("   ⚠ WARNING: generatePageManifest() is deprecated. Use generateSectionManifest() → generateComponentInventory() → generatePrimitiveMapping() instead."));
        const manifestPath = path.join(this.projectPath, ".mycontext/landing-page/landing-page-manifest.json");
        if (await fs.pathExists(manifestPath)) {
            console.log(chalk_1.default.gray("   → [DEPRECATED] Loading existing landing-page-manifest.json from disk..."));
            const parsed = await fs.readJSON(manifestPath);
            this.state.pageManifest = parsed;
            // Note: Stage not updated - deprecated method doesn't track new pipeline stages
            await this.saveState();
            return parsed;
        }
        const nar = narrative || this.state.narrative;
        if (!nar)
            throw new Error("Narrative Manifest is required to generate page manifest");
        console.log(chalk_1.default.gray("   → [DEPRECATED] Designing layout grid and component inventory via UX Architect..."));
        const prompt = `You are a UX Architect. Create a LandingPageManifest JSON that schedules sections to implement this narrative:

Narrative:
${JSON.stringify(nar, null, 2)}

Create a structural plan (layout orchestration, component inventory, responsive rules). Match this interface:
\`\`\`ts
interface Section {
  id: string; // e.g. "hero", "features", "workflow", "faq", "cta", "footer"
  name: string; // Capitalized name e.g. "HeroSection"
  type: string; // e.g. "hero" | "grid" | "workflow" | "pricing" | "cta" | "footer"
  purpose: string; // Crucial objective of this section
  contentRequired: string[]; // Specific copy/topics required in this section
}

interface LandingPageManifest {
  sections: Section[];
  layoutIntent: string; // Visual design grid logic (e.g. clean modern SaaS grid, terminal glassmorphism structure)
  componentInventory: string[]; // Sub-components needed
  responsiveRules: string[]; // Specific mobile layout/stacking expectations
}
\`\`\`

Return ONLY raw JSON.`;
        const response = await this.aiCore.generateText(prompt, { temperature: 0.2, maxTokens: 1000 });
        const parsed = JSON.parse(this.cleanJsonString(response));
        await fs.ensureDir(path.dirname(manifestPath));
        await fs.writeJSON(manifestPath, parsed, { spaces: 2 });
        this.state.pageManifest = parsed;
        // Note: Stage not updated - deprecated method doesn't track new pipeline stages
        await this.saveState();
        return parsed;
    }
    /**
     * Stage 8: Component Skeleton Generation (STRUCTURE-ONLY, no content)
     */
    async generateComponentSkeletons(sectionManifest) {
        const manifest = sectionManifest || this.state.sectionManifest;
        if (!manifest)
            throw new Error("Section Manifest is required to generate component skeletons");
        // Ensure primitive mapping was performed
        if (!this.state.primitiveMapping) {
            throw new Error("Primitive mapping must be performed before skeleton generation");
        }
        const skeletons = [];
        await fs.ensureDir(this.outputDir);
        const uiDir = path.join(path.dirname(this.outputDir), "ui");
        await this.ensureShadcnUiStubs(uiDir);
        // Check if skeletons already exist on disk
        let allExist = true;
        const loadedSkeletons = [];
        for (const section of manifest.sections) {
            const filePath = path.join(this.outputDir, `${section.name}.tsx`);
            if (await fs.pathExists(filePath)) {
                const code = await fs.readFile(filePath, "utf8");
                loadedSkeletons.push({
                    id: section.id,
                    name: section.name,
                    file: filePath,
                    code
                });
            }
            else {
                allExist = false;
                break;
            }
        }
        const pagePath = path.join(this.outputDir, "page.tsx");
        if (allExist && await fs.pathExists(pagePath) && loadedSkeletons.length === manifest.sections.length) {
            console.log(chalk_1.default.gray(`   → [Stage 8] Loading existing skeletons from ${this.outputDir}...`));
            this.state.skeletons = loadedSkeletons;
            this.state.stage = "SKELETON_GENERATED";
            await this.saveState();
            return loadedSkeletons;
        }
        console.log(chalk_1.default.gray(`   → [Stage 8] Generating STRUCTURE-ONLY React skeletons (no content yet)...`));
        // Get verified components from primitive mapping
        const verifiedComponents = this.state.primitiveMapping.mappings
            .filter(m => m.verified)
            .flatMap(m => m.shadcnComponents);
        for (const section of manifest.sections) {
            console.log(chalk_1.default.gray(`     → Generating structure skeleton for ${section.name}...`));
            const prompt = `You are a frontend developer creating a STRUCTURE-ONLY React component skeleton.

IMPORTANT: Generate LAYOUT and STRUCTURE only. Use PLACEHOLDER content (Lorem ipsum, placeholder text).
DO NOT generate final copy, headings, or specific content. Content will be added in the next stage.

Section ID: ${section.id}
Section Type: ${section.type}
Purpose: ${section.purpose}
Layout Intent: ${manifest.layoutIntent}

Available shadcn Components (VERIFIED as installed):
${verifiedComponents.map(c => `- ${c}`).join("\n")}

Requirements:
1. STRUCTURE ONLY - Use placeholder text for ALL content:
   - Headings: "Placeholder Heading", "Section Title"
   - Body text: "Lorem ipsum dolor sit amet consectetur adipiscing elit"
   - Button labels: "Action", "Learn More", "Get Started"
   - DO NOT write specific marketing copy

2. React/Next.js + Tailwind CSS + shadcn/ui components:
   - Import components from "@/components/ui/*"
   - Only use components from the verified list above
   - Lucide icons: \`import { Icon } from "lucide-react"\`

3. Layout focused:
   - Responsive grid/flex layouts
   - Proper spacing (py-12, px-4, gap-8, etc.)
   - Mobile-first responsive classes (md:, lg:)
   - Accessible semantic HTML (section, header, h1-h6)

4. Clean and minimal:
   - NO advanced visual polish yet
   - NO gradients, shadows, or decorative styles
   - Simple, functional layout structure
   - Component must export default

Return ONLY the TypeScript React component code.`;
            const code = await this.aiCore.generateText(prompt, { temperature: 0.05, maxTokens: 2000 });
            const cleanedCode = this.cleanCodeBlock(code);
            const filePath = path.join(this.outputDir, `${section.name}.tsx`);
            await fs.writeFile(filePath, cleanedCode);
            skeletons.push({
                id: section.id,
                name: section.name,
                file: filePath,
                code: cleanedCode,
            });
        }
        console.log(chalk_1.default.gray("     → Creating parent page.tsx container and importing sections..."));
        const pageImportStatements = manifest.sections
            .map(s => `import ${s.name} from "./${s.name}";`)
            .join("\n");
        const pageRenderElements = manifest.sections
            .map(s => `<${s.name} />`)
            .join("\n      ");
        const pageCode = `import React from "react";
${pageImportStatements}

export default function LandingPage() {
  return (
    <div className="min-h-screen bg-background text-foreground antialiased selection:bg-primary/10">
      ${pageRenderElements}
    </div>
  );
}
`;
        await fs.writeFile(path.join(this.outputDir, "page.tsx"), pageCode);
        this.state.skeletons = skeletons;
        this.state.stage = "SKELETON_GENERATED";
        await this.saveState();
        return skeletons;
    }
    /**
     * Stage 9: Content Population (fill skeletons with actual content)
     */
    async populateContent(skeletons, narrative, projectContext) {
        if (this.state.stage === "CONTENT_POPULATED") {
            console.log(chalk_1.default.gray("   → [Stage 9] Content already populated. Skipping..."));
            return;
        }
        const skels = skeletons || this.state.skeletons;
        const nar = narrative || this.state.narrative;
        const ctx = projectContext || this.state.projectContext;
        if (!skels)
            throw new Error("Skeletons are required for content population");
        if (!nar)
            throw new Error("Narrative is required for content population");
        if (!ctx)
            throw new Error("Project Context is required for content population");
        console.log(chalk_1.default.gray(`   → [Stage 9] Populating ${skels.length} components with actual content...`));
        for (const skeleton of skels) {
            console.log(chalk_1.default.gray(`     → Populating content for ${skeleton.name}...`));
            // Find the section from the manifest
            const section = this.state.sectionManifest?.sections.find(s => s.id === skeleton.id);
            if (!section) {
                console.log(chalk_1.default.yellow(`     ⚠ Could not find section manifest for ${skeleton.id}, skipping content population`));
                continue;
            }
            const prompt = `You are a conversion copywriter. Replace ALL placeholder content in this React component with compelling, specific copy.

CURRENT CODE (with placeholders):
\`\`\`tsx
${skeleton.code}
\`\`\`

PROJECT CONTEXT:
${JSON.stringify(ctx, null, 2)}

NARRATIVE STRATEGY:
${JSON.stringify(nar, null, 2)}

SECTION REQUIREMENTS:
- Section ID: ${section.id}
- Section Type: ${section.type}
- Purpose: ${section.purpose}
- Content Required: ${section.contentRequired.join(", ")}

TASK:
Replace ALL placeholder text with actual content that:
1. Aligns with the narrative strategy (hook, tension, transformation, trust, objections, CTA)
2. Addresses the section purpose directly
3. Includes all content requirements listed above
4. Uses conversion-focused copy (benefit-driven, specific, actionable)
5. Maintains the exact same component structure and styling

DO NOT:
- Change component structure or layout
- Modify Tailwind classes or styling
- Add or remove HTML elements
- Change imports or component names

ONLY replace:
- Heading text
- Body paragraphs
- Button labels
- List items
- Any other text content

Return ONLY the updated TypeScript React component code.`;
            const updatedCode = await this.aiCore.generateText(prompt, { temperature: 0.3, maxTokens: 3000 });
            const cleanedCode = this.cleanCodeBlock(updatedCode);
            // Update the file
            await fs.writeFile(skeleton.file, cleanedCode);
            // Update skeleton in state
            skeleton.code = cleanedCode;
        }
        this.state.skeletons = skels;
        this.state.stage = "CONTENT_POPULATED";
        await this.saveState();
        console.log(chalk_1.default.green(`   ✓ Content populated in ${skels.length} components`));
    }
    /**
     * Stage 10: Section Validation (validate each section independently)
     */
    async validateSections() {
        if (this.state.stage === "SECTION_VALIDATED") {
            console.log(chalk_1.default.gray("   → [Stage 10] Sections already validated. Skipping..."));
            return;
        }
        const skels = this.state.skeletons;
        if (!skels)
            throw new Error("Skeletons are required for section validation");
        console.log(chalk_1.default.gray(`   → [Stage 10] Validating ${skels.length} sections independently...`));
        const nearestTsconfigPath = await this.findNearestTsconfig(this.outputDir);
        const tempTsconfigPath = path.join(this.projectPath, ".mycontext/generated/tsconfig.section-validation.json");
        await fs.ensureDir(path.dirname(tempTsconfigPath));
        const runCwd = nearestTsconfigPath ? path.dirname(nearestTsconfigPath) : this.projectPath;
        const validatedSections = new Set();
        const failedSections = [];
        for (const skeleton of skels) {
            console.log(chalk_1.default.gray(`     → Validating ${skeleton.name}...`));
            // Create a minimal tsconfig for this one file
            const tsconfigContent = {
                extends: nearestTsconfigPath || undefined,
                compilerOptions: {
                    noEmit: true,
                    skipLibCheck: true,
                    jsx: "react-jsx",
                    module: "esnext",
                    target: "es2020",
                    moduleResolution: "bundler",
                    paths: {
                        "@/components/*": [path.join(path.dirname(this.outputDir), "*")],
                        "@/*": [path.join(this.projectPath, "*")]
                    }
                },
                include: [skeleton.file]
            };
            await fs.writeJSON(tempTsconfigPath, tsconfigContent, { spaces: 2 });
            try {
                await execAsync(`npx tsc --noEmit --project "${tempTsconfigPath}"`, { cwd: runCwd });
                console.log(chalk_1.default.green(`     ✓ ${skeleton.name} validated`));
                validatedSections.add(skeleton.id);
            }
            catch (error) {
                const stdout = error.stdout || "";
                const stderr = error.stderr || "";
                const fullError = stdout + "\n" + stderr;
                const cleanErrorLines = fullError
                    .replace(/\x1b\[[0-9;]*m/g, "")
                    .split("\n")
                    .filter(line => line.trim().length > 0)
                    .filter(line => line.includes("error TS") ||
                    line.includes(skeleton.file));
                failedSections.push({
                    sectionId: skeleton.id,
                    errors: cleanErrorLines
                });
                console.log(chalk_1.default.red(`     ✗ ${skeleton.name} has ${cleanErrorLines.length} errors`));
            }
        }
        // Clean up temp tsconfig
        await fs.remove(tempTsconfigPath);
        // Store validation results
        this.state.validatedSections = validatedSections;
        if (failedSections.length === 0) {
            console.log(chalk_1.default.green(`   ✓ All ${skels.length} sections validated successfully`));
            this.state.stage = "SECTION_VALIDATED";
            await this.saveState();
        }
        else {
            console.log(chalk_1.default.yellow(`   ⚠ ${failedSections.length}/${skels.length} sections failed validation:`));
            failedSections.forEach(f => {
                console.log(chalk_1.default.yellow(`     → ${f.sectionId}: ${f.errors.length} errors`));
                f.errors.slice(0, 3).forEach(err => console.log(chalk_1.default.gray(`       ${err}`)));
            });
            throw new Error(`Section validation failed for ${failedSections.length} sections. Fix errors and retry.`);
        }
    }
    /**
     * Stage 11: Constrained Design Refinement (measurable improvements only)
     */
    async refineComponents(skeletons, context) {
        if (this.state.stage === "CLASSNAME_REFINED" || this.state.stage === "FINAL_VALIDATED") {
            console.log(chalk_1.default.gray("   → [Stage 11] Skeletons already refined. Skipping refinement passes."));
            return;
        }
        const skels = skeletons || this.state.skeletons;
        const ctx = context || this.state.projectContext;
        if (!skels || !ctx)
            throw new Error("Skeletons and Project Context are required for refinement");
        console.log(chalk_1.default.gray(`   → [Stage 11] Running constrained design refinement on ${skels.length} components...`));
        for (const skeleton of skels) {
            let currentCode = skeleton.code;
            const passes = [
                {
                    name: "Typography & Hierarchy",
                    constraints: [
                        "Increase heading font-size difference between h1 and h2 by at least 4 units (e.g., text-4xl → text-5xl or text-6xl for h1)",
                        "Ensure h1 uses font-bold or font-extrabold for maximum prominence",
                        "Body text must be at least text-base, preferably text-lg for readability",
                        "Ensure at least 4.5:1 contrast ratio between text and background (use text-foreground, text-muted-foreground)",
                        "Align heading text-left on mobile, can use text-center on md+ breakpoints"
                    ]
                },
                {
                    name: "Spacing & Alignment",
                    constraints: [
                        "Normalize all spacing to 8px grid: use only gap-4, gap-6, gap-8, gap-12, gap-16",
                        "Section vertical padding must be py-16 on mobile, py-24 on md+ breakpoints",
                        "Container max-width should be max-w-7xl or max-w-6xl with mx-auto",
                        "Card/component internal padding: p-6 minimum, p-8 preferred",
                        "Flex/grid gaps between items: gap-6 minimum, gap-8 preferred"
                    ]
                },
                {
                    name: "Interactive & Visual Affordances",
                    constraints: [
                        "Primary CTA buttons must be at least text-lg px-8 py-4 (ensure 44x44px minimum touch target)",
                        "Add hover:opacity-90 or hover:bg-primary/90 to all buttons",
                        "Add transition-colors duration-200 to interactive elements",
                        "Ensure primary CTA has 4.5:1 contrast ratio (use bg-primary text-primary-foreground)",
                        "Cards: add border border-border and rounded-lg minimum",
                        "Subtle elevation: use shadow-sm for cards, shadow-md for elevated elements (NO shadow-2xl or drop-shadow-xl)"
                    ]
                }
            ];
            for (const pass of passes) {
                console.log(chalk_1.default.gray(`     → [Pass: ${pass.name}] Refining ${skeleton.name}...`));
                const constraintsList = pass.constraints.map((c, i) => `${i + 1}. ${c}`).join("\n");
                const prompt = `You are a design refinement agent specializing in Tailwind CSS and accessibility.
You will refine the React component code below to apply SPECIFIC, MEASURABLE improvements.

REFINEMENT PASS: ${pass.name}

CONSTRAINTS (MUST follow ALL):
${constraintsList}

RULES:
1. ONLY modify Tailwind CSS class names
2. Keep HTML structure, React hooks, logic, imports, and exports EXACTLY unchanged
3. DO NOT add decorative elements or change component functionality
4. Use ONLY the constraints listed above - NO subjective aesthetic decisions
5. Every change must be measurable (e.g., "increase from text-2xl to text-4xl")

❌ FORBIDDEN TERMS (do NOT use these justifications):
- "modern", "premium", "beautiful", "elegant", "clean"
- "futuristic", "glassmorphic", "cohesive", "polished"
- Any vague aesthetic language

✅ ALLOWED: Specific Tailwind utilities matching the constraints above

Original Component Code:
\`\`\`tsx
${currentCode}
\`\`\`

Return ONLY the updated TypeScript React component code.`;
                const result = await this.aiCore.generateText(prompt, { temperature: 0.2 });
                currentCode = this.cleanCodeBlock(result);
            }
            await fs.writeFile(skeleton.file, currentCode);
        }
        this.state.stage = "CLASSNAME_REFINED";
        await this.saveState();
        console.log(chalk_1.default.green(`   ✓ Constrained refinement completed for ${skels.length} components`));
    }
    async findNearestTsconfig(dir) {
        let currentDir = dir;
        while (currentDir.startsWith(this.projectPath)) {
            const tsconfigPath = path.join(currentDir, "tsconfig.json");
            if (await fs.pathExists(tsconfigPath)) {
                return tsconfigPath;
            }
            const parent = path.dirname(currentDir);
            if (parent === currentDir)
                break;
            currentDir = parent;
        }
        return null;
    }
    /**
     * Stage 12: Final Validation & Incremental Self-Healing
     */
    async validateAndHealComponents() {
        if (this.state.stage === "FINAL_VALIDATED" || this.state.stage === "SELF_HEALED") {
            console.log(chalk_1.default.gray("   → [Stage 12] Components already validated and healed. Skipping compiler pass."));
            return;
        }
        const maxHealingAttempts = 3;
        let attempt = 1;
        console.log(chalk_1.default.gray("   → [Stage 12] Configuring TypeScript compiler verification environment..."));
        const nearestTsconfigPath = await this.findNearestTsconfig(this.outputDir);
        const tsconfigPath = path.join(this.projectPath, ".mycontext/generated/tsconfig.landing.json");
        await fs.ensureDir(path.dirname(tsconfigPath));
        const tsconfig = {
            compilerOptions: {
                target: "es5",
                lib: ["dom", "dom.iterable", "esnext"],
                allowJs: true,
                skipLibCheck: true,
                strict: true,
                noEmit: true,
                esModuleInterop: true,
                module: "esnext",
                moduleResolution: "node",
                resolveJsonModule: true,
                isolatedModules: true,
                jsx: "preserve",
                incremental: true,
            },
            include: [
                path.relative(path.dirname(tsconfigPath), path.join(this.outputDir, "**/*.ts")),
                path.relative(path.dirname(tsconfigPath), path.join(this.outputDir, "**/*.tsx"))
            ],
            exclude: ["node_modules"]
        };
        if (nearestTsconfigPath) {
            tsconfig.extends = path.relative(path.dirname(tsconfigPath), nearestTsconfigPath);
            tsconfig.compilerOptions = {
                ...tsconfig.compilerOptions,
                strict: true,
                noEmit: true
            };
            const nextEnvPath = path.join(path.dirname(nearestTsconfigPath), "next-env.d.ts");
            if (await fs.pathExists(nextEnvPath)) {
                tsconfig.include.push(path.relative(path.dirname(tsconfigPath), nextEnvPath));
            }
        }
        await fs.writeJSON(tsconfigPath, tsconfig, { spaces: 2 });
        if (!this.state.report)
            this.state.report = [];
        const runCwd = nearestTsconfigPath ? path.dirname(nearestTsconfigPath) : this.projectPath;
        while (attempt <= maxHealingAttempts) {
            console.log(chalk_1.default.gray(`   → [Stage 12] Running TypeScript compilation checks (Attempt ${attempt}/${maxHealingAttempts})...`));
            try {
                await execAsync(`npx tsc --noEmit --project "${tsconfigPath}"`, { cwd: runCwd });
                console.log(chalk_1.default.green(`   → [Stage 12] Type-check validation passed cleanly!`));
                break;
            }
            catch (error) {
                const stdout = error.stdout || "";
                const stderr = error.stderr || "";
                const fullError = stdout + "\n" + stderr;
                console.log(chalk_1.default.yellow(`   → [Stage 12] TypeScript validation errors detected. Preparing self-healing...`));
                // Remove ANSI color codes
                const cleanErrorLines = fullError
                    .replace(/\x1b\[[0-9;]*m/g, "")
                    .split("\n")
                    .filter(line => line.trim().length > 0);
                const actionableError = cleanErrorLines.join("\n");
                if (!actionableError.includes("error TS")) {
                    // If there are no real typescript errors reported, break
                    break;
                }
                // Extract failed files
                const fileRegex = /^([^(]+?\.(?:tsx|ts))\(\d+,\d+\): error (TS\d+):/gm;
                const failedFiles = new Set();
                let match;
                while ((match = fileRegex.exec(actionableError)) !== null) {
                    if (match[1]) {
                        const rawPath = match[1].trim();
                        const resolvedPath = path.resolve(runCwd, rawPath);
                        if (await fs.pathExists(resolvedPath) && resolvedPath.startsWith(this.outputDir)) {
                            failedFiles.add(resolvedPath);
                        }
                        else {
                            const altPath = path.resolve(this.projectPath, rawPath);
                            if (await fs.pathExists(altPath) && altPath.startsWith(this.outputDir)) {
                                failedFiles.add(altPath);
                            }
                        }
                    }
                }
                if (failedFiles.size === 0) {
                    console.log(chalk_1.default.yellow("   → [Stage 12] No compilation errors found in our generated components. Validation passes."));
                    break;
                }
                console.log(chalk_1.default.yellow(`   → [Stage 12] Found compilation issues in: ${Array.from(failedFiles).map(f => path.basename(f)).join(", ")}`));
                // Heal each failed file
                for (const absoluteFilePath of failedFiles) {
                    const fileBasename = path.basename(absoluteFilePath);
                    const fileErrors = cleanErrorLines
                        .filter((line) => line.includes(fileBasename))
                        .join("\n");
                    if (!fileErrors)
                        continue;
                    console.log(chalk_1.default.gray(`     → [Healer] Resolving TS issues in ${fileBasename}...`));
                    // Read relevant TSX/TS files in outputDir for healer context
                    const allFiles = await fs.readdir(this.outputDir);
                    const tsxFiles = allFiles.filter(f => f.endsWith(".tsx") || f.endsWith(".ts"));
                    let projectFilesContext = "";
                    for (const file of tsxFiles) {
                        const componentName = path.basename(file, path.extname(file));
                        const isTargetFile = absoluteFilePath.endsWith(file);
                        const isMentioned = fileErrors.includes(file) || fileErrors.includes(componentName);
                        if (isTargetFile || isMentioned) {
                            const filePath = path.join(this.outputDir, file);
                            const content = await fs.readFile(filePath, "utf8");
                            projectFilesContext += `\n--- FILE: ${file} ---\n${content}\n`;
                        }
                    }
                    this.state.report.push({
                        stage: "VALIDATION_HEALING",
                        attempt,
                        file: fileBasename,
                        error: fileErrors,
                        status: "healing"
                    });
                    const currentCode = await fs.readFile(absoluteFilePath, "utf8");
                    const prompt = `You are an expert TypeScript developer. Your React/Next.js code failed to compile.
Fix the compiler errors in this React component.

Here is the context of all the generated landing page components in this project:
${projectFilesContext}

Here is the Project Context Manifest:
${JSON.stringify(this.state.projectContext, null, 2)}

Here is the Narrative Manifest:
${JSON.stringify(this.state.narrative, null, 2)}

Compiler Errors for ${fileBasename}:
${fileErrors}

Constraints:
1. ONLY fix the TypeScript/reference/prop errors. Do NOT change the layout or Tailwind classes unless absolutely necessary to fix the error.
2. If a variable or a prop is missing, check the other files in the project or the narrative manifest to see if it should be passed from the parent component (page.tsx) or defined as a mock local constant.
3. Return ONLY the fully updated, fixed TSX code for ${fileBasename}.
4. Do NOT output code for any other files.
5. CRITICAL: Do NOT write any conversational explanation, intro, or outro text before or after the code block. Your response must contain ONLY the valid TSX code, enclosed in a single code block starting with \`\`\`tsx and ending with \`\`\`. Any text outside the code block will cause compilation failure.
6. CRITICAL: Ensure the code has valid syntax. Do not output truncated code or comments indicating placeholders like '// ... rest of code'. The code must be complete and compile perfectly.

Original Component Code for ${fileBasename}:
\`\`\`tsx
${currentCode}
\`\`\`
`;
                    const result = await this.aiCore.generateText(prompt, { temperature: 0.1 });
                    const fixedCode = this.cleanCodeBlock(result);
                    await fs.writeFile(absoluteFilePath, fixedCode);
                    // Mark as healed in report
                    const reportEntry = this.state.report[this.state.report.length - 1];
                    reportEntry.status = "healed";
                    console.log(chalk_1.default.green(`     → [Healer] Wrote compiler healing patch to ${fileBasename}.`));
                }
                attempt++;
                if (attempt > maxHealingAttempts) {
                    throw new Error(`Validation failed after ${maxHealingAttempts} healing attempts. Last errors:\n${fullError}`);
                }
            }
        }
        this.state.stage = attempt > 1 ? "SELF_HEALED" : "FINAL_VALIDATED";
        await this.saveState();
        if (attempt > 1) {
            console.log(chalk_1.default.green(`   ✓ Self-healing completed after ${attempt - 1} healing attempt(s)`));
        }
    }
    getCompilationSummary() {
        const sections = this.state.pageManifest?.sections || [];
        const skeletons = this.state.skeletons || [];
        const report = this.state.report || [];
        let summary = `## Landing Page Compilation Summary\n\n`;
        summary += `Successfully built and compiled the landing page under **${this.outputDir}**.\n\n`;
        summary += `### 🏗️ Component Inventory\n`;
        for (const section of sections) {
            const skel = skeletons.find(s => s.id === section.id);
            const fileName = skel ? path.basename(skel.file) : `${section.name}.tsx`;
            summary += `- **${section.name}** (\`${fileName}\`)\n`;
            summary += `  - *Purpose:* ${section.purpose}\n`;
            summary += `  - *Content:* ${section.contentRequired.join(", ")}\n`;
        }
        summary += `\n`;
        summary += `### 🎨 Design System & Layout\n`;
        summary += `- **Layout Intent:** *${this.state.pageManifest?.layoutIntent || "N/A"}*\n`;
        summary += `- **Responsive Rules:**\n`;
        for (const rule of this.state.pageManifest?.responsiveRules || []) {
            summary += `  - ${rule}\n`;
        }
        summary += `\n`;
        if (report.length > 0) {
            summary += `### 🔧 Self-Healing Audit Trail\n`;
            for (const entry of report) {
                const errorSummary = entry.error.split("\n")[0] || "TypeScript compiler error";
                summary += `- **Attempt ${entry.attempt} for \`${entry.file}\`:**\n`;
                summary += `  - *Status:* **${entry.status}**\n`;
                summary += `  - *Details:* \`${errorSummary}\`\n`;
            }
            summary += `\n`;
        }
        else {
            summary += `### 🔧 Self-Healing Audit Trail\n`;
            summary += `- No compilation issues encountered. All components type-checked cleanly on the first pass!\n\n`;
        }
        summary += `### 🚀 Next Steps\n`;
        summary += `1. **Run Dev Server:** Start your dev environment using \`pnpm run dev\` or \`npm run dev\`.\n`;
        summary += `2. **Verify Layout:** Visit the routes at your Next.js site to view the generated components.\n`;
        summary += `3. **Run Doctor:** Run \`mycontext doctor\` to ensure your Living Brain and source tree remain aligned.\n`;
        return summary;
    }
    /**
     * Advance one stage in the pipeline (NEW 14-stage pipeline)
     */
    async advance() {
        switch (this.state.stage) {
            case "INIT":
                await this.performBaselineCheck();
                break;
            case "BASELINE_CHECK":
                await this.generateProjectContext();
                break;
            case "CONTEXT_GENERATED":
                await this.generateNarrative();
                break;
            case "NARRATIVE_GENERATED":
                await this.generateSectionManifest();
                break;
            case "SECTION_MANIFEST_GENERATED":
                await this.generateComponentInventory();
                break;
            case "COMPONENT_INVENTORY_GENERATED":
                await this.generatePrimitiveMapping();
                break;
            case "PRIMITIVE_MAPPING_GENERATED":
                // Content schema generation would go here when implemented
                // For now, skip to skeleton generation
                await this.generateComponentSkeletons();
                break;
            case "CONTENT_SCHEMA_GENERATED":
                await this.generateComponentSkeletons();
                break;
            case "SKELETON_GENERATED":
                await this.populateContent();
                break;
            case "CONTENT_POPULATED":
                await this.validateSections();
                break;
            case "SECTION_VALIDATED":
                await this.refineComponents();
                break;
            case "CLASSNAME_REFINED":
                await this.validateAndHealComponents();
                break;
            case "FINAL_VALIDATED":
            case "SELF_HEALED":
                // Done
                break;
        }
        return this.state;
    }
    /**
     * Benchmark mode: Generate direct-prompt baseline landing page
     */
    async generateDirectPromptBaseline(context, narrative) {
        const ctx = context || this.state.projectContext;
        const nar = narrative || this.state.narrative;
        if (!ctx || !nar)
            throw new Error("Context and Narrative are required for baseline");
        const baselineDir = path.join(path.dirname(this.outputDir), "landing-page-baseline");
        await fs.ensureDir(baselineDir);
        const prompt = `You are a frontend developer asked to generate a single-file, beautiful landing page for this project.

Context:
${JSON.stringify(ctx, null, 2)}

Narrative strategy:
${JSON.stringify(nar, null, 2)}

Create a complete React component (suitable for Next.js) that renders the entire landing page. Design it directly using Tailwind CSS classes. Make it beautiful, modern, and futuristic.

Return ONLY the code for this single-file component (e.g. \`page.tsx\`).`;
        const code = await this.aiCore.generateText(prompt, { temperature: 0.7 });
        const cleanedCode = this.cleanCodeBlock(code);
        await fs.writeFile(path.join(baselineDir, "page.tsx"), cleanedCode);
    }
    async safeReadFile(relativeFilePath) {
        try {
            const fullPath = path.join(this.projectPath, relativeFilePath);
            if (await fs.pathExists(fullPath)) {
                return await fs.readFile(fullPath, "utf-8");
            }
        }
        catch { }
        return "";
    }
    async ensureShadcnUiStubs(uiDir) {
        await fs.ensureDir(uiDir);
        const stubs = {
            "button.tsx": `import * as React from "react"

export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
  size?: 'default' | 'sm' | 'lg' | 'icon';
}

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className = "", variant = "default", size = "default", ...props }, ref) => {
    const baseStyles = "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
    
    const variants = {
      default: "bg-primary text-primary-foreground shadow hover:bg-primary/95",
      destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
      outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
      secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
      ghost: "hover:bg-accent hover:text-accent-foreground",
      link: "text-primary underline-offset-4 hover:underline",
    }
    
    const sizes = {
      default: "h-9 px-4 py-2",
      sm: "h-8 rounded-md px-3 text-xs",
      lg: "h-10 rounded-md px-8",
      icon: "h-9 w-9",
    }
    
    const classes = \`\${baseStyles} \${variants[variant]} \${sizes[size]} \${className}\`
    
    return <button ref={ref} className={classes} {...props} />
  }
)
Button.displayName = "Button"`,
            "card.tsx": `import * as React from "react"

export const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
  ({ className = "", ...props }, ref) => (
    <div ref={ref} className={\`rounded-xl border bg-card text-card-foreground shadow \${className}\`} {...props} />
  )
)
Card.displayName = "Card"

export const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
  ({ className = "", ...props }, ref) => (
    <div ref={ref} className={\`flex flex-col space-y-1.5 p-6 \${className}\`} {...props} />
  )
)
CardHeader.displayName = "CardHeader"

export const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
  ({ className = "", ...props }, ref) => (
    <h3 ref={ref} className={\`font-semibold leading-none tracking-tight text-xl \${className}\`} {...props} />
  )
)
CardTitle.displayName = "CardTitle"

export const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
  ({ className = "", ...props }, ref) => (
    <p ref={ref} className={\`text-sm text-muted-foreground \${className}\`} {...props} />
  )
)
CardDescription.displayName = "CardDescription"

export const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
  ({ className = "", ...props }, ref) => (
    <div ref={ref} className={\`p-6 pt-0 \${className}\`} {...props} />
  )
)
CardContent.displayName = "CardContent"

export const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
  ({ className = "", ...props }, ref) => (
    <div ref={ref} className={\`flex items-center p-6 pt-0 \${className}\`} {...props} />
  )
)
CardFooter.displayName = "CardFooter"`,
            "badge.tsx": `import * as React from "react"

export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {
  variant?: 'default' | 'secondary' | 'destructive' | 'outline';
}

export function Badge({ className = "", variant = "default", ...props }: BadgeProps) {
  const baseStyles = "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
  const variants = {
    default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
    secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
    destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
    outline: "text-foreground",
  }
  return <div className={\`\${baseStyles} \${variants[variant]} \${className}\`} {...props} />
}`,
            "accordion.tsx": `import * as React from "react"

export const Accordion: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className = "", ...props }) => (
  <div className={\`space-y-1 \${className}\`} {...props}>{children}</div>
)

export interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {
  value: string;
}

export const AccordionItem: React.FC<AccordionItemProps> = ({ children, className = "", ...props }) => (
  <div className={\`border-b \${className}\`} {...props}>{children}</div>
)

export const AccordionTrigger: React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>> = ({ children, className = "", ...props }) => {
  const [isOpen, setIsOpen] = React.useState(false)
  return (
    <button
      type="button"
      onClick={() => setIsOpen(!isOpen)}
      className={\`flex w-full items-center justify-between py-4 text-sm font-medium transition-all hover:underline \${className}\`}
      {...props}
    >
      {children}
      <span className={\`ml-2 text-xs transition-transform duration-200 \${isOpen ? "rotate-180" : ""}\`}>▼</span>
    </button>
  )
}

export const AccordionContent: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className = "", ...props }) => (
  <div className={\`pb-4 pt-0 text-sm text-muted-foreground \${className}\`} {...props}>{children}</div>
)`,
            "tabs.tsx": `import * as React from "react"

export interface TabsProps extends React.HTMLAttributes<HTMLDivElement> {
  defaultValue?: string;
  value?: string;
  onValueChange?: (value: string) => void;
}

export const Tabs: React.FC<TabsProps> = ({ children, defaultValue, className = "", ...props }) => {
  const [activeTab, setActiveTab] = React.useState(defaultValue)
  return (
    <div className={\`\${className}\`} {...props}>
      {React.Children.map(children, child => {
        if (React.isValidElement(child)) {
          return React.cloneElement(child as React.ReactElement<any>, { activeTab, setActiveTab })
        }
        return child;
      })}
    </div>
  )
}

export const TabsList: React.FC<React.HTMLAttributes<HTMLDivElement> & { activeTab?: string; setActiveTab?: (v: string) => void }> = ({ children, activeTab, setActiveTab, className = "", ...props }) => (
  <div className={\`inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground \${className}\`} {...props}>
    {React.Children.map(children, child => {
      if (React.isValidElement(child)) {
        return React.cloneElement(child as React.ReactElement<any>, { activeTab, setActiveTab })
      }
      return child;
    })}
  </div>
)

export interface TabsTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  value: string;
  activeTab?: string;
  setActiveTab?: (v: string) => void;
}

export const TabsTrigger: React.FC<TabsTriggerProps> = ({ children, value, activeTab, setActiveTab, className = "", ...props }) => {
  const isActive = activeTab === value
  return (
    <button
      type="button"
      onClick={() => setActiveTab?.(value)}
      className={\`inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 \${
        isActive ? "bg-background text-foreground shadow" : "hover:text-foreground"
      } \${className}\`}
      {...props}
    >
      {children}
    </button>
  )
}

export interface TabsContentProps extends React.HTMLAttributes<HTMLDivElement> {
  value: string;
  activeTab?: string;
}

export const TabsContent: React.FC<TabsContentProps> = ({ children, value, activeTab, className = "", ...props }) => {
  if (activeTab !== value) return null
  return <div className={\`mt-2 focus-visible:outline-none \${className}\`} {...props}>{children}</div>
}`,
            "skeleton.tsx": `import * as React from "react"

export function Skeleton({ className = "", ...props }: React.HTMLAttributes<HTMLDivElement>) {
  return <div className={\`animate-pulse rounded-md bg-muted \${className}\`} {...props} />
}`,
            "input.tsx": `import * as React from "react"

export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
  ({ className = "", type = "text", ...props }, ref) => (
    <input
      type={type}
      className={\`flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 \${className}\`}
      ref={ref}
      {...props}
    />
  )
)
Input.displayName = "Input"`,
            "textarea.tsx": `import * as React from "react"

export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
  ({ className = "", ...props }, ref) => (
    <textarea
      className={\`flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 \${className}\`}
      ref={ref}
      {...props}
    />
  )
)
Textarea.displayName = "Textarea"`,
            "label.tsx": `import * as React from "react"

export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {}

export const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
  ({ className = "", ...props }, ref) => (
    <label
      ref={ref}
      className={\`text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 \${className}\`}
      {...props}
    />
  )
)
Label.displayName = "Label"`,
            "carousel.tsx": `import * as React from "react"

export const Carousel: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className = "", ...props }) => (
  <div className={\`relative w-full \${className}\`} {...props}>{children}</div>
)

export const CarouselContent: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className = "", ...props }) => (
  <div className={\`flex gap-4 overflow-x-auto \${className}\`} {...props}>{children}</div>
)

export const CarouselItem: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className = "", ...props }) => (
  <div className={\`min-w-0 shrink-0 grow-0 basis-full \${className}\`} {...props}>{children}</div>
)

export const CarouselPrevious: React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>> = ({ className = "", ...props }) => (
  <button type="button" className={\`absolute left-4 top-1/2 -translate-y-1/2 h-8 w-8 rounded-full border bg-background \${className}\`} {...props}>◀</button>
)

export const CarouselNext: React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>> = ({ className = "", ...props }) => (
  <button type="button" className={\`absolute right-4 top-1/2 -translate-y-1/2 h-8 w-8 rounded-full border bg-background \${className}\`} {...props}>▶</button>
)`,
            "dialog.tsx": `import * as React from "react"

export const Dialog: React.FC<React.HTMLAttributes<HTMLDivElement> & { open?: boolean }> = ({ children, open = false, ...props }) => {
  if (!open) return null
  return <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50" {...props}>{children}</div>
}

export const DialogContent: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ children, className = "", ...props }) => (
  <div className={\`relative bg-background p-6 shadow-lg rounded-lg border max-w-lg w-full \${className}\`} {...props}>{children}</div>
)

export const DialogHeader: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ className = "", ...props }) => (
  <div className={\`flex flex-col space-y-1.5 text-center sm:text-left \${className}\`} {...props} />
)

export const DialogTitle: React.FC<React.HTMLAttributes<HTMLHeadingElement>> = ({ className = "", ...props }) => (
  <h2 className={\`text-lg font-semibold leading-none tracking-tight \${className}\`} {...props} />
)

export const DialogDescription: React.FC<React.HTMLAttributes<HTMLParagraphElement>> = ({ className = "", ...props }) => (
  <p className={\`text-sm text-muted-foreground \${className}\`} {...props} />
)`
        };
        for (const [filename, content] of Object.entries(stubs)) {
            const stubPath = path.join(uiDir, filename);
            if (!(await fs.pathExists(stubPath))) {
                await fs.writeFile(stubPath, content);
            }
        }
    }
    cleanCodeBlock(code) {
        const trimmed = code.trim();
        // Use regex to locate and extract any code blocks anywhere in the text
        const match = /```(?:tsx|typescript|javascript|js|json)?\n([\s\S]*?)```/.exec(trimmed);
        if (match && match[1]) {
            return match[1].trim();
        }
        // Fallback to strict prefix matching if regex match fails
        let clean = trimmed;
        if (clean.startsWith("```tsx")) {
            clean = clean.replace(/^```tsx\s*/m, "").replace(/\s*```$/m, "");
        }
        else if (clean.startsWith("```typescript")) {
            clean = clean.replace(/^```typescript\s*/m, "").replace(/\s*```$/m, "");
        }
        else if (clean.startsWith("```javascript")) {
            clean = clean.replace(/^```javascript\s*/m, "").replace(/\s*```$/m, "");
        }
        else if (clean.startsWith("```")) {
            clean = clean.replace(/^```\s*/m, "").replace(/\s*```$/m, "");
        }
        return clean;
    }
}
exports.LandingPageOrchestrator = LandingPageOrchestrator;
//# sourceMappingURL=LandingPageOrchestrator.js.map