import { existsSync, mkdirSync, writeFileSync, rmSync, statSync } from "node:fs";
import { dirname, join } from "node:path";
import { homedir } from "node:os";
import { execSync } from "node:child_process";
import { mergeBlock, removeBlock, readAsset, readSkillDir, mergeMcpJson } from "./utils.js";
function claudeDir() {
  return join(homedir(), ".claude");
}
function detect() {
  try {
    execSync("which claude", { stdio: ["pipe", "pipe", "pipe"] });
    return true;
  } catch {
    return false;
  }
}
function buildMcpArgs(cmd) {
  return ["mcp", "add", "wigolo", "--scope", "user", "--", cmd.command, ...cmd.args];
}
function isClaudeCliMissing(err) {
  if (err.code === "ENOENT") return true;
  const msg = err.message ?? "";
  return /claude: not found|claude: command not found|spawn claude ENOENT/i.test(msg);
}
function fallbackToClaudeJson(cmd) {
  const configPath = join(homedir(), ".claude.json");
  mergeMcpJson(configPath, { command: cmd.command, args: cmd.args }, ["mcpServers", "wigolo"]);
  return configPath;
}
async function installMcp(cmd) {
  const args = buildMcpArgs(cmd);
  try {
    execSync(`claude ${args.join(" ")}`, {
      stdio: ["pipe", "pipe", "pipe"],
      timeout: 15e3
    });
    return;
  } catch (err) {
    const e = err;
    const msg = e.message ?? "";
    if (msg.includes("already exists") || msg.includes("already registered")) {
      return;
    }
    if (isClaudeCliMissing(e)) {
      fallbackToClaudeJson(cmd);
      return;
    }
    throw err;
  }
}
async function installInstructions() {
  const block = readAsset("blocks/claude-code/CLAUDE.md.block");
  const target = join(claudeDir(), "CLAUDE.md");
  mergeBlock(target, block);
}
const SKILL_DIRS = [
  "wigolo",
  "wigolo-search",
  "wigolo-fetch",
  "wigolo-crawl",
  "wigolo-extract",
  "wigolo-find-similar",
  "wigolo-research",
  "wigolo-agent"
];
async function installSkills() {
  const skillsBase = join(claudeDir(), "skills");
  const plan = SKILL_DIRS.map((dirName) => ({
    dirName,
    dest: join(skillsBase, dirName),
    files: readSkillDir(dirName)
  }));
  for (const { dest } of plan) {
    if (existsSync(dest) && !statSync(dest).isDirectory()) {
      throw new Error(
        `wigolo install: ${dest} exists but is not a directory \u2014 refuse to overwrite`
      );
    }
  }
  mkdirSync(skillsBase, { recursive: true });
  const createdDirs = [];
  try {
    for (const { dest, files } of plan) {
      const dirExistedBefore = existsSync(dest);
      mkdirSync(dest, { recursive: true });
      if (!dirExistedBefore) createdDirs.push(dest);
      for (const [relPath, content] of Object.entries(files)) {
        const target = join(dest, relPath);
        mkdirSync(dirname(target), { recursive: true });
        writeFileSync(target, content, "utf-8");
      }
    }
  } catch (err) {
    for (const dir of createdDirs) {
      try {
        rmSync(dir, { recursive: true, force: true });
      } catch {
      }
    }
    throw err;
  }
}
async function installCommand() {
  const content = readAsset("blocks/claude-code/wigolo-command.md");
  const commandsDir = join(claudeDir(), "commands");
  mkdirSync(commandsDir, { recursive: true });
  writeFileSync(join(commandsDir, "wigolo.md"), content, "utf-8");
}
async function uninstall() {
  const removed = [];
  try {
    execSync("claude mcp remove wigolo --scope user", { stdio: ["pipe", "pipe", "pipe"], timeout: 1e4 });
    removed.push("MCP server (claude mcp remove)");
  } catch {
  }
  const claudeMd = join(claudeDir(), "CLAUDE.md");
  if (existsSync(claudeMd) && removeBlock(claudeMd)) {
    removed.push("~/.claude/CLAUDE.md block");
  }
  const skillsBase = join(claudeDir(), "skills");
  for (const dirName of SKILL_DIRS) {
    const skillDir = join(skillsBase, dirName);
    if (existsSync(skillDir)) {
      rmSync(skillDir, { recursive: true, force: true });
      removed.push(`~/.claude/skills/${dirName}`);
    }
  }
  const commandFile = join(claudeDir(), "commands", "wigolo.md");
  if (existsSync(commandFile)) {
    rmSync(commandFile);
    removed.push("~/.claude/commands/wigolo.md");
  }
  return { removed };
}
const claudeCodeHandler = {
  id: "claude-code",
  displayName: "Claude Code",
  supportsSkills: true,
  supportsCommands: true,
  detect,
  installMcp,
  installInstructions,
  installSkills,
  installCommand,
  uninstall
};
export {
  claudeCodeHandler
};
//# sourceMappingURL=claude-code.js.map