// src/actions/packman/convertToNpm.ts
import {
  existsSync as existsSync3,
  readFileSync as readFileSync4,
  rmSync,
  writeFileSync as writeFileSync3
} from "node:fs";
import PATH2 from "node:path";
import chalk4 from "chalk";

// src/lib/crossSpawn.ts
import crossSpawn from "cross-spawn";
function spawnSync(command, args, options) {
  return crossSpawn.sync(command, args, options);
}

// src/lib/packageManagerRuntime.ts
import fs from "node:fs";
import chalk from "chalk";
var DISPLAY_NAMES = {
  bun: "Bun",
  npm: "npm",
  pnpm: "pnpm",
  yarn: "Yarn"
};
var MAC_INSTALL_COMMANDS = {
  bun: "brew install oven-sh/bun/bun",
  npm: "brew install node",
  pnpm: "brew install pnpm",
  yarn: "brew install yarn"
};
function currentPlatform() {
  if (process.platform === "darwin" || process.platform === "linux" || process.platform === "win32") {
    return process.platform;
  }
  return "unknown";
}
function askYesNo(question) {
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
    return false;
  }
  process.stdout.write(question);
  const buffer = Buffer.alloc(1024);
  const bytesRead = fs.readSync(process.stdin.fd, buffer, 0, buffer.length, null);
  const answer = buffer.toString("utf8", 0, bytesRead).trim().toLowerCase();
  return answer === "y" || answer === "yes";
}
function isCommandInstalled(command) {
  const result = spawnSync(command, ["--version"], {
    encoding: "utf8",
    stdio: "ignore"
  });
  return !result.error && result.status === 0;
}
function isPackageManagerInstalled(pm) {
  return isCommandInstalled(pm);
}
function getPackageManagerInstallPlan(pm, platform = currentPlatform()) {
  const displayName = DISPLAY_NAMES[pm];
  if (platform === "darwin") {
    const command = MAC_INSTALL_COMMANDS[pm];
    return {
      command,
      manualInstructions: [
        `Install ${displayName} with: ${command}`
      ],
      packageManager: pm,
      platform,
      supported: true
    };
  }
  if (platform === "linux") {
    return {
      manualInstructions: [
        `Automatic installation for ${displayName} is not implemented on Linux yet.`,
        `Install ${displayName} manually and re-run the command.`
      ],
      packageManager: pm,
      platform,
      supported: false
    };
  }
  if (platform === "win32") {
    return {
      manualInstructions: [
        `Automatic installation for ${displayName} is not implemented on Windows yet.`,
        `Install ${displayName} manually and re-run the command.`
      ],
      packageManager: pm,
      platform,
      supported: false
    };
  }
  return {
    manualInstructions: [
      `Automatic installation for ${displayName} is not implemented on ${platform} yet.`,
      `Install ${displayName} manually and re-run the command.`
    ],
    packageManager: pm,
    platform,
    supported: false
  };
}
function printManualInstructions(plan, context) {
  console.error(chalk.yellow(`${DISPLAY_NAMES[plan.packageManager]} is required for "${context.operation}".`));
  for (const line of plan.manualInstructions) {
    console.error(chalk.gray(`  ${line}`));
  }
}
function installWithHomebrew(pm, cwd) {
  const command = MAC_INSTALL_COMMANDS[pm];
  const result = spawnSync("brew", command.replace("brew ", "").split(" "), {
    cwd,
    encoding: "utf8",
    stdio: "inherit"
  });
  return result.status === 0;
}
function ensurePackageManagerInstalled(pm, context) {
  if (isPackageManagerInstalled(pm)) return true;
  const plan = getPackageManagerInstallPlan(pm, context.platform ?? currentPlatform());
  const displayName = DISPLAY_NAMES[pm];
  console.error(chalk.yellow(`${context.operation} requires ${displayName}, but it is not installed.`));
  if (!plan.supported) {
    printManualInstructions(plan, context);
    return false;
  }
  if (!isCommandInstalled("brew")) {
    console.error(chalk.yellow("Homebrew is not installed, so automatic installation is unavailable."));
    console.error(chalk.gray("  Install Homebrew from https://brew.sh and then run:"));
    console.error(chalk.gray(`  ${plan.command}`));
    return false;
  }
  const confirmed = askYesNo(chalk.cyan(`Install ${displayName} with Homebrew now? [y/N] `));
  if (!confirmed) {
    console.error(chalk.gray(`Skipping install. Run "${plan.command}" manually and then retry.`));
    return false;
  }
  console.error(chalk.cyan(`Installing ${displayName} via Homebrew...
`));
  if (!installWithHomebrew(pm, context.cwd)) {
    console.error(chalk.red(`Homebrew failed to install ${displayName}.`));
    console.error(chalk.gray(`Run "${plan.command}" manually and then retry.`));
    return false;
  }
  if (!isPackageManagerInstalled(pm)) {
    console.error(chalk.red(`${displayName} still does not appear to be installed after Homebrew completed.`));
    console.error(chalk.gray(`Run "${plan.command}" manually and then retry.`));
    return false;
  }
  console.error(chalk.green(`${displayName} installed successfully.`));
  return true;
}
function failureResult() {
  return {
    output: ["", ""],
    pid: 0,
    signal: null,
    status: 1,
    stderr: "",
    stdout: ""
  };
}
function spawnPackageManagerSync(pm, args, options) {
  if (!ensurePackageManagerInstalled(pm, options.context)) {
    return failureResult();
  }
  return spawnSync(pm, args, { encoding: "utf8", ...options });
}

