// src/actions/dead/runDeadAnalysis.ts
import fs8 from "node:fs";
import path10 from "node:path";
import chalk2 from "chalk";

// src/lib/deepMerge.ts
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
function isPlainObject(value) {
  if (typeof value !== "object" || value === null) return false;
  const proto = Object.getPrototypeOf(value);
  return proto === Object.prototype || proto === null;
}
function isMergeable(value) {
  return Array.isArray(value) || isPlainObject(value);
}
function cloneValue(value) {
  if (Array.isArray(value)) {
    return value.map((item) => cloneValue(item));
  }
  if (isPlainObject(value)) {
    const result = {};
    for (const [key, item] of Object.entries(value)) {
      if (UNSAFE_KEYS.has(key)) continue;
      result[key] = cloneValue(item);
    }
    return result;
  }
  return value;
}
function mergeObject(target, source, options) {
  const destination = {};
  if (isPlainObject(target)) {
    for (const [key, item] of Object.entries(target)) {
      if (UNSAFE_KEYS.has(key)) continue;
      destination[key] = cloneValue(item);
    }
  }
  for (const [key, sourceValue] of Object.entries(source)) {
    if (UNSAFE_KEYS.has(key)) continue;
    if (Object.hasOwn(target, key) && isMergeable(sourceValue)) {
      const customMerge = options.customMerge?.(key);
      destination[key] = (customMerge ?? deepMerge)(target[key], sourceValue, options);
    } else {
      destination[key] = cloneValue(sourceValue);
    }
  }
  return destination;
}
function deepMerge(target, source, options = {}) {
  const isSourceIsArray = Array.isArray(source);
  const isTargetIsArray = Array.isArray(target);
  if (isSourceIsArray !== isTargetIsArray) {
    return cloneValue(source);
  }
  if (isSourceIsArray) {
    return [...target, ...source].map((item) => cloneValue(item));
  }
  return mergeObject(target, source, options);
}

// src/pm/workspaces.ts
import { existsSync, readFileSync } from "node:fs";
import PATH from "node:path";
import { globSync } from "glob";
function readJsonFile(path11) {
  if (!existsSync(path11)) return void 0;
  try {
    return JSON.parse(readFileSync(path11, "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 isInPackages = false;
  for (const line of content.split("\n")) {
    if (/^packages\s*:/.test(line.trim())) {
      isInPackages = true;
      continue;
    }
    if (isInPackages) {
      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 != null && packageManager.length > 0)) return void 0;
  return packageManager.split("@", 1)[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 != null && packageManager.length > 0 && 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/loadConfig.ts
import chalk from "chalk";
import { cosmiconfig } from "cosmiconfig";
import { TypeScriptLoader } from "cosmiconfig-typescript-loader";
var configState = {
  config: void 0,
  rootConfigPath: void 0
};
var workspaceConfigCache = /* @__PURE__ */ new Map();
var deprecationWarned = /* @__PURE__ */ new Set();
function isRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function createExplorer() {
  return cosmiconfig("xy", { cache: true, loaders: { ".ts": TypeScriptLoader() } });
}
var loadConfig = async (params) => {
  if (configState.config === void 0) {
    const cosmicConfigResult = await createExplorer().search();
    configState.config = cosmicConfigResult?.config ?? {};
    configState.rootConfigPath = cosmicConfigResult?.filepath;
    const configFilePath = cosmicConfigResult?.filepath;
    if (configFilePath !== void 0) {
      console.log(chalk.green(`Loaded config from ${configFilePath}`));
      if (Boolean(configState.config.verbose)) {
        console.log(chalk.gray(JSON.stringify(configState.config, null, 2)));
      }
    }
  }
  return deepMerge(configState.config, params ?? {});
};
async function loadWorkspaceConfig(workspaceDir) {
  const cached = workspaceConfigCache.get(workspaceDir);
  if (cached !== void 0) return cached;
  const result = await createExplorer().search(workspaceDir);
  if (!result || result.filepath === configState.rootConfigPath) {
    workspaceConfigCache.set(workspaceDir, {});
    return {};
  }
  const wsConfig = result.config ?? {};
  workspaceConfigCache.set(workspaceDir, wsConfig);
  return wsConfig;
}
var DEPRECATED_COMMAND_FIELDS = /* @__PURE__ */ new Set(["deplint", "publint"]);
function resolveCommandField(cfg, commandName, configPath) {
  const commands = cfg.commands;
  const fromCommands = commands?.[commandName];
  if (fromCommands !== void 0 && typeof fromCommands === "object") {
    return fromCommands;
  }
  const fromTopLevel = cfg[commandName];
  if (fromTopLevel !== void 0 && typeof fromTopLevel === "object" && DEPRECATED_COMMAND_FIELDS.has(commandName)) {
    const key = `${configPath ?? "unknown"}:${commandName}`;
    if (!deprecationWarned.has(key)) {
      deprecationWarned.add(key);
      console.warn(chalk.yellow(
        `[xy] Deprecated: top-level "${commandName}" in ${configPath ?? "xy.config"} \u2014 move to "commands.${commandName}"`
      ));
    }
    return fromTopLevel;
  }
  return {};
}
function mergeRuleConfigs(target, source) {
  if (isRecord(target) && isRecord(source)) {
    return { ...target, ...source };
  }
  return source;
}
function mergeCommandConfig(rootCmd, workspaceCmd, commandName) {
  return deepMerge(rootCmd, workspaceCmd, {
    customMerge: (key) => (commandName === "deplint" || commandName === "dead") && key === "rules" ? mergeRuleConfigs : void 0
  });
}
async function loadWorkspaceCommandConfig(workspaceDir, commandName) {
  const root = await loadConfig();
  const rootCmd = resolveCommandField(root, commandName, configState.rootConfigPath);
  const wsConfig = await loadWorkspaceConfig(workspaceDir);
  const wsConfigPath = workspaceConfigCache.has(workspaceDir) ? workspaceDir : void 0;
  const wsCmd = resolveCommandField(wsConfig, commandName, wsConfigPath);
  return mergeCommandConfig(rootCmd, wsCmd, commandName);
}

// src/lib/match.ts
import { minimatch } from "minimatch";
function makeMatcher(pattern, options = {}) {
  const patterns = Array.isArray(pattern) ? pattern : [pattern];
  return (input) => patterns.some((p) => minimatch(input, p, options));
}
function isMatch(input, pattern, options = {}) {
  return makeMatcher(pattern, options)(input);
}

// 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 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 != null && pattern.length > 0)) continue;
    patterns.add(pattern);
    if (!pattern.endsWith("/**")) patterns.add(`${pattern}/**`);
  }
  return [...patterns];
}
function createSourceFileFilter(location, sourceIgnorePatterns) {
  if (sourceIgnorePatterns.length === 0) return () => true;
  const isIgnored = makeMatcher(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 === void 0) return [];
  return typeof bin === "string" ? [bin] : Object.values(bin).filter((entry) => typeof entry === "string");
}
function canResolveToCode(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 != null && resolved.length > 0 ? [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 != null && file.length > 0) || 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 != null && resolved.length > 0 && shouldIncludeFile(resolved) && !seen.has(resolved)) queue.push(resolved);
    }
  }
  return result;
}
var launcherNodeTargetRe = /\bnode(?:\.exe)?\b[^\n]*?["']?([^"'\s]+\.(?:mjs|cjs|js))(?=["'\s]|$)/i;
var launcherDirVarRe = /^(?:\$\{?\w+\}?|%\w+%|%~dp0)\/?/;
var MAX_LAUNCHER_BYTES = 64 * 1024;
function resolveLauncherTarget(launcherAbs) {
  try {
    const stat = fs.statSync(launcherAbs);
    if (!stat.isFile() || stat.size > MAX_LAUNCHER_BYTES) return void 0;
    const match = launcherNodeTargetRe.exec(fs.readFileSync(launcherAbs, "utf8"));
    if (!match) return void 0;
    const target = match[1].replaceAll("\\", "/").replace(launcherDirVarRe, "");
    return resolveCodeFile(path.resolve(path.dirname(launcherAbs), target));
  } catch {
    return void 0;
  }
}
function getBinFiles(location, pkg) {
  const bin = pkg?.bin;
  if (bin === void 0) 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)) {
      if (fs.existsSync(abs)) results.push(abs);
      continue;
    }
    if (!fs.existsSync(abs)) continue;
    const launcherTarget = resolveLauncherTarget(abs);
    if (launcherTarget != null && launcherTarget.length > 0) results.push(launcherTarget);
  }
  return results;
}
function appendUniqueFiles(list, seen, result) {
  for (const file of list) {
    if (seen.has(file)) continue;
    seen.add(file);
    result.push(file);
  }
}
function uniqueFiles(...lists) {
  const seen = /* @__PURE__ */ new Set();
  const result = [];
  for (const list of lists) {
    appendUniqueFiles(list, seen, result);
  }
  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(canResolveToCode))];
  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/classifyPackageVisibility.ts
