@kernlang/agon 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/{chunk-4NTH3EAR.js → chunk-3PDYVGRS.js} +77 -22
  2. package/dist/chunk-3PDYVGRS.js.map +1 -0
  3. package/dist/{chunk-GPYWJO2Q.js → chunk-6IF2AV4Y.js} +8 -7
  4. package/dist/{chunk-GPYWJO2Q.js.map → chunk-6IF2AV4Y.js.map} +1 -1
  5. package/dist/{chunk-73ETZFDH.js → chunk-7WZ2O5WZ.js} +4 -4
  6. package/dist/{chunk-DGTU4UWQ.js → chunk-NBV37VMW.js} +2 -2
  7. package/dist/{chunk-46WNYE4R.js → chunk-PUNBDLQO.js} +31 -31
  8. package/dist/chunk-PUNBDLQO.js.map +1 -0
  9. package/dist/{chunk-HAJIKZGU.js → chunk-TMNHJOKU.js} +408 -68
  10. package/dist/chunk-TMNHJOKU.js.map +1 -0
  11. package/dist/{chunk-SOUF7XTW.js → chunk-XWHC6VAH.js} +3 -2
  12. package/dist/chunk-XWHC6VAH.js.map +1 -0
  13. package/dist/{dispatch-XHLJ44TF.js → dispatch-S3CR5HKX.js} +2 -2
  14. package/dist/engines/codex.json +3 -0
  15. package/dist/{forge-ZI7NE73F.js → forge-GUOEJ5DJ.js} +6 -6
  16. package/dist/index.js +28 -24
  17. package/dist/index.js.map +1 -1
  18. package/dist/{plan-mode-KIXDKD63.js → plan-mode-35BONR7S.js} +6 -6
  19. package/dist/{src-4A5FVACG.js → src-3NWTITZM.js} +9 -3
  20. package/dist/{update-DLPMYTF3.js → update-H3LE4ZSI.js} +5 -5
  21. package/package.json +3 -2
  22. package/dist/chunk-46WNYE4R.js.map +0 -1
  23. package/dist/chunk-4NTH3EAR.js.map +0 -1
  24. package/dist/chunk-HAJIKZGU.js.map +0 -1
  25. package/dist/chunk-SOUF7XTW.js.map +0 -1
  26. /package/dist/{chunk-73ETZFDH.js.map → chunk-7WZ2O5WZ.js.map} +0 -0
  27. /package/dist/{chunk-DGTU4UWQ.js.map → chunk-NBV37VMW.js.map} +0 -0
  28. /package/dist/{dispatch-XHLJ44TF.js.map → dispatch-S3CR5HKX.js.map} +0 -0
  29. /package/dist/{forge-ZI7NE73F.js.map → forge-GUOEJ5DJ.js.map} +0 -0
  30. /package/dist/{plan-mode-KIXDKD63.js.map → plan-mode-35BONR7S.js.map} +0 -0
  31. /package/dist/{src-4A5FVACG.js.map → src-3NWTITZM.js.map} +0 -0
  32. /package/dist/{update-DLPMYTF3.js.map → update-H3LE4ZSI.js.map} +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  __require,
6
6
  __toCommonJS,
7
7
  apiStreamDispatchWithHistory
8
- } from "./chunk-SOUF7XTW.js";
8
+ } from "./chunk-XWHC6VAH.js";
9
9
 
10
10
  // ../core/src/generated/signals/glicko.ts
11
11
  var glicko_exports = {};
