// src/actions/dead/dead.ts
import fs7 from "node:fs";
import path8 from "node:path";
import chalk2 from "chalk";

// src/pm/workspaces.ts
import { existsSync, readFileSync } from "node:fs";
import PATH from "node:path";
import { globSync } from "glob";
function readJsonFile(path9) {
  if (!existsSync(path9)) return void 0;
  try {
    return JSON.parse(readFileSync(path9, "utf8"));
  } catch {
    return void 0;
  }
}
function readRootPackageJson(cwd = process.cwd()) {
  return readJsonFile(PATH.resolve(cwd, "package.json"));
}
function readWorkspacePatternsFromPackageJson(cwd = process.cwd()) {
  const pkg = readRootPackageJson(cwd);
  if (!pkg?.workspaces) return [];
  if (Array.isArray(pkg.workspaces)) return [...pkg.workspaces];
  return pkg.workspaces.packages ? [...pkg.workspaces.packages] : [];
}
function readPnpmWorkspacePatterns(cwd = process.cwd()) {
  const wsPath = PATH.resolve(cwd, "pnpm-workspace.yaml");
  if (!existsSync(wsPath)) return [];
  const content = readFileSync(wsPath, "utf8");
  const patterns = [];
  let inPackages = false;
  for (const line of content.split("\n")) {
    if (/^packages\s*:/.test(line.trim())) {
      inPackages = true;
      continue;
    }
    if (inPackages) {
      const match = /^\s+-\s+['"]?([^'"]+)['"]?\s*$/.exec(line);
      if (match) {
        patterns.push(match[1]);
      } else if (line.trim() !== "" && !/^\s/.test(line)) {
        break;
      }
    }
  }
  return patterns;
}
function readWorkspacePatterns(cwd = process.cwd()) {
  const fromPackageJson = readWorkspacePatternsFromPackageJson(cwd);
  return fromPackageJson.length > 0 ? fromPackageJson : readPnpmWorkspacePatterns(cwd);
}
function detectPackageManagerFromPackageJson(cwd = process.cwd()) {
  const packageManager = readRootPackageJson(cwd)?.packageManager;
  if (!packageManager) return void 0;
  return packageManager.split("@")[0];
}

// src/pm/detectPackageManager.ts
import { existsSync as existsSync2 } from "node:fs";
var knownPackageManagers = /* @__PURE__ */ new Set(["bun", "npm", "pnpm", "yarn"]);
function detectPackageManager() {
  const packageManager = detectPackageManagerFromPackageJson();
  if (packageManager && knownPackageManagers.has(packageManager)) {
    return packageManager;
  }
  if (existsSync2("pnpm-lock.yaml") || existsSync2("pnpm-workspace.yaml")) return "pnpm";
  if (existsSync2("bun.lock") || existsSync2("bun.lockb")) return "bun";
  if (existsSync2("yarn.lock") || existsSync2(".yarnrc.yml")) return "yarn";
  if (existsSync2("package-lock.json") || existsSync2("npm-shrinkwrap.json")) return "npm";
  return "yarn";
}

// src/pm/registry.ts
var implementations = /* @__PURE__ */ new Map();
function getPackageManager(name) {
  const pmName = name ?? detectPackageManager();
  const pm = implementations.get(pmName);
  if (!pm) {
    throw new Error(
      `No package manager implementation registered for "${pmName}". Ensure registerPackageManager() has been called before getPackageManager().`
    );
  }
  return pm;
}

// src/lib/initCwd.ts
function INIT_CWD() {
  return process.env.INIT_CWD ?? process.cwd();
}

// src/lib/reporting/xyReporter.ts
var jsonMode = false;
function isJsonMode() {
  return jsonMode;
}

// src/actions/dead/analyzePackage.ts
import path4 from "node:path";

// src/actions/deplint/findFiles.ts
import fs from "node:fs";
import path from "node:path";
import picomatch from "picomatch";
import ts from "typescript";

// src/actions/deplint/findFilesByGlob.ts
import { globSync as globSync2 } from "glob";
function findFilesByGlob(cwd, pattern, ignore) {
  return globSync2(pattern, {
    cwd,
    absolute: true,
    ignore,
    nodir: true,
    dot: true
  });
}