function isScopedPackageName(name) {
  return typeof name === "string" && name.startsWith("@");
}
function classifyPackageVisibility(manifest) {
  if (manifest?.private === true) return "private";
  const access = manifest?.publishConfig;
  if (typeof access === "object" && access !== null && !Array.isArray(access)) {
    const publishAccess = access.access;
    if (publishAccess === "restricted") return "restricted";
    if (publishAccess === "public") return "public";
  }
  if (isScopedPackageName(manifest?.name)) return "restricted";
  return "public";
}

// src/actions/dead/collectSymbols.ts
import fs2 from "node:fs";
import path2 from "node:path";
import ts3 from "typescript";

// src/actions/dead/deprecation.ts
import ts2 from "typescript";
function getLeadingRanges(sourceFile, node) {
  const ranges = [
    ...ts2.getLeadingCommentRanges(sourceFile.text, node.pos) ?? [],
    ...ts2.getLeadingCommentRanges(sourceFile.text, node.getFullStart()) ?? []
  ];
  const seen = /* @__PURE__ */ new Set();
  return ranges.filter((range) => {
    if (seen.has(range.pos)) return false;
    seen.add(range.pos);
    return true;
  });
}
function hasDeprecatedTag(sourceFile, node) {
  for (const range of getLeadingRanges(sourceFile, node)) {
    const text = sourceFile.text.slice(range.pos, range.pos + range.end - range.pos);
    if (/@deprecated\b/.test(text)) return true;
  }
  const jsDocs = ts2.getJSDocCommentsAndTags(node);
  return jsDocs.some((doc) => {
    if (!ts2.isJSDoc(doc)) return false;
    return doc.tags?.some((tag) => tag.tagName.text === "deprecated") === true;
  });
}

