@kernlang/agon 0.1.7 → 0.1.8

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.
@@ -13,7 +13,7 @@ import {
13
13
  runForge,
14
14
  runTribunal,
15
15
  sessionResultStore
16
- } from "./chunk-AONHRJRW.js";
16
+ } from "./chunk-GMVFKWQA.js";
17
17
  import {
18
18
  ENGINE_COLORS,
19
19
  icons
@@ -2714,4 +2714,4 @@ export {
2714
2714
  handleExitPlanMode,
2715
2715
  buildStepExecutors
2716
2716
  };
2717
- //# sourceMappingURL=chunk-RKXVKX25.js.map
2717
+ //# sourceMappingURL=chunk-KPU23NS2.js.map
@@ -12,8 +12,8 @@ import {
12
12
  repairOverbroadForbiddenLiterals,
13
13
  taskWantsRepositoryLinkCheck,
14
14
  validateFitnessCommandIntent
15
- } from "./chunk-WDT5NJOA.js";
16
- import "./chunk-AONHRJRW.js";
15
+ } from "./chunk-CQBQPSE4.js";
16
+ import "./chunk-GMVFKWQA.js";
17
17
  import "./chunk-I2PMSXJ3.js";
18
18
  import "./chunk-BPKY4OF2.js";
19
19
  import "./chunk-45YTXJWJ.js";
@@ -31,4 +31,4 @@ export {
31
31
  taskWantsRepositoryLinkCheck,
32
32
  validateFitnessCommandIntent
33
33
  };
34
- //# sourceMappingURL=forge-O2SJ5JIQ.js.map
34
+ //# sourceMappingURL=forge-5QSRUNW6.js.map
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  parseProseToRichLines,
27
27
  saveDismissedVersion,
28
28
  updateCommand
29
- } from "./chunk-6WWOJXG4.js";
29
+ } from "./chunk-GHAMYNRC.js";
30
30
  import {
31
31
  buildAgentApprovalCallback,
32
32
  buildConsensus,
@@ -38,7 +38,7 @@ import {
38
38
  runAgentTeam,
39
39
  runReviewCore,
40
40
  selectReviewEngine
41
- } from "./chunk-RKXVKX25.js";
41
+ } from "./chunk-KPU23NS2.js";
42
42
  import {
43
43
  parsePatchPreview
44
44
  } from "./chunk-SUT2HDOY.js";
