// src/lib/packageManagerRuntime.ts
import { spawnSync } from "child_process";
import fs from "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",
    shell: false,
    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",
    shell: false,
    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/pm/workspaces.ts
import { existsSync, readFileSync } from "fs";
import PATH from "path";
import { globSync } from "glob";
function readJsonFile(path) {
  if (!existsSync(path)) return void 0;
  try {
    return JSON.parse(readFileSync(path, "utf8"));
  } catch {
    return void 0;
  }
}
function readRootPackageJson(cwd = process.cwd()) {
  return readJsonFile(PATH.resolve(cwd, "package.json"));
}
function readWorkspacePatternsFromPackageJson(cwd = process.cwd()) {
  const pkg = readRootPackageJson(cwd);
  if (!pkg?.workspaces) return [];
  if (Array.isArray(pkg.workspaces)) return [...pkg.workspaces];
  return pkg.workspaces.packages ? [...pkg.workspaces.packages] : [];
}
function readPnpmWorkspacePatterns(cwd = process.cwd()) {
  const wsPath = PATH.resolve(cwd, "pnpm-workspace.yaml");
  if (!existsSync(wsPath)) return [];
  const content = readFileSync(wsPath, "utf8");
  const patterns = [];
  let inPackages = false;
  for (const line of content.split("\n")) {
    if (/^packages\s*:/.test(line.trim())) {
      inPackages = true;
      continue;
    }
    if (inPackages) {
      const match = /^\s+-\s+['"]?([^'"]+)['"]?\s*$/.exec(line);
      if (match) {
        patterns.push(match[1]);
      } else if (line.trim() !== "" && !/^\s/.test(line)) {
        break;
      }
    }
  }
  return patterns;
}
function readWorkspacePatterns(cwd = process.cwd()) {
  const fromPackageJson = readWorkspacePatternsFromPackageJson(cwd);
  return fromPackageJson.length > 0 ? fromPackageJson : readPnpmWorkspacePatterns(cwd);
}
function listDeclaredWorkspaces(cwd = process.cwd()) {
  const patterns = readWorkspacePatterns(cwd);
  const seen = /* @__PURE__ */ new Set();
  const workspaces = [];
  for (const pattern of patterns) {
    const matches = globSync(PATH.posix.join(pattern.replaceAll(PATH.sep, "/"), "package.json"), {
      absolute: true,
      cwd,
      ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"]
    });
    for (const match of matches) {
      const pkg = readJsonFile(match);
      if (!pkg?.name) continue;
      const location = PATH.relative(cwd, PATH.dirname(match)) || ".";
      if (seen.has(location)) continue;
      seen.add(location);
      workspaces.push({ location, name: pkg.name });
    }
  }
  return workspaces.toSorted((a, b) => a.location.localeCompare(b.location));
}
function detectPackageManagerFromPackageJson(cwd = process.cwd()) {
  const packageManager = readRootPackageJson(cwd)?.packageManager;
  if (!packageManager) return void 0;
  return packageManager.split("@")[0];
}

// src/pm/bunPackageManager.ts
function parseBunVersions(output) {
  const versions = /* @__PURE__ */ new Map();
  for (const line of output.split("\n")) {
    const match = /(?:^|[├└]── )(@?[^@\s]+(?:\/[^@\s]+)?)@([^\s]+)/.exec(line.trim());
    if (match && !versions.has(match[1])) {
      versions.set(match[1], match[2]);
    }
  }
  return versions;
}
var BunPackageManager = class {
  command = "bun";
  lockfile = "bun.lock";
  name = "bun";
  dedupe() {
    return ["bun", ["install"]];
  }
  findWorkspace(name) {
    return this.listWorkspaces().find((ws) => ws.name === name);
  }
  foreachWorkspace(script, args = [], _options) {
    return ["bun", ["run", "--workspaces", "--if-present", script, ...args]];
  }
  install() {
    return ["bun", ["install"]];
  }
  listInstalledVersions() {
    const result = spawnPackageManagerSync("bun", ["pm", "ls", "--all"], {
      context: { operation: "Inspect installed bun package versions" },
      encoding: "utf8",
      maxBuffer: 64 * 1024 * 1024,
      shell: true
    });
    if (result.error) return /* @__PURE__ */ new Map();
    return parseBunVersions(result.stdout);
  }
  listWorkspaces() {
    return listDeclaredWorkspaces();
  }
  outdated() {
    return ["bun", ["outdated"]];
  }
  publish(_options = {}) {
    return [["bun", ["publish"]]];
  }
  runInWorkspace(pkg, script, args = []) {
    return ["bun", ["run", "--filter", pkg, script, ...args]];
  }
  runXy(args) {
    return ["bun", ["run", "xy", ...args]];
  }
  versionApply() {
    return ["bun", ["install"]];
  }
  versionBump(type) {
    const workspaces = this.listWorkspaces();
    return workspaces.map((workspace) => [
      "npm",
      ["version", type, `--workspace=${workspace.name}`, "--no-git-tag-version"]
    ]);
  }
};

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