// src/actions/dead/collectSymbols.ts
function getLineCol(sourceFile, pos) {
  const lc = sourceFile.getLineAndCharacterOfPosition(pos);
  return { column: lc.character + 1, line: lc.line + 1 };
}
function hasExportModifier(node) {
  if (!ts3.canHaveModifiers(node)) return false;
  const mods = ts3.getModifiers(node);
  if (!mods) return false;
  return mods.some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
}
function hasDefaultModifier(node) {
  if (!ts3.canHaveModifiers(node)) return false;
  const mods = ts3.getModifiers(node);
  if (!mods) return false;
  return mods.some((m) => m.kind === ts3.SyntaxKind.DefaultKeyword);
}
function pushDeclaration(declarations, sourceFile, name, nameNode, isExported, exportedAs, declarationNode) {
  const { line, column } = getLineCol(sourceFile, nameNode.getStart(sourceFile));
  const deprecated = hasDeprecatedTag(sourceFile, declarationNode) ? true : void 0;
  declarations.push({
    column,
    deprecated,
    isExported,
    exportedAs,
    line,
    name
  });
}
function isFunctionOverloadSignature(node) {
  return node.body === void 0;
}
function isGlobalAugmentation(node) {
  return ts3.isIdentifier(node.name) && node.name.text === "global";
}
function tryNamedDeclaration(node) {
  if (ts3.isFunctionDeclaration(node) && node.name) {
    if (isFunctionOverloadSignature(node)) return void 0;
    return { name: node.name };
  }
  if (ts3.isClassDeclaration(node) && node.name) return { name: node.name };
  if (ts3.isInterfaceDeclaration(node)) return { name: node.name };
  if (ts3.isTypeAliasDeclaration(node)) return { name: node.name };
  if (ts3.isEnumDeclaration(node)) return { name: node.name };
  if (ts3.isModuleDeclaration(node) && ts3.isIdentifier(node.name)) {
    if (isGlobalAugmentation(node)) return void 0;
    return { name: node.name };
  }
  return void 0;
}
function collectBindingNames(node, push) {
  if (ts3.isIdentifier(node)) {
    push(node.text);
    return;
  }
  if (ts3.isObjectBindingPattern(node) || ts3.isArrayBindingPattern(node)) {
    for (const el of node.elements) {
      if (ts3.isBindingElement(el)) collectBindingNames(el.name, push);
    }
  }
}
function handleVariableStatement(node, declarations, sourceFile) {
  const isExported = hasExportModifier(node);
  for (const decl of node.declarationList.declarations) {
    collectBindingNames(decl.name, (name) => {
      pushDeclaration(declarations, sourceFile, name, decl.name, isExported, name, node);
    });
  }
}
function handleExportAssignment(node, declarations, sourceFile) {
  if (ts3.isIdentifier(node.expression)) {
    const name = node.expression.text;
    const existing = declarations.find((d) => d.name === name);
    if (existing) {
      existing.isExported = true;
      existing.exportedAs = "default";
    }
  }
  return getLineCol(sourceFile, node.getStart(sourceFile));
}
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 markExportedDeclarations(declarations, importedName, exportedName) {
  for (const existing of declarations) {
    if (existing.name !== importedName) continue;
    existing.isExported = true;
    existing.exportedAs = exportedName;
  }
}
function handleNamedExportClauseLocal(clause, declarations) {
  for (const element of clause.elements) {
    const exportedName = element.name.text;
    const importedName = element.propertyName?.text ?? exportedName;
    markExportedDeclarations(declarations, importedName, exportedName);
  }
}
function handleExportDeclaration(node, declarations, reExportsFromRelative, reExportAllFromRelative) {
  const moduleSpec = node.moduleSpecifier && ts3.isStringLiteral(node.moduleSpecifier) ? node.moduleSpecifier.text : void 0;
  const isRelative = moduleSpec?.startsWith(".") ?? false;
  if (node.exportClause && ts3.isNamedExports(node.exportClause)) {
    if (moduleSpec != null && moduleSpec.length > 0 && isRelative) {
      handleNamedExportClauseWithModule(node.exportClause, moduleSpec, reExportsFromRelative);
    } else if (!(moduleSpec != null && moduleSpec.length > 0)) {
      handleNamedExportClauseLocal(node.exportClause, declarations);
    }
    return;
  }
  if (!node.exportClause && (moduleSpec != null && moduleSpec.length > 0) && 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,
      node
    );
    return;
  }
  if (ts3.isVariableStatement(node)) {
    handleVariableStatement(node, ctx.declarations, ctx.sourceFile);
    return;
  }
  if (ts3.isExportAssignment(node)) {
    ctx.setDefaultExport(handleExportAssignment(node, ctx.declarations, ctx.sourceFile));
    return;
  }
  if (ts3.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 (!ts3.isImportDeclaration(node)) return;
  if (!ts3.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 (ts3.isNamespaceImport(clause.namedBindings)) {
      ctx.importBindingNames.add(clause.namedBindings.name.text);
      ctx.namespaceImportFromRelative.add(spec);
    } else if (ts3.isNamedImports(clause.namedBindings)) {
      handleNamedImports(spec, clause.namedBindings, ctx);
    }
  }
}
function isTopLevelDeclarationName(node, parent) {
  if (ts3.isFunctionDeclaration(parent) && parent.name === node) return true;
  if (ts3.isClassDeclaration(parent) && parent.name === node) return true;
  if (ts3.isInterfaceDeclaration(parent) && parent.name === node) return true;
  if (ts3.isTypeAliasDeclaration(parent) && parent.name === node) return true;
  if (ts3.isEnumDeclaration(parent) && parent.name === node) return true;
  if (ts3.isModuleDeclaration(parent) && parent.name === node) return true;
  return false;
}
function isLocalBindingName(node, parent) {
  if (ts3.isVariableDeclaration(parent) && parent.name === node) return true;
  if (ts3.isParameter(parent) && parent.name === node) return true;
  if (ts3.isBindingElement(parent) && parent.name === node) return true;
  return false;
}
function isMemberName(node, parent) {
  if (ts3.isPropertyAssignment(parent) && parent.name === node) return true;
  if (ts3.isPropertyDeclaration(parent) && parent.name === node) return true;
  if (ts3.isMethodDeclaration(parent) && parent.name === node) return true;
  if (ts3.isPropertySignature(parent) && parent.name === node) return true;
  if (ts3.isMethodSignature(parent) && parent.name === node) return true;
  return false;
}
function isImportExportBindingName(node, parent) {
  if (ts3.isImportSpecifier(parent) && (parent.name === node || parent.propertyName === node)) return true;
  if (ts3.isImportClause(parent) && parent.name === node) return true;
  if (ts3.isNamespaceImport(parent) && parent.name === node) return true;
  if (ts3.isExportSpecifier(parent) && (parent.name === node || parent.propertyName === node)) return true;
  return false;
}
function isQualifiedMemberAccess(node, parent) {
  if (ts3.isQualifiedName(parent) && parent.right === node) return true;
  if (ts3.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 (ts3.isIdentifier(node)) {
    const parent = node.parent;
    if (!isDeclarationOrBindingPosition(node, parent)) {
      identifierRefs.add(node.text);
    }
  }
  ts3.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 = ts3.createSourceFile(
    path2.basename(filePath),
    sourceText,
    ts3.ScriptTarget.Latest,
    true,
    isJsLike ? ts3.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 !== void 0) {
    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 != null && resolved.length > 0) || 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 != null && resolved.length > 0) return resolved;
  }
  return void 0;
}

