import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
import {
  PROMPT_PREVIEW_CHARS
} from "./chunk-WBLTISAK.js";

// src/agents/adapter.ts
import fs from "fs";
import path from "path";
function findJsonlInSubdirs(baseDir, sessionId) {
  try {
    for (const entry of fs.readdirSync(baseDir, { withFileTypes: true })) {
      if (!entry.isDirectory()) continue;
      const candidate = path.join(baseDir, entry.name, `${sessionId}.jsonl`);
      try {
        fs.accessSync(candidate);
        return candidate;
      } catch {
      }
    }
  } catch {
  }
  return null;
}
function createPerProjectAdapter(baseDir, parseTurns, name) {
  return {
    name: name ?? `custom:${path.basename(baseDir)}`,
    displayName: `Custom (${baseDir})`,
    pluginRootEnvVar: "",
    hookFields: { transcriptPath: "transcript_path", lastResponse: "last_assistant_message", sessionId: "session_id" },
    findTranscript: (sessionId) => findJsonlInSubdirs(baseDir, sessionId),
    parseTurns,
    configureVaultEnv: () => false
  };
}
var MIME_TO_EXT = {
  "image/jpeg": "jpg",
  "image/gif": "gif",
  "image/webp": "webp",
  "image/png": "png"
};
function extensionForMimeType(mimeType) {
  return MIME_TO_EXT[mimeType] ?? "png";
}
var EXT_TO_MIME = {
  ".jpg": "image/jpeg",
  ".jpeg": "image/jpeg",
  ".gif": "image/gif",
  ".webp": "image/webp",
  ".png": "image/png"
};
function mimeTypeForExtension(ext) {
  return EXT_TO_MIME[ext.toLowerCase()] ?? "image/png";
}
var IMAGE_TEXT_REF_PATTERN = /\[Image: source: [^\]]+\]\n*/g;
function parseJsonlTurns(content, opts) {
  const lines = content.split("\n").filter(Boolean);
  const turns = [];
  let current = null;
  for (const line of lines) {
    let entry;
    try {
      entry = JSON.parse(line);
    } catch {
      continue;
    }
    const role = entry[opts.roleField];
    const timestamp = opts.extractTimestamp ? entry.timestamp ?? "" : "";
    if (role === "user") {
      const msg = entry.message;
      const blocks = Array.isArray(msg?.content) ? msg.content : [];
      const hasText = blocks.some((b) => b.type === "text" && b.text?.trim());
      if (!hasText && opts.skipToolResultUsers) continue;
      if (!hasText) continue;
      if (current) turns.push(current);
      const rawPrompt = blocks.filter((b) => b.type === "text" && b.text).map((b) => b.text).join("\n");
      const promptText = (opts.stripImageTextRefs ? rawPrompt.replace(IMAGE_TEXT_REF_PATTERN, "") : rawPrompt).trim().slice(0, PROMPT_PREVIEW_CHARS);
      const images = blocks.filter((b) => b.type === "image" && b.source?.type === "base64" && b.source.data).map((b) => ({ data: b.source.data, mediaType: b.source.media_type ?? "image/png" }));
      current = { prompt: promptText, toolCount: 0, timestamp, ...images.length > 0 ? { images } : {} };
    } else if (role === "assistant" && current) {
      const msg = entry.message;
      if (Array.isArray(msg?.content)) {
        const textParts = msg.content.filter((b) => b.type === "text" && b.text).map((b) => b.text);
        const text = textParts.join("\n").trim();
        if (text) current.aiResponse = text;
        current.toolCount += msg.content.filter((b) => b.type === "tool_use").length;
      }
    }
  }
  if (current) turns.push(current);
  return turns;
}