// src/actions/deplint/findFiles.ts
var codeExtensions = "*.{ts,tsx,mts,cts,js,mjs,cjs}";
var codeExtensionRe = /\.(?:ts|tsx|mts|cts|js|mjs|cjs)$/i;
var resolutionExtensions = [".mjs", ".cjs", ".js", ".d.mts", ".d.cts", ".d.ts", ".mts", ".cts", ".ts", ".tsx"];
var dotfileIgnorePatterns = [
  "**/.git/**",
  "**/.yarn/**",
  "**/.pnpm/**",
  "**/.pnpm-store/**",
  "**/.next/**",
  "**/.nuxt/**",
  "**/.svelte-kit/**",
  "**/.angular/**",
  "**/.vercel/**",
  "**/.netlify/**",
  "**/.turbo/**",
  "**/.cache/**",
  "**/.parcel-cache/**",
  "**/.docusaurus/**",
  "**/.vite/**",
  "**/.output/**"
];
function normalizeSourceExcludePattern(location, pattern) {
  const trimmed = pattern.trim();
  if (trimmed === "" || trimmed.startsWith("!")) return void 0;
  const relativePattern = path.isAbsolute(trimmed) ? path.relative(location, trimmed) : trimmed;
  if (relativePattern.startsWith("..")) return void 0;
  return relativePattern.replaceAll(path.sep, "/").replace(/^\.\//, "");
}
function toSourceIgnorePatterns(location, sourceExclude = []) {
  const patterns = /* @__PURE__ */ new Set();
  for (const exclude of sourceExclude) {
    const pattern = normalizeSourceExcludePattern(location, exclude);
    if (!pattern) continue;
    patterns.add(pattern);
    if (!pattern.endsWith("/**")) patterns.add(`${pattern}/**`);
  }
  return [...patterns];
}
function createSourceFileFilter(location, sourceIgnorePatterns) {
  if (sourceIgnorePatterns.length === 0) return () => true;
  const isIgnored = picomatch(sourceIgnorePatterns, { dot: true });
  return (filePath) => {
    const relativePath = path.relative(location, filePath).replaceAll(path.sep, "/");
    return !isIgnored(relativePath);
  };
}
function readPackageJson(location) {
  try {
    return JSON.parse(fs.readFileSync(`${location}/package.json`, "utf8"));
  } catch {
    return void 0;
  }
}
function collectExportTargets(value) {
  if (typeof value === "string") return value.startsWith("./") ? [value] : [];
  if (Array.isArray(value)) return value.flatMap(collectExportTargets);
  if (typeof value !== "object" || value === null) return [];
  return Object.values(value).flatMap(collectExportTargets);
}
function getManifestRuntimeEntries(pkg) {
  return [
    ...collectExportTargets(pkg?.exports),
    pkg?.main,
    pkg?.module,
    pkg?.types,
    pkg?.typings
  ].filter((entry) => typeof entry === "string");
}
function getBinEntries(pkg) {
  const bin = pkg?.bin;
  if (!bin) return [];
  return typeof bin === "string" ? [bin] : Object.values(bin).filter((entry) => typeof entry === "string");
}
function mayResolveToCode(entry) {
  const ext = path.extname(entry);
  return ext === "" || codeExtensionRe.test(entry);
}
function resolveCodeFile(filePath) {
  if (fs.existsSync(filePath) && codeExtensionRe.test(filePath)) return filePath;
  const ext = path.extname(filePath);
  if (ext) {
    const withoutExt = filePath.slice(0, -ext.length);
    for (const candidateExt of resolutionExtensions) {
      const candidate = `${withoutExt}${candidateExt}`;
      if (fs.existsSync(candidate)) return candidate;
    }
  }
  for (const ext2 of resolutionExtensions) {
    const candidate = `${filePath}${ext2}`;
    if (fs.existsSync(candidate)) return candidate;
  }
  for (const ext2 of resolutionExtensions) {
    const candidate = path.join(filePath, `index${ext2}`);
    if (fs.existsSync(candidate)) return candidate;
  }
  return void 0;
}
function resolveRuntimeEntry(location, entry) {
  if (path.isAbsolute(entry)) return [];
  const relativeEntry = entry.startsWith(".") ? entry : `./${entry}`;
  if (relativeEntry.includes("*")) return findFilesByGlob(location, relativeEntry).filter((file) => codeExtensionRe.test(file));
  const resolved = resolveCodeFile(path.resolve(location, relativeEntry));
  return resolved ? [resolved] : [];
}
function collectLocalImportSpecifiers(filePath) {
  const sourceCode = fs.readFileSync(filePath, "utf8");
  const isJsFile = /\.(?:js|mjs|cjs)$/i.test(filePath);
  const sourceFile = ts.createSourceFile(
    path.basename(filePath),
    sourceCode,
    ts.ScriptTarget.Latest,
    true,
    isJsFile ? ts.ScriptKind.JS : void 0
  );
  const imports = [];
  function addModuleSpecifier(moduleSpecifier) {
    if (moduleSpecifier && ts.isStringLiteral(moduleSpecifier) && moduleSpecifier.text.startsWith(".")) {
      imports.push(moduleSpecifier.text);
    }
  }
  function visit(node) {
    if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
      addModuleSpecifier(node.moduleSpecifier);
    } else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
      addModuleSpecifier(node.arguments[0]);
    } else if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "require" && node.arguments.length > 0) {
      addModuleSpecifier(node.arguments[0]);
    }
    ts.forEachChild(node, visit);
  }
  visit(sourceFile);
  return imports;
}
function getReachableRuntimeFiles(runtimeRoots, shouldIncludeFile) {
  const seen = /* @__PURE__ */ new Set();
  const queue = runtimeRoots.filter(shouldIncludeFile);
  const result = [];
  while (queue.length > 0) {
    const file = queue.shift();
    if (!file || seen.has(file)) continue;
    if (!shouldIncludeFile(file)) continue;
    seen.add(file);
    result.push(file);
    for (const specifier of collectLocalImportSpecifiers(file)) {
      const resolved = resolveCodeFile(path.resolve(path.dirname(file), specifier));
      if (resolved && shouldIncludeFile(resolved) && !seen.has(resolved)) queue.push(resolved);
    }
  }
  return result;
}
function getBinFiles(location, pkg) {
  const bin = pkg?.bin;
  if (!bin) return [];
  const entries = typeof bin === "string" ? [bin] : Object.values(bin);
  const results = [];
  for (const entry of entries) {
    if (typeof entry !== "string") continue;
    const abs = path.resolve(location, entry);
    if (!codeExtensionRe.test(abs)) continue;
    if (!fs.existsSync(abs)) continue;
    results.push(abs);
  }
  return results;
}
function uniqueFiles(...lists) {
  const seen = /* @__PURE__ */ new Set();
  const result = [];
  for (const list of lists) {
    for (const file of list) {
      if (seen.has(file)) continue;
      seen.add(file);
      result.push(file);
    }
  }
  return result;
}
function findFiles(location, sourceExclude) {
  const pkg = readPackageJson(location);
  const workspaceIgnores = readWorkspacePatterns(location).filter((p) => !p.startsWith("!")).map((w) => `${w}/**`);
  const sourceIgnorePatterns = toSourceIgnorePatterns(location, sourceExclude);
  const shouldIncludeFile = createSourceFileFilter(location, sourceIgnorePatterns);
  const ignore = [
    "**/node_modules/**",
    "dist/**",
    ...dotfileIgnorePatterns,
    ...workspaceIgnores,
    ...sourceIgnorePatterns
  ];
  const allFiles = findFilesByGlob(location, `./**/${codeExtensions}`, ignore);
  const manifestRuntimeEntries = getManifestRuntimeEntries(pkg);
  const runtimeEntries = [...new Set([
    ...manifestRuntimeEntries,
    ...getBinEntries(pkg)
  ].filter(mayResolveToCode))];
  const binFiles = getBinFiles(location, pkg);
  const manifestRuntimeFiles = manifestRuntimeEntries.flatMap((entry) => resolveRuntimeEntry(location, entry));
  const runtimeRoots = uniqueFiles(manifestRuntimeFiles, binFiles);
  const distFiles = getReachableRuntimeFiles(runtimeRoots, shouldIncludeFile);
  return {
    allFiles,
    distFiles,
    runtimeRoots: runtimeEntries
  };
}