// src/actions/deplint/getStorybookConfigImports.ts
import ts4 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("/", 1)[0];
}

// src/actions/deplint/getStorybookConfigImports.ts
var storybookMainPattern = /(?:^|[\\/])\.storybook[\\/]main\.[cm]?[jt]sx?$/;
function isStorybookMainFile(filePath) {
  return storybookMainPattern.test(filePath);
}

// src/actions/dead/storybookConventions.ts
var storyFilePattern = /\.stories\.[cm]?[jt]sx?$/i;
var storybookPreviewPattern = /(?:^|[\\/])\.storybook[\\/]preview\.[cm]?[jt]sx?$/i;
var storybookManagerPattern = /(?:^|[\\/])\.storybook[\\/]manager\.[cm]?[jt]sx?$/i;
function isStorybookConventionFile(filePath) {
  return storyFilePattern.test(filePath) || storybookPreviewPattern.test(filePath) || storybookManagerPattern.test(filePath) || isStorybookMainFile(filePath);
}

// 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 != null && resolved.length > 0) 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 != null && target.length > 0) addNamed(target, named.imported);
    }
    for (const reExport of report.symbols.reExportsFromRelative) {
      const target = report.resolvedRelative.get(reExport.specifier);
      if (target != null && target.length > 0) addNamed(target, reExport.imported);
    }
    for (const spec of report.symbols.namespaceImportFromRelative) {
      const target = report.resolvedRelative.get(spec);
      if (target != null && target.length > 0) filesWithFullExportUse.add(target);
    }
    for (const spec of report.symbols.reExportAllFromRelative) {
      const target = report.resolvedRelative.get(spec);
      if (target != null && target.length > 0) filesWithFullExportUse.add(target);
    }
  }
  return { filesWithFullExportUse, namedSymbolUsage };
}
function addStarDeclarations(file, report, out) {
  for (const decl of report.symbols.declarations) {
    if (!decl.isExported || !(decl.exportedAs != null && decl.exportedAs.length > 0) || decl.exportedAs === "default") continue;
    out.set(decl.exportedAs, {
      column: decl.column,
      file,
      line: decl.line
    });
  }
}
function addNamedStarReExports(file, report, ctx, out) {
  for (const reExport of report.symbols.reExportsFromRelative) {
    if (reExport.exportedAs === "default") continue;
    const target = report.resolvedRelative.get(reExport.specifier);
    const origin = target != null && target.length > 0 ? findOrigin(target, reExport.imported, ctx) : void 0;
    out.set(reExport.exportedAs, origin ?? {
      column: 1,
      file,
      line: 1
    });
  }
}
function addChildStarExports(report, ctx, out) {
  for (const spec of report.symbols.reExportAllFromRelative) {
    const target = report.resolvedRelative.get(spec);
    if (!(target != null && target.length > 0)) continue;
    const child = getStarExports(target, ctx);
    for (const [name, origin] of child) {
      if (!out.has(name)) out.set(name, origin);
    }
  }
}
function getStarExports(file, ctx) {
  const cached = ctx.starExportMemo.get(file);
  if (cached !== void 0) 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 !== void 0) {
    addStarDeclarations(file, report, out);
    addNamedStarReExports(file, report, ctx, out);
    addChildStarExports(report, ctx, out);
  }
  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.isExported || !(decl.exportedAs != null && decl.exportedAs.length > 0)) 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 != null && target.length > 0 ? 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 != null && target.length > 0)) continue;
    const stars = getStarExports(target, ctx);
    const pendingStars = [...stars].filter(([name]) => !results.has(name));
    for (const [name, origin] of pendingStars) {
      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().toArray();
}
function buildPublicSurfaceKeys(publicExports) {
  const keys = /* @__PURE__ */ new Set();
  for (const exp of publicExports) {
    keys.add(`${exp.file}\0${exp.name}`);
    keys.add(`${exp.file}\0${exp.line}\0${exp.column}`);
  }
  return keys;
}
function isOnPublicSurface(decl, file, publicSurfaceKeys) {
  const exportedAs = decl.exportedAs ?? decl.name;
  if (publicSurfaceKeys.has(`${file}\0${exportedAs}`)) return true;
  return publicSurfaceKeys.has(`${file}\0${decl.line}\0${decl.column}`);
}
function isUsedInPackage(decl, file, hasFileFullExportUse, namedUsesForFile, report) {
  if (report.symbols.identifierRefs.has(decl.name)) return true;
  if (decl.isExported && isStorybookConventionFile(file)) return true;
  if (!decl.isExported) return false;
  const exportedAs = decl.exportedAs ?? decl.name;
  if (namedUsesForFile.has(exportedAs) || namedUsesForFile.has(decl.name)) return true;
  return hasFileFullExportUse;
}
function buildAnalyzedSymbol(decl, file, hasFileFullExportUse, namedUsesForFile, report, publicSurfaceKeys) {
  const isSymbolUsedInPackage = isUsedInPackage(decl, file, hasFileFullExportUse, namedUsesForFile, report);
  return {
    column: decl.column,
    deprecated: decl.deprecated,
    exportedAs: decl.isExported ? decl.exportedAs ?? decl.name : void 0,
    file,
    line: decl.line,
    name: decl.name,
    onPublicSurface: isOnPublicSurface(decl, file, publicSurfaceKeys),
    usedInMonorepo: isSymbolUsedInPackage,
    isUsedInPackage: isSymbolUsedInPackage
  };
}
function applyMonorepoUsage(analyses, repoUsage) {
  return analyses.map((analysis) => {
    const pkgUsage = repoUsage.get(analysis.packageName);
    if (!pkgUsage) return analysis;
    return {
      ...analysis,
      symbols: analysis.symbols.map((symbol) => {
        if (symbol.usedInMonorepo || symbol.onPublicSurface) return symbol;
        const exportedAs = symbol.exportedAs;
        if (!(exportedAs != null && exportedAs.length > 0)) return symbol;
        const isConsumed2 = pkgUsage.hasNamespace || exportedAs === "default" && pkgUsage.hasDefault || pkgUsage.named.has(exportedAs);
        return isConsumed2 ? { ...symbol, usedInMonorepo: true } : symbol;
      })
    };
  });
}
function analyzePackage(workspace) {
  const location = path4.resolve(workspace.location);
  const manifest = readPackageManifest(location);
  const manifestName = manifest && typeof manifest.name === "string" ? manifest.name : void 0;
  const packageName = manifestName ?? workspace.name;
  const { allFiles } = findFiles(location);
  const reports = loadReports(allFiles);
  const runtimeRoots = getRuntimeRootFiles(location, manifest);
  const usage = computeCrossFileUsage(reports);
  const publicExports = collectPublicExports(reports, runtimeRoots);
  const publicSurfaceKeys = buildPublicSurfaceKeys(publicExports);
  const symbols = [];
  for (const report of reports) {
    const isFileHasFullExportUse = usage.filesWithFullExportUse.has(report.file);
    const namedUsesForFile = usage.namedSymbolUsage.get(report.file) ?? /* @__PURE__ */ new Set();
    for (const decl of report.symbols.declarations) {
      symbols.push(buildAnalyzedSymbol(
        decl,
        report.file,
        isFileHasFullExportUse,
        namedUsesForFile,
        report,
        publicSurfaceKeys
      ));
    }
  }
  return {
    location,
    packageName,
    publicExports,
    scannedFiles: reports.length,
    symbols,
    visibility: classifyPackageVisibility(manifest),
    workspaceName: workspace.name
  };
}

