@kernlang/agon 0.1.4 → 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 (35) hide show
  1. package/dist/{chunk-O6YP55RV.js → chunk-46WNYE4R.js} +114 -69
  2. package/dist/chunk-46WNYE4R.js.map +1 -0
  3. package/dist/{chunk-FCCH7IPJ.js → chunk-4NTH3EAR.js} +39 -11
  4. package/dist/chunk-4NTH3EAR.js.map +1 -0
  5. package/dist/{chunk-4LVYSUMN.js → chunk-73ETZFDH.js} +6 -27
  6. package/dist/chunk-73ETZFDH.js.map +1 -0
  7. package/dist/{chunk-WE32YJKT.js → chunk-DGTU4UWQ.js} +2 -2
  8. package/dist/{chunk-WE32YJKT.js.map → chunk-DGTU4UWQ.js.map} +1 -1
  9. package/dist/{chunk-ATUT2BUQ.js → chunk-GPYWJO2Q.js} +24 -7
  10. package/dist/chunk-GPYWJO2Q.js.map +1 -0
  11. package/dist/{chunk-C22VTCS6.js → chunk-HAJIKZGU.js} +846 -219
  12. package/dist/chunk-HAJIKZGU.js.map +1 -0
  13. package/dist/{chunk-6ANHPXGZ.js → chunk-HSPQEDHX.js} +1 -1
  14. package/dist/{chunk-6ANHPXGZ.js.map → chunk-HSPQEDHX.js.map} +1 -1
  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-ES4RN7YM.js → forge-ZI7NE73F.js} +6 -6
  19. package/dist/index.js +550 -121
  20. package/dist/index.js.map +1 -1
  21. package/dist/plan-mode-KIXDKD63.js +17 -0
  22. package/dist/{src-WJGIOESS.js → src-4A5FVACG.js} +49 -3
  23. package/dist/{update-HHN4PJQI.js → update-DLPMYTF3.js} +6 -6
  24. package/package.json +4 -4
  25. package/dist/chunk-4LVYSUMN.js.map +0 -1
  26. package/dist/chunk-ATUT2BUQ.js.map +0 -1
  27. package/dist/chunk-C22VTCS6.js.map +0 -1
  28. package/dist/chunk-FCCH7IPJ.js.map +0 -1
  29. package/dist/chunk-O6YP55RV.js.map +0 -1
  30. package/dist/plan-mode-4XRC2ZC7.js +0 -17
  31. /package/dist/{dispatch-6LQSMMGI.js.map → dispatch-XHLJ44TF.js.map} +0 -0
  32. /package/dist/{forge-ES4RN7YM.js.map → forge-ZI7NE73F.js.map} +0 -0
  33. /package/dist/{plan-mode-4XRC2ZC7.js.map → plan-mode-KIXDKD63.js.map} +0 -0
  34. /package/dist/{src-WJGIOESS.js.map → src-4A5FVACG.js.map} +0 -0
  35. /package/dist/{update-HHN4PJQI.js.map → update-DLPMYTF3.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 = {};
@@ -4927,10 +4927,10 @@ function isValidJWT(token, algorithm = null) {
4927
4927
  const tokensParts = token.split(".");
4928
4928
  if (tokensParts.length !== 3)
4929
4929
  return false;
4930
- const [header] = tokensParts;
4931
- if (!header)
4930
+ const [header2] = tokensParts;
4931
+ if (!header2)
4932
4932
  return false;
4933
- const parsedHeader = JSON.parse(atob(header));
4933
+ const parsedHeader = JSON.parse(atob(header2));
4934
4934
  if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT")
4935
4935
  return false;
4936
4936
  if (!parsedHeader.alg)
@@ -16429,7 +16429,194 @@ var EngineRegistry = class {
16429
16429
 
16430
16430
  // ../core/src/generated/blocks/context-scanner.ts
16431
16431
  import { readFileSync as readFileSync8, readdirSync as readdirSync6, statSync as statSync6, existsSync as existsSync6 } from "fs";
16432
- 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
16433
16620
  var PROJECT_BRIEF_FILES = [".agon/project.md", "AGON.md", "AGENT.md", "CLAUDE.md", "CODEX.md"];
16434
16621
  var MAX_PROJECT_BRIEF_BYTES = 512 * 1024;
16435
16622
  function projectBriefCap(file2) {
@@ -16592,6 +16779,78 @@ ${result}
16592
16779
  }
16593
16780
  return result;
16594
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
+ }
16595
16854
 
16596
16855
  // ../core/src/generated/blocks/codebase-map.ts
16597
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";
@@ -16932,7 +17191,7 @@ function ensureCurrentWorkspace(cwd) {
16932
17191
  }
16933
17192
 
16934
17193
  // ../core/src/generated/signals/token-tracker.ts
16935
- function estimateTokens(text) {
17194
+ function estimateTokens2(text) {
16936
17195
  return Math.ceil(text.length / 4);
16937
17196
  }
16938
17197
  function estimateCost(engineId, tokens, model) {
@@ -16949,8 +17208,8 @@ var TokenTracker = class {
16949
17208
  record(engineId, inputOrPrompt, responseText) {
16950
17209
  let promptTokens, responseTokens, totalTokens, source, model, costUsd;
16951
17210
  if (typeof inputOrPrompt === "string") {
16952
- promptTokens = estimateTokens(inputOrPrompt);
16953
- responseTokens = estimateTokens(responseText ?? "");
17211
+ promptTokens = estimateTokens2(inputOrPrompt);
17212
+ responseTokens = estimateTokens2(responseText ?? "");
16954
17213
  totalTokens = promptTokens + responseTokens;
16955
17214
  source = "estimated";
16956
17215
  model = void 0;
@@ -16963,8 +17222,8 @@ var TokenTracker = class {
16963
17222
  model = inputOrPrompt.model;
16964
17223
  costUsd = estimateCost(engineId, totalTokens, model);
16965
17224
  } else {
16966
- promptTokens = estimateTokens(inputOrPrompt.prompt);
16967
- responseTokens = estimateTokens(inputOrPrompt.response);
17225
+ promptTokens = estimateTokens2(inputOrPrompt.prompt);
17226
+ responseTokens = estimateTokens2(inputOrPrompt.response);
16968
17227
  totalTokens = promptTokens + responseTokens;
16969
17228
  source = "estimated";
16970
17229
  model = void 0;
@@ -17206,9 +17465,9 @@ function wordWrap(text, width) {
17206
17465
 
17207
17466
  // ../core/src/generated/blocks/stack-trace.ts
17208
17467
  import { existsSync as existsSync9, readFileSync as readFileSync12 } from "fs";
17209
- 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";
17210
17469
  import { fileURLToPath as fileURLToPath2 } from "url";
17211
- import { createRequire as createRequire2 } from "module";
17470
+ import { createRequire as createRequire3 } from "module";
17212
17471
  import { Buffer as Buffer2 } from "buffer";
17213
17472
  function setBoundedCacheEntry(cache, key, value) {
17214
17473
  if (!cache || typeof cache.set !== "function") return;
@@ -17249,7 +17508,7 @@ function readTextFileCached(filePath) {
17249
17508
  }
17250
17509
  function nodeModuleApi() {
17251
17510
  try {
17252
- return createRequire2(import.meta.url)("node:module");
17511
+ return createRequire3(import.meta.url)("node:module");
17253
17512
  } catch {
17254
17513
  return {};
17255
17514
  }
@@ -17285,7 +17544,7 @@ function loadSourceMapForFile(filePath) {
17285
17544
  const base643 = mappingUrl.match(/^data:application\/json(?:;charset=[^;,]+)?;base64,(.+)$/i)?.[1];
17286
17545
  if (base643) payload = JSON.parse(Buffer2.from(base643, "base64").toString("utf8"));
17287
17546
  } else {
17288
- const mapPath = resolve7(dirname5(normalized), decodeURIComponent(mappingUrl));
17547
+ const mapPath = resolve7(dirname6(normalized), decodeURIComponent(mappingUrl));
17289
17548
  if (existsSync9(mapPath)) payload = JSON.parse(readFileSync12(mapPath, "utf8"));
17290
17549
  }
17291
17550
  if (payload && typeof mod.SourceMap === "function") {
@@ -17330,7 +17589,7 @@ function resolveSourceMapSourcePath(mapFilePath, sourceMap, originFileName) {
17330
17589
  return normalize(sourceRef);
17331
17590
  }
17332
17591
  }
17333
- return normalize(resolve7(dirname5(normalizeStackFilePath(mapFilePath)), sourceRoot, sourceRef));
17592
+ return normalize(resolve7(dirname6(normalizeStackFilePath(mapFilePath)), sourceRoot, sourceRef));
17334
17593
  }
17335
17594
  function sourceMapOriginForLocation(sourceMap, lineNumber, columnNumber) {
17336
17595
  if (!sourceMap) return null;
@@ -17424,15 +17683,15 @@ function packageRootForGeneratedPath(generatedFile) {
17424
17683
  return null;
17425
17684
  }
17426
17685
  function resolveKernSourceFile(generatedFile, content, sourceName) {
17427
- const header = generatedHeaderSource(content);
17686
+ const header2 = generatedHeaderSource(content);
17428
17687
  const candidates = [];
17429
17688
  const root = packageRootForGeneratedPath(generatedFile);
17430
- if (header) {
17431
- if (isAbsolute2(header)) candidates.push(normalize(header));
17432
- if (root) candidates.push(normalize(resolve7(root, header)));
17433
- 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)));
17434
17693
  try {
17435
- candidates.push(normalize(resolve7(process.cwd(), header)));
17694
+ candidates.push(normalize(resolve7(process.cwd(), header2)));
17436
17695
  } catch {
17437
17696
  }
17438
17697
  }
@@ -17967,7 +18226,7 @@ function undoPatch(cwd, undoToken) {
17967
18226
 
17968
18227
  // ../core/src/generated/blocks/file-history.ts
17969
18228
  import { readFileSync as readFileSync14, writeFileSync as writeFileSync11, mkdirSync as mkdirSync10, existsSync as existsSync10, readdirSync as readdirSync9, unlinkSync as unlinkSync4 } from "fs";
17970
- 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";
17971
18230
  import { randomUUID as randomUUID2 } from "crypto";
17972
18231
  import { homedir as homedir7 } from "os";
17973
18232
  function snapshotsDir() {
@@ -18031,7 +18290,7 @@ function revertSnapshot(id) {
18031
18290
  reverted++;
18032
18291
  }
18033
18292
  } else {
18034
- mkdirSync10(dirname6(fullPath), { recursive: true });
18293
+ mkdirSync10(dirname7(fullPath), { recursive: true });
18035
18294
  writeFileSync11(fullPath, snap.content);
18036
18295
  reverted++;
18037
18296
  }
@@ -19553,7 +19812,7 @@ function createEditTool() {
19553
19812
 
19554
19813
  // ../core/src/generated/tools/tool-write.ts
19555
19814
  import { writeFileSync as writeFileSync15, statSync as statSync13, existsSync as existsSync15, mkdirSync as mkdirSync14 } from "fs";
19556
- 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";
19557
19816
  function createWriteTool() {
19558
19817
  const definition = {
19559
19818
  name: "Write",
@@ -19636,7 +19895,7 @@ function createWriteTool() {
19636
19895
  } else {
19637
19896
  snapshot = takeSnapshot(`Write (new): ${relPath}`, ctx.cwd, [relPath]);
19638
19897
  }
19639
- const parentDir = dirname9(filePath);
19898
+ const parentDir = dirname10(filePath);
19640
19899
  if (!existsSync15(parentDir)) {
19641
19900
  try {
19642
19901
  mkdirSync14(parentDir, { recursive: true });
@@ -19759,10 +20018,10 @@ function createBashTool() {
19759
20018
  const readRedirect = tryRedirectToRead(command);
19760
20019
  if (readRedirect) {
19761
20020
  try {
19762
- const { readFileSync: readFileSync33 } = await import("fs");
20021
+ const { readFileSync: readFileSync36 } = await import("fs");
19763
20022
  const { resolve: resolve28 } = await import("path");
19764
20023
  const filePath = resolve28(ctx.cwd, readRedirect.file);
19765
- const content = readFileSync33(filePath, "utf-8");
20024
+ const content = readFileSync36(filePath, "utf-8");
19766
20025
  const lines = content.split("\n");
19767
20026
  const offset = readRedirect.offset ?? 0;
19768
20027
  const limit = readRedirect.limit ?? lines.length;
@@ -20547,7 +20806,7 @@ function createTodoWriteTool() {
20547
20806
 
20548
20807
  // ../core/src/generated/signals/auth-store.ts
20549
20808
  import { readFileSync as readFileSync19, writeFileSync as writeFileSync16, mkdirSync as mkdirSync15, existsSync as existsSync16, chmodSync } from "fs";
20550
- 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";
20551
20810
  import { homedir as homedir9 } from "os";
20552
20811
  function getAuthFile() {
20553
20812
  const override = process.env.AGON_HOME?.trim();
@@ -20568,7 +20827,7 @@ function loadAuthStore() {
20568
20827
  }
20569
20828
  function saveAuthStore(store) {
20570
20829
  const authFile = getAuthFile();
20571
- const dir = dirname10(authFile);
20830
+ const dir = dirname11(authFile);
20572
20831
  mkdirSync15(dir, { recursive: true });
20573
20832
  writeFileSync16(authFile, JSON.stringify(store.entries, null, 2) + "\n", { mode: 384 });
20574
20833
  try {
@@ -22222,17 +22481,17 @@ function startChatSession(opts) {
22222
22481
  const id = `chat-${Date.now()}`;
22223
22482
  const session = { id, startedAt: (/* @__PURE__ */ new Date()).toISOString(), messages: [], cwd: opts?.cwd, branch: opts?.branch, engineIds: opts?.engineIds };
22224
22483
  const filePath = join21(chatsDir(), `${id}.ndjson`);
22225
- const header = { _type: "header", id, startedAt: session.startedAt };
22484
+ const header2 = { _type: "header", id, startedAt: session.startedAt };
22226
22485
  if (opts?.cwd) {
22227
- header.cwd = opts.cwd;
22486
+ header2.cwd = opts.cwd;
22228
22487
  }
22229
22488
  if (opts?.branch) {
22230
- header.branch = opts.branch;
22489
+ header2.branch = opts.branch;
22231
22490
  }
22232
22491
  if (opts?.engineIds) {
22233
- header.engineIds = opts.engineIds;
22492
+ header2.engineIds = opts.engineIds;
22234
22493
  }
22235
- appendFileSync(filePath, JSON.stringify(header) + "\n");
22494
+ appendFileSync(filePath, JSON.stringify(header2) + "\n");
22236
22495
  return session;
22237
22496
  }
22238
22497
  function appendMessage(session, msg) {
@@ -22407,10 +22666,10 @@ function loadChatSession(id) {
22407
22666
  const raw = readFileSync22(filePath, "utf-8");
22408
22667
  const lines = raw.trim().split("\n").filter(Boolean);
22409
22668
  if (lines.length === 0) return null;
22410
- const header = JSON.parse(lines[0]);
22669
+ const header2 = JSON.parse(lines[0]);
22411
22670
  const messages = [];
22412
- let summary = typeof header.summary === "string" ? header.summary : void 0;
22413
- 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;
22414
22673
  for (let i = 1; i < lines.length; i++) {
22415
22674
  const msg = JSON.parse(lines[i]);
22416
22675
  if (msg._type === "summary") {
@@ -22424,12 +22683,12 @@ function loadChatSession(id) {
22424
22683
  freeSummarizedMessageBodies(messages, 0, Math.min(summarizedMessageCount, messages.length));
22425
22684
  }
22426
22685
  return {
22427
- id: header.id ?? id,
22428
- startedAt: header.startedAt ?? "",
22686
+ id: header2.id ?? id,
22687
+ startedAt: header2.startedAt ?? "",
22429
22688
  messages,
22430
- cwd: header.cwd,
22431
- branch: header.branch,
22432
- engineIds: header.engineIds,
22689
+ cwd: header2.cwd,
22690
+ branch: header2.branch,
22691
+ engineIds: header2.engineIds,
22433
22692
  summary,
22434
22693
  summarizedMessageCount
22435
22694
  };
@@ -22467,9 +22726,9 @@ function latestChatSession() {
22467
22726
  import { existsSync as existsSync19 } from "fs";
22468
22727
  import { resolve as resolve19, basename as basename4, extname as extname2 } from "path";
22469
22728
  import { homedir as homedir11 } from "os";
22729
+ import { fileURLToPath as fileURLToPath3 } from "url";
22470
22730
  var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".bmp"]);
22471
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" };
22472
- 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;
22473
22732
  var IMG_CMD_REGEX = /^\/img\s+(.+)$/i;
22474
22733
  function isImagePath(filePath) {
22475
22734
  const ext = extname2(filePath).toLowerCase();
@@ -22497,59 +22756,404 @@ function buildImageAttachment(rawPath, cwd) {
22497
22756
  }
22498
22757
  return { path: resolved, filename: basename4(resolved), mimeType: mimeFromExt(resolved) };
22499
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
+ }
22500
22779
  function extractImagesFromInput(input, cwd) {
22501
22780
  const images = [];
22502
22781
  const imgCmdMatch = IMG_CMD_REGEX.exec(input.trim());
22503
22782
  if (imgCmdMatch) {
22504
- const att = buildImageAttachment(imgCmdMatch[1], cwd);
22783
+ const att = buildImageAttachment(normalizeDroppedPath(imgCmdMatch[1]), cwd);
22505
22784
  if (att) images.push(att);
22506
22785
  return { text: "", images };
22507
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
+ );
22508
22792
  let text = input;
22509
- const pathRegex = new RegExp(IMAGE_PATH_REGEX.source, "gi");
22510
22793
  let match;
22511
- const paths = [];
22512
- while ((match = pathRegex.exec(input)) !== null) {
22513
- const rawPath = match[1].trim();
22514
- 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);
22515
22801
  if (att) {
22516
22802
  images.push(att);
22517
- paths.push(match[0]);
22803
+ text = text.replace(hit.whole, "");
22518
22804
  }
22519
22805
  }
22520
- for (const p of paths) {
22521
- 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
+ }
22522
22815
  }
22523
22816
  text = text.replace(/\s{2,}/g, " ").trim();
22524
22817
  return { text, images };
22525
22818
  }
22526
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
+
22527
23131
  // ../core/src/generated/signals/flow.ts
22528
- import { readFileSync as readFileSync23, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18, readdirSync as readdirSync14 } from "fs";
22529
- 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";
22530
23134
  import { homedir as homedir12 } from "os";
22531
23135
  function getFlowsDir() {
22532
23136
  const override = process.env.AGON_HOME?.trim();
22533
- const home = override ? resolve20(override) : join22(homedir12(), ".agon");
22534
- return join22(home, "flows");
23137
+ const home = override ? resolve20(override) : join25(homedir12(), ".agon");
23138
+ return join25(home, "flows");
22535
23139
  }
22536
23140
  var FLOWS_DIR = getFlowsDir();
22537
23141
  var FRICTION_TAGS = ["slow", "wrong-mode", "engine-error", "unclear-output", "timeout", "context-lost", "other"];
22538
23142
  function ensureFlowsDir() {
22539
- mkdirSync18(getFlowsDir(), { recursive: true });
23143
+ mkdirSync20(getFlowsDir(), { recursive: true });
22540
23144
  }
22541
23145
  function logFlow(record2) {
22542
23146
  ensureFlowsDir();
22543
23147
  const filename = `flow-${record2.id}.json`;
22544
- const filepath = join22(getFlowsDir(), filename);
22545
- writeFileSync19(filepath, JSON.stringify(record2, null, 2));
23148
+ const filepath = join25(getFlowsDir(), filename);
23149
+ writeFileSync22(filepath, JSON.stringify(record2, null, 2));
22546
23150
  return filepath;
22547
23151
  }
22548
23152
  function readFlows(limit) {
22549
23153
  ensureFlowsDir();
22550
23154
  let files;
22551
23155
  try {
22552
- 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();
22553
23157
  } catch (err) {
22554
23158
  console.warn(`[agon] failed to read flows directory: ${err instanceof Error ? err.message : String(err)}`);
22555
23159
  return [];
@@ -22558,7 +23162,7 @@ function readFlows(limit) {
22558
23162
  const records = [];
22559
23163
  for (const file2 of files) {
22560
23164
  try {
22561
- const data = JSON.parse(readFileSync23(join22(getFlowsDir(), file2), "utf-8"));
23165
+ const data = JSON.parse(readFileSync26(join25(getFlowsDir(), file2), "utf-8"));
22562
23166
  records.push(data);
22563
23167
  } catch (err) {
22564
23168
  console.warn(`[agon] skipping malformed flow record ${file2}: ${err instanceof Error ? err.message : String(err)}`);
@@ -22987,19 +23591,19 @@ async function companionDispatch(opts) {
22987
23591
  }
22988
23592
 
22989
23593
  // ../core/src/generated/signals/models-registry.ts
22990
- import { readFileSync as readFileSync24, writeFileSync as writeFileSync20, mkdirSync as mkdirSync19, existsSync as existsSync20, statSync as statSync16 } from "fs";
22991
- 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";
22992
23596
  var CACHE_TTL_MS = 36e5;
22993
23597
  var MODELS_DEV_URL = "https://models.dev/api.json";
22994
23598
  async function fetchModelsRegistry() {
22995
23599
  const cacheDir = getCacheDir();
22996
- const cacheFile = join23(cacheDir, "models-dev.json");
22997
- if (existsSync20(cacheFile)) {
23600
+ const cacheFile = join26(cacheDir, "models-dev.json");
23601
+ if (existsSync22(cacheFile)) {
22998
23602
  try {
22999
- const stat = statSync16(cacheFile);
23603
+ const stat = statSync17(cacheFile);
23000
23604
  const age = Date.now() - stat.mtimeMs;
23001
23605
  if (age < CACHE_TTL_MS) {
23002
- return JSON.parse(readFileSync24(cacheFile, "utf-8"));
23606
+ return JSON.parse(readFileSync27(cacheFile, "utf-8"));
23003
23607
  }
23004
23608
  } catch (_e) {
23005
23609
  console.warn(`[agon] models-registry: cache read failed, refetching: ${_e instanceof Error ? _e.message : String(_e)}`);
@@ -23007,14 +23611,14 @@ async function fetchModelsRegistry() {
23007
23611
  }
23008
23612
  const response = await fetch(MODELS_DEV_URL);
23009
23613
  if (!response.ok) {
23010
- if (existsSync20(cacheFile)) {
23011
- return JSON.parse(readFileSync24(cacheFile, "utf-8"));
23614
+ if (existsSync22(cacheFile)) {
23615
+ return JSON.parse(readFileSync27(cacheFile, "utf-8"));
23012
23616
  }
23013
23617
  throw new Error(`Failed to fetch models registry: ${response.status}`);
23014
23618
  }
23015
23619
  const data = await response.json();
23016
- mkdirSync19(cacheDir, { recursive: true });
23017
- writeFileSync20(cacheFile, JSON.stringify(data));
23620
+ mkdirSync21(cacheDir, { recursive: true });
23621
+ writeFileSync23(cacheFile, JSON.stringify(data));
23018
23622
  return data;
23019
23623
  }
23020
23624
  function resolveModelFormat(providerNpm, model) {
@@ -23135,24 +23739,24 @@ function modelEntryToEngineDef(entry) {
23135
23739
 
23136
23740
  // ../core/src/generated/signals/cli-models-registry.ts
23137
23741
  import { execSync as execSync4 } from "child_process";
23138
- import { readFileSync as readFileSync25, writeFileSync as writeFileSync21, mkdirSync as mkdirSync20, existsSync as existsSync21, statSync as statSync17 } from "fs";
23139
- 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";
23140
23744
  import { homedir as homedir13 } from "os";
23141
- import { createRequire as createRequire3 } from "module";
23745
+ import { createRequire as createRequire4 } from "module";
23142
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: [] } };
23143
23747
  var ENGINE_DISPLAY_NAMES = { claude: "Claude", codex: "Codex", agy: "Antigravity", opencode: "OpenCode", mistral: "Mistral", openrouter: "OpenRouter" };
23144
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 }] };
23145
23749
  var PROBE_TTL_MS = 864e5;
23146
23750
  function probedModelsCacheFile(engineId) {
23147
- 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`);
23148
23752
  }
23149
23753
  function readProbedCliModels(engineId, ttlMs) {
23150
23754
  try {
23151
23755
  const file2 = probedModelsCacheFile(engineId);
23152
- if (!existsSync21(file2)) return null;
23153
- const age = Date.now() - statSync17(file2).mtimeMs;
23756
+ if (!existsSync23(file2)) return null;
23757
+ const age = Date.now() - statSync18(file2).mtimeMs;
23154
23758
  if (age > (ttlMs ?? PROBE_TTL_MS)) return null;
23155
- const data = JSON.parse(readFileSync25(file2, "utf-8"));
23759
+ const data = JSON.parse(readFileSync28(file2, "utf-8"));
23156
23760
  const raw = Array.isArray(data?.models) ? data.models : [];
23157
23761
  const models = raw.map((m) => ({ id: String(m.id ?? ""), name: String(m.name ?? m.id ?? ""), current: !!m.current })).filter((m) => m.name);
23158
23762
  return models.length > 0 ? models : null;
@@ -23162,7 +23766,7 @@ function readProbedCliModels(engineId, ttlMs) {
23162
23766
  }
23163
23767
  function resolveModelProbeScript() {
23164
23768
  try {
23165
- const req = createRequire3(import.meta.url);
23769
+ const req = createRequire4(import.meta.url);
23166
23770
  const anchor = req.resolve("@kernlang/agon-engines/cli/claude.js");
23167
23771
  const candidates = [
23168
23772
  // Canonical: the package ships the probe at py/kern_engines/cli/ (see
@@ -23170,16 +23774,16 @@ function resolveModelProbeScript() {
23170
23774
  // to the package root, then into py/. This is the path that actually
23171
23775
  // exists — the dist/cli & root/cli guesses below never matched, so the
23172
23776
  // probe silently never ran and every engine fell back to its static list.
23173
- join24(anchor, "..", "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23777
+ join27(anchor, "..", "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23174
23778
  // dist/cli → root → py/kern_engines/cli
23175
- join24(anchor, "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23779
+ join27(anchor, "..", "..", "py", "kern_engines", "cli", "model_probe.py"),
23176
23780
  // (alt layout: cli/claude.js → root)
23177
- join24(anchor, "..", "..", "..", "cli", "model_probe.py"),
23178
- join24(anchor, "..", "..", "cli", "model_probe.py"),
23179
- 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")
23180
23784
  ];
23181
23785
  for (const c of candidates) {
23182
- if (existsSync21(c)) return c;
23786
+ if (existsSync23(c)) return c;
23183
23787
  }
23184
23788
  return null;
23185
23789
  } catch {
@@ -23249,8 +23853,8 @@ async function refreshProbedCliModels(engineId, binary, listCmd, pythonBin) {
23249
23853
  return false;
23250
23854
  }
23251
23855
  const dir = getCacheDir();
23252
- mkdirSync20(dir, { recursive: true });
23253
- 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 }));
23254
23858
  return true;
23255
23859
  } catch (e) {
23256
23860
  dbg(`probe threw: ${e?.message ?? e}`);
@@ -23266,10 +23870,10 @@ function findBinary(binary) {
23266
23870
  } catch (e) {
23267
23871
  }
23268
23872
  const home = homedir13();
23269
- 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"];
23270
23874
  for (const dir of searchPaths) {
23271
- const fullPath = join24(dir, binary);
23272
- if (existsSync21(fullPath)) {
23875
+ const fullPath = join27(dir, binary);
23876
+ if (existsSync23(fullPath)) {
23273
23877
  return fullPath;
23274
23878
  }
23275
23879
  }
@@ -24435,7 +25039,7 @@ function createResumeSession(config2) {
24435
25039
  }
24436
25040
  return 50;
24437
25041
  };
24438
- const estimateTokens2 = (msgs) => msgs.reduce((sum, m) => {
25042
+ const estimateTokens3 = (msgs) => msgs.reduce((sum, m) => {
24439
25043
  if (m._tokenEstimate === void 0) {
24440
25044
  m._tokenEstimate = estimateSingle(m);
24441
25045
  }
@@ -24456,7 +25060,7 @@ function createResumeSession(config2) {
24456
25060
  })();
24457
25061
  const COMPACTION_BUFFER = Math.max(2e4, Math.round(CONTEXT_LIMIT * 0.15));
24458
25062
  const PRUNE_PROTECT_TURNS = 6;
24459
- const totalTokens = estimateTokens2(messageHistory);
25063
+ const totalTokens = estimateTokens3(messageHistory);
24460
25064
  if (totalTokens > CONTEXT_LIMIT - COMPACTION_BUFFER) {
24461
25065
  const hasSystem = messageHistory[0].role === "system";
24462
25066
  const startIdx = hasSystem ? 1 : 0;
@@ -24483,7 +25087,7 @@ function createResumeSession(config2) {
24483
25087
  delete msg._tokenEstimate;
24484
25088
  }
24485
25089
  }
24486
- const afterTier1 = estimateTokens2(messageHistory);
25090
+ const afterTier1 = estimateTokens3(messageHistory);
24487
25091
  if (afterTier1 > CONTEXT_LIMIT - COMPACTION_BUFFER) {
24488
25092
  const old = messageHistory.slice(startIdx, protectFrom);
24489
25093
  const recent = messageHistory.slice(protectFrom);
@@ -24582,11 +25186,11 @@ ${newSummary.decisions.map((d) => ` - ${d}`).join("\n")}` : "",
24582
25186
  }
24583
25187
  }
24584
25188
  }
24585
- const afterTier2 = estimateTokens2(messageHistory);
25189
+ const afterTier2 = estimateTokens3(messageHistory);
24586
25190
  const tier3CompactionEnabled = process.env.AGON_DISABLE_TIER3_COMPACTION !== "1";
24587
25191
  if (tier3CompactionEnabled && afterTier2 > CONTEXT_LIMIT - COMPACTION_BUFFER && config2.engine.api) {
24588
25192
  try {
24589
- const { apiDispatch: apiDispatch2 } = await import("./dispatch-6LQSMMGI.js");
25193
+ const { apiDispatch: apiDispatch2 } = await import("./dispatch-XHLJ44TF.js");
24590
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.
24591
25195
 
24592
25196
  CONTEXT TO SUMMARIZE:
@@ -24606,7 +25210,7 @@ ${newSummary.decisions.map((d) => ` - ${d}`).join("\n")}` : "",
24606
25210
  ${compactionResult.stdout}` },
24607
25211
  ...protectedRecent
24608
25212
  );
24609
- 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`);
24610
25214
  }
24611
25215
  } catch (tier3Err) {
24612
25216
  console.warn(`[agon] Tier 3 compaction failed (non-fatal): ${tier3Err instanceof Error ? tier3Err.message : String(tier3Err)}`);
@@ -24624,7 +25228,7 @@ ${compactionResult.stdout}` },
24624
25228
  toolCacheManifest = toolCacheManifest.filter((e) => activeIds.has(e.toolCallId));
24625
25229
  }
24626
25230
  {
24627
- const ctxTokens = totalTokens <= CONTEXT_LIMIT - COMPACTION_BUFFER ? totalTokens : estimateTokens2(messageHistory);
25231
+ const ctxTokens = totalTokens <= CONTEXT_LIMIT - COMPACTION_BUFFER ? totalTokens : estimateTokens3(messageHistory);
24628
25232
  const ctxPct = Math.round(ctxTokens / CONTEXT_LIMIT * 100);
24629
25233
  const cachedCount = toolCacheManifest.length;
24630
25234
  const compactedCount = compactionSummary?.messagesCompacted ?? 0;
@@ -25364,8 +25968,8 @@ function createStreamBridge(dispatch, opts) {
25364
25968
  }
25365
25969
 
25366
25970
  // ../core/src/generated/forge/virtual-fs.ts
25367
- import { readFileSync as readFileSync26, existsSync as existsSync22, readdirSync as readdirSync15, statSync as statSync18 } from "fs";
25368
- 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";
25369
25973
  import { createHash as createHash5 } from "crypto";
25370
25974
  function createFileSnapshot(rootDir) {
25371
25975
  const snapshotId = createHash5("sha256").update(rootDir + Date.now().toString()).digest("hex").slice(0, 12);
@@ -25381,16 +25985,16 @@ function snapshotRead(snap, absPath) {
25381
25985
  return snap.cache.get(key) ?? null;
25382
25986
  }
25383
25987
  try {
25384
- if (!existsSync22(key)) {
25988
+ if (!existsSync24(key)) {
25385
25989
  snap.cache.set(key, null);
25386
25990
  return null;
25387
25991
  }
25388
- const st = statSync18(key);
25992
+ const st = statSync19(key);
25389
25993
  if (!st.isFile()) {
25390
25994
  snap.cache.set(key, null);
25391
25995
  return null;
25392
25996
  }
25393
- const content = readFileSync26(key, "utf-8");
25997
+ const content = readFileSync29(key, "utf-8");
25394
25998
  snap.cache.set(key, content);
25395
25999
  return content;
25396
26000
  } catch (e) {
@@ -25401,13 +26005,13 @@ function snapshotRead(snap, absPath) {
25401
26005
  function snapshotList(snap, absDir) {
25402
26006
  const dir = resolve21(absDir);
25403
26007
  try {
25404
- return readdirSync15(dir).filter((f) => {
26008
+ return readdirSync16(dir).filter((f) => {
25405
26009
  try {
25406
- return statSync18(join25(dir, f)).isFile();
26010
+ return statSync19(join28(dir, f)).isFile();
25407
26011
  } catch {
25408
26012
  return false;
25409
26013
  }
25410
- }).map((f) => join25(dir, f));
26014
+ }).map((f) => join28(dir, f));
25411
26015
  } catch {
25412
26016
  return [];
25413
26017
  }
@@ -25473,7 +26077,7 @@ var VirtualFS = class {
25473
26077
  const overlayWritten = [];
25474
26078
  const overlayDeleted = /* @__PURE__ */ new Set();
25475
26079
  for (const [path, content] of this.overlay.entries()) {
25476
- if (dirname11(path) === dir) {
26080
+ if (dirname12(path) === dir) {
25477
26081
  if (content === null) {
25478
26082
  overlayDeleted.add(path);
25479
26083
  } else {
@@ -25532,7 +26136,7 @@ function applyEffectPackage(pkg, targetDir) {
25532
26136
  for (const effect of pkg.effects) {
25533
26137
  const absPath = resolve21(targetDir, effect.kind === "rename" ? effect.from : effect.path);
25534
26138
  if (effect.kind === "write") {
25535
- const dir = dirname11(absPath);
26139
+ const dir = dirname12(absPath);
25536
26140
  import_fs.mkdirSync(dir, { recursive: true });
25537
26141
  import_fs.writeFileSync(absPath, effect.content, "utf-8");
25538
26142
  modified.push(absPath);
@@ -25544,7 +26148,7 @@ function applyEffectPackage(pkg, targetDir) {
25544
26148
  modified.push(absPath);
25545
26149
  } else if (effect.kind === "rename") {
25546
26150
  const dest = resolve21(targetDir, effect.to);
25547
- import_fs.mkdirSync(dirname11(dest), { recursive: true });
26151
+ import_fs.mkdirSync(dirname12(dest), { recursive: true });
25548
26152
  import_fs.renameSync(absPath, dest);
25549
26153
  modified.push(absPath);
25550
26154
  modified.push(dest);
@@ -25622,7 +26226,7 @@ function scoreEffectPackage(pkg, taskKeywords) {
25622
26226
 
25623
26227
  // ../core/src/generated/cesar/speculator.ts
25624
26228
  import { randomUUID as randomUUID4 } from "crypto";
25625
- import { resolve as resolve22, join as join26 } from "path";
26229
+ import { resolve as resolve22, join as join29 } from "path";
25626
26230
  var Speculator = class {
25627
26231
  runId;
25628
26232
  snapshot;
@@ -25644,7 +26248,7 @@ var Speculator = class {
25644
26248
  if (isolate) {
25645
26249
  const baseSha = stashSnapshot(root);
25646
26250
  for (const member of opts.members) {
25647
- const wtPath = join26(root, `.agon/speculate-worktrees/${this.runId}/${member.engineId}`);
26251
+ const wtPath = join29(root, `.agon/speculate-worktrees/${this.runId}/${member.engineId}`);
25648
26252
  try {
25649
26253
  await worktreeCreate(root, wtPath, baseSha);
25650
26254
  worktreesByEngine[member.engineId] = wtPath;
@@ -25817,17 +26421,17 @@ ${sessionLines.join("\n")}`);
25817
26421
  }
25818
26422
 
25819
26423
  // ../core/src/generated/cesar/context-thread.ts
25820
- 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";
25821
- 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";
25822
26426
  import { randomUUID as randomUUID5, createHash as createHash6 } from "crypto";
25823
26427
  import { homedir as homedir14 } from "os";
25824
26428
  function threadsDir() {
25825
26429
  const override = process.env.AGON_HOME?.trim();
25826
- const home = override ? resolve23(override) : join27(homedir14(), ".agon");
25827
- return join27(home, "threads");
26430
+ const home = override ? resolve23(override) : join30(homedir14(), ".agon");
26431
+ return join30(home, "threads");
25828
26432
  }
25829
26433
  function activePointerPath() {
25830
- return join27(threadsDir(), "active.json");
26434
+ return join30(threadsDir(), "active.json");
25831
26435
  }
25832
26436
  function projectHash16(projectPath) {
25833
26437
  return createHash6("sha256").update(projectPath).digest("hex").slice(0, 16);
@@ -25836,7 +26440,7 @@ function projectSha8(projectPath) {
25836
26440
  return projectHash16(projectPath);
25837
26441
  }
25838
26442
  function threadDirFor(projectPath) {
25839
- return join27(threadsDir(), projectHash16(projectPath));
26443
+ return join30(threadsDir(), projectHash16(projectPath));
25840
26444
  }
25841
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})$/;
25842
26446
  function threadJournalPath(projectPath, threadId) {
@@ -25849,7 +26453,7 @@ function threadFilePath(projectPath, threadId) {
25849
26453
  const dir = threadDirFor(projectPath);
25850
26454
  const full = resolve23(dir, `${threadId}.json`);
25851
26455
  const resolvedDir = resolve23(dir);
25852
- const nativeSep = join27("a", "b")[1];
26456
+ const nativeSep = join30("a", "b")[1];
25853
26457
  const isContained = full === resolvedDir || full.startsWith(resolvedDir + "/") || full.startsWith(resolvedDir + nativeSep);
25854
26458
  if (!isContained) {
25855
26459
  throw new Error(`Invalid thread path (traversal attempt): ${threadId}`);
@@ -25858,7 +26462,7 @@ function threadFilePath(projectPath, threadId) {
25858
26462
  }
25859
26463
  function ensureThreadDir(projectPath) {
25860
26464
  ensureAgonHome();
25861
- mkdirSync21(threadDirFor(projectPath), { recursive: true });
26465
+ mkdirSync23(threadDirFor(projectPath), { recursive: true });
25862
26466
  }
25863
26467
  var LOCK_MAX_RETRIES = 8;
25864
26468
  var LOCK_BASE_DELAY_MS = 20;
@@ -25868,9 +26472,9 @@ function threadLockPath(projectPath, threadId) {
25868
26472
  async function acquireLock(lockPath) {
25869
26473
  for (let attempt = 0; attempt < LOCK_MAX_RETRIES; attempt++) {
25870
26474
  try {
25871
- const fd = openSync(lockPath, "wx", 384);
25872
- writeFileSync22(fd, String(process.pid));
25873
- closeSync(fd);
26475
+ const fd = openSync2(lockPath, "wx", 384);
26476
+ writeFileSync25(fd, String(process.pid));
26477
+ closeSync2(fd);
25874
26478
  return attempt;
25875
26479
  } catch (err) {
25876
26480
  if (err?.code !== "EEXIST") throw err;
@@ -25882,7 +26486,7 @@ async function acquireLock(lockPath) {
25882
26486
  }
25883
26487
  function releaseLock(lockPath) {
25884
26488
  try {
25885
- unlinkSync9(lockPath);
26489
+ unlinkSync10(lockPath);
25886
26490
  } catch {
25887
26491
  }
25888
26492
  }
@@ -26042,14 +26646,14 @@ var ContextThread = class {
26042
26646
  const now = Date.now();
26043
26647
  if (config2.threadId) {
26044
26648
  const candidatePath = threadFilePath(this.projectPath, config2.threadId);
26045
- if (existsSync23(candidatePath)) {
26649
+ if (existsSync25(candidatePath)) {
26046
26650
  try {
26047
- const stat = statSync19(candidatePath);
26651
+ const stat = statSync20(candidatePath);
26048
26652
  if (stat.size > MAX_THREAD_FILE_BYTES) {
26049
26653
  console.warn(`[agon] context-thread: ${candidatePath} is ${stat.size} bytes (> ${MAX_THREAD_FILE_BYTES}), refusing to load. Run /thread compact or /thread fork.`);
26050
26654
  throw new Error("thread file too large");
26051
26655
  }
26052
- const raw = readFileSync27(candidatePath, "utf-8");
26656
+ const raw = readFileSync30(candidatePath, "utf-8");
26053
26657
  const snap = JSON.parse(raw);
26054
26658
  if (snap && typeof snap === "object" && Array.isArray(snap.messages)) {
26055
26659
  const filteredMessages = (snap.messages ?? []).filter((m) => m && m.role !== "system");
@@ -26067,9 +26671,9 @@ var ContextThread = class {
26067
26671
  this.fileTouches = snap.fileTouches ?? {};
26068
26672
  this.hydrated = true;
26069
26673
  const jPathOnLoad = threadFilePath(this.projectPath, this.threadId).replace(/\.json$/, ".journal.jsonl");
26070
- if (existsSync23(jPathOnLoad)) {
26674
+ if (existsSync25(jPathOnLoad)) {
26071
26675
  try {
26072
- const journalLines = readFileSync27(jPathOnLoad, "utf-8").split("\n").filter(Boolean);
26676
+ const journalLines = readFileSync30(jPathOnLoad, "utf-8").split("\n").filter(Boolean);
26073
26677
  const knownOnLoad = new Set(this.messages.map((m) => m.id));
26074
26678
  let merged = false;
26075
26679
  for (const line of journalLines) {
@@ -26153,7 +26757,7 @@ var ContextThread = class {
26153
26757
  ensureThreadDir(this.projectPath);
26154
26758
  const jPath = threadJournalPath(this.projectPath, this.threadId);
26155
26759
  const line = JSON.stringify({ _kind: "msg", ...msg }) + "\n";
26156
- appendFileSync2(jPath, line, { encoding: "utf-8", mode: 384, flag: "a" });
26760
+ appendFileSync3(jPath, line, { encoding: "utf-8", mode: 384, flag: "a" });
26157
26761
  this.journaledIds.add(msg.id);
26158
26762
  } catch {
26159
26763
  }
@@ -26339,8 +26943,8 @@ ${msg.content}` };
26339
26943
  let bytes = 0;
26340
26944
  try {
26341
26945
  const path = threadFilePath(this.projectPath, this.threadId);
26342
- if (existsSync23(path)) {
26343
- bytes = readFileSync27(path, "utf-8").length;
26946
+ if (existsSync25(path)) {
26947
+ bytes = readFileSync30(path, "utf-8").length;
26344
26948
  }
26345
26949
  } catch {
26346
26950
  }
@@ -26372,12 +26976,12 @@ ${msg.content}` };
26372
26976
  const tmpPath = target + ".tmp";
26373
26977
  let fd = -1;
26374
26978
  try {
26375
- fd = openSync(tmpPath, "w", 384);
26376
- writeFileSync22(fd, body, "utf-8");
26979
+ fd = openSync2(tmpPath, "w", 384);
26980
+ writeFileSync25(fd, body, "utf-8");
26377
26981
  fsyncSync(fd);
26378
26982
  } finally {
26379
26983
  if (fd >= 0) try {
26380
- closeSync(fd);
26984
+ closeSync2(fd);
26381
26985
  } catch {
26382
26986
  }
26383
26987
  }
@@ -26389,7 +26993,7 @@ ${msg.content}` };
26389
26993
  this.dirty = false;
26390
26994
  this.hydrated = true;
26391
26995
  const jPath = threadJournalPath(this.projectPath, this.threadId);
26392
- if (existsSync23(jPath)) unlinkSync9(jPath);
26996
+ if (existsSync25(jPath)) unlinkSync10(jPath);
26393
26997
  this.journaledIds.clear();
26394
26998
  } catch {
26395
26999
  }
@@ -26421,9 +27025,9 @@ ${msg.content}` };
26421
27025
  }
26422
27026
  try {
26423
27027
  const jPath = threadJournalPath(this.projectPath, this.threadId);
26424
- if (existsSync23(jPath)) {
27028
+ if (existsSync25(jPath)) {
26425
27029
  try {
26426
- const journalLines = readFileSync27(jPath, "utf-8").split("\n").filter(Boolean);
27030
+ const journalLines = readFileSync30(jPath, "utf-8").split("\n").filter(Boolean);
26427
27031
  const known = new Set(this.messages.map((m) => m.id));
26428
27032
  for (const line of journalLines) {
26429
27033
  try {
@@ -26442,11 +27046,11 @@ ${msg.content}` };
26442
27046
  console.warn(`[agon] context-thread: journal merge failed (will overwrite): ${err instanceof Error ? err.message : String(err)}`);
26443
27047
  }
26444
27048
  }
26445
- if (existsSync23(target)) {
27049
+ if (existsSync25(target)) {
26446
27050
  try {
26447
- const stat = statSync19(target);
27051
+ const stat = statSync20(target);
26448
27052
  if (stat.size <= MAX_THREAD_FILE_BYTES) {
26449
- const raw = readFileSync27(target, "utf-8");
27053
+ const raw = readFileSync30(target, "utf-8");
26450
27054
  const onDisk = JSON.parse(raw);
26451
27055
  if (onDisk && Array.isArray(onDisk.messages)) {
26452
27056
  const known = new Set(this.messages.map((m) => m.id));
@@ -26484,13 +27088,13 @@ ${msg.content}` };
26484
27088
  const body = JSON.stringify(snapshot, null, 2) + "\n";
26485
27089
  let fd = -1;
26486
27090
  try {
26487
- fd = openSync(tmpPath, "w", 384);
26488
- writeFileSync22(fd, body, "utf-8");
27091
+ fd = openSync2(tmpPath, "w", 384);
27092
+ writeFileSync25(fd, body, "utf-8");
26489
27093
  fsyncSync(fd);
26490
27094
  } finally {
26491
27095
  if (fd >= 0) {
26492
27096
  try {
26493
- closeSync(fd);
27097
+ closeSync2(fd);
26494
27098
  } catch {
26495
27099
  }
26496
27100
  }
@@ -26504,7 +27108,7 @@ ${msg.content}` };
26504
27108
  this.dirty = false;
26505
27109
  this.hydrated = true;
26506
27110
  try {
26507
- if (existsSync23(jPath)) unlinkSync9(jPath);
27111
+ if (existsSync25(jPath)) unlinkSync10(jPath);
26508
27112
  this.journaledIds.clear();
26509
27113
  } catch {
26510
27114
  }
@@ -26525,8 +27129,8 @@ ${msg.content}` };
26525
27129
  function loadActivePointer() {
26526
27130
  try {
26527
27131
  const path = activePointerPath();
26528
- if (existsSync23(path)) {
26529
- const raw = readFileSync27(path, "utf-8");
27132
+ if (existsSync25(path)) {
27133
+ const raw = readFileSync30(path, "utf-8");
26530
27134
  const parsed = JSON.parse(raw);
26531
27135
  if (parsed && typeof parsed === "object" && parsed.byProject) {
26532
27136
  return parsed;
@@ -26540,9 +27144,9 @@ function loadActivePointer() {
26540
27144
  function saveActivePointer(pointer) {
26541
27145
  ensureAgonHome();
26542
27146
  const path = activePointerPath();
26543
- mkdirSync21(threadsDir(), { recursive: true });
27147
+ mkdirSync23(threadsDir(), { recursive: true });
26544
27148
  const tmpPath = path + ".tmp";
26545
- writeFileSync22(tmpPath, JSON.stringify(pointer, null, 2) + "\n", "utf-8");
27149
+ writeFileSync25(tmpPath, JSON.stringify(pointer, null, 2) + "\n", "utf-8");
26546
27150
  renameSync11(tmpPath, path);
26547
27151
  }
26548
27152
  var _WeakRefCtor = globalThis.WeakRef;
@@ -26598,9 +27202,9 @@ async function forkActiveThread(projectPath, systemPrompt) {
26598
27202
  }
26599
27203
  function listThreadsForProject(projectPath) {
26600
27204
  const dir = threadDirFor(projectPath);
26601
- if (!existsSync23(dir)) return [];
27205
+ if (!existsSync25(dir)) return [];
26602
27206
  try {
26603
- 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));
26604
27208
  } catch (err) {
26605
27209
  console.warn(`[agon] context-thread: failed to list threads: ${err instanceof Error ? err.message : String(err)}`);
26606
27210
  return [];
@@ -26608,9 +27212,9 @@ function listThreadsForProject(projectPath) {
26608
27212
  }
26609
27213
  function deleteThread(projectPath, threadId) {
26610
27214
  try {
26611
- unlinkSync9(threadFilePath(projectPath, threadId));
27215
+ unlinkSync10(threadFilePath(projectPath, threadId));
26612
27216
  try {
26613
- unlinkSync9(threadJournalPath(projectPath, threadId));
27217
+ unlinkSync10(threadJournalPath(projectPath, threadId));
26614
27218
  } catch {
26615
27219
  }
26616
27220
  return true;
@@ -26961,7 +27565,7 @@ var AgentSession = class {
26961
27565
  this.state = "running";
26962
27566
  const perStepSec = this.config.perStepTimeoutSec ?? Math.floor(remainingMs / 1e3);
26963
27567
  const timeoutSec = Math.min(perStepSec, Math.floor(remainingMs / 1e3));
26964
- const promptTokens = estimateTokens(prompt);
27568
+ const promptTokens = estimateTokens2(prompt);
26965
27569
  const onEvent = opts?.onEvent;
26966
27570
  const thread = this.config.thread;
26967
27571
  const windowTokens = this.config.contextWindowTokens;
@@ -27022,7 +27626,7 @@ var AgentSession = class {
27022
27626
  }
27023
27627
  if (this.abortController.signal.aborted) {
27024
27628
  this.state = "cancelled";
27025
- const partialResponseTokens = estimateTokens(result.response ?? "");
27629
+ const partialResponseTokens = estimateTokens2(result.response ?? "");
27026
27630
  const partialTotal = promptTokens + partialResponseTokens;
27027
27631
  this.turnsUsed += 1;
27028
27632
  this.tokensUsed += partialTotal;
@@ -27054,7 +27658,7 @@ var AgentSession = class {
27054
27658
  engineFault: result.engineFault ?? false
27055
27659
  };
27056
27660
  }
27057
- const responseTokens = estimateTokens(result.response);
27661
+ const responseTokens = estimateTokens2(result.response);
27058
27662
  const stepTokens = promptTokens + responseTokens;
27059
27663
  const stepCost = estimateCost(this.config.engineId, stepTokens, this.config.api.model);
27060
27664
  this.turnsUsed += 1;
@@ -27140,7 +27744,7 @@ var AgentSession = class {
27140
27744
  };
27141
27745
 
27142
27746
  // ../core/src/generated/cesar/agent-team.ts
27143
- import { join as join28 } from "path";
27747
+ import { join as join31 } from "path";
27144
27748
  import { randomBytes as randomBytes2 } from "crypto";
27145
27749
  function makeAgentTeamError(message, cause) {
27146
27750
  const err = new Error(`AgentTeam: ${message}`);
@@ -27223,7 +27827,7 @@ var AgentTeam = class {
27223
27827
  if (!this.config.isolate) {
27224
27828
  return { m, wt: null };
27225
27829
  }
27226
- 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);
27227
27831
  worktreeCreate(root, wt, this.baseSha);
27228
27832
  return { m, wt };
27229
27833
  });
@@ -27556,10 +28160,10 @@ function buildAgentSynthesisPrompt(opts) {
27556
28160
  let remaining = maxLoserContent;
27557
28161
  for (let i = 0; i < opts.losers.length; i++) {
27558
28162
  const loser = opts.losers[i];
27559
- const header = `## OTHER ENGINE ${i + 1}: ${loser.engineId}${loser.passedFitness ? " (passed fitness gate)" : " (did NOT pass fitness gate)"}`;
27560
- 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);
27561
28165
  lines.push(`<untrusted_data engine="${loser.engineId}">`);
27562
- remaining -= header.length + 50;
28166
+ remaining -= header2.length + 50;
27563
28167
  if (remaining <= 0) {
27564
28168
  lines.push(`*(trimmed for prompt budget)*`);
27565
28169
  lines.push(`</untrusted_data>`);
@@ -28049,10 +28653,10 @@ function hooksOutput(results) {
28049
28653
  }
28050
28654
 
28051
28655
  // ../core/src/generated/blocks/skill-loader.ts
28052
- import { readFileSync as readFileSync28, readdirSync as readdirSync17, existsSync as existsSync24 } from "fs";
28053
- 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";
28054
28658
  import { homedir as homedir15 } from "os";
28055
- import { fileURLToPath as fileURLToPath3 } from "url";
28659
+ import { fileURLToPath as fileURLToPath4 } from "url";
28056
28660
  function parseFrontmatter(content) {
28057
28661
  const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
28058
28662
  if (!match) {
@@ -28071,7 +28675,7 @@ function parseFrontmatter(content) {
28071
28675
  }
28072
28676
  function loadSkillFile(filePath) {
28073
28677
  try {
28074
- const content = readFileSync28(filePath, "utf-8");
28678
+ const content = readFileSync31(filePath, "utf-8");
28075
28679
  const { meta: meta3, body } = parseFrontmatter(content);
28076
28680
  if (!meta3.name || !meta3.trigger) return null;
28077
28681
  return {
@@ -28089,11 +28693,11 @@ function loadSkillFile(filePath) {
28089
28693
  }
28090
28694
  function loadSkillsFromDir(dir, source) {
28091
28695
  const skills = [];
28092
- if (!existsSync24(dir)) return skills;
28696
+ if (!existsSync26(dir)) return skills;
28093
28697
  try {
28094
- const files = readdirSync17(dir).filter((f) => f.endsWith(".md"));
28698
+ const files = readdirSync18(dir).filter((f) => f.endsWith(".md"));
28095
28699
  for (const file2 of files) {
28096
- const skill = loadSkillFile(join29(dir, file2));
28700
+ const skill = loadSkillFile(join32(dir, file2));
28097
28701
  if (skill) {
28098
28702
  skill.source = source;
28099
28703
  skills.push(skill);
@@ -28107,12 +28711,12 @@ function loadSkillsFromDir(dir, source) {
28107
28711
  function loadSkills(cwd) {
28108
28712
  const skills = [];
28109
28713
  const override = process.env.AGON_HOME?.trim();
28110
- const home = override ? resolve24(override) : join29(homedir15(), ".agon");
28111
- 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");
28112
28716
  skills.push(...loadSkillsFromDir(builtinDir, "builtin"));
28113
- skills.push(...loadSkillsFromDir(join29(home, "skills"), "global"));
28717
+ skills.push(...loadSkillsFromDir(join32(home, "skills"), "global"));
28114
28718
  if (cwd) {
28115
- skills.push(...loadSkillsFromDir(join29(cwd, ".agon", "skills"), "project"));
28719
+ skills.push(...loadSkillsFromDir(join32(cwd, ".agon", "skills"), "project"));
28116
28720
  }
28117
28721
  const seen = /* @__PURE__ */ new Map();
28118
28722
  for (const skill of skills) {
@@ -28129,17 +28733,17 @@ function renderSkillPrompt(skill, input) {
28129
28733
  }
28130
28734
 
28131
28735
  // ../core/src/generated/blocks/engine-memory.ts
28132
- import { readFileSync as readFileSync29, writeFileSync as writeFileSync23, mkdirSync as mkdirSync22, renameSync as renameSync12 } from "fs";
28133
- 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";
28134
28738
  import { homedir as homedir16 } from "os";
28135
28739
  function memoryPath() {
28136
28740
  const override = process.env.AGON_HOME?.trim();
28137
- const home = override ? resolve25(override) : join30(homedir16(), ".agon");
28138
- return join30(home, "engine-memory.json");
28741
+ const home = override ? resolve25(override) : join33(homedir16(), ".agon");
28742
+ return join33(home, "engine-memory.json");
28139
28743
  }
28140
28744
  function loadEngineMemory() {
28141
28745
  try {
28142
- return JSON.parse(readFileSync29(memoryPath(), "utf-8"));
28746
+ return JSON.parse(readFileSync32(memoryPath(), "utf-8"));
28143
28747
  } catch (err) {
28144
28748
  if (err.code !== "ENOENT") {
28145
28749
  console.warn(`[agon] failed to load engine memory: ${err instanceof Error ? err.message : String(err)}`);
@@ -28149,12 +28753,12 @@ function loadEngineMemory() {
28149
28753
  }
28150
28754
  function saveEngineMemory(record2) {
28151
28755
  const override = process.env.AGON_HOME?.trim();
28152
- const home = override ? resolve25(override) : join30(homedir16(), ".agon");
28153
- mkdirSync22(home, { recursive: true });
28756
+ const home = override ? resolve25(override) : join33(homedir16(), ".agon");
28757
+ mkdirSync24(home, { recursive: true });
28154
28758
  record2.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
28155
28759
  const path = memoryPath();
28156
28760
  const tmpPath = path + ".tmp";
28157
- writeFileSync23(tmpPath, JSON.stringify(record2, null, 2) + "\n");
28761
+ writeFileSync26(tmpPath, JSON.stringify(record2, null, 2) + "\n");
28158
28762
  renameSync12(tmpPath, path);
28159
28763
  }
28160
28764
  function ensureProfile(record2, engineId) {
@@ -28346,7 +28950,7 @@ function rankByTaskClass(engineIds, taskClass) {
28346
28950
  let specialization;
28347
28951
  if (i === 0 && r.total >= 3) {
28348
28952
  role = "lead";
28349
- 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.`;
28350
28954
  } else if (i === ranked.length - 1 && r.total >= 3) {
28351
28955
  role = "challenger";
28352
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.`;
@@ -28382,13 +28986,13 @@ function assignForgeRoles(engineIds, taskClass) {
28382
28986
  }
28383
28987
 
28384
28988
  // ../core/src/generated/blocks/sidechain-logger.ts
28385
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync23 } from "fs";
28386
- import { join as join31 } from "path";
28989
+ import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync25 } from "fs";
28990
+ import { join as join34 } from "path";
28387
28991
  function createSidechainLogger(opts) {
28388
28992
  const suffix = opts.parentId ? `_sidechain_${opts.parentId}` : "";
28389
28993
  const filename = `${opts.sessionType}_${opts.sessionId}${suffix}.jsonl`;
28390
- const logPath = join31(opts.outputDir, filename);
28391
- mkdirSync23(opts.outputDir, { recursive: true });
28994
+ const logPath = join34(opts.outputDir, filename);
28995
+ mkdirSync25(opts.outputDir, { recursive: true });
28392
28996
  function log(type, engineId, data) {
28393
28997
  const event = {
28394
28998
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -28400,7 +29004,7 @@ function createSidechainLogger(opts) {
28400
29004
  ...data && { data }
28401
29005
  };
28402
29006
  try {
28403
- appendFileSync3(logPath, JSON.stringify(event) + "\n");
29007
+ appendFileSync4(logPath, JSON.stringify(event) + "\n");
28404
29008
  } catch (err) {
28405
29009
  console.warn(`[agon] sidechain write failed (${logPath}): ${err instanceof Error ? err.message : String(err)}`);
28406
29010
  }
@@ -28417,12 +29021,12 @@ function createSidechainLogger(opts) {
28417
29021
  }
28418
29022
 
28419
29023
  // ../core/src/generated/blocks/provenance.ts
28420
- import { readFileSync as readFileSync30, writeFileSync as writeFileSync24, mkdirSync as mkdirSync24 } from "fs";
28421
- 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";
28422
29026
  import { createHash as createHash7 } from "crypto";
28423
29027
  function sha256OfFile(path) {
28424
29028
  try {
28425
- return "sha256:" + createHash7("sha256").update(readFileSync30(path)).digest("hex");
29029
+ return "sha256:" + createHash7("sha256").update(readFileSync33(path)).digest("hex");
28426
29030
  } catch (e) {
28427
29031
  console.warn(`[agon] provenance: could not hash ${path}: ${e instanceof Error ? e.message : String(e)}`);
28428
29032
  return "unavailable";
@@ -28582,18 +29186,18 @@ function renderProvenanceMarkdown(led) {
28582
29186
  function writeProvenanceReport(manifest, manifestPath, outDir, format) {
28583
29187
  const fmt = format ?? "md";
28584
29188
  const ledger = buildForgeProvenance(manifest, manifestPath);
28585
- mkdirSync24(outDir, { recursive: true });
29189
+ mkdirSync26(outDir, { recursive: true });
28586
29190
  if (fmt === "md" || fmt === "both") {
28587
- const mdPath = resolve26(join32(outDir, "provenance.md"));
28588
- writeFileSync24(mdPath, renderProvenanceMarkdown(ledger), "utf-8");
29191
+ const mdPath = resolve26(join35(outDir, "provenance.md"));
29192
+ writeFileSync27(mdPath, renderProvenanceMarkdown(ledger), "utf-8");
28589
29193
  if (fmt === "md") return mdPath;
28590
29194
  }
28591
29195
  if (fmt === "json" || fmt === "both") {
28592
- const jsonPath = resolve26(join32(outDir, "provenance.json"));
28593
- writeFileSync24(jsonPath, renderProvenanceJson(ledger), "utf-8");
29196
+ const jsonPath = resolve26(join35(outDir, "provenance.json"));
29197
+ writeFileSync27(jsonPath, renderProvenanceJson(ledger), "utf-8");
28594
29198
  if (fmt === "json") return jsonPath;
28595
29199
  }
28596
- return resolve26(join32(outDir, "provenance.md"));
29200
+ return resolve26(join35(outDir, "provenance.md"));
28597
29201
  }
28598
29202
 
28599
29203
  // ../core/src/generated/models/extension-manifest.ts
@@ -28699,8 +29303,8 @@ var CommandRegistry = class {
28699
29303
  };
28700
29304
 
28701
29305
  // ../core/src/generated/blocks/extension-loader.ts
28702
- import { join as join33, resolve as resolve27 } from "path";
28703
- 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";
28704
29308
  import { homedir as homedir17 } from "os";
28705
29309
 
28706
29310
  // ../core/src/generated/signals/event-bus.ts
@@ -28791,31 +29395,31 @@ function bridgeShellHooks(bus, hooks) {
28791
29395
  function discoverExtensionDirs(cwd) {
28792
29396
  const results = [];
28793
29397
  const override = process.env.AGON_HOME?.trim();
28794
- const home = override ? resolve27(override) : join33(homedir17(), ".agon");
28795
- const userDir = join33(home, "extensions");
28796
- if (existsSync25(userDir)) {
29398
+ const home = override ? resolve27(override) : join36(homedir17(), ".agon");
29399
+ const userDir = join36(home, "extensions");
29400
+ if (existsSync27(userDir)) {
28797
29401
  try {
28798
- const entries = readdirSync18(userDir, { withFileTypes: true });
29402
+ const entries = readdirSync19(userDir, { withFileTypes: true });
28799
29403
  for (const entry of entries) {
28800
29404
  if (entry.isDirectory()) {
28801
- const manifestPath = join33(userDir, entry.name, "manifest.json");
28802
- if (existsSync25(manifestPath)) {
28803
- 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" });
28804
29408
  }
28805
29409
  }
28806
29410
  }
28807
29411
  } catch {
28808
29412
  }
28809
29413
  }
28810
- const repoDir = join33(cwd, ".agon", "extensions");
28811
- if (existsSync25(repoDir)) {
29414
+ const repoDir = join36(cwd, ".agon", "extensions");
29415
+ if (existsSync27(repoDir)) {
28812
29416
  try {
28813
- const entries = readdirSync18(repoDir, { withFileTypes: true });
29417
+ const entries = readdirSync19(repoDir, { withFileTypes: true });
28814
29418
  for (const entry of entries) {
28815
29419
  if (entry.isDirectory()) {
28816
- const manifestPath = join33(repoDir, entry.name, "manifest.json");
28817
- if (existsSync25(manifestPath)) {
28818
- 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" });
28819
29423
  }
28820
29424
  }
28821
29425
  }
@@ -28825,9 +29429,9 @@ function discoverExtensionDirs(cwd) {
28825
29429
  return results;
28826
29430
  }
28827
29431
  function loadExtensionManifest(dir, source) {
28828
- const manifestPath = join33(dir, "manifest.json");
29432
+ const manifestPath = join36(dir, "manifest.json");
28829
29433
  try {
28830
- const raw = JSON.parse(readFileSync31(manifestPath, "utf-8"));
29434
+ const raw = JSON.parse(readFileSync34(manifestPath, "utf-8"));
28831
29435
  const result = validateManifest(raw, manifestPath);
28832
29436
  if (!result.ok || !result.data) {
28833
29437
  console.warn(`[agon] skipping extension ${dir}: ${result.error}`);
@@ -28896,7 +29500,7 @@ function registerExtensionEngines(ext, engineRegistry) {
28896
29500
  for (const enginePath of enginePaths) {
28897
29501
  try {
28898
29502
  const fullPath = resolve27(ext.dir, enginePath);
28899
- const raw = JSON.parse(readFileSync31(fullPath, "utf-8"));
29503
+ const raw = JSON.parse(readFileSync34(fullPath, "utf-8"));
28900
29504
  if (raw.id) {
28901
29505
  engineRegistry.register(raw);
28902
29506
  registered.push(raw.id);
@@ -29045,7 +29649,7 @@ function registerBuiltinCommands(registry2) {
29045
29649
  // Info
29046
29650
  { name: "tokens", desc: " \u2014 show token usage & costs", category: "info" },
29047
29651
  { name: "doctor", desc: "[engines|harness] \u2014 diagnose engines, worktree, or Cesar harness", category: "info" },
29048
- { name: "leaderboard", desc: " \u2014 ELO rankings", category: "info" },
29652
+ { name: "leaderboard", desc: " \u2014 Glicko rankings", category: "info" },
29049
29653
  { name: "history", desc: "[id] \u2014 past forge runs", category: "info" },
29050
29654
  { name: "provenance", desc: "[id] [-f md|json|both] [-o file] \u2014 AI-contribution / transparency report", category: "info" },
29051
29655
  { name: "flow", desc: " \u2014 log this session", category: "info" },
@@ -29311,8 +29915,8 @@ function computeContributionWeights(team, trace) {
29311
29915
  }
29312
29916
 
29313
29917
  // ../core/src/generated/teams/team-elo.ts
29314
- import { readFileSync as readFileSync32, writeFileSync as writeFileSync25, mkdirSync as mkdirSync25, renameSync as renameSync13 } from "fs";
29315
- 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";
29316
29920
  function defaultCompositionRating(lineupKey2) {
29317
29921
  return { lineupKey: lineupKey2, rating: 1500, wins: 0, losses: 0, draws: 0, matches: 0 };
29318
29922
  }
@@ -29321,7 +29925,7 @@ function defaultRoleRating(engineId, role) {
29321
29925
  }
29322
29926
  function loadTeamElo() {
29323
29927
  try {
29324
- return JSON.parse(readFileSync32(TEAM_ELO_PATH, "utf-8"));
29928
+ return JSON.parse(readFileSync35(TEAM_ELO_PATH, "utf-8"));
29325
29929
  } catch (err) {
29326
29930
  if (err.code !== "ENOENT") {
29327
29931
  console.warn(`[agon] failed to load team ELO: ${err instanceof Error ? err.message : String(err)}`);
@@ -29330,10 +29934,10 @@ function loadTeamElo() {
29330
29934
  }
29331
29935
  }
29332
29936
  function saveTeamElo(record2) {
29333
- mkdirSync25(dirname13(TEAM_ELO_PATH), { recursive: true });
29937
+ mkdirSync27(dirname14(TEAM_ELO_PATH), { recursive: true });
29334
29938
  record2.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
29335
29939
  const tmpPath = TEAM_ELO_PATH + ".tmp";
29336
- writeFileSync25(tmpPath, JSON.stringify(record2, null, 2) + "\n");
29940
+ writeFileSync28(tmpPath, JSON.stringify(record2, null, 2) + "\n");
29337
29941
  renameSync13(tmpPath, TEAM_ELO_PATH);
29338
29942
  }
29339
29943
  function expectedScore(rA, rB) {
@@ -29528,6 +30132,7 @@ export {
29528
30132
  hasProjectBrief,
29529
30133
  isKernProject,
29530
30134
  scanProjectContext,
30135
+ buildKernContextSpine,
29531
30136
  collectSourceFiles,
29532
30137
  extractSymbols,
29533
30138
  buildCodebaseMap,
@@ -29541,7 +30146,7 @@ export {
29541
30146
  snapshotWorkspace,
29542
30147
  resolveWorkingDir,
29543
30148
  ensureCurrentWorkspace,
29544
- estimateTokens,
30149
+ estimateTokens2 as estimateTokens,
29545
30150
  estimateCost,
29546
30151
  tracker,
29547
30152
  createPlan,
@@ -29696,7 +30301,29 @@ export {
29696
30301
  mimeFromExt,
29697
30302
  resolveImagePath,
29698
30303
  buildImageAttachment,
30304
+ normalizeDroppedPath,
29699
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,
29700
30327
  FLOWS_DIR,
29701
30328
  FRICTION_TAGS,
29702
30329
  logFlow,
@@ -29829,4 +30456,4 @@ export {
29829
30456
  predictTeamRating,
29830
30457
  updateTeamElo
29831
30458
  };
29832
- //# sourceMappingURL=chunk-C22VTCS6.js.map
30459
+ //# sourceMappingURL=chunk-HAJIKZGU.js.map