// src/actions/dead/collectSymbols.ts
import fs2 from "node:fs";
import path2 from "node:path";
import ts2 from "typescript";
function getLineCol(sourceFile, pos) {
  const lc = sourceFile.getLineAndCharacterOfPosition(pos);
  return { column: lc.character + 1, line: lc.line + 1 };
}
function hasExportModifier(node) {
  if (!ts2.canHaveModifiers(node)) return false;
  const mods = ts2.getModifiers(node);
  if (!mods) return false;
  return mods.some((m) => m.kind === ts2.SyntaxKind.ExportKeyword);
}
function hasDefaultModifier(node) {
  if (!ts2.canHaveModifiers(node)) return false;
  const mods = ts2.getModifiers(node);
  if (!mods) return false;
  return mods.some((m) => m.kind === ts2.SyntaxKind.DefaultKeyword);
}
function pushDeclaration(declarations, sourceFile, name, nameNode, exported, exportedAs) {
  const { line, column } = getLineCol(sourceFile, nameNode.getStart(sourceFile));
  declarations.push({
    column,
    exported,
    exportedAs,
    line,
    name
  });
}
function tryNamedDeclaration(node) {
  if (ts2.isFunctionDeclaration(node) && node.name) return { name: node.name };
  if (ts2.isClassDeclaration(node) && node.name) return { name: node.name };
  if (ts2.isInterfaceDeclaration(node)) return { name: node.name };
  if (ts2.isTypeAliasDeclaration(node)) return { name: node.name };
  if (ts2.isEnumDeclaration(node)) return { name: node.name };
  if (ts2.isModuleDeclaration(node) && node.name && ts2.isIdentifier(node.name)) return { name: node.name };
  return void 0;
}
function collectBindingNames(node, push) {
  if (ts2.isIdentifier(node)) {
    push(node.text);
    return;
  }
  if (ts2.isObjectBindingPattern(node) || ts2.isArrayBindingPattern(node)) {
    for (const el of node.elements) {
      if (ts2.isBindingElement(el)) collectBindingNames(el.name, push);
    }
  }
}
function handleVariableStatement(node, declarations, sourceFile) {
  const exported = hasExportModifier(node);
  for (const decl of node.declarationList.declarations) {
    collectBindingNames(decl.name, (name) => {
      pushDeclaration(declarations, sourceFile, name, decl.name, exported, name);
    });
  }
}
function handleExportAssignment(node, declarations, sourceFile) {
  const pos = getLineCol(sourceFile, node.getStart(sourceFile));
  if (ts2.isIdentifier(node.expression)) {
    const name = node.expression.text;
    const existing = declarations.find((d) => d.name === name);
    if (existing) {
      existing.exported = true;
      existing.exportedAs = "default";
    }
  }
  return pos;
}
function handleNamedExportClauseWithModule(clause, moduleSpec, reExportsFromRelative) {
  for (const element of clause.elements) {
    const exportedName = element.name.text;
    const importedName = element.propertyName?.text ?? exportedName;
    reExportsFromRelative.push({
      exportedAs: exportedName,
      imported: importedName,
      specifier: moduleSpec
    });
  }
}
function handleNamedExportClauseLocal(clause, declarations) {
  for (const element of clause.elements) {
    const exportedName = element.name.text;
    const importedName = element.propertyName?.text ?? exportedName;
    const existing = declarations.find((d) => d.name === importedName);
    if (existing) {
      existing.exported = true;
      existing.exportedAs = exportedName;
    }
  }
}
function handleExportDeclaration(node, declarations, reExportsFromRelative, reExportAllFromRelative) {
  const moduleSpec = node.moduleSpecifier && ts2.isStringLiteral(node.moduleSpecifier) ? node.moduleSpecifier.text : void 0;
  const isRelative = moduleSpec?.startsWith(".") ?? false;
  if (node.exportClause && ts2.isNamedExports(node.exportClause)) {
    if (moduleSpec && isRelative) {
      handleNamedExportClauseWithModule(node.exportClause, moduleSpec, reExportsFromRelative);
    } else if (!moduleSpec) {
      handleNamedExportClauseLocal(node.exportClause, declarations);
    }
    return;
  }
  if (!node.exportClause && moduleSpec && isRelative) {
    reExportAllFromRelative.add(moduleSpec);
  }
}
function visitTopLevel(node, ctx) {
  const named = tryNamedDeclaration(node);
  if (named?.name) {
    pushDeclaration(
      ctx.declarations,
      ctx.sourceFile,
      named.name.text,
      named.name,
      hasExportModifier(node),
      hasDefaultModifier(node) ? "default" : named.name.text
    );
    return;
  }
  if (ts2.isVariableStatement(node)) {
    handleVariableStatement(node, ctx.declarations, ctx.sourceFile);
    return;
  }
  if (ts2.isExportAssignment(node)) {
    ctx.setDefaultExport(handleExportAssignment(node, ctx.declarations, ctx.sourceFile));
    return;
  }
  if (ts2.isExportDeclaration(node)) {
    handleExportDeclaration(node, ctx.declarations, ctx.reExportsFromRelative, ctx.reExportAllFromRelative);
  }
}
function handleNamedImports(spec, clause, ctx) {
  for (const element of clause.elements) {
    const importedName = element.propertyName?.text ?? element.name.text;
    const alias = element.name.text;
    ctx.importBindingNames.add(alias);
    ctx.namedImportsFromRelative.push({
      alias,
      imported: importedName,
      specifier: spec
    });
  }
}
function visitImports(node, ctx) {
  if (!ts2.isImportDeclaration(node)) return;
  if (!ts2.isStringLiteral(node.moduleSpecifier)) return;
  const spec = node.moduleSpecifier.text;
  if (!spec.startsWith(".")) return;
  const clause = node.importClause;
  if (!clause) {
    ctx.sideEffectFromRelative.add(spec);
    return;
  }
  if (clause.name) {
    const alias = clause.name.text;
    ctx.importBindingNames.add(alias);
    ctx.namedImportsFromRelative.push({
      alias,
      imported: "default",
      specifier: spec
    });
  }
  if (clause.namedBindings) {
    if (ts2.isNamespaceImport(clause.namedBindings)) {
      ctx.importBindingNames.add(clause.namedBindings.name.text);
      ctx.namespaceImportFromRelative.add(spec);
    } else if (ts2.isNamedImports(clause.namedBindings)) {
      handleNamedImports(spec, clause.namedBindings, ctx);
    }
  }
}
function isTopLevelDeclarationName(node, parent) {
  if (ts2.isFunctionDeclaration(parent) && parent.name === node) return true;
  if (ts2.isClassDeclaration(parent) && parent.name === node) return true;
  if (ts2.isInterfaceDeclaration(parent) && parent.name === node) return true;
  if (ts2.isTypeAliasDeclaration(parent) && parent.name === node) return true;
  if (ts2.isEnumDeclaration(parent) && parent.name === node) return true;
  if (ts2.isModuleDeclaration(parent) && parent.name === node) return true;
  return false;
}
function isLocalBindingName(node, parent) {
  if (ts2.isVariableDeclaration(parent) && parent.name === node) return true;
  if (ts2.isParameter(parent) && parent.name === node) return true;
  if (ts2.isBindingElement(parent) && parent.name === node) return true;
  return false;
}
function isMemberName(node, parent) {
  if (ts2.isPropertyAssignment(parent) && parent.name === node) return true;
  if (ts2.isPropertyDeclaration(parent) && parent.name === node) return true;
  if (ts2.isMethodDeclaration(parent) && parent.name === node) return true;
  if (ts2.isPropertySignature(parent) && parent.name === node) return true;
  if (ts2.isMethodSignature(parent) && parent.name === node) return true;
  return false;
}
function isImportExportBindingName(node, parent) {
  if (ts2.isImportSpecifier(parent) && (parent.name === node || parent.propertyName === node)) return true;
  if (ts2.isImportClause(parent) && parent.name === node) return true;
  if (ts2.isNamespaceImport(parent) && parent.name === node) return true;
  if (ts2.isExportSpecifier(parent) && (parent.name === node || parent.propertyName === node)) return true;
  return false;
}
function isQualifiedMemberAccess(node, parent) {
  if (ts2.isQualifiedName(parent) && parent.right === node) return true;
  if (ts2.isPropertyAccessExpression(parent) && parent.name === node) return true;
  return false;
}
function isDeclarationOrBindingPosition(node, parent) {
  return isTopLevelDeclarationName(node, parent) || isLocalBindingName(node, parent) || isMemberName(node, parent) || isImportExportBindingName(node, parent) || isQualifiedMemberAccess(node, parent);
}
function visitForReferences(node, identifierRefs) {
  if (ts2.isIdentifier(node)) {
    const parent = node.parent;
    if (!parent || !isDeclarationOrBindingPosition(node, parent)) {
      identifierRefs.add(node.text);
    }
  }
  ts2.forEachChild(node, (child) => visitForReferences(child, identifierRefs));
}
function collectSymbolsFromFile(filePath) {
  const sourceText = fs2.readFileSync(filePath, "utf8");
  const isJsLike = /\.(?:js|mjs|cjs)$/i.test(filePath);
  const sourceFile = ts2.createSourceFile(
    path2.basename(filePath),
    sourceText,
    ts2.ScriptTarget.Latest,
    true,
    isJsLike ? ts2.ScriptKind.JS : void 0
  );
  const declarations = [];
  const identifierRefs = /* @__PURE__ */ new Set();
  const namedImportsFromRelative = [];
  const namespaceImportFromRelative = /* @__PURE__ */ new Set();
  const sideEffectFromRelative = /* @__PURE__ */ new Set();
  const reExportsFromRelative = [];
  const reExportAllFromRelative = /* @__PURE__ */ new Set();
  let defaultExport;
  const importBindingNames = /* @__PURE__ */ new Set();
  const topCtx = {
    declarations,
    reExportAllFromRelative,
    reExportsFromRelative,
    setDefaultExport: (pos) => {
      defaultExport = pos;
    },
    sourceFile
  };
  const importCtx = {
    importBindingNames,
    namedImportsFromRelative,
    namespaceImportFromRelative,
    sideEffectFromRelative
  };
  for (const stmt of sourceFile.statements) {
    visitTopLevel(stmt, topCtx);
    visitImports(stmt, importCtx);
  }
  visitForReferences(sourceFile, identifierRefs);
  return {
    declarations,
    defaultExport,
    identifierRefs,
    namedImportsFromRelative,
    namespaceImportFromRelative,
    reExportAllFromRelative,
    reExportsFromRelative,
    sideEffectFromRelative
  };
}

