// src/mcp/local-harness.ts
import { spawn } from "child_process";
var HARNESS_INVOCATIONS = {
  claude: {
    command: "claude",
    buildArgs: (taskPrompt) => ["--headless", "-p", taskPrompt],
    modelArgs: (model) => ["-m", model]
  },
  codex: {
    command: "codex",
    buildArgs: (taskPrompt) => ["run", taskPrompt],
    modelArgs: (model) => ["-m", model]
  },
  opencode: {
    command: "opencode",
    buildArgs: (taskPrompt) => ["run", taskPrompt],
    modelArgs: (model) => ["-m", model]
  }
};
function harnessInvocation(harness, profile, taskPrompt) {
  const invocation = HARNESS_INVOCATIONS[harness];
  if (!invocation) {
    throw new Error(`harnessInvocation: unknown harness ${String(harness)}`);
  }
  const systemPrompt = profile.prompt?.systemPrompt;
  const composedPrompt = typeof systemPrompt === "string" && systemPrompt.trim().length > 0 ? `${systemPrompt}

${taskPrompt}` : taskPrompt;
  const args = invocation.buildArgs(composedPrompt);
  const model = profile.model?.default;
  if (typeof model === "string" && model.length > 0) {
    args.push(...invocation.modelArgs(model));
  }
  return { command: invocation.command, args };
}
var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
function runLocalHarness(options) {
  const { harness, cwd, taskPrompt } = options;
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
  const env = options.env ?? process.env;
  const spawnImpl = options.spawn ?? spawn;
  const invocation = HARNESS_INVOCATIONS[harness];
  if (!invocation) {
    return Promise.reject(new Error(`runLocalHarness: unknown harness ${String(harness)}`));
  }
  const startedAt = Date.now();
  const command = options.invocation?.command ?? invocation.command;
  const args = options.invocation ? [...options.invocation.args] : invocation.buildArgs(taskPrompt);
  return new Promise((resolve, reject) => {
    let child;
    try {
      child = spawnImpl(command, args, { cwd, env, stdio: "pipe" });
    } catch (err) {
      reject(err instanceof Error ? err : new Error(String(err)));
      return;
    }
    child.stdin?.end();
    let stdout = "";
    let stderr = "";
    let timedOut = false;
    let settled = false;
    const timer = timeoutMs > 0 ? setTimeout(() => {
      timedOut = true;
      if (!child.killed) child.kill("SIGTERM");
    }, timeoutMs) : null;
    if (timer && typeof timer.unref === "function") {
      ;
      timer.unref();
    }
    const onAbort = () => {
      if (!child.killed) child.kill("SIGTERM");
    };
    if (options.signal) {
      if (options.signal.aborted) onAbort();
      else options.signal.addEventListener("abort", onAbort, { once: true });
    }
    child.stdout?.on("data", (chunk) => {
      stdout += String(chunk);
    });
    child.stderr?.on("data", (chunk) => {
      stderr += String(chunk);
    });
    const finalize = (result) => {
      if (settled) return;
      settled = true;
      if (timer) clearTimeout(timer);
      options.signal?.removeEventListener("abort", onAbort);
      resolve(result);
    };
    child.on("error", (err) => {
      if (settled) return;
      settled = true;
      if (timer) clearTimeout(timer);
      options.signal?.removeEventListener("abort", onAbort);
      reject(err);
    });
    child.on("close", (code, signal) => {
      finalize({
        exitCode: code,
        stdout,
        stderr,
        killedBySignal: signal,
        durationMs: Date.now() - startedAt,
        timedOut
      });
    });
  });
}

export {
  harnessInvocation,
  runLocalHarness
};
//# sourceMappingURL=chunk-7LO5GMAO.js.map