@kernlang/agon 0.1.3 → 0.1.5

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 (34) hide show
  1. package/dist/{chunk-52VTWOLH.js → chunk-46WNYE4R.js} +118 -162
  2. package/dist/chunk-46WNYE4R.js.map +1 -0
  3. package/dist/{chunk-XOJPAFCJ.js → chunk-4NTH3EAR.js} +286 -541
  4. package/dist/chunk-4NTH3EAR.js.map +1 -0
  5. package/dist/{chunk-H7KZ34VX.js → chunk-73ETZFDH.js} +8 -27
  6. package/dist/chunk-73ETZFDH.js.map +1 -0
  7. package/dist/chunk-DGTU4UWQ.js +489 -0
  8. package/dist/chunk-DGTU4UWQ.js.map +1 -0
  9. package/dist/chunk-GPYWJO2Q.js +2924 -0
  10. package/dist/chunk-GPYWJO2Q.js.map +1 -0
  11. package/dist/{chunk-PFHGKBQT.js → chunk-HAJIKZGU.js} +912 -228
  12. package/dist/chunk-HAJIKZGU.js.map +1 -0
  13. package/dist/chunk-HSPQEDHX.js +102 -0
  14. package/dist/chunk-HSPQEDHX.js.map +1 -0
  15. package/dist/{chunk-5QMVQPHY.js → chunk-SOUF7XTW.js} +1 -1
  16. package/dist/{chunk-5QMVQPHY.js.map → chunk-SOUF7XTW.js.map} +1 -1
  17. package/dist/{dispatch-6LQSMMGI.js → dispatch-XHLJ44TF.js} +2 -2
  18. package/dist/{forge-6NV4WCMB.js → forge-ZI7NE73F.js} +6 -5
  19. package/dist/index.js +2070 -3551
  20. package/dist/index.js.map +1 -1
  21. package/dist/plan-mode-KIXDKD63.js +17 -0
  22. package/dist/{src-4VOZ6GIN.js → src-4A5FVACG.js} +53 -3
  23. package/dist/update-DLPMYTF3.js +30 -0
  24. package/dist/update-DLPMYTF3.js.map +1 -0
  25. package/package.json +4 -4
  26. package/dist/chunk-52VTWOLH.js.map +0 -1
  27. package/dist/chunk-H7KZ34VX.js.map +0 -1
  28. package/dist/chunk-PFHGKBQT.js.map +0 -1
  29. package/dist/chunk-XOJPAFCJ.js.map +0 -1
  30. package/dist/plan-mode-OSU42TOI.js +0 -15
  31. /package/dist/{dispatch-6LQSMMGI.js.map → dispatch-XHLJ44TF.js.map} +0 -0
  32. /package/dist/{forge-6NV4WCMB.js.map → forge-ZI7NE73F.js.map} +0 -0
  33. /package/dist/{plan-mode-OSU42TOI.js.map → plan-mode-KIXDKD63.js.map} +0 -0
  34. /package/dist/{src-4VOZ6GIN.js.map → src-4A5FVACG.js.map} +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  __require,
6
6
  __toCommonJS,
7
7
  apiStreamDispatchWithHistory
8
- } from "./chunk-5QMVQPHY.js";
8
+ } from "./chunk-SOUF7XTW.js";
9
9
 
10
10
  // ../core/src/generated/signals/glicko.ts
11
11
  var glicko_exports = {};