// src/actions/dead/collectExternalUsage.ts
import fs4 from "node:fs";
import path5 from "node:path";
import ts5 from "typescript";
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 (!ts5.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 (ts5.isNamespaceImport(clause.namedBindings)) summary.namespace = true;
    else if (ts5.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 || !ts5.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 (ts5.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 (ts5.isNamespaceExport(node.exportClause)) {
    summary.namespace = true;
  }
  return summary;
}
function summarizeDynamicImport(node) {
  if (node.expression.kind !== ts5.SyntaxKind.ImportKeyword) return void 0;
  if (node.arguments.length === 0 || !ts5.isStringLiteral(node.arguments[0])) return void 0;
  return {
    defaultBinding: false,
    named: [],
    namespace: true,
    spec: node.arguments[0].text
  };
}
function summarizeNode(node) {
  if (ts5.isImportDeclaration(node)) return summarizeImportDeclaration(node);
  if (ts5.isExportDeclaration(node)) return summarizeExportDeclaration(node);
  if (ts5.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 = ts5.createSourceFile(
    path5.basename(file),
    sourceText,
    ts5.ScriptTarget.Latest,
    true,
    isJsLike ? ts5.ScriptKind.JS : void 0
  );
  function visit(node) {
    const summary = summarizeNode(node);
    if (summary) recordSpecifier(summary, targets, out);
    ts5.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;
    }
    const codeFiles = allFiles.filter(
      (file) => codeExtensionRe2.test(file) && !file.endsWith(".d.ts") && !file.endsWith(".d.mts") && !file.endsWith(".d.cts")
    );
    for (const file of codeFiles) {
      collectFromFile(file, targetPackageNames, map);
    }
  }
  return map;
}

// src/actions/dead/evaluateRules.ts
import path6 from "node:path";

// src/actions/dead/ruleConfig.ts
var VALID_RULE_LEVELS = /* @__PURE__ */ new Set(["off", "warn", "error"]);
function isRecord2(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isRuleLevel(value) {
  return typeof value === "string" && VALID_RULE_LEVELS.has(value);
}
function severityFromLevel(level) {
  return level === "warn" ? "warning" : "error";
}
function formatRuleConfigLocation(ruleId) {
  return `commands.dead.rules["${ruleId}"]`;
}
function parseRuleConfig(ruleId, value) {
  if (typeof value === "string") {
    if (!isRuleLevel(value)) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} must be one of "off", "warn", or "error"`);
    }
    return { level: value, options: {} };
  }
  if (Array.isArray(value)) {
    if (value.length !== 2) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} tuple must be [level, options]`);
    }
    const level = value[0];
    if (!isRuleLevel(level)) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} level must be one of "off", "warn", or "error"`);
    }
    const options = value[1];
    if (!isRecord2(options)) {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} options must be an object`);
    }
    return { level, options: { ...options } };
  }
  if (isRecord2(value)) {
    return { level: "warn", options: { ...value } };
  }
  throw new TypeError(`${formatRuleConfigLocation(ruleId)} must be a level, options object, or [level, options] tuple`);
}
function validateIgnore(ruleId, options) {
  if (options.ignore === void 0) return;
  if (!Array.isArray(options.ignore) || options.ignore.some((pattern) => typeof pattern !== "string")) {
    throw new TypeError(`${formatRuleConfigLocation(ruleId)}.ignore must be an array of strings`);
  }
}
function validateOptions(ruleId, options) {
  validateIgnore(ruleId, options);
  for (const key of Object.keys(options)) {
    if (key !== "ignore") {
      throw new TypeError(`${formatRuleConfigLocation(ruleId)} has unknown option "${key}"`);
    }
  }
}
function normalizeDeadRules(rules, config) {
  const ruleConfigs = config?.rules ?? {};
  const ruleIds = new Set(rules.map((rule) => rule.id));
  const unknownRuleIds = Object.keys(ruleConfigs).filter((ruleId) => !ruleIds.has(ruleId));
  if (unknownRuleIds.length > 0) {
    throw new TypeError(`Unknown dead rule ${unknownRuleIds.map((ruleId) => `"${ruleId}"`).join(", ")} in commands.dead.rules`);
  }
  return rules.map((rule) => {
    const ruleConfig = ruleConfigs[rule.id];
    if (ruleConfig === void 0) {
      return {
        ...rule,
        enabled: rule.enabled,
        meta: {
          ...rule.meta,
          severity: rule.enabled ? rule.meta.severity ?? "warning" : void 0
        },
        options: {}
      };
    }
    const { level, options } = parseRuleConfig(rule.id, ruleConfig);
    validateOptions(rule.id, options);
    return {
      ...rule,
      enabled: level !== "off",
      meta: level === "off" ? { ...rule.meta } : { ...rule.meta, severity: severityFromLevel(level) },
      options
    };
  });
}
function isPackageIgnoredByRule(packageName, options) {
  return options?.ignore?.some((pattern) => pattern === packageName || isMatch(packageName, pattern)) ?? false;
}

