"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.BlueprintCommand = void 0;
const chalk_1 = __importDefault(require("chalk"));
const prompts_1 = __importDefault(require("prompts"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs-extra"));
const BlueprintLoader_1 = require("../services/BlueprintLoader");
const BlueprintEngine_1 = require("../services/BlueprintEngine");
function resolveYesOption(options, program) {
    if (options?.yes)
        return true;
    if (typeof options?.opts === "function" && options.opts().yes)
        return true;
    if (program && typeof program.opts === "function" && program.opts().yes)
        return true;
    return false;
}
class BlueprintCommand {
    register(program) {
        this.program = program;
        const group = program
            .command("blueprint")
            .description("🏗️ Verify, align, and scaffold project blueprints");
        // 1. mycontext blueprint list
        group
            .command("list")
            .description("List all available blueprints (built-in and workspace-local)")
            .action(async () => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const list = await loader.listBlueprints();
                console.log(chalk_1.default.bold("\n📋 Available Architecture Blueprints"));
                console.log(chalk_1.default.dim("─".repeat(70)));
                if (list.length === 0) {
                    console.log(chalk_1.default.yellow("  No blueprints found."));
                }
                else {
                    for (const bp of list) {
                        console.log(`  ${chalk_1.default.cyan(bp.id.padEnd(20))} [v${bp.version}] - ${bp.name}`);
                        if (bp.description) {
                            console.log(chalk_1.default.gray(`    ${bp.description}`));
                        }
                        console.log();
                    }
                }
                console.log(chalk_1.default.dim("─".repeat(70)));
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ List failed: ${error.message}`));
                process.exit(1);
            }
        });
        // 2. mycontext blueprint check <blueprint>
        group
            .command("check <blueprint>")
            .description("Check workspace compliance against a blueprint")
            .option("--json", "Output results in JSON format")
            .option("--fail-on-high", "Exit with code 1 if any high severity violations are found")
            .action(async (blueprintId, options) => {
            try {
                const isJson = options?.json || options?.opts?.().json || false;
                const failOnHigh = options?.failOnHigh || options?.opts?.().failOnHigh || false;
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                const engine = new BlueprintEngine_1.BlueprintEngine();
                const report = await engine.check(blueprint);
                // Cache the conformance status
                try {
                    const cacheDir = path.join(process.cwd(), ".mycontext", "cache");
                    await fs.ensureDir(cacheDir);
                    const cachePath = path.join(cacheDir, "blueprint-status.json");
                    await fs.writeJson(cachePath, {
                        blueprint: blueprint.blueprintId,
                        score: report.score,
                        checkedAt: new Date().toISOString()
                    }, { spaces: 2 });
                }
                catch (e) {
                    // Ignore cache write failures
                }
                if (isJson) {
                    console.log(JSON.stringify(report, null, 2));
                    if (failOnHigh && report.violations.some(v => v.severity === "high")) {
                        process.exit(1);
                    }
                    return;
                }
                console.log(chalk_1.default.bold(`\n🔍 Compliance Check: ${blueprint.name} (v${blueprint.version})`));
                console.log(chalk_1.default.dim("─".repeat(70)));
                // Display score with color indicators
                let scoreColor = chalk_1.default.green;
                let scoreBadge = "✓ EXCELLENT";
                if (report.score < 50) {
                    scoreColor = chalk_1.default.red;
                    scoreBadge = "🚨 CRITICAL GAP";
                }
                else if (report.score < 100) {
                    scoreColor = chalk_1.default.yellow;
                    scoreBadge = "⚠️ VIOLATIONS PRESENT";
                }
                console.log(`  Compliance Score: ${scoreColor.bold(`${report.score}/100`)} [${scoreBadge}]`);
                console.log(chalk_1.default.dim("─".repeat(70)));
                if (report.violations.length === 0) {
                    console.log(chalk_1.default.green("  🎉 Clean workspace! 100% compliant with blueprint standards."));
                }
                else {
                    console.log(chalk_1.default.yellow(`  Detected ${report.violations.length} deviations:`));
                    console.log();
                    for (const v of report.violations) {
                        const icon = v.severity === "high" ? chalk_1.default.red("✗") : v.severity === "medium" ? chalk_1.default.yellow("✗") : chalk_1.default.gray("✗");
                        const severityText = v.severity.toUpperCase();
                        const typeText = chalk_1.default.gray(`[${v.type}]`);
                        const autofixText = v.autoFixable
                            ? v.requiresHumanReview
                                ? chalk_1.default.blue(" (Requires Human Review)")
                                : chalk_1.default.green(" (Auto-fixable)")
                            : chalk_1.default.dim(" (Requires Manual Fix)");
                        console.log(`  ${icon} [${chalk_1.default.bold(severityText)}] ${typeText} ${v.description}${autofixText}`);
                        if (v.path) {
                            console.log(chalk_1.default.gray(`     Location: ${v.path}`));
                        }
                    }
                }
                console.log();
                if (failOnHigh && report.violations.some(v => v.severity === "high")) {
                    console.error(chalk_1.default.red("❌ Fail-on-high constraint triggered: High severity violations found in workspace.\n"));
                    process.exit(1);
                }
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ Check failed: ${error.message}`));
                process.exit(1);
            }
        });
        // 3. mycontext blueprint plan <blueprint>
        group
            .command("plan <blueprint>")
            .description("Generate the operation alignment plan without writing changes")
            .action(async (blueprintId) => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                const engine = new BlueprintEngine_1.BlueprintEngine();
                const report = await engine.check(blueprint);
                const ops = engine.plan(report, blueprint);
                console.log(chalk_1.default.bold(`\n📋 Proposed Operations Plan for: ${blueprint.blueprintId}`));
                console.log(chalk_1.default.dim("─".repeat(70)));
                if (ops.length === 0) {
                    console.log(chalk_1.default.green("  Workspace is fully aligned. No operations to generate."));
                }
                else {
                    for (const op of ops) {
                        // Deduce if it requires review
                        const pathParam = op.params.path;
                        const fileReq = blueprint.files?.required?.find(f => f.path === pathParam);
                        const reviewNeeded = fileReq?.requiresHumanReview ?? false;
                        const reviewBadge = reviewNeeded
                            ? chalk_1.default.red("[UNSAFE / REQUIRES REVIEW]")
                            : chalk_1.default.green("[SAFE AUTOFIX]");
                        console.log(`  ${chalk_1.default.cyan(op.type.padEnd(12))} - ${op.description}`);
                        console.log(`                 Safety: ${reviewBadge}`);
                        console.log();
                    }
                }
                console.log(chalk_1.default.dim("─".repeat(70)));
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ Plan failed: ${error.message}`));
                process.exit(1);
            }
        });
        // 4. mycontext blueprint align <blueprint>
        group
            .command("align <blueprint>")
            .description("Align workspace files against blueprint rules")
            .option("--yes", "Automatically execute safe fixes without interactive prompting")
            .option("--include-unsafe", "Include unsafe/review-required operations in the alignment plan")
            .option("--dry-run", "Output operations that would occur without modifying files")
            .action(async (blueprintId, options) => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                const engine = new BlueprintEngine_1.BlueprintEngine();
                const report = await engine.check(blueprint);
                const allOps = engine.plan(report, blueprint);
                if (allOps.length === 0) {
                    console.log(chalk_1.default.green("\n✓ Workspace is already aligned. No changes needed.\n"));
                    return;
                }
                const isYes = resolveYesOption(options, this.program);
                const isIncludeUnsafe = options?.includeUnsafe || options?.opts?.().includeUnsafe || false;
                const isDryRun = options?.dryRun || options?.opts?.().dryRun || false;
                // Filter safe vs unsafe operations
                const opsToRun = allOps.filter(op => {
                    const pathParam = op.params.path;
                    const fileReq = blueprint.files?.required?.find(f => f.path === pathParam);
                    const reviewNeeded = fileReq?.requiresHumanReview ?? false;
                    if (reviewNeeded && !isIncludeUnsafe) {
                        return false; // Skip if unsafe and user didn't request unsafe
                    }
                    return true;
                });
                const skippedUnsafeCount = allOps.length - opsToRun.length;
                if (opsToRun.length === 0) {
                    console.log(chalk_1.default.yellow(`\n⚠️  No safe operations to execute.`));
                    if (skippedUnsafeCount > 0) {
                        console.log(chalk_1.default.gray(`   Skipped ${skippedUnsafeCount} unsafe operations. Run with --include-unsafe to execute.`));
                    }
                    console.log();
                    return;
                }
                // Dry Run Mode
                if (isDryRun) {
                    console.log(chalk_1.default.cyan.bold("\n✨ Dry Run Alignment Preview:"));
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    for (const op of opsToRun) {
                        console.log(`  [Preview] ${chalk_1.default.cyan(op.type)} - ${op.description}`);
                    }
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    console.log(chalk_1.default.cyan(`  Total previewed: ${opsToRun.length} operations. 0 files modified.\n`));
                    return;
                }
                // Confirmation gating
                let confirmExecution = false;
                if (isYes) {
                    confirmExecution = true;
                    if (isIncludeUnsafe) {
                        console.log(chalk_1.default.red.bold("\n⚠️  WARNING: Executing safe AND unsafe fixes automatically without prompt.\n"));
                    }
                }
                else {
                    console.log(chalk_1.default.bold("\n⚙️  Candidate Operations for Alignment:"));
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    for (const op of opsToRun) {
                        const pathParam = op.params.path;
                        const fileReq = blueprint.files?.required?.find(f => f.path === pathParam);
                        const reviewNeeded = fileReq?.requiresHumanReview ?? false;
                        const safetyLabel = reviewNeeded ? chalk_1.default.red("UNSAFE") : chalk_1.default.green("SAFE");
                        console.log(`  [${safetyLabel}] ${op.description}`);
                    }
                    if (skippedUnsafeCount > 0) {
                        console.log(chalk_1.default.yellow(`\n  * Note: Skipping ${skippedUnsafeCount} unsafe operations. Pass --include-unsafe to include.`));
                    }
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    const answer = await (0, prompts_1.default)({
                        type: "confirm",
                        name: "execute",
                        message: `Apply these ${opsToRun.length} operations to align the workspace?`,
                        initial: true
                    });
                    confirmExecution = answer.execute;
                }
                if (!confirmExecution) {
                    console.log(chalk_1.default.yellow("\nAlignment aborted.\n"));
                    return;
                }
                // Run alignment execution
                console.log(chalk_1.default.blue("\n🏗️ Applying alignment updates..."));
                const results = await engine.executeAlign(opsToRun);
                let passed = 0;
                let failed = 0;
                results.forEach((res, i) => {
                    const op = opsToRun[i];
                    if (res.success) {
                        passed++;
                        console.log(`  ${chalk_1.default.green("✓")} ${op.description}`);
                    }
                    else {
                        failed++;
                        console.log(`  ${chalk_1.default.red("✗")} ${op.description} — ${res.error}`);
                    }
                });
                console.log(chalk_1.default.dim("─".repeat(70)));
                console.log(`  ${chalk_1.default.green(`${passed} applied`)}${failed > 0 ? ` · ${chalk_1.default.red(`${failed} failed`)}` : ""}`);
                // Post-alignment check
                console.log(chalk_1.default.gray("\nRunning post-alignment check..."));
                const postReport = await engine.check(blueprint);
                let postColor = postReport.score === 100 ? chalk_1.default.green : chalk_1.default.yellow;
                console.log(`  New Compliance Score: ${postColor.bold(`${postReport.score}/100`)}\n`);
            }
            catch (error) {
                console.error(chalk_1.default.red(`\n❌ Alignment failed: ${error.message}\n`));
                process.exit(1);
            }
        });
        // 5. mycontext blueprint scaffold <blueprint>
        group
            .command("scaffold <blueprint>")
            .description("Initialize baseline structural directories and templates from a blueprint")
            .option("--yes", "Do not prompt for scaffolding confirmation")
            .option("--dry-run", "Output scaffolding operations without writing changes")
            .action(async (blueprintId, options) => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                const engine = new BlueprintEngine_1.BlueprintEngine();
                const ops = engine.scaffold(blueprint);
                if (ops.length === 0) {
                    console.log(chalk_1.default.yellow("  No scaffolding configurations defined in this blueprint."));
                    return;
                }
                const isYes = resolveYesOption(options, this.program);
                const isDryRun = options?.dryRun || options?.opts?.().dryRun || false;
                if (isDryRun) {
                    console.log(chalk_1.default.cyan.bold(`\n✨ Dry Run Scaffolding Preview for ${blueprint.name}:`));
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    for (const op of ops) {
                        console.log(`  [Preview] ${chalk_1.default.cyan(op.type)} - ${op.description}`);
                    }
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    console.log(chalk_1.default.cyan(`  Total scaffold preview: ${ops.length} operations. 0 files written.\n`));
                    return;
                }
                let confirmScaffold = false;
                if (isYes) {
                    confirmScaffold = true;
                }
                else {
                    console.log(chalk_1.default.bold(`\n🏗️  Scaffolding Template: ${blueprint.name}`));
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    for (const op of ops) {
                        console.log(`  + ${op.description}`);
                    }
                    console.log(chalk_1.default.dim("─".repeat(70)));
                    const answer = await (0, prompts_1.default)({
                        type: "confirm",
                        name: "scaffold",
                        message: `Initialize these ${ops.length} structure changes in your current project?`,
                        initial: true
                    });
                    confirmScaffold = answer.scaffold;
                }
                if (!confirmScaffold) {
                    console.log(chalk_1.default.yellow("\nScaffolding aborted.\n"));
                    return;
                }
                console.log(chalk_1.default.blue("\n🏗️ Generating project skeleton..."));
                const results = await engine.executeAlign(ops);
                let passed = 0;
                let failed = 0;
                results.forEach((res, i) => {
                    const op = ops[i];
                    if (res.success) {
                        passed++;
                        console.log(`  ${chalk_1.default.green("✓")} ${op.description}`);
                    }
                    else {
                        failed++;
                        console.log(`  ${chalk_1.default.red("✗")} ${op.description} — ${res.error}`);
                    }
                });
                console.log(chalk_1.default.dim("─".repeat(70)));
                console.log(`  Scaffolding complete: ${chalk_1.default.green(`${passed} applied`)}${failed > 0 ? ` · ${chalk_1.default.red(`${failed} failed`)}` : ""}\n`);
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ Scaffolding failed: ${error.message}`));
                process.exit(1);
            }
        });
        // 6. mycontext blueprint review <blueprint>
        group
            .command("review <blueprint>")
            .description("Review violations requiring manual human intervention")
            .action(async (blueprintId) => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                const engine = new BlueprintEngine_1.BlueprintEngine();
                const report = await engine.check(blueprint);
                console.log(chalk_1.default.bold(`\n⚠️  Human Review Report: ${blueprint.name}`));
                console.log(chalk_1.default.dim("─".repeat(70)));
                const reviewRequiredViolations = report.violations.filter(v => v.requiresHumanReview || !v.autoFixable);
                if (reviewRequiredViolations.length === 0) {
                    console.log(chalk_1.default.green("  🎉 Zero deviations require manual human review!"));
                    console.log(chalk_1.default.gray("  (Any remaining deviations can be automatically aligned using 'mycontext blueprint align')"));
                }
                else {
                    console.log(chalk_1.default.red(`  Detected ${reviewRequiredViolations.length} gaps requiring human verification:`));
                    console.log();
                    for (const v of reviewRequiredViolations) {
                        const icon = chalk_1.default.red("✗");
                        const fixability = v.autoFixable ? chalk_1.default.blue(" (Autofix available but requires review)") : chalk_1.default.red(" (Manual review/fix only)");
                        console.log(`  ${icon} [${v.severity.toUpperCase()}] ${v.description}${fixability}`);
                        if (v.path) {
                            console.log(chalk_1.default.gray(`     Location: ${v.path}`));
                        }
                        if (v.expected) {
                            console.log(chalk_1.default.gray("     Expected alignment signature:"));
                            console.log(chalk_1.default.dim(v.expected.split("\n").map(l => `       | ${l}`).join("\n")));
                        }
                        console.log();
                    }
                }
                console.log(chalk_1.default.dim("─".repeat(70)));
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ Review failed: ${error.message}`));
                process.exit(1);
            }
        });
        // 7. mycontext blueprint export <blueprint>
        group
            .command("export <blueprint>")
            .description("Export the resolved normalized blueprint structure as JSON")
            .action(async (blueprintId) => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                console.log(JSON.stringify(blueprint, null, 2));
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ Export failed: ${error.message}`));
                process.exit(1);
            }
        });
        // 8. mycontext blueprint init <blueprint>
        group
            .command("init <blueprint>")
            .description("Install / initialize a blueprint locally under .mycontext/blueprints/")
            .action(async (blueprintId) => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                const localDir = path.join(process.cwd(), ".mycontext", "blueprints");
                await fs.ensureDir(localDir);
                const destPath = path.join(localDir, `${blueprint.blueprintId}.json`);
                await fs.writeJson(destPath, blueprint, { spaces: 2 });
                console.log(chalk_1.default.green(`\n✓ Blueprint '${blueprint.blueprintId}' initialized locally at:`));
                console.log(chalk_1.default.gray(`  .mycontext/blueprints/${blueprint.blueprintId}.json\n`));
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ Init failed: ${error.message}`));
                process.exit(1);
            }
        });
        // 9. mycontext blueprint doctor <blueprint>
        group
            .command("doctor <blueprint>")
            .description("Diagnose workspace compliance, show manual review points, and auto-fix safe items")
            .option("--yes", "Auto-execute safe fixes without interactive prompting")
            .action(async (blueprintId, options) => {
            try {
                const loader = new BlueprintLoader_1.BlueprintLoader();
                const blueprint = await loader.loadBlueprint(blueprintId);
                const engine = new BlueprintEngine_1.BlueprintEngine();
                console.log(chalk_1.default.bold(`\n🩺 Blueprint Doctor: Diagnosing ${blueprint.name}`));
                console.log(chalk_1.default.dim("─".repeat(70)));
                const report = await engine.check(blueprint);
                let scoreColor = chalk_1.default.green;
                if (report.score < 50)
                    scoreColor = chalk_1.default.red;
                else if (report.score < 100)
                    scoreColor = chalk_1.default.yellow;
                console.log(`  Current Compliance Score: ${scoreColor.bold(`${report.score}/100`)}`);
                const reviewRequired = report.violations.filter(v => v.requiresHumanReview || !v.autoFixable);
                const autofixableSafe = report.violations.filter(v => v.autoFixable && !v.requiresHumanReview);
                console.log(chalk_1.default.dim("─".repeat(70)));
                if (report.violations.length === 0) {
                    console.log(chalk_1.default.green("  🎉 Clean workspace! 100% compliant with blueprint standards.\n"));
                    return;
                }
                // Print review required issues
                if (reviewRequired.length > 0) {
                    console.log(chalk_1.default.red(`  ⚠️  Manual Human Review Required (${reviewRequired.length} issues):`));
                    for (const v of reviewRequired) {
                        console.log(`    ✗ [${v.severity.toUpperCase()}] ${v.description}`);
                        if (v.path)
                            console.log(chalk_1.default.gray(`      Location: ${v.path}`));
                    }
                    console.log();
                }
                // Align safe fixes if any
                if (autofixableSafe.length > 0) {
                    console.log(chalk_1.default.green(`  🔧 Safe Autofixes Available (${autofixableSafe.length} issues):`));
                    for (const v of autofixableSafe) {
                        console.log(`    ✓ [${v.severity.toUpperCase()}] ${v.description}`);
                    }
                    console.log();
                    const isYes = resolveYesOption(options, this.program);
                    let confirmExecution = false;
                    if (isYes) {
                        confirmExecution = true;
                    }
                    else {
                        const answer = await (0, prompts_1.default)({
                            type: "confirm",
                            name: "execute",
                            message: "Do you want Doctor to auto-fix these safe violations?",
                            initial: true
                        });
                        confirmExecution = answer.execute;
                    }
                    if (confirmExecution) {
                        const opsToRun = engine.plan(report, blueprint).filter(op => {
                            const pathParam = op.params.path;
                            const fileReq = blueprint.files?.required?.find(f => f.path === pathParam);
                            return !(fileReq?.requiresHumanReview ?? false);
                        });
                        console.log(chalk_1.default.blue("\n🏗️ Applying safe doctor fixes..."));
                        const results = await engine.executeAlign(opsToRun);
                        let passed = 0;
                        results.forEach((res, i) => {
                            if (res.success) {
                                passed++;
                                console.log(`    ${chalk_1.default.green("✓")} ${opsToRun[i]?.description}`);
                            }
                        });
                        console.log(chalk_1.default.gray("\nRe-evaluating compliance..."));
                        const postReport = await engine.check(blueprint);
                        scoreColor = postReport.score === 100 ? chalk_1.default.green : chalk_1.default.yellow;
                        console.log(`    New Compliance Score: ${scoreColor.bold(`${postReport.score}/100`)}`);
                    }
                }
                console.log();
            }
            catch (error) {
                console.error(chalk_1.default.red(`❌ Doctor failed: ${error.message}`));
                process.exit(1);
            }
        });
    }
}
exports.BlueprintCommand = BlueprintCommand;
//# sourceMappingURL=blueprint.js.map