// src/actions/dead/runtimeEntries.ts
import fs3 from "node:fs";
import path3 from "node:path";
var codeExtensionRe2 = /\.(?:ts|tsx|mts|cts|js|mjs|cjs)$/i;
var resolutionExtensions2 = [".mjs", ".cjs", ".js", ".d.mts", ".d.cts", ".d.ts", ".mts", ".cts", ".ts", ".tsx"];
function readPackageManifest(location) {
  try {
    return JSON.parse(fs3.readFileSync(path3.join(location, "package.json"), "utf8"));
  } catch {
    return void 0;
  }
}
function collectExportTargets2(value) {
  if (typeof value === "string") return value.startsWith("./") ? [value] : [];
  if (Array.isArray(value)) return value.flatMap(collectExportTargets2);
  if (typeof value !== "object" || value === null) return [];
  return Object.values(value).flatMap(collectExportTargets2);
}
function resolveCodeFile2(filePath) {
  if (fs3.existsSync(filePath) && codeExtensionRe2.test(filePath)) return filePath;
  const ext = path3.extname(filePath);
  if (ext) {
    const withoutExt = filePath.slice(0, -ext.length);
    for (const candidateExt of resolutionExtensions2) {
      const candidate = `${withoutExt}${candidateExt}`;
      if (fs3.existsSync(candidate)) return candidate;
    }
  }
  for (const candidateExt of resolutionExtensions2) {
    const candidate = `${filePath}${candidateExt}`;
    if (fs3.existsSync(candidate)) return candidate;
  }
  for (const candidateExt of resolutionExtensions2) {
    const candidate = path3.join(filePath, `index${candidateExt}`);
    if (fs3.existsSync(candidate)) return candidate;
  }
  return void 0;
}
function resolveManifestEntry(location, entry) {
  if (path3.isAbsolute(entry)) return void 0;
  if (entry.includes("*")) return void 0;
  const relativeEntry = entry.startsWith(".") ? entry : `./${entry}`;
  return resolveCodeFile2(path3.resolve(location, relativeEntry));
}
function getRuntimeRootFiles(location, manifest) {
  if (!manifest) return [];
  const candidates = [
    ...collectExportTargets2(manifest.exports),
    manifest.main,
    manifest.module,
    manifest.types,
    manifest.typings
  ].filter((entry) => typeof entry === "string");
  const bin = manifest.bin;
  if (bin) {
    if (typeof bin === "string") candidates.push(bin);
    else for (const value of Object.values(bin)) if (typeof value === "string") candidates.push(value);
  }
  const seen = /* @__PURE__ */ new Set();
  const results = [];
  for (const entry of candidates) {
    const resolved = resolveManifestEntry(location, entry);
    if (!resolved || seen.has(resolved)) continue;
    const distMapped = mapDistToSrc(location, resolved);
    const final = distMapped ?? resolved;
    if (seen.has(final)) continue;
    seen.add(final);
    results.push(final);
  }
  return results;
}
function mapDistToSrc(location, file) {
  const rel = path3.relative(location, file);
  if (!rel.startsWith("dist" + path3.sep) && !rel.startsWith("dist/")) return void 0;
  const tail = rel.slice("dist".length).replace(/^[\\/]/, "");
  const tailNoExt = tail.replace(/\.(?:mjs|cjs|js|d\.mts|d\.cts|d\.ts)$/i, "");
  const candidates = [
    path3.join(location, "src", tailNoExt),
    path3.join(location, "src", tailNoExt + ".ts"),
    path3.join(location, "src", tailNoExt + ".tsx"),
    path3.join(location, "src", tailNoExt + ".mts"),
    path3.join(location, "src", tailNoExt + ".cts")
  ];
  for (const candidate of candidates) {
    const resolved = resolveCodeFile2(candidate);
    if (resolved) return resolved;
  }
  return void 0;
}

