var O = Object.defineProperty;
var D = (n, e, s) => e in n ? O(n, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : n[e] = s;
var d = (n, e, s) => D(n, typeof e != "symbol" ? e + "" : e, s);
import { c as q, b as v, i as A, a as M, d as y } from "./index-DsbpjH8L.js";
const E = 1e4, C = 1e3;
let T = null, w = null;
async function H() {
  if (!(T && w))
    try {
      let n = null;
      if (typeof (window == null ? void 0 : window.require) == "function" ? (n = window.require, console.log("[STDIO Plugin] Using window.require")) : typeof (globalThis == null ? void 0 : globalThis.require) == "function" ? (n = globalThis.require, console.log("[STDIO Plugin] Using globalThis.require")) : typeof require != "undefined" && (n = require, console.log("[STDIO Plugin] Using global require")), n) {
        console.log("[STDIO Plugin] Loading Node.js modules via require");
        const e = n("node:child_process"), s = n("node:readline");
        T = e.spawn, w = s.createInterface, console.log("[STDIO Plugin] Node.js modules loaded successfully via require");
      } else {
        console.log("[STDIO Plugin] Attempting dynamic import of Node.js modules");
        const e = await import("node:child_process"), s = await import("node:readline");
        T = e.spawn, w = s.createInterface, console.log("[STDIO Plugin] Node.js modules loaded successfully via import");
      }
    } catch (n) {
      throw console.error("[STDIO Plugin] Failed to load Node.js modules:", n), new Error(`Failed to load Node.js modules: ${n instanceof Error ? n.message : String(n)}`);
    }
}
class N {
  constructor() {
    d(this, "name", "local-stdio");
    d(this, "description", "Local stdio transport for MCP servers");
    d(this, "onNotification");
    d(this, "options", null);
    d(this, "process", null);
    d(this, "lineReader", null);
    d(this, "startPromise", null);
    d(this, "restartTimer", null);
    d(this, "disposed", !1);
    d(this, "initialized", !1);
    d(this, "autoRestart", !0);
    d(this, "timeoutMs", E);
    d(this, "pendingRequests", /* @__PURE__ */ new Map());
  }
  async initialize(e) {
    var l;
    console.log("[STDIO Plugin] initialize called with options:", e), (this.process || this.lineReader) && await this.dispose();
    const s = e, o = (l = s.command) == null ? void 0 : l.trim();
    if (!o)
      throw new Error("STDIO transport requires a command to run");
    this.options = {
      ...s,
      command: o
    }, this.autoRestart = s.autoRestart !== !1, this.timeoutMs = typeof s.timeoutMs == "number" ? s.timeoutMs : E, this.disposed = !1, console.log("[STDIO Plugin] Calling ensureStarted"), await this.ensureStarted(), console.log("[STDIO Plugin] initialize complete");
  }
  isReady() {
    return this.initialized && this.process !== null && !this.process.killed;
  }
  async sendRequest(e, s, o = {}) {
    var a;
    if (console.log("[STDIO Plugin] sendRequest called:", e, s), this.disposed)
      throw new Error("STDIO transport disposed");
    await this.ensureStarted();
    const l = this.process;
    if (!l || !l.stdin)
      throw new Error("STDIO transport process is not available");
    const i = q(e, s != null ? s : {}), t = i.id;
    if ((a = o.signal) != null && a.aborted)
      throw new Error("MCP request was aborted");
    return await new Promise((f, h) => {
      let c;
      const u = () => {
        var r;
        c.timeout && clearTimeout(c.timeout), (r = c.abortCleanup) == null || r.call(c), this.pendingRequests.delete(t);
      };
      if (c = {
        resolve: (r) => {
          u(), f(r);
        },
        reject: (r) => {
          u(), h(r);
        },
        onEvent: o.onEvent
      }, o.signal) {
        const r = new AbortController();
        if (c.abortCleanup = v(o.signal, r), o.signal.aborted) {
          u(), h(new Error("MCP request was aborted"));
          return;
        }
        r.signal.addEventListener(
          "abort",
          () => {
            u(), h(new Error("MCP request was aborted"));
          },
          { once: !0 }
        );
      }
      c.timeout = setTimeout(() => {
        u(), h(new Error(`MCP request "${e}" timed out after ${this.timeoutMs}ms`));
      }, this.timeoutMs), this.pendingRequests.set(t, c);
      try {
        const r = l.stdin;
        if (!r)
          throw new Error("STDIO transport stdin is not available");
        const p = `${JSON.stringify(i)}
`;
        r.write(p) || r.once("drain", () => {
        });
      } catch (r) {
        u(), h(new Error(`Failed to send MCP request: ${r instanceof Error ? r.message : String(r)}`));
      }
    });
  }
  async dispose() {
    this.disposed = !0, this.initialized = !1, this.restartTimer && (clearTimeout(this.restartTimer), this.restartTimer = null), this.rejectAllPendingRequests(new Error("STDIO transport disposed")), this.lineReader && (this.lineReader.removeAllListeners(), this.lineReader.close(), this.lineReader = null);
    const e = this.process;
    this.process = null, e && await new Promise((s) => {
      const o = setTimeout(() => {
        e.killed || e.kill("SIGKILL"), s();
      }, 2e3);
      e.once("exit", () => {
        clearTimeout(o), s();
      }), e.killed || e.kill("SIGTERM");
    }), this.startPromise = null, this.options = null;
  }
  async ensureStarted() {
    if (console.log("[STDIO Plugin] ensureStarted - disposed:", this.disposed, "startPromise:", !!this.startPromise), this.disposed)
      throw new Error("STDIO transport disposed");
    this.startPromise || (console.log("[STDIO Plugin] Creating new startProcess promise"), this.startPromise = this.startProcess()), await this.startPromise, console.log("[STDIO Plugin] ensureStarted complete");
  }
  async startProcess() {
    var o, l, i, t, a, f, h;
    if (console.log("[STDIO Plugin] startProcess beginning"), console.log("[STDIO Plugin] process.platform:", process.platform), console.log("[STDIO Plugin] Current process.env.PATH:", process.env.PATH), !this.options)
      throw new Error("STDIO transport options are not configured");
    if (await H(), !T)
      throw new Error("Failed to load Node.js child_process module");
    let e = { ...process.env, ...this.options.env };
    if (console.log("[STDIO Plugin] About to check PATH fix. Platform:", process.platform, "PATH includes nvm:", (o = e.PATH) == null ? void 0 : o.includes("nvm")), process.platform === "darwin") {
      console.log("[STDIO Plugin] Fixing PATH for macOS. Current PATH:", e.PATH);
      const u = (((l = globalThis.require) == null ? void 0 : l.call(globalThis, "node:os")) || await import("node:os")).homedir();
      let r = !1;
      try {
        const { execSync: p } = ((i = globalThis.require) == null ? void 0 : i.call(globalThis, "node:child_process")) || await import("node:child_process"), m = process.env.SHELL || "/bin/zsh", g = p(
          `${m} -l -c 'source ~/.zprofile 2>/dev/null; echo $PATH'`,
          {
            encoding: "utf8",
            env: { HOME: u }
          }
        ).trim();
        g && g.length > 20 && g.includes("nvm") && (e.PATH = g, r = !0, console.log("[STDIO Plugin] Fixed PATH from shell profile:", g.substring(0, 150)));
      } catch (p) {
        console.warn("[STDIO Plugin] Could not get PATH from shell:", p);
      }
      if (!r) {
        console.log("[STDIO Plugin] Attempting to auto-detect NVM installation");
        const p = process.env.NVM_DIR || `${u}/.nvm`;
        let m = null;
        try {
          const P = ((t = globalThis.require) == null ? void 0 : t.call(globalThis, "node:fs")) || await import("node:fs"), S = ((a = globalThis.require) == null ? void 0 : a.call(globalThis, "node:path")) || await import("node:path"), I = S.join(p, "versions/node"), b = P.readdirSync(I);
          if (b.length > 0) {
            const R = b.sort().reverse()[0];
            m = S.join(I, R, "bin"), console.log("[STDIO Plugin] Found NVM node at:", m);
          }
        } catch (P) {
          console.warn("[STDIO Plugin] Could not detect NVM installation:", P);
        }
        const g = [
          m,
          "/opt/homebrew/bin",
          "/usr/local/bin",
          "/usr/bin",
          "/bin",
          "/usr/sbin",
          "/sbin"
        ].filter(Boolean);
        e.PATH = [...g, e.PATH].filter(Boolean).join(":"), console.log("[STDIO Plugin] Using fallback PATH:", e.PATH.substring(0, 150));
      }
    }
    console.log("[STDIO Plugin] Final PATH for spawn:", (f = e.PATH) == null ? void 0 : f.substring(0, 150)), console.log("[STDIO Plugin] Spawning process:", this.options.command, this.options.args);
    const s = T(this.options.command, (h = this.options.args) != null ? h : [], {
      stdio: ["pipe", "pipe", "pipe"],
      cwd: this.options.cwd,
      env: e
    });
    if (this.process = s, !s.stdout || !s.stdin)
      throw s.kill("SIGKILL"), this.process = null, new Error("Failed to create stdio pipes for MCP process");
    this.attachProcessListeners(s), await new Promise((c, u) => {
      let r = !1;
      const p = () => {
        r = !0, g(), this.initialized = !0, c();
      }, m = (P) => {
        g(), r ? this.handleProcessError(P) : u(P);
      }, g = () => {
        s.off("spawn", p), s.off("error", m);
      };
      s.once("spawn", p), s.once("error", m);
    });
  }
  attachProcessListeners(e) {
    if (this.lineReader && (this.lineReader.removeAllListeners(), this.lineReader.close()), !w)
      throw new Error("Node.js readline module not loaded");
    e.stdout && (this.lineReader = w({
      input: e.stdout,
      crlfDelay: 1 / 0
    }), this.lineReader.on("line", (s) => {
      this.handleMessage(s);
    })), e.on("error", (s) => {
      this.handleProcessError(s);
    }), e.on("exit", (s, o) => {
      this.handleProcessExit(s, o);
    }), e.stderr && e.stderr.on("data", (s) => {
      console.warn(`MCP stdio stderr: ${s.toString().trim()}`);
    });
  }
  handleMessage(e) {
    var o, l;
    const s = e.trim();
    if (s)
      try {
        const i = JSON.parse(s), t = i.id;
        if (typeof t == "number") {
          const a = this.pendingRequests.get(t);
          if (a) {
            const f = A(i, t), h = M(i, t), c = f || h;
            if ((o = a.onEvent) == null || o.call(a, i, { requestId: t, isFinal: c }), f) {
              const { error: u } = i;
              a.reject(y(u));
              return;
            }
            if (h) {
              a.resolve(i);
              return;
            }
          }
        }
        "method" in i && !("id" in i) && ((l = this.onNotification) == null || l.call(this, i));
      } catch (i) {
        console.warn("Failed to parse MCP stdio message:", i, e);
      }
  }
  handleProcessError(e) {
    this.disposed || (console.error("MCP stdio process error:", e), this.rejectAllPendingRequests(new Error(`MCP stdio process error: ${e.message}`)));
  }
  handleProcessExit(e, s) {
    var i, t;
    this.initialized = !1, (i = this.lineReader) == null || i.removeAllListeners(), (t = this.lineReader) == null || t.close(), this.lineReader = null, this.process = null, this.startPromise = null;
    const o = s ? `terminated by signal ${s}` : `exited with code ${e}`, l = new Error(`MCP stdio process ${o}`);
    this.rejectAllPendingRequests(l), !this.disposed && this.autoRestart && (this.restartTimer && clearTimeout(this.restartTimer), this.restartTimer = setTimeout(() => {
      this.restartTimer = null, !this.disposed && (this.startPromise = this.startProcess().catch((a) => {
        console.error("Failed to restart MCP stdio process:", a), this.startPromise = null;
      }));
    }, C));
  }
  rejectAllPendingRequests(e) {
    var s, o, l;
    for (const [i, t] of this.pendingRequests)
      (o = t.onEvent) == null || o.call(
        t,
        {
          jsonrpc: "2.0",
          id: i,
          error: {
            code: (s = e.code) != null ? s : -32e3,
            message: e.message
          }
        },
        { requestId: i, isFinal: !0 }
      ), t.timeout && clearTimeout(t.timeout), (l = t.abortCleanup) == null || l.call(t), t.reject(e);
    this.pendingRequests.clear();
  }
}
const j = (n) => ({
  plugin: new N(),
  options: n
});
export {
  j as createStdioTransportConfig
};
//# sourceMappingURL=stdioTransportPlugin-CU0MpVsA.js.map