// src/agents/claude-code.ts
import fs2 from "fs";
import path2 from "path";
import os from "os";
var TRANSCRIPT_BASE = path2.join(os.homedir(), ".claude", "projects");
var claudeCodeAdapter = {
  name: "claude-code",
  displayName: "Claude Code",
  pluginRootEnvVar: "CLAUDE_PLUGIN_ROOT",
  hookFields: {
    transcriptPath: "transcript_path",
    lastResponse: "last_assistant_message",
    sessionId: "session_id"
  },
  findTranscript: (sessionId) => findJsonlInSubdirs(TRANSCRIPT_BASE, sessionId),
  parseTurns: (content) => parseJsonlTurns(content, {
    roleField: "type",
    extractTimestamp: true,
    skipToolResultUsers: true,
    stripImageTextRefs: true
  }),
  configureVaultEnv: (projectRoot, vaultDir) => {
    const settingsDir = path2.join(projectRoot, ".claude");
    if (!fs2.existsSync(settingsDir)) return false;
    const settingsPath = path2.join(settingsDir, "settings.json");
    let settings = {};
    if (fs2.existsSync(settingsPath)) {
      try {
        settings = JSON.parse(fs2.readFileSync(settingsPath, "utf-8"));
      } catch {
      }
    }
    const env = settings.env ?? {};
    env.MYCO_VAULT_DIR = vaultDir;
    settings.env = env;
    fs2.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
    return true;
  }
};