// src/actions/dead/analyzePackage.ts
function isAnalyzableFile(file) {
  if (!codeExtensionRe2.test(file)) return false;
  if (file.endsWith(".d.ts") || file.endsWith(".d.mts") || file.endsWith(".d.cts")) return false;
  return true;
}
function resolveRelativeImport(fromFile, specifier) {
  return resolveCodeFile2(path4.resolve(path4.dirname(fromFile), specifier));
}
function loadReports(files) {
  const reports = [];
  for (const file of files) {
    if (!isAnalyzableFile(file)) continue;
    const symbols = collectSymbolsFromFile(file);
    const resolvedRelative = /* @__PURE__ */ new Map();
    const specifiers = /* @__PURE__ */ new Set([
      ...symbols.namedImportsFromRelative.map((i) => i.specifier),
      ...symbols.namespaceImportFromRelative,
      ...symbols.sideEffectFromRelative,
      ...symbols.reExportsFromRelative.map((r) => r.specifier),
      ...symbols.reExportAllFromRelative
    ]);
    for (const spec of specifiers) {
      const resolved = resolveRelativeImport(file, spec);
      if (resolved) resolvedRelative.set(spec, resolved);
    }
    reports.push({
      file,
      resolvedRelative,
      symbols
    });
  }
  return reports;
}
function computeCrossFileUsage(reports) {
  const namedSymbolUsage = /* @__PURE__ */ new Map();
  const filesWithFullExportUse = /* @__PURE__ */ new Set();
  function addNamed(targetFile, name) {
    let bucket = namedSymbolUsage.get(targetFile);
    if (!bucket) {
      bucket = /* @__PURE__ */ new Set();
      namedSymbolUsage.set(targetFile, bucket);
    }
    bucket.add(name);
  }
  for (const report of reports) {
    for (const named of report.symbols.namedImportsFromRelative) {
      const target = report.resolvedRelative.get(named.specifier);
      if (target) addNamed(target, named.imported);
    }
    for (const reExport of report.symbols.reExportsFromRelative) {
      const target = report.resolvedRelative.get(reExport.specifier);
      if (target) addNamed(target, reExport.imported);
    }
    for (const spec of report.symbols.namespaceImportFromRelative) {
      const target = report.resolvedRelative.get(spec);
      if (target) filesWithFullExportUse.add(target);
    }
    for (const spec of report.symbols.reExportAllFromRelative) {
      const target = report.resolvedRelative.get(spec);
      if (target) filesWithFullExportUse.add(target);
    }
  }
  return { filesWithFullExportUse, namedSymbolUsage };
}
function computeReachableFiles(reports, runtimeRoots) {
  const reachable = /* @__PURE__ */ new Set();
  const byFile = new Map(reports.map((r) => [r.file, r]));
  const queue = [];
  for (const root of runtimeRoots) {
    if (byFile.has(root) && !reachable.has(root)) {
      reachable.add(root);
      queue.push(root);
    }
  }
  while (queue.length > 0) {
    const current = queue.shift();
    if (!current) break;
    const report = byFile.get(current);
    if (!report) continue;
    for (const target of report.resolvedRelative.values()) {
      if (!byFile.has(target) || reachable.has(target)) continue;
      reachable.add(target);
      queue.push(target);
    }
  }
  return reachable;
}
function getStarExports(file, ctx) {
  const cached = ctx.starExportMemo.get(file);
  if (cached) return cached;
  if (ctx.visiting.has(file)) return /* @__PURE__ */ new Map();
  ctx.visiting.add(file);
  const out = /* @__PURE__ */ new Map();
  const report = ctx.byFile.get(file);
  if (report) {
    for (const decl of report.symbols.declarations) {
      if (!decl.exported || !decl.exportedAs || decl.exportedAs === "default") continue;
      out.set(decl.exportedAs, {
        column: decl.column,
        file,
        line: decl.line
      });
    }
    for (const reExport of report.symbols.reExportsFromRelative) {
      if (reExport.exportedAs === "default") continue;
      const target = report.resolvedRelative.get(reExport.specifier);
      const origin = target ? findOrigin(target, reExport.imported, ctx) : void 0;
      out.set(reExport.exportedAs, origin ?? {
        column: 1,
        file,
        line: 1
      });
    }
    for (const spec of report.symbols.reExportAllFromRelative) {
      const target = report.resolvedRelative.get(spec);
      if (!target) continue;
      const child = getStarExports(target, ctx);
      for (const [name, origin] of child) {
        if (!out.has(name)) out.set(name, origin);
      }
    }
  }
  ctx.visiting.delete(file);
  ctx.starExportMemo.set(file, out);
  return out;
}
function findOrigin(targetFile, name, ctx) {
  const stars = getStarExports(targetFile, ctx);
  return stars.get(name);
}
function addDirectDeclarations(report, rootFile, results) {
  for (const decl of report.symbols.declarations) {
    if (!decl.exported || !decl.exportedAs) continue;
    const name = decl.exportedAs;
    if (results.has(name)) continue;
    results.set(name, {
      column: decl.column,
      file: rootFile,
      line: decl.line,
      name,
      rootFile
    });
  }
}
function addDefaultExport(report, rootFile, results) {
  const def = report.symbols.defaultExport;
  if (!def || results.has("default")) return;
  results.set("default", {
    column: def.column,
    file: rootFile,
    line: def.line,
    name: "default",
    rootFile
  });
}
function addReExports(report, rootFile, ctx, results) {
  for (const reExport of report.symbols.reExportsFromRelative) {
    const exportedAs = reExport.exportedAs;
    if (results.has(exportedAs)) continue;
    const target = report.resolvedRelative.get(reExport.specifier);
    const origin = target ? findOrigin(target, reExport.imported, ctx) : void 0;
    results.set(exportedAs, {
      column: origin?.column ?? 1,
      file: origin?.file ?? rootFile,
      line: origin?.line ?? 1,
      name: exportedAs,
      rootFile
    });
  }
}
function addReExportAll(report, rootFile, ctx, results) {
  for (const spec of report.symbols.reExportAllFromRelative) {
    const target = report.resolvedRelative.get(spec);
    if (!target) continue;
    const stars = getStarExports(target, ctx);
    for (const [name, origin] of stars) {
      if (results.has(name)) continue;
      results.set(name, {
        column: origin.column,
        file: origin.file,
        line: origin.line,
        name,
        rootFile
      });
    }
  }
}
function collectPublicExports(reports, runtimeRoots) {
  const byFile = new Map(reports.map((r) => [r.file, r]));
  const ctx = {
    byFile,
    results: /* @__PURE__ */ new Map(),
    starExportMemo: /* @__PURE__ */ new Map(),
    visiting: /* @__PURE__ */ new Set()
  };
  const results = /* @__PURE__ */ new Map();
  for (const rootFile of runtimeRoots) {
    const report = byFile.get(rootFile);
    if (!report) continue;
    addDirectDeclarations(report, rootFile, results);
    addDefaultExport(report, rootFile, results);
    addReExports(report, rootFile, ctx, results);
    addReExportAll(report, rootFile, ctx, results);
  }
  return [...results.values()];
}
function makeUnusedLocalFinding(packageName, workspaceLocation, file, decl) {
  return {
    column: decl.column,
    file: path4.relative(workspaceLocation, file),
    kind: "unused-local",
    line: decl.line,
    pkg: packageName,
    symbol: decl.name
  };
}
function analyzePackage(workspace) {
  const location = path4.resolve(workspace.location);
  const manifest = readPackageManifest(location);
  const packageName = manifest && typeof manifest.name === "string" ? manifest.name : workspace.name;
  const { allFiles } = findFiles(location);
  const reports = loadReports(allFiles);
  const runtimeRoots = getRuntimeRootFiles(location, manifest);
  const reachable = computeReachableFiles(reports, runtimeRoots);
  const usage = computeCrossFileUsage(reports);
  const localFindings = [];
  for (const report of reports) {
    const fileHasFullExportUse = usage.filesWithFullExportUse.has(report.file);
    const namedUsesForFile = usage.namedSymbolUsage.get(report.file) ?? /* @__PURE__ */ new Set();
    const fileIsReachable = reachable.has(report.file);
    for (const decl of report.symbols.declarations) {
      const usedInternallyInFile = report.symbols.identifierRefs.has(decl.name);
      if (!decl.exported) {
        if (!usedInternallyInFile) {
          localFindings.push(makeUnusedLocalFinding(packageName, location, report.file, decl));
        }
        continue;
      }
      const exportedAs = decl.exportedAs ?? decl.name;
      const namedConsumed = namedUsesForFile.has(exportedAs) || namedUsesForFile.has(decl.name);
      const consumedByStarOrNamespace = fileHasFullExportUse;
      const onPublicSurface = fileIsReachable;
      const alive = usedInternallyInFile || namedConsumed || consumedByStarOrNamespace || onPublicSurface;
      if (!alive) {
        localFindings.push({
          ...makeUnusedLocalFinding(packageName, location, report.file, decl),
          detail: "exported but not referenced in this package"
        });
      }
    }
  }
  const publicExports = collectPublicExports(reports, runtimeRoots);
  return {
    localFindings,
    packageName,
    publicExports,
    scannedFiles: reports.length,
    workspaceName: workspace.name
  };
}