@@ -380,6 +380,7 @@ var DEFAULT_AGON_CONFIG = {
380
380
  allowedCommands: [],
381
381
  toolPermissions: {},
382
382
  hiddenEngines: [],
383
+ removedEngines: [],
383
384
  engineModels: {},
384
385
  engineEfforts: {},
385
386
  engineIsolation: "workspace-pure",
@@ -396,6 +397,7 @@ var DEFAULT_AGON_CONFIG = {
396
397
  var DEFAULT_CONFIG = DEFAULT_AGON_CONFIG;
397
398
 
398
399
  // ../core/src/generated/models/errors.ts
400
+ var AGON_MODE_NAMES = ["forge", "brainstorm", "tribunal", "campfire", "council", "synthesis", "conquer", "goal", "agent", "pipeline", "review", "nero", "think"];
399
401
  var AgonError = class extends Error {
400
402
  constructor(message) {
401
403
  super(message);
@@ -404,7 +406,8 @@ var AgonError = class extends Error {
404
406
  };
405
407
  var EngineNotFoundError = class extends AgonError {
406
408
  constructor(engineId, installHint) {
407
- const hint = installHint ? `. Install: ${installHint}` : "";
409
+ const modeId = engineId.toLowerCase();
410
+ const hint = AGON_MODE_NAMES.includes(modeId) ? `. "${engineId}" is an Agon mode (a command), not an engine \u2014 run /${modeId} instead. Engines are backends like codex, claude, or agy.` : installHint ? `. Install: ${installHint}` : "";
408
411
  super(`Engine "${engineId}" not found${hint}`);
409
412
  this.engineId = engineId;
410
413
  this.installHint = installHint;
@@ -504,6 +507,7 @@ function loadConfig(cwd) {
504
507
  const merged = { ...DEFAULT_AGON_CONFIG, ...global, ...local, ...localPrivate };
505
508
  if (!Array.isArray(merged.forgeEnabledEngines)) merged.forgeEnabledEngines = [];
506
509
  if (!Array.isArray(merged.hiddenEngines)) merged.hiddenEngines = [];
510
+ if (!Array.isArray(merged.removedEngines)) merged.removedEngines = [];
507
511
  if (!["auto", "explicit"].includes(String(merged.engineActivationMode))) merged.engineActivationMode = "auto";
508
512
  if (!merged.hooks || typeof merged.hooks === "string") merged.hooks = {};
509
513
  if (!merged.allowedCommands || typeof merged.allowedCommands === "string") merged.allowedCommands = [];
@@ -4923,10 +4927,10 @@ function isValidJWT(token, algorithm = null) {
4923
4927
  const tokensParts = token.split(".");
4924
4928
  if (tokensParts.length !== 3)
4925
4929
  return false;
4926
- const [header] = tokensParts;
4927
- if (!header)
4930
+ const [header2] = tokensParts;
4931
+ if (!header2)
4928
4932
  return false;
4929
- const parsedHeader = JSON.parse(atob(header));
4933
+ const parsedHeader = JSON.parse(atob(header2));
4930
4934
  if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT")
4931
4935
  return false;
4932
4936
  if (!parsedHeader.alg)
@@ -16361,8 +16365,8 @@ var EngineRegistry = class {
16361
16365
  return this.availableEngines().map((e) => e.id);
16362
16366
  }
16363
16367
  activeEngines(config2) {
16364
- const hidden = new Set(config2?.hiddenEngines ?? []);
16365
- const available = this.availableEngines().filter((e) => !hidden.has(e.id));
16368
+ const excluded = /* @__PURE__ */ new Set([...config2?.hiddenEngines ?? [], ...config2?.removedEngines ?? []]);
16369
+ const available = this.availableEngines().filter((e) => !excluded.has(e.id));
16366
16370
  if (!config2 || config2.engineActivationMode !== "explicit") {
16367
16371
  return available;
16368
16372
  }
@@ -16372,6 +16376,24 @@ var EngineRegistry = class {
16372
16376
  activeIds(config2) {
16373
16377
  return this.activeEngines(config2).map((e) => e.id);
16374
16378
  }
16379
+ partitionRoster(requested, config2) {
16380
+ if (!requested) {
16381
+ return { active: this.activeIds(config2), removed: [] };
16382
+ }
16383
+ const removedSet = new Set(config2?.removedEngines ?? []);
16384
+ const active = [];
16385
+ const removed = [];
16386
+ for (const raw of requested) {
16387
+ const id = this.resolveId(String(raw ?? "").trim());
16388
+ if (id && removedSet.has(id) && !removed.includes(id)) {
16389
+ removed.push(id);
16390
+ }
16391
+ if (id && !removedSet.has(id) && !active.includes(id)) {
16392
+ active.push(id);
16393
+ }
16394
+ }
16395
+ return { active, removed };
16396
+ }
16375
16397
  pickStarter(available, strategy, preferred) {
16376
16398
  if (available.length === 0) {
16377
16399
  throw new EngineNotFoundError("(any)", "No engines available");
@@ -16407,7 +16429,213 @@ var EngineRegistry = class {
16407
16429
 
16408
16430
  // ../core/src/generated/blocks/context-scanner.ts
16409
16431
  import { readFileSync as readFileSync8, readdirSync as readdirSync6, statSync as statSync6, existsSync as existsSync6 } from "fs";
16410
- import { join as join9, basename } from "path";
16432
+ import { join as join9, basename, dirname as dirname5 } from "path";
16433
+ import { createRequire as createRequire2 } from "module";
16434
+
16435
+ // ../../node_modules/@kernlang/context/dist/spine.js
16436
+ var CHARS_PER_TOKEN = 4;
16437
+ var DEFAULT_SPINE_TOKENS = 1500;
16438
+ var MAX_SITES_PER_SYMBOL = 3;
16439
+ var MAX_TOKEN_CHARS = 80;
16440
+ var UNSAFE_TOKEN_CHARS = /[\u0000-\u001f\u007f-\u009f<>;{},`]/g;
16441
+ function estimateTokens(text) {
16442
+ return Math.ceil(text.length / CHARS_PER_TOKEN);
16443
+ }
16444
+ function sanitize(raw) {
16445
+ const cleaned = raw.replace(UNSAFE_TOKEN_CHARS, " ").replace(/\s+/g, " ").trim();
16446
+ return cleaned.length > MAX_TOKEN_CHARS ? `${cleaned.slice(0, MAX_TOKEN_CHARS)}\u2026` : cleaned;
16447
+ }
16448
+ var KIND_ABBR = {
16449
+ function: "fn",
16450
+ method: "fn",
16451
+ class: "cls",
16452
+ const: "const",
16453
+ type: "type",
16454
+ module: "mod"
16455
+ };
16456
+ function usageVerb(kind) {
16457
+ return kind === "const" || kind === "type" || kind === "module" ? "readby" : "callby";
16458
+ }
16459
+ function confGlyph(c) {
16460
+ if (c === "unresolved")
16461
+ return "~";
16462
+ if (c === "heuristic")
16463
+ return "?";
16464
+ return "";
16465
+ }
16466
+ function renderSite(s) {
16467
+ return `${confGlyph(s.confidence)}${sanitize(s.path)}:${s.line}`;
16468
+ }
16469
+ function prepareSymbols(artifact, batchSet) {
16470
+ const fileById = new Map(artifact.files.map((f) => [f.id, f]));
16471
+ const prepared = [];
16472
+ for (const sym of artifact.symbols) {
16473
+ const file2 = fileById.get(sym.fileId);
16474
+ if (!file2 || !batchSet.has(file2.path))
16475
+ continue;
16476
+ const usage = artifact.usage[sym.id];
16477
+ prepared.push({
16478
+ name: sym.name,
16479
+ kind: sym.kind,
16480
+ exported: sym.exported,
16481
+ publicApi: sym.publicApi ?? false,
16482
+ fileId: sym.fileId,
16483
+ line: sym.line,
16484
+ sites: usage?.callers ?? [],
16485
+ totalCount: usage?.totalCount ?? 0
16486
+ });
16487
+ }
16488
+ prepared.sort((a, b) => {
16489
+ if (a.publicApi !== b.publicApi)
16490
+ return a.publicApi ? -1 : 1;
16491
+ if (a.exported !== b.exported)
16492
+ return a.exported ? -1 : 1;
16493
+ if (a.totalCount !== b.totalCount)
16494
+ return b.totalCount - a.totalCount;
16495
+ if (a.name !== b.name)
16496
+ return a.name < b.name ? -1 : 1;
16497
+ if (a.fileId !== b.fileId)
16498
+ return a.fileId < b.fileId ? -1 : 1;
16499
+ return a.line - b.line;
16500
+ });
16501
+ return prepared;
16502
+ }
16503
+ function symbolLineA(s) {
16504
+ const flags = [s.exported ? "exp" : "", s.publicApi ? "public" : ""].filter(Boolean).join(" ");
16505
+ const shown = s.sites.slice(0, MAX_SITES_PER_SYMBOL).map(renderSite).join(" ");
16506
+ const rest = s.totalCount - Math.min(s.sites.length, MAX_SITES_PER_SYMBOL);
16507
+ const tail = rest > 0 ? ` +${rest}` : "";
16508
+ const usagePart = s.totalCount > 0 ? ` ${usageVerb(s.kind)} ${shown}${tail}` : " unused";
16509
+ const head = `sym ${sanitize(s.name)} ${KIND_ABBR[s.kind]}${flags ? ` ${flags}` : ""} line${s.line}`;
16510
+ return `${head}${usagePart}`;
16511
+ }
16512
+ function symbolLineB(s) {
16513
+ const flags = [s.exported ? "exp" : "", s.publicApi ? "public" : ""].filter(Boolean).join(" ");
16514
+ return `sym ${sanitize(s.name)} ${KIND_ABBR[s.kind]}${flags ? ` ${flags}` : ""} used=${s.totalCount}`;
16515
+ }
16516
+ function symbolLineC(s) {
16517
+ return `sym ${sanitize(s.name)} used=${s.totalCount}`;
16518
+ }
16519
+ function depsLine(artifact, batchSet) {
16520
+ const deps = [];
16521
+ const seen = /* @__PURE__ */ new Set();
16522
+ for (const f of artifact.files) {
16523
+ if (!batchSet.has(f.path))
16524
+ continue;
16525
+ for (const imp of f.imports ?? []) {
16526
+ if (batchSet.has(imp.path) || seen.has(imp.path))
16527
+ continue;
16528
+ seen.add(imp.path);
16529
+ const names = imp.symbols?.length ? `{${imp.symbols.map(sanitize).join(",")}}` : "";
16530
+ deps.push(`${sanitize(imp.path)}${names}`);
16531
+ }
16532
+ }
16533
+ return deps.length ? `deps ${deps.join(" ")}` : null;
16534
+ }
16535
+ function taintLines(artifact) {
16536
+ return (artifact.taint ?? []).map((t) => `taint ${sanitize(t.source)} -> ${sanitize(t.through)} -> ${sanitize(t.sink)} conf=${t.confidence}`);
16537
+ }
16538
+ function elsewhereLine(otherBatches) {
16539
+ if (!otherBatches?.length)
16540
+ return null;
16541
+ const parts = otherBatches.map((b) => b.dirs.map((d) => `${sanitize(d)}/*#${sanitize(b.id)}`).join(" ")).filter(Boolean);
16542
+ return parts.length ? `elsewhere ${parts.join(" ")}` : null;
16543
+ }
16544
+ function header(opts, fileTotal) {
16545
+ const batch = opts.batchIndex && opts.batchTotal ? ` batch=${opts.batchIndex}/${opts.batchTotal}` : "";
16546
+ return `<kern-map v=1${batch} files=${fileTotal}>`;
16547
+ }
16548
+ function renderTier(tier, symbols, artifact, batchSet, opts) {
16549
+ const lines = [];
16550
+ if (tier === "A") {
16551
+ for (const s of symbols)
16552
+ lines.push(symbolLineA(s));
16553
+ const deps = depsLine(artifact, batchSet);
16554
+ if (deps)
16555
+ lines.push(deps);
16556
+ lines.push(...taintLines(artifact));
16557
+ const elsewhere = elsewhereLine(opts.otherBatches);
16558
+ if (elsewhere)
16559
+ lines.push(elsewhere);
16560
+ } else if (tier === "B") {
16561
+ for (const s of symbols)
16562
+ lines.push(symbolLineB(s));
16563
+ const elsewhere = elsewhereLine(opts.otherBatches);
16564
+ if (elsewhere)
16565
+ lines.push(elsewhere);
16566
+ } else {
16567
+ for (const s of symbols.filter((sym) => sym.exported))
16568
+ lines.push(symbolLineC(s));
16569
+ }
16570
+ return lines;
16571
+ }
16572
+ function buildSpine(artifact, opts) {
16573
+ const batchSet = new Set(opts.batchFiles);
16574
+ const symbols = prepareSymbols(artifact, batchSet);
16575
+ if (symbols.length === 0)
16576
+ return "";
16577
+ const budget = opts.tokenBudget ?? DEFAULT_SPINE_TOKENS;
16578
+ const head = header(opts, artifact.files.length);
16579
+ const close = "</kern-map>";
16580
+ const envelope = estimateTokens(`${head}
16581
+ ${close}`);
16582
+ const assemble = (bodyLines) => [head, ...bodyLines, close].join("\n");
16583
+ for (const tier of ["A", "B", "C"]) {
16584
+ const body = renderTier(tier, symbols, artifact, batchSet, opts);
16585
+ const text = assemble(body);
16586
+ if (estimateTokens(text) <= budget)
16587
+ return text;
16588
+ if (tier === "C") {
16589
+ return clipToBudget(symbols, head, close, envelope, budget);
16590
+ }
16591
+ }
16592
+ return assemble(renderTier("C", symbols, artifact, batchSet, opts));
16593
+ }
16594
+ var MARKER_RESERVE_TOKENS = 4;
16595
+ function clipToBudget(symbols, head, close, envelope, budget) {
16596
+ if (envelope + MARKER_RESERVE_TOKENS > budget)
16597
+ return "";
16598
+ const exported = symbols.filter((s) => s.exported);
16599
+ const kept = [];
16600
+ let used = envelope;
16601
+ let droppedExported = 0;
16602
+ for (const s of exported) {
16603
+ const line = symbolLineC(s);
16604
+ const cost = estimateTokens(`${line}
16605
+ `);
16606
+ if (used + cost + MARKER_RESERVE_TOKENS <= budget) {
16607
+ kept.push(line);
16608
+ used += cost;
16609
+ } else {
16610
+ droppedExported++;
16611
+ }
16612
+ }
16613
+ const dropped = droppedExported + (symbols.length - exported.length);
16614
+ if (dropped > 0)
16615
+ kept.push(`+${dropped} more`);
16616
+ return [head, ...kept, close].join("\n");
16617
+ }
16618
+
16619
+ // ../core/src/generated/blocks/context-scanner.ts
16620
+ var PROJECT_BRIEF_FILES = [".agon/project.md", "AGON.md", "AGENT.md", "CLAUDE.md", "CODEX.md"];
16621
+ var MAX_PROJECT_BRIEF_BYTES = 512 * 1024;
16622
+ function projectBriefCap(file2) {
16623
+ return file2 === ".agon/project.md" || file2 === "AGON.md" ? 4e3 : 2e3;
16624
+ }
16625
+ function hasProjectBrief(cwd) {
16626
+ for (const file2 of PROJECT_BRIEF_FILES) {
16627
+ try {
16628
+ const path = join9(cwd, file2);
16629
+ const st = existsSync6(path) ? statSync6(path) : null;
16630
+ if (st && st.isFile() && st.size > 0) {
16631
+ if (st.size > MAX_PROJECT_BRIEF_BYTES) return true;
16632
+ if (readFileSync8(path, "utf-8").trim().length > 0) return true;
16633
+ }
16634
+ } catch {
16635
+ }
16636
+ }
16637
+ return false;
16638
+ }
16411
16639
  function isKernProject(cwd) {
16412
16640
  if (existsSync6(join9(cwd, "kern.config.ts"))) return true;
16413
16641
  try {
@@ -16519,14 +16747,15 @@ ${tree}`);
16519
16747
  ${diff}`);
16520
16748
  }
16521
16749
  }
16522
- const instructionFiles = ["AGON.md", "AGENT.md", "CLAUDE.md", "CODEX.md"];
16523
- for (const file2 of instructionFiles) {
16750
+ for (const file2 of PROJECT_BRIEF_FILES) {
16524
16751
  try {
16525
16752
  const path = join9(cwd, file2);
16526
16753
  if (existsSync6(path)) {
16527
16754
  const content = readFileSync8(path, "utf-8").trim();
16528
16755
  if (content) {
16529
- const capped = content.length > 2e3 ? content.slice(0, 2e3) + "\n... (truncated)" : content;
16756
+ const cap = projectBriefCap(file2);
16757
+ const capped = content.length > cap ? content.slice(0, cap) + `
16758
+ ... (truncated at ${cap} chars)` : content;
16530
16759
  sections.push(`Project instructions (${file2}):
16531
16760
  ${capped}`);
16532
16761
  break;
@@ -16550,6 +16779,78 @@ ${result}
16550
16779
  }
16551
16780
  return result;
16552
16781
  }
16782
+ var KERN_SPINE_TTL_MS = 5 * 60 * 1e3;
16783
+ var KERN_SPINE_CACHE = /* @__PURE__ */ new Map();
16784
+ var KERN_SPINE_WARNED = /* @__PURE__ */ new Set();
16785
+ async function computeKernContextSpine(cwd) {
16786
+ const debugFail = (msg) => {
16787
+ if (process.env.AGON_DEBUG && !KERN_SPINE_WARNED.has(cwd)) {
16788
+ KERN_SPINE_WARNED.add(cwd);
16789
+ console.warn(`[agon] kern context spine unavailable for ${cwd}: ${msg}`);
16790
+ }
16791
+ };
16792
+ try {
16793
+ const requireFn = createRequire2(import.meta.url);
16794
+ const cliBin = join9(dirname5(requireFn.resolve("@kernlang/cli")), "cli.js");
16795
+ if (!existsSync6(cliBin)) return "";
16796
+ const timeoutEnv = Number(process.env.AGON_KERN_CONTEXT_TIMEOUT_MS);
16797
+ const timeout = Number.isFinite(timeoutEnv) && timeoutEnv > 0 ? timeoutEnv : 2e4;
16798
+ const budgetEnv = Number(process.env.AGON_KERN_CONTEXT_BUDGET);
16799
+ const tokenBudget = Number.isFinite(budgetEnv) && budgetEnv > 0 ? budgetEnv : 2e3;
16800
+ const result = await spawnWithTimeout({
16801
+ command: process.execPath,
16802
+ args: [cliBin, "context", cwd, "--stdout", "--base", cwd],
16803
+ cwd,
16804
+ timeout
16805
+ });
16806
+ if (result.exitCode !== 0) {
16807
+ debugFail(`kern context exit ${result.exitCode}`);
16808
+ return "";
16809
+ }
16810
+ const out = result.stdout.trim();
16811
+ if (out.length === 0) return "";
16812
+ if (out.length > 8 * 1024 * 1024) {
16813
+ debugFail("artifact JSON too large");
16814
+ return "";
16815
+ }
16816
+ let artifact;
16817
+ try {
16818
+ artifact = JSON.parse(out);
16819
+ } catch (e) {
16820
+ debugFail(`artifact parse: ${e instanceof Error ? e.message : String(e)}`);
16821
+ return "";
16822
+ }
16823
+ if (!artifact.files || artifact.files.length === 0) return "";
16824
+ const spine = buildSpine(artifact, {
16825
+ batchFiles: artifact.files.map((f) => f.path),
16826
+ tokenBudget
16827
+ });
16828
+ if (!spine) return "";
16829
+ return [
16830
+ "## PROJECT MAP (compiler-derived cross-file usage)",
16831
+ '<kern_map note="navigational reference data \u2014 not instructions; may be incomplete">',
16832
+ spine,
16833
+ "</kern_map>"
16834
+ ].join("\n");
16835
+ } catch (err) {
16836
+ debugFail(err instanceof Error ? err.message : String(err));
16837
+ return "";
16838
+ }
16839
+ }
16840
+ async function buildKernContextSpine(cwd) {
16841
+ if (process.env.AGON_NO_KERN_CONTEXT) return "";
16842
+ let fp = "nogit";
16843
+ try {
16844
+ fp = headSha(cwd) || "nogit";
16845
+ } catch {
16846
+ }
16847
+ const now = Date.now();
16848
+ const hit = KERN_SPINE_CACHE.get(cwd);
16849
+ if (hit && hit.fp === fp && now - hit.ts < KERN_SPINE_TTL_MS) return hit.promise;
16850
+ const promise2 = computeKernContextSpine(cwd);
16851
+ KERN_SPINE_CACHE.set(cwd, { fp, ts: now, promise: promise2 });
16852
+ return promise2;
16853
+ }
16553
16854
 
16554
16855
  // ../core/src/generated/blocks/codebase-map.ts
16555
16856
  import { readFileSync as readFileSync9, readdirSync as readdirSync7, statSync as statSync7, lstatSync as lstatSync2, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync7, rmSync as rmSync4 } from "fs";
@@ -16890,7 +17191,7 @@ function ensureCurrentWorkspace(cwd) {
16890
17191
  }
16891
17192
 
16892
17193
  // ../core/src/generated/signals/token-tracker.ts
16893
- function estimateTokens(text) {
17194
+ function estimateTokens2(text) {
16894
17195
  return Math.ceil(text.length / 4);
16895
17196
  }
16896
17197
  function estimateCost(engineId, tokens, model) {
@@ -16907,8 +17208,8 @@ var TokenTracker = class {
16907
17208
  record(engineId, inputOrPrompt, responseText) {
16908
17209
  let promptTokens, responseTokens, totalTokens, source, model, costUsd;
16909
17210
  if (typeof inputOrPrompt === "string") {
16910
- promptTokens = estimateTokens(inputOrPrompt);
16911
- responseTokens = estimateTokens(responseText ?? "");
17211
+ promptTokens = estimateTokens2(inputOrPrompt);
17212
+ responseTokens = estimateTokens2(responseText ?? "");
16912
17213
  totalTokens = promptTokens + responseTokens;
16913
17214
  source = "estimated";
16914
17215
  model = void 0;
@@ -16921,8 +17222,8 @@ var TokenTracker = class {
16921
17222
  model = inputOrPrompt.model;
16922
17223
  costUsd = estimateCost(engineId, totalTokens, model);
16923
17224
  } else {
16924
- promptTokens = estimateTokens(inputOrPrompt.prompt);
16925
- responseTokens = estimateTokens(inputOrPrompt.response);
17225
+ promptTokens = estimateTokens2(inputOrPrompt.prompt);
17226
+ responseTokens = estimateTokens2(inputOrPrompt.response);
16926
17227
  totalTokens = promptTokens + responseTokens;
16927
17228
  source = "estimated";
16928
17229
  model = void 0;
@@ -17164,9 +17465,9 @@ function wordWrap(text, width) {
17164
17465
 
17165
17466
  // ../core/src/generated/blocks/stack-trace.ts
17166
17467
  import { existsSync as existsSync9, readFileSync as readFileSync12 } from "fs";
17167
- import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute2, normalize, resolve as resolve7 } from "path";
17468
+ import { basename as basename3, dirname as dirname6, isAbsolute as isAbsolute2, normalize, resolve as resolve7 } from "path";
17168
17469
  import { fileURLToPath as fileURLToPath2 } from "url";
17169
- import { createRequire as createRequire2 } from "module";
17470
+ import { createRequire as createRequire3 } from "module";
17170
17471
  import { Buffer as Buffer2 } from "buffer";
17171
17472
  function setBoundedCacheEntry(cache, key, value) {
17172
17473
  if (!cache || typeof cache.set !== "function") return;
@@ -17207,7 +17508,7 @@ function readTextFileCached(filePath) {
17207
17508
  }
17208
17509
  function nodeModuleApi() {
17209
17510
  try {
17210
- return createRequire2(import.meta.url)("node:module");
17511
+ return createRequire3(import.meta.url)("node:module");
17211
17512
  } catch {
17212
17513
  return {};
17213
17514
  }
@@ -17243,7 +17544,7 @@ function loadSourceMapForFile(filePath) {
17243
17544
  const base643 = mappingUrl.match(/^data:application\/json(?:;charset=[^;,]+)?;base64,(.+)$/i)?.[1];
17244
17545
  if (base643) payload = JSON.parse(Buffer2.from(base643, "base64").toString("utf8"));
17245
17546
  } else {
17246
- const mapPath = resolve7(dirname5(normalized), decodeURIComponent(mappingUrl));
17547
+ const mapPath = resolve7(dirname6(normalized), decodeURIComponent(mappingUrl));
17247
17548
  if (existsSync9(mapPath)) payload = JSON.parse(readFileSync12(mapPath, "utf8"));
17248
17549
  }
17249
17550
  if (payload && typeof mod.SourceMap === "function") {
@@ -17288,7 +17589,7 @@ function resolveSourceMapSourcePath(mapFilePath, sourceMap, originFileName) {
17288
17589
  return normalize(sourceRef);
17289
17590
  }
17290
17591
  }
17291
- return normalize(resolve7(dirname5(normalizeStackFilePath(mapFilePath)), sourceRoot, sourceRef));
17592
+ return normalize(resolve7(dirname6(normalizeStackFilePath(mapFilePath)), sourceRoot, sourceRef));
17292
17593
  }
17293
17594
  function sourceMapOriginForLocation(sourceMap, lineNumber, columnNumber) {
17294
17595
  if (!sourceMap) return null;
@@ -17382,15 +17683,15 @@ function packageRootForGeneratedPath(generatedFile) {
17382
17683
  return null;
17383
17684
  }
17384
17685
  function resolveKernSourceFile(generatedFile, content, sourceName) {
17385
- const header = generatedHeaderSource(content);
17686
+ const header2 = generatedHeaderSource(content);
17386
17687
  const candidates = [];
17387
17688
  const root = packageRootForGeneratedPath(generatedFile);
17388
- if (header) {
17389
- if (isAbsolute2(header)) candidates.push(normalize(header));
17390
- if (root) candidates.push(normalize(resolve7(root, header)));
17391
- candidates.push(normalize(resolve7(dirname5(normalizeStackFilePath(generatedFile)), header)));
17689
+ if (header2) {
17690
+ if (isAbsolute2(header2)) candidates.push(normalize(header2));
17691
+ if (root) candidates.push(normalize(resolve7(root, header2)));
17692
+ candidates.push(normalize(resolve7(dirname6(normalizeStackFilePath(generatedFile)), header2)));
17392
17693
  try {
17393
- candidates.push(normalize(resolve7(process.cwd(), header)));
17694
+ candidates.push(normalize(resolve7(process.cwd(), header2)));
17394
17695
  } catch {
17395
17696
  }
17396
17697
  }
@@ -17925,7 +18226,7 @@ function undoPatch(cwd, undoToken) {
17925
18226
 
17926
18227
  // ../core/src/generated/blocks/file-history.ts
17927
18228
  import { readFileSync as readFileSync14, writeFileSync as writeFileSync11, mkdirSync as mkdirSync10, existsSync as existsSync10, readdirSync as readdirSync9, unlinkSync as unlinkSync4 } from "fs";
17928
- import { join as join15, dirname as dirname6, resolve as resolve9 } from "path";
18229
+ import { join as join15, dirname as dirname7, resolve as resolve9 } from "path";
17929
18230
  import { randomUUID as randomUUID2 } from "crypto";
17930
18231
  import { homedir as homedir7 } from "os";
17931
18232
  function snapshotsDir() {
@@ -17989,7 +18290,7 @@ function revertSnapshot(id) {
17989
18290
  reverted++;
17990
18291
  }
17991
18292
  } else {
17992
- mkdirSync10(dirname6(fullPath), { recursive: true });
18293
+ mkdirSync10(dirname7(fullPath), { recursive: true });
17993
18294
  writeFileSync11(fullPath, snap.content);
17994
18295
  reverted++;
17995
18296
  }
@@ -19511,7 +19812,7 @@ function createEditTool() {
19511
19812
 
19512
19813
  // ../core/src/generated/tools/tool-write.ts
19513
19814
  import { writeFileSync as writeFileSync15, statSync as statSync13, existsSync as existsSync15, mkdirSync as mkdirSync14 } from "fs";
19514
- import { resolve as resolve13, dirname as dirname9, relative as relative6 } from "path";
19815
+ import { resolve as resolve13, dirname as dirname10, relative as relative6 } from "path";
19515
19816
  function createWriteTool() {
19516
19817
  const definition = {
19517
19818
  name: "Write",
@@ -19594,7 +19895,7 @@ function createWriteTool() {
19594
19895
  } else {
19595
19896
  snapshot = takeSnapshot(`Write (new): ${relPath}`, ctx.cwd, [relPath]);
19596
19897
  }
19597
- const parentDir = dirname9(filePath);
19898
+ const parentDir = dirname10(filePath);
19598
19899
  if (!existsSync15(parentDir)) {
19599
19900
  try {
19600
19901
  mkdirSync14(parentDir, { recursive: true });
@@ -19642,6 +19943,13 @@ function extractBaseCommand(command) {
19642
19943
  }
19643
19944
  return cmd;
19644
19945
  }
19946
+ function guiUnavailableHint(command, stderr) {
19947
+ const cmd = (command ?? "").trim();
19948
+ const launchesGui = /(^|\s)electron(\s|$)/i.test(cmd) || /(^|\s)(pnpm|npm|yarn|bun)\s+(run\s+)?(studio|gui)(\s|$)/i.test(cmd);
19949
+ const displayFailure = /(DISPLAY\s+not\s+set|cannot\s+open\s+display|Missing X server)/i.test(stderr ?? "");
19950
+ if (!launchesGui && !displayFailure) return null;
19951
+ return "This looks like a GUI/desktop app, which cannot run in this headless shell. Use a headless equivalent (a build/test/CLI script, or a --headless flag), or run the GUI on your own machine.";
19952
+ }
19645
19953
  function createBashTool() {
19646
19954
  const definition = {
19647
19955
  name: "Bash",
@@ -19710,10 +20018,10 @@ function createBashTool() {
19710
20018
  const readRedirect = tryRedirectToRead(command);
19711
20019
  if (readRedirect) {
19712
20020
  try {
19713
- const { readFileSync: readFileSync33 } = await import("fs");
20021
+ const { readFileSync: readFileSync36 } = await import("fs");
19714
20022
  const { resolve: resolve28 } = await import("path");
19715
20023
  const filePath = resolve28(ctx.cwd, readRedirect.file);
19716
- const content = readFileSync33(filePath, "utf-8");
20024
+ const content = readFileSync36(filePath, "utf-8");
19717
20025
  const lines = content.split("\n");
19718
20026
  const offset = readRedirect.offset ?? 0;
19719
20027
  const limit = readRedirect.limit ?? lines.length;
@@ -19758,19 +20066,23 @@ function createBashTool() {
19758
20066
  }
19759
20067
  const durationMs = Date.now() - start;
19760
20068
  const exitCode = closeResult?.exitCode ?? 1;
20069
+ const guiHint = guiUnavailableHint(command, stderr);
19761
20070
  if (closeResult?.timedOut) {
19762
20071
  return {
19763
20072
  ok: false,
19764
20073
  content: stdout,
19765
- error: `Command timed out after ${timeout}ms`,
20074
+ error: `Command timed out after ${timeout}ms` + (guiHint ? `
20075
+ ${guiHint}` : ""),
19766
20076
  metadata: { exitCode: 124, durationMs, timedOut: true }
19767
20077
  };
19768
20078
  }
19769
20079
  if (exitCode !== 0) {
20080
+ const baseErr = stderr || `Process exited with code ${exitCode}`;
19770
20081
  return {
19771
20082
  ok: false,
19772
20083
  content: stdout,
19773
- error: stderr || `Process exited with code ${exitCode}`,
20084
+ error: guiHint ? `${baseErr}
20085
+ ${guiHint}` : baseErr,
19774
20086
  metadata: { exitCode, durationMs, timedOut: false }
19775
20087
  };
19776
20088
  }
@@ -20494,7 +20806,7 @@ function createTodoWriteTool() {
20494
20806
 
20495
20807
  // ../core/src/generated/signals/auth-store.ts
20496
20808
  import { readFileSync as readFileSync19, writeFileSync as writeFileSync16, mkdirSync as mkdirSync15, existsSync as existsSync16, chmodSync } from "fs";
20497
- import { join as join18, dirname as dirname10, resolve as resolve15 } from "path";
20809
+ import { join as join18, dirname as dirname11, resolve as resolve15 } from "path";
20498
20810
  import { homedir as homedir9 } from "os";
20499
20811
  function getAuthFile() {
20500
20812
  const override = process.env.AGON_HOME?.trim();
@@ -20515,7 +20827,7 @@ function loadAuthStore() {
20515
20827
  }
20516
20828
  function saveAuthStore(store) {
20517
20829
  const authFile = getAuthFile();
20518
- const dir = dirname10(authFile);
20830
+ const dir = dirname11(authFile);
20519
20831
  mkdirSync15(dir, { recursive: true });
20520
20832
  writeFileSync16(authFile, JSON.stringify(store.entries, null, 2) + "\n", { mode: 384 });
20521
20833
  try {
@@ -22169,17 +22481,17 @@ function startChatSession(opts) {
22169
22481
  const id = `chat-${Date.now()}`;
22170
22482
  const session = { id, startedAt: (/* @__PURE__ */ new Date()).toISOString(), messages: [], cwd: opts?.cwd, branch: opts?.branch, engineIds: opts?.engineIds };
22171
22483
  const filePath = join21(chatsDir(), `${id}.ndjson`);
22172
- const header = { _type: "header", id, startedAt: session.startedAt };
22484
+ const header2 = { _type: "header", id, startedAt: session.startedAt };
22173
22485
  if (opts?.cwd) {
22174
- header.cwd = opts.cwd;
22486
+ header2.cwd = opts.cwd;
22175
22487
  }
22176
22488
  if (opts?.branch) {
22177
- header.branch = opts.branch;
22489
+ header2.branch = opts.branch;
22178
22490
  }
22179
22491
  if (opts?.engineIds) {
22180
- header.engineIds = opts.engineIds;
22492
+ header2.engineIds = opts.engineIds;
22181
22493
  }
22182
- appendFileSync(filePath, JSON.stringify(header) + "\n");
22494
+ appendFileSync(filePath, JSON.stringify(header2) + "\n");
22183
22495
  return session;
22184
22496
  }
22185
22497
  function appendMessage(session, msg) {
@@ -22354,10 +22666,10 @@ function loadChatSession(id) {
22354
22666
  const raw = readFileSync22(filePath, "utf-8");
22355
22667
  const lines = raw.trim().split("\n").filter(Boolean);
22356
22668
  if (lines.length === 0) return null;
22357
- const header = JSON.parse(lines[0]);
22669
+ const header2 = JSON.parse(lines[0]);
22358
22670
  const messages = [];
22359
- let summary = typeof header.summary === "string" ? header.summary : void 0;
22360
- let summarizedMessageCount = typeof header.summarizedMessageCount === "number" ? header.summarizedMessageCount : void 0;
22671
+ let summary = typeof header2.summary === "string" ? header2.summary : void 0;
22672
+ let summarizedMessageCount = typeof header2.summarizedMessageCount === "number" ? header2.summarizedMessageCount : void 0;
22361
22673
  for (let i = 1; i < lines.length; i++) {
22362
22674
  const msg = JSON.parse(lines[i]);
22363
22675
  if (msg._type === "summary") {
@@ -22371,12 +22683,12 @@ function loadChatSession(id) {
22371
22683
  freeSummarizedMessageBodies(messages, 0, Math.min(summarizedMessageCount, messages.length));
22372
22684
  }
22373
22685
  return {
22374
- id: header.id ?? id,
22375
- startedAt: header.startedAt ?? "",
22686
+ id: header2.id ?? id,
22687
+ startedAt: header2.startedAt ?? "",
22376
22688
  messages,
22377
- cwd: header.cwd,
22378
- branch: header.branch,
22379
- engineIds: header.engineIds,
22689
+ cwd: header2.cwd,
22690
+ branch: header2.branch,
22691
+ engineIds: header2.engineIds,
22380
22692
  summary,
22381
22693
  summarizedMessageCount
22382
22694
  };
@@ -22414,9 +22726,9 @@ function latestChatSession() {
22414
22726
  import { existsSync as existsSync19 } from "fs";
22415
22727
  import { resolve as resolve19, basename as basename4, extname as extname2 } from "path";
22416
22728
  import { homedir as homedir11 } from "os";
22729
+ import { fileURLToPath as fileURLToPath3 } from "url";
22417
22730
  var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".bmp"]);
22418
22731
  var MIME_MAP = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".webp": "image/webp", ".svg": "image/svg+xml", ".bmp": "image/bmp" };
22419
- var IMAGE_PATH_REGEX = /(?:^|\s)((?:\/[\w.\-]+)+\.(?:png|jpe?g|gif|webp|svg|bmp)|~\/[\w.\-\/]+\.(?:png|jpe?g|gif|webp|svg|bmp)|\.{1,2}\/[\w.\-\/]+\.(?:png|jpe?g|gif|webp|svg|bmp))/gi;
22420
22732
  var IMG_CMD_REGEX = /^\/img\s+(.+)$/i;
22421
22733
  function isImagePath(filePath) {
22422
22734
  const ext = extname2(filePath).toLowerCase();
@@ -22444,59 +22756,404 @@ function buildImageAttachment(rawPath, cwd) {
22444
22756
  }
22445
22757
  return { path: resolved, filename: basename4(resolved), mimeType: mimeFromExt(resolved) };
22446
22758
  }
22759
+ function normalizeDroppedPath(raw) {
22760
+ let p = raw.trim();
22761
+ const sq = p.startsWith("'") && p.endsWith("'");
22762
+ const dq = p.startsWith('"') && p.endsWith('"');
22763
+ if (sq || dq) p = p.slice(1, -1);
22764
+ if (p.startsWith("file://")) {
22765
+ try {
22766
+ return fileURLToPath3(p).trim();
22767
+ } catch {
22768
+ p = p.slice("file://".length);
22769
+ try {
22770
+ p = decodeURIComponent(p);
22771
+ } catch {
22772
+ }
22773
+ return p.trim();
22774
+ }
22775
+ }
22776
+ p = p.replace(/\\(.)/g, "$1");
22777
+ return p.trim();
22778
+ }
22447
22779
  function extractImagesFromInput(input, cwd) {
22448
22780
  const images = [];
22449
22781
  const imgCmdMatch = IMG_CMD_REGEX.exec(input.trim());
22450
22782
  if (imgCmdMatch) {
22451
- const att = buildImageAttachment(imgCmdMatch[1], cwd);
22783
+ const att = buildImageAttachment(normalizeDroppedPath(imgCmdMatch[1]), cwd);
22452
22784
  if (att) images.push(att);
22453
22785
  return { text: "", images };
22454
22786
  }
22787
+ const EXT = "(?:png|jpe?g|gif|webp|svg|bmp)";
22788
+ const detector = new RegExp(
22789
+ "'([^']*\\." + EXT + `)'|"([^"]*\\.` + EXT + ')"|(file:\\/\\/\\S+?\\.' + EXT + `)|(?:^|\\s)((?:\\/|~\\/|\\.{1,2}\\/)(?:\\\\\\x20|[^\\s'"])*\\.` + EXT + ")",
22790
+ "gi"
22791
+ );
22455
22792
  let text = input;
22456
- const pathRegex = new RegExp(IMAGE_PATH_REGEX.source, "gi");
22457
22793
  let match;
22458
- const paths = [];
22459
- while ((match = pathRegex.exec(input)) !== null) {
22460
- const rawPath = match[1].trim();
22461
- const att = buildImageAttachment(rawPath, cwd);
22794
+ const hits = [];
22795
+ while ((match = detector.exec(input)) !== null) {
22796
+ const raw = match[1] ?? match[2] ?? match[3] ?? match[4];
22797
+ if (raw) hits.push({ raw, whole: match[0] });
22798
+ }
22799
+ for (const hit of hits) {
22800
+ const att = buildImageAttachment(normalizeDroppedPath(hit.raw), cwd);
22462
22801
  if (att) {
22463
22802
  images.push(att);
22464
- paths.push(match[0]);
22803
+ text = text.replace(hit.whole, "");
22465
22804
  }
22466
22805
  }
22467
- for (const p of paths) {
22468
- text = text.replace(p, "");
22806
+ if (images.length === 0) {
22807
+ const whole = normalizeDroppedPath(input);
22808
+ if (isImagePath(whole)) {
22809
+ const att = buildImageAttachment(whole, cwd);
22810
+ if (att) {
22811
+ images.push(att);
22812
+ text = "";
22813
+ }
22814
+ }
22469
22815
  }
22470
22816
  text = text.replace(/\s{2,}/g, " ").trim();
22471
22817
  return { text, images };
22472
22818
  }
22473
22819
 
22820
+ // ../core/src/generated/rooms/store.ts
22821
+ import { mkdirSync as mkdirSync18, existsSync as existsSync20, readFileSync as readFileSync23, writeFileSync as writeFileSync19, appendFileSync as appendFileSync2, readdirSync as readdirSync14, openSync, closeSync, unlinkSync as unlinkSync9, statSync as statSync16 } from "fs";
22822
+ import { join as join22 } from "path";
22823
+ var LOCK_TIMEOUT_MS = 2e3;
22824
+ var LOCK_STALE_MS = 5e3;
22825
+ function roomsDir() {
22826
+ return runtimeAgonPath("rooms");
22827
+ }
22828
+ function roomDir(roomId) {
22829
+ return join22(roomsDir(), roomId);
22830
+ }
22831
+ function eventsPath(roomId) {
22832
+ return join22(roomDir(roomId), "events.ndjson");
22833
+ }
22834
+ function metaPath(roomId) {
22835
+ return join22(roomDir(roomId), "room.json");
22836
+ }
22837
+ function slugifyRoomId(name) {
22838
+ const slug = String(name ?? "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
22839
+ return slug || "room";
22840
+ }
22841
+ function roomExists(roomId) {
22842
+ return existsSync20(metaPath(roomId));
22843
+ }
22844
+ function readMeta(roomId) {
22845
+ try {
22846
+ return JSON.parse(readFileSync23(metaPath(roomId), "utf-8"));
22847
+ } catch {
22848
+ return null;
22849
+ }
22850
+ }
22851
+ function writeMeta(meta3) {
22852
+ mkdirSync18(roomDir(meta3.roomId), { recursive: true });
22853
+ writeFileSync19(metaPath(meta3.roomId), JSON.stringify(meta3, null, 2) + "\n");
22854
+ }
22855
+ function createRoom(name) {
22856
+ const roomId = slugifyRoomId(name);
22857
+ const existing = readMeta(roomId);
22858
+ if (existing) return existing;
22859
+ mkdirSync18(roomDir(roomId), { recursive: true });
22860
+ const meta3 = {
22861
+ roomId,
22862
+ name: String(name ?? roomId),
22863
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
22864
+ nextSeq: 1,
22865
+ closed: false
22866
+ };
22867
+ writeMeta(meta3);
22868
+ if (!existsSync20(eventsPath(roomId))) writeFileSync19(eventsPath(roomId), "");
22869
+ return meta3;
22870
+ }
22871
+ function listRooms() {
22872
+ let ids;
22873
+ try {
22874
+ ids = readdirSync14(roomsDir());
22875
+ } catch {
22876
+ return [];
22877
+ }
22878
+ const out = [];
22879
+ for (const id of ids) {
22880
+ const meta3 = readMeta(id);
22881
+ if (meta3) out.push(meta3);
22882
+ }
22883
+ out.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
22884
+ return out;
22885
+ }
22886
+ function parseMentions(text) {
22887
+ const out = [];
22888
+ const re = /(?:^|[^\w@])@([a-z0-9][\w-]*)/gi;
22889
+ let m;
22890
+ while ((m = re.exec(String(text ?? ""))) !== null) {
22891
+ const tag = m[1].toLowerCase();
22892
+ if (!out.includes(tag)) out.push(tag);
22893
+ }
22894
+ return out;
22895
+ }
22896
+ function withRoomLock(roomId, work) {
22897
+ mkdirSync18(roomDir(roomId), { recursive: true });
22898
+ const lock = join22(roomDir(roomId), ".lock");
22899
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
22900
+ let fd = null;
22901
+ while (fd === null) {
22902
+ try {
22903
+ fd = openSync(lock, "wx");
22904
+ } catch (err) {
22905
+ if (err?.code !== "EEXIST") throw err;
22906
+ try {
22907
+ const st = statSync16(lock);
22908
+ if (Date.now() - st.mtimeMs > LOCK_STALE_MS) {
22909
+ unlinkSync9(lock);
22910
+ continue;
22911
+ }
22912
+ } catch {
22913
+ continue;
22914
+ }
22915
+ if (Date.now() > deadline) throw new Error(`room lock timeout: ${roomId}`);
22916
+ const spinUntil = Date.now() + 12;
22917
+ while (Date.now() < spinUntil) {
22918
+ }
22919
+ }
22920
+ }
22921
+ try {
22922
+ work();
22923
+ } finally {
22924
+ try {
22925
+ closeSync(fd);
22926
+ } catch {
22927
+ }
22928
+ try {
22929
+ unlinkSync9(lock);
22930
+ } catch {
22931
+ }
22932
+ }
22933
+ }
22934
+ function appendEvent(roomId, input) {
22935
+ let result = null;
22936
+ withRoomLock(roomId, () => {
22937
+ const meta3 = readMeta(roomId) ?? createRoom(roomId);
22938
+ const seq = meta3.nextSeq;
22939
+ const event = {
22940
+ seq,
22941
+ id: `evt_${Date.now().toString(36)}${Math.floor(Math.random() * 1e9).toString(36)}`,
22942
+ roomId,
22943
+ kind: input.kind,
22944
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
22945
+ actor: input.actor,
22946
+ repoHint: input.repoHint,
22947
+ body: input.body,
22948
+ mentions: input.mentions,
22949
+ replyTo: input.replyTo,
22950
+ auto: input.auto === true
22951
+ };
22952
+ appendFileSync2(eventsPath(roomId), JSON.stringify(event) + "\n");
22953
+ meta3.nextSeq = seq + 1;
22954
+ writeMeta(meta3);
22955
+ result = event;
22956
+ });
22957
+ if (!result) throw new Error(`appendEvent: lock produced no event for ${roomId}`);
22958
+ return result;
22959
+ }
22960
+ function readEvents(roomId, sinceSeq, limit) {
22961
+ let raw;
22962
+ try {
22963
+ raw = readFileSync23(eventsPath(roomId), "utf-8");
22964
+ } catch {
22965
+ return [];
22966
+ }
22967
+ const out = [];
22968
+ for (const line of raw.split("\n")) {
22969
+ if (!line.trim()) continue;
22970
+ try {
22971
+ const ev = JSON.parse(line);
22972
+ if (typeof ev.seq === "number" && ev.seq > sinceSeq) out.push(ev);
22973
+ } catch {
22974
+ }
22975
+ }
22976
+ if (limit > 0 && out.length > limit) return out.slice(out.length - limit);
22977
+ return out;
22978
+ }
22979
+ function closeRoom(roomId) {
22980
+ const meta3 = readMeta(roomId);
22981
+ if (!meta3) return;
22982
+ meta3.closed = true;
22983
+ writeMeta(meta3);
22984
+ }
22985
+ function isRoomClosed(roomId) {
22986
+ const meta3 = readMeta(roomId);
22987
+ return meta3 ? meta3.closed === true : false;
22988
+ }
22989
+
22990
+ // ../core/src/generated/rooms/presence.ts
22991
+ import { mkdirSync as mkdirSync19, readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "fs";
22992
+ import { join as join23 } from "path";
22993
+ var PRESENCE_TTL_MS = 9e4;
22994
+ function presencePath(roomId) {
22995
+ return join23(roomDir(roomId), "presence.json");
22996
+ }
22997
+ function readPresenceRaw(roomId) {
22998
+ try {
22999
+ return JSON.parse(readFileSync24(presencePath(roomId), "utf-8"));
23000
+ } catch {
23001
+ return {};
23002
+ }
23003
+ }
23004
+ function recordPresence(roomId, actor, lastReadSeq, auto) {
23005
+ mkdirSync19(roomDir(roomId), { recursive: true });
23006
+ const map2 = readPresenceRaw(roomId);
23007
+ map2[actor.callsign] = {
23008
+ callsign: actor.callsign,
23009
+ actorId: actor.actorId,
23010
+ status: "here",
23011
+ lastSeenAt: (/* @__PURE__ */ new Date()).toISOString(),
23012
+ lastReadSeq,
23013
+ auto,
23014
+ cli: actor.cli
23015
+ };
23016
+ writeFileSync20(presencePath(roomId), JSON.stringify(map2, null, 2) + "\n");
23017
+ }
23018
+ function removePresence(roomId, callsign) {
23019
+ const map2 = readPresenceRaw(roomId);
23020
+ if (!map2[callsign]) return;
23021
+ delete map2[callsign];
23022
+ try {
23023
+ writeFileSync20(presencePath(roomId), JSON.stringify(map2, null, 2) + "\n");
23024
+ } catch {
23025
+ }
23026
+ }
23027
+ function listPresence(roomId) {
23028
+ const map2 = readPresenceRaw(roomId);
23029
+ const now = Date.now();
23030
+ const out = [];
23031
+ for (const key of Object.keys(map2)) {
23032
+ const entry = map2[key];
23033
+ const age = now - new Date(entry.lastSeenAt).getTime();
23034
+ const status = !Number.isFinite(age) ? "left" : age <= PRESENCE_TTL_MS ? "here" : age <= PRESENCE_TTL_MS * 4 ? "stale" : "left";
23035
+ out.push({ ...entry, status });
23036
+ }
23037
+ out.sort((a, b) => a.callsign.localeCompare(b.callsign));
23038
+ return out;
23039
+ }
23040
+
23041
+ // ../core/src/generated/rooms/leases.ts
23042
+ import { readFileSync as readFileSync25, writeFileSync as writeFileSync21 } from "fs";
23043
+ import { join as join24 } from "path";
23044
+ function leasesPath(roomId) {
23045
+ return join24(roomDir(roomId), "leases.json");
23046
+ }
23047
+ function readActiveLease(roomId) {
23048
+ try {
23049
+ const raw = JSON.parse(readFileSync25(leasesPath(roomId), "utf-8"));
23050
+ if (!raw || !raw.leaseId) return null;
23051
+ if (Date.now() >= new Date(raw.expiresAt).getTime()) return null;
23052
+ return raw;
23053
+ } catch {
23054
+ return null;
23055
+ }
23056
+ }
23057
+ function acquireTurnLease(roomId, holder, triggerSeq, ttlMs) {
23058
+ let acquired = null;
23059
+ withRoomLock(roomId, () => {
23060
+ const active = readActiveLease(roomId);
23061
+ if (active && active.holder !== holder) return;
23062
+ const now = Date.now();
23063
+ const lease = {
23064
+ leaseId: `lease_${now.toString(36)}${Math.floor(Math.random() * 1e9).toString(36)}`,
23065
+ holder,
23066
+ triggerSeq,
23067
+ acquiredAt: new Date(now).toISOString(),
23068
+ expiresAt: new Date(now + Math.max(1e3, ttlMs)).toISOString()
23069
+ };
23070
+ writeFileSync21(leasesPath(roomId), JSON.stringify(lease, null, 2) + "\n");
23071
+ acquired = lease;
23072
+ });
23073
+ return acquired;
23074
+ }
23075
+ function releaseTurnLease(roomId, leaseId) {
23076
+ withRoomLock(roomId, () => {
23077
+ const active = readActiveLease(roomId);
23078
+ if (active && active.leaseId === leaseId) {
23079
+ try {
23080
+ writeFileSync21(leasesPath(roomId), JSON.stringify(null) + "\n");
23081
+ } catch {
23082
+ }
23083
+ }
23084
+ });
23085
+ }
23086
+
23087
+ // ../core/src/generated/rooms/auto-policy.ts
23088
+ function detectTrigger(events, myCallsign, openFloor, quietMs) {
23089
+ if (!Array.isArray(events) || events.length === 0) return { trigger: false, triggerSeq: 0, reason: "no-events" };
23090
+ for (let i = events.length - 1; i >= 0; i--) {
23091
+ const ev = events[i];
23092
+ if (ev.kind !== "post") continue;
23093
+ if (ev.actor.callsign === myCallsign) return { trigger: false, triggerSeq: 0, reason: "self-latest" };
23094
+ if (Array.isArray(ev.mentions) && ev.mentions.includes(myCallsign)) {
23095
+ return { trigger: true, triggerSeq: ev.seq, reason: "mentioned" };
23096
+ }
23097
+ if (openFloor) {
23098
+ const ageMs = Date.now() - new Date(ev.createdAt).getTime();
23099
+ if (ageMs >= quietMs) return { trigger: true, triggerSeq: ev.seq, reason: "open-floor" };
23100
+ return { trigger: false, triggerSeq: 0, reason: "waiting-quiet" };
23101
+ }
23102
+ return { trigger: false, triggerSeq: 0, reason: "not-mentioned" };
23103
+ }
23104
+ return { trigger: false, triggerSeq: 0, reason: "no-posts" };
23105
+ }
23106
+ function detectPingPong(events) {
23107
+ const posts = events.filter((e) => e.kind === "post").slice(-4);
23108
+ if (posts.length < 4) return false;
23109
+ if (!posts.every((p) => p.auto === true)) return false;
23110
+ const a = posts[0].actor.callsign;
23111
+ const b = posts[1].actor.callsign;
23112
+ if (a === b) return false;
23113
+ return posts[2].actor.callsign === a && posts[3].actor.callsign === b;
23114
+ }
23115
+ function evaluateStop(state, config2, events) {
23116
+ if (state.turns >= config2.maxTurns) return { stop: true, reason: `max-turns (${config2.maxTurns})` };
23117
+ if (Date.now() - state.startedAtMs >= config2.maxWallMs) return { stop: true, reason: "max-wall-time" };
23118
+ if (detectPingPong(events)) return { stop: true, reason: "ping-pong-halt" };
23119
+ if (config2.untilHuman && state.turns >= 1) {
23120
+ const human = events.find((e) => e.kind === "post" && e.auto !== true && e.actor.callsign !== config2.callsign && e.seq > state.lastSelfSeq);
23121
+ if (human) return { stop: true, reason: "human-replied" };
23122
+ }
23123
+ if (config2.stopPhrase) {
23124
+ const needle = config2.stopPhrase.toLowerCase();
23125
+ const hit = events.find((e) => e.kind === "post" && e.actor.callsign !== config2.callsign && e.body.toLowerCase().includes(needle));
23126
+ if (hit) return { stop: true, reason: "stop-phrase" };
23127
+ }
23128
+ return { stop: false, reason: "" };
23129
+ }
23130
+
22474
23131
  // ../core/src/generated/signals/flow.ts
22475
- import { readFileSync as readFileSync23, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18, readdirSync as readdirSync14 } from "fs";
22476
- import { join as join22, resolve as resolve20 } from "path";
23132
+ import { readFileSync as readFileSync26, writeFileSync as writeFileSync22, mkdirSync as mkdirSync20, readdirSync as readdirSync15 } from "fs";
23133
+ import { join as join25, resolve as resolve20 } from "path";
22477
23134
  import { homedir as homedir12 } from "os";
22478
23135
  function getFlowsDir() {
22479
23136
  const override = process.env.AGON_HOME?.trim();
22480
- const home = override ? resolve20(override) : join22(homedir12(), ".agon");
22481
- return join22(home, "flows");
23137
+ const home = override ? resolve20(override) : join25(homedir12(), ".agon");
23138
+ return join25(home, "flows");
22482
23139
  }
22483
23140
  var FLOWS_DIR = getFlowsDir();
22484
23141
  var FRICTION_TAGS = ["slow", "wrong-mode", "engine-error", "unclear-output", "timeout", "context-lost", "other"];
22485
23142
  function ensureFlowsDir() {
22486
- mkdirSync18(getFlowsDir(), { recursive: true });
23143
+ mkdirSync20(getFlowsDir(), { recursive: true });
22487
23144
  }
22488
23145
  function logFlow(record2) {
22489
23146
  ensureFlowsDir();
22490
23147
  const filename = `flow-${record2.id}.json`;
22491
- const filepath = join22(getFlowsDir(), filename);
22492
- writeFileSync19(filepath, JSON.stringify(record2, null, 2));
23148
+ const filepath = join25(getFlowsDir(), filename);
23149
+ writeFileSync22(filepath, JSON.stringify(record2, null, 2));
22493
23150
  return filepath;
22494
23151
  }
22495
23152
  function readFlows(limit) {
22496
23153
  ensureFlowsDir();
22497
23154
  let files;
22498
23155
  try {
22499
- files = readdirSync14(getFlowsDir()).filter((f) => f.startsWith("flow-") && f.endsWith(".json")).sort().reverse();
23156
+ files = readdirSync15(getFlowsDir()).filter((f) => f.startsWith("flow-") && f.endsWith(".json")).sort().reverse();
22500
23157
  } catch (err) {
22501
23158
  console.warn(`[agon] failed to read flows directory: ${err instanceof Error ? err.message : String(err)}`);
22502
23159
  return [];
@@ -22505,7 +23162,7 @@ function readFlows(limit) {
22505
23162
  const records = [];
22506
23163
  for (const file2 of files) {
22507
23164
  try {
22508
- const data = JSON.parse(readFileSync23(join22(getFlowsDir(), file2), "utf-8"));
23165
+ const data = JSON.parse(readFileSync26(join25(getFlowsDir(), file2), "utf-8"));
22509
23166
  records.push(data);
22510
23167
  } catch (err) {
22511
23168
  console.warn(`[agon] skipping malformed flow record ${file2}: ${err instanceof Error ? err.message : String(err)}`);
@@ -22934,19 +23591,19 @@ async function companionDispatch(opts) {
22934
23591
  }
22935
23592
 
22936
23593
  // ../core/src/generated/signals/models-registry.ts
22937
- import { readFileSync as readFileSync24, writeFileSync as writeFileSync20, mkdirSync as mkdirSync19, existsSync as existsSync20, statSync as statSync16 } from "fs";
22938
- import { join as join23 } from "path";
23594
+ import { readFileSync as readFileSync27, writeFileSync as writeFileSync23, mkdirSync as mkdirSync21, existsSync as existsSync22, statSync as statSync17 } from "fs";
23595
+ import { join as join26 } from "path";
22939
23596
  var CACHE_TTL_MS = 36e5;
22940
23597
  var MODELS_DEV_URL = "https://models.dev/api.json";
22941
23598
  async function fetchModelsRegistry() {
22942
23599
  const cacheDir = getCacheDir();
22943
- const cacheFile = join23(cacheDir, "models-dev.json");
22944
- if (existsSync20(cacheFile)) {
23600
+ const cacheFile = join26(cacheDir, "models-dev.json");
23601
+ if (existsSync22(cacheFile)) {
22945
23602
  try {
22946
- const stat = statSync16(cacheFile);
23603
+ const stat = statSync17(cacheFile);
22947
23604
  const age = Date.now() - stat.mtimeMs;
22948
23605
  if (age < CACHE_TTL_MS) {
22949
- return JSON.parse(readFileSync24(cacheFile, "utf-8"));
23606
+ return JSON.parse(readFileSync27(cacheFile, "utf-8"));
22950
23607
  }
22951
23608
  } catch (_e) {
22952
23609
  console.warn(`[agon] models-registry: cache read failed, refetching: ${_e instanceof Error ? _e.message : String(_e)}`);
@@ -22954,14 +23611,14 @@ async function fetchModelsRegistry() {
22954
23611
  }
22955
23612
  const response = await fetch(MODELS_DEV_URL);
22956
23613
  if (!response.ok) {
22957
- if (existsSync20(cacheFile)) {
22958
- return JSON.parse(readFileSync24(cacheFile, "utf-8"));
23614
+ if (existsSync22(cacheFile)) {
23615
+ return JSON.parse(readFileSync27(cacheFile, "utf-8"));
22959
23616
  }
22960
23617
  throw new Error(`Failed to fetch models registry: ${response.status}`);
22961
23618
  }
22962
23619
  const data = await response.json();
22963
- mkdirSync19(cacheDir, { recursive: true });
22964
- writeFileSync20(cacheFile, JSON.stringify(data));
23620
+ mkdirSync21(cacheDir, { recursive: true });
23621
+ writeFileSync23(cacheFile, JSON.stringify(data));
22965
23622
  return data;
22966
23623
  }
22967
23624
  function resolveModelFormat(providerNpm, model) {
@@ -23082,24 +23739,24 @@ function modelEntryToEngineDef(entry) {
23082
23739
 
23083
23740
  // ../core/src/generated/signals/cli-models-registry.ts
23084
23741
  import { execSync as execSync4 } from "child_process";
23085
- import { readFileSync as readFileSync25, writeFileSync as writeFileSync21, mkdirSync as mkdirSync20, existsSync as existsSync21, statSync as statSync17 } from "fs";
23086
- import { join as join24 } from "path";
23742
+ import { readFileSync as readFileSync28, writeFileSync as writeFileSync24, mkdirSync as mkdirSync22, existsSync as existsSync23, statSync as statSync18 } from "fs";
23743
+ import { join as join27 } from "path";
23087
23744
  import { homedir as homedir13 } from "os";
23088
- import { createRequire as createRequire3 } from "module";
23745
+ import { createRequire as createRequire4 } from "module";
23089
23746
  var ENGINE_PROVIDER_MAP = { anthropic: { providerId: "anthropic", engineId: "claude", engineBinary: "claude", versionCmd: ["--version"], listCmd: ["__pty:/model"], effortLevels: ["low", "medium", "high", "xhigh", "max"] }, openai: { providerId: "openai", engineId: "codex", engineBinary: "codex", versionCmd: ["--version"], listCmd: ["__pty:/model"], effortLevels: ["low", "medium", "high", "xhigh"] }, google: { providerId: "google", engineId: "agy", engineBinary: "agy", versionCmd: ["--version"], listCmd: ["__pty:/model"] }, opencode: { providerId: "opencode", engineId: "opencode", engineBinary: "opencode", versionCmd: ["--version"], listCmd: ["models"] }, mistral: { providerId: "mistral", engineId: "mistral", engineBinary: "mistral", versionCmd: ["--version"] }, openrouter: { providerId: "openrouter", engineId: "openrouter", engineBinary: "openrouter", versionCmd: [] } };
23090
23747
  var ENGINE_DISPLAY_NAMES = { claude: "Claude", codex: "Codex", agy: "Antigravity", opencode: "OpenCode", mistral: "Mistral", openrouter: "OpenRouter" };
23091
23748
  var FALLBACK_MODELS = { anthropic: [{ id: "claude-sonnet-4-5-20250929", name: "Claude Sonnet 4.5", contextWindow: 2e5, toolCall: true, reasoning: true }, { id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5", contextWindow: 2e5, toolCall: true, reasoning: true }], openai: [{ id: "gpt-4o", name: "GPT-4o", contextWindow: 128e3, toolCall: true, reasoning: false }, { id: "o4-mini", name: "o4-mini", contextWindow: 2e5, toolCall: true, reasoning: true }], google: [{ id: "gemini-3.5-flash", name: "Gemini 3.5 Flash", contextWindow: 1048576, toolCall: true, reasoning: true }, { id: "gemini-3.1-pro", name: "Gemini 3.1 Pro", contextWindow: 1048576, toolCall: true, reasoning: true }, { id: "gemini-3-flash-preview", name: "Gemini 3 Flash", contextWindow: 1048576, toolCall: true, reasoning: true }], mistral: [{ id: "mistral-large-latest", name: "Mistral Large", contextWindow: 128e3, toolCall: true, reasoning: false }, { id: "codestral-latest", name: "Codestral", contextWindow: 256e3, toolCall: true, reasoning: false }], openrouter: [{ id: "auto", name: "Auto (best for task)", toolCall: true, reasoning: false }], opencode: [{ id: "anthropic/claude-sonnet-4", name: "anthropic/claude-sonnet-4", toolCall: true, reasoning: false }, { id: "openai/gpt-5.3-codex", name: "openai/gpt-5.3-codex", toolCall: true, reasoning: false }] };
23092
23749
  var PROBE_TTL_MS = 864e5;
23093
23750
  function probedModelsCacheFile(engineId) {
23094
- return join24(getCacheDir(), `cli-models-${engineId.replace(/[^a-zA-Z0-9_-]/g, "-")}.json`);
23751
+ return join27(getCacheDir(), `cli-models-${engineId.replace(/[^a-zA-Z0-9_-]/g, "-")}.json`);
23095
23752
  }
23096
23753
  function readProbedCliModels(engineId, ttlMs) {
23097
23754
  try {
23098
23755
  const file2 = probedModelsCacheFile(engineId);
23099
- if (!existsSync21(file2)) return null;
23100
- const age = Date.now() - statSync17(file2).mtimeMs;
23756
+ if (!existsSync23(file2)) return null;
23757
+ const age = Date.now() - statSync18(file2).mtimeMs;
23101
23758
  if (age > (ttlMs ?? PROBE_TTL_MS)) return null;
23102
- const data = JSON.parse(readFileSync25(file2, "utf-8"));
23759
+ const data = JSON.parse(readFileSync28(file2, "utf-8"));
23103
23760
  const raw = Array.isArray(data?.models) ? data.models : [];
23104
23761
  const models = raw.map((m) => ({ id: String(m.id ?? ""), name: String(m.name ?? m.id ?? ""), current: !!m.current })).filter((m) => m.name);
23105
23762
  return models.length > 0 ? models : null;
@@ -23109,7 +23766,7 @@ function readProbedCliModels(engineId, ttlMs) {
23109
23766
  }
23110
23767
  function resolveModelProbeScript() {
23111
23768
  try {
23112
- const req = createRequire3(import.meta.url);
23769
+ const req = createRequire4(import.meta.url);
23113
23770
  const anchor = req.resolve("@kernlang/agon-engines/cli/claude.js");
23114
23771
  const candidates = [
23115
23772
  // Canonical: the package ships the probe at py/kern_engines/cli/ (see
@@ -23117,16 +23774,16 @@ function resolveModelProbeScript() {
23117
23774
  // to the package root, then into py/. This is the path that actually
23118
23775
  // exists — the dist/cli & root/cli guesses below never matched, so the
23119
23776
  // probe silently never ran and every engine fell back to its static list.
23120
- join24(anchor, "..", "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23777
+ join27(anchor, "..", "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23121
23778
  // dist/cli → root → py/kern_engines/cli
23122
- join24(anchor, "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23779
+ join27(anchor, "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23123
23780
  // (alt layout: cli/claude.js → root)
23124
- join24(anchor, "..", "..", "..", "cli", "model_probe.py"),
23125
- join24(anchor, "..", "..", "cli", "model_probe.py"),
23126
- join24(anchor, "..", "model_probe.py")
23781
+ join27(anchor, "..", "..", "..", "cli", "model_probe.py"),
23782
+ join27(anchor, "..", "..", "cli", "model_probe.py"),
23783
+ join27(anchor, "..", "model_probe.py")
23127
23784
  ];
23128
23785
  for (const c of candidates) {
23129
- if (existsSync21(c)) return c;
23786
+ if (existsSync23(c)) return c;
23130
23787
  }
23131
23788
  return null;
23132
23789
  } catch {
@@ -23196,8 +23853,8 @@ async function refreshProbedCliModels(engineId, binary, listCmd, pythonBin) {
23196
23853
  return false;
23197
23854
  }
23198
23855
  const dir = getCacheDir();
23199
- mkdirSync20(dir, { recursive: true });
23200
- writeFileSync21(probedModelsCacheFile(engineId), JSON.stringify({ ts: Date.now(), engineId, models }));
23856
+ mkdirSync22(dir, { recursive: true });
23857
+ writeFileSync24(probedModelsCacheFile(engineId), JSON.stringify({ ts: Date.now(), engineId, models }));
23201
23858
  return true;
23202
23859
  } catch (e) {
23203
23860
  dbg(`probe threw: ${e?.message ?? e}`);
@@ -23213,10 +23870,10 @@ function findBinary(binary) {
23213
23870
  } catch (e) {
23214
23871
  }
23215
23872
  const home = homedir13();
23216
- const searchPaths = [join24(home, ".local", "bin"), join24(home, ".npm-global", "bin"), "/usr/local/bin"];
23873
+ const searchPaths = [join27(home, ".local", "bin"), join27(home, ".npm-global", "bin"), "/usr/local/bin"];
23217
23874
  for (const dir of searchPaths) {
23218
- const fullPath = join24(dir, binary);
23219
- if (existsSync21(fullPath)) {
23875
+ const fullPath = join27(dir, binary);
23876
+ if (existsSync23(fullPath)) {
23220
23877
  return fullPath;
23221
23878
  }
23222
23879
  }
@@ -24382,7 +25039,7 @@ function createResumeSession(config2) {
24382
25039
  }
24383
25040
  return 50;
24384
25041
  };
24385
- const estimateTokens2 = (msgs) => msgs.reduce((sum, m) => {
25042
+ const estimateTokens3 = (msgs) => msgs.reduce((sum, m) => {
24386
25043
  if (m._tokenEstimate === void 0) {
24387
25044
  m._tokenEstimate = estimateSingle(m);
24388
25045
  }
@@ -24403,7 +25060,7 @@ function createResumeSession(config2) {
24403
25060
  })();
24404
25061
  const COMPACTION_BUFFER = Math.max(2e4, Math.round(CONTEXT_LIMIT * 0.15));
24405
25062
  const PRUNE_PROTECT_TURNS = 6;
24406
- const totalTokens = estimateTokens2(messageHistory);
25063
+ const totalTokens = estimateTokens3(messageHistory);
24407
25064
  if (totalTokens > CONTEXT_LIMIT - COMPACTION_BUFFER) {
24408
25065
  const hasSystem = messageHistory[0].role === "system";
24409
25066
  const startIdx = hasSystem ? 1 : 0;
@@ -24430,7 +25087,7 @@ function createResumeSession(config2) {
24430
25087
  delete msg._tokenEstimate;
24431
25088
  }
24432
25089
  }
24433
- const afterTier1 = estimateTokens2(messageHistory);
25090
+ const afterTier1 = estimateTokens3(messageHistory);
24434
25091
  if (afterTier1 > CONTEXT_LIMIT - COMPACTION_BUFFER) {
24435
25092
  const old = messageHistory.slice(startIdx, protectFrom);
24436
25093
  const recent = messageHistory.slice(protectFrom);
@@ -24529,11 +25186,11 @@ ${newSummary.decisions.map((d) => ` - ${d}`).join("\n")}` : "",
24529
25186
  }
24530
25187
  }
24531
25188
  }
24532
- const afterTier2 = estimateTokens2(messageHistory);
25189
+ const afterTier2 = estimateTokens3(messageHistory);
24533
25190
  const tier3CompactionEnabled = process.env.AGON_DISABLE_TIER3_COMPACTION !== "1";
24534
25191
  if (tier3CompactionEnabled && afterTier2 > CONTEXT_LIMIT - COMPACTION_BUFFER && config2.engine.api) {
24535
25192
  try {
24536
- const { apiDispatch: apiDispatch2 } = await import("./dispatch-6LQSMMGI.js");
25193
+ const { apiDispatch: apiDispatch2 } = await import("./dispatch-XHLJ44TF.js");
24537
25194
  const compactionPrompt = `Summarize this conversation context into a concise briefing. Preserve: the user's goal, key discoveries, files read/modified, important decisions, and current progress. Drop: verbose tool outputs, repeated attempts, and pleasantries.
24538
25195
 
24539
25196
  CONTEXT TO SUMMARIZE:
@@ -24553,7 +25210,7 @@ ${newSummary.decisions.map((d) => ` - ${d}`).join("\n")}` : "",
24553
25210
  ${compactionResult.stdout}` },
24554
25211
  ...protectedRecent
24555
25212
  );
24556
- console.log(`[agon] Tier 3 LLM compaction fired: ${afterTier2} \u2192 ${estimateTokens2(messageHistory)} tokens`);
25213
+ console.log(`[agon] Tier 3 LLM compaction fired: ${afterTier2} \u2192 ${estimateTokens3(messageHistory)} tokens`);
24557
25214
  }
24558
25215
  } catch (tier3Err) {
24559
25216
  console.warn(`[agon] Tier 3 compaction failed (non-fatal): ${tier3Err instanceof Error ? tier3Err.message : String(tier3Err)}`);
@@ -24571,7 +25228,7 @@ ${compactionResult.stdout}` },
24571
25228
  toolCacheManifest = toolCacheManifest.filter((e) => activeIds.has(e.toolCallId));
24572
25229
  }
24573
25230
  {
24574
- const ctxTokens = totalTokens <= CONTEXT_LIMIT - COMPACTION_BUFFER ? totalTokens : estimateTokens2(messageHistory);
25231
+ const ctxTokens = totalTokens <= CONTEXT_LIMIT - COMPACTION_BUFFER ? totalTokens : estimateTokens3(messageHistory);
24575
25232
  const ctxPct = Math.round(ctxTokens / CONTEXT_LIMIT * 100);
24576
25233
  const cachedCount = toolCacheManifest.length;
24577
25234
  const compactedCount = compactionSummary?.messagesCompacted ?? 0;
@@ -25311,8 +25968,8 @@ function createStreamBridge(dispatch, opts) {
25311
25968
  }
25312
25969
 
25313
25970
  // ../core/src/generated/forge/virtual-fs.ts
25314
- import { readFileSync as readFileSync26, existsSync as existsSync22, readdirSync as readdirSync15, statSync as statSync18 } from "fs";
25315
- import { join as join25, resolve as resolve21, relative as relative8, dirname as dirname11 } from "path";
25971
+ import { readFileSync as readFileSync29, existsSync as existsSync24, readdirSync as readdirSync16, statSync as statSync19 } from "fs";
25972
+ import { join as join28, resolve as resolve21, relative as relative8, dirname as dirname12 } from "path";
25316
25973
  import { createHash as createHash5 } from "crypto";
25317
25974
  function createFileSnapshot(rootDir) {
25318
25975
  const snapshotId = createHash5("sha256").update(rootDir + Date.now().toString()).digest("hex").slice(0, 12);
@@ -25328,16 +25985,16 @@ function snapshotRead(snap, absPath) {
25328
25985
  return snap.cache.get(key) ?? null;
25329
25986
  }
25330
25987
  try {
25331
- if (!existsSync22(key)) {
25988
+ if (!existsSync24(key)) {
25332
25989
  snap.cache.set(key, null);
25333
25990
  return null;
25334
25991
  }
25335
- const st = statSync18(key);
25992
+ const st = statSync19(key);
25336
25993
  if (!st.isFile()) {
25337
25994
  snap.cache.set(key, null);
25338
25995
  return null;
25339
25996
  }
25340
- const content = readFileSync26(key, "utf-8");
25997
+ const content = readFileSync29(key, "utf-8");
25341
25998
  snap.cache.set(key, content);
25342
25999
  return content;
25343
26000
  } catch (e) {
@@ -25348,13 +26005,13 @@ function snapshotRead(snap, absPath) {
25348
26005
  function snapshotList(snap, absDir) {
25349
26006
  const dir = resolve21(absDir);
25350
26007
  try {
25351
- return readdirSync15(dir).filter((f) => {
26008
+ return readdirSync16(dir).filter((f) => {
25352
26009
  try {
25353
- return statSync18(join25(dir, f)).isFile();
26010
+ return statSync19(join28(dir, f)).isFile();
25354
26011
  } catch {
25355
26012
  return false;
25356
26013
  }
25357
- }).map((f) => join25(dir, f));
26014
+ }).map((f) => join28(dir, f));
25358
26015
  } catch {
25359
26016
  return [];
25360
26017
  }
@@ -25420,7 +26077,7 @@ var VirtualFS = class {
25420
26077
  const overlayWritten = [];
25421
26078
  const overlayDeleted = /* @__PURE__ */ new Set();
25422
26079
  for (const [path, content] of this.overlay.entries()) {
25423
- if (dirname11(path) === dir) {
26080
+ if (dirname12(path) === dir) {
25424
26081
  if (content === null) {
25425
26082
  overlayDeleted.add(path);
25426
26083
  } else {
@@ -25479,7 +26136,7 @@ function applyEffectPackage(pkg, targetDir) {
25479
26136
  for (const effect of pkg.effects) {
25480
26137
  const absPath = resolve21(targetDir, effect.kind === "rename" ? effect.from : effect.path);
25481
26138
  if (effect.kind === "write") {
25482
- const dir = dirname11(absPath);
26139
+ const dir = dirname12(absPath);
25483
26140
  import_fs.mkdirSync(dir, { recursive: true });
25484
26141
  import_fs.writeFileSync(absPath, effect.content, "utf-8");
25485
26142
  modified.push(absPath);
@@ -25491,7 +26148,7 @@ function applyEffectPackage(pkg, targetDir) {
25491
26148
  modified.push(absPath);
25492
26149
  } else if (effect.kind === "rename") {
25493
26150
  const dest = resolve21(targetDir, effect.to);
25494
- import_fs.mkdirSync(dirname11(dest), { recursive: true });
26151
+ import_fs.mkdirSync(dirname12(dest), { recursive: true });
25495
26152
  import_fs.renameSync(absPath, dest);
25496
26153
  modified.push(absPath);
25497
26154
  modified.push(dest);
@@ -25569,7 +26226,7 @@ function scoreEffectPackage(pkg, taskKeywords) {
25569
26226
 
25570
26227
  // ../core/src/generated/cesar/speculator.ts
25571
26228
  import { randomUUID as randomUUID4 } from "crypto";
25572
- import { resolve as resolve22, join as join26 } from "path";
26229
+ import { resolve as resolve22, join as join29 } from "path";
25573
26230
  var Speculator = class {
25574
26231
  runId;
25575
26232
  snapshot;
@@ -25591,7 +26248,7 @@ var Speculator = class {
25591
26248
  if (isolate) {
25592
26249
  const baseSha = stashSnapshot(root);
25593
26250
  for (const member of opts.members) {
25594
- const wtPath = join26(root, `.agon/speculate-worktrees/${this.runId}/${member.engineId}`);
26251
+ const wtPath = join29(root, `.agon/speculate-worktrees/${this.runId}/${member.engineId}`);
25595
26252
  try {
25596
26253
  await worktreeCreate(root, wtPath, baseSha);
25597
26254
  worktreesByEngine[member.engineId] = wtPath;
@@ -25764,17 +26421,17 @@ ${sessionLines.join("\n")}`);
25764
26421
  }
25765
26422
 
25766
26423
  // ../core/src/generated/cesar/context-thread.ts
25767
- import { readFileSync as readFileSync27, writeFileSync as writeFileSync22, mkdirSync as mkdirSync21, renameSync as renameSync11, existsSync as existsSync23, readdirSync as readdirSync16, unlinkSync as unlinkSync9, statSync as statSync19, chmodSync as chmodSync2, openSync, fsyncSync, closeSync, appendFileSync as appendFileSync2 } from "fs";
25768
- import { join as join27, resolve as resolve23, basename as basename6 } from "path";
26424
+ import { readFileSync as readFileSync30, writeFileSync as writeFileSync25, mkdirSync as mkdirSync23, renameSync as renameSync11, existsSync as existsSync25, readdirSync as readdirSync17, unlinkSync as unlinkSync10, statSync as statSync20, chmodSync as chmodSync2, openSync as openSync2, fsyncSync, closeSync as closeSync2, appendFileSync as appendFileSync3 } from "fs";
26425
+ import { join as join30, resolve as resolve23, basename as basename6 } from "path";
25769
26426
  import { randomUUID as randomUUID5, createHash as createHash6 } from "crypto";
25770
26427
  import { homedir as homedir14 } from "os";
25771
26428
  function threadsDir() {
25772
26429
  const override = process.env.AGON_HOME?.trim();
25773
- const home = override ? resolve23(override) : join27(homedir14(), ".agon");
25774
- return join27(home, "threads");
26430
+ const home = override ? resolve23(override) : join30(homedir14(), ".agon");
26431
+ return join30(home, "threads");
25775
26432
  }
25776
26433
  function activePointerPath() {
25777
- return join27(threadsDir(), "active.json");
26434
+ return join30(threadsDir(), "active.json");
25778
26435
  }
25779
26436
  function projectHash16(projectPath) {
25780
26437
  return createHash6("sha256").update(projectPath).digest("hex").slice(0, 16);
@@ -25783,7 +26440,7 @@ function projectSha8(projectPath) {
25783
26440
  return projectHash16(projectPath);
25784
26441
  }
25785
26442
  function threadDirFor(projectPath) {
25786
- return join27(threadsDir(), projectHash16(projectPath));
26443
+ return join30(threadsDir(), projectHash16(projectPath));
25787
26444
  }
25788
26445
  var THREAD_ID_RE = /^(thread_\d{10,16}_[0-9a-f]{8}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;
25789
26446
  function threadJournalPath(projectPath, threadId) {
@@ -25796,7 +26453,7 @@ function threadFilePath(projectPath, threadId) {
25796
26453
  const dir = threadDirFor(projectPath);
25797
26454
  const full = resolve23(dir, `${threadId}.json`);
25798
26455
  const resolvedDir = resolve23(dir);
25799
- const nativeSep = join27("a", "b")[1];
26456
+ const nativeSep = join30("a", "b")[1];
25800
26457
  const isContained = full === resolvedDir || full.startsWith(resolvedDir + "/") || full.startsWith(resolvedDir + nativeSep);
25801
26458
  if (!isContained) {
25802
26459
  throw new Error(`Invalid thread path (traversal attempt): ${threadId}`);
@@ -25805,7 +26462,7 @@ function threadFilePath(projectPath, threadId) {
25805
26462
  }
25806
26463
  function ensureThreadDir(projectPath) {
25807
26464
  ensureAgonHome();
25808
- mkdirSync21(threadDirFor(projectPath), { recursive: true });
26465
+ mkdirSync23(threadDirFor(projectPath), { recursive: true });
25809
26466
  }
25810
26467
  var LOCK_MAX_RETRIES = 8;
25811
26468
  var LOCK_BASE_DELAY_MS = 20;
@@ -25815,9 +26472,9 @@ function threadLockPath(projectPath, threadId) {
25815
26472
  async function acquireLock(lockPath) {
25816
26473
  for (let attempt = 0; attempt < LOCK_MAX_RETRIES; attempt++) {
25817
26474
  try {
25818
- const fd = openSync(lockPath, "wx", 384);
25819
- writeFileSync22(fd, String(process.pid));
25820
- closeSync(fd);
26475
+ const fd = openSync2(lockPath, "wx", 384);
26476
+ writeFileSync25(fd, String(process.pid));
26477
+ closeSync2(fd);
25821
26478
  return attempt;
25822
26479
  } catch (err) {
25823
26480
  if (err?.code !== "EEXIST") throw err;
@@ -25829,7 +26486,7 @@ async function acquireLock(lockPath) {
25829
26486
  }
25830
26487
  function releaseLock(lockPath) {
25831
26488
  try {
25832
- unlinkSync9(lockPath);
26489
+ unlinkSync10(lockPath);
25833
26490
  } catch {
25834
26491
  }
25835
26492
  }
@@ -25989,14 +26646,14 @@ var ContextThread = class {
25989
26646
  const now = Date.now();
25990
26647
  if (config2.threadId) {
25991
26648
  const candidatePath = threadFilePath(this.projectPath, config2.threadId);
25992
- if (existsSync23(candidatePath)) {
26649
+ if (existsSync25(candidatePath)) {
25993
26650
  try {
25994
- const stat = statSync19(candidatePath);
26651
+ const stat = statSync20(candidatePath);
25995
26652
  if (stat.size > MAX_THREAD_FILE_BYTES) {
25996
26653
  console.warn(`[agon] context-thread: ${candidatePath} is ${stat.size} bytes (> ${MAX_THREAD_FILE_BYTES}), refusing to load. Run /thread compact or /thread fork.`);
25997
26654
  throw new Error("thread file too large");
25998
26655
  }
25999
- const raw = readFileSync27(candidatePath, "utf-8");
26656
+ const raw = readFileSync30(candidatePath, "utf-8");
26000
26657
  const snap = JSON.parse(raw);
26001
26658
  if (snap && typeof snap === "object" && Array.isArray(snap.messages)) {
26002
26659
  const filteredMessages = (snap.messages ?? []).filter((m) => m && m.role !== "system");
@@ -26014,9 +26671,9 @@ var ContextThread = class {
26014
26671
  this.fileTouches = snap.fileTouches ?? {};
26015
26672
  this.hydrated = true;
26016
26673
  const jPathOnLoad = threadFilePath(this.projectPath, this.threadId).replace(/\.json$/, ".journal.jsonl");
26017
- if (existsSync23(jPathOnLoad)) {
26674
+ if (existsSync25(jPathOnLoad)) {
26018
26675
  try {
26019
- const journalLines = readFileSync27(jPathOnLoad, "utf-8").split("\n").filter(Boolean);
26676
+ const journalLines = readFileSync30(jPathOnLoad, "utf-8").split("\n").filter(Boolean);
26020
26677
  const knownOnLoad = new Set(this.messages.map((m) => m.id));
26021
26678
  let merged = false;
26022
26679
  for (const line of journalLines) {
@@ -26100,7 +26757,7 @@ var ContextThread = class {
26100
26757
  ensureThreadDir(this.projectPath);
26101
26758
  const jPath = threadJournalPath(this.projectPath, this.threadId);
26102
26759
  const line = JSON.stringify({ _kind: "msg", ...msg }) + "\n";
26103
- appendFileSync2(jPath, line, { encoding: "utf-8", mode: 384, flag: "a" });
26760
+ appendFileSync3(jPath, line, { encoding: "utf-8", mode: 384, flag: "a" });
26104
26761
  this.journaledIds.add(msg.id);
26105
26762
  } catch {
26106
26763
  }
@@ -26286,8 +26943,8 @@ ${msg.content}` };
26286
26943
  let bytes = 0;
26287
26944
  try {
26288
26945
  const path = threadFilePath(this.projectPath, this.threadId);
26289
- if (existsSync23(path)) {
26290
- bytes = readFileSync27(path, "utf-8").length;
26946
+ if (existsSync25(path)) {
26947
+ bytes = readFileSync30(path, "utf-8").length;
26291
26948
  }
26292
26949
  } catch {
26293
26950
  }
@@ -26319,12 +26976,12 @@ ${msg.content}` };
26319
26976
  const tmpPath = target + ".tmp";
26320
26977
  let fd = -1;
26321
26978
  try {
26322
- fd = openSync(tmpPath, "w", 384);
26323
- writeFileSync22(fd, body, "utf-8");
26979
+ fd = openSync2(tmpPath, "w", 384);
26980
+ writeFileSync25(fd, body, "utf-8");
26324
26981
  fsyncSync(fd);
26325
26982
  } finally {
26326
26983
  if (fd >= 0) try {
26327
- closeSync(fd);
26984
+ closeSync2(fd);
26328
26985
  } catch {
26329
26986
  }
26330
26987
  }
@@ -26336,7 +26993,7 @@ ${msg.content}` };
26336
26993
  this.dirty = false;
26337
26994
  this.hydrated = true;
26338
26995
  const jPath = threadJournalPath(this.projectPath, this.threadId);
26339
- if (existsSync23(jPath)) unlinkSync9(jPath);
26996
+ if (existsSync25(jPath)) unlinkSync10(jPath);
26340
26997
  this.journaledIds.clear();
26341
26998
  } catch {
26342
26999
  }
@@ -26368,9 +27025,9 @@ ${msg.content}` };
26368
27025
  }
26369
27026
  try {
26370
27027
  const jPath = threadJournalPath(this.projectPath, this.threadId);
26371
- if (existsSync23(jPath)) {
27028
+ if (existsSync25(jPath)) {
26372
27029
  try {
26373
- const journalLines = readFileSync27(jPath, "utf-8").split("\n").filter(Boolean);
27030
+ const journalLines = readFileSync30(jPath, "utf-8").split("\n").filter(Boolean);
26374
27031
  const known = new Set(this.messages.map((m) => m.id));
26375
27032
  for (const line of journalLines) {
26376
27033
  try {
@@ -26389,11 +27046,11 @@ ${msg.content}` };
26389
27046
  console.warn(`[agon] context-thread: journal merge failed (will overwrite): ${err instanceof Error ? err.message : String(err)}`);
26390
27047
  }
26391
27048
  }
26392
- if (existsSync23(target)) {
27049
+ if (existsSync25(target)) {
26393
27050
  try {
26394
- const stat = statSync19(target);
27051
+ const stat = statSync20(target);
26395
27052
  if (stat.size <= MAX_THREAD_FILE_BYTES) {
26396
- const raw = readFileSync27(target, "utf-8");
27053
+ const raw = readFileSync30(target, "utf-8");
26397
27054
  const onDisk = JSON.parse(raw);
26398
27055
  if (onDisk && Array.isArray(onDisk.messages)) {
26399
27056
  const known = new Set(this.messages.map((m) => m.id));
@@ -26431,13 +27088,13 @@ ${msg.content}` };
26431
27088
  const body = JSON.stringify(snapshot, null, 2) + "\n";
26432
27089
  let fd = -1;
26433
27090
  try {
26434
- fd = openSync(tmpPath, "w", 384);
26435
- writeFileSync22(fd, body, "utf-8");
27091
+ fd = openSync2(tmpPath, "w", 384);
27092
+ writeFileSync25(fd, body, "utf-8");
26436
27093
  fsyncSync(fd);
26437
27094
  } finally {
26438
27095
  if (fd >= 0) {
26439
27096
  try {
26440
- closeSync(fd);
27097
+ closeSync2(fd);
26441
27098
  } catch {
26442
27099
  }
26443
27100
  }
@@ -26451,7 +27108,7 @@ ${msg.content}` };
26451
27108
  this.dirty = false;
26452
27109
  this.hydrated = true;
26453
27110
  try {
26454
- if (existsSync23(jPath)) unlinkSync9(jPath);
27111
+ if (existsSync25(jPath)) unlinkSync10(jPath);
26455
27112
  this.journaledIds.clear();
26456
27113
  } catch {
26457
27114
  }
@@ -26472,8 +27129,8 @@ ${msg.content}` };
26472
27129
  function loadActivePointer() {
26473
27130
  try {
26474
27131
  const path = activePointerPath();
26475
- if (existsSync23(path)) {
26476
- const raw = readFileSync27(path, "utf-8");
27132
+ if (existsSync25(path)) {
27133
+ const raw = readFileSync30(path, "utf-8");
26477
27134
  const parsed = JSON.parse(raw);
26478
27135
  if (parsed && typeof parsed === "object" && parsed.byProject) {
26479
27136
  return parsed;
@@ -26487,9 +27144,9 @@ function loadActivePointer() {
26487
27144
  function saveActivePointer(pointer) {
26488
27145
  ensureAgonHome();
26489
27146
  const path = activePointerPath();
26490
- mkdirSync21(threadsDir(), { recursive: true });
27147
+ mkdirSync23(threadsDir(), { recursive: true });
26491
27148
  const tmpPath = path + ".tmp";
26492
- writeFileSync22(tmpPath, JSON.stringify(pointer, null, 2) + "\n", "utf-8");
27149
+ writeFileSync25(tmpPath, JSON.stringify(pointer, null, 2) + "\n", "utf-8");
26493
27150
  renameSync11(tmpPath, path);
26494
27151
  }
26495
27152
  var _WeakRefCtor = globalThis.WeakRef;
@@ -26545,9 +27202,9 @@ async function forkActiveThread(projectPath, systemPrompt) {
26545
27202
  }
26546
27203
  function listThreadsForProject(projectPath) {
26547
27204
  const dir = threadDirFor(projectPath);
26548
- if (!existsSync23(dir)) return [];
27205
+ if (!existsSync25(dir)) return [];
26549
27206
  try {
26550
- return readdirSync16(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5));
27207
+ return readdirSync17(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5));
26551
27208
  } catch (err) {
26552
27209
  console.warn(`[agon] context-thread: failed to list threads: ${err instanceof Error ? err.message : String(err)}`);
26553
27210
  return [];
@@ -26555,9 +27212,9 @@ function listThreadsForProject(projectPath) {
26555
27212
  }
26556
27213
  function deleteThread(projectPath, threadId) {
26557
27214
  try {
26558
- unlinkSync9(threadFilePath(projectPath, threadId));
27215
+ unlinkSync10(threadFilePath(projectPath, threadId));
26559
27216
  try {
26560
- unlinkSync9(threadJournalPath(projectPath, threadId));
27217
+ unlinkSync10(threadJournalPath(projectPath, threadId));
26561
27218
  } catch {
26562
27219
  }
26563
27220
  return true;
@@ -26908,7 +27565,7 @@ var AgentSession = class {
26908
27565
  this.state = "running";
26909
27566
  const perStepSec = this.config.perStepTimeoutSec ?? Math.floor(remainingMs / 1e3);
26910
27567
  const timeoutSec = Math.min(perStepSec, Math.floor(remainingMs / 1e3));
26911
- const promptTokens = estimateTokens(prompt);
27568
+ const promptTokens = estimateTokens2(prompt);
26912
27569
  const onEvent = opts?.onEvent;
26913
27570
  const thread = this.config.thread;
26914
27571
  const windowTokens = this.config.contextWindowTokens;
@@ -26969,7 +27626,7 @@ var AgentSession = class {
26969
27626
  }
26970
27627
  if (this.abortController.signal.aborted) {
26971
27628
  this.state = "cancelled";
26972
- const partialResponseTokens = estimateTokens(result.response ?? "");
27629
+ const partialResponseTokens = estimateTokens2(result.response ?? "");
26973
27630
  const partialTotal = promptTokens + partialResponseTokens;
26974
27631
  this.turnsUsed += 1;
26975
27632
  this.tokensUsed += partialTotal;
@@ -27001,7 +27658,7 @@ var AgentSession = class {
27001
27658
  engineFault: result.engineFault ?? false
27002
27659
  };
27003
27660
  }
27004
- const responseTokens = estimateTokens(result.response);
27661
+ const responseTokens = estimateTokens2(result.response);
27005
27662
  const stepTokens = promptTokens + responseTokens;
27006
27663
  const stepCost = estimateCost(this.config.engineId, stepTokens, this.config.api.model);
27007
27664
  this.turnsUsed += 1;
@@ -27087,7 +27744,7 @@ var AgentSession = class {
27087
27744
  };
27088
27745
 
27089
27746
  // ../core/src/generated/cesar/agent-team.ts
27090
- import { join as join28 } from "path";
27747
+ import { join as join31 } from "path";
27091
27748
  import { randomBytes as randomBytes2 } from "crypto";
27092
27749
  function makeAgentTeamError(message, cause) {
27093
27750
  const err = new Error(`AgentTeam: ${message}`);
@@ -27170,7 +27827,7 @@ var AgentTeam = class {
27170
27827
  if (!this.config.isolate) {
27171
27828
  return { m, wt: null };
27172
27829
  }
27173
- const wt = join28(this.config.cwd, ".agon", "agent-worktrees", this.runId, m.engineId);
27830
+ const wt = join31(this.config.cwd, ".agon", "agent-worktrees", this.runId, m.engineId);
27174
27831
  worktreeCreate(root, wt, this.baseSha);
27175
27832
  return { m, wt };
27176
27833
  });
@@ -27503,10 +28160,10 @@ function buildAgentSynthesisPrompt(opts) {
27503
28160
  let remaining = maxLoserContent;
27504
28161
  for (let i = 0; i < opts.losers.length; i++) {
27505
28162
  const loser = opts.losers[i];
27506
- const header = `## OTHER ENGINE ${i + 1}: ${loser.engineId}${loser.passedFitness ? " (passed fitness gate)" : " (did NOT pass fitness gate)"}`;
27507
- lines.push(header);
28163
+ const header2 = `## OTHER ENGINE ${i + 1}: ${loser.engineId}${loser.passedFitness ? " (passed fitness gate)" : " (did NOT pass fitness gate)"}`;
28164
+ lines.push(header2);
27508
28165
  lines.push(`<untrusted_data engine="${loser.engineId}">`);
27509
- remaining -= header.length + 50;
28166
+ remaining -= header2.length + 50;
27510
28167
  if (remaining <= 0) {
27511
28168
  lines.push(`*(trimmed for prompt budget)*`);
27512
28169
  lines.push(`</untrusted_data>`);
@@ -27996,10 +28653,10 @@ function hooksOutput(results) {
27996
28653
  }
27997
28654
 
27998
28655
  // ../core/src/generated/blocks/skill-loader.ts
27999
- import { readFileSync as readFileSync28, readdirSync as readdirSync17, existsSync as existsSync24 } from "fs";
28000
- import { join as join29, dirname as dirname12, resolve as resolve24 } from "path";
28656
+ import { readFileSync as readFileSync31, readdirSync as readdirSync18, existsSync as existsSync26 } from "fs";
28657
+ import { join as join32, dirname as dirname13, resolve as resolve24 } from "path";
28001
28658
  import { homedir as homedir15 } from "os";
28002
- import { fileURLToPath as fileURLToPath3 } from "url";
28659
+ import { fileURLToPath as fileURLToPath4 } from "url";
28003
28660
  function parseFrontmatter(content) {
28004
28661
  const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
28005
28662
  if (!match) {
@@ -28018,7 +28675,7 @@ function parseFrontmatter(content) {
28018
28675
  }
28019
28676
  function loadSkillFile(filePath) {
28020
28677
  try {
28021
- const content = readFileSync28(filePath, "utf-8");
28678
+ const content = readFileSync31(filePath, "utf-8");
28022
28679
  const { meta: meta3, body } = parseFrontmatter(content);
28023
28680
  if (!meta3.name || !meta3.trigger) return null;
28024
28681
  return {
@@ -28036,11 +28693,11 @@ function loadSkillFile(filePath) {
28036
28693
  }
28037
28694
  function loadSkillsFromDir(dir, source) {
28038
28695
  const skills = [];
28039
- if (!existsSync24(dir)) return skills;
28696
+ if (!existsSync26(dir)) return skills;
28040
28697
  try {
28041
- const files = readdirSync17(dir).filter((f) => f.endsWith(".md"));
28698
+ const files = readdirSync18(dir).filter((f) => f.endsWith(".md"));
28042
28699
  for (const file2 of files) {
28043
- const skill = loadSkillFile(join29(dir, file2));
28700
+ const skill = loadSkillFile(join32(dir, file2));
28044
28701
  if (skill) {
28045
28702
  skill.source = source;
28046
28703
  skills.push(skill);
@@ -28054,12 +28711,12 @@ function loadSkillsFromDir(dir, source) {
28054
28711
  function loadSkills(cwd) {
28055
28712
  const skills = [];
28056
28713
  const override = process.env.AGON_HOME?.trim();
28057
- const home = override ? resolve24(override) : join29(homedir15(), ".agon");
28058
- const builtinDir = join29(dirname12(fileURLToPath3(import.meta.url)), "../../skills");
28714
+ const home = override ? resolve24(override) : join32(homedir15(), ".agon");
28715
+ const builtinDir = join32(dirname13(fileURLToPath4(import.meta.url)), "../../skills");
28059
28716
  skills.push(...loadSkillsFromDir(builtinDir, "builtin"));
28060
- skills.push(...loadSkillsFromDir(join29(home, "skills"), "global"));
28717
+ skills.push(...loadSkillsFromDir(join32(home, "skills"), "global"));
28061
28718
  if (cwd) {
28062
- skills.push(...loadSkillsFromDir(join29(cwd, ".agon", "skills"), "project"));
28719
+ skills.push(...loadSkillsFromDir(join32(cwd, ".agon", "skills"), "project"));
28063
28720
  }
28064
28721
  const seen = /* @__PURE__ */ new Map();
28065
28722
  for (const skill of skills) {
@@ -28076,17 +28733,17 @@ function renderSkillPrompt(skill, input) {
28076
28733
  }
28077
28734
 
28078
28735
  // ../core/src/generated/blocks/engine-memory.ts
28079
- import { readFileSync as readFileSync29, writeFileSync as writeFileSync23, mkdirSync as mkdirSync22, renameSync as renameSync12 } from "fs";
28080
- import { join as join30, resolve as resolve25 } from "path";
28736
+ import { readFileSync as readFileSync32, writeFileSync as writeFileSync26, mkdirSync as mkdirSync24, renameSync as renameSync12 } from "fs";
28737
+ import { join as join33, resolve as resolve25 } from "path";
28081
28738
  import { homedir as homedir16 } from "os";
28082
28739
  function memoryPath() {
28083
28740
  const override = process.env.AGON_HOME?.trim();
28084
- const home = override ? resolve25(override) : join30(homedir16(), ".agon");
28085
- return join30(home, "engine-memory.json");
28741
+ const home = override ? resolve25(override) : join33(homedir16(), ".agon");
28742
+ return join33(home, "engine-memory.json");
28086
28743
  }
28087
28744
  function loadEngineMemory() {
28088
28745
  try {
28089
- return JSON.parse(readFileSync29(memoryPath(), "utf-8"));
28746
+ return JSON.parse(readFileSync32(memoryPath(), "utf-8"));
28090
28747
  } catch (err) {
28091
28748
  if (err.code !== "ENOENT") {
28092
28749
  console.warn(`[agon] failed to load engine memory: ${err instanceof Error ? err.message : String(err)}`);
@@ -28096,12 +28753,12 @@ function loadEngineMemory() {
28096
28753
  }
28097
28754
  function saveEngineMemory(record2) {
28098
28755
  const override = process.env.AGON_HOME?.trim();
28099
- const home = override ? resolve25(override) : join30(homedir16(), ".agon");
28100
- mkdirSync22(home, { recursive: true });
28756
+ const home = override ? resolve25(override) : join33(homedir16(), ".agon");
28757
+ mkdirSync24(home, { recursive: true });
28101
28758
  record2.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
28102
28759
  const path = memoryPath();
28103
28760
  const tmpPath = path + ".tmp";
28104
- writeFileSync23(tmpPath, JSON.stringify(record2, null, 2) + "\n");
28761
+ writeFileSync26(tmpPath, JSON.stringify(record2, null, 2) + "\n");
28105
28762
  renameSync12(tmpPath, path);
28106
28763
  }
28107
28764
  function ensureProfile(record2, engineId) {
@@ -28293,7 +28950,7 @@ function rankByTaskClass(engineIds, taskClass) {
28293
28950
  let specialization;
28294
28951
  if (i === 0 && r.total >= 3) {
28295
28952
  role = "lead";
28296
- specialization = `You are the top-rated engine for ${taskClass} tasks (${r.classElo} ELO, ${Math.round(r.winRate * 100)}% win rate). Lead with your best approach.`;
28953
+ specialization = `You are the top-rated engine for ${taskClass} tasks (${r.classElo} Glicko, ${Math.round(r.winRate * 100)}% win rate). Lead with your best approach.`;
28297
28954
  } else if (i === ranked.length - 1 && r.total >= 3) {
28298
28955
  role = "challenger";
28299
28956
  specialization = `You are the challenger. Focus on what the lead engine might miss: edge cases, error handling, performance pitfalls. Your contrarian perspective is your strength.`;
@@ -28329,13 +28986,13 @@ function assignForgeRoles(engineIds, taskClass) {
28329
28986
  }
28330
28987
 
28331
28988
  // ../core/src/generated/blocks/sidechain-logger.ts
28332
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync23 } from "fs";
28333
- import { join as join31 } from "path";
28989
+ import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync25 } from "fs";
28990
+ import { join as join34 } from "path";
28334
28991
  function createSidechainLogger(opts) {
28335
28992
  const suffix = opts.parentId ? `_sidechain_${opts.parentId}` : "";
28336
28993
  const filename = `${opts.sessionType}_${opts.sessionId}${suffix}.jsonl`;
28337
- const logPath = join31(opts.outputDir, filename);
28338
- mkdirSync23(opts.outputDir, { recursive: true });
28994
+ const logPath = join34(opts.outputDir, filename);
28995
+ mkdirSync25(opts.outputDir, { recursive: true });
28339
28996
  function log(type, engineId, data) {
28340
28997
  const event = {
28341
28998
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -28347,7 +29004,7 @@ function createSidechainLogger(opts) {
28347
29004
  ...data && { data }
28348
29005
  };
28349
29006
  try {
28350
- appendFileSync3(logPath, JSON.stringify(event) + "\n");
29007
+ appendFileSync4(logPath, JSON.stringify(event) + "\n");
28351
29008
  } catch (err) {
28352
29009
  console.warn(`[agon] sidechain write failed (${logPath}): ${err instanceof Error ? err.message : String(err)}`);
28353
29010
  }
@@ -28364,12 +29021,12 @@ function createSidechainLogger(opts) {
28364
29021
  }
28365
29022
 
28366
29023
  // ../core/src/generated/blocks/provenance.ts
28367
- import { readFileSync as readFileSync30, writeFileSync as writeFileSync24, mkdirSync as mkdirSync24 } from "fs";
28368
- import { join as join32, resolve as resolve26 } from "path";
29024
+ import { readFileSync as readFileSync33, writeFileSync as writeFileSync27, mkdirSync as mkdirSync26 } from "fs";
29025
+ import { join as join35, resolve as resolve26 } from "path";
28369
29026
  import { createHash as createHash7 } from "crypto";
28370
29027
  function sha256OfFile(path) {
28371
29028
  try {
28372
- return "sha256:" + createHash7("sha256").update(readFileSync30(path)).digest("hex");
29029
+ return "sha256:" + createHash7("sha256").update(readFileSync33(path)).digest("hex");
28373
29030
  } catch (e) {
28374
29031
  console.warn(`[agon] provenance: could not hash ${path}: ${e instanceof Error ? e.message : String(e)}`);
28375
29032
  return "unavailable";
@@ -28529,18 +29186,18 @@ function renderProvenanceMarkdown(led) {
28529
29186
  function writeProvenanceReport(manifest, manifestPath, outDir, format) {
28530
29187
  const fmt = format ?? "md";
28531
29188
  const ledger = buildForgeProvenance(manifest, manifestPath);
28532
- mkdirSync24(outDir, { recursive: true });
29189
+ mkdirSync26(outDir, { recursive: true });
28533
29190
  if (fmt === "md" || fmt === "both") {
28534
- const mdPath = resolve26(join32(outDir, "provenance.md"));
28535
- writeFileSync24(mdPath, renderProvenanceMarkdown(ledger), "utf-8");
29191
+ const mdPath = resolve26(join35(outDir, "provenance.md"));
29192
+ writeFileSync27(mdPath, renderProvenanceMarkdown(ledger), "utf-8");
28536
29193
  if (fmt === "md") return mdPath;
28537
29194
  }
28538
29195
  if (fmt === "json" || fmt === "both") {
28539
- const jsonPath = resolve26(join32(outDir, "provenance.json"));
28540
- writeFileSync24(jsonPath, renderProvenanceJson(ledger), "utf-8");
29196
+ const jsonPath = resolve26(join35(outDir, "provenance.json"));
29197
+ writeFileSync27(jsonPath, renderProvenanceJson(ledger), "utf-8");
28541
29198
  if (fmt === "json") return jsonPath;
28542
29199
  }
28543
- return resolve26(join32(outDir, "provenance.md"));
29200
+ return resolve26(join35(outDir, "provenance.md"));
28544
29201
  }
28545
29202
 
28546
29203
  // ../core/src/generated/models/extension-manifest.ts
@@ -28646,8 +29303,8 @@ var CommandRegistry = class {
28646
29303
  };
28647
29304
 
28648
29305
  // ../core/src/generated/blocks/extension-loader.ts
28649
- import { join as join33, resolve as resolve27 } from "path";
28650
- import { readdirSync as readdirSync18, readFileSync as readFileSync31, existsSync as existsSync25 } from "fs";
29306
+ import { join as join36, resolve as resolve27 } from "path";
29307
+ import { readdirSync as readdirSync19, readFileSync as readFileSync34, existsSync as existsSync27 } from "fs";
28651
29308
  import { homedir as homedir17 } from "os";
28652
29309
 
28653
29310
  // ../core/src/generated/signals/event-bus.ts
@@ -28738,31 +29395,31 @@ function bridgeShellHooks(bus, hooks) {
28738
29395
  function discoverExtensionDirs(cwd) {
28739
29396
  const results = [];
28740
29397
  const override = process.env.AGON_HOME?.trim();
28741
- const home = override ? resolve27(override) : join33(homedir17(), ".agon");
28742
- const userDir = join33(home, "extensions");
28743
- if (existsSync25(userDir)) {
29398
+ const home = override ? resolve27(override) : join36(homedir17(), ".agon");
29399
+ const userDir = join36(home, "extensions");
29400
+ if (existsSync27(userDir)) {
28744
29401
  try {
28745
- const entries = readdirSync18(userDir, { withFileTypes: true });
29402
+ const entries = readdirSync19(userDir, { withFileTypes: true });
28746
29403
  for (const entry of entries) {
28747
29404
  if (entry.isDirectory()) {
28748
- const manifestPath = join33(userDir, entry.name, "manifest.json");
28749
- if (existsSync25(manifestPath)) {
28750
- results.push({ dir: join33(userDir, entry.name), source: "user" });
29405
+ const manifestPath = join36(userDir, entry.name, "manifest.json");
29406
+ if (existsSync27(manifestPath)) {
29407
+ results.push({ dir: join36(userDir, entry.name), source: "user" });
28751
29408
  }
28752
29409
  }
28753
29410
  }
28754
29411
  } catch {
28755
29412
  }
28756
29413
  }
28757
- const repoDir = join33(cwd, ".agon", "extensions");
28758
- if (existsSync25(repoDir)) {
29414
+ const repoDir = join36(cwd, ".agon", "extensions");
29415
+ if (existsSync27(repoDir)) {
28759
29416
  try {
28760
- const entries = readdirSync18(repoDir, { withFileTypes: true });
29417
+ const entries = readdirSync19(repoDir, { withFileTypes: true });
28761
29418
  for (const entry of entries) {
28762
29419
  if (entry.isDirectory()) {
28763
- const manifestPath = join33(repoDir, entry.name, "manifest.json");
28764
- if (existsSync25(manifestPath)) {
28765
- results.push({ dir: join33(repoDir, entry.name), source: "repo" });
29420
+ const manifestPath = join36(repoDir, entry.name, "manifest.json");
29421
+ if (existsSync27(manifestPath)) {
29422
+ results.push({ dir: join36(repoDir, entry.name), source: "repo" });
28766
29423
  }
28767
29424
  }
28768
29425
  }
@@ -28772,9 +29429,9 @@ function discoverExtensionDirs(cwd) {
28772
29429
  return results;
28773
29430
  }
28774
29431
  function loadExtensionManifest(dir, source) {
28775
- const manifestPath = join33(dir, "manifest.json");
29432
+ const manifestPath = join36(dir, "manifest.json");
28776
29433
  try {
28777
- const raw = JSON.parse(readFileSync31(manifestPath, "utf-8"));
29434
+ const raw = JSON.parse(readFileSync34(manifestPath, "utf-8"));
28778
29435
  const result = validateManifest(raw, manifestPath);
28779
29436
  if (!result.ok || !result.data) {
28780
29437
  console.warn(`[agon] skipping extension ${dir}: ${result.error}`);
@@ -28843,7 +29500,7 @@ function registerExtensionEngines(ext, engineRegistry) {
28843
29500
  for (const enginePath of enginePaths) {
28844
29501
  try {
28845
29502
  const fullPath = resolve27(ext.dir, enginePath);
28846
- const raw = JSON.parse(readFileSync31(fullPath, "utf-8"));
29503
+ const raw = JSON.parse(readFileSync34(fullPath, "utf-8"));
28847
29504
  if (raw.id) {
28848
29505
  engineRegistry.register(raw);
28849
29506
  registered.push(raw.id);
@@ -28992,7 +29649,7 @@ function registerBuiltinCommands(registry2) {
28992
29649
  // Info
28993
29650
  { name: "tokens", desc: " \u2014 show token usage & costs", category: "info" },
28994
29651
  { name: "doctor", desc: "[engines|harness] \u2014 diagnose engines, worktree, or Cesar harness", category: "info" },
28995
- { name: "leaderboard", desc: " \u2014 ELO rankings", category: "info" },
29652
+ { name: "leaderboard", desc: " \u2014 Glicko rankings", category: "info" },
28996
29653
  { name: "history", desc: "[id] \u2014 past forge runs", category: "info" },
28997
29654
  { name: "provenance", desc: "[id] [-f md|json|both] [-o file] \u2014 AI-contribution / transparency report", category: "info" },
28998
29655
  { name: "flow", desc: " \u2014 log this session", category: "info" },
@@ -29000,12 +29657,14 @@ function registerBuiltinCommands(registry2) {
29000
29657
  { name: "chats", desc: "[id|resume <id>] \u2014 chat history or resume session", category: "info" },
29001
29658
  { name: "jobs", desc: " \u2014 list running/completed jobs", category: "info" },
29002
29659
  { name: "focus", desc: "<id> \u2014 switch to background job output", category: "info" },
29660
+ { name: "update", desc: "[version] [--check] \u2014 self-update from npm (also runs from the in-app banner)", category: "info" },
29003
29661
  // Session
29004
29662
  { name: "mcp", desc: "connect <name|url> | disconnect | list \u2014 manage session MCP servers", category: "session" },
29005
29663
  { name: "explore", desc: " \u2014 toggle exploration mode (read-only)", category: "session" },
29006
29664
  { name: "nero", desc: " \u2014 toggle Nero mode (adversarial)", category: "session" },
29007
29665
  { name: "btw", desc: "<question> \u2014 ask something while engines work", category: "session" },
29008
- { name: "clear", desc: " \u2014 reset session", category: "session", aliases: ["clean"] },
29666
+ { name: "compact", desc: " \u2014 shrink Cesar context without clearing transcript", category: "session" },
29667
+ { name: "clear", desc: " \u2014 reset session (saves chat, clears brain)", category: "session", aliases: ["clean"] },
29009
29668
  // Utility
29010
29669
  { name: "worktree", desc: "new|list|rm|prune|rehydrate <branch> \u2014 isolated per-session git worktrees", category: "utility", aliases: ["wt"] },
29011
29670
  { name: "create-skill", desc: "<name> \u2014 scaffold a new skill (.agon/skills/)", category: "utility" },
@@ -29256,8 +29915,8 @@ function computeContributionWeights(team, trace) {
29256
29915
  }
29257
29916
 
29258
29917
  // ../core/src/generated/teams/team-elo.ts
29259
- import { readFileSync as readFileSync32, writeFileSync as writeFileSync25, mkdirSync as mkdirSync25, renameSync as renameSync13 } from "fs";
29260
- import { dirname as dirname13 } from "path";
29918
+ import { readFileSync as readFileSync35, writeFileSync as writeFileSync28, mkdirSync as mkdirSync27, renameSync as renameSync13 } from "fs";
29919
+ import { dirname as dirname14 } from "path";
29261
29920
  function defaultCompositionRating(lineupKey2) {
29262
29921
  return { lineupKey: lineupKey2, rating: 1500, wins: 0, losses: 0, draws: 0, matches: 0 };
29263
29922
  }
@@ -29266,7 +29925,7 @@ function defaultRoleRating(engineId, role) {
29266
29925
  }
29267
29926
  function loadTeamElo() {
29268
29927
  try {
29269
- return JSON.parse(readFileSync32(TEAM_ELO_PATH, "utf-8"));
29928
+ return JSON.parse(readFileSync35(TEAM_ELO_PATH, "utf-8"));
29270
29929
  } catch (err) {
29271
29930
  if (err.code !== "ENOENT") {
29272
29931
  console.warn(`[agon] failed to load team ELO: ${err instanceof Error ? err.message : String(err)}`);
@@ -29275,10 +29934,10 @@ function loadTeamElo() {
29275
29934
  }
29276
29935
  }
29277
29936
  function saveTeamElo(record2) {
29278
- mkdirSync25(dirname13(TEAM_ELO_PATH), { recursive: true });
29937
+ mkdirSync27(dirname14(TEAM_ELO_PATH), { recursive: true });
29279
29938
  record2.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
29280
29939
  const tmpPath = TEAM_ELO_PATH + ".tmp";
29281
- writeFileSync25(tmpPath, JSON.stringify(record2, null, 2) + "\n");
29940
+ writeFileSync28(tmpPath, JSON.stringify(record2, null, 2) + "\n");
29282
29941
  renameSync13(tmpPath, TEAM_ELO_PATH);
29283
29942
  }
29284
29943
  function expectedScore(rA, rB) {
@@ -29365,6 +30024,7 @@ function updateTeamElo(match, kFactor) {
29365
30024
  export {
29366
30025
  DEFAULT_AGON_CONFIG,
29367
30026
  DEFAULT_CONFIG,
30027
+ AGON_MODE_NAMES,
29368
30028
  AgonError,
29369
30029
  EngineNotFoundError,
29370
30030
  EngineTimeoutError,
@@ -29469,8 +30129,10 @@ export {
29469
30129
  validateEngineConfig,
29470
30130
  validateEngineDir,
29471
30131
  EngineRegistry,
30132
+ hasProjectBrief,
29472
30133
  isKernProject,
29473
30134
  scanProjectContext,
30135
+ buildKernContextSpine,
29474
30136
  collectSourceFiles,
29475
30137
  extractSymbols,
29476
30138
  buildCodebaseMap,
@@ -29484,7 +30146,7 @@ export {
29484
30146
  snapshotWorkspace,
29485
30147
  resolveWorkingDir,
29486
30148
  ensureCurrentWorkspace,
29487
- estimateTokens,
30149
+ estimateTokens2 as estimateTokens,
29488
30150
  estimateCost,
29489
30151
  tracker,
29490
30152
  createPlan,
@@ -29639,7 +30301,29 @@ export {
29639
30301
  mimeFromExt,
29640
30302
  resolveImagePath,
29641
30303
  buildImageAttachment,
30304
+ normalizeDroppedPath,
29642
30305
  extractImagesFromInput,
30306
+ roomsDir,
30307
+ roomDir,
30308
+ slugifyRoomId,
30309
+ roomExists,
30310
+ createRoom,
30311
+ listRooms,
30312
+ parseMentions,
30313
+ appendEvent,
30314
+ readEvents,
30315
+ closeRoom,
30316
+ isRoomClosed,
30317
+ PRESENCE_TTL_MS,
30318
+ recordPresence,
30319
+ removePresence,
30320
+ listPresence,
30321
+ readActiveLease,
30322
+ acquireTurnLease,
30323
+ releaseTurnLease,
30324
+ detectTrigger,
30325
+ detectPingPong,
30326
+ evaluateStop,
29643
30327
  FLOWS_DIR,
29644
30328
  FRICTION_TAGS,
29645
30329
  logFlow,
@@ -29772,4 +30456,4 @@ export {
29772
30456
  predictTeamRating,
29773
30457
  updateTeamElo
29774
30458
  };
29775
- //# sourceMappingURL=chunk-PFHGKBQT.js.map
30459
+ //# sourceMappingURL=chunk-HAJIKZGU.js.map