@tangle-network/agent-runtime 0.55.0 → 0.56.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/agent.js +3 -1
  2. package/dist/agent.js.map +1 -1
  3. package/dist/{chunk-JTH2FPCK.js → chunk-4H2FML7G.js} +392 -11
  4. package/dist/chunk-4H2FML7G.js.map +1 -0
  5. package/dist/{chunk-2BDXWZUC.js → chunk-6XKXWA7H.js} +2 -2
  6. package/dist/chunk-6XKXWA7H.js.map +1 -0
  7. package/dist/{chunk-KADIJAD4.js → chunk-7QYOXFCD.js} +75 -60
  8. package/dist/chunk-7QYOXFCD.js.map +1 -0
  9. package/dist/{chunk-ZMPQEPQ7.js → chunk-EXIV2C72.js} +10 -89
  10. package/dist/chunk-EXIV2C72.js.map +1 -0
  11. package/dist/{chunk-KJH62YEK.js → chunk-F5XQA43K.js} +2 -2
  12. package/dist/{chunk-A73RADPB.js → chunk-G4NIVG34.js} +6 -6
  13. package/dist/chunk-G4NIVG34.js.map +1 -0
  14. package/dist/{chunk-H2KWSZAN.js → chunk-GLMFBUKT.js} +27 -6
  15. package/dist/chunk-GLMFBUKT.js.map +1 -0
  16. package/dist/{coder-CEkUFv8h.d.ts → coder-COuOK8h8.d.ts} +51 -2
  17. package/dist/{coordination-BMzskrUR.d.ts → coordination-DWNGqygr.d.ts} +81 -2
  18. package/dist/{delegates-BPLIl8EC.d.ts → delegates-D9o5_VFj.d.ts} +17 -1
  19. package/dist/improvement.d.ts +1 -1
  20. package/dist/improvement.js +1 -1
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +6 -5
  23. package/dist/index.js.map +1 -1
  24. package/dist/{local-harness-KrdFTY5R.d.ts → local-harness-BE_h8szs.d.ts} +11 -0
  25. package/dist/{loop-runner-bin-BGpVVyXp.d.ts → loop-runner-bin-CN2Se3jB.d.ts} +2 -2
  26. package/dist/loop-runner-bin.d.ts +3 -3
  27. package/dist/loop-runner-bin.js +5 -4
  28. package/dist/loops.d.ts +6 -4
  29. package/dist/loops.js +13 -3
  30. package/dist/mcp/bin.js +7 -7
  31. package/dist/mcp/index.d.ts +8 -87
  32. package/dist/mcp/index.js +11 -11
  33. package/dist/profiles.d.ts +1 -1
  34. package/dist/profiles.js +4 -2
  35. package/dist/profiles.js.map +1 -1
  36. package/dist/runtime.d.ts +281 -5
  37. package/dist/runtime.js +13 -3
  38. package/dist/workflow.js +3 -1
  39. package/dist/workflow.js.map +1 -1
  40. package/package.json +1 -1
  41. package/dist/chunk-2BDXWZUC.js.map +0 -1
  42. package/dist/chunk-A73RADPB.js.map +0 -1
  43. package/dist/chunk-H2KWSZAN.js.map +0 -1
  44. package/dist/chunk-JTH2FPCK.js.map +0 -1
  45. package/dist/chunk-KADIJAD4.js.map +0 -1
  46. package/dist/chunk-ZMPQEPQ7.js.map +0 -1
  47. /package/dist/{chunk-KJH62YEK.js.map → chunk-F5XQA43K.js.map} +0 -0
@@ -1,3 +1,6 @@
1
+ import {
2
+ runCoderChecks
3
+ } from "./chunk-7QYOXFCD.js";
1
4
  import {
2
5
  UI_LENSES
3
6
  } from "./chunk-WIR4HOOJ.js";