// src/actions/dead/evaluateRules.ts
var SCOPE_NARROWNESS = {
  package: 0,
  repo: 1,
  workspace: 2
};
function isConsumed(name, pkgUsage) {
  if (pkgUsage.hasNamespace) return true;
  if (name === "default" && pkgUsage.hasDefault) return true;
  return pkgUsage.named.has(name);
}
function makeFinding(analysis, rule, scope, file, symbol, line, column, detail, isDeprecated) {
  return {
    column,
    deprecated: isDeprecated,
    detail,
    file: path6.relative(analysis.location, file),
    line,
    pkg: analysis.packageName,
    rule,
    scope,
    symbol
  };
}
function symbolDeprecated(analysis, file, line, column, symbol) {
  return analysis.symbols.find((candidate) => candidate.file === file && candidate.line === line && candidate.column === column && candidate.name === symbol)?.deprecated;
}
function makeExportFinding(analysis, rule, scope, exp, detail) {
  return makeFinding(
    analysis,
    rule,
    scope,
    exp.file,
    exp.name,
    exp.line,
    exp.column,
    detail,
    symbolDeprecated(analysis, exp.file, exp.line, exp.column, exp.name)
  );
}
function findingDedupeKey(finding) {
  return `${finding.pkg}\0${finding.file}\0${finding.line}\0${finding.column}\0${finding.symbol}`;
}
function dedupeToNarrowestScope(findings) {
  const best = /* @__PURE__ */ new Map();
  for (const finding of findings) {
    const key = findingDedupeKey(finding);
    const existing = best.get(key);
    if (!existing || SCOPE_NARROWNESS[finding.scope] < SCOPE_NARROWNESS[existing.scope]) {
      best.set(key, finding);
    }
  }
  return best.values().toArray();
}
function isRuleApplicableToPackage(rule, analysis) {
  if (isPackageIgnoredByRule(analysis.packageName, rule.options)) return false;
  if (!rule.appliesToVisibility) return true;
  return rule.appliesToVisibility.includes(analysis.visibility);
}
function evaluateInternalRule(analysis, rule, shouldUseMonorepoRefs) {
  const findings = [];
  for (const symbol of analysis.symbols) {
    const isReferenced = symbol[shouldUseMonorepoRefs ? "usedInMonorepo" : "isUsedInPackage"];
    if (symbol.onPublicSurface || isReferenced) continue;
    findings.push(makeFinding(
      analysis,
      rule.id,
      rule.meta.scope,
      symbol.file,
      symbol.name,
      symbol.line,
      symbol.column,
      void 0,
      symbol.deprecated
    ));
  }
  return findings;
}
function evaluateExportRule(analysis, rule, usage, detail) {
  const pkgUsage = usage.get(analysis.packageName);
  const findings = [];
  for (const exp of analysis.publicExports) {
    if (pkgUsage && isConsumed(exp.name, pkgUsage)) continue;
    findings.push(makeExportFinding(analysis, rule.id, rule.meta.scope, exp, detail));
  }
  return findings;
}
function evaluatePackageRules(analysis, rule) {
  if (rule.id === "dead.package.internal") {
    return evaluateInternalRule(analysis, rule, false);
  }
  return [];
}
function evaluateRepoRules(analysis, rule, repoUsage) {
  if (rule.id === "dead.repo.internal") {
    return evaluateInternalRule(analysis, rule, true);
  }
  if (rule.id === "dead.repo.export") {
    return evaluateExportRule(analysis, rule, repoUsage, "no consumer in monorepo");
  }
  return [];
}
function evaluateWorkspaceRules(analysis, rule, workspaceUsage) {
  if (rule.id === "dead.workspace.export" || rule.id === "dead.workspace.export-published") {
    return evaluateExportRule(analysis, rule, workspaceUsage, "no consumer in workspace");
  }
  return [];
}
function evaluateRuleForAnalysis(analysis, rule, repoUsage, workspaceUsage) {
  if (!isRuleApplicableToPackage(rule, analysis)) return [];
  if (rule.meta.scope === "package") {
    return evaluatePackageRules(analysis, rule);
  }
  if (rule.meta.scope === "repo") {
    return evaluateRepoRules(analysis, rule, repoUsage);
  }
  if (rule.meta.scope === "workspace" && workspaceUsage !== void 0) {
    return evaluateWorkspaceRules(analysis, rule, workspaceUsage);
  }
  return [];
}
function evaluateDeadRules(analyses, rules, repoUsage, workspaceUsage) {
  const findings = [];
  const enabledRules = rules.filter((rule) => rule.enabled);
  for (const analysis of analyses) {
    for (const rule of enabledRules) {
      findings.push(...evaluateRuleForAnalysis(analysis, rule, repoUsage, workspaceUsage));
    }
  }
  return dedupeToNarrowestScope(findings);
}
function getDisabledWorkspaceRules(rules, hasCodeWorkspace) {
  if (hasCodeWorkspace) return [];
  return rules.filter((rule) => rule.requiresCodeWorkspace === true && rule.enabled).map((rule) => rule.id);
}

// src/actions/dead/findWorkspaceFile.ts
import fs7 from "node:fs";
import path9 from "node:path";

// src/actions/dead/detectActiveCodeWorkspace.ts
import fs6 from "node:fs";
import os from "node:os";
import path8 from "node:path";