// src/pm/detectReact.ts
import { readFileSync as readFileSync2 } from "fs";

// src/pm/registry.ts
var implementations = /* @__PURE__ */ new Map();
function registerPackageManager(pm) {
  implementations.set(pm.name, pm);
}
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/pm/detectReact.ts
var cached;
function detectReact() {
  if (cached !== void 0) return cached;
  try {
    const pm = getPackageManager();
    const workspaces = pm.listWorkspaces();
    cached = workspaces.some((ws) => {
      try {
        const pkg = JSON.parse(readFileSync2(`${ws.location}/package.json`, "utf8"));
        const allDeps = {
          ...pkg.dependencies,
          ...pkg.devDependencies,
          ...pkg.peerDependencies
        };
        return "react" in allDeps || "react-dom" in allDeps;
      } catch {
        return false;
      }
    });
  } catch {
    cached = false;
  }
  return cached;
}

// src/pm/npmPackageManager.ts
function collectVersions(node, versions) {
  if (!node || typeof node !== "object") return;
  const value = node;
  if (value.name && value.version && !versions.has(value.name)) {
    versions.set(value.name, value.version);
  }
  for (const dep of Object.values(value.dependencies ?? {})) {
    collectVersions(dep, versions);
  }
}
var NpmPackageManager = class {
  command = "npm";
  lockfile = "package-lock.json";
  name = "npm";
  dedupe() {
    return ["npm", ["dedupe"]];
  }
  findWorkspace(name) {
    return this.listWorkspaces().find((ws) => ws.name === name);
  }
  foreachWorkspace(script, args = [], _options) {
    const extraArgs = args.length > 0 ? ["--", ...args] : [];
    return ["npm", ["run", script, "--workspaces", "--if-present", ...extraArgs]];
  }
  install() {
    return ["npm", ["install"]];
  }
  listInstalledVersions() {
    const result = spawnPackageManagerSync("npm", ["ls", "--workspaces", "--all", "--json"], {
      context: { operation: "Inspect installed npm package versions" },
      encoding: "utf8",
      maxBuffer: 64 * 1024 * 1024,
      shell: true
    });
    const versions = /* @__PURE__ */ new Map();
    if (result.error) return versions;
    try {
      collectVersions(JSON.parse(result.stdout), versions);
    } catch {
    }
    return versions;
  }
  listWorkspaces() {
    return listDeclaredWorkspaces();
  }
  outdated() {
    return ["npm", ["outdated", "--workspaces"]];
  }
  publish(_options = {}) {
    return [["npm", ["publish", "--workspaces", "--include-workspace-root=false"]]];
  }
  runInWorkspace(pkg, script, args = []) {
    const extraArgs = args.length > 0 ? ["--", ...args] : [];
    return ["npm", ["run", script, `--workspace=${pkg}`, ...extraArgs]];
  }
  runXy(args) {
    return ["npm", ["exec", "--", "xy", ...args]];
  }
  versionApply() {
    return ["npm", ["install", "--package-lock-only"]];
  }
  versionBump(type) {
    return [[
      "npm",
      ["version", type, "--workspaces", "--include-workspace-root=false", "--no-git-tag-version"]
    ]];
  }
};