// src/actions/dead/collectExternalUsage.ts
import fs4 from "node:fs";
import path5 from "node:path";
import ts3 from "typescript";

// src/actions/deplint/getBasePackageName.ts
function getBasePackageName(importName) {
  const importNameScrubbed = importName.replaceAll('"', "").trim();
  if (importNameScrubbed.startsWith("@")) {
    const parts = importNameScrubbed.split("/");
    return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : importNameScrubbed;
  }
  return importNameScrubbed.split("/")[0];
}

// src/actions/dead/collectExternalUsage.ts
function getOrCreateUsage(map, pkg) {
  let entry = map.get(pkg);
  if (!entry) {
    entry = {
      hasDefault: false,
      hasNamespace: false,
      named: /* @__PURE__ */ new Set()
    };
    map.set(pkg, entry);
  }
  return entry;
}
function recordSpecifier(summary, targets, out) {
  const base = getBasePackageName(summary.spec);
  if (!targets.has(base)) return;
  const usage = getOrCreateUsage(out, base);
  if (summary.namespace) usage.hasNamespace = true;
  if (summary.defaultBinding) usage.hasDefault = true;
  for (const n of summary.named) {
    usage.named.add(n.imported === "default" ? "default" : n.imported);
  }
}
function summarizeImportDeclaration(node) {
  if (!ts3.isStringLiteral(node.moduleSpecifier)) return void 0;
  const summary = {
    defaultBinding: false,
    named: [],
    namespace: false,
    spec: node.moduleSpecifier.text
  };
  const clause = node.importClause;
  if (!clause) return summary;
  if (clause.name) {
    summary.defaultBinding = true;
    summary.named.push({ alias: clause.name.text, imported: "default" });
  }
  if (clause.namedBindings) {
    if (ts3.isNamespaceImport(clause.namedBindings)) summary.namespace = true;
    else if (ts3.isNamedImports(clause.namedBindings)) {
      for (const element of clause.namedBindings.elements) {
        const importedName = element.propertyName?.text ?? element.name.text;
        summary.named.push({ alias: element.name.text, imported: importedName });
      }
    }
  }
  return summary;
}
function summarizeExportDeclaration(node) {
  if (!node.moduleSpecifier || !ts3.isStringLiteral(node.moduleSpecifier)) return void 0;
  const summary = {
    defaultBinding: false,
    named: [],
    namespace: false,
    spec: node.moduleSpecifier.text
  };
  if (!node.exportClause) {
    summary.namespace = true;
    return summary;
  }
  if (ts3.isNamedExports(node.exportClause)) {
    for (const element of node.exportClause.elements) {
      const importedName = element.propertyName?.text ?? element.name.text;
      summary.named.push({ alias: element.name.text, imported: importedName });
    }
  } else if (ts3.isNamespaceExport(node.exportClause)) {
    summary.namespace = true;
  }
  return summary;
}
function summarizeDynamicImport(node) {
  if (node.expression.kind !== ts3.SyntaxKind.ImportKeyword) return void 0;
  if (node.arguments.length === 0 || !ts3.isStringLiteral(node.arguments[0])) return void 0;
  return {
    defaultBinding: false,
    named: [],
    namespace: true,
    spec: node.arguments[0].text
  };
}
function summarizeNode(node) {
  if (ts3.isImportDeclaration(node)) return summarizeImportDeclaration(node);
  if (ts3.isExportDeclaration(node)) return summarizeExportDeclaration(node);
  if (ts3.isCallExpression(node)) return summarizeDynamicImport(node);
  return void 0;
}
function collectFromFile(file, targets, out) {
  let sourceText;
  try {
    sourceText = fs4.readFileSync(file, "utf8");
  } catch {
    return;
  }
  const isJsLike = /\.(?:js|mjs|cjs)$/i.test(file);
  const sourceFile = ts3.createSourceFile(
    path5.basename(file),
    sourceText,
    ts3.ScriptTarget.Latest,
    true,
    isJsLike ? ts3.ScriptKind.JS : void 0
  );
  function visit(node) {
    const summary = summarizeNode(node);
    if (summary) recordSpecifier(summary, targets, out);
    ts3.forEachChild(node, visit);
  }
  visit(sourceFile);
}
function collectExternalUsage(folderRoots, targetPackageNames) {
  const map = /* @__PURE__ */ new Map();
  if (targetPackageNames.size === 0) return map;
  for (const root of folderRoots) {
    let allFiles;
    try {
      ({ allFiles } = findFiles(root));
    } catch {
      continue;
    }
    for (const file of allFiles) {
      if (!codeExtensionRe2.test(file)) continue;
      if (file.endsWith(".d.ts") || file.endsWith(".d.mts") || file.endsWith(".d.cts")) continue;
      collectFromFile(file, targetPackageNames, map);
    }
  }
  return map;
}

