import { a as normalizeLowercaseStringOrEmpty } from "./string-coerce-DyL154ka.js";
import { u as pathExists } from "./utils-CNnMhEDp.js";
import { a as readJsonIfExists } from "./json-files-D7wa8Ux4.js";
import { a as parseSemver } from "./runtime-guard-CeaQ7tel.js";
import { n as applyPosixNpmScriptShellEnv, r as createNpmFreshnessBypassArgs, t as applyNpmFreshnessBypassEnv } from "./npm-install-env-BDr63VWf.js";
import { t as BUNDLED_RUNTIME_SIDECAR_PATHS } from "./runtime-sidecar-paths-Blgi5sh-.js";
import { t as applyPathPrepend } from "./path-prepend-6X5fKWgG.js";
import { r as readPackageVersion } from "./package-json-CIZcDaQ6.js";
import fs from "node:fs";
import path from "node:path";
import fs$1 from "node:fs/promises";
import os from "node:os";
const LOCAL_BUILD_METADATA_DIST_PATHS = Object.freeze([`dist/.buildstamp`, `dist/.runtime-postbuildstamp`]);
const LOCAL_BUILD_METADATA_DIST_PATH_SET = new Set(LOCAL_BUILD_METADATA_DIST_PATHS);
function isLocalBuildMetadataDistPath(relativePath) {
	return LOCAL_BUILD_METADATA_DIST_PATH_SET.has(relativePath);
}
//#endregion
//#region src/infra/package-dist-inventory.ts
const PACKAGE_DIST_INVENTORY_RELATIVE_PATH = "dist/postinstall-inventory.json";
const LEGACY_QA_CHANNEL_DIR = ["qa", "channel"].join("-");
const LEGACY_QA_LAB_DIR = ["qa", "lab"].join("-");
const OMITTED_QA_EXTENSION_PREFIXES = [
	`dist/extensions/${LEGACY_QA_CHANNEL_DIR}/`,
	`dist/extensions/${LEGACY_QA_LAB_DIR}/`,
	"dist/extensions/qa-matrix/"
];
const OMITTED_PRIVATE_QA_PLUGIN_SDK_PREFIXES = [`dist/plugin-sdk/extensions/${LEGACY_QA_CHANNEL_DIR}/`, `dist/plugin-sdk/extensions/${LEGACY_QA_LAB_DIR}/`];
const OMITTED_PRIVATE_QA_PLUGIN_SDK_FILES = new Set([
	`dist/plugin-sdk/${LEGACY_QA_CHANNEL_DIR}.d.ts`,
	`dist/plugin-sdk/${LEGACY_QA_CHANNEL_DIR}.js`,
	`dist/plugin-sdk/${LEGACY_QA_CHANNEL_DIR}-protocol.d.ts`,
	`dist/plugin-sdk/${LEGACY_QA_CHANNEL_DIR}-protocol.js`,
	`dist/plugin-sdk/${LEGACY_QA_LAB_DIR}.d.ts`,
	`dist/plugin-sdk/${LEGACY_QA_LAB_DIR}.js`,
	"dist/plugin-sdk/qa-runtime.d.ts",
	"dist/plugin-sdk/qa-runtime.js",
	`dist/plugin-sdk/src/plugin-sdk/${LEGACY_QA_CHANNEL_DIR}.d.ts`,
	`dist/plugin-sdk/src/plugin-sdk/${LEGACY_QA_CHANNEL_DIR}-protocol.d.ts`,
	`dist/plugin-sdk/src/plugin-sdk/${LEGACY_QA_LAB_DIR}.d.ts`,
	"dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts"
]);
const OMITTED_PRIVATE_QA_DIST_PREFIXES = ["dist/qa-runtime-"];
const OMITTED_DIST_SUBTREE_PATTERNS = [
	/^dist\/extensions\/node_modules(?:\/|$)/u,
	/^dist\/extensions\/[^/]+\/node_modules(?:\/|$)/u,
	/^dist\/extensions\/qa-matrix(?:\/|$)/u,
	new RegExp(`^dist/plugin-sdk/extensions/${LEGACY_QA_CHANNEL_DIR}(?:/|$)`, "u"),
	new RegExp(`^dist/plugin-sdk/extensions/${LEGACY_QA_LAB_DIR}(?:/|$)`, "u")
];
function normalizeRelativePath(value) {
	return value.replace(/\\/g, "/");
}
function isLegacyPluginDependencyDirPath(relativePath) {
	const parts = normalizeRelativePath(relativePath).split("/");
	if (parts[0]?.toLowerCase() !== "dist" || parts[1]?.toLowerCase() !== "extensions") return false;
	if ((parts[2] ?? "").toLowerCase() === "node_modules") return true;
	return (parts[3] ?? "").toLowerCase() === "node_modules";
}
function collectExcludedPackagedExtensionDirs(rootPackageJson) {
	if (!rootPackageJson || typeof rootPackageJson !== "object") return /* @__PURE__ */ new Set();
	const files = rootPackageJson.files;
	if (!Array.isArray(files)) return /* @__PURE__ */ new Set();
	const excluded = /* @__PURE__ */ new Set();
	for (const entry of files) {
		if (typeof entry !== "string") continue;
		const match = /^!dist\/extensions\/([^/]+)\/\*\*$/u.exec(entry);
		if (match?.[1]) excluded.add(match[1]);
	}
	return excluded;
}
function isExternalizedBundledExtensionDistPath(relativePath, externalizedExtensionIds) {
	if (externalizedExtensionIds.size === 0) return false;
	const parts = normalizeRelativePath(relativePath).split("/");
	return parts.length >= 3 && parts[0] === "dist" && parts[1] === "extensions" && Boolean(parts[2]) && externalizedExtensionIds.has(parts[2] ?? "");
}
async function collectExternalizedBundledExtensionIds(packageRoot) {
	return collectExcludedPackagedExtensionDirs(await readJsonIfExists(path.join(packageRoot, "package.json")));
}
function isPackagedDistPath(relativePath, externalizedExtensionIds) {
	if (!relativePath.startsWith("dist/")) return false;
	if (isExternalizedBundledExtensionDistPath(relativePath, externalizedExtensionIds)) return false;
	if (isLegacyPluginDependencyDirPath(relativePath)) return false;
	if (relativePath === "dist/postinstall-inventory.json") return false;
	if (isLocalBuildMetadataDistPath(relativePath)) return false;
	if (relativePath.endsWith(".map")) return false;
	if (relativePath === "dist/plugin-sdk/.tsbuildinfo") return false;
	if (OMITTED_PRIVATE_QA_PLUGIN_SDK_PREFIXES.some((prefix) => relativePath.startsWith(prefix)) || OMITTED_PRIVATE_QA_PLUGIN_SDK_FILES.has(relativePath) || OMITTED_PRIVATE_QA_DIST_PREFIXES.some((prefix) => relativePath.startsWith(prefix))) return false;
	if (OMITTED_QA_EXTENSION_PREFIXES.some((prefix) => relativePath.startsWith(prefix))) return false;
	return true;
}
function isOmittedDistSubtree(relativePath, externalizedExtensionIds) {
	return isExternalizedBundledExtensionDistPath(relativePath, externalizedExtensionIds) || isLegacyPluginDependencyDirPath(relativePath) || OMITTED_DIST_SUBTREE_PATTERNS.some((pattern) => pattern.test(relativePath));
}
async function collectRelativeFiles(rootDir, baseDir, externalizedExtensionIds) {
	const rootRelativePath = normalizeRelativePath(path.relative(baseDir, rootDir));
	if (rootRelativePath && isOmittedDistSubtree(rootRelativePath, externalizedExtensionIds)) return [];
	try {
		const rootStats = await fs$1.lstat(rootDir);
		if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) throw new Error(`Unsafe package dist path: ${normalizeRelativePath(path.relative(baseDir, rootDir))}`);
		const entries = await fs$1.readdir(rootDir, { withFileTypes: true });
		return (await Promise.all(entries.map(async (entry) => {
			const entryPath = path.join(rootDir, entry.name);
			const relativePath = normalizeRelativePath(path.relative(baseDir, entryPath));
			if (entry.isSymbolicLink()) throw new Error(`Unsafe package dist path: ${relativePath}`);
			if (entry.isDirectory()) return await collectRelativeFiles(entryPath, baseDir, externalizedExtensionIds);
			if (entry.isFile()) return isPackagedDistPath(relativePath, externalizedExtensionIds) ? [relativePath] : [];
			return [];
		}))).flat().toSorted((left, right) => left.localeCompare(right));
	} catch (error) {
		if (error.code === "ENOENT") return [];
		throw error;
	}
}
async function collectPackageDistInventory(packageRoot) {
	const externalizedExtensionIds = await collectExternalizedBundledExtensionIds(packageRoot);
	return await collectRelativeFiles(path.join(packageRoot, "dist"), packageRoot, externalizedExtensionIds);
}
async function readPackageDistInventoryOptional(packageRoot) {
	const parsed = await readJsonIfExists(path.join(packageRoot, PACKAGE_DIST_INVENTORY_RELATIVE_PATH));
	if (parsed === null) return null;
	if (!Array.isArray(parsed) || parsed.some((entry) => typeof entry !== "string")) throw new Error(`Invalid package dist inventory at ${PACKAGE_DIST_INVENTORY_RELATIVE_PATH}`);
	return [...new Set(parsed.map(normalizeRelativePath))].toSorted((left, right) => left.localeCompare(right));
}
async function readPackageDistInventoryIfPresent(packageRoot) {
	return await readPackageDistInventoryOptional(packageRoot);
}
//#endregion
//#region src/infra/update-global.ts
const PRIMARY_PACKAGE_NAME = "@gaodefa/daocore";
const ALL_PACKAGE_NAMES = [PRIMARY_PACKAGE_NAME];
const GLOBAL_RENAME_PREFIX = ".";
const DAOCORE_MAIN_PACKAGE_SPEC = "github:daocore/daocore#main";
const COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT = "0";
const NPM_GLOBAL_INSTALL_QUIET_FLAGS = [
	"--no-fund",
	"--no-audit",
	"--loglevel=error"
];
const PNPM_DAOCORE_BUILD_ALLOWLIST_FLAG = `--allow-build=${PRIMARY_PACKAGE_NAME}`;
const FIRST_PACKAGED_DIST_INVENTORY_VERSION = {
	major: 2026,
	minor: 4,
	patch: 15
};
const OMITTED_PRIVATE_QA_BUNDLED_PLUGIN_ROOTS = new Set([
	"dist/extensions/qa-channel",
	"dist/extensions/qa-lab",
	"dist/extensions/qa-matrix"
]);
function normalizePackageTarget(value) {
	return value.trim();
}
function normalizePackageVersionForComparison(value) {
	const trimmed = value?.trim();
	if (!trimmed) return null;
	return trimmed.replace(/^[vV](?=\d)/, "");
}
function isMainPackageTarget(value) {
	return normalizeLowercaseStringOrEmpty(normalizePackageTarget(value)) === "main";
}
function isExplicitPackageInstallSpec(value) {
	const trimmed = normalizePackageTarget(value);
	if (!trimmed) return false;
	return /\.(?:tgz|tar\.gz)$/iu.test(trimmed) || trimmed.includes("://") || trimmed.includes("#") || /^(?:file|github|git\+ssh|git\+https|git\+http|git\+file|npm):/i.test(trimmed);
}
function stripPrimaryPackageAlias(spec) {
	const normalized = normalizePackageTarget(spec);
	const prefix = `${PRIMARY_PACKAGE_NAME}@`;
	return normalized.toLowerCase().startsWith(prefix) ? normalized.slice(prefix.length).trim() : normalized;
}
function isPnpmDaoCoreSourceInstallSpec(spec) {
	const target = stripPrimaryPackageAlias(spec);
	return /^github:/i.test(target) || /^git\+(?:ssh|https|http|file):/i.test(target) || /^git:/i.test(target);
}
function resolveExpectedInstalledVersionFromSpec(packageName, spec) {
	const normalizedPackageName = packageName.trim();
	const normalizedSpec = normalizePackageTarget(spec);
	if (!normalizedPackageName || !normalizedSpec.startsWith(`${normalizedPackageName}@`)) return null;
	const rawVersion = normalizedSpec.slice(normalizedPackageName.length + 1).trim();
	if (!rawVersion || rawVersion.includes("/") || rawVersion.includes(":") || rawVersion.includes("#") || /^(latest|beta|next|main)$/i.test(rawVersion)) return null;
	return normalizePackageVersionForComparison(rawVersion);
}
async function collectInstalledGlobalPackageErrors(params) {
	const errors = [];
	errors.push(...await collectSourceCheckoutInstallErrors(params.packageRoot));
	const installedVersion = await readPackageVersion(params.packageRoot);
	const expectedComparable = normalizePackageVersionForComparison(params.expectedVersion);
	const installedComparable = normalizePackageVersionForComparison(installedVersion);
	if (expectedComparable && installedComparable !== expectedComparable) errors.push(`expected installed version ${expectedComparable}, found ${installedComparable ?? "<missing>"}`);
	errors.push(...await collectInstalledPackageDistErrors({
		packageRoot: params.packageRoot,
		installedVersion,
		expectedVersion: params.expectedVersion
	}));
	return errors;
}
async function collectSourceCheckoutInstallErrors(packageRoot) {
	const realPackageRoot = await tryRealpath(packageRoot);
	return (await pathExists(path.join(realPackageRoot, ".git")) || await pathExists(path.join(realPackageRoot, "pnpm-workspace.yaml"))) && await pathExists(path.join(realPackageRoot, "src")) && await pathExists(path.join(realPackageRoot, "extensions")) ? [`global package root resolves to source checkout: ${realPackageRoot}`] : [];
}
function shouldRequirePackagedDistInventory(version) {
	const parsed = parseSemver(version ?? null);
	if (!parsed) return false;
	if (parsed.major !== FIRST_PACKAGED_DIST_INVENTORY_VERSION.major) return parsed.major > FIRST_PACKAGED_DIST_INVENTORY_VERSION.major;
	if (parsed.minor !== FIRST_PACKAGED_DIST_INVENTORY_VERSION.minor) return parsed.minor > FIRST_PACKAGED_DIST_INVENTORY_VERSION.minor;
	return parsed.patch >= FIRST_PACKAGED_DIST_INVENTORY_VERSION.patch;
}
async function collectInstalledPackageDistErrors(params) {
	const criticalPaths = await collectCriticalInstalledPackageDistPaths(params.packageRoot);
	let inventoryFiles = null;
	let inventoryError = null;
	try {
		inventoryFiles = await readPackageDistInventoryIfPresent(params.packageRoot);
	} catch {
		inventoryError = `invalid package dist inventory ${PACKAGE_DIST_INVENTORY_RELATIVE_PATH}`;
	}
	if (inventoryFiles !== null) {
		const actualFiles = await collectPackageDistInventory(params.packageRoot);
		const inventoryErrors = await collectInstalledPathErrors({
			packageRoot: params.packageRoot,
			expectedFiles: inventoryFiles,
			actualFiles,
			missingMessage: (relativePath) => `missing packaged dist file ${relativePath}`,
			unexpectedMessage: (relativePath) => `unexpected packaged dist file ${relativePath}`
		});
		const inventorySet = new Set(inventoryFiles);
		const supplementalCriticalPaths = criticalPaths.filter((relativePath) => !inventorySet.has(relativePath));
		if (supplementalCriticalPaths.length === 0) return inventoryErrors;
		return [...inventoryErrors, ...await collectInstalledPathErrors({
			packageRoot: params.packageRoot,
			expectedFiles: supplementalCriticalPaths,
			actualFiles,
			missingMessage: (relativePath) => `missing bundled runtime sidecar ${relativePath}`
		})];
	}
	const criticalErrors = await collectInstalledPathErrors({
		packageRoot: params.packageRoot,
		expectedFiles: await collectLegacyInstalledPackageDistPaths(params.packageRoot),
		actualFiles: null,
		missingMessage: (relativePath) => `missing bundled runtime sidecar ${relativePath}`
	});
	if (inventoryError) return [inventoryError, ...criticalErrors];
	if (shouldRequirePackagedDistInventory(params.installedVersion) || shouldRequirePackagedDistInventory(params.expectedVersion)) return [`missing package dist inventory ${PACKAGE_DIST_INVENTORY_RELATIVE_PATH}`, ...criticalErrors];
	return criticalErrors;
}
async function collectLegacyInstalledPackageDistPaths(packageRoot) {
	return await collectCriticalInstalledPackageDistPaths(packageRoot);
}
async function collectCriticalInstalledPackageDistPaths(packageRoot) {
	const expectedFiles = /* @__PURE__ */ new Set();
	await Promise.all(BUNDLED_RUNTIME_SIDECAR_PATHS.map(async (relativePath) => {
		const pluginRoot = resolveBundledPluginRoot(relativePath);
		if (pluginRoot === null) return;
		if (OMITTED_PRIVATE_QA_BUNDLED_PLUGIN_ROOTS.has(pluginRoot)) return;
		if (await pathExists(path.join(packageRoot, pluginRoot, "package.json")) || await pathExists(path.join(packageRoot, pluginRoot, "daocore.plugin.json"))) expectedFiles.add(relativePath);
	}));
	return [...expectedFiles].toSorted((left, right) => left.localeCompare(right));
}
function resolveBundledPluginRoot(relativePath) {
	const match = /^dist\/extensions\/[^/]+/u.exec(relativePath);
	return match ? match[0] : null;
}
async function collectInstalledPathErrors(params) {
	const errors = [];
	const actualSet = params.actualFiles ? new Set(params.actualFiles) : null;
	for (const relativePath of params.expectedFiles) if (!(actualSet !== null ? actualSet.has(relativePath) : await pathExists(path.join(params.packageRoot, relativePath)))) errors.push(params.missingMessage(relativePath));
	if (actualSet !== null && params.unexpectedMessage) {
		const expectedSet = new Set(params.expectedFiles);
		for (const relativePath of params.actualFiles ?? []) if (!expectedSet.has(relativePath)) errors.push(params.unexpectedMessage(relativePath));
	}
	return errors;
}
function canResolveRegistryVersionForPackageTarget(value) {
	const trimmed = normalizePackageTarget(value);
	if (!trimmed) return true;
	return !isMainPackageTarget(trimmed) && !isExplicitPackageInstallSpec(trimmed);
}
async function resolvePortableGitPathPrepend() {
	if (process.platform !== "win32") return [];
	const localAppData = process.env.LOCALAPPDATA?.trim();
	if (!localAppData) return [];
	const portableGitRoot = path.join(localAppData, "DaoCore", "deps", "portable-git");
	const candidates = [
		path.join(portableGitRoot, "mingw64", "bin"),
		path.join(portableGitRoot, "usr", "bin"),
		path.join(portableGitRoot, "cmd"),
		path.join(portableGitRoot, "bin")
	];
	const existing = [];
	for (const candidate of candidates) if (await pathExists(candidate)) existing.push(candidate);
	return existing;
}
function applyWindowsPackageInstallEnv(env) {
	if (process.platform !== "win32") return;
	env.NPM_CONFIG_UPDATE_NOTIFIER = "false";
	env.NPM_CONFIG_FUND = "false";
	env.NPM_CONFIG_AUDIT = "false";
	env.NODE_LLAMA_CPP_SKIP_DOWNLOAD = "1";
}
function applyCorepackDownloadPromptEnv(env) {
	if (!env.COREPACK_ENABLE_DOWNLOAD_PROMPT?.trim()) env.COREPACK_ENABLE_DOWNLOAD_PROMPT = COREPACK_ENABLE_DOWNLOAD_PROMPT_DEFAULT;
}
function resolveGlobalInstallSpec(params) {
	const override = params.env?.DAOCORE_UPDATE_PACKAGE_SPEC?.trim() || process.env.DAOCORE_UPDATE_PACKAGE_SPEC?.trim();
	if (override) return override;
	const target = normalizePackageTarget(params.tag);
	if (isMainPackageTarget(target)) return DAOCORE_MAIN_PACKAGE_SPEC;
	if (isExplicitPackageInstallSpec(target)) return target;
	return `${params.packageName}@${target}`;
}
async function createGlobalInstallEnv(env) {
	const pathPrepend = await resolvePortableGitPathPrepend();
	const sourceEnv = env ?? process.env;
	const merged = Object.fromEntries(Object.entries(sourceEnv).filter(([, value]) => value != null).map(([key, value]) => [key, String(value)]));
	applyPathPrepend(merged, pathPrepend);
	applyWindowsPackageInstallEnv(merged);
	applyCorepackDownloadPromptEnv(merged);
	applyNpmFreshnessBypassEnv(merged);
	applyPosixNpmScriptShellEnv(merged);
	return merged;
}
async function tryRealpath(targetPath) {
	try {
		return await fs$1.realpath(targetPath);
	} catch {
		return path.resolve(targetPath);
	}
}
function resolveBunGlobalRoot() {
	const bunInstall = process.env.BUN_INSTALL?.trim() || path.join(os.homedir(), ".bun");
	return path.join(bunInstall, "install", "global", "node_modules");
}
function inferNpmPrefixFromPackageRoot(pkgRoot) {
	const trimmed = pkgRoot?.trim();
	if (!trimmed) return null;
	const normalized = path.resolve(trimmed);
	const pkgDir = path.dirname(normalized);
	if (pkgDir.startsWith("@") || path.basename(pkgDir).startsWith("@")) {
		const scopeDir = pkgDir;
		const nodeModulesDir = path.dirname(scopeDir);
		if (path.basename(nodeModulesDir) === "node_modules") {
			const parentDir = path.dirname(nodeModulesDir);
			if (path.basename(parentDir) === "lib") return path.dirname(parentDir);
			if (process.platform === "win32" && normalizeLowercaseStringOrEmpty(path.basename(parentDir)) === "npm") return parentDir;
		}
		return null;
	}
	const nodeModulesDir = path.dirname(normalized);
	if (path.basename(nodeModulesDir) !== "node_modules") return null;
	const parentDir = path.dirname(nodeModulesDir);
	if (path.basename(parentDir) === "lib") return path.dirname(parentDir);
	if (process.platform === "win32" && normalizeLowercaseStringOrEmpty(path.basename(parentDir)) === "npm") return parentDir;
	return null;
}
function resolveNpmGlobalPrefixLayoutFromGlobalRoot(globalRoot, options = {}) {
	const trimmed = globalRoot?.trim();
	if (!trimmed) return null;
	const normalized = path.resolve(trimmed);
	if (path.basename(normalized) !== "node_modules") return null;
	const parentDir = path.dirname(normalized);
	if (path.basename(parentDir) === "lib") {
		const prefix = path.dirname(parentDir);
		return {
			prefix,
			globalRoot: normalized,
			binDir: path.join(prefix, "bin")
		};
	}
	if (process.platform === "win32") return {
		prefix: parentDir,
		globalRoot: normalized,
		binDir: parentDir
	};
	if (options.allowDirectNodeModulesRoot) return {
		prefix: parentDir,
		globalRoot: normalized,
		binDir: path.join(normalized, ".bin")
	};
	return null;
}
function resolveNpmGlobalPrefixLayoutFromPrefix(prefix) {
	const resolvedPrefix = path.resolve(prefix);
	if (process.platform === "win32") return {
		prefix: resolvedPrefix,
		globalRoot: path.join(resolvedPrefix, "node_modules"),
		binDir: resolvedPrefix
	};
	return {
		prefix: resolvedPrefix,
		globalRoot: path.join(resolvedPrefix, "lib", "node_modules"),
		binDir: path.join(resolvedPrefix, "bin")
	};
}
function resolvePreferredNpmCommand(pkgRoot) {
	const prefix = inferNpmPrefixFromPackageRoot(pkgRoot);
	if (!prefix) return null;
	const candidate = process.platform === "win32" ? path.join(prefix, "npm.cmd") : path.join(prefix, "bin", "npm");
	return fs.existsSync(candidate) ? candidate : null;
}
function inferGlobalRootFromPackageRoot(pkgRoot) {
	const trimmed = pkgRoot?.trim();
	if (!trimmed) return null;
	const normalized = path.resolve(trimmed);
	const globalRoot = path.dirname(normalized);
	return path.basename(globalRoot) === "node_modules" ? globalRoot : null;
}
function isDirectNpmNodeModulesRoot(globalRoot) {
	return globalRoot !== null && resolveNpmGlobalPrefixLayoutFromGlobalRoot(globalRoot) === null && resolveNpmGlobalPrefixLayoutFromGlobalRoot(globalRoot, { allowDirectNodeModulesRoot: true }) !== null;
}
function inferBunGlobalRootFromPackageRoot(pkgRoot) {
	const directGlobalRoot = inferGlobalRootFromPackageRoot(pkgRoot);
	if (!directGlobalRoot) return null;
	return path.resolve(directGlobalRoot) === path.resolve(resolveBunGlobalRoot()) ? directGlobalRoot : null;
}
function inferPnpmGlobalRootFromPackageRoot(pkgRoot) {
	const directGlobalRoot = inferGlobalRootFromPackageRoot(pkgRoot);
	if (resolvePnpmGlobalDirFromGlobalRoot(directGlobalRoot)) return directGlobalRoot;
	const trimmed = pkgRoot?.trim();
	if (!trimmed) return null;
	const parts = path.resolve(trimmed).split(path.sep);
	const pnpmIndex = parts.lastIndexOf(".pnpm");
	if (pnpmIndex <= 0) return null;
	if (parts[pnpmIndex + 2] !== "node_modules") return null;
	const layoutDir = parts.slice(0, pnpmIndex).join(path.sep) || path.sep;
	const globalRoot = path.basename(layoutDir) === "node_modules" ? layoutDir : path.join(layoutDir, "node_modules");
	return resolvePnpmGlobalDirFromGlobalRoot(globalRoot) ? globalRoot : null;
}
function resolvePnpmGlobalDirFromGlobalRoot(globalRoot) {
	const trimmed = globalRoot?.trim();
	if (!trimmed) return null;
	const normalized = path.resolve(trimmed);
	if (path.basename(normalized) !== "node_modules") return null;
	const layoutDir = path.dirname(normalized);
	return /^\d+$/u.test(path.basename(layoutDir)) ? path.dirname(layoutDir) : null;
}
async function isPnpmGlobalPackageRoot(pkgRoot) {
	const globalRoot = inferPnpmGlobalRootFromPackageRoot(pkgRoot);
	if (!globalRoot) return false;
	const layoutDir = path.dirname(globalRoot);
	if (!await pathExists(path.join(globalRoot, ".modules.yaml"))) return false;
	return await pathExists(path.join(layoutDir, "pnpm-lock.yaml")) || await pathExists(path.join(layoutDir, "package.json"));
}
function resolvePreferredGlobalManagerCommand(manager, pkgRoot) {
	if (manager !== "npm") return manager;
	return resolvePreferredNpmCommand(pkgRoot) ?? manager;
}
function resolveGlobalInstallCommand(manager, pkgRoot) {
	return {
		manager,
		command: resolvePreferredGlobalManagerCommand(manager, pkgRoot)
	};
}
function normalizeGlobalInstallCommand(managerOrCommand, pkgRoot) {
	return typeof managerOrCommand === "string" ? resolveGlobalInstallCommand(managerOrCommand, pkgRoot) : managerOrCommand;
}
function resolveInstallCommandForManager(managerOrCommand, manager, pkgRoot) {
	const normalized = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);
	return normalized.manager === manager ? normalized : resolveGlobalInstallCommand(manager, pkgRoot);
}
async function resolveGlobalRoot(managerOrCommand, runCommand, timeoutMs, pkgRoot) {
	const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);
	if (resolved.manager === "bun") return resolveBunGlobalRoot();
	const res = await runCommand([
		resolved.command,
		"root",
		"-g"
	], { timeoutMs }).catch(() => null);
	if (!res || res.code !== 0) return null;
	return res.stdout.trim() || null;
}
async function resolveGlobalInstallTarget(params) {
	const honoredPackageRootGlobalRoot = params.honorPackageRoot ? inferGlobalRootFromPackageRoot(params.pkgRoot) : null;
	const pnpmPackageRootGlobalRoot = await isPnpmGlobalPackageRoot(params.pkgRoot) ? inferPnpmGlobalRootFromPackageRoot(params.pkgRoot) : null;
	const bunPackageRootGlobalRoot = inferBunGlobalRootFromPackageRoot(params.pkgRoot);
	const honoredDirectNpmRoot = pnpmPackageRootGlobalRoot === null && bunPackageRootGlobalRoot === null && isDirectNpmNodeModulesRoot(honoredPackageRootGlobalRoot);
	const command = bunPackageRootGlobalRoot ? resolveInstallCommandForManager(params.manager, "bun", params.pkgRoot) : pnpmPackageRootGlobalRoot ? resolveInstallCommandForManager(params.manager, "pnpm", params.pkgRoot) : honoredDirectNpmRoot ? resolveInstallCommandForManager(params.manager, "npm", params.pkgRoot) : normalizeGlobalInstallCommand(params.manager, params.pkgRoot);
	const globalRoot = await resolveGlobalRoot(command, params.runCommand, params.timeoutMs, params.pkgRoot);
	const pkgRootGlobalRoot = command.manager === "pnpm" ? pnpmPackageRootGlobalRoot : null;
	const targetGlobalRoot = (command.manager === "bun" ? bunPackageRootGlobalRoot : null) ?? pkgRootGlobalRoot ?? (command.manager === "npm" ? honoredPackageRootGlobalRoot : null) ?? globalRoot;
	return {
		...command,
		globalRoot: targetGlobalRoot,
		packageRoot: targetGlobalRoot ? path.join(targetGlobalRoot, PRIMARY_PACKAGE_NAME) : null,
		...honoredPackageRootGlobalRoot && targetGlobalRoot === honoredPackageRootGlobalRoot && honoredDirectNpmRoot ? { directNodeModulesRoot: true } : {}
	};
}
async function detectGlobalInstallManagerForRoot(runCommand, pkgRoot, timeoutMs) {
	const pkgReal = await tryRealpath(pkgRoot);
	for (const { manager, argv } of [{
		manager: "npm",
		argv: [
			"npm",
			"root",
			"-g"
		]
	}, {
		manager: "pnpm",
		argv: [
			"pnpm",
			"root",
			"-g"
		]
	}]) {
		const res = await runCommand(argv, { timeoutMs }).catch(() => null);
		if (!res || res.code !== 0) continue;
		const globalRoot = res.stdout.trim();
		if (!globalRoot) continue;
		const globalReal = await tryRealpath(globalRoot);
		for (const name of ALL_PACKAGE_NAMES) {
			const expectedReal = await tryRealpath(path.join(globalReal, name));
			if (path.resolve(expectedReal) === path.resolve(pkgReal)) return manager;
		}
	}
	if (await isPnpmGlobalPackageRoot(pkgRoot)) return "pnpm";
	const bunGlobalReal = await tryRealpath(resolveBunGlobalRoot());
	for (const name of ALL_PACKAGE_NAMES) {
		const bunExpectedReal = await tryRealpath(path.join(bunGlobalReal, name));
		if (path.resolve(bunExpectedReal) === path.resolve(pkgReal)) return "bun";
	}
	if (resolvePreferredNpmCommand(pkgRoot)) return "npm";
	return null;
}
async function detectGlobalInstallManagerByPresence(runCommand, timeoutMs) {
	for (const manager of ["npm", "pnpm"]) {
		const root = await resolveGlobalRoot(manager, runCommand, timeoutMs);
		if (!root) continue;
		for (const name of ALL_PACKAGE_NAMES) if (await pathExists(path.join(root, name))) return manager;
	}
	const bunRoot = resolveBunGlobalRoot();
	for (const name of ALL_PACKAGE_NAMES) if (await pathExists(path.join(bunRoot, name))) return "bun";
	return null;
}
function globalInstallArgs(managerOrCommand, spec, pkgRoot, installPrefix) {
	const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);
	if (resolved.manager === "pnpm") return [
		resolved.command,
		"add",
		"-g",
		...installPrefix ? ["--global-dir", installPrefix] : [],
		...isPnpmDaoCoreSourceInstallSpec(spec) ? [PNPM_DAOCORE_BUILD_ALLOWLIST_FLAG] : [],
		spec
	];
	if (resolved.manager === "bun") return [
		resolved.command,
		"add",
		"-g",
		spec
	];
	return [
		resolved.command,
		"i",
		"-g",
		...installPrefix ? ["--prefix", installPrefix] : [],
		spec,
		...NPM_GLOBAL_INSTALL_QUIET_FLAGS,
		...createNpmFreshnessBypassArgs(process.env, /* @__PURE__ */ new Date(), { npmConfigPrefix: installPrefix })
	];
}
function globalInstallFallbackArgs(managerOrCommand, spec, pkgRoot, installPrefix) {
	const resolved = normalizeGlobalInstallCommand(managerOrCommand, pkgRoot);
	if (resolved.manager !== "npm") return null;
	return [
		resolved.command,
		"i",
		"-g",
		...installPrefix ? ["--prefix", installPrefix] : [],
		spec,
		"--omit=optional",
		...NPM_GLOBAL_INSTALL_QUIET_FLAGS,
		...createNpmFreshnessBypassArgs(process.env, /* @__PURE__ */ new Date(), { npmConfigPrefix: installPrefix })
	];
}
async function cleanupGlobalRenameDirs(params) {
	const removed = [];
	const root = params.globalRoot.trim();
	const name = params.packageName.trim();
	if (!root || !name) return { removed };
	const prefix = `${GLOBAL_RENAME_PREFIX}${name}-`;
	let entries = [];
	try {
		entries = await fs$1.readdir(root);
	} catch {
		return { removed };
	}
	for (const entry of entries) {
		if (!entry.startsWith(prefix)) continue;
		const target = path.join(root, entry);
		try {
			if (!(await fs$1.lstat(target)).isDirectory()) continue;
			await fs$1.rm(target, {
				recursive: true,
				force: true
			});
			removed.push(entry);
		} catch {}
	}
	return { removed };
}
//#endregion
export { detectGlobalInstallManagerByPresence as a, globalInstallFallbackArgs as c, resolveGlobalInstallTarget as d, resolveNpmGlobalPrefixLayoutFromGlobalRoot as f, createGlobalInstallEnv as i, resolveExpectedInstalledVersionFromSpec as l, resolvePnpmGlobalDirFromGlobalRoot as m, cleanupGlobalRenameDirs as n, detectGlobalInstallManagerForRoot as o, resolveNpmGlobalPrefixLayoutFromPrefix as p, collectInstalledGlobalPackageErrors as r, globalInstallArgs as s, canResolveRegistryVersionForPackageTarget as t, resolveGlobalInstallSpec as u };
