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