@@ -20018,10 +20018,10 @@ function createBashTool() {
20018
20018
  const readRedirect = tryRedirectToRead(command);
20019
20019
  if (readRedirect) {
20020
20020
  try {
20021
- const { readFileSync: readFileSync36 } = await import("fs");
20021
+ const { readFileSync: readFileSync38 } = await import("fs");
20022
20022
  const { resolve: resolve28 } = await import("path");
20023
20023
  const filePath = resolve28(ctx.cwd, readRedirect.file);
20024
- const content = readFileSync36(filePath, "utf-8");
20024
+ const content = readFileSync38(filePath, "utf-8");
20025
20025
  const lines = content.split("\n");
20026
20026
  const offset = readRedirect.offset ?? 0;
20027
20027
  const limit = readRedirect.limit ?? lines.length;
@@ -22065,6 +22065,8 @@ function cesarPlanMarkdownPath(planId) {
22065
22065
  }
22066
22066
  return full;
22067
22067
  }
22068
+ var CESAR_STEP_TYPE_TABLE = { self: true, forge: true, teamforge: true, delegate: true, brainstorm: true, campfire: true, tribunal: true, pipeline: true, review: true, agent: true, "team-agent": true };
22069
+ var CESAR_STEP_TYPES = Object.keys(CESAR_STEP_TYPE_TABLE);
22068
22070
  function createCesarPlan(intent, steps) {
22069
22071
  const id = `cplan-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
22070
22072
  const initializedSteps = steps.map((s) => Object.assign({}, s, { state: s.dependsOn && s.dependsOn.length > 0 ? "blocked" : "pending" }));
@@ -22080,10 +22082,11 @@ function advanceCesarStep(plan, stepId, result) {
22080
22082
  const stepIdx = plan.steps.findIndex((s) => s.id === stepId);
22081
22083
  if (stepIdx === -1) return plan;
22082
22084
  const isSuccess = result.status === "success";
22083
- const stepState = isSuccess ? "done" : "failed";
22085
+ const isPaused = result.status === "paused";
22086
+ const stepState = isSuccess ? "done" : isPaused ? "pending" : "failed";
22084
22087
  const now = (/* @__PURE__ */ new Date()).toISOString();
22085
22088
  let newSteps = plan.steps.map(
22086
- (s, i) => i === stepIdx ? { ...s, state: stepState, result, completedAt: now } : s
22089
+ (s, i) => i === stepIdx ? { ...s, state: stepState, result: isPaused ? void 0 : result, completedAt: isPaused ? void 0 : now } : s
22087
22090
  );
22088
22091
  if (isSuccess) {
22089
22092
  newSteps = newSteps.map((s) => {
@@ -22723,13 +22726,16 @@ function latestChatSession() {
22723
22726
  }
22724
22727
 
22725
22728
  // ../core/src/generated/blocks/image.ts
22726
- import { existsSync as existsSync19 } from "fs";
22729
+ import { existsSync as existsSync19, readFileSync as readFileSync23, statSync as statSync16 } from "fs";
22727
22730
  import { resolve as resolve19, basename as basename4, extname as extname2 } from "path";
22728
22731
  import { homedir as homedir11 } from "os";
22729
22732
  import { fileURLToPath as fileURLToPath3 } from "url";
22730
22733
  var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg", ".bmp"]);
22731
22734
  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" };
22732
22735
  var IMG_CMD_REGEX = /^\/img\s+(.+)$/i;
22736
+ var MAX_DISPATCH_IMAGE_BYTES = 5 * 1024 * 1024;
22737
+ var MAX_DISPATCH_IMAGES = 4;
22738
+ var DISPATCH_VISION_MIME = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp", "image/gif"]);
22733
22739
  function isImagePath(filePath) {
22734
22740
  const ext = extname2(filePath).toLowerCase();
22735
22741
  return IMAGE_EXTENSIONS.has(ext);
@@ -22816,9 +22822,55 @@ function extractImagesFromInput(input, cwd) {
22816
22822
  text = text.replace(/\s{2,}/g, " ").trim();
22817
22823
  return { text, images };
22818
22824
  }
22825
+ function encodeImagesRaw(paths, maxBytes, maxImages) {
22826
+ const lim = maxBytes ?? MAX_DISPATCH_IMAGE_BYTES;
22827
+ const cap = maxImages ?? MAX_DISPATCH_IMAGES;
22828
+ const images = [];
22829
+ const skipped = [];
22830
+ const kb = (n) => `${Math.round(n / 1024)}KB`;
22831
+ for (const p of paths) {
22832
+ const name = basename4(p);
22833
+ if (images.length >= cap) {
22834
+ skipped.push(`${name} (exceeds ${cap}-image limit)`);
22835
+ continue;
22836
+ }
22837
+ try {
22838
+ if (!existsSync19(p)) {
22839
+ skipped.push(`${name} (not found)`);
22840
+ continue;
22841
+ }
22842
+ const mediaType = mimeFromExt(p);
22843
+ if (!DISPATCH_VISION_MIME.has(mediaType)) {
22844
+ skipped.push(`${name} (unsupported type ${mediaType})`);
22845
+ continue;
22846
+ }
22847
+ const st = statSync16(p);
22848
+ if (!st.isFile()) {
22849
+ skipped.push(`${name} (not a regular file)`);
22850
+ continue;
22851
+ }
22852
+ if (st.size > lim) {
22853
+ skipped.push(`${name} (${kb(st.size)} over ${kb(lim)} limit)`);
22854
+ continue;
22855
+ }
22856
+ const data = readFileSync23(p).toString("base64");
22857
+ images.push({ data, mediaType });
22858
+ } catch {
22859
+ skipped.push(`${name} (read error)`);
22860
+ }
22861
+ }
22862
+ return { images, skipped };
22863
+ }
22864
+ function encodeImagesForDispatch(paths, maxBytes, maxImages) {
22865
+ const { images, skipped } = encodeImagesRaw(paths, maxBytes, maxImages);
22866
+ return {
22867
+ parts: images.map((i) => ({ type: "image", image: `data:${i.mediaType};base64,${i.data}`, mediaType: i.mediaType })),
22868
+ skipped
22869
+ };
22870
+ }
22819
22871
 
22820
22872
  // ../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";
22873
+ import { mkdirSync as mkdirSync18, existsSync as existsSync20, readFileSync as readFileSync24, writeFileSync as writeFileSync19, appendFileSync as appendFileSync2, readdirSync as readdirSync14, openSync, closeSync, unlinkSync as unlinkSync9, statSync as statSync17 } from "fs";
22822
22874
  import { join as join22 } from "path";
22823
22875
  var LOCK_TIMEOUT_MS = 2e3;
22824
22876
  var LOCK_STALE_MS = 5e3;
@@ -22843,7 +22895,7 @@ function roomExists(roomId) {
22843
22895
  }
22844
22896
  function readMeta(roomId) {
22845
22897
  try {
22846
- return JSON.parse(readFileSync23(metaPath(roomId), "utf-8"));
22898
+ return JSON.parse(readFileSync24(metaPath(roomId), "utf-8"));
22847
22899
  } catch {
22848
22900
  return null;
22849
22901
  }
@@ -22904,7 +22956,7 @@ function withRoomLock(roomId, work) {
22904
22956
  } catch (err) {
22905
22957
  if (err?.code !== "EEXIST") throw err;
22906
22958
  try {
22907
- const st = statSync16(lock);
22959
+ const st = statSync17(lock);
22908
22960
  if (Date.now() - st.mtimeMs > LOCK_STALE_MS) {
22909
22961
  unlinkSync9(lock);
22910
22962
  continue;
@@ -22960,7 +23012,7 @@ function appendEvent(roomId, input) {
22960
23012
  function readEvents(roomId, sinceSeq, limit) {
22961
23013
  let raw;
22962
23014
  try {
22963
- raw = readFileSync23(eventsPath(roomId), "utf-8");
23015
+ raw = readFileSync24(eventsPath(roomId), "utf-8");
22964
23016
  } catch {
22965
23017
  return [];
22966
23018
  }
@@ -22988,7 +23040,7 @@ function isRoomClosed(roomId) {
22988
23040
  }
22989
23041
 
22990
23042
  // ../core/src/generated/rooms/presence.ts
22991
- import { mkdirSync as mkdirSync19, readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "fs";
23043
+ import { mkdirSync as mkdirSync19, readFileSync as readFileSync25, writeFileSync as writeFileSync20 } from "fs";
22992
23044
  import { join as join23 } from "path";
22993
23045
  var PRESENCE_TTL_MS = 9e4;
22994
23046
  function presencePath(roomId) {
@@ -22996,7 +23048,7 @@ function presencePath(roomId) {
22996
23048
  }
22997
23049
  function readPresenceRaw(roomId) {
22998
23050
  try {
22999
- return JSON.parse(readFileSync24(presencePath(roomId), "utf-8"));
23051
+ return JSON.parse(readFileSync25(presencePath(roomId), "utf-8"));
23000
23052
  } catch {
23001
23053
  return {};
23002
23054
  }
@@ -23039,14 +23091,14 @@ function listPresence(roomId) {
23039
23091
  }
23040
23092
 
23041
23093
  // ../core/src/generated/rooms/leases.ts
23042
- import { readFileSync as readFileSync25, writeFileSync as writeFileSync21 } from "fs";
23094
+ import { readFileSync as readFileSync26, writeFileSync as writeFileSync21 } from "fs";
23043
23095
  import { join as join24 } from "path";
23044
23096
  function leasesPath(roomId) {
23045
23097
  return join24(roomDir(roomId), "leases.json");
23046
23098
  }
23047
23099
  function readActiveLease(roomId) {
23048
23100
  try {
23049
- const raw = JSON.parse(readFileSync25(leasesPath(roomId), "utf-8"));
23101
+ const raw = JSON.parse(readFileSync26(leasesPath(roomId), "utf-8"));
23050
23102
  if (!raw || !raw.leaseId) return null;
23051
23103
  if (Date.now() >= new Date(raw.expiresAt).getTime()) return null;
23052
23104
  return raw;
@@ -23129,7 +23181,7 @@ function evaluateStop(state, config2, events) {
23129
23181
  }
23130
23182
 
23131
23183
  // ../core/src/generated/signals/flow.ts
23132
- import { readFileSync as readFileSync26, writeFileSync as writeFileSync22, mkdirSync as mkdirSync20, readdirSync as readdirSync15 } from "fs";
23184
+ import { readFileSync as readFileSync27, writeFileSync as writeFileSync22, mkdirSync as mkdirSync20, readdirSync as readdirSync15 } from "fs";
23133
23185
  import { join as join25, resolve as resolve20 } from "path";
23134
23186
  import { homedir as homedir12 } from "os";
23135
23187
  function getFlowsDir() {
@@ -23162,7 +23214,7 @@ function readFlows(limit) {
23162
23214
  const records = [];
23163
23215
  for (const file2 of files) {
23164
23216
  try {
23165
- const data = JSON.parse(readFileSync26(join25(getFlowsDir(), file2), "utf-8"));
23217
+ const data = JSON.parse(readFileSync27(join25(getFlowsDir(), file2), "utf-8"));
23166
23218
  records.push(data);
23167
23219
  } catch (err) {
23168
23220
  console.warn(`[agon] skipping malformed flow record ${file2}: ${err instanceof Error ? err.message : String(err)}`);
@@ -23591,7 +23643,7 @@ async function companionDispatch(opts) {
23591
23643
  }
23592
23644
 
23593
23645
  // ../core/src/generated/signals/models-registry.ts
23594
- import { readFileSync as readFileSync27, writeFileSync as writeFileSync23, mkdirSync as mkdirSync21, existsSync as existsSync22, statSync as statSync17 } from "fs";
23646
+ import { readFileSync as readFileSync28, writeFileSync as writeFileSync23, mkdirSync as mkdirSync21, existsSync as existsSync22, statSync as statSync18 } from "fs";
23595
23647
  import { join as join26 } from "path";
23596
23648
  var CACHE_TTL_MS = 36e5;
23597
23649
  var MODELS_DEV_URL = "https://models.dev/api.json";
@@ -23600,10 +23652,10 @@ async function fetchModelsRegistry() {
23600
23652
  const cacheFile = join26(cacheDir, "models-dev.json");
23601
23653
  if (existsSync22(cacheFile)) {
23602
23654
  try {
23603
- const stat = statSync17(cacheFile);
23655
+ const stat = statSync18(cacheFile);
23604
23656
  const age = Date.now() - stat.mtimeMs;
23605
23657
  if (age < CACHE_TTL_MS) {
23606
- return JSON.parse(readFileSync27(cacheFile, "utf-8"));
23658
+ return JSON.parse(readFileSync28(cacheFile, "utf-8"));
23607
23659
  }
23608
23660
  } catch (_e) {
23609
23661
  console.warn(`[agon] models-registry: cache read failed, refetching: ${_e instanceof Error ? _e.message : String(_e)}`);
@@ -23612,7 +23664,7 @@ async function fetchModelsRegistry() {
23612
23664
  const response = await fetch(MODELS_DEV_URL);
23613
23665
  if (!response.ok) {
23614
23666
  if (existsSync22(cacheFile)) {
23615
- return JSON.parse(readFileSync27(cacheFile, "utf-8"));
23667
+ return JSON.parse(readFileSync28(cacheFile, "utf-8"));
23616
23668
  }
23617
23669
  throw new Error(`Failed to fetch models registry: ${response.status}`);
23618
23670
  }
@@ -23739,7 +23791,7 @@ function modelEntryToEngineDef(entry) {
23739
23791
 
23740
23792
  // ../core/src/generated/signals/cli-models-registry.ts
23741
23793
  import { execSync as execSync4 } from "child_process";
23742
- import { readFileSync as readFileSync28, writeFileSync as writeFileSync24, mkdirSync as mkdirSync22, existsSync as existsSync23, statSync as statSync18 } from "fs";
23794
+ import { readFileSync as readFileSync29, writeFileSync as writeFileSync24, mkdirSync as mkdirSync22, existsSync as existsSync23, statSync as statSync19 } from "fs";
23743
23795
  import { join as join27 } from "path";
23744
23796
  import { homedir as homedir13 } from "os";
23745
23797
  import { createRequire as createRequire4 } from "module";
@@ -23754,9 +23806,9 @@ function readProbedCliModels(engineId, ttlMs) {
23754
23806
  try {
23755
23807
  const file2 = probedModelsCacheFile(engineId);
23756
23808
  if (!existsSync23(file2)) return null;
23757
- const age = Date.now() - statSync18(file2).mtimeMs;
23809
+ const age = Date.now() - statSync19(file2).mtimeMs;
23758
23810
  if (age > (ttlMs ?? PROBE_TTL_MS)) return null;
23759
- const data = JSON.parse(readFileSync28(file2, "utf-8"));
23811
+ const data = JSON.parse(readFileSync29(file2, "utf-8"));
23760
23812
  const raw = Array.isArray(data?.models) ? data.models : [];
23761
23813
  const models = raw.map((m) => ({ id: String(m.id ?? ""), name: String(m.name ?? m.id ?? ""), current: !!m.current })).filter((m) => m.name);
23762
23814
  return models.length > 0 ? models : null;
@@ -23991,6 +24043,7 @@ async function discoverCliModelsAsync() {
23991
24043
  // ../core/src/generated/sessions/session-companion.ts
23992
24044
  import { spawn as spawn3 } from "child_process";
23993
24045
  import { createInterface as createInterface2 } from "readline";
24046
+ import { existsSync as existsSync24 } from "fs";
23994
24047
  function createCompanionSession(config2) {
23995
24048
  let proc = null;
23996
24049
  let alive = false;
@@ -24296,9 +24349,37 @@ ${config2.systemPrompt}
24296
24349
  ${message}`;
24297
24350
  }
24298
24351
  firstTurn = false;
24352
+ const input = [{ type: "text", text: message, text_elements: [] }];
24353
+ if (opts.images?.length) {
24354
+ if (config2.engine.capabilities?.includes("vision")) {
24355
+ let attached = 0;
24356
+ const skipped = [];
24357
+ for (const p of opts.images) {
24358
+ if (attached >= MAX_DISPATCH_IMAGES) {
24359
+ skipped.push(`${p} (exceeds ${MAX_DISPATCH_IMAGES}-image limit)`);
24360
+ continue;
24361
+ }
24362
+ if (!existsSync24(p) || !isImagePath(p)) {
24363
+ skipped.push(`${p} (not found or not an image)`);
24364
+ continue;
24365
+ }
24366
+ if (!DISPATCH_VISION_MIME.has(mimeFromExt(p))) {
24367
+ skipped.push(`${p} (unsupported type ${mimeFromExt(p)})`);
24368
+ continue;
24369
+ }
24370
+ input.push({ type: "localImage", path: p });
24371
+ attached++;
24372
+ }
24373
+ if (skipped.length) {
24374
+ chunks.push({ type: "status", content: `image(s) not sent: ${skipped.join("; ")}` });
24375
+ }
24376
+ } else {
24377
+ chunks.push({ type: "status", content: `${config2.engine.id} has no vision capability \u2014 ${opts.images.length} image(s) not sent to the model` });
24378
+ }
24379
+ }
24299
24380
  await sendRpc("turn/start", {
24300
24381
  threadId,
24301
- input: [{ type: "text", text: message, text_elements: [] }]
24382
+ input
24302
24383
  });
24303
24384
  while (!turnDone) {
24304
24385
  if (chunks.length > 0) {
@@ -25031,7 +25112,41 @@ function createResumeSession(config2) {
25031
25112
  }
25032
25113
  firstTurn = false;
25033
25114
  }
25034
- messageHistory.push({ role: "user", content: opts.message });
25115
+ const hasVision = !!config2.engine.capabilities?.includes("vision");
25116
+ let turnImageParts = [];
25117
+ if (opts.images?.length) {
25118
+ if (hasVision) {
25119
+ const enc = encodeImagesForDispatch(opts.images);
25120
+ turnImageParts = enc.parts;
25121
+ if (enc.skipped.length) {
25122
+ yield { type: "status", content: `image(s) not sent: ${enc.skipped.join("; ")}` };
25123
+ }
25124
+ } else {
25125
+ yield { type: "status", content: `${config2.engine.id} has no vision capability \u2014 ${opts.images.length} image(s) not sent to the model` };
25126
+ }
25127
+ }
25128
+ const userTurnMsg = { role: "user", content: opts.message };
25129
+ messageHistory.push(userTurnMsg);
25130
+ const withImages = (history) => {
25131
+ if (!turnImageParts.length) return history;
25132
+ let idx = history.indexOf(userTurnMsg);
25133
+ if (idx < 0) {
25134
+ for (let i = history.length - 1; i >= 0; i--) {
25135
+ const m = history[i];
25136
+ if (m?.role === "user" && typeof m.content === "string" && m.content === userTurnMsg.content) {
25137
+ idx = i;
25138
+ break;
25139
+ }
25140
+ }
25141
+ }
25142
+ if (idx < 0) return history;
25143
+ const base = history[idx];
25144
+ const text = typeof base.content === "string" ? base.content : "";
25145
+ const content = text.trim() ? [{ type: "text", text }, ...turnImageParts] : [...turnImageParts];
25146
+ const cloned = history.slice();
25147
+ cloned[idx] = { ...base, content };
25148
+ return cloned;
25149
+ };
25035
25150
  const estimateSingle = (m) => {
25036
25151
  if (typeof m.content === "string") return Math.ceil(m.content.length / 3.5);
25037
25152
  if (m.content === null && m.tool_calls) {
@@ -25190,7 +25305,7 @@ ${newSummary.decisions.map((d) => ` - ${d}`).join("\n")}` : "",
25190
25305
  const tier3CompactionEnabled = process.env.AGON_DISABLE_TIER3_COMPACTION !== "1";
25191
25306
  if (tier3CompactionEnabled && afterTier2 > CONTEXT_LIMIT - COMPACTION_BUFFER && config2.engine.api) {
25192
25307
  try {
25193
- const { apiDispatch: apiDispatch2 } = await import("./dispatch-XHLJ44TF.js");
25308
+ const { apiDispatch: apiDispatch2 } = await import("./dispatch-S3CR5HKX.js");
25194
25309
  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.
25195
25310
 
25196
25311
  CONTEXT TO SUMMARIZE:
@@ -25325,7 +25440,7 @@ ${compactionResult.stdout}` },
25325
25440
  } else {
25326
25441
  yield { type: "status", content: `tool loop turn ${step}/${budget}\u2026` };
25327
25442
  }
25328
- const gen = apiStreamDispatchWithHistory(config2.engine.api, messageHistory, config2.engine.timeout ?? 180, opts.signal, effectiveTools);
25443
+ const gen = apiStreamDispatchWithHistory(config2.engine.api, withImages(messageHistory), config2.engine.timeout ?? 180, opts.signal, effectiveTools);
25329
25444
  try {
25330
25445
  while (true) {
25331
25446
  const { value, done: done2 } = await gen.next();
@@ -25866,6 +25981,191 @@ ${compactionResult.stdout}` },
25866
25981
  return session;
25867
25982
  }
25868
25983
 
25984
+ // ../core/src/generated/sessions/session-pty.ts
25985
+ import { existsSync as existsSync25, readFileSync as readFileSync30, rmSync as rmSync5 } from "fs";
25986
+ function createPtySession(config2) {
25987
+ let claudeSession = null;
25988
+ let alive = false;
25989
+ let firstTurn = true;
25990
+ let turnActive = false;
25991
+ let pendingDrain = null;
25992
+ const TURN_TIMEOUT_MS = 15 * 60 * 1e3;
25993
+ function buildExtraArgv() {
25994
+ const args = [];
25995
+ if (config2.mcpServers && config2.mcpServers.length > 0) {
25996
+ const mcpConfig = JSON.stringify({
25997
+ mcpServers: Object.fromEntries(
25998
+ config2.mcpServers.map((s) => [s.name ?? s.command ?? "mcp", s])
25999
+ )
26000
+ });
26001
+ args.push("--mcp-config", mcpConfig, "--strict-mcp-config");
26002
+ }
26003
+ args.push("--disallowedTools", "Bash Edit Write MultiEdit NotebookEdit");
26004
+ args.push("--allowedTools", "Read Grep Glob mcp__agon-orchestration");
26005
+ if (config2.claudePtyLaunchArgs && config2.claudePtyLaunchArgs.length > 0) {
26006
+ args.push(...config2.claudePtyLaunchArgs);
26007
+ }
26008
+ return args;
26009
+ }
26010
+ function readAnswer() {
26011
+ const p = config2.answerChannelPath;
26012
+ if (!p) return null;
26013
+ try {
26014
+ if (!existsSync25(p)) return null;
26015
+ const parsed = JSON.parse(readFileSync30(p, "utf-8"));
26016
+ const t = parsed?.text;
26017
+ return typeof t === "string" ? t : null;
26018
+ } catch {
26019
+ return null;
26020
+ }
26021
+ }
26022
+ function clearAnswer() {
26023
+ const p = config2.answerChannelPath;
26024
+ if (!p) return;
26025
+ try {
26026
+ rmSync5(p, { force: true });
26027
+ } catch {
26028
+ }
26029
+ }
26030
+ const session = {
26031
+ get alive() {
26032
+ return alive;
26033
+ },
26034
+ sessionId: null,
26035
+ engineId: config2.engine.id,
26036
+ get pid() {
26037
+ return null;
26038
+ },
26039
+ async start() {
26040
+ if (alive) return;
26041
+ const mod = await import("@kernlang/agon-engines/cli/claude.js");
26042
+ claudeSession = await mod.ClaudeCliSession.spawn({
26043
+ mode: "agent",
26044
+ cwd: config2.cwd,
26045
+ extraArgv: buildExtraArgv(),
26046
+ daemonTimeoutMs: 6e4
26047
+ });
26048
+ alive = true;
26049
+ firstTurn = true;
26050
+ },
26051
+ async *send(opts) {
26052
+ if (turnActive) {
26053
+ yield { type: "error", content: "claude PTY session busy (concurrent turn rejected)" };
26054
+ return;
26055
+ }
26056
+ turnActive = true;
26057
+ try {
26058
+ if (pendingDrain) {
26059
+ try {
26060
+ await pendingDrain;
26061
+ } catch {
26062
+ }
26063
+ pendingDrain = null;
26064
+ }
26065
+ if (!alive || !claudeSession) {
26066
+ try {
26067
+ await session.start();
26068
+ } catch (e) {
26069
+ yield { type: "error", content: `claude PTY session not alive: ${e instanceof Error ? e.message : String(e)}` };
26070
+ return;
26071
+ }
26072
+ }
26073
+ if (opts.signal?.aborted) {
26074
+ yield { type: "done", content: "cancelled" };
26075
+ return;
26076
+ }
26077
+ clearAnswer();
26078
+ const sys = firstTurn ? opts.systemPrompt ?? config2.systemPrompt : void 0;
26079
+ firstTurn = false;
26080
+ const composed = sys ? `[System Instructions]
26081
+ ${sys}
26082
+
26083
+ [User Message]
26084
+ ${opts.message}` : opts.message;
26085
+ let aborted2 = false;
26086
+ const onAbort = () => {
26087
+ aborted2 = true;
26088
+ try {
26089
+ claudeSession?.close?.();
26090
+ } catch {
26091
+ }
26092
+ claudeSession = null;
26093
+ alive = false;
26094
+ };
26095
+ opts.signal?.addEventListener("abort", onAbort, { once: true });
26096
+ let scrapedFinal = "";
26097
+ let driverError = null;
26098
+ const it = claudeSession.askStream(composed, TURN_TIMEOUT_MS);
26099
+ const driver = (async () => {
26100
+ try {
26101
+ let res = await it.next();
26102
+ while (!res.done) {
26103
+ res = await it.next();
26104
+ }
26105
+ scrapedFinal = typeof res.value === "string" ? res.value : "";
26106
+ } catch (e) {
26107
+ driverError = e;
26108
+ }
26109
+ })();
26110
+ pendingDrain = driver;
26111
+ let driverDone = false;
26112
+ void driver.then(() => {
26113
+ driverDone = true;
26114
+ });
26115
+ await new Promise((resolve28) => {
26116
+ const tick = setInterval(() => {
26117
+ if (driverDone || readAnswer() !== null) {
26118
+ clearInterval(tick);
26119
+ resolve28();
26120
+ }
26121
+ }, 100);
26122
+ void driver.finally(() => {
26123
+ clearInterval(tick);
26124
+ resolve28();
26125
+ });
26126
+ });
26127
+ opts.signal?.removeEventListener("abort", onAbort);
26128
+ if (aborted2) {
26129
+ yield { type: "done", content: "cancelled" };
26130
+ return;
26131
+ }
26132
+ const answer = readAnswer();
26133
+ if (answer !== null && answer.length > 0) {
26134
+ yield { type: "text", content: answer };
26135
+ yield { type: "done", content: "end_turn" };
26136
+ return;
26137
+ }
26138
+ await driver;
26139
+ pendingDrain = null;
26140
+ if (driverError) {
26141
+ alive = false;
26142
+ claudeSession = null;
26143
+ yield { type: "error", content: `claude PTY turn failed: ${driverError instanceof Error ? driverError.message : String(driverError)}` };
26144
+ return;
26145
+ }
26146
+ if (scrapedFinal && scrapedFinal.trim()) {
26147
+ yield { type: "text", content: scrapedFinal };
26148
+ }
26149
+ yield { type: "done", content: "end_turn" };
26150
+ } finally {
26151
+ turnActive = false;
26152
+ }
26153
+ },
26154
+ close() {
26155
+ try {
26156
+ claudeSession?.close?.();
26157
+ } catch {
26158
+ }
26159
+ claudeSession = null;
26160
+ alive = false;
26161
+ },
26162
+ getMessageHistory() {
26163
+ return [];
26164
+ }
26165
+ };
26166
+ return session;
26167
+ }
26168
+
25869
26169
  // ../core/src/generated/sessions/persistent-session.ts
25870
26170
  function createPersistentSession(config2) {
25871
26171
  const engine = config2.engine;
@@ -25873,7 +26173,11 @@ function createPersistentSession(config2) {
25873
26173
  return createResumeSession(config2);
25874
26174
  }
25875
26175
  if ((engine.companion?.protocol === "stream-json" || engine.id === "claude" || engine.binary === "claude") && config2.binaryPath) {
25876
- return createStreamJsonSession(config2);
26176
+ const printOptOut = process.env.AGON_CLAUDE_PRINT;
26177
+ if (printOptOut === "1" || printOptOut === "true") {
26178
+ return createStreamJsonSession(config2);
26179
+ }
26180
+ return createPtySession(config2);
25877
26181
  }
25878
26182
  if (engine.companion && engine.companion.protocol === "acp") {
25879
26183
  return createAcpSession(config2);
@@ -25968,7 +26272,7 @@ function createStreamBridge(dispatch, opts) {
25968
26272
  }
25969
26273
 
25970
26274
  // ../core/src/generated/forge/virtual-fs.ts
25971
- import { readFileSync as readFileSync29, existsSync as existsSync24, readdirSync as readdirSync16, statSync as statSync19 } from "fs";
26275
+ import { readFileSync as readFileSync31, existsSync as existsSync26, readdirSync as readdirSync16, statSync as statSync20 } from "fs";
25972
26276
  import { join as join28, resolve as resolve21, relative as relative8, dirname as dirname12 } from "path";
25973
26277
  import { createHash as createHash5 } from "crypto";
25974
26278
  function createFileSnapshot(rootDir) {
@@ -25985,16 +26289,16 @@ function snapshotRead(snap, absPath) {
25985
26289
  return snap.cache.get(key) ?? null;
25986
26290
  }
25987
26291
  try {
25988
- if (!existsSync24(key)) {
26292
+ if (!existsSync26(key)) {
25989
26293
  snap.cache.set(key, null);
25990
26294
  return null;
25991
26295
  }
25992
- const st = statSync19(key);
26296
+ const st = statSync20(key);
25993
26297
  if (!st.isFile()) {
25994
26298
  snap.cache.set(key, null);
25995
26299
  return null;
25996
26300
  }
25997
- const content = readFileSync29(key, "utf-8");
26301
+ const content = readFileSync31(key, "utf-8");
25998
26302
  snap.cache.set(key, content);
25999
26303
  return content;
26000
26304
  } catch (e) {
@@ -26007,7 +26311,7 @@ function snapshotList(snap, absDir) {
26007
26311
  try {
26008
26312
  return readdirSync16(dir).filter((f) => {
26009
26313
  try {
26010
- return statSync19(join28(dir, f)).isFile();
26314
+ return statSync20(join28(dir, f)).isFile();
26011
26315
  } catch {
26012
26316
  return false;
26013
26317
  }
@@ -26421,7 +26725,7 @@ ${sessionLines.join("\n")}`);
26421
26725
  }
26422
26726
 
26423
26727
  // ../core/src/generated/cesar/context-thread.ts
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";
26728
+ import { readFileSync as readFileSync32, writeFileSync as writeFileSync25, mkdirSync as mkdirSync23, renameSync as renameSync11, existsSync as existsSync27, readdirSync as readdirSync17, unlinkSync as unlinkSync10, statSync as statSync21, chmodSync as chmodSync2, openSync as openSync2, fsyncSync, closeSync as closeSync2, appendFileSync as appendFileSync3 } from "fs";
26425
26729
  import { join as join30, resolve as resolve23, basename as basename6 } from "path";
26426
26730
  import { randomUUID as randomUUID5, createHash as createHash6 } from "crypto";
26427
26731
  import { homedir as homedir14 } from "os";
@@ -26646,14 +26950,14 @@ var ContextThread = class {
26646
26950
  const now = Date.now();
26647
26951
  if (config2.threadId) {
26648
26952
  const candidatePath = threadFilePath(this.projectPath, config2.threadId);
26649
- if (existsSync25(candidatePath)) {
26953
+ if (existsSync27(candidatePath)) {
26650
26954
  try {
26651
- const stat = statSync20(candidatePath);
26955
+ const stat = statSync21(candidatePath);
26652
26956
  if (stat.size > MAX_THREAD_FILE_BYTES) {
26653
26957
  console.warn(`[agon] context-thread: ${candidatePath} is ${stat.size} bytes (> ${MAX_THREAD_FILE_BYTES}), refusing to load. Run /thread compact or /thread fork.`);
26654
26958
  throw new Error("thread file too large");
26655
26959
  }
26656
- const raw = readFileSync30(candidatePath, "utf-8");
26960
+ const raw = readFileSync32(candidatePath, "utf-8");
26657
26961
  const snap = JSON.parse(raw);
26658
26962
  if (snap && typeof snap === "object" && Array.isArray(snap.messages)) {
26659
26963
  const filteredMessages = (snap.messages ?? []).filter((m) => m && m.role !== "system");
@@ -26671,9 +26975,9 @@ var ContextThread = class {
26671
26975
  this.fileTouches = snap.fileTouches ?? {};
26672
26976
  this.hydrated = true;
26673
26977
  const jPathOnLoad = threadFilePath(this.projectPath, this.threadId).replace(/\.json$/, ".journal.jsonl");
26674
- if (existsSync25(jPathOnLoad)) {
26978
+ if (existsSync27(jPathOnLoad)) {
26675
26979
  try {
26676
- const journalLines = readFileSync30(jPathOnLoad, "utf-8").split("\n").filter(Boolean);
26980
+ const journalLines = readFileSync32(jPathOnLoad, "utf-8").split("\n").filter(Boolean);
26677
26981
  const knownOnLoad = new Set(this.messages.map((m) => m.id));
26678
26982
  let merged = false;
26679
26983
  for (const line of journalLines) {
@@ -26943,8 +27247,8 @@ ${msg.content}` };
26943
27247
  let bytes = 0;
26944
27248
  try {
26945
27249
  const path = threadFilePath(this.projectPath, this.threadId);
26946
- if (existsSync25(path)) {
26947
- bytes = readFileSync30(path, "utf-8").length;
27250
+ if (existsSync27(path)) {
27251
+ bytes = readFileSync32(path, "utf-8").length;
26948
27252
  }
26949
27253
  } catch {
26950
27254
  }
@@ -26993,7 +27297,7 @@ ${msg.content}` };
26993
27297
  this.dirty = false;
26994
27298
  this.hydrated = true;
26995
27299
  const jPath = threadJournalPath(this.projectPath, this.threadId);
26996
- if (existsSync25(jPath)) unlinkSync10(jPath);
27300
+ if (existsSync27(jPath)) unlinkSync10(jPath);
26997
27301
  this.journaledIds.clear();
26998
27302
  } catch {
26999
27303
  }
@@ -27025,9 +27329,9 @@ ${msg.content}` };
27025
27329
  }
27026
27330
  try {
27027
27331
  const jPath = threadJournalPath(this.projectPath, this.threadId);
27028
- if (existsSync25(jPath)) {
27332
+ if (existsSync27(jPath)) {
27029
27333
  try {
27030
- const journalLines = readFileSync30(jPath, "utf-8").split("\n").filter(Boolean);
27334
+ const journalLines = readFileSync32(jPath, "utf-8").split("\n").filter(Boolean);
27031
27335
  const known = new Set(this.messages.map((m) => m.id));
27032
27336
  for (const line of journalLines) {
27033
27337
  try {
@@ -27046,11 +27350,11 @@ ${msg.content}` };
27046
27350
  console.warn(`[agon] context-thread: journal merge failed (will overwrite): ${err instanceof Error ? err.message : String(err)}`);
27047
27351
  }
27048
27352
  }
27049
- if (existsSync25(target)) {
27353
+ if (existsSync27(target)) {
27050
27354
  try {
27051
- const stat = statSync20(target);
27355
+ const stat = statSync21(target);
27052
27356
  if (stat.size <= MAX_THREAD_FILE_BYTES) {
27053
- const raw = readFileSync30(target, "utf-8");
27357
+ const raw = readFileSync32(target, "utf-8");
27054
27358
  const onDisk = JSON.parse(raw);
27055
27359
  if (onDisk && Array.isArray(onDisk.messages)) {
27056
27360
  const known = new Set(this.messages.map((m) => m.id));
@@ -27108,7 +27412,7 @@ ${msg.content}` };
27108
27412
  this.dirty = false;
27109
27413
  this.hydrated = true;
27110
27414
  try {
27111
- if (existsSync25(jPath)) unlinkSync10(jPath);
27415
+ if (existsSync27(jPath)) unlinkSync10(jPath);
27112
27416
  this.journaledIds.clear();
27113
27417
  } catch {
27114
27418
  }
@@ -27129,8 +27433,8 @@ ${msg.content}` };
27129
27433
  function loadActivePointer() {
27130
27434
  try {
27131
27435
  const path = activePointerPath();
27132
- if (existsSync25(path)) {
27133
- const raw = readFileSync30(path, "utf-8");
27436
+ if (existsSync27(path)) {
27437
+ const raw = readFileSync32(path, "utf-8");
27134
27438
  const parsed = JSON.parse(raw);
27135
27439
  if (parsed && typeof parsed === "object" && parsed.byProject) {
27136
27440
  return parsed;
@@ -27202,7 +27506,7 @@ async function forkActiveThread(projectPath, systemPrompt) {
27202
27506
  }
27203
27507
  function listThreadsForProject(projectPath) {
27204
27508
  const dir = threadDirFor(projectPath);
27205
- if (!existsSync25(dir)) return [];
27509
+ if (!existsSync27(dir)) return [];
27206
27510
  try {
27207
27511
  return readdirSync17(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5));
27208
27512
  } catch (err) {
@@ -27260,6 +27564,39 @@ var PlanCostEstimator = class {
27260
27564
  };
27261
27565
  var planCostEstimator = new PlanCostEstimator();
27262
27566
 
27567
+ // ../core/src/generated/cesar/plan-validation.ts
27568
+ var VALID_STEP_TYPES = new Set(CESAR_STEP_TYPES);
27569
+ function sanitizePlanSteps(rawSteps) {
27570
+ const SAFE_ID = /^[a-z0-9_-]{1,64}$/;
27571
+ const sanitizeId = (raw, fallback) => {
27572
+ if (typeof raw === "string" && SAFE_ID.test(raw)) return raw;
27573
+ return fallback;
27574
+ };
27575
+ const input = Array.isArray(rawSteps) ? rawSteps : [];
27576
+ const steps = input.filter((s) => s && VALID_STEP_TYPES.has(s.type)).map((s, i) => {
27577
+ const est = planCostEstimator.estimate(s.type, s.engines ?? []);
27578
+ return {
27579
+ id: sanitizeId(s.id, `step-${i}-${Math.random().toString(36).slice(2, 8)}`),
27580
+ type: s.type,
27581
+ description: typeof s.description === "string" && s.description.trim().length > 0 ? s.description : "(no description)",
27582
+ engines: s.engines,
27583
+ engine: s.engine,
27584
+ fitnessCmd: s.fitnessCmd,
27585
+ tribunalMode: s.tribunalMode,
27586
+ parallel: s.parallel ?? false,
27587
+ dependsOn: s.dependsOn,
27588
+ exports: typeof s.exports === "string" ? [s.exports] : s.exports,
27589
+ imports: typeof s.imports === "string" ? [s.imports] : s.imports,
27590
+ estimatedTokens: est.tokens,
27591
+ estimatedCostUsd: est.costUsd,
27592
+ rationale: s.rationale,
27593
+ verifyCmd: s.verifyCmd
27594
+ };
27595
+ });
27596
+ const dropped = input.length - steps.length;
27597
+ return { steps, dropped };
27598
+ }
27599
+
27263
27600
  // ../core/src/generated/cesar/plan-executor.ts
27264
27601
  function getReadySteps(plan) {
27265
27602
  return plan.steps.filter((s) => s.state === "pending");
@@ -28653,7 +28990,7 @@ function hooksOutput(results) {
28653
28990
  }
28654
28991
 
28655
28992
  // ../core/src/generated/blocks/skill-loader.ts
28656
- import { readFileSync as readFileSync31, readdirSync as readdirSync18, existsSync as existsSync26 } from "fs";
28993
+ import { readFileSync as readFileSync33, readdirSync as readdirSync18, existsSync as existsSync28 } from "fs";
28657
28994
  import { join as join32, dirname as dirname13, resolve as resolve24 } from "path";
28658
28995
  import { homedir as homedir15 } from "os";
28659
28996
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -28675,7 +29012,7 @@ function parseFrontmatter(content) {
28675
29012
  }
28676
29013
  function loadSkillFile(filePath) {
28677
29014
  try {
28678
- const content = readFileSync31(filePath, "utf-8");
29015
+ const content = readFileSync33(filePath, "utf-8");
28679
29016
  const { meta: meta3, body } = parseFrontmatter(content);
28680
29017
  if (!meta3.name || !meta3.trigger) return null;
28681
29018
  return {
@@ -28693,7 +29030,7 @@ function loadSkillFile(filePath) {
28693
29030
  }
28694
29031
  function loadSkillsFromDir(dir, source) {
28695
29032
  const skills = [];
28696
- if (!existsSync26(dir)) return skills;
29033
+ if (!existsSync28(dir)) return skills;
28697
29034
  try {
28698
29035
  const files = readdirSync18(dir).filter((f) => f.endsWith(".md"));
28699
29036
  for (const file2 of files) {
@@ -28733,7 +29070,7 @@ function renderSkillPrompt(skill, input) {
28733
29070
  }
28734
29071
 
28735
29072
  // ../core/src/generated/blocks/engine-memory.ts
28736
- import { readFileSync as readFileSync32, writeFileSync as writeFileSync26, mkdirSync as mkdirSync24, renameSync as renameSync12 } from "fs";
29073
+ import { readFileSync as readFileSync34, writeFileSync as writeFileSync26, mkdirSync as mkdirSync24, renameSync as renameSync12 } from "fs";
28737
29074
  import { join as join33, resolve as resolve25 } from "path";
28738
29075
  import { homedir as homedir16 } from "os";
28739
29076
  function memoryPath() {
@@ -28743,7 +29080,7 @@ function memoryPath() {
28743
29080
  }
28744
29081
  function loadEngineMemory() {
28745
29082
  try {
28746
- return JSON.parse(readFileSync32(memoryPath(), "utf-8"));
29083
+ return JSON.parse(readFileSync34(memoryPath(), "utf-8"));
28747
29084
  } catch (err) {
28748
29085
  if (err.code !== "ENOENT") {
28749
29086
  console.warn(`[agon] failed to load engine memory: ${err instanceof Error ? err.message : String(err)}`);
@@ -29021,12 +29358,12 @@ function createSidechainLogger(opts) {
29021
29358
  }
29022
29359
 
29023
29360
  // ../core/src/generated/blocks/provenance.ts
29024
- import { readFileSync as readFileSync33, writeFileSync as writeFileSync27, mkdirSync as mkdirSync26 } from "fs";
29361
+ import { readFileSync as readFileSync35, writeFileSync as writeFileSync27, mkdirSync as mkdirSync26 } from "fs";
29025
29362
  import { join as join35, resolve as resolve26 } from "path";
29026
29363
  import { createHash as createHash7 } from "crypto";
29027
29364
  function sha256OfFile(path) {
29028
29365
  try {
29029
- return "sha256:" + createHash7("sha256").update(readFileSync33(path)).digest("hex");
29366
+ return "sha256:" + createHash7("sha256").update(readFileSync35(path)).digest("hex");
29030
29367
  } catch (e) {
29031
29368
  console.warn(`[agon] provenance: could not hash ${path}: ${e instanceof Error ? e.message : String(e)}`);
29032
29369
  return "unavailable";
@@ -29304,7 +29641,7 @@ var CommandRegistry = class {
29304
29641
 
29305
29642
  // ../core/src/generated/blocks/extension-loader.ts
29306
29643
  import { join as join36, resolve as resolve27 } from "path";
29307
- import { readdirSync as readdirSync19, readFileSync as readFileSync34, existsSync as existsSync27 } from "fs";
29644
+ import { readdirSync as readdirSync19, readFileSync as readFileSync36, existsSync as existsSync29 } from "fs";
29308
29645
  import { homedir as homedir17 } from "os";
29309
29646
 
29310
29647
  // ../core/src/generated/signals/event-bus.ts
@@ -29397,13 +29734,13 @@ function discoverExtensionDirs(cwd) {
29397
29734
  const override = process.env.AGON_HOME?.trim();
29398
29735
  const home = override ? resolve27(override) : join36(homedir17(), ".agon");
29399
29736
  const userDir = join36(home, "extensions");
29400
- if (existsSync27(userDir)) {
29737
+ if (existsSync29(userDir)) {
29401
29738
  try {
29402
29739
  const entries = readdirSync19(userDir, { withFileTypes: true });
29403
29740
  for (const entry of entries) {
29404
29741
  if (entry.isDirectory()) {
29405
29742
  const manifestPath = join36(userDir, entry.name, "manifest.json");
29406
- if (existsSync27(manifestPath)) {
29743
+ if (existsSync29(manifestPath)) {
29407
29744
  results.push({ dir: join36(userDir, entry.name), source: "user" });
29408
29745
  }
29409
29746
  }
@@ -29412,13 +29749,13 @@ function discoverExtensionDirs(cwd) {
29412
29749
  }
29413
29750
  }
29414
29751
  const repoDir = join36(cwd, ".agon", "extensions");
29415
- if (existsSync27(repoDir)) {
29752
+ if (existsSync29(repoDir)) {
29416
29753
  try {
29417
29754
  const entries = readdirSync19(repoDir, { withFileTypes: true });
29418
29755
  for (const entry of entries) {
29419
29756
  if (entry.isDirectory()) {
29420
29757
  const manifestPath = join36(repoDir, entry.name, "manifest.json");
29421
- if (existsSync27(manifestPath)) {
29758
+ if (existsSync29(manifestPath)) {
29422
29759
  results.push({ dir: join36(repoDir, entry.name), source: "repo" });
29423
29760
  }
29424
29761
  }
@@ -29431,7 +29768,7 @@ function discoverExtensionDirs(cwd) {
29431
29768
  function loadExtensionManifest(dir, source) {
29432
29769
  const manifestPath = join36(dir, "manifest.json");
29433
29770
  try {
29434
- const raw = JSON.parse(readFileSync34(manifestPath, "utf-8"));
29771
+ const raw = JSON.parse(readFileSync36(manifestPath, "utf-8"));
29435
29772
  const result = validateManifest(raw, manifestPath);
29436
29773
  if (!result.ok || !result.data) {
29437
29774
  console.warn(`[agon] skipping extension ${dir}: ${result.error}`);
@@ -29500,7 +29837,7 @@ function registerExtensionEngines(ext, engineRegistry) {
29500
29837
  for (const enginePath of enginePaths) {
29501
29838
  try {
29502
29839
  const fullPath = resolve27(ext.dir, enginePath);
29503
- const raw = JSON.parse(readFileSync34(fullPath, "utf-8"));
29840
+ const raw = JSON.parse(readFileSync36(fullPath, "utf-8"));
29504
29841
  if (raw.id) {
29505
29842
  engineRegistry.register(raw);
29506
29843
  registered.push(raw.id);
@@ -29915,7 +30252,7 @@ function computeContributionWeights(team, trace) {
29915
30252
  }
29916
30253
 
29917
30254
  // ../core/src/generated/teams/team-elo.ts
29918
- import { readFileSync as readFileSync35, writeFileSync as writeFileSync28, mkdirSync as mkdirSync27, renameSync as renameSync13 } from "fs";
30255
+ import { readFileSync as readFileSync37, writeFileSync as writeFileSync28, mkdirSync as mkdirSync27, renameSync as renameSync13 } from "fs";
29919
30256
  import { dirname as dirname14 } from "path";
29920
30257
  function defaultCompositionRating(lineupKey2) {
29921
30258
  return { lineupKey: lineupKey2, rating: 1500, wins: 0, losses: 0, draws: 0, matches: 0 };
@@ -29925,7 +30262,7 @@ function defaultRoleRating(engineId, role) {
29925
30262
  }
29926
30263
  function loadTeamElo() {
29927
30264
  try {
29928
- return JSON.parse(readFileSync35(TEAM_ELO_PATH, "utf-8"));
30265
+ return JSON.parse(readFileSync37(TEAM_ELO_PATH, "utf-8"));
29929
30266
  } catch (err) {
29930
30267
  if (err.code !== "ENOENT") {
29931
30268
  console.warn(`[agon] failed to load team ELO: ${err instanceof Error ? err.message : String(err)}`);
@@ -30272,6 +30609,7 @@ export {
30272
30609
  getCesarPlansDir,
30273
30610
  cesarPlanJsonPath,
30274
30611
  cesarPlanMarkdownPath,
30612
+ CESAR_STEP_TYPES,
30275
30613
  createCesarPlan,
30276
30614
  approveCesarPlan,
30277
30615
  advanceCesarStep,
@@ -30303,6 +30641,7 @@ export {
30303
30641
  buildImageAttachment,
30304
30642
  normalizeDroppedPath,
30305
30643
  extractImagesFromInput,
30644
+ encodeImagesForDispatch,
30306
30645
  roomsDir,
30307
30646
  roomDir,
30308
30647
  slugifyRoomId,
@@ -30371,6 +30710,7 @@ export {
30371
30710
  listThreadsForProject,
30372
30711
  deleteThread,
30373
30712
  planCostEstimator,
30713
+ sanitizePlanSteps,
30374
30714
  getReadySteps,
30375
30715
  executePlan,
30376
30716
  makeAssistantChunk,
@@ -30456,4 +30796,4 @@ export {
30456
30796
  predictTeamRating,
30457
30797
  updateTeamElo
30458
30798
  };
30459
- //# sourceMappingURL=chunk-HAJIKZGU.js.map
30799
+ //# sourceMappingURL=chunk-TMNHJOKU.js.map