// src/pm/pnpmPackageManager.ts
import { readFileSync as readFileSync3 } from "fs";
import PATH2 from "path";
function isPublishableWorkspace(location) {
  try {
    const pkgPath = PATH2.resolve(location, "package.json");
    const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
    return pkg.private !== true;
  } catch {
    return false;
  }
}
var PnpmPackageManager = class {
  command = "pnpm";
  lockfile = "pnpm-lock.yaml";
  name = "pnpm";
  dedupe() {
    return ["pnpm", ["dedupe"]];
  }
  findWorkspace(name) {
    return this.listWorkspaces().find((ws) => ws.name === name);
  }
  foreachWorkspace(script, args = [], options) {
    const filter = options.incremental ? ["--filter", "...[HEAD~1]"] : [];
    return ["pnpm", ["-r", `--workspace-concurrency=${options.jobs}`, ...filter, "exec", "run-or-exec", script, ...args]];
  }
  install() {
    return ["pnpm", ["install"]];
  }
  listInstalledVersions() {
    const result = spawnPackageManagerSync("pnpm", ["list", "--recursive", "--json", "--depth=0"], {
      context: { operation: "Inspect installed pnpm package versions" },
      encoding: "utf8",
      maxBuffer: 64 * 1024 * 1024,
      shell: true
    });
    const versions = /* @__PURE__ */ new Map();
    if (result.error) return versions;
    try {
      const parsed = JSON.parse(result.stdout);
      if (Array.isArray(parsed)) {
        for (const workspace of parsed) {
          for (const depField of ["dependencies", "devDependencies", "optionalDependencies"]) {
            const deps = workspace[depField];
            if (!deps) continue;
            for (const [name, info] of Object.entries(deps)) {
              if (info.version && !versions.has(name)) {
                versions.set(name, info.version);
              }
            }
          }
        }
      }
    } catch {
    }
    return versions;
  }
  listWorkspaces() {
    const result = spawnPackageManagerSync("pnpm", ["list", "--recursive", "--json", "--depth=0"], {
      context: { operation: "List pnpm workspaces" },
      encoding: "utf8",
      maxBuffer: 64 * 1024 * 1024,
      shell: true
    });
    if (result.error) {
      throw result.error;
    }
    try {
      const parsed = JSON.parse(result.stdout);
      if (Array.isArray(parsed)) {
        const cwd = process.env.INIT_CWD ?? process.cwd();
        return parsed.map((pkg) => {
          const rel = PATH2.relative(cwd, pkg.path);
          return {
            location: rel === "" ? "." : rel,
            name: pkg.name
          };
        });
      }
    } catch {
    }
    return [];
  }
  outdated() {
    return ["pnpm", ["outdated", "-r"]];
  }
  publish(options = {}) {
    const reporterFlags = options.verbose ? ["--loglevel=debug"] : ["--reporter=append-only"];
    const env = { NODE_OPTIONS: "--max-old-space-size=8192" };
    const baseFlags = ["--no-git-checks", ...reporterFlags];
    const chunkSize = options.chunkSize ?? 0;
    if (chunkSize <= 0) {
      return [["pnpm", ["publish", "-r", ...baseFlags], { env }]];
    }
    const publishable = this.listWorkspaces().filter((ws) => isPublishableWorkspace(ws.location));
    if (publishable.length === 0) {
      return [["pnpm", ["publish", "-r", ...baseFlags], { env }]];
    }
    const chunks = [];
    for (let i = 0; i < publishable.length; i += chunkSize) {
      chunks.push(publishable.slice(i, i + chunkSize));
    }
    return chunks.map((chunk) => [
      "pnpm",
      [
        "publish",
        ...chunk.flatMap((ws) => ["--filter", ws.name]),
        ...baseFlags
      ],
      { env }
    ]);
  }
  runInWorkspace(pkg, script, args = []) {
    return ["pnpm", ["--filter", pkg, "exec", "run-or-exec", script, ...args]];
  }
  runXy(args) {
    return ["pnpm", ["xy", ...args]];
  }
  versionApply() {
    return ["pnpm", ["install", "--lockfile-only"]];
  }
  versionBump(type) {
    return [
      ["pnpm", ["-r", "exec", "--", "pnpm", "version", type, "--no-git-tag-version"]]
    ];
  }
};