// src/agents/cursor.ts
import fs3 from "fs";
import path3 from "path";
import os2 from "os";
var USER_MARKER = "\nuser:\n";
var ASSISTANT_MARKER = "\nassistant:\n";
var TOOL_CALL_MARKER = "[Tool call]";
var TOOL_RESULT_MARKER = "[Tool result]";
var THINKING_MARKER = "[Thinking]";
function getCursorProjectsBase() {
  return path3.join(os2.homedir(), ".cursor", "projects");
}
var CURSOR_PROJECTS = getCursorProjectsBase();
var cursorAdapter = {
  name: "cursor",
  displayName: "Cursor",
  pluginRootEnvVar: "CURSOR_PLUGIN_ROOT",
  hookFields: {
    transcriptPath: "transcript_path",
    lastResponse: "last_assistant_message",
    sessionId: "conversation_id"
  },
  findTranscript(sessionId) {
    try {
      for (const project of fs3.readdirSync(CURSOR_PROJECTS, { withFileTypes: true })) {
        if (!project.isDirectory()) continue;
        const transcriptsDir = path3.join(CURSOR_PROJECTS, project.name, "agent-transcripts");
        for (const candidate of [
          path3.join(transcriptsDir, `${sessionId}.txt`),
          path3.join(transcriptsDir, sessionId, `${sessionId}.jsonl`)
        ]) {
          try {
            fs3.accessSync(candidate);
            return candidate;
          } catch {
          }
        }
      }
    } catch {
    }
    return null;
  },
  parseTurns(content) {
    const trimmed = content.trimStart();
    if (trimmed.startsWith("{")) {
      return parseCursorJsonl(content);
    }
    return parseCursorText(content);
  },
  configureVaultEnv(projectRoot, vaultDir) {
    const mcpPath = path3.join(projectRoot, ".cursor", "mcp.json");
    if (!fs3.existsSync(mcpPath)) return false;
    try {
      const config = JSON.parse(fs3.readFileSync(mcpPath, "utf-8"));
      if (config.mcpServers?.myco) {
        config.mcpServers.myco.env = { ...config.mcpServers.myco.env, MYCO_VAULT_DIR: vaultDir };
        fs3.writeFileSync(mcpPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
        return true;
      }
    } catch {
    }
    return false;
  }
};
function parseCursorJsonl(content) {
  return parseJsonlTurns(content, {
    roleField: "role",
    extractTimestamp: false,
    skipToolResultUsers: false,
    stripImageTextRefs: false
  });
}
function parseCursorText(content) {
  const turns = [];
  const sections = ("\n" + content).split(USER_MARKER).slice(1);
  for (const section of sections) {
    let promptText = "";
    const queryMatch = section.match(/<user_query>\s*([\s\S]*?)\s*<\/user_query>/);
    if (queryMatch) {
      promptText = queryMatch[1].trim().slice(0, PROMPT_PREVIEW_CHARS);
    } else {
      const beforeAssistant = section.split(ASSISTANT_MARKER)[0];
      promptText = beforeAssistant.replace(/<[^>]+>[\s\S]*?<\/[^>]+>/g, "").trim().slice(0, PROMPT_PREVIEW_CHARS);
    }
    const images = [];
    const imageFilesMatch = section.match(/<image_files>([\s\S]*?)<\/image_files>/);
    if (imageFilesMatch) {
      const imageBlock = imageFilesMatch[1];
      const pathMatches = imageBlock.matchAll(/^\d+\.\s+(.+\.(?:png|jpg|jpeg|gif|webp))\s*$/gmi);
      for (const match of pathMatches) {
        const imagePath = match[1].trim();
        try {
          const data = fs3.readFileSync(imagePath).toString("base64");
          const mediaType = mimeTypeForExtension(path3.extname(imagePath));
          images.push({ data, mediaType });
        } catch {
        }
      }
    }
    const toolCallCount = section.split(TOOL_CALL_MARKER).length - 1;
    let aiResponse;
    const assistantBlocks = section.split(ASSISTANT_MARKER).slice(1);
    for (let j = assistantBlocks.length - 1; j >= 0; j--) {
      const lines = assistantBlocks[j].split("\n");
      const textLines = [];
      let skip = false;
      for (const line of lines) {
        if (line.startsWith(TOOL_CALL_MARKER) || line.startsWith(TOOL_RESULT_MARKER) || line.startsWith(THINKING_MARKER)) {
          skip = true;
          continue;
        }
        if (skip && line.trim() === "") continue;
        if (skip && !line.startsWith("  ")) skip = false;
        if (skip) continue;
        textLines.push(line);
      }
      const text = textLines.join("\n").trim();
      if (text) {
        aiResponse = text;
        break;
      }
    }
    if (promptText || images.length > 0) {
      turns.push({
        prompt: promptText,
        toolCount: toolCallCount,
        timestamp: "",
        ...aiResponse ? { aiResponse } : {},
        ...images.length > 0 ? { images } : {}
      });
    }
  }
  return turns;
}

// src/agents/registry.ts
import fs4 from "fs";
var ALL_ADAPTERS = [
  claudeCodeAdapter,
  cursorAdapter
];
var AgentRegistry = class {
  adapters;
  constructor(additionalAdapters = []) {
    this.adapters = [...ALL_ADAPTERS, ...additionalAdapters];
  }
  /**
   * Find and parse transcript turns for a session.
   * Tries each adapter in priority order. Returns the first match.
   */
  getTranscriptTurns(sessionId) {
    for (const adapter of this.adapters) {
      const filePath = adapter.findTranscript(sessionId);
      if (!filePath) continue;
      try {
        const content = fs4.readFileSync(filePath, "utf-8");
        const turns = adapter.parseTurns(content);
        if (turns.length > 0) {
          return { turns, source: adapter.name };
        }
      } catch {
      }
    }
    return null;
  }
  /** List all registered adapter names */
  get adapterNames() {
    return this.adapters.map((a) => a.name);
  }
  /** Get a specific adapter by name */
  getAdapter(name) {
    return this.adapters.find((a) => a.name === name);
  }
  /** Detect which agent is currently active based on environment variables */
  detectActiveAgent() {
    for (const adapter of this.adapters) {
      if (process.env[adapter.pluginRootEnvVar]) {
        return adapter;
      }
    }
    return void 0;
  }
  /**
   * Parse turns from a known transcript file path (provided by hook).
   * Tries each adapter's parseTurns until one produces results.
   * Skips directory scanning entirely — the path is already known.
   */
  parseTurnsFromPath(filePath) {
    try {
      const content = fs4.readFileSync(filePath, "utf-8");
      const active = this.detectActiveAgent();
      const orderedAdapters = active ? [active, ...this.adapters.filter((a) => a !== active)] : this.adapters;
      for (const adapter of orderedAdapters) {
        const turns = adapter.parseTurns(content);
        if (turns.length > 0) {
          return { turns, source: `${adapter.name}:direct` };
        }
      }
    } catch {
    }
    return null;
  }
  /**
   * Resolve the plugin root directory from the active agent's environment variable.
   * Returns undefined if no agent env var is set (e.g., running from CLI directly).
   */
  resolvePluginRoot() {
    for (const adapter of this.adapters) {
      const value = process.env[adapter.pluginRootEnvVar];
      if (value) return value;
    }
    return void 0;
  }
};

export {
  createPerProjectAdapter,
  extensionForMimeType,
  claudeCodeAdapter,
  AgentRegistry
};
//# sourceMappingURL=chunk-RNWALAFP.js.map