// src/actions/dead/parseCodeWorkspace.ts
import fs5 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];
    if (ch === '"' || ch === "'") {
      consumeString(input, ctx, ch);
      continue;
    }
    const next = ctx.i + 1 < input.length ? input[ctx.i + 1] : "";
    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 = fs5.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 (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/detectActiveCodeWorkspace.ts
function uriToPath(uri) {
  if (!uri.startsWith("file://")) return void 0;
  try {
    const parsed = new URL(uri);
    let pathname = decodeURIComponent(parsed.pathname);
    if (process.platform === "win32" && pathname.startsWith("/") && /^\/[A-Za-z]:/.test(pathname)) {
      pathname = pathname.slice(1);
    }
    return pathname;
  } catch {
    return void 0;
  }
}
function isPathContainedIn(container, target) {
  const resolvedContainer = path8.resolve(container);
  const resolvedTarget = path8.resolve(target);
  return resolvedTarget === resolvedContainer || resolvedTarget.startsWith(`${resolvedContainer}${path8.sep}`);
}
function hasWorkspaceFileContainingPath(workspaceFilePath, targetPath) {
  try {
    const folders = parseCodeWorkspace(workspaceFilePath);
    return folders.some((folder) => isPathContainedIn(folder.absolutePath, targetPath));
  } catch {
    return false;
  }
}
function getEditorStorageRoots() {
  const home = os.homedir();
  return [
    path8.join(home, "Library", "Application Support", "Code", "User", "workspaceStorage"),
    path8.join(home, "Library", "Application Support", "Cursor", "User", "workspaceStorage"),
    path8.join(home, ".config", "Code", "User", "workspaceStorage"),
    path8.join(home, ".config", "Cursor", "User", "workspaceStorage")
  ].filter((root) => fs6.existsSync(root));
}
function readWorkspaceCandidate(workspaceJsonPath, resolvedStart) {
  let parsed;
  try {
    parsed = JSON.parse(fs6.readFileSync(workspaceJsonPath, "utf8"));
  } catch {
    return void 0;
  }
  if (typeof parsed.workspace !== "string") return void 0;
  const candidate = uriToPath(parsed.workspace);
  if (!(candidate != null && candidate.length > 0)) return void 0;
  if (!candidate.endsWith(".code-workspace")) return void 0;
  if (!fs6.existsSync(candidate)) return void 0;
  if (!hasWorkspaceFileContainingPath(candidate, resolvedStart)) return void 0;
  return candidate;
}
function updateBestFromEntry(storageRoot, entry, resolvedStart, best) {
  const workspaceJsonPath = path8.join(storageRoot, entry, "workspace.json");
  let stat;
  try {
    stat = fs6.statSync(workspaceJsonPath);
  } catch {
    return best;
  }
  const candidate = readWorkspaceCandidate(workspaceJsonPath, resolvedStart);
  if (!(candidate != null && candidate.length > 0)) return best;
  if (!best || stat.mtimeMs > best.mtimeMs) {
    return { mtimeMs: stat.mtimeMs, path: candidate };
  }
  return best;
}
function scanStorageRoot(storageRoot, resolvedStart, best) {
  let entries;
  try {
    entries = fs6.readdirSync(storageRoot);
  } catch {
    return best;
  }
  let nextBest = best;
  for (const entry of entries) {
    nextBest = updateBestFromEntry(storageRoot, entry, resolvedStart, nextBest);
  }
  return nextBest;
}
function detectActiveCodeWorkspace(startDir) {
  const resolvedStart = path8.resolve(startDir);
  let best;
  for (const storageRoot of getEditorStorageRoots()) {
    best = scanStorageRoot(storageRoot, resolvedStart, best);
  }
  return best?.path;
}

// src/actions/dead/findWorkspaceFile.ts
function listWorkspaceCandidates(dir) {
  let entries;
  try {
    entries = fs7.readdirSync(dir);
  } catch {
    entries = [];
  }
  return entries.filter((name) => name.endsWith(".code-workspace")).map((name) => path9.join(dir, name)).toSorted((a, b) => a.localeCompare(b));
}
function scoreWorkspaceCandidate(filePath, startDir) {
  if (!fs7.existsSync(filePath)) return -1;
  return hasWorkspaceFileContainingPath(filePath, startDir) ? 2 : 1;
}
function considerWorkspaceCandidate(candidate, candidates, startDir, best) {
  const score = scoreWorkspaceCandidate(candidate, startDir);
  if (score < 0) return best;
  if (!best || score > best.score || score === best.score && candidate.localeCompare(best.path) < 0) {
    return {
      alternates: candidates.filter((file) => file !== candidate),
      path: candidate,
      score
    };
  }
  return best;
}
function pickBestInDirectory(dir, startDir, best) {
  const candidates = listWorkspaceCandidates(dir);
  let nextBest = best;
  for (const candidate of candidates) {
    nextBest = considerWorkspaceCandidate(candidate, candidates, startDir, nextBest);
  }
  return nextBest;
}
function findCodeWorkspaceFile(startDir) {
  let dir = path9.resolve(startDir);
  let best;
  while (true) {
    best = pickBestInDirectory(dir, startDir, best);
    if (best?.score === 2) break;
    const parent = path9.dirname(dir);
    if (parent === dir) break;
    dir = parent;
  }
  if (!best) return void 0;
  return {
    alternates: best.alternates.length > 0 ? best.alternates : void 0,
    path: best.path,
    source: "walk-up"
  };
}
function resolveCodeWorkspaceFile(explicit, startDir) {
  if (explicit != null && explicit.length > 0) {
    const absolute = path9.isAbsolute(explicit) ? explicit : path9.resolve(startDir, explicit);
    if (!fs7.existsSync(absolute)) return void 0;
    return { path: absolute, source: "explicit" };
  }
  const active = detectActiveCodeWorkspace(startDir);
  if (active != null && active.length > 0 && fs7.existsSync(active)) {
    return { path: active, source: "active-editor" };
  }
  const walked = findCodeWorkspaceFile(startDir);
  return walked;
}

// src/actions/dead/rules.ts
var DEAD_RULES = [
  {
    appliesToVisibility: void 0,
    enabled: true,
    id: "dead.package.internal",
    meta: {
      description: "Declarations that are neither referenced in the package nor part of its public export surface",
      scope: "package",
      severity: "warning"
    },
    options: {}
  },
  {
    appliesToVisibility: void 0,
    enabled: true,
    id: "dead.repo.internal",
    meta: {
      description: "Declarations that are neither referenced anywhere in the monorepo nor part of the public export surface",
      scope: "repo",
      severity: "warning"
    },
    options: {}
  },
  {
    appliesToVisibility: ["private"],
    enabled: true,
    id: "dead.repo.export",
    meta: {
      description: "Public exports of private packages that no other monorepo package imports",
      scope: "repo",
      severity: "warning"
    },
    options: {}
  },
  {
    appliesToVisibility: ["restricted"],
    enabled: true,
    id: "dead.workspace.export",
    meta: {
      description: "Public exports of restricted or scoped packages that no other folder in the VS Code workspace imports",
      scope: "workspace",
      severity: "warning"
    },
    options: {},
    requiresCodeWorkspace: true
  },
  {
    appliesToVisibility: ["public"],
    enabled: false,
    id: "dead.workspace.export-published",
    meta: {
      description: "Public exports of explicitly public packages that no other folder in the VS Code workspace imports",
      scope: "workspace",
      severity: "warning"
    },
    options: {},
    requiresCodeWorkspace: true
  }
];
function loadDeadRules(config) {
  return normalizeDeadRules(DEAD_RULES, config);
}

// src/actions/dead/runDeadAnalysis.ts
function resolveExternalFolders(workspaceFilePath, ownLocations) {
  const folders = parseCodeWorkspace(workspaceFilePath);
  const externalFolders = [];
  for (const folder of folders) {
    if (!fs8.existsSync(folder.absolutePath)) continue;
    if (!fs8.existsSync(path10.join(folder.absolutePath, "package.json"))) continue;
    if (ownLocations.has(path10.resolve(folder.absolutePath))) continue;
    externalFolders.push(folder.absolutePath);
  }
  return externalFolders;
}
function resolveRepoConsumerFolders(targets) {
  const pm = getPackageManager();
  const ownLocations = new Set(targets.map((target) => path10.resolve(target.location)));
  return pm.listWorkspaces().map((workspace) => path10.resolve(workspace.location)).filter((location) => !ownLocations.has(location)).filter((location) => fs8.existsSync(path10.join(location, "package.json")));
}
function logWorkspaceLookup(lookup, isVerbose) {
  if (!isVerbose) return;
  const sourceLabel = lookup.source === "active-editor" ? "active VS Code/Cursor workspace" : lookup.source === "explicit" ? "explicit --workspace" : "walk-up discovery";
  console.log(chalk2.gray(`Using code-workspace (${sourceLabel}): ${lookup.path}`));
  if (lookup.alternates?.length != null && !Number.isNaN(lookup.alternates?.length) && lookup.alternates?.length !== 0) {
    for (const alt of lookup.alternates) console.log(chalk2.gray(`  (also present: ${alt})`));
  }
}
async function buildDeadAnalysisContext(targets, workspace, isVerbose) {
  const deadConfig = await loadWorkspaceCommandConfig(targets[0].location, "dead");
  const rules = loadDeadRules(deadConfig);
  const analyses = targets.map(analyzePackage);
  const targetPackageNames = new Set(analyses.map((analysis) => analysis.packageName));
  const repoConsumerFolders = resolveRepoConsumerFolders(targets);
  const repoUsage = collectExternalUsage(repoConsumerFolders, targetPackageNames);
  const lookup = resolveCodeWorkspaceFile(workspace, INIT_CWD());
  const hasCodeWorkspace = lookup !== void 0;
  const disabledWorkspaceRules = getDisabledWorkspaceRules(rules, hasCodeWorkspace);
  let workspaceUsage;
  if (lookup) {
    logWorkspaceLookup(lookup, isVerbose);
    const ownLocations = new Set(targets.map((target) => path10.resolve(target.location)));
    workspaceUsage = collectExternalUsage(resolveExternalFolders(lookup.path, ownLocations), targetPackageNames);
  } else if (isVerbose) {
    console.log(chalk2.gray("No *.code-workspace file found \u2014 workspace-scoped dead rules are disabled"));
  }
  const effectiveRules = rules.map((rule) => {
    if (rule.requiresCodeWorkspace !== true || hasCodeWorkspace) return rule;
    return { ...rule, enabled: false };
  });
  return {
    analyses,
    disabledWorkspaceRules,
    effectiveRules,
    lookup,
    repoUsage,
    targetPackageNames,
    targets,
    workspaceUsage
  };
}
function evaluateFindings(context) {
  const enrichedAnalyses = applyMonorepoUsage(context.analyses, context.repoUsage);
  return evaluateDeadRules(enrichedAnalyses, context.effectiveRules, context.repoUsage, context.workspaceUsage);
}
function refreshFindingsAfterRemoval(context) {
  const refreshedAnalyses = context.targets.map(analyzePackage);
  const refreshedRepoUsage = collectExternalUsage(
    resolveRepoConsumerFolders(context.targets),
    context.targetPackageNames
  );
  const refreshedEnriched = applyMonorepoUsage(refreshedAnalyses, refreshedRepoUsage);
  const refreshedWorkspaceUsage = context.lookup ? collectExternalUsage(
    resolveExternalFolders(
      context.lookup.path,
      new Set(context.targets.map((target) => path10.resolve(target.location)))
    ),
    context.targetPackageNames
  ) : void 0;
  return evaluateDeadRules(refreshedEnriched, context.effectiveRules, refreshedRepoUsage, refreshedWorkspaceUsage);
}
export {
  buildDeadAnalysisContext,
  evaluateFindings,
  refreshFindingsAfterRemoval
};
//# sourceMappingURL=runDeadAnalysis.mjs.map
