import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);

// src/adapters/claude/conversion/tool-use-to-acp.ts
import fs from "fs";
import path from "path";

// src/utils/acp-content.ts
function text(value) {
  return { type: "text", text: value };
}
function image(data, mimeType, uri) {
  return { type: "image", data, mimeType, uri };
}
function resourceLink(uri, name, options) {
  return {
    type: "resource_link",
    uri,
    name,
    ...options
  };
}
var ToolContentBuilder = class {
  items = [];
  text(value) {
    this.items.push({ type: "content", content: text(value) });
    return this;
  }
  image(data, mimeType, uri) {
    this.items.push({ type: "content", content: image(data, mimeType, uri) });
    return this;
  }
  diff(path2, oldText, newText) {
    this.items.push({ type: "diff", path: path2, oldText, newText });
    return this;
  }
  build() {
    return this.items;
  }
};
function toolContent() {
  return new ToolContentBuilder();
}

// src/adapters/claude/mcp/tool-metadata.ts
var mcpToolMetadataCache = /* @__PURE__ */ new Map();
function getMcpToolMetadata(toolName) {
  return mcpToolMetadataCache.get(toolName);
}

// src/adapters/claude/conversion/tool-use-to-acp.ts
var SYSTEM_REMINDER_REGEX = /\s*<system-reminder>[\s\S]*?<\/system-reminder>/g;
function stripSystemReminders(value) {
  return value.replace(SYSTEM_REMINDER_REGEX, "");
}
function toDisplayPath(filePath, cwd) {
  if (!cwd) return filePath;
  const resolvedCwd = path.resolve(cwd);
  const resolvedFile = path.resolve(filePath);
  if (resolvedFile.startsWith(resolvedCwd + path.sep) || resolvedFile === resolvedCwd) {
    return path.relative(resolvedCwd, resolvedFile);
  }
  return filePath;
}
function toolInfoFromToolUse(toolUse, options) {
  const name = toolUse.name;
  const input = toolUse.input;
  switch (name) {
    case "Task":
    case "Agent":
      return {
        title: input?.description ? String(input.description) : name,
        kind: "think",
        content: input?.prompt ? toolContent().text(String(input.prompt)).build() : []
      };
    case "NotebookRead":
      return {
        title: input?.notebook_path ? `Read Notebook ${String(input.notebook_path)}` : "Read Notebook",
        kind: "read",
        content: [],
        locations: input?.notebook_path ? [{ path: String(input.notebook_path) }] : []
      };
    case "NotebookEdit":
      return {
        title: input?.notebook_path ? `Edit Notebook ${String(input.notebook_path)}` : "Edit Notebook",
        kind: "edit",
        content: input?.new_source ? toolContent().text(String(input.new_source)).build() : [],
        locations: input?.notebook_path ? [{ path: String(input.notebook_path) }] : []
      };
    case "Bash":
      if (options?.supportsTerminalOutput && options?.toolUseId) {
        return {
          title: input?.description ? String(input.description) : "Execute command",
          kind: "execute",
          content: [{ type: "terminal", terminalId: options.toolUseId }]
        };
      }
      return {
        title: input?.description ? String(input.description) : "Execute command",
        kind: "execute",
        content: input?.command ? toolContent().text(String(input.command)).build() : []
      };
    case "BashOutput":
      return {
        title: "Tail Logs",
        kind: "execute",
        content: []
      };
    case "KillShell":
      return {
        title: "Kill Process",
        kind: "execute",
        content: []
      };
    case "Read": {
      let limit = "";
      const inputLimit = input?.limit;
      const inputOffset = input?.offset ?? 1;
      if (inputLimit) {
        limit = ` (${inputOffset} - ${inputOffset + inputLimit - 1})`;
      } else if (inputOffset > 1) {
        limit = ` (from line ${inputOffset})`;
      }
      const displayPath = input?.file_path ? toDisplayPath(String(input.file_path), options?.cwd) : "File";
      return {
        title: `Read ${displayPath}${limit}`,
        kind: "read",
        locations: input?.file_path ? [
          {
            path: String(input.file_path),
            line: inputOffset
          }
        ] : [],
        content: []
      };
    }
    case "LS":
      return {
        title: `List the ${input?.path ? `\`${String(input.path)}\`` : "current"} directory's contents`,
        kind: "search",
        content: [],
        locations: []
      };
    case "Edit": {
      const filePath = input?.file_path ? String(input.file_path) : void 0;
      const displayPath = filePath ? toDisplayPath(filePath, options?.cwd) : void 0;
      let oldText = input?.old_string ? String(input.old_string) : null;
      let newText = input?.new_string ? String(input.new_string) : "";
      if (filePath && oldText !== null) {
        const fileContent = resolveFileContent(
          filePath,
          oldText,
          options?.cachedFileContent
        );
        if (fileContent) {
          const newContent = input?.replace_all ? fileContent.replaceAll(oldText, newText) : fileContent.replace(oldText, newText);
          oldText = fileContent;
          newText = newContent;
        }
      }
      return {
        title: displayPath ? `Edit \`${displayPath}\`` : "Edit",
        kind: "edit",
        content: input && filePath ? [
          {
            type: "diff",
            path: filePath,
            oldText,
            newText
          }
        ] : [],
        locations: filePath ? [{ path: filePath }] : []
      };
    }
    case "Write": {
      let contentResult = [];
      const writeFilePath = input?.file_path ? String(input.file_path) : void 0;
      const writeDisplayPath = writeFilePath ? toDisplayPath(writeFilePath, options?.cwd) : void 0;
      const contentStr = input?.content ? String(input.content) : void 0;
      if (writeFilePath) {
        let oldContent = null;
        if (options?.cachedFileContent && writeFilePath in options.cachedFileContent) {
          oldContent = options.cachedFileContent[writeFilePath];
        } else {
          try {
            oldContent = fs.readFileSync(writeFilePath, "utf-8");
          } catch {
          }
        }
        contentResult = toolContent().diff(writeFilePath, oldContent, contentStr ?? "").build();
      } else if (contentStr) {
        contentResult = toolContent().text(contentStr).build();
      }
      return {
        title: writeDisplayPath ? `Write ${writeDisplayPath}` : "Write",
        kind: "edit",
        content: contentResult,
        locations: writeFilePath ? [{ path: writeFilePath }] : []
      };
    }
    case "Glob": {
      let label = "Find";
      const pathStr = input?.path ? String(input.path) : void 0;
      if (pathStr) {
        label += ` "${pathStr}"`;
      }
      if (input?.pattern) {
        label += ` "${String(input.pattern)}"`;
      }
      return {
        title: label,
        kind: "search",
        content: [],
        locations: pathStr ? [{ path: pathStr }] : []
      };
    }
    case "Grep": {
      let label = "grep";
      if (input?.["-i"]) {
        label += " -i";
      }
      if (input?.["-n"]) {
        label += " -n";
      }
      if (input?.["-A"] !== void 0) {
        label += ` -A ${input["-A"]}`;
      }
      if (input?.["-B"] !== void 0) {
        label += ` -B ${input["-B"]}`;
      }
      if (input?.["-C"] !== void 0) {
        label += ` -C ${input["-C"]}`;
      }
      if (input?.output_mode) {
        switch (input.output_mode) {
          case "files_with_matches":
            label += " -l";
            break;
          case "count":
            label += " -c";
            break;
          default:
            break;
        }
      }
      if (input?.head_limit !== void 0) {
        label += ` | head -${input.head_limit}`;
      }
      if (input?.glob) {
        label += ` --include="${String(input.glob)}"`;
      }
      if (input?.type) {
        label += ` --type=${String(input.type)}`;
      }
      if (input?.multiline) {
        label += " -P";
      }
      if (input?.pattern) {
        label += ` "${String(input.pattern)}"`;
      }
      if (input?.path) {
        label += ` ${String(input.path)}`;
      }
      return {
        title: label,
        kind: "search",
        content: []
      };
    }
    case "WebFetch":
      return {
        title: "Fetch",
        kind: "fetch",
        content: input?.url ? [
          {
            type: "content",
            content: resourceLink(String(input.url), String(input.url), {
              description: input?.prompt ? String(input.prompt) : void 0
            })
          }
        ] : []
      };
    case "WebSearch": {
      let label = `"${input?.query ? String(input.query) : ""}"`;
      const allowedDomains = input?.allowed_domains;
      const blockedDomains = input?.blocked_domains;
      if (allowedDomains && allowedDomains.length > 0) {
        label += ` (allowed: ${allowedDomains.join(", ")})`;
      }
      if (blockedDomains && blockedDomains.length > 0) {
        label += ` (blocked: ${blockedDomains.join(", ")})`;
      }
      return {
        title: label,
        kind: "fetch",
        content: []
      };
    }
    case "TaskCreate": {
      const subject = typeof input?.subject === "string" ? input.subject : void 0;
      return {
        title: subject ? `Create task: ${subject}` : "Create task",
        kind: "think",
        content: []
      };
    }
    case "TaskUpdate": {
      const subject = typeof input?.subject === "string" ? input.subject : void 0;
      return {
        title: subject ? `Update task: ${subject}` : "Update task",
        kind: "think",
        content: []
      };
    }
    case "TaskList":
      return {
        title: "List tasks",
        kind: "think",
        content: []
      };
    case "TaskGet":
      return {
        title: "Get task",
        kind: "think",
        content: []
      };
    case "Skill": {
      const skill = typeof input?.skill === "string" ? input.skill : void 0;
      const skillArgs = typeof input?.args === "string" ? input.args : void 0;
      return {
        title: skill ? `Skill: ${skill}` : "Skill",
        kind: "other",
        content: skillArgs ? toolContent().text(skillArgs).build() : []
      };
    }
    case "ExitPlanMode":
      return {
        title: "Ready to code?",
        kind: "switch_mode",
        content: input?.plan ? toolContent().text(String(input.plan)).build() : []
      };
    case "AskUserQuestion": {
      const questions = input?.questions;
      return {
        title: questions?.[0]?.question || "Question",
        kind: "other",
        content: questions ? toolContent().text(JSON.stringify(questions, null, 2)).build() : []
      };
    }
    case "Other": {
      let output;
      try {
        output = JSON.stringify(input, null, 2);
      } catch {
        output = typeof input === "string" ? input : "{}";
      }
      return {
        title: name || "Unknown Tool",
        kind: "other",
        content: toolContent().text(`\`\`\`json
${output}\`\`\``).build()
      };
    }
    default: {
      if (name?.startsWith("mcp__")) {
        return mcpToolInfo(name, input);
      }
      return {
        title: name || "Unknown Tool",
        kind: "other",
        content: []
      };
    }
  }
}
function mcpToolInfo(name, _input) {
  const metadata = getMcpToolMetadata(name);
  const title = metadata?.name ?? (name.split("__").slice(2).join("__") || name);
  return {
    title,
    kind: "other",
    content: []
  };
}
function toolUpdateFromEditToolResponse(toolResponse) {
  if (!toolResponse || typeof toolResponse !== "object") return null;
  const response = toolResponse;
  const patches = response.structuredPatch;
  if (!Array.isArray(patches) || patches.length === 0) return null;
  const content = [];
  const locations = [];
  for (const patch of patches) {
    if (!patch.hunks || patch.hunks.length === 0) continue;
    const filePath = patch.newFileName || patch.oldFileName;
    const oldLines = [];
    const newLines = [];
    for (const hunk of patch.hunks) {
      for (const line of hunk.lines) {
        if (line.startsWith("-")) {
          oldLines.push(line.slice(1));
        } else if (line.startsWith("+")) {
          newLines.push(line.slice(1));
        } else if (line.startsWith(" ")) {
          oldLines.push(line.slice(1));
          newLines.push(line.slice(1));
        }
      }
    }
    content.push({
      type: "diff",
      path: filePath,
      oldText: oldLines.join("\n"),
      newText: newLines.join("\n")
    });
    const firstHunk = patch.hunks[0];
    locations.push({
      path: filePath,
      line: firstHunk.newStart
    });
  }
  if (content.length === 0) return null;
  return { content, locations };
}
function toolUpdateFromToolResult(toolResult, toolUse, options) {
  if ("is_error" in toolResult && toolResult.is_error && toolResult.content && toolResult.content.length > 0 && // Bash errors keep rendering through the terminal-output channel below.
  !(toolUse?.name === "Bash" && options?.supportsTerminalOutput)) {
    return toAcpContentUpdate(toolResult.content, true);
  }
  switch (toolUse?.name) {
    case "Read": {
      const cache = options?.enrichedReadCache;
      const enriched = cache && options?.toolUseId ? cache.get(options.toolUseId) : void 0;
      if (enriched !== void 0 && cache && options?.toolUseId) {
        cache.delete(options.toolUseId);
        return {
          content: [
            {
              type: "content",
              content: text(markdownEscape(enriched))
            }
          ]
        };
      }
      if (Array.isArray(toolResult.content) && toolResult.content.length > 0) {
        return {
          content: toolResult.content.map((item) => {
            const itemObj = item;
            if (itemObj.type === "text") {
              return {
                type: "content",
                content: text(
                  markdownEscape(stripSystemReminders(itemObj.text ?? ""))
                )
              };
            }
            if (itemObj.type === "image" && itemObj.source) {
              return {
                type: "content",
                content: {
                  type: "image",
                  data: itemObj.source.data ?? "",
                  mimeType: itemObj.source.media_type ?? "image/png"
                }
              };
            }
            return {
              type: "content",
              content: item
            };
          })
        };
      } else if (typeof toolResult.content === "string" && toolResult.content.length > 0) {
        return {
          content: toolContent().text(markdownEscape(stripSystemReminders(toolResult.content))).build()
        };
      }
      return {};
    }
    case "Bash": {
      const result = toolResult.content;
      const terminalId = "tool_use_id" in toolResult ? String(toolResult.tool_use_id) : "";
      const isError = "is_error" in toolResult && toolResult.is_error;
      let output = "";
      let exitCode = isError ? 1 : 0;
      if (result && typeof result === "object" && "type" in result && result.type === "bash_code_execution_result") {
        const bashResult = result;
        output = [bashResult.stdout, bashResult.stderr].filter(Boolean).join("\n");
        exitCode = bashResult.return_code;
      } else if (typeof result === "string") {
        output = result;
      } else if (Array.isArray(result) && result.length > 0) {
        const textOnly = result.every(
          (c) => c && typeof c === "object" && typeof c.text === "string"
        );
        if (textOnly) {
          output = result.map((c) => c.text ?? "").join("\n");
        } else {
          return toAcpContentUpdate(result, isError === true);
        }
      }
      if (options?.supportsTerminalOutput) {
        return {
          content: [{ type: "terminal", terminalId }],
          _meta: {
            terminal_info: {
              terminal_id: terminalId
            },
            terminal_output: {
              terminal_id: terminalId,
              data: output
            },
            terminal_exit: {
              terminal_id: terminalId,
              exit_code: exitCode,
              signal: null
            }
          }
        };
      }
      if (output.trim()) {
        return {
          content: toolContent().text(`\`\`\`console
${output.trimEnd()}
\`\`\``).build()
        };
      }
      return {};
    }
    case "Edit":
    case "Write":
      return {};
    case "ExitPlanMode": {
      return { title: "Exited Plan Mode" };
    }
    case "AskUserQuestion": {
      const content = toolResult.content;
      if (Array.isArray(content) && content.length > 0) {
        const firstItem = content[0];
        if (typeof firstItem === "object" && firstItem !== null && "text" in firstItem) {
          return {
            title: "Answer received",
            content: toolContent().text(String(firstItem.text)).build()
          };
        }
      }
      return { title: "Question answered" };
    }
    case "WebFetch": {
      const input = toolUse?.input;
      const url = input?.url ? String(input.url) : "";
      const prompt = input?.prompt ? String(input.prompt) : void 0;
      const resultContent = toAcpContentUpdate(
        toolResult.content,
        "is_error" in toolResult ? toolResult.is_error : false
      );
      const content = [];
      if (url) {
        content.push({
          type: "content",
          content: resourceLink(url, url, {
            description: prompt
          })
        });
      }
      if (resultContent.content) {
        content.push(...resultContent.content);
      }
      return { content };
    }
    default: {
      return toAcpContentUpdate(
        toolResult.content,
        "is_error" in toolResult ? toolResult.is_error : false
      );
    }
  }
}
function itemToText(item) {
  if (!item || typeof item !== "object") return null;
  const obj = item;
  if (obj.type === "text" && typeof obj.text === "string") {
    return stripSystemReminders(obj.text);
  }
  try {
    return JSON.stringify(obj, null, 2);
  } catch {
    return null;
  }
}
function toAcpContentUpdate(content, isError = false) {
  if (Array.isArray(content) && content.length > 0) {
    const texts = [];
    for (const item of content) {
      const t = itemToText(item);
      if (t) texts.push(t);
    }
    if (texts.length > 0) {
      const combined = texts.join("\n");
      return {
        content: toolContent().text(isError ? `\`\`\`
${combined}
\`\`\`` : combined).build()
      };
    }
  } else if (typeof content === "string" && content.length > 0) {
    return {
      content: toolContent().text(isError ? `\`\`\`
${content}
\`\`\`` : content).build()
    };
  } else if (content && typeof content === "object") {
    try {
      const json = JSON.stringify(content, null, 2);
      if (json && json !== "{}") {
        return {
          content: toolContent().text(json).build()
        };
      }
    } catch {
    }
  }
  return {};
}
function resolveFileContent(filePath, oldText, cachedFileContent) {
  if (cachedFileContent && filePath in cachedFileContent) {
    const cached = cachedFileContent[filePath];
    if (cached.includes(oldText)) {
      return cached;
    }
  }
  try {
    const content = fs.readFileSync(filePath, "utf-8");
    if (content.includes(oldText)) {
      return content;
    }
  } catch {
    return null;
  }
  return null;
}
function markdownEscape(text2) {
  let escapedText = "```";
  for (const [m] of text2.matchAll(/^```+/gm)) {
    while (m.length >= escapedText.length) {
      escapedText += "`";
    }
  }
  return `${escapedText}
${text2}${text2.endsWith("\n") ? "" : "\n"}${escapedText}`;
}
export {
  toDisplayPath,
  toolInfoFromToolUse,
  toolUpdateFromEditToolResponse,
  toolUpdateFromToolResult
};
//# sourceMappingURL=tool-use-to-acp.js.map