// src/actions/dead/findWorkspaceFile.ts
import fs5 from "node:fs";
import path6 from "node:path";
function findCodeWorkspaceFile(startDir) {
  let dir = path6.resolve(startDir);
  while (true) {
    let entries;
    try {
      entries = fs5.readdirSync(dir);
    } catch {
      entries = [];
    }
    const candidates = entries.filter((name) => name.endsWith(".code-workspace"));
    if (candidates.length > 0) {
      candidates.sort((a, b) => a.localeCompare(b));
      const [first, ...rest] = candidates;
      return {
        alternates: rest.length > 0 ? rest.map((name) => path6.join(dir, name)) : void 0,
        path: path6.join(dir, first)
      };
    }
    const parent = path6.dirname(dir);
    if (parent === dir) return void 0;
    dir = parent;
  }
}
function resolveCodeWorkspaceFile(explicit, startDir) {
  if (explicit) {
    const absolute = path6.isAbsolute(explicit) ? explicit : path6.resolve(startDir, explicit);
    if (!fs5.existsSync(absolute)) return void 0;
    return { path: absolute };
  }
  return findCodeWorkspaceFile(startDir);
}

// src/actions/dead/parseCodeWorkspace.ts
import fs6 from "node:fs";
import path7 from "node:path";
function consumeString(input, ctx, quote) {
  ctx.out += input[ctx.i];
  ctx.i += 1;
  while (ctx.i < input.length) {
    const ch = input[ctx.i];
    ctx.out += ch;
    if (ch === "\\" && ctx.i + 1 < input.length) {
      ctx.out += input[ctx.i + 1];
      ctx.i += 2;
      continue;
    }
    if (ch === quote) {
      ctx.i += 1;
      return;
    }
    ctx.i += 1;
  }
}
function consumeLineComment(input, ctx) {
  while (ctx.i < input.length && input[ctx.i] !== "\n") ctx.i += 1;
}
function consumeBlockComment(input, ctx) {
  ctx.i += 2;
  while (ctx.i < input.length && !(input[ctx.i] === "*" && input[ctx.i + 1] === "/")) ctx.i += 1;
  ctx.i += 2;
}
function stripJsonc(input) {
  const ctx = { i: 0, out: "" };
  while (ctx.i < input.length) {
    const ch = input[ctx.i];
    const next = ctx.i + 1 < input.length ? input[ctx.i + 1] : "";
    if (ch === '"' || ch === "'") {
      consumeString(input, ctx, ch);
      continue;
    }
    if (ch === "/" && next === "/") {
      consumeLineComment(input, ctx);
      continue;
    }
    if (ch === "/" && next === "*") {
      consumeBlockComment(input, ctx);
      continue;
    }
    ctx.out += ch;
    ctx.i += 1;
  }
  return ctx.out.replaceAll(/,(\s*[}\]])/g, "$1");
}
function parseWorkspaceJson(workspaceFilePath, stripped) {
  try {
    return JSON.parse(stripped);
  } catch (ex) {
    throw new Error(
      `Failed to parse code-workspace file ${workspaceFilePath}: ${ex instanceof Error ? ex.message : String(ex)}`,
      { cause: ex }
    );
  }
}
function parseCodeWorkspace(workspaceFilePath) {
  const raw = fs6.readFileSync(workspaceFilePath, "utf8");
  const stripped = stripJsonc(raw);
  const parsed = parseWorkspaceJson(workspaceFilePath, stripped);
  if (!parsed.folders || !Array.isArray(parsed.folders)) return [];
  const baseDir = path7.dirname(workspaceFilePath);
  const results = [];
  for (const entry of parsed.folders) {
    if (!entry || typeof entry.path !== "string") continue;
    const rawPath = entry.path;
    const absolutePath = path7.isAbsolute(rawPath) ? rawPath : path7.resolve(baseDir, rawPath);
    results.push({
      absolutePath,
      name: typeof entry.name === "string" ? entry.name : void 0,
      rawPath
    });
  }
  return results;
}

