// src/lib/packageManagerRuntime.ts
import fs from "node:fs";
import chalk 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
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"
};
var SUPPORTED_PLATFORMS = ["darwin", "linux", "win32"];
function currentPlatform() {
  return SUPPORTED_PLATFORMS.find((platform) => platform === process.platform) ?? "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/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/pm/resolveWorkspace.ts
import chalk2 from "chalk";
function shortName(name) {
  const slash = name.lastIndexOf("/");
  return slash === -1 ? name : name.slice(slash + 1);
}
function resolveWorkspace(workspaces, query) {
  const exact = workspaces.find((ws) => ws.name === query);
  if (exact) return exact;
  const byLocation = workspaces.find((ws) => ws.location === query);
  if (byLocation) return byLocation;
  const byShort = workspaces.filter((ws) => shortName(ws.name) === query);
  if (byShort.length === 1) return byShort[0];
  if (byShort.length > 1) {
    console.error(chalk2.red(`Ambiguous workspace "${query}"; matches: ${byShort.map((ws) => ws.name).join(", ")}`));
    return void 0;
  }
  return void 0;
}

// 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) {
    return resolveWorkspace(yarnWorkspaces(), name);
  }
  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",
      String(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 = []) {
    const resolved = this.findWorkspace(pkg)?.name ?? pkg;
    return this.runInWorkspaceByName(resolved, script, args);
  }
  runInWorkspaceByName(pkg, script, args = []) {
    const resolved = pkg;
    return ["yarn", ["workspace", resolved, "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 {
  YarnPackageManager
};
//# sourceMappingURL=yarnPackageManager.mjs.map
