#!/usr/bin/env node
import {
  getErrorMessage,
  warn
} from "./chunk-C4QI54PN.js";
import {
  init_esm_shims
} from "./chunk-DHET7RCE.js";

// src/cli/utils/exec.ts
init_esm_shims();
import { spawn } from "child_process";
var MAX_PLUGIN_PATH_LENGTH = 1024;
var MAX_PLUGIN_NAME_LENGTH = 256;
var MAX_MARKETPLACE_SOURCE_LENGTH = 1024;
var SAFE_NAME_PATTERN = /^[a-zA-Z0-9._@/-]+$/;
var SAFE_PLUGIN_PATH_PATTERN = /^[a-zA-Z0-9._@/:~-]+$/;
var CONTROL_CHAR_PATTERN = /[\x00-\x08\x0E-\x1F\x7F]/u;
function validatePluginPath(pluginPath) {
  if (!pluginPath || pluginPath.trim().length === 0) {
    throw new Error("Plugin path must not be empty.");
  }
  if (pluginPath.length > MAX_PLUGIN_PATH_LENGTH) {
    throw new Error(
      `Plugin path is too long (${pluginPath.length} characters, max ${MAX_PLUGIN_PATH_LENGTH}).`
    );
  }
  if (CONTROL_CHAR_PATTERN.test(pluginPath)) {
    throw new Error("Plugin path contains invalid control characters.");
  }
  if (!SAFE_PLUGIN_PATH_PATTERN.test(pluginPath)) {
    throw new Error(
      `Plugin path contains invalid characters: "${pluginPath}"
Plugin paths may only contain alphanumeric characters, dashes, underscores, dots, slashes, @, and colons.`
    );
  }
}
function validateMarketplaceSource(source) {
  if (!source || source.trim().length === 0) {
    throw new Error("Marketplace source must not be empty.");
  }
  if (source.length > MAX_MARKETPLACE_SOURCE_LENGTH) {
    throw new Error(
      `Marketplace source is too long (${source.length} characters, max ${MAX_MARKETPLACE_SOURCE_LENGTH}).`
    );
  }
  if (CONTROL_CHAR_PATTERN.test(source)) {
    throw new Error("Marketplace source contains invalid control characters.");
  }
  if (!SAFE_PLUGIN_PATH_PATTERN.test(source)) {
    throw new Error(
      `Marketplace source contains invalid characters: "${source}"
Source may only contain alphanumeric characters, dashes, underscores, dots, slashes, @, and colons.`
    );
  }
}
function validatePluginName(pluginName) {
  if (!pluginName || pluginName.trim().length === 0) {
    throw new Error("Plugin name must not be empty.");
  }
  if (pluginName.length > MAX_PLUGIN_NAME_LENGTH) {
    throw new Error(
      `Plugin name is too long (${pluginName.length} characters, max ${MAX_PLUGIN_NAME_LENGTH}).`
    );
  }
  if (CONTROL_CHAR_PATTERN.test(pluginName)) {
    throw new Error("Plugin name contains invalid control characters.");
  }
  if (!SAFE_NAME_PATTERN.test(pluginName)) {
    throw new Error(
      `Plugin name contains invalid characters: "${pluginName}"
Names may only contain alphanumeric characters, dashes, underscores, dots, @, and slashes.`
    );
  }
}
async function execCommand(command, args, options) {
  return new Promise((resolve, reject) => {
    const proc = spawn(command, args, {
      cwd: options?.cwd,
      env: { ...process.env, ...options?.env },
      stdio: ["ignore", "pipe", "pipe"]
    });
    let stdout = "";
    let stderr = "";
    proc.stdout.on("data", (data) => {
      stdout += data.toString();
    });
    proc.stderr.on("data", (data) => {
      stderr += data.toString();
    });
    proc.on("close", (code) => {
      resolve({
        stdout,
        stderr,
        exitCode: code ?? 1
      });
    });
    proc.on("error", (err) => {
      reject(err);
    });
  });
}
async function claudePluginInstall(pluginPath, scope, projectDir) {
  validatePluginPath(pluginPath);
  const args = ["plugin", "install", pluginPath, "--scope", scope];
  const result = await execCommand("claude", args, { cwd: projectDir });
  if (result.exitCode !== 0) {
    const errorMessage = result.stderr || result.stdout || "Unknown error";
    throw new Error(`Plugin installation failed: ${errorMessage.trim()}`);
  }
}
async function isClaudeCLIAvailable() {
  try {
    const result = await execCommand("claude", ["--version"], {});
    return result.exitCode === 0;
  } catch {
    return false;
  }
}
async function claudePluginMarketplaceList() {
  try {
    const result = await execCommand("claude", ["plugin", "marketplace", "list", "--json"], {});
    if (result.exitCode !== 0) {
      return [];
    }
    let parsed;
    try {
      parsed = JSON.parse(result.stdout);
    } catch {
      warn("Failed to parse marketplace list output as JSON");
      return [];
    }
    if (!Array.isArray(parsed)) {
      warn("Unexpected marketplace list format \u2014 expected an array");
      return [];
    }
    return parsed;
  } catch {
    return [];
  }
}
async function claudePluginMarketplaceExists(name) {
  const marketplaces = await claudePluginMarketplaceList();
  return marketplaces.some((m) => m.name === name);
}
async function claudePluginMarketplaceAdd(source) {
  validateMarketplaceSource(source);
  const args = ["plugin", "marketplace", "add", source];
  let result;
  try {
    result = await execCommand("claude", args, {});
  } catch (err) {
    throw new Error(`Failed to add marketplace: ${getErrorMessage(err)}`);
  }
  if (result.exitCode !== 0) {
    const errorMessage = result.stderr || result.stdout || "Unknown error";
    if (errorMessage.includes("already installed")) {
      return;
    }
    throw new Error(`Failed to add marketplace: ${errorMessage.trim()}`);
  }
}
async function claudePluginUninstall(pluginName, scope, projectDir) {
  validatePluginName(pluginName);
  const args = ["plugin", "uninstall", pluginName, "--scope", scope];
  const result = await execCommand("claude", args, { cwd: projectDir });
  if (result.exitCode !== 0) {
    const errorMessage = result.stderr || result.stdout || "Unknown error";
    if (errorMessage.includes("not installed") || errorMessage.includes("not found")) {
      return;
    }
    throw new Error(`Plugin uninstall failed: ${errorMessage.trim()}`);
  }
}

export {
  claudePluginInstall,
  isClaudeCLIAvailable,
  claudePluginMarketplaceExists,
  claudePluginMarketplaceAdd,
  claudePluginUninstall
};
//# sourceMappingURL=chunk-CJFWO46A.js.map