// src/actions/dead/reporters.ts
import chalk from "chalk";
function groupBy(items, keyFn) {
  const out = /* @__PURE__ */ new Map();
  for (const item of items) {
    const key = keyFn(item);
    let bucket = out.get(key);
    if (!bucket) {
      bucket = [];
      out.set(key, bucket);
    }
    bucket.push(item);
  }
  return out;
}
function kindLabel(kind) {
  return kind === "unused-local" ? "unused-local" : "unused-export";
}
function renderHuman(result) {
  if (result.findings.length === 0) {
    console.log(chalk.green(`Dead Code: no findings (${result.summary.scannedFiles} files in ${result.summary.scannedPackages} package${result.summary.scannedPackages === 1 ? "" : "s"})`));
    return;
  }
  const byPkg = groupBy(result.findings, (f) => f.pkg);
  for (const [pkg, findings] of byPkg) {
    console.log(chalk.green(`Dead Code [${pkg}]`));
    findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.column - b.column);
    for (const f of findings) {
      const loc = `${f.file}:${f.line}:${f.column}`;
      const kind = chalk.yellow(kindLabel(f.kind).padEnd(13));
      const detail = f.detail ? chalk.gray(`  (${f.detail})`) : "";
      console.log(`  ${loc.padEnd(40)} ${kind} ${f.symbol}${detail}`);
    }
  }
  const localCount = result.findings.filter((f) => f.kind === "unused-local").length;
  const exportCount = result.findings.filter((f) => f.kind === "unused-export").length;
  console.log(chalk.gray(`
  scanned ${result.summary.scannedFiles} files in ${result.summary.scannedPackages} package${result.summary.scannedPackages === 1 ? "" : "s"}`));
  const parts = [];
  if (localCount > 0) parts.push(`${localCount} unused local${localCount === 1 ? "" : "s"}`);
  if (exportCount > 0) parts.push(`${exportCount} unused export${exportCount === 1 ? "" : "s"}`);
  if (parts.length > 0) console.log(chalk.yellow(`  ${parts.join(", ")}`));
}
function getDeadReporter(format) {
  if (format === "json") {
    return {
      render(result) {
        console.log(JSON.stringify(result, null, 2));
      }
    };
  }
  return { render: renderHuman };
}

// src/actions/dead/dead.ts
function resolveTargets(pkg) {
  const pm = getPackageManager();
  const workspaces = pm.listWorkspaces();
  if (pkg === void 0) return workspaces;
  const target = pm.findWorkspace(pkg);
  return target ? [target] : void 0;
}
var workspaceLocationCache = /* @__PURE__ */ new Map();
function getWorkspaceLocationFor(analysis) {
  const cached = workspaceLocationCache.get(analysis.workspaceName);
  if (cached) return cached;
  const pm = getPackageManager();
  const ws = pm.findWorkspace(analysis.workspaceName) ?? pm.findWorkspace(analysis.packageName);
  const location = ws ? path8.resolve(ws.location) : process.cwd();
  workspaceLocationCache.set(analysis.workspaceName, location);
  return location;
}
function makeUnusedExportFinding(analysis, exp) {
  const fileRel = path8.relative(getWorkspaceLocationFor(analysis), exp.file);
  return {
    column: exp.column,
    detail: "no consumer in workspace",
    file: fileRel,
    kind: "unused-export",
    line: exp.line,
    pkg: analysis.packageName,
    symbol: exp.name
  };
}
function isConsumed(name, pkgUsage) {
  if (pkgUsage.hasNamespace) return true;
  if (name === "default" && pkgUsage.hasDefault) return true;
  return pkgUsage.named.has(name);
}
function collectExportsFindings(analyses, usage) {
  const findings = [];
  for (const analysis of analyses) {
    const pkgUsage = usage.get(analysis.packageName);
    for (const exp of analysis.publicExports) {
      if (!pkgUsage || !isConsumed(exp.name, pkgUsage)) {
        findings.push(makeUnusedExportFinding(analysis, exp));
      }
    }
  }
  return findings;
}
function errorEnvelope(message) {
  if (!isJsonMode()) console.error(chalk2.red(message));
  return {
    envelope: {
      errorCount: 1,
      errors: [{ message }]
    },
    exitCode: 1
  };
}
function logWorkspaceLookup(lookup, verbose) {
  if (!verbose) return;
  console.log(chalk2.gray(`Using code-workspace: ${lookup.path}`));
  if (lookup.alternates?.length) {
    for (const alt of lookup.alternates) console.log(chalk2.gray(`  (also present: ${alt})`));
  }
}
function resolveExternalFolders(workspaceFilePath, ownLocations) {
  const folders = parseCodeWorkspace(workspaceFilePath);
  const externalFolders = [];
  for (const folder of folders) {
    if (!fs7.existsSync(folder.absolutePath)) continue;
    if (!fs7.existsSync(path8.join(folder.absolutePath, "package.json"))) continue;
    if (ownLocations.has(folder.absolutePath)) continue;
    externalFolders.push(folder.absolutePath);
  }
  return externalFolders;
}
function runExportsPass(options, targets, analyses) {
  const lookup = resolveCodeWorkspaceFile(options.workspace, INIT_CWD());
  if (!lookup) {
    const message = options.workspace ? `code-workspace file not found: ${options.workspace}` : "No *.code-workspace file found in any parent of the current directory. Pass --workspace <path>.";
    return errorEnvelope(message);
  }
  logWorkspaceLookup(lookup, options.verbose ?? false);
  const ownLocations = new Set(targets.map((t) => path8.resolve(t.location)));
  const externalFolders = resolveExternalFolders(lookup.path, ownLocations);
  const targetPackageNames = new Set(analyses.map((a) => a.packageName));
  const usage = collectExternalUsage(externalFolders, targetPackageNames);
  return { findings: collectExportsFindings(analyses, usage) };
}
var dead = async (options = {}) => {
  const effectiveFormat = options.format ?? (isJsonMode() ? "json" : "human");
  const targets = resolveTargets(options.pkg);
  if (!targets || targets.length === 0) {
    return errorEnvelope(options.pkg ? `Workspace not found: ${options.pkg}` : "No workspaces found");
  }
  const analyses = targets.map(analyzePackage);
  const allFindings = analyses.flatMap((a) => a.localFindings);
  if (options.exports) {
    const exportsResult = runExportsPass(options, targets, analyses);
    if ("exitCode" in exportsResult) return exportsResult;
    allFindings.push(...exportsResult.findings);
  }
  const summary = {
    errorCount: allFindings.length,
    scannedFiles: analyses.reduce((sum, a) => sum + a.scannedFiles, 0),
    scannedPackages: analyses.length,
    warningCount: 0
  };
  const result = { findings: allFindings, summary };
  if (!isJsonMode()) {
    getDeadReporter(effectiveFormat).render(result);
  }
  return {
    envelope: {
      data: result,
      errorCount: summary.errorCount,
      warningCount: summary.warningCount
    },
    exitCode: summary.errorCount > 0 ? 1 : 0
  };
};
export {
  dead
};
//# sourceMappingURL=dead.mjs.map