// src/lib/toolchainVersion.ts
import { readFileSync } from "node:fs";
import { createRequire } from "node:module";
var require2 = createRequire(import.meta.url);
function bundledToolchainVersion() {
  const pkgPath = require2.resolve("@xylabs/toolchain/package.json");
  const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
  if (!pkg.version) throw new Error("Could not read @xylabs/toolchain version");
  return pkg.version;
}
function bundledToolchainRange() {
  return `^${bundledToolchainVersion()}`;
}

// src/actions/packman/rewriteScripts.ts
function xyCommand(pm) {
  switch (pm) {
    case "bun": {
      return "bun run xy";
    }
    case "npm": {
      return "npm exec -- xy";
    }
    case "pnpm": {
      return "pnpm xy";
    }
    default: {
      return "yarn xy";
    }
  }
}
function rootRunCommand(pm, script, rest = "") {
  const suffix = rest.trim() ? ` ${rest.trim()}` : "";
  return `${pm} run ${script}${suffix}`;
}
function addCommand(pm) {
  switch (pm) {
    case "bun": {
      return "bun add";
    }
    case "npm": {
      return "npm install";
    }
    case "pnpm": {
      return "pnpm add";
    }
    default: {
      return "yarn add";
    }
  }
}
function removeCommand(pm) {
  switch (pm) {
    case "bun": {
      return "bun remove";
    }
    case "npm": {
      return "npm uninstall";
    }
    case "pnpm": {
      return "pnpm remove";
    }
    default: {
      return "yarn remove";
    }
  }
}
function installCommand(pm) {
  return `${pm} install`;
}
function outdatedCommand(pm) {
  return `${pm} outdated`;
}
function dedupeCommand(pm) {
  return pm === "npm" ? "npm dedupe" : `${pm} dedupe`;
}
function trimRest(rest) {
  if (!rest) return "";
  const normalized = rest.trim();
  return normalized ? ` ${normalized}` : "";
}
function workspaceRunCommand(pm, pkg, script, rest = "") {
  const suffix = trimRest(rest);
  switch (pm) {
    case "bun": {
      return `bun run --filter ${pkg} ${script}${suffix}`;
    }
    case "npm": {
      return `npm run ${script} --workspace=${pkg}${suffix}`;
    }
    case "pnpm": {
      return `pnpm --filter ${pkg} run ${script}${suffix}`;
    }
    default: {
      return `yarn workspace ${pkg} run ${script}${suffix}`;
    }
  }
}
function workspaceRunAllCommand(pm, script, rest = "") {
  const suffix = trimRest(rest);
  switch (pm) {
    case "bun": {
      return `bun run --workspaces --if-present ${script}${suffix}`;
    }
    case "npm": {
      return `npm run ${script} --workspaces --if-present${suffix}`;
    }
    case "pnpm": {
      return `pnpm -r run ${script}${suffix}`;
    }
    default: {
      return `yarn workspaces foreach -Apt run ${script}${suffix}`;
    }
  }
}
function normalizeWorkspaceCommands(script, target) {
  let result = script;
  result = result.replaceAll(/\byarn workspace (\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\byarn workspace (\S+) (package-\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bpnpm --filter (\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bpnpm --filter (\S+) (package-\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bnpm run (\S+) --workspace(?:=|\s+)(\S+)(?:\s+(.*))?$/g, (_, command, pkg, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bnpm --workspace(?:=|\s+)(\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bnpm run (\S+) -w (\S+)(?:\s+(.*))?$/g, (_, command, pkg, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bbun run --filter (\S+) (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\bbun --filter (\S+) run (\S+)(?:\s+(.*))?$/g, (_, pkg, command, rest) => workspaceRunCommand(target, pkg, command, rest));
  result = result.replaceAll(/\byarn workspaces foreach\s+(?:[^\s]+\s+)*run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  result = result.replaceAll(/\bpnpm -r(?:\s+[^\s]+)* run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  result = result.replaceAll(/\bnpm run (\S+) --workspaces(?: --if-present)?(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  result = result.replaceAll(/\bbun run(?:\s+--[^\s]+)* --workspaces(?: --if-present)? (\S+)(?:\s+(.*))?$/g, (_, command, rest) => workspaceRunAllCommand(target, command, rest));
  return result;
}
function normalizeRootRunCommands(script, target) {
  let result = script;
  result = result.replaceAll(/\byarn run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  result = result.replaceAll(/\bpnpm run (\S+)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  result = result.replaceAll(/\bnpm run (\S+)(?!\s+(?:--workspace(?:=|\s)|-w\s|--workspaces)\b)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  result = result.replaceAll(/\bbun run (\S+)(?!\s+(?:--filter|--workspaces)\b)(?:\s+(.*))?$/g, (_, command, rest) => rootRunCommand(target, command, rest));
  return result;
}
function normalizeXyCommands(script, target) {
  return script.replaceAll(/\byarn xy\b/g, xyCommand(target)).replaceAll(/\bpnpm xy\b/g, xyCommand(target)).replaceAll(/\bnpm exec(?: --)? xy\b/g, xyCommand(target)).replaceAll(/\bnpx(?: --no-install)? xy\b/g, xyCommand(target)).replaceAll(/\bbun run xy\b/g, xyCommand(target)).replaceAll(/\bbun x xy\b/g, xyCommand(target));
}
function rewriteScript(script, target) {
  let result = normalizeWorkspaceCommands(script, target);
  result = normalizeRootRunCommands(result, target);
  result = normalizeXyCommands(result, target);
  result = result.replaceAll(/\byarn add\b/g, addCommand(target));
  result = result.replaceAll(/\bpnpm add\b/g, addCommand(target));
  result = result.replaceAll(/\bbun add\b/g, addCommand(target));
  result = result.replaceAll(/\byarn remove\b/g, removeCommand(target));
  result = result.replaceAll(/\bpnpm remove\b/g, removeCommand(target));
  result = result.replaceAll(/\bbun remove\b/g, removeCommand(target));
  result = result.replaceAll(/\bnpm uninstall\b/g, removeCommand(target));
  result = result.replaceAll(/\byarn install\b/g, installCommand(target));
  result = result.replaceAll(/\bpnpm install\b/g, installCommand(target));
  result = result.replaceAll(/\bbun install\b/g, installCommand(target));
  result = result.replaceAll(/\bnpm install\b/g, installCommand(target));
  result = result.replaceAll(/\byarn dedupe\b/g, dedupeCommand(target));
  result = result.replaceAll(/\bpnpm dedupe\b/g, dedupeCommand(target));
  result = result.replaceAll(/\bnpm dedupe\b/g, dedupeCommand(target));
  result = result.replaceAll(/\byarn outdated\b/g, outdatedCommand(target));
  result = result.replaceAll(/\bpnpm outdated\b/g, outdatedCommand(target));
  result = result.replaceAll(/\bbun outdated\b/g, outdatedCommand(target));
  result = result.replaceAll(/\bnpm outdated\b/g, outdatedCommand(target));
  return result;
}
function rewriteScriptsInPackageJson(pkg, target) {
  const scripts = pkg.scripts;
  if (!scripts) return pkg;
  const rewritten = {};
  for (const [name, script] of Object.entries(scripts)) {
    rewritten[name] = rewriteScript(script, target);
  }
  return { ...pkg, scripts: rewritten };
}

// src/actions/packman/rewriteSourceImports.ts
import {
  existsSync,
  readFileSync as readFileSync2,
  writeFileSync
} from "node:fs";
import chalk2 from "chalk";
import { globSync } from "glob";
var SWAPS = [
  ["@xylabs/toolchain", "@xylabs/toolchain"],
  ["@xylabs/toolchain", "@xylabs/toolchain"]
];
var SOURCE_GLOBS = [
  "**/*.ts",
  "**/*.tsx",
  "**/*.mts",
  "**/*.cts",
  "**/*.js",
  "**/*.mjs"
];
var IGNORE_PATTERNS = [
  "**/node_modules/**",
  "**/dist/**",
  "**/build/**",
  "**/.yarn/**"
];
function rewriteSourceImports(cwd) {
  const files = globSync(SOURCE_GLOBS, {
    cwd,
    absolute: true,
    ignore: IGNORE_PATTERNS
  });
  let count = 0;
  for (const file of files) {
    if (!existsSync(file)) continue;
    const original = readFileSync2(file, "utf8");
    let content = original;
    for (const [from, to] of SWAPS) {
      content = content.replaceAll(from, to);
    }
    if (content !== original) {
      writeFileSync(file, content, "utf8");
      count++;
    }
  }
  if (count > 0) {
    console.log(chalk2.green(`  Rewrote toolchain imports in ${count} source file(s)`));
  }
}

// src/actions/packman/swapTsScriptsDependency.ts
import {
  existsSync as existsSync2,
  readFileSync as readFileSync3,
  writeFileSync as writeFileSync2
} from "node:fs";
import PATH from "node:path";
import chalk3 from "chalk";
var TARGET_PACKAGE = "@xylabs/toolchain";
var managedPackages = [
  "@xylabs/toolchain",
  "@xylabs/toolchain",
  "@xylabs/toolchain"
];
function setToolchainInPackageJson(pkgPath, range) {
  if (!existsSync2(pkgPath)) return false;
  const raw = readFileSync3(pkgPath, "utf8");
  const pkg = JSON.parse(raw);
  let changed = false;
  let foundInDepsField;
  for (const depField of ["dependencies", "devDependencies"]) {
    const deps = pkg[depField];
    if (!deps) continue;
    let removed = false;
    for (const name of managedPackages) {
      if (deps[name]) {
        delete deps[name];
        removed = true;
        changed = true;
      }
    }
    if (removed) {
      foundInDepsField = depField;
      deps[TARGET_PACKAGE] = range;
    }
  }
  if (foundInDepsField) {
    const targetDeps = pkg[foundInDepsField];
    if (targetDeps[TARGET_PACKAGE] !== range) {
      targetDeps[TARGET_PACKAGE] = range;
      changed = true;
    }
  } else {
    const devDeps = pkg.devDependencies ?? {};
    if (devDeps[TARGET_PACKAGE] !== range) {
      devDeps[TARGET_PACKAGE] = range;
      pkg.devDependencies = devDeps;
      changed = true;
    }
  }
  if (changed) {
    writeFileSync2(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
  }
  return changed;
}
function swapTsScriptsDependency(cwd, workspacePackageJsonPaths) {
  const range = bundledToolchainRange();
  let count = 0;
  if (setToolchainInPackageJson(PATH.join(cwd, "package.json"), range)) {
    count++;
  }
  for (const pkgPath of workspacePackageJsonPaths) {
    const fullPath = PATH.resolve(cwd, pkgPath, "package.json");
    if (setToolchainInPackageJson(fullPath, range)) {
      count++;
    }
  }
  if (count > 0) {
    console.log(chalk3.green(`  Set toolchain dependency to ${TARGET_PACKAGE}@${range} in ${count} package(s)`));
  }
}

// src/actions/packman/convertToNpm.ts
var NPM_VERSION = "10.9.4";
function readWorkspacePatterns(cwd) {
  const pkgPath = PATH2.join(cwd, "package.json");
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
  return pkg.workspaces ?? [];
}
function updateRootPackageJson(cwd) {
  const pkgPath = PATH2.join(cwd, "package.json");
  const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
  pkg.packageManager = `npm@${NPM_VERSION}`;
  const updated = rewriteScriptsInPackageJson(pkg, "npm");
  writeFileSync3(pkgPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
  console.log(chalk4.green("  Updated root package.json"));
}
function deleteArtifacts(cwd) {
  for (const relativePath of ["bun.lock", "bun.lockb", "pnpm-lock.yaml", "pnpm-workspace.yaml", "yarn.lock", ".yarnrc.yml"]) {
    const fullPath = PATH2.join(cwd, relativePath);
    if (existsSync3(fullPath)) {
      rmSync(fullPath, { force: true, recursive: true });
      console.log(chalk4.gray(`  Deleted ${relativePath}`));
    }
  }
  const yarnDir = PATH2.join(cwd, ".yarn");
  if (existsSync3(yarnDir)) {
    rmSync(yarnDir, { force: true, recursive: true });
    console.log(chalk4.gray("  Deleted .yarn/"));
  }
}
function convertToNpm(cwd, workspacePackageJsonPaths) {
  console.log(chalk4.blue("\nConverting to npm...\n"));
  const workspacePatterns = readWorkspacePatterns(cwd);
  if (workspacePatterns.length === 0) {
    console.warn(chalk4.yellow("  No root package.json workspaces found; npm monorepo support relies on the workspaces field"));
  }
  updateRootPackageJson(cwd);
  for (const pkgPath of workspacePackageJsonPaths) {
    const fullPath = PATH2.resolve(cwd, pkgPath, "package.json");
    if (!existsSync3(fullPath)) continue;
    const pkg = JSON.parse(readFileSync4(fullPath, "utf8"));
    const updated = rewriteScriptsInPackageJson(pkg, "npm");
    if (JSON.stringify(pkg) !== JSON.stringify(updated)) {
      writeFileSync3(fullPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
    }
  }
  console.log(chalk4.green(`  Rewrote scripts in ${workspacePackageJsonPaths.length} workspace package(s)`));
  swapTsScriptsDependency(cwd, workspacePackageJsonPaths);
  rewriteSourceImports(cwd);
  deleteArtifacts(cwd);
  console.log(chalk4.blue("\nRunning npm install..."));
  const install = spawnPackageManagerSync("npm", ["install"], {
    context: { cwd, operation: "Convert repo to npm and install dependencies" },
    cwd,
    encoding: "utf8",
    stdio: "inherit"
  });
  if (install.status !== 0) {
    console.error(chalk4.red("npm install failed"));
    return 1;
  }
  console.log(chalk4.blue("\nConversion complete.\n"));
  return 0;
}
export {
  convertToNpm
};
//# sourceMappingURL=convertToNpm.mjs.map
