import { defineCommand, useLoader } from '@kb-labs/sdk';
import { buildDependencyGraph, getBuildOrderForPackage, topologicalSort, findCircularDependencies, getReverseDependencies, getImpactAnalysis } from '@kb-labs/quality-core/graph';
import { CACHE_KEYS } from '@kb-labs/quality-contracts';
import { checkBuilds } from '@kb-labs/quality-core/builds';
import { runTests } from '@kb-labs/quality-core/tests';
import { analyzeTypes } from '@kb-labs/quality-core/types';
import { listBackups, restoreFromBackup, scanDeadFiles, removeDeadFiles } from '@kb-labs/quality-core/dead-code';
import fs from 'fs';
import path3 from 'path';

// src/cli/commands/build-order.ts
var build_order_default = defineCommand({
  id: "quality:build-order",
  description: "Calculate build order using topological sort",
  handler: {
    async execute(ctx, input) {
      const { ui } = ctx;
      const flags = input.flags ?? input;
      const graph = buildDependencyGraph(ctx.cwd);
      let result;
      if (flags.package) {
        result = getBuildOrderForPackage(graph, flags.package);
      } else {
        result = topologicalSort(graph);
      }
      if (result.circular.length > 0) {
        ui?.error?.(
          `Found ${result.circular.length} circular dependencies. Build order cannot be determined.`
        );
        outputCircularDependencies(result.circular, ui);
        return { exitCode: 1, result };
      }
      outputBuildOrder(result, flags, ui);
      return { exitCode: 0, result };
    }
  }
});
function outputBuildOrder(result, flags, ui) {
  if (flags.json) {
    ui?.json?.(result);
    return;
  }
  if (flags.script) {
    ui?.write?.("#!/bin/bash");
    ui?.write?.("# Generated build script");
    ui?.write?.("set -e");
    ui?.write?.("");
    for (let i = 0; i < result.layers.length; i++) {
      const layer = result.layers[i];
      if (!layer) {
        continue;
      }
      ui?.write?.(`# Layer ${i + 1} (${layer.length} packages)`);
      for (const pkg of layer) {
        ui?.write?.(`pnpm --filter "${pkg}" run build`);
      }
      ui?.write?.("");
    }
    return;
  }
  const sections = [];
  if (flags.layers) {
    const layerItems = [];
    for (let i = 0; i < result.layers.length; i++) {
      const layer = result.layers[i];
      if (!layer) {
        continue;
      }
      layerItems.push(`Layer ${i + 1}: ${layer.length} packages (can build in parallel)`);
      for (const pkg of layer) {
        layerItems.push(`  \u2022 ${pkg}`);
      }
      layerItems.push("");
    }
    sections.push({ header: "Build Layers", items: layerItems });
  } else {
    const orderItems = result.sorted.map((pkg, idx) => `${idx + 1}. ${pkg}`);
    sections.push({ header: "Build Order", items: orderItems });
  }
  sections.push({
    header: "Summary",
    items: [
      `Total packages: ${result.sorted.length}`,
      `Build layers: ${result.layers.length}`,
      `Circular dependencies: ${result.circular.length}`
    ]
  });
  const title = flags.package ? `\u{1F4E6} Build Order for ${flags.package}` : "\u{1F4E6} Monorepo Build Order";
  ui?.success?.("Build order calculated successfully", {
    title,
    sections
  });
}
function outputCircularDependencies(cycles, ui) {
  const sections = [];
  for (let i = 0; i < cycles.length; i++) {
    const cycle = cycles[i];
    if (!cycle) {
      continue;
    }
    sections.push({
      header: `Cycle ${i + 1}`,
      items: cycle.map((pkg, idx) => {
        if (idx === cycle.length - 1) {
          const firstPkg = cycle[0];
          return `  ${pkg} \u2192 ${firstPkg ?? "?"} (circular!)`;
        }
        return `  ${pkg} \u2192`;
      })
    });
  }
  ui?.error?.("Circular dependencies detected", {
    title: "\u26A0\uFE0F Circular Dependencies",
    sections
  });
}
var check_builds_default = defineCommand({
  id: "quality:check-builds",
  description: "Check build status across monorepo",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      const cacheKey = `${CACHE_KEYS.BUILDS}:${flags.package || "all"}`;
      if (!flags.refresh) {
        const cached = await platform.cache.get(cacheKey);
        if (cached) {
          outputBuildCheck({ ...cached, cached: true }, flags, ui);
          return { exitCode: cached.failing > 0 ? 1 : 0, result: cached };
        }
      }
      const result = await checkBuilds(ctx.cwd, {
        packageFilter: flags.package,
        timeout: flags.timeout ? Number(flags.timeout) : 3e4
      });
      await platform.cache.set(cacheKey, result, 10 * 60 * 1e3);
      await platform.analytics.track("quality:check-builds", {
        totalPackages: result.totalPackages,
        passing: result.passing,
        failing: result.failing,
        staleBuilds: result.staleBuilds.length,
        duration: result.duration,
        packageSpecific: !!flags.package
      });
      outputBuildCheck({ ...result, cached: false }, flags, ui);
      return {
        exitCode: result.failing > 0 ? 1 : 0,
        result
      };
    }
  }
});
function outputBuildCheck(result, flags, ui) {
  if (flags.json) {
    ui?.json?.(result);
    return;
  }
  const sections = [];
  const statusIcon = result.failing === 0 ? "\u2705" : "\u274C";
  const statusText = result.failing === 0 ? "All builds passing" : "Build failures detected";
  const statusItems = [
    `${statusIcon} ${statusText}`,
    `Passing: ${result.passing} package(s)`,
    result.failing > 0 ? `Failing: ${result.failing} package(s)` : null
  ].filter(Boolean);
  sections.push({ header: "Build Status", items: statusItems });
  if (result.failures.length > 0) {
    const failureItems = [];
    for (const failure of result.failures.slice(0, 5)) {
      failureItems.push(`\u2022 ${failure.package}`);
      const firstLine = failure.error.split("\n")[0];
      failureItems.push(`  ${firstLine?.substring(0, 80) || "Build failed"}`);
    }
    if (result.failures.length > 5) {
      failureItems.push(`... and ${result.failures.length - 5} more failures`);
    }
    sections.push({ header: "\u274C Failed Packages", items: failureItems });
  }
  if (result.staleBuilds.length > 0) {
    const staleItems = result.staleBuilds.slice(0, 5).map((s) => `\u2022 ${s.package}`);
    if (result.staleBuilds.length > 5) {
      staleItems.push(`... and ${result.staleBuilds.length - 5} more`);
    }
    sections.push({
      header: "\u26A0\uFE0F  Stale Builds (dist/ older than src/)",
      items: staleItems
    });
  }
  const summaryItems = [
    `Total packages: ${result.totalPackages}`,
    `Duration: ${(result.duration / 1e3).toFixed(1)}s`,
    result.cached ? "\u{1F4BE} Cached (use --refresh to recheck)" : "\u{1F504} Fresh check"
  ];
  sections.push({ header: "Summary", items: summaryItems });
  const title = result.failing === 0 ? "\u2705 All Builds Passing" : `\u274C ${result.failing} Build Failure(s) Detected`;
  ui?.success?.("Build check completed", {
    title,
    sections
  });
}
var check_tests_default = defineCommand({
  id: "quality:check-tests",
  description: "Run tests and track coverage across monorepo",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      const cacheKey = `${CACHE_KEYS.TESTS}:${flags.package || "all"}`;
      if (!flags.refresh) {
        const cached = await platform.cache.get(cacheKey);
        if (cached) {
          outputTestResults({ ...cached, cached: true }, flags, ui);
          return { exitCode: cached.failing > 0 ? 1 : 0, result: cached };
        }
      }
      const result = await runTests(ctx.cwd, {
        packageFilter: flags.package,
        timeout: flags.timeout ? Number(flags.timeout) : 6e4,
        withCoverage: flags["with-coverage"],
        coverageOnly: flags["coverage-only"]
      });
      await platform.cache.set(cacheKey, result, 5 * 60 * 1e3);
      await platform.analytics.track("quality:check-tests", {
        packageFilter: flags.package || "all",
        totalPackages: result.totalPackages,
        passing: result.passing,
        failing: result.failing,
        withCoverage: flags["with-coverage"],
        cached: false
      });
      outputTestResults({ ...result, cached: false }, flags, ui);
      return {
        exitCode: result.failing > 0 ? 1 : 0,
        result,
        meta: { cached: false }
      };
    }
  }
});
function outputTestResults(result, flags, ui) {
  if (flags.json) {
    ui?.json?.(result);
    return;
  }
  const sections = [];
  const statusIcon = result.failing === 0 ? "\u2705" : "\u274C";
  const statusText = result.failing === 0 ? "All tests passing" : "Test failures detected";
  const statusItems = [
    `${statusIcon} ${statusText}`,
    `Total packages: ${result.totalPackages}`,
    `Passing: ${result.passing}`,
    result.failing > 0 ? `Failing: ${result.failing}` : null,
    result.skipped > 0 ? `Skipped: ${result.skipped} (no test script)` : null
  ].filter(Boolean);
  sections.push({ header: "Test Status", items: statusItems });
  if (result.summary.totalTests > 0) {
    const summaryItems2 = [
      `Total tests: ${result.summary.totalTests}`,
      `Passed: ${result.summary.passedTests}`,
      result.summary.failedTests > 0 ? `Failed: ${result.summary.failedTests}` : null
    ].filter(Boolean);
    sections.push({ header: "Test Summary", items: summaryItems2 });
  }
  if (result.failures.length > 0) {
    const failureItems = [];
    for (const failure of result.failures.slice(0, 5)) {
      failureItems.push(`\u274C ${failure.package}`);
      if (failure.failedTests && failure.totalTests) {
        failureItems.push(`  ${failure.failedTests}/${failure.totalTests} tests failed`);
      }
      const firstLine = failure.error.split("\n")[0];
      failureItems.push(`  ${firstLine?.substring(0, 80) || "Test failed"}`);
    }
    if (result.failures.length > 5) {
      failureItems.push(`... and ${result.failures.length - 5} more failures`);
    }
    sections.push({ header: "Failed Packages", items: failureItems });
  }
  if (result.coverage.packages.length > 0) {
    const coverageItems = [];
    coverageItems.push(`Average coverage: ${result.coverage.avgCoverage.toFixed(1)}%`);
    coverageItems.push("");
    const topPackages = result.coverage.packages.sort((a, b) => b.lines - a.lines).slice(0, 5);
    for (const pkg of topPackages) {
      coverageItems.push(`${pkg.name}`);
      coverageItems.push(
        `  Lines: ${pkg.lines.toFixed(1)}% | Statements: ${pkg.statements.toFixed(1)}% | Functions: ${pkg.functions.toFixed(1)}% | Branches: ${pkg.branches.toFixed(1)}%`
      );
    }
    if (result.coverage.packages.length > 5) {
      coverageItems.push(`... and ${result.coverage.packages.length - 5} more packages`);
    }
    sections.push({ header: "Coverage", items: coverageItems });
  }
  const summaryItems = [
    `Duration: ${(result.duration / 1e3).toFixed(1)}s`,
    result.cached ? "\u{1F4BE} Cached (use --refresh to re-run)" : "\u{1F504} Fresh run"
  ];
  sections.push({ header: "Summary", items: summaryItems });
  const title = result.failing === 0 ? "\u2705 All Tests Passed" : `\u274C ${result.failing} Package(s) with Test Failures`;
  ui?.success?.("Test run completed", {
    title,
    sections
  });
}
var check_types_default = defineCommand({
  id: "quality:check-types",
  description: "Analyze TypeScript type safety across monorepo",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      const cacheKey = `${CACHE_KEYS.TYPE_ANALYSIS}:${flags.package || "all"}`;
      if (!flags.refresh) {
        const cached = await platform.cache.get(cacheKey);
        if (cached) {
          outputTypeAnalysis({ ...cached, cached: true }, flags, ui);
          return { exitCode: cached.totalErrors > 0 ? 1 : 0, result: cached };
        }
      }
      const result = await analyzeTypes(ctx.cwd, {
        packageFilter: flags.package,
        errorsOnly: flags["errors-only"]
      });
      await platform.cache.set(cacheKey, result, 10 * 60 * 1e3);
      await platform.analytics.track("quality:check-types", {
        packageFilter: flags.package || "all",
        totalPackages: result.totalPackages,
        totalErrors: result.totalErrors,
        avgCoverage: result.avgCoverage,
        cached: false
      });
      outputTypeAnalysis({ ...result, cached: false }, flags, ui);
      return {
        exitCode: result.totalErrors > 0 ? 1 : 0,
        result,
        meta: { cached: false }
      };
    }
  }
});
function outputTypeAnalysis(result, flags, ui) {
  if (flags.json) {
    ui?.json?.(result);
    return;
  }
  const errorsOnly = flags["errors-only"] || false;
  const sections = [];
  const statusIcon = result.totalErrors === 0 ? "\u2705" : "\u274C";
  const statusText = result.totalErrors === 0 ? "All packages passed type checks" : "Type errors detected";
  const statusItems = [
    `${statusIcon} ${statusText}`,
    `Analyzed: ${result.totalPackages} package(s)`,
    `Errors: ${result.totalErrors}`,
    `Warnings: ${result.totalWarnings}`,
    `Avg Coverage: ${result.avgCoverage.toFixed(1)}%`
  ];
  sections.push({ header: "Type Safety Status", items: statusItems });
  if (result.packagesWithErrors > 0) {
    const errorItems = [];
    const packagesToShow = result.packages.filter((pkg) => !errorsOnly || pkg.errors > 0).slice(0, 10);
    for (const pkg of packagesToShow) {
      const status = pkg.errors > 0 ? "\u274C" : "\u2705";
      errorItems.push(`${status} ${pkg.name}`);
      const details = [
        pkg.errors > 0 ? `${pkg.errors} error(s)` : null,
        pkg.warnings > 0 ? `${pkg.warnings} warning(s)` : null,
        `${pkg.coverage.toFixed(1)}% coverage`,
        pkg.anyCount > 0 ? `${pkg.anyCount} any` : null,
        pkg.tsIgnoreCount > 0 ? `${pkg.tsIgnoreCount} @ts-ignore` : null
      ].filter(Boolean).join(", ");
      errorItems.push(`  ${details}`);
    }
    if (result.packages.length > 10) {
      errorItems.push(`... and ${result.packages.length - 10} more packages`);
    }
    sections.push({
      header: `Packages with Type Errors (${result.packagesWithErrors})`,
      items: errorItems
    });
  }
  const excellent = result.packages.filter((p) => p.coverage >= 90).length;
  const good = result.packages.filter((p) => p.coverage >= 70 && p.coverage < 90).length;
  const poor = result.packages.filter((p) => p.coverage < 70).length;
  if (result.packages.length > 0) {
    const coverageItems = [
      `\u2705 Excellent (\u226590%): ${excellent} package(s)`,
      `\u26A0\uFE0F  Good (70-90%):   ${good} package(s)`,
      poor > 0 ? `\u274C Poor (<70%):     ${poor} package(s)` : null
    ].filter(Boolean);
    sections.push({ header: "Type Coverage Distribution", items: coverageItems });
  }
  const summaryItems = [
    `Total packages: ${result.totalPackages}`,
    `Duration: ${(result.duration / 1e3).toFixed(1)}s`,
    result.cached ? "\u{1F4BE} Cached (use --refresh to recheck)" : "\u{1F504} Fresh analysis"
  ];
  sections.push({ header: "Summary", items: summaryItems });
  const title = result.totalErrors === 0 ? "\u2705 All Type Checks Passed" : `\u274C ${result.packagesWithErrors} Package(s) with Type Errors`;
  ui?.success?.("Type analysis completed", {
    title,
    sections
  });
}
var cycles_default = defineCommand({
  id: "quality:cycles",
  description: "Detect circular dependencies in monorepo",
  handler: {
    async execute(ctx, input) {
      const { ui } = ctx;
      const flags = input.flags ?? input;
      const graph = buildDependencyGraph(ctx.cwd);
      const cycles = findCircularDependencies(graph);
      outputCycles(cycles, flags, ui);
      return {
        exitCode: cycles.length > 0 ? 1 : 0,
        cycles
      };
    }
  }
});
function outputCycles(cycles, flags, ui) {
  if (flags.json) {
    ui?.json?.({ cycles, count: cycles.length });
    return;
  }
  if (cycles.length === 0) {
    ui?.success?.("No circular dependencies found", {
      title: "\u2705 Circular Dependencies Check",
      sections: [
        {
          header: "Result",
          items: ["\u2705 No circular dependencies detected"]
        }
      ]
    });
    return;
  }
  const sections = [];
  sections.push({
    header: "Summary",
    items: [
      `\u26A0\uFE0F Found ${cycles.length} circular dependency chain(s)`,
      "These must be broken to enable clean builds"
    ]
  });
  for (let i = 0; i < cycles.length; i++) {
    const cycle = cycles[i];
    if (!cycle) {
      continue;
    }
    const cycleItems = [];
    for (let j = 0; j < cycle.length; j++) {
      const pkg = cycle[j];
      if (j === cycle.length - 1) {
        cycleItems.push(`  ${j + 1}. ${pkg}`);
        const firstPkg = cycle[0];
        cycleItems.push(`  ${j + 2}. ${firstPkg ?? "?"} \u2B05 circular!`);
      } else {
        cycleItems.push(`  ${j + 1}. ${pkg}`);
      }
    }
    sections.push({
      header: `Cycle ${i + 1} (${cycle.length} packages)`,
      items: cycleItems
    });
  }
  sections.push({
    header: "Recommendations",
    items: [
      "1. Extract shared code into a new package",
      "2. Move one dependency to devDependencies",
      "3. Refactor to remove bidirectional dependencies",
      "4. Use dependency injection patterns"
    ]
  });
  ui?.error?.("Circular dependencies detected", {
    title: `\u26A0\uFE0F Circular Dependencies Detected (${cycles.length})`,
    sections
  });
}
var dead_code_default = defineCommand({
  id: "quality:dead-code",
  description: "Detect and optionally remove dead (unreachable) source files",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      if (flags["list-backups"]) {
        const backups = listBackups(ctx.cwd);
        if (flags.json) {
          ui?.json?.(backups);
        } else {
          outputBackupList(backups, ui);
        }
        return { exitCode: 0, result: backups };
      }
      if (flags.restore) {
        try {
          const result2 = await restoreFromBackup(ctx.cwd, flags.restore);
          if (flags.json) {
            ui?.json?.(result2);
          } else {
            ui?.success?.(`Restored ${result2.restoredFiles} file(s) from backup ${flags.restore}`, {});
            if (result2.restoredExports > 0) {
              ui?.info?.(`Note: ${result2.restoredExports} package.json export(s) were cleaned. You may need to rebuild.`);
            }
          }
          return { exitCode: 0 };
        } catch (err) {
          if (flags.json) {
            ui?.json?.({ error: err.message });
          } else {
            ui?.error?.(err.message);
          }
          return { exitCode: 1 };
        }
      }
      const cacheKey = `${CACHE_KEYS.DEAD_CODE}:${flags.package || "all"}`;
      if (!flags.refresh && !flags["auto-remove"]) {
        const cached = await platform.cache.get(cacheKey);
        if (cached) {
          outputDeadCodeReport({ ...cached, cached: true }, flags, ui);
          return { exitCode: cached.summary.totalDead > 0 ? 1 : 0, result: cached };
        }
      }
      const result = await scanDeadFiles(ctx.cwd, {
        packageFilter: flags.package,
        verbose: flags.verbose
      });
      await platform.cache.set(cacheKey, result, 5 * 60 * 1e3);
      await platform.analytics.track("quality:dead-code", {
        totalPackages: result.summary.totalPackages,
        totalFiles: result.summary.totalFiles,
        totalDead: result.summary.totalDead,
        totalDeadBytes: result.summary.totalDeadBytes,
        duration: result.duration,
        autoRemove: !!flags["auto-remove"],
        dryRun: !!flags["dry-run"]
      });
      if (flags["auto-remove"]) {
        if (result.summary.totalDead === 0) {
          if (flags.json) {
            ui?.json?.({ message: "No dead files found", ...result });
          } else {
            ui?.success?.("No dead files found. Nothing to remove.", {});
          }
          return { exitCode: 0, result };
        }
        const removalResult = await removeDeadFiles(ctx.cwd, result, {
          dryRun: flags["dry-run"]
        });
        if (flags.json) {
          ui?.json?.(removalResult);
        } else {
          outputRemovalReport(removalResult, flags, ui);
        }
        return { exitCode: 0, result: removalResult };
      }
      outputDeadCodeReport({ ...result, cached: false }, flags, ui);
      return {
        exitCode: result.summary.totalDead > 0 ? 1 : 0,
        result
      };
    }
  }
});
function outputDeadCodeReport(result, flags, ui) {
  if (flags.json) {
    ui?.json?.(result);
    return;
  }
  const sections = [];
  const packagesWithDead = result.packages.filter((p) => p.deadFiles.length > 0);
  if (packagesWithDead.length > 0) {
    const items = [];
    for (const pkg of packagesWithDead) {
      items.push(`${pkg.packageName} (${pkg.deadFiles.length} dead file${pkg.deadFiles.length === 1 ? "" : "s"})`);
      for (const dead of pkg.deadFiles.slice(0, 5)) {
        const sizeKb = (dead.sizeBytes / 1024).toFixed(1);
        items.push(`  ${dead.relativePath} (${sizeKb} KB)`);
      }
      if (pkg.deadFiles.length > 5) {
        items.push(`  ... and ${pkg.deadFiles.length - 5} more`);
      }
    }
    sections.push({ header: "Dead Files", items });
  }
  if (flags.verbose) {
    for (const pkg of result.packages) {
      if (pkg.entryPoints.length > 0) {
        const items = pkg.entryPoints.slice(0, 10).map((ep) => `  ${ep}`);
        if (pkg.entryPoints.length > 10) {
          items.push(`  ... and ${pkg.entryPoints.length - 10} more`);
        }
        sections.push({ header: `Entry Points: ${pkg.packageName}`, items });
      }
    }
  }
  const allWarnings = result.packages.flatMap((p) => p.warnings);
  if (allWarnings.length > 0) {
    sections.push({
      header: "Warnings",
      items: allWarnings.slice(0, 10)
    });
  }
  const totalDeadKb = (result.summary.totalDeadBytes / 1024).toFixed(1);
  const summaryItems = [
    `Packages scanned: ${result.summary.totalPackages}`,
    `Total source files: ${result.summary.totalFiles}`,
    `Alive files: ${result.summary.totalAlive}`,
    `Dead files: ${result.summary.totalDead}`,
    result.summary.totalDead > 0 ? `Dead code size: ${totalDeadKb} KB` : null,
    result.summary.emptyDirectories.length > 0 ? `Empty directories: ${result.summary.emptyDirectories.length}` : null,
    `Duration: ${(result.duration / 1e3).toFixed(1)}s`,
    result.cached ? "(cached \u2014 use --refresh to rescan)" : null
  ].filter(Boolean);
  sections.push({ header: "Summary", items: summaryItems });
  if (result.summary.totalDead > 0) {
    sections.push({
      header: "Next Steps",
      items: [
        "Run with --auto-remove --dry-run to preview removal",
        "Run with --auto-remove to remove and create backup",
        "Run with --verbose to see entry points"
      ]
    });
  }
  const title = result.summary.totalDead === 0 ? "No dead files found" : `${result.summary.totalDead} dead file(s) found`;
  ui?.success?.("Dead code analysis completed", { title, sections });
}
function outputRemovalReport(result, flags, ui) {
  const isDryRun = flags["dry-run"];
  const prefix = isDryRun ? "[DRY RUN] Would" : "Successfully";
  const sections = [];
  const items = [
    `${prefix} remove ${result.filesRemoved} file(s)`,
    `${prefix} free ${(result.bytesRemoved / 1024).toFixed(1)} KB`
  ];
  if (result.emptyDirsRemoved > 0) {
    items.push(`${prefix} remove ${result.emptyDirsRemoved} empty director${result.emptyDirsRemoved === 1 ? "y" : "ies"}`);
  }
  if (result.exportsCleanedUp > 0) {
    items.push(`${prefix} clean ${result.exportsCleanedUp} package.json export(s)`);
  }
  sections.push({ header: isDryRun ? "Preview" : "Removal Complete", items });
  if (!isDryRun) {
    sections.push({
      header: "Backup",
      items: [
        `Backup ID: ${result.backupId}`,
        `To restore: pnpm kb quality:dead-code --restore ${result.backupId}`
      ]
    });
  }
  const fileItems = [];
  for (const file of result.manifest.removedFiles.slice(0, 10)) {
    const sizeKb = (file.sizeBytes / 1024).toFixed(1);
    fileItems.push(`${file.backupPath} (${sizeKb} KB)`);
  }
  if (result.manifest.removedFiles.length > 10) {
    fileItems.push(`... and ${result.manifest.removedFiles.length - 10} more`);
  }
  sections.push({ header: "Files", items: fileItems });
  const title = isDryRun ? `[DRY RUN] Would remove ${result.filesRemoved} file(s)` : `Removed ${result.filesRemoved} file(s)`;
  ui?.success?.(title, { title, sections });
}
function outputBackupList(backups, ui) {
  if (backups.length === 0) {
    ui?.info?.("No backups found.");
    return;
  }
  const sections = [];
  for (const backup of backups) {
    const date = new Date(backup.createdAt).toLocaleString();
    const items = [
      `Date: ${date}`,
      `Git: ${backup.gitBranch} @ ${backup.gitSha.slice(0, 8)}`,
      `Files: ${backup.totalFilesRemoved}`,
      `Size: ${(backup.totalBytesRemoved / 1024).toFixed(1)} KB`,
      `Restore: pnpm kb quality:dead-code --restore ${backup.id}`
    ];
    sections.push({ header: `Backup: ${backup.id}`, items });
  }
  ui?.success?.(`${backups.length} backup(s) found`, {
    title: "Dead Code Backups",
    sections
  });
}
var fix_deps_default = defineCommand({
  id: "quality:fix-deps",
  description: "Auto-fix dependency issues",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      const dryRun = flags["dry-run"] ?? false;
      const removeUnused = flags["remove-unused"] || flags.all;
      const addMissing = flags["add-missing"] || flags.all;
      const alignVersions = flags["align-versions"] || flags.all;
      const showStats = flags.stats;
      if (showStats) {
        const stats = await getDependencyStats(ctx.cwd);
        outputStats(stats, flags, ui);
        return { exitCode: 0 };
      }
      if (!removeUnused && !addMissing && !alignVersions) {
        ui?.error?.("No fix options specified. Use --remove-unused, --add-missing, --align-versions, or --all");
        return { exitCode: 1 };
      }
      const loader = useLoader("Scanning packages...");
      loader.start();
      const result = {
        packagesScanned: 0,
        removedDeps: [],
        addedDeps: [],
        alignedDeps: [],
        dryRun
      };
      const packages = findPackages(ctx.cwd);
      result.packagesScanned = packages.length;
      loader.update({ text: `Scanned ${packages.length} packages` });
      if (alignVersions) {
        loader.update({ text: "Analyzing duplicate dependencies..." });
        const aligned = await alignDuplicateVersions(packages, dryRun);
        result.alignedDeps = aligned;
      }
      if (addMissing) {
        loader.update({ text: "Checking for missing workspace dependencies..." });
        const added = await addMissingWorkspaceDeps(packages, dryRun);
        result.addedDeps = added;
      }
      if (removeUnused) {
        loader.update({ text: "Checking for unused dependencies..." });
        const removed = await removeUnusedDeps(packages, dryRun);
        result.removedDeps = removed;
      }
      loader.succeed("Dependency analysis completed");
      await platform.analytics.track("quality:fix-deps", {
        dryRun,
        packagesScanned: result.packagesScanned,
        removedCount: result.removedDeps.length,
        addedCount: result.addedDeps.length,
        alignedCount: result.alignedDeps.length
      });
      outputResults(result, flags, ui);
      return {
        exitCode: 0,
        result
      };
    }
  }
});
function findPackages(rootDir) {
  const packages = [];
  if (!fs.existsSync(rootDir)) {
    return packages;
  }
  const entries = fs.readdirSync(rootDir, { withFileTypes: true });
  for (const entry of entries) {
    if (!entry.isDirectory() || !entry.name.startsWith("kb-labs-")) {
      continue;
    }
    const repoPath = path3.join(rootDir, entry.name);
    const packagesDir = path3.join(repoPath, "packages");
    if (!fs.existsSync(packagesDir)) {
      continue;
    }
    const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
    for (const pkgDir of packageDirs) {
      if (!pkgDir.isDirectory()) {
        continue;
      }
      const packageJsonPath = path3.join(packagesDir, pkgDir.name, "package.json");
      if (fs.existsSync(packageJsonPath)) {
        const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
        packages.push({
          name: packageJson.name || pkgDir.name,
          path: packageJsonPath,
          json: packageJson
        });
      }
    }
  }
  return packages;
}
async function getDependencyStats(rootDir) {
  const packages = findPackages(rootDir);
  const allDeps = /* @__PURE__ */ new Map();
  for (const pkg of packages) {
    const deps = {
      ...pkg.json.dependencies,
      ...pkg.json.devDependencies
    };
    for (const [dep, version] of Object.entries(deps)) {
      if (!allDeps.has(dep)) {
        allDeps.set(dep, /* @__PURE__ */ new Set());
      }
      allDeps.get(dep).add(version);
    }
  }
  const duplicates = Array.from(allDeps.entries()).filter(([_, versions]) => versions.size > 1).filter(([dep]) => !dep.startsWith("@kb-labs/"));
  const topUsed = Array.from(allDeps.entries()).map(([name, versions]) => ({ name, count: versions.size > 1 ? versions.size : 1 })).sort((a, b) => b.count - a.count).slice(0, 10);
  return {
    totalPackages: packages.length,
    totalDeps: allDeps.size,
    duplicates: duplicates.length,
    topUsed
  };
}
async function alignDuplicateVersions(packages, dryRun) {
  const aligned = [];
  const depVersions = /* @__PURE__ */ new Map();
  for (const pkg of packages) {
    const deps = {
      ...pkg.json.dependencies,
      ...pkg.json.devDependencies
    };
    for (const [dep, version] of Object.entries(deps)) {
      if (dep.startsWith("@kb-labs/")) {
        continue;
      }
      if (!depVersions.has(dep)) {
        depVersions.set(dep, /* @__PURE__ */ new Map());
      }
      const versions = depVersions.get(dep);
      if (!versions.has(version)) {
        versions.set(version, /* @__PURE__ */ new Set());
      }
      versions.get(version).add(pkg.name);
    }
  }
  for (const [dep, versions] of depVersions.entries()) {
    if (versions.size <= 1) {
      continue;
    }
    const versionCounts = Array.from(versions.entries()).map(([ver, pkgs]) => ({
      version: ver,
      count: pkgs.size,
      packages: Array.from(pkgs)
    }));
    versionCounts.sort((a, b) => b.count - a.count);
    const targetVersion = versionCounts[0]?.version;
    if (!targetVersion) {
      continue;
    }
    for (const { version, packages: pkgNames } of versionCounts.slice(1)) {
      aligned.push({
        dep,
        from: version,
        to: targetVersion,
        packages: pkgNames
      });
      if (!dryRun) {
        for (const pkgName of pkgNames) {
          const pkg = packages.find((p) => p.name === pkgName);
          if (!pkg) {
            continue;
          }
          if (pkg.json.dependencies?.[dep]) {
            pkg.json.dependencies[dep] = targetVersion;
          }
          if (pkg.json.devDependencies?.[dep]) {
            pkg.json.devDependencies[dep] = targetVersion;
          }
          fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + "\n");
        }
      }
    }
  }
  return aligned;
}
async function addMissingWorkspaceDeps(packages, dryRun) {
  const added = [];
  const workspacePackages = /* @__PURE__ */ new Map();
  for (const pkg of packages) {
    if (pkg.name.startsWith("@kb-labs/")) {
      workspacePackages.set(pkg.name, "workspace:*");
    }
  }
  for (const pkg of packages) {
    const packageDir = path3.dirname(pkg.path);
    const srcDir = path3.join(packageDir, "src");
    if (!fs.existsSync(srcDir)) {
      continue;
    }
    const imports = scanImports(srcDir);
    const currentDeps = {
      ...pkg.json.dependencies,
      ...pkg.json.devDependencies
    };
    for (const imp of imports) {
      if (imp.startsWith("@kb-labs/") && workspacePackages.has(imp) && !currentDeps[imp]) {
        added.push({
          package: pkg.name,
          dep: imp,
          version: "workspace:*"
        });
        if (!dryRun) {
          if (!pkg.json.dependencies) {
            pkg.json.dependencies = {};
          }
          pkg.json.dependencies[imp] = "workspace:*";
          fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + "\n");
        }
      }
    }
  }
  return added;
}
async function removeUnusedDeps(packages, dryRun) {
  const removed = [];
  for (const pkg of packages) {
    const packageDir = path3.dirname(pkg.path);
    const srcDir = path3.join(packageDir, "src");
    if (!fs.existsSync(srcDir)) {
      continue;
    }
    const imports = new Set(scanImports(srcDir));
    const deps = {
      ...pkg.json.dependencies,
      ...pkg.json.devDependencies
    };
    for (const dep of Object.keys(deps)) {
      if (isProtectedDep(dep)) {
        continue;
      }
      if (!imports.has(dep)) {
        removed.push({
          package: pkg.name,
          dep
        });
        if (!dryRun) {
          delete pkg.json.dependencies?.[dep];
          delete pkg.json.devDependencies?.[dep];
          fs.writeFileSync(pkg.path, JSON.stringify(pkg.json, null, 2) + "\n");
        }
      }
    }
  }
  return removed;
}
function scanImports(dir) {
  const imports = [];
  function walk(currentDir) {
    const entries = fs.readdirSync(currentDir, { withFileTypes: true });
    for (const entry of entries) {
      const fullPath = path3.join(currentDir, entry.name);
      if (entry.isDirectory()) {
        walk(fullPath);
      } else if (entry.isFile() && /\.(ts|tsx|js|jsx)$/.test(entry.name)) {
        const content = fs.readFileSync(fullPath, "utf-8");
        const importRegex = /(?:import|require)\s*\(?['"]([^'"]+)['"]\)?/g;
        let match;
        while ((match = importRegex.exec(content)) !== null) {
          const imp = match[1];
          if (!imp) {
            continue;
          }
          const pkgName = imp.startsWith("@") ? imp.split("/").slice(0, 2).join("/") : imp.split("/")[0];
          if (pkgName) {
            imports.push(pkgName);
          }
        }
      }
    }
  }
  walk(dir);
  return Array.from(new Set(imports));
}
function isProtectedDep(dep) {
  const protectedDeps = [
    "typescript",
    "tsup",
    "esbuild",
    "vite",
    "rollup",
    "rimraf",
    "vitest",
    "jest",
    "playwright",
    "eslint",
    "prettier"
  ];
  return protectedDeps.some((p) => dep === p || dep.startsWith(`${p}-`) || dep.startsWith(`@${p}/`));
}
function outputStats(stats, flags, ui) {
  if (flags.json) {
    ui?.json?.(stats);
    return;
  }
  const sections = [];
  sections.push({
    header: "Overview",
    items: [
      `Total Packages: ${stats.totalPackages}`,
      `Total Dependencies: ${stats.totalDeps}`,
      `Duplicate Versions: ${stats.duplicates}`
    ]
  });
  if (stats.topUsed.length > 0) {
    sections.push({
      header: "Top 10 Most Used",
      items: stats.topUsed.map((d) => `${d.name} (${d.count} packages)`)
    });
  }
  ui?.success?.("Dependency statistics", {
    title: "\u{1F4CA} Dependency Statistics",
    sections
  });
}
function outputResults(result, flags, ui) {
  if (flags.json) {
    ui?.json?.(result);
    return;
  }
  const sections = [];
  const summaryItems = [
    `Packages Scanned: ${result.packagesScanned}`,
    `Mode: ${result.dryRun ? "\u{1F50D} Dry Run (no changes applied)" : "\u2705 Changes Applied"}`
  ];
  sections.push({ header: "Summary", items: summaryItems });
  if (result.alignedDeps.length > 0) {
    const alignedItems = result.alignedDeps.map(
      (a) => `${a.dep}: ${a.from} \u2192 ${a.to} (${a.packages.length} packages)`
    );
    sections.push({ header: "Aligned Versions", items: alignedItems.slice(0, 10) });
    if (result.alignedDeps.length > 10) {
      const lastSection = sections[sections.length - 1];
      if (lastSection) {
        lastSection.items.push(`... and ${result.alignedDeps.length - 10} more`);
      }
    }
  }
  if (result.addedDeps.length > 0) {
    const addedItems = result.addedDeps.map((a) => `${a.package}: +${a.dep}`);
    sections.push({ header: "Added Dependencies", items: addedItems.slice(0, 10) });
    if (result.addedDeps.length > 10) {
      const lastSection = sections[sections.length - 1];
      if (lastSection) {
        lastSection.items.push(`... and ${result.addedDeps.length - 10} more`);
      }
    }
  }
  if (result.removedDeps.length > 0) {
    const removedItems = result.removedDeps.map((r) => `${r.package}: -${r.dep}`);
    sections.push({ header: "Removed Dependencies", items: removedItems.slice(0, 10) });
    if (result.removedDeps.length > 10) {
      const lastSection = sections[sections.length - 1];
      if (lastSection) {
        lastSection.items.push(`... and ${result.removedDeps.length - 10} more`);
      }
    }
  }
  if (result.alignedDeps.length === 0 && result.addedDeps.length === 0 && result.removedDeps.length === 0) {
    sections.push({ header: "Result", items: ["\u2705 No issues found!"] });
  }
  if (result.dryRun && (result.alignedDeps.length > 0 || result.addedDeps.length > 0 || result.removedDeps.length > 0)) {
    sections.push({
      header: "Next Steps",
      items: ["Remove --dry-run flag to apply changes", "Run `pnpm install` after applying changes"]
    });
  }
  const title = result.dryRun ? "\u{1F50D} Dependency Fix Preview" : "\u2705 Dependency Fix Complete";
  ui?.success?.("Dependency fix completed", {
    title,
    sections
  });
}
var health_default = defineCommand({
  id: "quality:health",
  description: "Check monorepo health score",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      const health = await calculateHealth(ctx.cwd, flags.package);
      await platform.cache.set(CACHE_KEYS.HEALTH, health, 5 * 60 * 1e3);
      await platform.analytics.track("quality:health", {
        score: health.score,
        grade: health.grade,
        issueCount: health.issues.length,
        packageSpecific: !!flags.package
      });
      outputHealth(health, flags, ui);
      return {
        exitCode: health.score < 60 ? 1 : 0,
        result: health
      };
    }
  }
});
function findPackages2(rootDir, specificPackage) {
  const packages = [];
  if (!fs.existsSync(rootDir)) {
    return packages;
  }
  const entries = fs.readdirSync(rootDir, { withFileTypes: true });
  for (const entry of entries) {
    if (!entry.isDirectory() || !entry.name.startsWith("kb-labs-")) {
      continue;
    }
    const repoPath = path3.join(rootDir, entry.name);
    const packagesDir = path3.join(repoPath, "packages");
    if (!fs.existsSync(packagesDir)) {
      continue;
    }
    const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
    for (const pkgDir of packageDirs) {
      if (!pkgDir.isDirectory()) {
        continue;
      }
      const packageJsonPath = path3.join(packagesDir, pkgDir.name, "package.json");
      if (fs.existsSync(packageJsonPath)) {
        if (specificPackage) {
          const pkgJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
          if (pkgJson.name === specificPackage || pkgDir.name === specificPackage) {
            packages.push(packageJsonPath);
          }
        } else {
          packages.push(packageJsonPath);
        }
      }
    }
  }
  return packages;
}
async function calculateHealth(rootDir, specificPackage) {
  const packages = findPackages2(rootDir, specificPackage);
  let score = 100;
  const issues = [];
  const allDeps = /* @__PURE__ */ new Map();
  for (const packagePath of packages) {
    const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
    const deps = {
      ...packageJson.dependencies,
      ...packageJson.devDependencies
    };
    for (const [dep, version] of Object.entries(deps)) {
      if (!allDeps.has(dep)) {
        allDeps.set(dep, /* @__PURE__ */ new Set());
      }
      allDeps.get(dep).add(version);
    }
  }
  const duplicates = Array.from(allDeps.entries()).filter(([_, versions]) => versions.size > 1).filter(([dep]) => !dep.startsWith("@kb-labs/"));
  if (duplicates.length > 0) {
    const penalty = Math.min(20, duplicates.length * 2);
    score -= penalty;
    issues.push({
      type: "duplicates",
      severity: "warning",
      message: `${duplicates.length} duplicate dependencies (-${penalty})`
    });
  }
  let missingReadmes = 0;
  for (const packagePath of packages) {
    const packageDir = path3.dirname(packagePath);
    const readmePath = path3.join(packageDir, "README.md");
    if (!fs.existsSync(readmePath)) {
      missingReadmes++;
    }
  }
  if (missingReadmes > 0) {
    const penalty = Math.min(15, missingReadmes);
    score -= penalty;
    issues.push({
      type: "missing-docs",
      severity: "warning",
      message: `${missingReadmes} packages missing README (-${penalty})`
    });
  }
  let namingIssues = 0;
  for (const packagePath of packages) {
    const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
    const packageName = packageJson.name;
    if (!packageName || !packageName.startsWith("@kb-labs/")) {
      namingIssues++;
    }
  }
  if (namingIssues > 0) {
    const penalty = Math.min(10, namingIssues * 2);
    score -= penalty;
    issues.push({
      type: "naming",
      severity: "critical",
      message: `${namingIssues} packages with naming issues (-${penalty})`
    });
  }
  let missingTypes = 0;
  for (const packagePath of packages) {
    const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
    if (!packageJson.types && !packageJson.typings) {
      missingTypes++;
    }
  }
  if (missingTypes > 0) {
    const penalty = Math.min(15, missingTypes);
    score -= penalty;
    issues.push({
      type: "missing-types",
      severity: "warning",
      message: `${missingTypes} packages missing types field (-${penalty})`
    });
  }
  let grade;
  if (score >= 90) {
    grade = "A";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 60) {
    grade = "D";
  } else {
    grade = "F";
  }
  return {
    score: Math.max(0, score),
    grade,
    issues
  };
}
function outputHealth(health, flags, ui) {
  if (flags.json) {
    ui?.json?.(health);
    return;
  }
  const sections = [];
  const scoreItems = [
    `Score: ${health.score}/100`,
    `Grade: ${health.grade}`,
    `Status: ${health.score >= 80 ? "\u2705 Healthy" : health.score >= 60 ? "\u26A0\uFE0F Needs Attention" : "\u274C Critical"}`
  ];
  sections.push({ header: "Health Score", items: scoreItems });
  if (health.issues.length > 0) {
    const issueItems = health.issues.map((issue) => {
      const icon = issue.severity === "critical" ? "\u274C" : issue.severity === "warning" ? "\u26A0\uFE0F" : "\u2139\uFE0F";
      return `${icon} ${issue.message}`;
    });
    if (flags.detailed) {
      sections.push({ header: "Issues (Detailed)", items: issueItems });
    } else {
      sections.push({ header: "Issues", items: issueItems });
    }
  } else {
    sections.push({ header: "Issues", items: ["\u2705 No issues found!"] });
  }
  if (health.score < 90) {
    const recommendations = [];
    if (health.issues.some((i) => i.type === "duplicates")) {
      recommendations.push("Run `kb quality:fix-deps --align-versions` to fix duplicates");
    }
    if (health.issues.some((i) => i.type === "missing-docs")) {
      recommendations.push("Add README.md files to packages");
    }
    if (health.issues.some((i) => i.type === "missing-types")) {
      recommendations.push('Add "types" field to package.json or enable dts generation');
    }
    if (recommendations.length > 0) {
      sections.push({ header: "Recommendations", items: recommendations });
    }
  }
  const title = health.score >= 80 ? "\u{1F49A} Monorepo Health Check - Healthy" : health.score >= 60 ? "\u{1F49B} Monorepo Health Check - Needs Attention" : "\u2764\uFE0F Monorepo Health Check - Critical";
  ui?.success?.("Health check completed", {
    title,
    sections
  });
}
var stats_default = defineCommand({
  id: "quality:stats",
  description: "Show monorepo statistics and health score",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      if (!flags.refresh) {
        const cached = await platform.cache.get(CACHE_KEYS.STATS);
        if (cached) {
          outputStats2(cached, flags, ui);
          return { exitCode: 0 };
        }
      }
      const stats = await collectStats(ctx.cwd);
      if (flags.health) {
        stats.health = calculateHealthScore(stats);
      }
      await platform.cache.set(CACHE_KEYS.STATS, stats, 5 * 60 * 1e3);
      await platform.analytics.track("quality:stats", {
        packages: stats.overview.totalPackages,
        repositories: stats.overview.totalRepositories,
        withHealth: flags.health ?? false
      });
      outputStats2(stats, flags, ui);
      return { exitCode: 0 };
    }
  }
});
function findPackages3(rootDir) {
  const packages = [];
  if (!fs.existsSync(rootDir)) {
    return packages;
  }
  const entries = fs.readdirSync(rootDir, { withFileTypes: true });
  for (const entry of entries) {
    if (!entry.isDirectory() || !entry.name.startsWith("kb-labs-")) {
      continue;
    }
    const repoPath = path3.join(rootDir, entry.name);
    const packagesDir = path3.join(repoPath, "packages");
    if (!fs.existsSync(packagesDir)) {
      continue;
    }
    const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
    for (const pkgDir of packageDirs) {
      if (!pkgDir.isDirectory()) {
        continue;
      }
      const packageJsonPath = path3.join(packagesDir, pkgDir.name, "package.json");
      if (fs.existsSync(packageJsonPath)) {
        packages.push(packageJsonPath);
      }
    }
  }
  return packages;
}
function calculateSize(packageDir) {
  const srcDir = path3.join(packageDir, "src");
  if (!fs.existsSync(srcDir)) {
    return { files: 0, lines: 0, bytes: 0 };
  }
  let files = 0;
  let lines = 0;
  let bytes = 0;
  function walk(dir) {
    const entries = fs.readdirSync(dir, { withFileTypes: true });
    for (const entry of entries) {
      const fullPath = path3.join(dir, entry.name);
      if (entry.isDirectory()) {
        walk(fullPath);
      } else if (entry.isFile() && /\.(ts|tsx|js|jsx)$/.test(entry.name)) {
        files++;
        const content = fs.readFileSync(fullPath, "utf-8");
        lines += content.split("\n").length;
        bytes += Buffer.byteLength(content, "utf-8");
      }
    }
  }
  walk(srcDir);
  return { files, lines, bytes };
}
async function collectStats(rootDir) {
  const packages = findPackages3(rootDir);
  const stats = {
    overview: {
      totalPackages: 0,
      totalRepositories: 0,
      totalFiles: 0,
      totalLines: 0,
      totalBytes: 0
    },
    byRepository: {},
    dependencies: {
      total: 0,
      workspace: 0,
      external: 0,
      duplicates: 0,
      topUsed: []
    },
    health: {
      score: 0,
      grade: "F",
      issues: []
    },
    largestPackages: []
  };
  const repos = /* @__PURE__ */ new Set();
  const allDeps = /* @__PURE__ */ new Map();
  for (const packagePath of packages) {
    const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
    const packageName = packageJson.name;
    if (!packageName || !packageName.startsWith("@kb-labs/")) {
      continue;
    }
    stats.overview.totalPackages++;
    const packageDir = path3.dirname(packagePath);
    const repoName = path3.basename(path3.dirname(path3.dirname(packageDir)));
    repos.add(repoName);
    const size = calculateSize(packageDir);
    stats.overview.totalFiles += size.files;
    stats.overview.totalLines += size.lines;
    stats.overview.totalBytes += size.bytes;
    if (!stats.byRepository[repoName]) {
      stats.byRepository[repoName] = {
        name: repoName,
        packages: 0,
        files: 0,
        lines: 0,
        bytes: 0
      };
    }
    stats.byRepository[repoName].packages++;
    stats.byRepository[repoName].files += size.files;
    stats.byRepository[repoName].lines += size.lines;
    stats.byRepository[repoName].bytes += size.bytes;
    const deps = {
      ...packageJson.dependencies,
      ...packageJson.devDependencies
    };
    for (const dep of Object.keys(deps)) {
      stats.dependencies.total++;
      if (dep.startsWith("@kb-labs/")) {
        stats.dependencies.workspace++;
      } else {
        stats.dependencies.external++;
      }
      allDeps.set(dep, (allDeps.get(dep) || 0) + 1);
    }
    stats.largestPackages.push({
      name: packageName,
      repository: repoName,
      files: size.files,
      lines: size.lines,
      bytes: size.bytes
    });
  }
  stats.overview.totalRepositories = repos.size;
  stats.dependencies.duplicates = Array.from(allDeps.values()).filter((count) => count > 1).length;
  stats.dependencies.topUsed = Array.from(allDeps.entries()).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([name, count]) => ({ name, count }));
  stats.largestPackages.sort((a, b) => b.lines - a.lines);
  stats.largestPackages = stats.largestPackages.slice(0, 10);
  return stats;
}
function calculateHealthScore(stats) {
  let score = 100;
  const issues = [];
  if (stats.dependencies.duplicates > 0) {
    const penalty = Math.min(20, stats.dependencies.duplicates * 2);
    score -= penalty;
    issues.push({
      type: "duplicates",
      severity: "warning",
      message: `${stats.dependencies.duplicates} duplicate dependencies (-${penalty})`
    });
  }
  let grade;
  if (score >= 90) {
    grade = "A";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 60) {
    grade = "D";
  } else {
    grade = "F";
  }
  return {
    score,
    grade,
    issues
  };
}
function outputStats2(stats, flags, ui) {
  if (flags.json) {
    ui?.json?.(stats);
    return;
  }
  if (flags.md) {
    outputMarkdown(stats);
    return;
  }
  const overviewItems = [
    `Packages: ${stats.overview.totalPackages}`,
    `Repositories: ${stats.overview.totalRepositories}`,
    `Lines of Code: ${stats.overview.totalLines.toLocaleString()}`,
    `Total Size: ${formatBytes(stats.overview.totalBytes)}`
  ];
  const sections = [
    { header: "Overview", items: overviewItems }
  ];
  if (flags.health && stats.health) {
    const healthItems = [
      `Score: ${stats.health.score}/100 (Grade ${stats.health.grade})`
    ];
    if (stats.health.issues.length > 0) {
      healthItems.push("");
      healthItems.push("Issues:");
      stats.health.issues.forEach((issue) => {
        healthItems.push(`  ${issue.message}`);
      });
    }
    sections.push({ header: "Health Score", items: healthItems });
  }
  const topRepos = Object.values(stats.byRepository).sort((a, b) => b.lines - a.lines).slice(0, 5).map((repo) => `${repo.name}: ${repo.lines.toLocaleString()} lines, ${repo.packages} pkg(s)`);
  if (topRepos.length > 0) {
    sections.push({ header: "Top Repositories", items: topRepos });
  }
  ui?.success?.("Statistics collected successfully", {
    title: "\u{1F4CA} KB Labs Monorepo Statistics",
    sections
  });
}
function outputMarkdown(stats) {
  console.log("# KB Labs Monorepo Statistics\n");
  console.log("## Overview\n");
  console.log("| Metric | Value |");
  console.log("|--------|-------|");
  console.log(`| Packages | ${stats.overview.totalPackages} |`);
  console.log(`| Repositories | ${stats.overview.totalRepositories} |`);
  console.log(`| Lines of Code | ${stats.overview.totalLines.toLocaleString()} |`);
  console.log(`| Total Size | ${formatBytes(stats.overview.totalBytes)} |
`);
  if (stats.health) {
    console.log("## Health Score\n");
    console.log(`**${stats.health.score}/100** (Grade ${stats.health.grade})
`);
    if (stats.health.issues.length > 0) {
      console.log("### Issues\n");
      for (const issue of stats.health.issues) {
        console.log(`- ${issue.message}`);
      }
      console.log("");
    }
  }
  console.log("## By Repository\n");
  console.log("| Repository | Packages | Lines | Size |");
  console.log("|------------|----------|-------|------|");
  for (const [name, repo] of Object.entries(stats.byRepository)) {
    console.log(`| ${name} | ${repo.packages} | ${repo.lines.toLocaleString()} | ${formatBytes(repo.bytes)} |`);
  }
}
function formatBytes(bytes) {
  if (bytes === 0) {
    return "0 B";
  }
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
}
var visualize_default = defineCommand({
  id: "quality:visualize",
  description: "Visualize dependency graph",
  handler: {
    async execute(ctx, input) {
      const { ui } = ctx;
      const flags = input.flags ?? input;
      const graph = buildDependencyGraph(ctx.cwd);
      if (flags.dot) {
        outputDot(graph, flags, ui);
      } else if (flags.tree && flags.package) {
        outputTree(graph, flags.package, flags, ui);
      } else if (flags.reverse && flags.package) {
        outputReverse(graph, flags.package, flags, ui);
      } else if (flags.impact && flags.package) {
        outputImpact(graph, flags.package, flags, ui);
      } else if (flags.stats) {
        outputStats3(graph, flags, ui);
      } else {
        outputStats3(graph, flags, ui);
      }
      return { exitCode: 0 };
    }
  }
});
function outputTree(graph, packageName, flags, ui) {
  const { nodes } = graph;
  const node = nodes.get(packageName);
  if (!node) {
    ui?.fatal?.(`Package not found: ${packageName}`);
    return;
  }
  const sections = [];
  const visited = /* @__PURE__ */ new Set();
  const treeItems = [];
  function buildTree(pkg, depth, prefix) {
    if (visited.has(pkg)) {
      treeItems.push(`${prefix}${pkg} (circular)`);
      return;
    }
    visited.add(pkg);
    const pkgNode = nodes.get(pkg);
    if (!pkgNode) {
      return;
    }
    treeItems.push(`${prefix}${pkg}`);
    const deps = Array.from(pkgNode.deps);
    for (let i = 0; i < deps.length; i++) {
      const dep = deps[i];
      if (!dep) {
        continue;
      }
      const isLast = i === deps.length - 1;
      const newPrefix = prefix + (isLast ? "  \u2514\u2500 " : "  \u251C\u2500 ");
      buildTree(dep, depth + 1, newPrefix);
    }
  }
  buildTree(packageName, 0, "");
  sections.push({
    header: "Dependency Tree",
    items: treeItems
  });
  ui?.success?.("Dependency tree generated", {
    title: `\u{1F4E6} Dependency Tree for ${packageName}`,
    sections
  });
}
function outputReverse(graph, packageName, flags, ui) {
  const reverseDeps = getReverseDependencies(graph, packageName);
  if (flags.json) {
    ui?.json?.({ package: packageName, reverseDependencies: Array.from(reverseDeps) });
    return;
  }
  const sections = [];
  if (reverseDeps.size === 0) {
    sections.push({
      header: "Result",
      items: ["No packages depend on this package"]
    });
  } else {
    sections.push({
      header: `Packages that depend on ${packageName}`,
      items: Array.from(reverseDeps).map((dep) => `\u2022 ${dep}`)
    });
  }
  ui?.success?.("Reverse dependencies found", {
    title: `\u2B05\uFE0F Reverse Dependencies for ${packageName}`,
    sections
  });
}
function outputImpact(graph, packageName, flags, ui) {
  const affected = getImpactAnalysis(graph, packageName);
  if (flags.json) {
    ui?.json?.({ package: packageName, affectedPackages: Array.from(affected) });
    return;
  }
  const sections = [];
  if (affected.size === 0) {
    sections.push({
      header: "Result",
      items: ["No other packages affected by changes to this package"]
    });
  } else {
    sections.push({
      header: `Impact Analysis for ${packageName}`,
      items: [
        `Changes to this package will affect ${affected.size} other packages:`,
        "",
        ...Array.from(affected).map((dep) => `\u2022 ${dep}`)
      ]
    });
    sections.push({
      header: "Recommendations",
      items: [
        "\u{1F9EA} Run tests in affected packages",
        "\u{1F528} Rebuild affected packages",
        "\u{1F4DD} Update documentation if API changed"
      ]
    });
  }
  ui?.success?.("Impact analysis completed", {
    title: `\u{1F4A5} Impact Analysis for ${packageName}`,
    sections
  });
}
function outputStats3(graph, flags, ui) {
  const { nodes } = graph;
  let totalDeps = 0;
  let maxDeps = 0;
  let maxDepsPackage = "";
  const depCounts = /* @__PURE__ */ new Map();
  for (const [name, node] of nodes) {
    const depCount = node.deps.size;
    totalDeps += depCount;
    if (depCount > maxDeps) {
      maxDeps = depCount;
      maxDepsPackage = name;
    }
    depCounts.set(depCount, (depCounts.get(depCount) ?? 0) + 1);
  }
  const avgDeps = nodes.size > 0 ? (totalDeps / nodes.size).toFixed(2) : "0";
  if (flags.json) {
    ui?.json?.({
      totalPackages: nodes.size,
      totalDependencies: totalDeps,
      averageDependencies: Number.parseFloat(avgDeps),
      maxDependencies: maxDeps,
      maxDependenciesPackage: maxDepsPackage
    });
    return;
  }
  const sections = [];
  sections.push({
    header: "Graph Statistics",
    items: [
      `Total packages: ${nodes.size}`,
      `Total dependencies: ${totalDeps}`,
      `Average dependencies per package: ${avgDeps}`,
      `Max dependencies: ${maxDeps} (${maxDepsPackage})`
    ]
  });
  const distributionItems = [];
  const sortedCounts = Array.from(depCounts.entries()).sort((a, b) => a[0] - b[0]);
  for (const [count, packages] of sortedCounts) {
    const bar = "\u2588".repeat(Math.min(packages, 20));
    distributionItems.push(`${count} deps: ${bar} ${packages} packages`);
  }
  sections.push({
    header: "Dependency Distribution",
    items: distributionItems
  });
  ui?.success?.("Graph statistics calculated", {
    title: "\u{1F4CA} Dependency Graph Statistics",
    sections
  });
}
function outputDot(graph, flags, ui) {
  const { nodes } = graph;
  const lines = [];
  lines.push("digraph dependencies {");
  lines.push("  rankdir=LR;");
  lines.push("  node [shape=box];");
  lines.push("");
  for (const [name, node] of nodes) {
    for (const dep of node.deps) {
      const safeName = name.replace(/[@\/]/g, "_");
      const safeDep = dep.replace(/[@\/]/g, "_");
      lines.push(`  "${safeName}" -> "${safeDep}";`);
    }
  }
  lines.push("}");
  if (flags.json) {
    ui?.json?.({ dot: lines.join("\n") });
  } else {
    for (const line of lines) {
      ui?.write?.(line);
    }
    ui?.write?.("");
    ui?.write?.("# Save to file and visualize with:");
    ui?.write?.("# dot -Tpng dependencies.dot -o dependencies.png");
  }
}

export { build_order_default as buildOrder, check_builds_default as checkBuilds, check_tests_default as checkTests, check_types_default as checkTypes, cycles_default as cycles, dead_code_default as deadCode, fix_deps_default as fixDeps, health_default as health, stats_default as stats, visualize_default as visualize };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map