@@ -10,6 +13,10 @@ import {
10
13
  ValidationError,
11
14
  extractLlmCallEvent
12
15
  } from "./chunk-VLF5RHEQ.js";
16
+ import {
17
+ harnessInvocation,
18
+ runLocalHarness
19
+ } from "./chunk-GLMFBUKT.js";
13
20
  import {
14
21
  buildLoopSpanNodes
15
22
  } from "./chunk-G3RGMA7C.js";
@@ -2124,7 +2131,7 @@ function createScope(args) {
2124
2131
  let spawnOrdinal = 0;
2125
2132
  let cursorSeq = 0;
2126
2133
  const now = args.now ?? Date.now;
2127
- function spawn2(agent, task, opts) {
2134
+ function spawn4(agent, task, opts) {
2128
2135
  if (args.maxDepth !== void 0 && args.depth >= args.maxDepth) {
2129
2136
  return { ok: false, reason: "depth-exceeded" };
2130
2137
  }
@@ -2251,7 +2258,7 @@ function createScope(args) {
2251
2258
  return true;
2252
2259
  }
2253
2260
  return {
2254
- spawn: spawn2,
2261
+ spawn: spawn4,
2255
2262
  next,
2256
2263
  send,
2257
2264
  get view() {
@@ -2531,6 +2538,9 @@ function pipeline(stages) {
2531
2538
  });
2532
2539
  }
2533
2540
  function fanout(items, opts) {
2541
+ if (opts.synthesize && opts.selectWinner) {
2542
+ throw new ValidationError("fanout: pass at most one of `synthesize` or `selectWinner`");
2543
+ }
2534
2544
  return (ctx) => ({
2535
2545
  name: `${ctx.persona.name}/fanout`,
2536
2546
  async act(_task, scope) {
@@ -2538,7 +2548,8 @@ function fanout(items, opts) {
2538
2548
  let opened = 0;
2539
2549
  for (const [i, item] of items.entries()) {
2540
2550
  const label = opts.label ? opts.label(item, i) : `item:${i}`;
2541
- const child = ctx.spawnChild(label, ctx.persona.root);
2551
+ const spec = opts.itemSpec ? opts.itemSpec(item, i, ctx) : ctx.persona.root;
2552
+ const child = ctx.spawnChild(label, spec);
2542
2553
  const res = scope.spawn(child, opts.itemTask(item, i, ctx), {
2543
2554
  budget: ctx.budget.perChild,
2544
2555
  label
@@ -2562,7 +2573,8 @@ function fanout(items, opts) {
2562
2573
  );
2563
2574
  }
2564
2575
  if (!opts.synthesize) {
2565
- const winner = defaultSelectWinner(drained.iterations);
2576
+ const select = opts.selectWinner ?? defaultSelectWinner;
2577
+ const winner = select(drained.iterations);
2566
2578
  if (!winner || winner.output === void 0) {
2567
2579
  return blocked(
2568
2580
  orderedBlockers(drained.blockers, rejected, "fanout: no item survived selection")
@@ -3180,7 +3192,7 @@ function isAgent(value) {
3180
3192
  }
3181
3193
 
3182
3194
  // src/runtime/supervise/runtime.ts
3183
- import { spawn } from "child_process";
3195
+ import { spawn as spawn3 } from "child_process";
3184
3196
  import { estimateCost as estimateCost2, isModelPriced as isModelPriced2 } from "@tangle-network/agent-eval";
3185
3197
 
3186
3198
  // src/runtime/router-client.ts
@@ -3314,11 +3326,262 @@ async function routerToolLoop(cfg, system, user, tools, execute, opts) {
3314
3326
  return { final: lastText, turns: maxTurns, toolCalls, toolTrace, usage, messages };
3315
3327
  }
3316
3328
 
3329
+ // src/runtime/supervise/worktree-cli-executor.ts
3330
+ import { spawn as spawn2 } from "child_process";
3331
+ import { randomUUID } from "crypto";
3332
+
3333
+ // src/mcp/worktree.ts
3334
+ import { spawn } from "child_process";
3335
+ async function runGitAsync(args, cwd, runner) {
3336
+ if (runner) return runner(args, { cwd });
3337
+ return new Promise((resolve, reject) => {
3338
+ const proc = spawn("git", args, { cwd, stdio: "pipe" });
3339
+ let stdout = "";
3340
+ let stderr = "";
3341
+ proc.stdout?.on("data", (c) => {
3342
+ stdout += String(c);
3343
+ });
3344
+ proc.stderr?.on("data", (c) => {
3345
+ stderr += String(c);
3346
+ });
3347
+ proc.on("error", reject);
3348
+ proc.on("close", (code) => resolve({ stdout, stderr, exitCode: code ?? -1 }));
3349
+ });
3350
+ }
3351
+ function ensureGitOk(step, result) {
3352
+ if (result.exitCode !== 0) {
3353
+ throw new Error(
3354
+ `worktree: git ${step} failed (exit ${result.exitCode}): ${result.stderr.slice(0, 400)}`
3355
+ );
3356
+ }
3357
+ }
3358
+ async function createWorktree(options) {
3359
+ const variants = options.variantsDir ?? ".coder-variants";
3360
+ const baseRef = options.baseRef ?? "HEAD";
3361
+ const branch = `delegate/${options.runId}`;
3362
+ const path2 = `${options.repoRoot.replace(/\/+$/, "")}/${variants}/${options.runId}`;
3363
+ const headSha = await runGitAsync(["rev-parse", baseRef], options.repoRoot, options.runGit);
3364
+ ensureGitOk(`rev-parse ${baseRef}`, headSha);
3365
+ const add = await runGitAsync(
3366
+ ["worktree", "add", "-b", branch, path2, baseRef],
3367
+ options.repoRoot,
3368
+ options.runGit
3369
+ );
3370
+ ensureGitOk(`worktree add ${path2}`, add);
3371
+ return { path: path2, baseSha: headSha.stdout.trim(), branch };
3372
+ }
3373
+ async function captureWorktreeDiff(options) {
3374
+ const baseRef = options.baseRef ?? options.worktree.baseSha;
3375
+ const patch = await runGitAsync(["diff", baseRef], options.worktree.path, options.runGit);
3376
+ const shortstat = await runGitAsync(
3377
+ ["diff", "--shortstat", baseRef],
3378
+ options.worktree.path,
3379
+ options.runGit
3380
+ );
3381
+ const stats = parseShortstat(shortstat.stdout);
3382
+ return { patch: patch.stdout, stats };
3383
+ }
3384
+ function parseShortstat(text) {
3385
+ const out = { filesChanged: 0, insertions: 0, deletions: 0 };
3386
+ const filesMatch = text.match(/(\d+)\s+files?\s+changed/);
3387
+ if (filesMatch?.[1]) out.filesChanged = Number(filesMatch[1]);
3388
+ const insertMatch = text.match(/(\d+)\s+insertions?/);
3389
+ if (insertMatch?.[1]) out.insertions = Number(insertMatch[1]);
3390
+ const deleteMatch = text.match(/(\d+)\s+deletions?/);
3391
+ if (deleteMatch?.[1]) out.deletions = Number(deleteMatch[1]);
3392
+ return out;
3393
+ }
3394
+ async function removeWorktree(options) {
3395
+ const force = options.force ?? true;
3396
+ const args = ["worktree", "remove"];
3397
+ if (force) args.push("--force");
3398
+ args.push(options.worktree.path);
3399
+ const result = await runGitAsync(args, options.repoRoot, options.runGit);
3400
+ if (result.exitCode !== 0 && !/not a working tree/.test(result.stderr)) {
3401
+ await runGitAsync(
3402
+ ["branch", "-D", options.worktree.branch],
3403
+ options.repoRoot,
3404
+ options.runGit
3405
+ ).catch(() => void 0);
3406
+ }
3407
+ await runGitAsync(
3408
+ ["branch", "-D", options.worktree.branch],
3409
+ options.repoRoot,
3410
+ options.runGit
3411
+ ).catch(() => void 0);
3412
+ }
3413
+
3414
+ // src/runtime/supervise/worktree-cli-executor.ts
3415
+ var checkOutputCap = 16e3;
3416
+ function createWorktreeCliExecutor(options) {
3417
+ if (!options.repoRoot) {
3418
+ throw new ValidationError("createWorktreeCliExecutor: repoRoot required");
3419
+ }
3420
+ if (!options.harness) {
3421
+ throw new ValidationError("createWorktreeCliExecutor: harness required");
3422
+ }
3423
+ if (typeof options.taskPrompt !== "string" || options.taskPrompt.length === 0) {
3424
+ throw new ValidationError("createWorktreeCliExecutor: taskPrompt required");
3425
+ }
3426
+ const runId = options.runId ?? randomUUID();
3427
+ const runHarness = options.runHarness ?? runLocalHarness;
3428
+ const runCommand = options.runCommand ?? defaultRunCommand;
3429
+ const checkTimeoutMs = options.checkTimeoutMs ?? options.harnessTimeoutMs ?? 5 * 60 * 1e3;
3430
+ const controller = new AbortController();
3431
+ let worktree;
3432
+ let artifact;
3433
+ const removeIfPresent = async () => {
3434
+ if (!worktree) return;
3435
+ const wt = worktree;
3436
+ worktree = void 0;
3437
+ await removeWorktree({
3438
+ worktree: wt,
3439
+ repoRoot: options.repoRoot,
3440
+ ...options.runGit ? { runGit: options.runGit } : {}
3441
+ }).catch(() => void 0);
3442
+ };
3443
+ return {
3444
+ runtime: "cli",
3445
+ // A harness CLI cannot account tokens — exclude it from the conserved pool + equal-k.
3446
+ budgetExempt: true,
3447
+ async execute(_task, signal) {
3448
+ const linked = linkSignals(signal, controller.signal);
3449
+ const started = Date.now();
3450
+ worktree = await createWorktree({
3451
+ repoRoot: options.repoRoot,
3452
+ runId,
3453
+ ...options.baseRef ? { baseRef: options.baseRef } : {},
3454
+ ...options.runGit ? { runGit: options.runGit } : {}
3455
+ });
3456
+ const { command, args } = harnessInvocation(
3457
+ options.harness,
3458
+ options.profile,
3459
+ options.taskPrompt
3460
+ );
3461
+ const harnessResult = await runHarness({
3462
+ harness: options.harness,
3463
+ cwd: worktree.path,
3464
+ taskPrompt: options.taskPrompt,
3465
+ invocation: { command, args },
3466
+ ...options.harnessTimeoutMs !== void 0 ? { timeoutMs: options.harnessTimeoutMs } : {},
3467
+ ...linked ? { signal: linked } : {}
3468
+ });
3469
+ const checks = await runWorktreeChecks({
3470
+ worktreePath: worktree.path,
3471
+ ...options.testCmd !== void 0 ? { testCmd: options.testCmd } : {},
3472
+ ...options.typecheckCmd !== void 0 ? { typecheckCmd: options.typecheckCmd } : {},
3473
+ timeoutMs: checkTimeoutMs,
3474
+ runCommand,
3475
+ ...linked ? { signal: linked } : {}
3476
+ });
3477
+ const diff = await captureWorktreeDiff({
3478
+ worktree,
3479
+ ...options.runGit ? { runGit: options.runGit } : {}
3480
+ });
3481
+ const out = {
3482
+ branch: worktree.branch,
3483
+ patch: diff.patch,
3484
+ stats: diff.stats,
3485
+ harness: {
3486
+ name: options.harness,
3487
+ exitCode: harnessResult.exitCode,
3488
+ timedOut: harnessResult.timedOut,
3489
+ killedBySignal: harnessResult.killedBySignal,
3490
+ durationMs: harnessResult.durationMs,
3491
+ stdout: harnessResult.stdout,
3492
+ stderr: harnessResult.stderr
3493
+ },
3494
+ ...checks ? { checks } : {}
3495
+ };
3496
+ const spent = {
3497
+ iterations: 1,
3498
+ // budgetExempt: spend is recorded zero (not metered), never a fabricated cost.
3499
+ tokens: zeroTokenUsage(),
3500
+ usd: 0,
3501
+ ms: Date.now() - started
3502
+ };
3503
+ artifact = { outRef: contentAddress(out), out, spent };
3504
+ return artifact;
3505
+ },
3506
+ async teardown(_grace) {
3507
+ controller.abort();
3508
+ await removeIfPresent();
3509
+ return { destroyed: true };
3510
+ },
3511
+ resultArtifact() {
3512
+ if (!artifact) {
3513
+ throw new ValidationError(
3514
+ "createWorktreeCliExecutor: resultArtifact() read before execute() resolved"
3515
+ );
3516
+ }
3517
+ return artifact;
3518
+ }
3519
+ };
3520
+ }
3521
+ async function runWorktreeChecks(opts) {
3522
+ if (opts.testCmd === void 0 && opts.typecheckCmd === void 0) return void 0;
3523
+ const run = async (command) => {
3524
+ const res = await opts.runCommand({
3525
+ command,
3526
+ cwd: opts.worktreePath,
3527
+ timeoutMs: opts.timeoutMs,
3528
+ ...opts.signal ? { signal: opts.signal } : {}
3529
+ });
3530
+ return {
3531
+ command,
3532
+ passed: res.exitCode === 0,
3533
+ exitCode: res.exitCode,
3534
+ output: res.output.length > checkOutputCap ? res.output.slice(-checkOutputCap) : res.output
3535
+ };
3536
+ };
3537
+ const checks = {};
3538
+ if (opts.testCmd !== void 0) checks.tests = await run(opts.testCmd);
3539
+ if (opts.typecheckCmd !== void 0) checks.typecheck = await run(opts.typecheckCmd);
3540
+ return checks;
3541
+ }
3542
+ function defaultRunCommand(opts) {
3543
+ return new Promise((resolve, reject) => {
3544
+ const child = spawn2("/bin/sh", ["-c", opts.command], {
3545
+ cwd: opts.cwd,
3546
+ stdio: ["ignore", "pipe", "pipe"]
3547
+ });
3548
+ const chunks = [];
3549
+ let settled = false;
3550
+ const timer = setTimeout(() => child.kill("SIGTERM"), opts.timeoutMs);
3551
+ const onAbort = () => child.kill("SIGTERM");
3552
+ opts.signal?.addEventListener("abort", onAbort, { once: true });
3553
+ child.stdout?.on("data", (d) => chunks.push(String(d)));
3554
+ child.stderr?.on("data", (d) => chunks.push(String(d)));
3555
+ const finish = (fn) => {
3556
+ if (settled) return;
3557
+ settled = true;
3558
+ clearTimeout(timer);
3559
+ opts.signal?.removeEventListener("abort", onAbort);
3560
+ fn();
3561
+ };
3562
+ child.on("error", (err) => finish(() => reject(err)));
3563
+ child.on("close", (code) => finish(() => resolve({ exitCode: code, output: chunks.join("") })));
3564
+ });
3565
+ }
3566
+ function linkSignals(a, b) {
3567
+ if (a.aborted || b.aborted) {
3568
+ const c2 = new AbortController();
3569
+ c2.abort();
3570
+ return c2.signal;
3571
+ }
3572
+ const c = new AbortController();
3573
+ const onAbort = () => c.abort();
3574
+ a.addEventListener("abort", onAbort, { once: true });
3575
+ b.addEventListener("abort", onAbort, { once: true });
3576
+ return c.signal;
3577
+ }
3578
+
3317
3579
  // src/runtime/supervise/runtime.ts
3318
3580
  var routerSeamKey = "router";
3319
3581
  var sandboxSeamKey = "sandbox";
3320
3582
  var cliSeamKey = "cli";
3321
3583
  var bridgeSeamKey = "bridge";
3584
+ var cliWorktreeSeamKey = "cli-worktree";
3322
3585
  function contentRef(prefix, value) {
3323
3586
  let str;
3324
3587
  try {
@@ -3359,7 +3622,7 @@ var routerInlineExecutor = (spec, ctx) => {
3359
3622
  async execute(task, signal) {
3360
3623
  const messages = taskToMessages(task, spec);
3361
3624
  const started = Date.now();
3362
- const linked = linkSignals(signal, controller.signal);
3625
+ const linked = linkSignals2(signal, controller.signal);
3363
3626
  const r = await routerChatWithUsage(
3364
3627
  { routerBaseUrl: seam.routerBaseUrl, routerKey: seam.routerKey, model },
3365
3628
  messages,
@@ -3413,7 +3676,7 @@ var routerToolsInlineExecutor = (spec, ctx) => {
3413
3676
  runtime: "router",
3414
3677
  async execute(task, signal) {
3415
3678
  const started = Date.now();
3416
- const linked = linkSignals(signal, controller.signal);
3679
+ const linked = linkSignals2(signal, controller.signal);
3417
3680
  const messages = [
3418
3681
  ...taskToMessages(task, spec)
3419
3682
  ];
@@ -3654,7 +3917,7 @@ var cliExecutor = (_spec, ctx) => {
3654
3917
  };
3655
3918
  async function* streamCliLeaf(args) {
3656
3919
  const prompt = taskToPrompt(args.task);
3657
- const proc = spawn(args.seam.bin, args.seam.args ?? [], {
3920
+ const proc = spawn3(args.seam.bin, args.seam.args ?? [], {
3658
3921
  ...args.seam.cwd ? { cwd: args.seam.cwd } : {},
3659
3922
  env: { ...process.env, ...args.seam.env ?? {} },
3660
3923
  stdio: ["pipe", "pipe", "pipe"]
@@ -3732,7 +3995,7 @@ var bridgeExecutor = (spec, ctx) => {
3732
3995
  async execute(task, signal) {
3733
3996
  const messages = taskToMessages(task, spec);
3734
3997
  const started = Date.now();
3735
- const linked = linkSignals(signal, controller.signal);
3998
+ const linked = linkSignals2(signal, controller.signal);
3736
3999
  const timer = seam.timeoutMs ? setTimeout(() => controller.abort(), seam.timeoutMs) : void 0;
3737
4000
  try {
3738
4001
  const res = await fetch(`${seam.bridgeUrl.replace(/\/$/, "")}/v1/chat/completions`, {
@@ -3785,6 +4048,23 @@ var bridgeExecutor = (spec, ctx) => {
3785
4048
  }
3786
4049
  };
3787
4050
  };
4051
+ var cliWorktreeExecutor = (spec, ctx) => {
4052
+ const seam = readSeam(ctx, cliWorktreeSeamKey, "cli-worktree");
4053
+ if (!seam.repoRoot || !seam.harness || !seam.taskPrompt) {
4054
+ throw new ValidationError(
4055
+ "cliWorktreeExecutor: CliWorktreeSeam.repoRoot + harness + taskPrompt required"
4056
+ );
4057
+ }
4058
+ return createWorktreeCliExecutor({
4059
+ repoRoot: seam.repoRoot,
4060
+ profile: spec.profile,
4061
+ harness: seam.harness,
4062
+ taskPrompt: seam.taskPrompt,
4063
+ ...seam.runId ? { runId: seam.runId } : {},
4064
+ ...seam.baseRef ? { baseRef: seam.baseRef } : {},
4065
+ ...seam.harnessTimeoutMs !== void 0 ? { harnessTimeoutMs: seam.harnessTimeoutMs } : {}
4066
+ });
4067
+ };
3788
4068
  function createExecutor(config) {
3789
4069
  return (spec, ctx) => {
3790
4070
  const { backend, ...seam } = config;
@@ -3798,6 +4078,8 @@ function createExecutor(config) {
3798
4078
  return bridgeExecutor(spec, seamed);
3799
4079
  case "cli":
3800
4080
  return cliExecutor(spec, seamed);
4081
+ case "cli-worktree":
4082
+ return cliWorktreeExecutor(spec, seamed);
3801
4083
  case "sandbox": {
3802
4084
  const harness = spec.harness ?? config.harness ?? null;
3803
4085
  return sandboxExecutor({ ...spec, harness }, seamed);
@@ -3877,7 +4159,7 @@ function singleShotDriver(maxIterations) {
3877
4159
  }
3878
4160
  };
3879
4161
  }
3880
- function linkSignals(a, b) {
4162
+ function linkSignals2(a, b) {
3881
4163
  if (a.aborted || b.aborted) {
3882
4164
  const c2 = new AbortController();
3883
4165
  c2.abort();
@@ -6334,6 +6616,98 @@ function authoredWorker(profile, opts) {
6334
6616
  return { name: profile.name, act: async () => "", executorSpec: spec };
6335
6617
  }
6336
6618
 
6619
+ // src/runtime/supervise/coder-deliverable.ts
6620
+ function coderDeliverable(options = {}) {
6621
+ const require2 = new Set(options.require ?? []);
6622
+ const constraints = {
6623
+ ...options.maxDiffLines !== void 0 ? { maxDiffLines: options.maxDiffLines } : {},
6624
+ ...options.forbiddenPaths !== void 0 ? { forbiddenPaths: options.forbiddenPaths } : {}
6625
+ };
6626
+ return {
6627
+ describe: "coder patch: no-op/secret/forbidden/diff-size + required test/typecheck pass",
6628
+ check(artifact) {
6629
+ const input = {
6630
+ patch: artifact.patch,
6631
+ testsPassed: signalPass(artifact.checks?.tests?.passed, require2.has("tests")),
6632
+ typecheckPassed: signalPass(artifact.checks?.typecheck?.passed, require2.has("typecheck"))
6633
+ };
6634
+ return runCoderChecks(input, constraints).valid === true;
6635
+ }
6636
+ };
6637
+ }
6638
+ function signalPass(value, required) {
6639
+ if (value !== void 0) return value;
6640
+ return !required;
6641
+ }
6642
+
6643
+ // src/runtime/supervise/coder-fanout.ts
6644
+ function worktreeCoderFanout(options) {
6645
+ const deliverable = coderDeliverable({
6646
+ ...options.maxDiffLines !== void 0 ? { maxDiffLines: options.maxDiffLines } : {},
6647
+ ...options.forbiddenPaths !== void 0 ? { forbiddenPaths: options.forbiddenPaths } : {},
6648
+ ...options.require !== void 0 ? { require: options.require } : {}
6649
+ });
6650
+ const itemSpec = (item) => {
6651
+ const executor = gateOnDeliverable(
6652
+ createWorktreeCliExecutor({
6653
+ repoRoot: options.repoRoot,
6654
+ profile: item.profile,
6655
+ harness: item.harness,
6656
+ taskPrompt: options.taskPrompt,
6657
+ ...item.runId ? { runId: item.runId } : {},
6658
+ ...item.baseRef ? { baseRef: item.baseRef } : {},
6659
+ ...options.testCmd !== void 0 ? { testCmd: options.testCmd } : {},
6660
+ ...options.typecheckCmd !== void 0 ? { typecheckCmd: options.typecheckCmd } : {},
6661
+ ...options.harnessTimeoutMs !== void 0 ? { harnessTimeoutMs: options.harnessTimeoutMs } : {},
6662
+ ...options.runGit ? { runGit: options.runGit } : {},
6663
+ ...options.runHarness ? { runHarness: options.runHarness } : {},
6664
+ ...options.runCommand ? { runCommand: options.runCommand } : {}
6665
+ }),
6666
+ deliverable
6667
+ );
6668
+ return { profile: item.profile, harness: null, executor };
6669
+ };
6670
+ const selectWinner = winnerSelectorFor(options.winnerStrategy ?? "highest-score");
6671
+ return fanout(options.harnesses, {
6672
+ itemTask: () => options.taskPrompt,
6673
+ label: (item, i) => `${item.name}:${i}`,
6674
+ itemSpec: (item) => itemSpec(item),
6675
+ selectWinner
6676
+ });
6677
+ }
6678
+ function winnerSelectorFor(strategy) {
6679
+ return (iterations) => {
6680
+ const valid = iterations.filter(
6681
+ (iter) => iter.output !== void 0 && !iter.error && iter.verdict?.valid === true
6682
+ );
6683
+ if (valid.length === 0) return void 0;
6684
+ switch (strategy) {
6685
+ case "first-valid":
6686
+ return [...valid].sort((a, b) => a.index - b.index)[0];
6687
+ case "smallest-diff":
6688
+ return [...valid].sort((a, b) => diffLines(a) - diffLines(b) || a.index - b.index)[0];
6689
+ default:
6690
+ return [...valid].sort(
6691
+ (a, b) => (b.verdict?.score ?? 0) - (a.verdict?.score ?? 0) || a.index - b.index
6692
+ )[0];
6693
+ }
6694
+ };
6695
+ }
6696
+ function diffLines(iter) {
6697
+ const artifact = artifactOf(iter.output);
6698
+ if (!artifact) return Number.POSITIVE_INFINITY;
6699
+ return artifact.stats.insertions + artifact.stats.deletions;
6700
+ }
6701
+ function artifactOf(output) {
6702
+ if (!output) return void 0;
6703
+ if (isArtifact(output)) return output;
6704
+ if (output.kind === "done" && isArtifact(output.deliverable)) return output.deliverable;
6705
+ return void 0;
6706
+ }
6707
+ function isArtifact(value) {
6708
+ return value !== null && typeof value === "object" && typeof value.patch === "string" && typeof value.stats === "object";
6709
+ }
6710
+
6337
6711
  // src/mcp/tools/coordination.ts
6338
6712
  var idArg = { type: "string", description: "The workerId returned by spawn_worker." };
6339
6713
  function createCoordinationTools(opts) {
@@ -9244,6 +9618,11 @@ export {
9244
9618
  routerChatWithUsage,
9245
9619
  routerChatWithTools,
9246
9620
  routerToolLoop,
9621
+ createWorktree,
9622
+ captureWorktreeDiff,
9623
+ removeWorktree,
9624
+ createWorktreeCliExecutor,
9625
+ cliWorktreeExecutor,
9247
9626
  createExecutor,
9248
9627
  createExecutorRegistry,
9249
9628
  spendFromUsageEvents,
@@ -9280,6 +9659,8 @@ export {
9280
9659
  asAuthoredProfile,
9281
9660
  supervisorSkill,
9282
9661
  authoredWorker,
9662
+ coderDeliverable,
9663
+ worktreeCoderFanout,
9283
9664
  createCoordinationTools,
9284
9665
  coordinationDriverAgent,
9285
9666
  InMemoryFeedbackStore,
@@ -9341,4 +9722,4 @@ export {
9341
9722
  jjWorkspace,
9342
9723
  runInWorkspace
9343
9724
  };
9344
- //# sourceMappingURL=chunk-JTH2FPCK.js.map
9725
+ //# sourceMappingURL=chunk-4H2FML7G.js.map