import {
  createKbGate
} from "./chunk-SGKPNBXE.js";
import {
  definePersona,
  runPersonified,
  worktreeFanout
} from "./chunk-QDVLTRCP.js";
import {
  createExecutorRegistry
} from "./chunk-SSA6OERV.js";
import {
  runAnalystLoop
} from "./chunk-YPA5MLVE.js";
import {
  ConfigError
} from "./chunk-YEJR7IXO.js";

// src/loop-runner.ts
import {
  selfImprove
} from "@tangle-network/agent-eval/contract";
var DELEGATED_LOOP_MODES = ["code", "review", "research", "audit", "self-improve"];
function isDelegatedLoopMode(value) {
  return typeof value === "string" && DELEGATED_LOOP_MODES.includes(value);
}
async function runDelegatedLoop(mode, registry, options = {}) {
  const runner = registry[mode];
  if (!runner) {
    throw new ConfigError(
      `runDelegatedLoop: no runner registered for mode '${mode}' (registered: ${Object.keys(registry).join(", ") || "none"})`
    );
  }
  const now = options.now ?? Date.now;
  const signal = options.signal ?? new AbortController().signal;
  const start = now();
  try {
    const output = await runner(signal);
    return { mode, ok: true, output, durationMs: now() - start };
  } catch (err) {
    return {
      mode,
      ok: false,
      error: err instanceof Error ? err.message : String(err),
      durationMs: now() - start
    };
  }
}
function worktreeLoopRunner(options) {
  const shape = worktreeFanout({
    repoRoot: options.repoRoot,
    taskPrompt: options.taskPrompt,
    harnesses: options.harnesses,
    ...options.testCmd !== void 0 ? { testCmd: options.testCmd } : {},
    ...options.typecheckCmd !== void 0 ? { typecheckCmd: options.typecheckCmd } : {},
    ...options.require !== void 0 ? { require: options.require } : {},
    ...options.maxDiffLines !== void 0 ? { maxDiffLines: options.maxDiffLines } : {},
    ...options.forbiddenPaths !== void 0 ? { forbiddenPaths: options.forbiddenPaths } : {},
    ...options.winnerStrategy !== void 0 ? { winnerStrategy: options.winnerStrategy } : {},
    ...options.runGit ? { runGit: options.runGit } : {},
    ...options.runHarness ? { runHarness: options.runHarness } : {},
    ...options.runCommand ? { runCommand: options.runCommand } : {}
  });
  const persona = definePersona({
    name: "worktree-coder",
    root: { profile: { name: "worktree-coder" }, harness: null },
    directive: "deliver a minimal validated patch on a fresh worktree",
    context: { role: "coder" },
    executors: { registry: createExecutorRegistry() }
  });
  return async (signal) => {
    const result = await runPersonified({
      persona,
      shape,
      task: options.taskPrompt,
      budget: options.budget,
      signal
    });
    if (result.kind !== "winner" || result.out.kind !== "done") {
      const blockers = result.kind === "winner" && result.out.kind === "blocked" ? result.out.blockers.join("; ") : `supervisor settled ${result.kind}`;
      throw new Error(`worktreeLoopRunner: no delivered patch (${blockers})`);
    }
    return result.out.deliverable;
  };
}
function researchLoopRunner(o) {
  const gate = createKbGate(o.gate);
  const maxRounds = Math.max(1, Math.trunc(o.maxRounds ?? 1));
  return async (signal) => {
    const accepted = [];
    let vetoed = [];
    let rounds = 0;
    for (let round = 0; round < maxRounds; round += 1) {
      if (signal.aborted) break;
      rounds += 1;
      const candidates = await o.research(round, vetoed);
      if (candidates.length === 0) break;
      vetoed = [];
      for (const c of candidates) {
        const v = await gate(c);
        if (v.accepted) accepted.push(c);
        else vetoed.push({ candidate: c, vetoedBy: v.vetoedBy, reason: v.reason });
      }
      if (vetoed.length === 0) break;
    }
    return { accepted, vetoed, rounds };
  };
}
function selfImproveLoopRunner(options) {
  return async () => selfImprove(options);
}
function auditLoopRunner(options) {
  return async () => runAnalystLoop(options);
}

// src/loop-runner-bin.ts
async function runLoopRunnerCli(args) {
  if (!isDelegatedLoopMode(args.mode)) {
    return {
      exitCode: 2,
      error: `unknown mode '${args.mode}' (expected one of: ${DELEGATED_LOOP_MODES.join(", ")})`
    };
  }
  let registry;
  try {
    registry = await args.loadRegistry();
  } catch (err) {
    return { exitCode: 2, error: `failed to load registry: ${errMsg(err)}` };
  }
  if (!registry[args.mode]) {
    return {
      exitCode: 2,
      error: `config registers no runner for mode '${args.mode}' (registered: ${Object.keys(registry).join(", ") || "none"})`
    };
  }
  const result = await runDelegatedLoop(args.mode, registry, {
    ...args.now ? { now: args.now } : {}
  });
  return { exitCode: result.ok ? 0 : 1, result };
}
function parseLoopRunnerArgv(argv) {
  const out = {};
  for (let i = 0; i < argv.length; i += 1) {
    const a = argv[i];
    if (a === "--mode") out.mode = argv[++i];
    else if (a === "--config") out.config = argv[++i];
    else if (a?.startsWith("--mode=")) out.mode = a.slice("--mode=".length);
    else if (a?.startsWith("--config=")) out.config = a.slice("--config=".length);
  }
  return out;
}
function resolveRegistry(mod) {
  const def = mod?.default ?? mod;
  const value = typeof def === "function" ? def() : def;
  return value;
}
function errMsg(err) {
  return err instanceof Error ? err.message : String(err);
}
async function main() {
  const { mode, config } = parseLoopRunnerArgv(process.argv.slice(2));
  if (!mode || !config) {
    process.stderr.write(
      `usage: agent-runtime-loop --mode <mode> --config <module>
  modes: ${DELEGATED_LOOP_MODES.join(" | ")}
  config: a JS/TS module default-exporting a DelegatedLoopRegistry (or a factory)
`
    );
    process.exit(2);
  }
  const { pathToFileURL } = await import("url");
  const { resolve } = await import("path");
  const cli = await runLoopRunnerCli({
    mode,
    loadRegistry: async () => resolveRegistry(await import(pathToFileURL(resolve(config)).href))
  });
  process.stdout.write(`${JSON.stringify(cli.result ?? { error: cli.error }, null, 2)}
`);
  if (cli.error) process.stderr.write(`${cli.error}
`);
  process.exit(cli.exitCode);
}
var invokedScript = typeof process !== "undefined" ? process.argv?.[1] : void 0;
if (invokedScript && /loop-runner-bin\.(js|ts|mjs)$/.test(invokedScript)) {
  void main();
}

export {
  DELEGATED_LOOP_MODES,
  isDelegatedLoopMode,
  runDelegatedLoop,
  worktreeLoopRunner,
  researchLoopRunner,
  selfImproveLoopRunner,
  auditLoopRunner,
  runLoopRunnerCli,
  parseLoopRunnerArgv
};
//# sourceMappingURL=chunk-UJ3ONGHR.js.map