// src/lib/yarn/workspace/yarnWorkspaces.ts
var yarnWorkspaces = () => {
  const result = spawnPackageManagerSync("yarn", ["workspaces", "list", "--json", "--recursive"], {
    context: { operation: "List Yarn workspaces" },
    encoding: "utf8"
  });
  if (result.error) {
    throw result.error;
  }
  return result.stdout.toString().split("\n").slice(0, -1).map((item) => {
    return JSON.parse(item);
  });
};

// src/lib/yarn/workspace/yarnWorkspace.ts
var yarnWorkspace = (pkg) => {
  const workspace = yarnWorkspaces().find(({ name }) => name === pkg);
  if (!workspace) throw new Error(`Workspace ${pkg} not found`);
  return workspace;
};

// src/pm/yarnPackageManager.ts
function parseLocatorName(value) {
  const atIndex = value.startsWith("@") ? value.indexOf("@", 1) : value.indexOf("@");
  if (atIndex <= 0) return void 0;
  return value.slice(0, atIndex);
}
var YarnPackageManager = class {
  command = "yarn";
  lockfile = "yarn.lock";
  name = "yarn";
  dedupe() {
    return ["yarn", ["dedupe"]];
  }
  findWorkspace(name) {
    try {
      return yarnWorkspace(name);
    } catch {
      return void 0;
    }
  }
  foreachWorkspace(script, args = [], options) {
    const verboseOptions = options.verbose ? ["--verbose"] : ["--no-verbose"];
    const incrementalOptions = options.incremental ? ["--since", "-Ap", "--topological-dev"] : ["--parallel", "-Ap", "--topological-dev"];
    return ["yarn", [
      "workspaces",
      "foreach",
      ...incrementalOptions,
      "-j",
      `${options.jobs}`,
      ...verboseOptions,
      "run",
      script,
      ...args
    ]];
  }
  install() {
    return ["yarn", ["install"]];
  }
  listInstalledVersions() {
    const result = spawnPackageManagerSync("yarn", ["info", "--all", "--json"], {
      context: { operation: "Inspect installed yarn package versions" },
      encoding: "utf8",
      maxBuffer: 64 * 1024 * 1024
    });
    const versions = /* @__PURE__ */ new Map();
    if (result.error) return versions;
    try {
      const lines = result.stdout.split("\n").filter(Boolean);
      for (const line of lines) {
        const entry = JSON.parse(line);
        const name = parseLocatorName(entry.value);
        const version = entry.children?.Version;
        if (name && version && !versions.has(name)) {
          versions.set(name, version);
        }
      }
    } catch {
    }
    return versions;
  }
  listWorkspaces() {
    return yarnWorkspaces();
  }
  outdated() {
    return ["yarn", ["outdated"]];
  }
  publish(_options = {}) {
    return [["npm", ["publish", "--workspaces"]]];
  }
  runInWorkspace(pkg, script, args = []) {
    return ["yarn", ["workspace", pkg, "run", script, ...args]];
  }
  runXy(args) {
    return ["yarn", ["xy", ...args]];
  }
  versionApply() {
    return ["yarn", ["version", "apply", "--all"]];
  }
  versionBump(type) {
    if (type === "prerelease") {
      return [
        ["yarn", "workspaces foreach --all --no-private version patch --deferred --prerelease"]
      ];
    }
    return [
      ["yarn", `workspaces foreach --all --no-private version ${type} --deferred`]
    ];
  }
};
export {
  BunPackageManager,
  NpmPackageManager,
  PnpmPackageManager,
  YarnPackageManager,
  detectPackageManager,
  detectPackageManagerFromPackageJson,
  detectReact,
  getPackageManager,
  listDeclaredWorkspaces,
  readPnpmWorkspacePatterns,
  readRootPackageJson,
  readWorkspacePatterns,
  readWorkspacePatternsFromPackageJson,
  registerPackageManager
};
//# sourceMappingURL=index.mjs.map