@@ -54,7 +54,7 @@ import {
54
54
  renderScoreboard,
55
55
  scoreboardFailEngine,
56
56
  scoreboardFinishEngine
57
- } from "./chunk-WDT5NJOA.js";
57
+ } from "./chunk-CQBQPSE4.js";
58
58
  import {
59
59
  buildCesarSystemPrompt,
60
60
  buildOracleCheatPrompt,
@@ -108,7 +108,7 @@ import {
108
108
  synthesisRoutingAdvice,
109
109
  todosFromPlanSteps,
110
110
  yieldToInk
111
- } from "./chunk-AONHRJRW.js";
111
+ } from "./chunk-GMVFKWQA.js";
112
112
  import {
113
113
  ENGINE_COLORS,
114
114
  bold,
@@ -294,7 +294,7 @@ import { defineCommand as defineCommand31, runMain } from "citty";
294
294
 
295
295
  // src/generated/commands/forge.ts
296
296
  import { defineCommand } from "citty";
297
- import { readFileSync } from "fs";
297
+ import { readFileSync as readFileSync2 } from "fs";
298
298
 
299
299
  // src/generated/lib/engines-dir.ts
300
300
  import { join, dirname } from "path";
@@ -318,9 +318,9 @@ import { writeFileSync, mkdirSync as mkdirSync2 } from "fs";
318
318
  import { join as join3, dirname as dirname3 } from "path";
319
319
 
320
320
  // ../adapter-cli/src/generated/adapter-helpers.ts
321
- import { statSync, mkdirSync, existsSync as existsSync2, copyFileSync, chmodSync, unlinkSync } from "fs";
321
+ import { statSync, mkdirSync, existsSync as existsSync2, copyFileSync, chmodSync, unlinkSync, readFileSync, mkdtempSync, rmSync } from "fs";
322
322
  import { join as join2, dirname as dirname2, basename } from "path";
323
- import { homedir } from "os";
323
+ import { homedir, tmpdir } from "os";
324
324
  function recordDispatchHealth(engineId, result) {
325
325
  const exitCode = result.exitCode ?? 0;
326
326
  if (exitCode === 0 && !result.timedOut) {
@@ -548,6 +548,43 @@ ${systemPrompt}
548
548
  [User Message]
549
549
  ${prompt2}`;
550
550
  }
551
+ function answerChannelMode() {
552
+ const v = (process.env.AGON_CLAUDE_ANSWER_CHANNEL || "").trim().toLowerCase();
553
+ if (v === "off" || v === "0" || v === "false") return "off";
554
+ if (v === "mcp") return "mcp";
555
+ return "file";
556
+ }
557
+ function fileChannelInstruction(answerFile) {
558
+ return `
559
+
560
+ ---
561
+ [ANSWER DELIVERY \u2014 REQUIRED] After composing your COMPLETE final answer, use your Write tool to write that answer \u2014 markdown only, no preamble, no commentary, nothing but the answer itself \u2014 to this exact file path:
562
+ ${answerFile}
563
+ That file is the ONLY channel by which your answer is captured. Write it exactly once, at the very end. Do NOT skip it.`;
564
+ }
565
+ function readAnswerChannelFile(answerFile) {
566
+ try {
567
+ if (!existsSync2(answerFile)) return "";
568
+ const raw = readFileSync(answerFile, "utf-8");
569
+ if (!raw.trim()) return "";
570
+ const t = raw.trim();
571
+ if (t.startsWith("{")) {
572
+ try {
573
+ const parsed = JSON.parse(t);
574
+ if (parsed && typeof parsed.text === "string" && parsed.text.trim()) return parsed.text;
575
+ } catch {
576
+ }
577
+ }
578
+ return raw;
579
+ } catch {
580
+ return "";
581
+ }
582
+ }
583
+ function setupFileAnswerChannel(composed) {
584
+ const dir = mkdtempSync(join2(tmpdir(), "agon-ac-"));
585
+ const answerFile = join2(dir, "answer.md");
586
+ return { prompt: composed + fileChannelInstruction(answerFile), answerFile, dir };
587
+ }
551
588
  async function runClaudePtyDispatch(prompt2, timeoutSec, signal, mode, cwd, systemPrompt, env, extraArgv) {
552
589
  const start = Date.now();
553
590
  try {
@@ -592,18 +629,36 @@ async function runClaudePtyDispatch(prompt2, timeoutSec, signal, mode, cwd, syst
592
629
  }
593
630
  signal.addEventListener("abort", onAbort, { once: true });
594
631
  }
632
+ const useFileChannel = (mode ?? "exec") === "exec" && answerChannelMode() === "file";
633
+ let channelDir = "";
595
634
  try {
596
- const composed = composeClaudePtyPrompt(prompt2, systemPrompt);
597
- const text = await session.ask(composed, timeoutSec * 1e3);
635
+ let composed = composeClaudePtyPrompt(prompt2, systemPrompt);
636
+ let answerFile = "";
637
+ if (useFileChannel) {
638
+ const ch = setupFileAnswerChannel(composed);
639
+ composed = ch.prompt;
640
+ answerFile = ch.answerFile;
641
+ channelDir = ch.dir;
642
+ }
643
+ const scraped = await session.ask(composed, timeoutSec * 1e3);
644
+ const channelText = useFileChannel ? readAnswerChannelFile(answerFile) : "";
645
+ if (useFileChannel && process.env.AGON_DEBUG) console.error(`[agon] answer-channel(file): ${channelText ? "hit " + channelText.length + "ch" : "miss \u2192 scrape fallback"}`);
646
+ const text = channelText || scraped;
598
647
  return {
599
648
  exitCode: 0,
600
649
  stdout: text,
601
- stderr: "",
650
+ stderr: channelText ? "" : useFileChannel ? "answer-channel: file empty, used scrape fallback" : "",
602
651
  durationMs: Date.now() - start,
603
652
  timedOut: false
604
653
  };
605
654
  } catch (e) {
606
655
  const isTimeout = e?.kind === "timeout" || e?.name === "ClaudeSessionTimeout";
656
+ if (useFileChannel && channelDir) {
657
+ const salvaged = readAnswerChannelFile(join2(channelDir, "answer.md"));
658
+ if (salvaged) {
659
+ return { exitCode: 0, stdout: salvaged, stderr: "answer-channel: salvaged from file after ask error", durationMs: Date.now() - start, timedOut: false };
660
+ }
661
+ }
607
662
  return {
608
663
  exitCode: isTimeout ? 124 : 1,
609
664
  stdout: "",
@@ -614,6 +669,12 @@ async function runClaudePtyDispatch(prompt2, timeoutSec, signal, mode, cwd, syst
614
669
  } finally {
615
670
  if (signal) signal.removeEventListener("abort", onAbort);
616
671
  await session.close().catch(() => void 0);
672
+ if (channelDir) {
673
+ try {
674
+ rmSync(channelDir, { recursive: true, force: true });
675
+ } catch {
676
+ }
677
+ }
617
678
  }
618
679
  } catch (e) {
619
680
  return {
@@ -670,18 +731,29 @@ async function* runClaudePtyStreamDispatch(prompt2, timeoutSec, signal, mode, cw
670
731
  }
671
732
  signal.addEventListener("abort", onAbort, { once: true });
672
733
  }
734
+ const useFileChannel = (mode ?? "exec") === "exec" && answerChannelMode() === "file";
735
+ let channelDir = "";
673
736
  const collected = [];
674
737
  try {
675
- const composed = composeClaudePtyPrompt(prompt2, systemPrompt);
738
+ let composed = composeClaudePtyPrompt(prompt2, systemPrompt);
739
+ let answerFile = "";
740
+ if (useFileChannel) {
741
+ const ch = setupFileAnswerChannel(composed);
742
+ composed = ch.prompt;
743
+ answerFile = ch.answerFile;
744
+ channelDir = ch.dir;
745
+ }
676
746
  const gen = session.askStream(composed, timeoutSec * 1e3);
677
747
  while (true) {
678
748
  const next = await gen.next();
679
749
  if (next.done) {
680
- const text = typeof next.value === "string" && next.value ? next.value : collected.join("");
750
+ const scraped = typeof next.value === "string" && next.value ? next.value : collected.join("");
751
+ const channelText = useFileChannel ? readAnswerChannelFile(answerFile) : "";
752
+ if (useFileChannel && process.env.AGON_DEBUG) console.error(`[agon] answer-channel(file): ${channelText ? "hit " + channelText.length + "ch" : "miss \u2192 scrape fallback"}`);
681
753
  return {
682
754
  exitCode: 0,
683
- stdout: text,
684
- stderr: "",
755
+ stdout: channelText || scraped,
756
+ stderr: channelText ? "" : useFileChannel ? "answer-channel: file empty, used scrape fallback" : "",
685
757
  durationMs: Date.now() - start,
686
758
  timedOut: false
687
759
  };
@@ -691,6 +763,10 @@ async function* runClaudePtyStreamDispatch(prompt2, timeoutSec, signal, mode, cw
691
763
  }
692
764
  } catch (e) {
693
765
  const isTimeout = e?.kind === "timeout" || e?.name === "ClaudeSessionTimeout";
766
+ const salvaged = useFileChannel && channelDir ? readAnswerChannelFile(join2(channelDir, "answer.md")) : "";
767
+ if (salvaged) {
768
+ return { exitCode: 0, stdout: salvaged, stderr: "answer-channel: salvaged from file after ask error", durationMs: Date.now() - start, timedOut: false };
769
+ }
694
770
  return {
695
771
  exitCode: isTimeout ? 124 : 1,
696
772
  stdout: collected.join(""),
@@ -701,6 +777,12 @@ async function* runClaudePtyStreamDispatch(prompt2, timeoutSec, signal, mode, cw
701
777
  } finally {
702
778
  if (signal) signal.removeEventListener("abort", onAbort);
703
779
  await session.close().catch(() => void 0);
780
+ if (channelDir) {
781
+ try {
782
+ rmSync(channelDir, { recursive: true, force: true });
783
+ } catch {
784
+ }
785
+ }
704
786
  }
705
787
  } catch (e) {
706
788
  try {
@@ -730,7 +812,15 @@ var CliAdapter = class {
730
812
  this.isAvailable = this.isAvailable.bind(this);
731
813
  this.getVersion = this.getVersion.bind(this);
732
814
  }
815
+ withEngineTimeout(options) {
816
+ const declared = Number(options.engine?.timeout ?? 0);
817
+ if (declared > Number(options.timeout ?? 0)) {
818
+ return { ...options, timeout: declared };
819
+ }
820
+ return options;
821
+ }
733
822
  async dispatch(options) {
823
+ options = this.withEngineTimeout(options);
734
824
  const binaryPath = options.engine.binary ? this.registry.findBinary(options.engine) : null;
735
825
  if (!binaryPath) {
736
826
  if (options.engine.api) {
@@ -813,6 +903,7 @@ ${options.prompt}`;
813
903
  return result;
814
904
  }
815
905
  async *dispatchStream(options) {
906
+ options = this.withEngineTimeout(options);
816
907
  const iso = computeEngineIsolation(options.engine, { isolation: options.isolation, cwd: options.cwd });
817
908
  if (shouldUseClaudePty(options.engine)) {
818
909
  const gen2 = runClaudePtyStreamDispatch(options.prompt, options.timeout, options.signal, "exec", options.cwd, options.systemPrompt, iso.env, resolveClaudePtyExtraArgs(options.engine, options.cwd));
@@ -903,6 +994,7 @@ ${options.prompt}`;
903
994
  return result;
904
995
  }
905
996
  async dispatchAgent(options) {
997
+ options = this.withEngineTimeout(options);
906
998
  const iso = computeEngineIsolation(options.engine, { isolation: options.isolation, cwd: options.cwd });
907
999
  if (shouldUseClaudePty(options.engine)) {
908
1000
  const ptyStart = Date.now();
@@ -1047,6 +1139,7 @@ ${options.prompt}`;
1047
1139
  return { ...result, diff, diffLines: lines, filesChanged: files };
1048
1140
  }
1049
1141
  async *dispatchAgentStream(options) {
1142
+ options = this.withEngineTimeout(options);
1050
1143
  const iso = computeEngineIsolation(options.engine, { isolation: options.isolation, cwd: options.cwd });
1051
1144
  if (shouldUseClaudePty(options.engine)) {
1052
1145
  const baselineDiff2 = readOnlyDiff(options.cwd);
@@ -1463,7 +1556,7 @@ var forgeCommand = defineCommand({
1463
1556
  const patchPath = manifest.patches[manifest.winner];
1464
1557
  let winnerDiff = "";
1465
1558
  try {
1466
- winnerDiff = patchPath ? readFileSync(patchPath, "utf-8") : "";
1559
+ winnerDiff = patchPath ? readFileSync2(patchPath, "utf-8") : "";
1467
1560
  } catch (err) {
1468
1561
  warn(`Judge: could not read winner patch (${err instanceof Error ? err.message : String(err)})`);
1469
1562
  }
@@ -2320,7 +2413,7 @@ var leaderboardCommand = defineCommand8({
2320
2413
 
2321
2414
  // src/generated/commands/history.ts
2322
2415
  import { defineCommand as defineCommand9 } from "citty";
2323
- import { readdirSync, readFileSync as readFileSync2 } from "fs";
2416
+ import { readdirSync, readFileSync as readFileSync3 } from "fs";
2324
2417
  import { join as join7 } from "path";
2325
2418
  function showRunDetail(id) {
2326
2419
  let files;
@@ -2335,7 +2428,7 @@ function showRunDetail(id) {
2335
2428
  return;
2336
2429
  }
2337
2430
  const manifest = JSON.parse(
2338
- readFileSync2(join7(RUNS_DIR, files[0]), "utf-8")
2431
+ readFileSync3(join7(RUNS_DIR, files[0]), "utf-8")
2339
2432
  );
2340
2433
  header(`Forge Run: ${manifest.forgeId.slice(0, 8)}`);
2341
2434
  console.log(` Task: ${manifest.task}`);
@@ -2416,7 +2509,7 @@ var historyCommand = defineCommand9({
2416
2509
  for (const file of filesToLoad) {
2417
2510
  try {
2418
2511
  const manifest = JSON.parse(
2419
- readFileSync2(join7(RUNS_DIR, file), "utf-8")
2512
+ readFileSync3(join7(RUNS_DIR, file), "utf-8")
2420
2513
  );
2421
2514
  if (typeof manifest?.forgeId !== "string" || typeof manifest?.task !== "string" || typeof manifest?.timestamp !== "string") {
2422
2515
  throw new Error("manifest missing forgeId/task/timestamp");
@@ -2814,7 +2907,7 @@ ${transcript}`;
2814
2907
 
2815
2908
  // src/generated/commands/provenance.ts
2816
2909
  import { defineCommand as defineCommand11 } from "citty";
2817
- import { readdirSync as readdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
2910
+ import { readdirSync as readdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
2818
2911
  import { join as join8 } from "path";
2819
2912
  var provenanceCommand = defineCommand11({
2820
2913
  meta: {
@@ -2875,7 +2968,7 @@ var provenanceCommand = defineCommand11({
2875
2968
  const manifestPath = join8(RUNS_DIR, file);
2876
2969
  let manifest;
2877
2970
  try {
2878
- manifest = JSON.parse(readFileSync3(manifestPath, "utf-8"));
2971
+ manifest = JSON.parse(readFileSync4(manifestPath, "utf-8"));
2879
2972
  } catch (e) {
2880
2973
  info(`Could not read run ${file}: ${e instanceof Error ? e.message : String(e)}`);
2881
2974
  return;
@@ -3082,8 +3175,8 @@ var engineCommand = defineCommand12({
3082
3175
  // src/generated/commands/doctor.ts
3083
3176
  import { defineCommand as defineCommand13 } from "citty";
3084
3177
  import { spawnSync } from "child_process";
3085
- import { mkdtempSync, rmSync, writeFileSync as writeFileSync3, existsSync as existsSync3 } from "fs";
3086
- import { tmpdir, homedir as homedir2 } from "os";
3178
+ import { mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync as writeFileSync3, existsSync as existsSync3 } from "fs";
3179
+ import { tmpdir as tmpdir2, homedir as homedir2 } from "os";
3087
3180
  import { join as join10, basename as basename3 } from "path";
3088
3181
  import "url";
3089
3182
  function shellQuoteForDoctor(value) {
@@ -3242,7 +3335,7 @@ function checkDoctorWorktree(cwd) {
3242
3335
  try {
3243
3336
  root = repoRoot(cwd);
3244
3337
  const sha = headSha(cwd);
3245
- tempDir = mkdtempSync(join10(tmpdir(), "agon-doctor-"));
3338
+ tempDir = mkdtempSync2(join10(tmpdir2(), "agon-doctor-"));
3246
3339
  worktreePath = join10(tempDir, "worktree");
3247
3340
  worktreeCreate(root, worktreePath, sha);
3248
3341
  writeFileSync3(join10(worktreePath, ".agon-doctor-write-test"), "ok\n");
@@ -3267,7 +3360,7 @@ function checkDoctorWorktree(cwd) {
3267
3360
  }
3268
3361
  if (tempDir) {
3269
3362
  try {
3270
- rmSync(tempDir, { recursive: true, force: true });
3363
+ rmSync2(tempDir, { recursive: true, force: true });
3271
3364
  } catch {
3272
3365
  }
3273
3366
  }
@@ -3545,7 +3638,7 @@ var doctorCommand = defineCommand13({
3545
3638
 
3546
3639
  // src/generated/commands/last.ts
3547
3640
  import { defineCommand as defineCommand14 } from "citty";
3548
- import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
3641
+ import { readFileSync as readFileSync5, existsSync as existsSync4 } from "fs";
3549
3642
  import { join as join11 } from "path";
3550
3643
  var lastCommand = defineCommand14({
3551
3644
  meta: {
@@ -3594,7 +3687,7 @@ var lastCommand = defineCommand14({
3594
3687
  return;
3595
3688
  }
3596
3689
  try {
3597
- process.stdout.write(readFileSync4(statusPath, "utf-8"));
3690
+ process.stdout.write(readFileSync5(statusPath, "utf-8"));
3598
3691
  } catch (err) {
3599
3692
  process.stderr.write(`agon last: failed to read ${statusPath}: ${err instanceof Error ? err.message : String(err)}
3600
3693
  `);
@@ -3907,7 +4000,7 @@ var configCommand = defineCommand16({
3907
4000
 
3908
4001
  // src/commands/provider.ts
3909
4002
  import { defineCommand as defineCommand17 } from "citty";
3910
- import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, readdirSync as readdirSync3, readFileSync as readFileSync5, existsSync as existsSync5 } from "fs";
4003
+ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, readdirSync as readdirSync3, readFileSync as readFileSync6, existsSync as existsSync5 } from "fs";
3911
4004
  import { join as join13 } from "path";
3912
4005
  import { homedir as homedir3 } from "os";
3913
4006
  import { createInterface } from "readline";
@@ -4234,7 +4327,7 @@ var providerCommand = defineCommand17({
4234
4327
  const rows = [];
4235
4328
  for (const file of files) {
4236
4329
  try {
4237
- const def = JSON.parse(readFileSync5(join13(dir, file), "utf-8"));
4330
+ const def = JSON.parse(readFileSync6(join13(dir, file), "utf-8"));
4238
4331
  if (def.api) {
4239
4332
  const hasKey = !!getAuthKey(def.api.apiKeyEnv);
4240
4333
  rows.push([
@@ -5198,7 +5291,7 @@ var installAgentPromptsCommand = defineCommand21({
5198
5291
 
5199
5292
  // src/generated/commands/goal.ts
5200
5293
  import { defineCommand as defineCommand22 } from "citty";
5201
- import { readFileSync as readFileSync6, readdirSync as readdirSync4, existsSync as existsSync7, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
5294
+ import { readFileSync as readFileSync7, readdirSync as readdirSync4, existsSync as existsSync7, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
5202
5295
  import { resolve } from "path";
5203
5296
  var goalCommand = (() => {
5204
5297
  const slug = (s) => String(s ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 128);
@@ -5224,12 +5317,12 @@ var goalCommand = (() => {
5224
5317
  });
5225
5318
  }
5226
5319
  if (abs.endsWith(".json")) {
5227
- const parsed = JSON.parse(readFileSync6(abs, "utf-8"));
5320
+ const parsed = JSON.parse(readFileSync7(abs, "utf-8"));
5228
5321
  const arr = Array.isArray(parsed) ? parsed : parsed && Array.isArray(parsed.tasks) ? parsed.tasks : [parsed];
5229
5322
  return arr.map((o, i) => toTask(o, i));
5230
5323
  }
5231
5324
  if (abs.endsWith(".jsonl")) {
5232
- return readFileSync6(abs, "utf-8").split("\n").map((l) => l.trim()).filter(Boolean).map((line, i) => {
5325
+ return readFileSync7(abs, "utf-8").split("\n").map((l) => l.trim()).filter(Boolean).map((line, i) => {
5233
5326
  try {
5234
5327
  return toTask(JSON.parse(line), i);
5235
5328
  } catch (e) {
@@ -5607,7 +5700,7 @@ Return ONLY a JSON array of the engine ids that should COMPETE on this task \u20
5607
5700
  const patches = manifest.patches;
5608
5701
  const readPatchPath = (p) => {
5609
5702
  try {
5610
- return p ? readFileSync6(p, "utf-8") : "";
5703
+ return p ? readFileSync7(p, "utf-8") : "";
5611
5704
  } catch {
5612
5705
  return "";
5613
5706
  }
@@ -9216,7 +9309,7 @@ ${projectCtx}` : question;
9216
9309
  }
9217
9310
 
9218
9311
  // src/generated/handlers/info.ts
9219
- import { readdirSync as readdirSync5, readFileSync as readFileSync7, existsSync as existsSync9, rmSync as rmSync2 } from "fs";
9312
+ import { readdirSync as readdirSync5, readFileSync as readFileSync8, existsSync as existsSync9, rmSync as rmSync3 } from "fs";
9220
9313
  import { join as join23 } from "path";
9221
9314
  function handleLeaderboard(dispatch) {
9222
9315
  const ratings = getRatings();
@@ -9250,7 +9343,7 @@ function handleCesarReport(dispatch) {
9250
9343
  }
9251
9344
  let raw = "";
9252
9345
  try {
9253
- raw = readFileSync7(reportPath, "utf-8");
9346
+ raw = readFileSync8(reportPath, "utf-8");
9254
9347
  } catch (err) {
9255
9348
  dispatch({ type: "error", message: `Failed to read Cesar report: ${err instanceof Error ? err.message : String(err)}` });
9256
9349
  return;
@@ -9428,7 +9521,7 @@ function showRunDetail2(dispatch, id) {
9428
9521
  dispatch({ type: "info", message: `Run "${id}" not found` });
9429
9522
  return;
9430
9523
  }
9431
- const manifest = JSON.parse(readFileSync7(join23(RUNS_DIR, files[0]), "utf-8"));
9524
+ const manifest = JSON.parse(readFileSync8(join23(RUNS_DIR, files[0]), "utf-8"));
9432
9525
  dispatch({ type: "header", title: `Forge Run: ${manifest.forgeId.slice(0, 8)}` });
9433
9526
  dispatch({ type: "text", content: `Task: ${manifest.task}
9434
9527
  Fitness: ${manifest.fitnessCmd}
@@ -9470,7 +9563,7 @@ function handleHistory(dispatch, id) {
9470
9563
  const rows = [];
9471
9564
  for (const file of recent) {
9472
9565
  try {
9473
- const manifest = JSON.parse(readFileSync7(join23(RUNS_DIR, file), "utf-8"));
9566
+ const manifest = JSON.parse(readFileSync8(join23(RUNS_DIR, file), "utf-8"));
9474
9567
  const date = new Date(manifest.timestamp).toLocaleString();
9475
9568
  const taskStr = manifest.task.length > 40 ? manifest.task.slice(0, 40) + "..." : manifest.task;
9476
9569
  const winner = manifest.winner ?? "none";
@@ -9533,7 +9626,7 @@ async function handleEngines(dispatch, ctx, intent) {
9533
9626
  let removedUserConfig = false;
9534
9627
  const userConfigPath = join23(getAgonHome(), "engines", `${id}.json`);
9535
9628
  if (existsSync9(userConfigPath)) {
9536
- rmSync2(userConfigPath, { force: true });
9629
+ rmSync3(userConfigPath, { force: true });
9537
9630
  try {
9538
9631
  ctx.registry.unregister?.(id);
9539
9632
  } catch {
@@ -9983,7 +10076,7 @@ async function handlePlanShow(dispatch, ctx, planId) {
9983
10076
  savePlan(approved);
9984
10077
  dispatch({ type: "success", message: "Plan approved." });
9985
10078
  if (approved.action.type === "forge") {
9986
- const { handleForge: handleForge2 } = await import("./forge-O2SJ5JIQ.js");
10079
+ const { handleForge: handleForge2 } = await import("./forge-5QSRUNW6.js");
9987
10080
  await handleForge2(approved.action.task, approved.action.fitnessCmd ?? null, dispatch, ctx, approved, approved.action.hardened);
9988
10081
  } else {
9989
10082
  dispatch({ type: "info", message: "Run the build again to execute." });
@@ -10009,7 +10102,7 @@ async function handleApprove(dispatch, ctx) {
10009
10102
  savePlan(plan);
10010
10103
  dispatch({ type: "success", message: "Plan approved." });
10011
10104
  if (plan.action.type === "forge") {
10012
- const { handleForge: handleForge2 } = await import("./forge-O2SJ5JIQ.js");
10105
+ const { handleForge: handleForge2 } = await import("./forge-5QSRUNW6.js");
10013
10106
  await handleForge2(plan.action.task, plan.action.fitnessCmd ?? null, dispatch, ctx, plan, plan.action.hardened);
10014
10107
  } else {
10015
10108
  dispatch({ type: "info", message: "Run the build again to execute." });
@@ -10037,7 +10130,7 @@ async function handleRetry(dispatch, ctx) {
10037
10130
  plan = startPlan(plan);
10038
10131
  ctx.setCurrentPlan(plan);
10039
10132
  savePlan(plan);
10040
- const { handleForge: handleForge2 } = await import("./forge-O2SJ5JIQ.js");
10133
+ const { handleForge: handleForge2 } = await import("./forge-5QSRUNW6.js");
10041
10134
  await handleForge2(plan.action.task, plan.action.fitnessCmd ?? null, dispatch, ctx, plan, plan.action.hardened);
10042
10135
  } else {
10043
10136
  dispatch({ type: "info", message: "Plan reset to approved. Run the build again to execute." });
@@ -10152,7 +10245,7 @@ ${listing}` });
10152
10245
 
10153
10246
  // src/generated/handlers/build.ts
10154
10247
  import { join as join25 } from "path";
10155
- import { mkdirSync as mkdirSync13, readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
10248
+ import { mkdirSync as mkdirSync13, readFileSync as readFileSync9, existsSync as existsSync10 } from "fs";
10156
10249
  function injectFileReferences(input, cwd) {
10157
10250
  const FILE_REF = /(?:^|\s)([\w./-]+\.\w{1,10})\b/g;
10158
10251
  let result = input;
@@ -10165,7 +10258,7 @@ function injectFileReferences(input, cwd) {
10165
10258
  const fullPath = join25(cwd, ref);
10166
10259
  if (existsSync10(fullPath)) {
10167
10260
  try {
10168
- const content = readFileSync8(fullPath, "utf-8");
10261
+ const content = readFileSync9(fullPath, "utf-8");
10169
10262
  if (content.length < 5e4) {
10170
10263
  result += `
10171
10264
 
@@ -10415,7 +10508,7 @@ async function handleRun(command, dispatch, ctx) {
10415
10508
  }
10416
10509
 
10417
10510
  // src/generated/cesar/orchestration.ts
10418
- import { tmpdir as tmpdir2 } from "os";
10511
+ import { tmpdir as tmpdir3 } from "os";
10419
10512
 
10420
10513
  // src/generated/handlers/pipeline.ts
10421
10514
  import { join as join26 } from "path";
@@ -11510,7 +11603,7 @@ Beta: ${String(subB?.finalOutput ?? "").slice(0, 500)}`,
11510
11603
 
11511
11604
  // src/generated/handlers/team-forge.ts
11512
11605
  import { join as join33 } from "path";
11513
- import { mkdirSync as mkdirSync21, readFileSync as readFileSync9 } from "fs";
11606
+ import { mkdirSync as mkdirSync21, readFileSync as readFileSync10 } from "fs";
11514
11607
  async function handleTeamForge(task, fitnessCmd, dispatch, ctx, membersPerSide) {
11515
11608
  const teamAbort = new AbortController();
11516
11609
  try {
@@ -11604,7 +11697,7 @@ async function handleTeamForge(task, fitnessCmd, dispatch, ctx, membersPerSide)
11604
11697
  const patchPath = winnerOutput?.patchPath;
11605
11698
  if (patchPath) {
11606
11699
  try {
11607
- const patchContent = readFileSync9(patchPath, "utf-8");
11700
+ const patchContent = readFileSync10(patchPath, "utf-8");
11608
11701
  dispatch({ type: "patch-review", winnerId: `team:${result.winnerTeamId}`, patchPath, patchContent });
11609
11702
  } catch (err) {
11610
11703
  dispatch({ type: "info", message: `Winning patch: ${patchPath} (use git apply to apply manually)` });
@@ -12209,7 +12302,7 @@ function shouldEmitCesarRecap(event) {
12209
12302
  // src/generated/signals/file-tracker.ts
12210
12303
  import { relative, isAbsolute, resolve as resolve2, dirname as dirname6 } from "path";
12211
12304
  import { spawnSync as spawnSync3 } from "child_process";
12212
- import { existsSync as existsSync11, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
12305
+ import { existsSync as existsSync11, readFileSync as readFileSync11, statSync as statSync3 } from "fs";
12213
12306
  var EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit", "AgonEdit", "AgonWrite", "apply_patch", "applypatch", "ApplyPatch"]);
12214
12307
  var READ_TOOLS = /* @__PURE__ */ new Set(["Read", "Glob", "Grep"]);
12215
12308
  function extractFilePaths(tool, input) {
@@ -12311,7 +12404,7 @@ function getFileDiff(absPath, maxLines) {
12311
12404
  if (!st.isFile()) {
12312
12405
  return "";
12313
12406
  }
12314
- const content = readFileSync10(absPath, "utf8");
12407
+ const content = readFileSync11(absPath, "utf8");
12315
12408
  const contentLines = content.split("\n");
12316
12409
  const shown = contentLines.slice(0, Math.max(1, cap - 1)).map((line) => `+${line}`);
12317
12410
  const omitted = Math.max(0, contentLines.length - shown.length);
@@ -13749,7 +13842,7 @@ ${result.winner?.slice(0, 500) ?? ""}` });
13749
13842
  import "path";
13750
13843
 
13751
13844
  // src/generated/handlers/provider.ts
13752
- import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync24, unlinkSync as unlinkSync3, readdirSync as readdirSync6, readFileSync as readFileSync11, existsSync as existsSync12 } from "fs";
13845
+ import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync24, unlinkSync as unlinkSync3, readdirSync as readdirSync6, readFileSync as readFileSync12, existsSync as existsSync12 } from "fs";
13753
13846
  import { join as join38, resolve as resolve3 } from "path";
13754
13847
  import { homedir as homedir5 } from "os";
13755
13848
  function parseProviderKeyArgs(args) {
@@ -13835,7 +13928,7 @@ function handleProviderList(dispatch) {
13835
13928
  const rows = [];
13836
13929
  for (const file of files) {
13837
13930
  try {
13838
- const def = JSON.parse(readFileSync11(join38(dir, file), "utf-8"));
13931
+ const def = JSON.parse(readFileSync12(join38(dir, file), "utf-8"));
13839
13932
  if (def.api) {
13840
13933
  const hasKey = !!process.env[def.api.apiKeyEnv];
13841
13934
  rows.push([def.id, def.api.model, def.api.baseUrl, hasKey ? "ready" : "no key"]);
@@ -14818,7 +14911,7 @@ async function dispatchInitIntent(intent, input, cb) {
14818
14911
 
14819
14912
  // src/generated/signals/dispatch/intent-skills.ts
14820
14913
  import { join as join42 } from "path";
14821
- import { readFileSync as readFileSync13 } from "fs";
14914
+ import { readFileSync as readFileSync14 } from "fs";
14822
14915
  async function dispatchSkillsUiIntent(intent, input, cb) {
14823
14916
  switch (intent.type) {
14824
14917
  case "create-skill": {
@@ -14916,7 +15009,7 @@ ${lines}` });
14916
15009
  let found = null;
14917
15010
  for (const configPath of [join42(resolveWorkingDir(), ".mcp.json"), join42(getAgonHome(), "mcp.json")]) {
14918
15011
  try {
14919
- const raw = JSON.parse(readFileSync13(configPath, "utf-8"));
15012
+ const raw = JSON.parse(readFileSync14(configPath, "utf-8"));
14920
15013
  const servers = raw.mcpServers ?? raw.servers ?? raw;
14921
15014
  if (servers[serverInput]) {
14922
15015
  found = { name: serverInput, ...servers[serverInput] };
@@ -18913,7 +19006,7 @@ function formatRelativeTime(ms) {
18913
19006
  import { join as join46 } from "path";
18914
19007
  import "url";
18915
19008
  import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync29, unlinkSync as unlinkSync4, statSync as statSync4 } from "fs";
18916
- import { tmpdir as tmpdir3 } from "os";
19009
+ import { tmpdir as tmpdir4 } from "os";
18917
19010
  import { spawnSync as spawnSync6 } from "child_process";
18918
19011
 
18919
19012
  // src/generated/blocks/results-formatter.ts
@@ -19202,14 +19295,14 @@ function setWindowTitle(label) {
19202
19295
 
19203
19296
  // src/generated/surfaces/app-composer.ts
19204
19297
  import { join as join45 } from "path";
19205
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
19298
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "fs";
19206
19299
  var COMPOSER_HISTORY_LIMIT = 200;
19207
19300
  function composerHistoryPath() {
19208
19301
  return join45(getAgonHome(), "composer-history.json");
19209
19302
  }
19210
19303
  function loadComposerInputHistory() {
19211
19304
  try {
19212
- const parsed = JSON.parse(readFileSync14(composerHistoryPath(), "utf-8"));
19305
+ const parsed = JSON.parse(readFileSync15(composerHistoryPath(), "utf-8"));
19213
19306
  if (!Array.isArray(parsed)) {
19214
19307
  return [];
19215
19308
  }
@@ -20331,7 +20424,15 @@ function cachedMarkdownRows(baseKey, text, wrapWidth, paddingLeft, borderColor)
20331
20424
  const hit = _mdRowCache.get(key);
20332
20425
  if (hit) return hit;
20333
20426
  const rows = parseMarkdownToRows(baseKey, text, wrapWidth, paddingLeft, borderColor);
20334
- if (_mdRowCache.size >= _MD_ROW_CACHE_MAX) _mdRowCache.clear();
20427
+ if (_mdRowCache.size >= _MD_ROW_CACHE_MAX) {
20428
+ const evictCount = Math.floor(_MD_ROW_CACHE_MAX * 0.2);
20429
+ const it = _mdRowCache.keys();
20430
+ for (let i = 0; i < evictCount; i++) {
20431
+ const oldest = it.next().value;
20432
+ if (oldest === void 0) break;
20433
+ _mdRowCache.delete(oldest);
20434
+ }
20435
+ }
20335
20436
  _mdRowCache.set(key, rows);
20336
20437
  return rows;
20337
20438
  }
@@ -22592,14 +22693,14 @@ function App() {
22592
22693
  return;
22593
22694
  }
22594
22695
  content = formatChatTranscript(chatSession);
22595
- tmpFile = join46(tmpdir3(), `agon-chat-${Date.now()}.txt`);
22696
+ tmpFile = join46(tmpdir4(), `agon-chat-${Date.now()}.txt`);
22596
22697
  } else {
22597
22698
  if (!sessionResultStore.hasResults()) {
22598
22699
  dispatch({ type: "info", message: "No results yet \u2014 run /brainstorm, /campfire, /tribunal, or /forge first" });
22599
22700
  return;
22600
22701
  }
22601
22702
  content = formatSessionResults(sessionResultStore.getResults());
22602
- tmpFile = join46(tmpdir3(), `agon-results-${Date.now()}.txt`);
22703
+ tmpFile = join46(tmpdir4(), `agon-results-${Date.now()}.txt`);
22603
22704
  }
22604
22705
  try {
22605
22706
  writeFileSync13(tmpFile, content, "utf-8");
@@ -22701,7 +22802,7 @@ function App() {
22701
22802
  if (ans === "later") return;
22702
22803
  if (ans === "update") {
22703
22804
  setUpdateInfo(null);
22704
- import("./update-ODAAXWOD.js").then((m) => m.runUpdate(latest)).catch((err) => {
22805
+ import("./update-WLRTYR77.js").then((m) => m.runUpdate(latest)).catch((err) => {
22705
22806
  console.error("[agon] failed to launch update:", err && err.message ? err.message : String(err));
22706
22807
  });
22707
22808
  return;
@@ -24234,7 +24335,7 @@ maybeNotifyIsolationMigration();
24234
24335
  var main = defineCommand31({
24235
24336
  meta: {
24236
24337
  name: "agon",
24237
- version: "0.1.7",
24338
+ version: "0.1.8",
24238
24339
  description: "Any AI can join. They compete. You ship."
24239
24340
  },
24240
24341
  subCommands: {