@kernlang/agon 0.1.5 → 0.1.7

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 (56) hide show
  1. package/dist/{chunk-SOUF7XTW.js → chunk-45YTXJWJ.js} +3 -2
  2. package/dist/chunk-45YTXJWJ.js.map +1 -0
  3. package/dist/{chunk-GPYWJO2Q.js → chunk-6WWOJXG4.js} +108 -50
  4. package/dist/chunk-6WWOJXG4.js.map +1 -0
  5. package/dist/{chunk-4NTH3EAR.js → chunk-AONHRJRW.js} +240 -27
  6. package/dist/chunk-AONHRJRW.js.map +1 -0
  7. package/dist/{chunk-HAJIKZGU.js → chunk-BPKY4OF2.js} +479 -68
  8. package/dist/chunk-BPKY4OF2.js.map +1 -0
  9. package/dist/{chunk-DGTU4UWQ.js → chunk-I2PMSXJ3.js} +2 -2
  10. package/dist/chunk-I2PMSXJ3.js.map +1 -0
  11. package/dist/{chunk-46WNYE4R.js → chunk-RKXVKX25.js} +69 -35
  12. package/dist/chunk-RKXVKX25.js.map +1 -0
  13. package/dist/{chunk-HSPQEDHX.js → chunk-SUT2HDOY.js} +1 -1
  14. package/dist/chunk-SUT2HDOY.js.map +1 -0
  15. package/dist/{chunk-73ETZFDH.js → chunk-WDT5NJOA.js} +4 -4
  16. package/dist/chunk-WDT5NJOA.js.map +1 -0
  17. package/dist/{dispatch-XHLJ44TF.js → dispatch-J4RSWLXM.js} +2 -2
  18. package/dist/dispatch-J4RSWLXM.js.map +1 -0
  19. package/dist/engines/codex.json +3 -0
  20. package/dist/{forge-ZI7NE73F.js → forge-O2SJ5JIQ.js} +6 -6
  21. package/dist/forge-O2SJ5JIQ.js.map +1 -0
  22. package/dist/index.js +396 -60
  23. package/dist/index.js.map +1 -1
  24. package/dist/mcp/engines/agy.json +43 -0
  25. package/dist/mcp/engines/aider.json +40 -0
  26. package/dist/mcp/engines/claude.json +79 -0
  27. package/dist/mcp/engines/codex.json +77 -0
  28. package/dist/mcp/engines/minimax-coding-plan-minimax-m3.json +27 -0
  29. package/dist/mcp/engines/mistral.json +44 -0
  30. package/dist/mcp/engines/ollama.json +35 -0
  31. package/dist/mcp/engines/opencode.json +55 -0
  32. package/dist/mcp/engines/openrouter.json +54 -0
  33. package/dist/mcp/engines/qwen.json +40 -0
  34. package/dist/mcp/index.js +464 -0
  35. package/dist/mcp/index.js.map +1 -0
  36. package/dist/plan-mode-PFLUPGSY.js +17 -0
  37. package/dist/plan-mode-PFLUPGSY.js.map +1 -0
  38. package/dist/{src-4A5FVACG.js → src-253BUXEF.js} +11 -3
  39. package/dist/src-253BUXEF.js.map +1 -0
  40. package/dist/{update-DLPMYTF3.js → update-ODAAXWOD.js} +6 -6
  41. package/dist/update-ODAAXWOD.js.map +1 -0
  42. package/package.json +2 -2
  43. package/dist/chunk-46WNYE4R.js.map +0 -1
  44. package/dist/chunk-4NTH3EAR.js.map +0 -1
  45. package/dist/chunk-73ETZFDH.js.map +0 -1
  46. package/dist/chunk-DGTU4UWQ.js.map +0 -1
  47. package/dist/chunk-GPYWJO2Q.js.map +0 -1
  48. package/dist/chunk-HAJIKZGU.js.map +0 -1
  49. package/dist/chunk-HSPQEDHX.js.map +0 -1
  50. package/dist/chunk-SOUF7XTW.js.map +0 -1
  51. package/dist/dispatch-XHLJ44TF.js.map +0 -1
  52. package/dist/forge-ZI7NE73F.js.map +0 -1
  53. package/dist/plan-mode-KIXDKD63.js +0 -17
  54. package/dist/plan-mode-KIXDKD63.js.map +0 -1
  55. package/dist/src-4A5FVACG.js.map +0 -1
  56. package/dist/update-DLPMYTF3.js.map +0 -1
@@ -4,7 +4,7 @@ import {
4
4
  cleanEngineOutput,
5
5
  icons,
6
6
  parseMarkdownBlocks
7
- } from "./chunk-DGTU4UWQ.js";
7
+ } from "./chunk-I2PMSXJ3.js";
8
8
  import {
9
9
  AGON_MODE_NAMES,
10
10
  CORPUS_PATH,
@@ -108,8 +108,9 @@ import {
108
108
  worktreeChangedDiff,
109
109
  worktreeCreate,
110
110
  worktreeDiff,
111
+ worktreePruneOrphaned,
111
112
  worktreeRemoveBestEffort
112
- } from "./chunk-HAJIKZGU.js";
113
+ } from "./chunk-BPKY4OF2.js";
113
114
 
114
115
  // ../forge/src/generated/forge.ts
115
116
  import { randomUUID as randomUUID2 } from "crypto";
@@ -2253,6 +2254,10 @@ ${role.specialization}`);
2253
2254
  for (const wt of worktrees) {
2254
2255
  worktreeRemoveBestEffort(wt.repoRoot, wt.path);
2255
2256
  }
2257
+ try {
2258
+ worktreePruneOrphaned(root);
2259
+ } catch (err) {
2260
+ }
2256
2261
  }
2257
2262
  return manifest;
2258
2263
  }
@@ -6690,7 +6695,7 @@ function filterDefaultOrchestrationEngines(engineIds) {
6690
6695
 
6691
6696
  // src/generated/cesar/brain.ts
6692
6697
  import { join as join14 } from "path";
6693
- import { mkdirSync as mkdirSync13, appendFileSync as appendFileSync2, existsSync as existsSync12, readFileSync as readFileSync13, unlinkSync, readdirSync, writeFileSync as writeFileSync11 } from "fs";
6698
+ import { mkdirSync as mkdirSync13, appendFileSync as appendFileSync2, existsSync as existsSync13, readFileSync as readFileSync13, unlinkSync, readdirSync, writeFileSync as writeFileSync11 } from "fs";
6694
6699
 
6695
6700
  // src/generated/cesar/confidence.ts
6696
6701
  var CONFIDENCE_TIERS = { direct: 96, quickNero: 93, nero: 88, brainstorm: 72, advisor: 72 };
@@ -6758,11 +6763,12 @@ function parseSuggestion(response) {
6758
6763
  }
6759
6764
 
6760
6765
  // src/generated/cesar/session.ts
6761
- import { readFileSync as readFileSync12, statSync as statSync4 } from "fs";
6766
+ import { readFileSync as readFileSync12, statSync as statSync4, existsSync as existsSync12 } from "fs";
6762
6767
  import { isAbsolute as isAbsolute2, resolve as resolve3, dirname as dirname5 } from "path";
6763
6768
  import { join as join12 } from "path";
6764
6769
  import { mkdirSync as mkdirSync11 } from "fs";
6765
- import { fileURLToPath } from "url";
6770
+ import { fileURLToPath, pathToFileURL } from "url";
6771
+ import { createRequire } from "module";
6766
6772
 
6767
6773
  // src/generated/cesar/tools.ts
6768
6774
  function createCesarToolRegistry(engineId) {
@@ -6892,6 +6898,112 @@ async function executeEagerTool(toolName, meta, toolRegistry, toolCtx, dispatch,
6892
6898
  return result;
6893
6899
  }
6894
6900
 
6901
+ // src/generated/blocks/narration-fold.ts
6902
+ var _NARR_STARTERS = "I will|I'll|I am going to|I'm going to|Let me|Let's|Now I|Now let|Next,? I|Next,? let|I need to|I should|I want to|Checking|Searching|Reading|Viewing|Opening|Running|Looking at|First,? I";
6903
+ var _NARR_INTENT_RE = new RegExp(`^(?:${_NARR_STARTERS})\\b`, "i");
6904
+ var _NARR_TOOL_VERB_RE = /\b(?:read|re-?read|view|inspect|examine|search(?:ing)?|grep|list|open(?:ing)?|check(?:ing)?|look(?:ing)?\s+at|see\s+(?:if|how|what|where)|locate|find(?:\s+(?:the|where|references|out))?|run(?:ning)?\s+(?:the\s+)?tests?|scan(?:ning)?|explore|navigate|understand\s+how|verify|map\s+out|trace)\b/i;
6905
+ var _NARR_SUBSTANCE_RE = /\b(?:recommend|the\s+(?:fix|issue|bug|root\s+cause|answer|problem|solution|reason)|because|therefore|so\s+that|found\s+that|in\s+(?:short|summary|conclusion)|here(?:'s|\s+is)|refers?\s+to|means?\b|works?\s+by|consists?\s+of|note\s+that|important(?:ly)?|warning|trade-?off|risk|failure\s+mode|you\s+(?:should|can|need)|we\s+(?:should|can|need)|confidence)\b/i;
6906
+ var _NARR_PROTECTED_RE = /^(?:#{1,6}\s|[-*+]\s|\d+[.)]\s|>\s|\||@@FENCE)/;
6907
+ function _isNarrationSegment(s) {
6908
+ const t = String(s ?? "").trim();
6909
+ if (!t) return false;
6910
+ if (_NARR_PROTECTED_RE.test(t)) return false;
6911
+ if (t.endsWith("?")) return false;
6912
+ if (!_NARR_INTENT_RE.test(t)) return false;
6913
+ if (_NARR_SUBSTANCE_RE.test(t)) return false;
6914
+ if (!_NARR_TOOL_VERB_RE.test(t)) return false;
6915
+ if (t.length > 240) return false;
6916
+ return true;
6917
+ }
6918
+ function foldNarration(text, policy) {
6919
+ const raw = String(text ?? "");
6920
+ const mode = policy ?? "safe";
6921
+ const noFold = { raw, visible: raw, foldedSteps: 0, didFold: false };
6922
+ if (mode === "off") return noFold;
6923
+ if (!raw.trim()) return noFold;
6924
+ const fences = [];
6925
+ const guarded = raw.replace(/```[\s\S]*?```/g, (m) => {
6926
+ fences.push(m);
6927
+ return `@@FENCE${fences.length - 1}@@`;
6928
+ });
6929
+ const seg = guarded.replace(/\r/g, "").replace(/\n+/g, "\n").replace(/([.!?])(?=[A-Z][a-z])/g, "$1\n").replace(new RegExp(`([\\s.;:!?)\\]])(?=(?:${_NARR_STARTERS})\\b)`, "g"), "$1\n");
6930
+ const sentences = seg.split("\n").map((s) => s.trim()).filter((s) => s.length > 0);
6931
+ const flags = sentences.map((s) => _isNarrationSegment(s));
6932
+ let tailStart = sentences.length;
6933
+ for (let i2 = sentences.length - 1; i2 >= 0; i2--) {
6934
+ if (flags[i2]) break;
6935
+ tailStart = i2;
6936
+ }
6937
+ if (tailStart >= sentences.length) return noFold;
6938
+ const FOLD_MIN_RUN = mode === "aggressive" ? 1 : 2;
6939
+ const out = [];
6940
+ let folded = 0;
6941
+ let i = 0;
6942
+ while (i < tailStart) {
6943
+ if (flags[i]) {
6944
+ let j = i;
6945
+ while (j < tailStart && flags[j]) j++;
6946
+ const runLen = j - i;
6947
+ if (runLen >= FOLD_MIN_RUN) {
6948
+ folded += runLen;
6949
+ } else {
6950
+ for (let k = i; k < j; k++) out.push(sentences[k]);
6951
+ }
6952
+ i = j;
6953
+ } else {
6954
+ out.push(sentences[i]);
6955
+ i++;
6956
+ }
6957
+ }
6958
+ for (let k = tailStart; k < sentences.length; k++) out.push(sentences[k]);
6959
+ if (folded === 0) return noFold;
6960
+ const visible = out.join("\n").replace(/@@FENCE(\d+)@@/g, (_m, n) => fences[Number(n)] ?? "").replace(/\n{3,}/g, "\n\n").trim();
6961
+ return { raw, visible, foldedSteps: folded, didFold: true };
6962
+ }
6963
+ function foldNarrationLines(text, policy) {
6964
+ const raw = String(text ?? "");
6965
+ const mode = policy ?? "safe";
6966
+ const noFold = { visible: raw, foldedSteps: 0, lastStep: "" };
6967
+ if (mode === "off" || !raw.trim()) return noFold;
6968
+ const lines = raw.split("\n");
6969
+ let inFence = false;
6970
+ const out = [];
6971
+ let folded = 0;
6972
+ let lastStep = "";
6973
+ for (const ln of lines) {
6974
+ if (/^\s*```/.test(ln)) {
6975
+ inFence = !inFence;
6976
+ out.push(ln);
6977
+ continue;
6978
+ }
6979
+ if (!inFence && _isNarrationSegment(ln)) {
6980
+ folded++;
6981
+ lastStep = ln.trim();
6982
+ continue;
6983
+ }
6984
+ out.push(ln);
6985
+ }
6986
+ if (folded === 0) return noFold;
6987
+ const visible = out.join("\n").replace(/\n{3,}/g, "\n\n").trim();
6988
+ return { visible, foldedSteps: folded, lastStep };
6989
+ }
6990
+ var _FOLD_RING_MAX = 20;
6991
+ var _foldedRaws = [];
6992
+ function setLastFoldedRaw(raw) {
6993
+ const r = String(raw ?? "");
6994
+ if (!r) return;
6995
+ _foldedRaws.push(r);
6996
+ while (_foldedRaws.length > _FOLD_RING_MAX) _foldedRaws.shift();
6997
+ }
6998
+ function getFoldedRawCount() {
6999
+ return _foldedRaws.length;
7000
+ }
7001
+ function getFoldedRaw(fromEnd) {
7002
+ const n = Math.max(1, Math.floor(Number(fromEnd) || 1));
7003
+ const idx = _foldedRaws.length - n;
7004
+ return idx >= 0 ? _foldedRaws[idx] : "";
7005
+ }
7006
+
6895
7007
  // src/generated/blocks/code-buffer.ts
6896
7008
  var CodeBlockBuffer = class {
6897
7009
  blocks = [];
@@ -7054,6 +7166,14 @@ function _showNextPermission(actions) {
7054
7166
  }
7055
7167
  });
7056
7168
  }
7169
+ function foldEngineContent(content) {
7170
+ const cfg = loadConfig();
7171
+ const policy = String(cfg.narrationFold ?? "safe");
7172
+ const r = foldNarration(content, policy);
7173
+ if (!r.didFold) return { content };
7174
+ setLastFoldedRaw(r.raw);
7175
+ return { content: r.visible, foldedSteps: r.foldedSteps };
7176
+ }
7057
7177
  function handleOutputEvent(event, state, actions, mode, chatStartTime) {
7058
7178
  if (event.type !== "thinking-chunk" && _thinkingBuffer.content) {
7059
7179
  actions.addBlock({ type: "thinking-chunk", engineId: _thinkingBuffer.engineId, chunk: _thinkingBuffer.content });
@@ -7146,9 +7266,10 @@ function handleOutputEvent(event, state, actions, mode, chatStartTime) {
7146
7266
  return next;
7147
7267
  });
7148
7268
  if (cleaned.trim()) {
7149
- const segments = parseMarkdownBlocks(cleaned);
7269
+ const folded = foldEngineContent(cleaned);
7270
+ const segments = parseMarkdownBlocks(folded.content);
7150
7271
  codeBlockBuffer.recordFromSegments(segments);
7151
- actions.addBlock({ type: "engine-block", engineId: st.engineId, color, content: cleaned });
7272
+ actions.addBlock({ type: "engine-block", engineId: st.engineId, color, content: folded.content, foldedSteps: folded.foldedSteps });
7152
7273
  if (mode === "chat" && chatStartTime > 0) {
7153
7274
  actions.addBlock({ type: "response-meta", engineId: st.engineId, elapsed: Date.now() - chatStartTime });
7154
7275
  }
@@ -7503,9 +7624,11 @@ function handleOutputEvent(event, state, actions, mode, chatStartTime) {
7503
7624
  default:
7504
7625
  if (event.type === "engine-block") {
7505
7626
  const cleaned = cleanEngineOutput(event.content);
7506
- const segments = parseMarkdownBlocks(cleaned);
7627
+ const preFolded = event.foldedSteps != null;
7628
+ const folded = preFolded ? { content: cleaned, foldedSteps: event.foldedSteps } : foldEngineContent(cleaned);
7629
+ const segments = parseMarkdownBlocks(folded.content);
7507
7630
  codeBlockBuffer.recordFromSegments(segments);
7508
- event = { ...event, content: cleaned };
7631
+ event = { ...event, content: folded.content, foldedSteps: folded.foldedSteps };
7509
7632
  }
7510
7633
  if (event.type === "text" || event.type === "engine-block" || event.type === "separator") {
7511
7634
  actions.flushStream();
@@ -8122,6 +8245,29 @@ function isUserDirectedQuestion(lastLine) {
8122
8245
  const isForkChoice = /\bor\b[^?]{0,160}\?\s*$/i.test(last);
8123
8246
  return userAddressed || isForkChoice;
8124
8247
  }
8248
+ function findTrailingUserQuestion(text) {
8249
+ const lines = String(text ?? "").split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
8250
+ const TAIL = 6;
8251
+ const start = Math.max(0, lines.length - TAIL);
8252
+ for (let i = lines.length - 1; i >= start; i--) {
8253
+ if (isUserDirectedQuestion(lines[i])) return lines[i];
8254
+ }
8255
+ return null;
8256
+ }
8257
+ function detectAwaitingUserInput(text) {
8258
+ const body = String(text ?? "");
8259
+ if (findTrailingUserQuestion(body)) return true;
8260
+ const tail = body.split(/\r?\n/).map((l) => l.trim().replace(/^(?:[-*>•]\s+|\d+[.)]\s+)/, "")).filter(Boolean).slice(-3);
8261
+ if (tail.length === 0) return false;
8262
+ const HOLDING_RE = /^holding\b(?:\s*$|\s*[.,;:!?…—–-]|\s+for\b|\s+until\b|\s+off\b)/i;
8263
+ const AWAITING_RE = /\b(?:awaiting\s+(?:(?:your|user|the\s+user'?s?|explicit\s+user|my)\s+(?:approval|greenlight|sign[-\s]?off|go[-\s]?ahead|confirmation|input|decision|response|reply|call|word|ok)|(?:approval|greenlight|sign[-\s]?off|go[-\s]?ahead|a\s+decision))|waiting\s+(?:on|for)\s+(?:you\s+to\s+(?:approve|confirm|decide|respond|reply)|your\s+(?:approval|greenlight|sign[-\s]?off|go[-\s]?ahead|input|confirmation|decision|response|reply|ok)|approval|greenlight|sign[-\s]?off|confirmation)|hold(?:ing)?\s+(?:for|until|off)|need(?:s|ing)?\s+(?:your|explicit\s+user|user)\s+(?:approval|greenlight|go[-\s]?ahead|sign[-\s]?off|input|confirmation|ok|decision)|your\s+(?:greenlight|go[-\s]?ahead|sign[-\s]?off)\s+(?:to|before)|need\s+(?:a\s+|the\s+)?greenlight|explicit\s+(?:user\s+)?approval|stand(?:ing)?\s+by\s+(?:for|until))\b/i;
8264
+ for (const line of tail) {
8265
+ const head = line.slice(0, 300);
8266
+ if (HOLDING_RE.test(head)) return true;
8267
+ if (AWAITING_RE.test(head)) return true;
8268
+ }
8269
+ return false;
8270
+ }
8125
8271
  function detectNarratedToolStall(text) {
8126
8272
  const body = String(text ?? "").trim();
8127
8273
  if (!body) {
@@ -8142,6 +8288,14 @@ function detectMutationIntentStall(text) {
8142
8288
  const HANDBACK_RE = /\b(?:read-?only|can'?t (?:write|edit|apply|mutate|touch)|no (?:write|edit|bash) tool|(?:edit|write|bash)(?: tool)?(?: is)? (?:not enabled|disabled|not wired|not available|unavailable)|not (?:enabled|wired|reachable) in this (?:context|session|turn)|spawn (?:an? )?agent|dispatch (?:an? )?agent|paste (?:it|this|the\b)|apply (?:it|this)\b|git apply|you (?:can )?(?:run|apply|paste)|in your terminal|hand you the (?:patch|diff|commands?)|copy[- ]?paste)\b/i;
8143
8289
  return MUTATION_INTENT_RE.test(body) && HANDBACK_RE.test(body);
8144
8290
  }
8291
+ function detectFabricatedDelegation(text) {
8292
+ const body = String(text ?? "").trim();
8293
+ if (!body) return false;
8294
+ const TARGET_RE = /\b(?:review(?:er)?s?|forg(?:e|ing)|tribunal|brainstorm|campfire|agents?|engines?|jobs?)\b/i;
8295
+ if (!TARGET_RE.test(body)) return false;
8296
+ const DISPATCH_RE = /\b(?:kick(?:ed|ing)?\s*(?:it|them|that|the\s+\w+)?\s*off|fired?\s*(?:it|them|off)|dispatch(?:ed|ing)|delegat(?:ed|ing)|(?:is|are|now)\s+running|running\s+(?:in|now)|in\s+parallel|reading\s+the\s+(?:diff|changes|code)|working\s+(?:on\s+it|in\s+parallel)|in\s+progress|under\s*way|i'?ll\s+(?:get\s+back|report|let\s+you\s+know|surface|update)|report(?:s|ing)?\s+back|when\s+they\s+(?:report|land|return|finish|come\s+back)|still\s+(?:running|going|working|in\s+progress)|spun?\s+up|started\s+(?:the|a)\s+(?:review|forge|job|tribunal|brainstorm))\b/i;
8297
+ return DISPATCH_RE.test(body);
8298
+ }
8145
8299
  function eagerFailedToolNames(results) {
8146
8300
  const names = [];
8147
8301
  for (const result of results ?? []) {
@@ -9114,7 +9268,7 @@ ${cleaned}`;
9114
9268
  }
9115
9269
  }
9116
9270
  if (name === "ExitPlanMode") {
9117
- const { handleExitPlanMode } = await import("./plan-mode-KIXDKD63.js");
9271
+ const { handleExitPlanMode } = await import("./plan-mode-PFLUPGSY.js");
9118
9272
  return "[DELEGATION_BREAK] " + handleExitPlanMode(String(args.reason ?? ""), ctx.cesar?.planDispatch ?? null, ctx);
9119
9273
  }
9120
9274
  if (name === "ProposePlan") {
@@ -9137,7 +9291,7 @@ ${cleaned}`;
9137
9291
  }
9138
9292
  }
9139
9293
  }
9140
- const { handleProposePlan } = await import("./plan-mode-KIXDKD63.js");
9294
+ const { handleProposePlan } = await import("./plan-mode-PFLUPGSY.js");
9141
9295
  const dispatch = ctx.cesar.planDispatch;
9142
9296
  if (!dispatch) {
9143
9297
  return "[PLAN_ERROR] Internal plan display dispatch unavailable. Retry the plan request so Agon can render the approval panel.";
@@ -9472,6 +9626,27 @@ function mcpConfigFingerprint(config) {
9472
9626
  const discoveryFp = mcpDiscoveryFingerprint(resolveWorkingDir());
9473
9627
  return `${enabled}:${configPath}:${mtime}:${discoveryFp}`;
9474
9628
  }
9629
+ function resolveAgonMcpServerPath(fromUrl) {
9630
+ const raw = fromUrl ?? import.meta.url;
9631
+ const url = raw.startsWith("file:") ? raw : pathToFileURL(raw).href;
9632
+ const bundledSibling = join12(dirname5(fileURLToPath(url)), "mcp", "index.js");
9633
+ if (existsSync12(bundledSibling)) return bundledSibling;
9634
+ try {
9635
+ const req = createRequire(url);
9636
+ const resolved = req.resolve("@kernlang/agon-mcp");
9637
+ if (existsSync12(resolved)) return resolved;
9638
+ } catch {
9639
+ }
9640
+ let dir = dirname5(fileURLToPath(url));
9641
+ for (let i = 0; i < 12; i++) {
9642
+ const cand = join12(dir, "packages", "mcp", "dist", "index.js");
9643
+ if (existsSync12(cand)) return cand;
9644
+ const parent = dirname5(dir);
9645
+ if (parent === dir) break;
9646
+ dir = parent;
9647
+ }
9648
+ return join12(dirname5(fileURLToPath(url)), "../../../../mcp/dist/index.js");
9649
+ }
9475
9650
  function resolveCesarBackend(ctx, engineId) {
9476
9651
  const config = ctx.config;
9477
9652
  const cesarEngineId = engineId ?? config.cesarEngine ?? config.forgeFixedStarter ?? "claude";
@@ -9574,20 +9749,30 @@ async function ensureCesarSession(ctx) {
9574
9749
  mcpServers = mcpServers ? [...mcpServers, ...sessionMcpWired] : sessionMcpWired;
9575
9750
  }
9576
9751
  const isCompanion = !!binaryPath && (engine.companion?.protocol === "jsonrpc" || engine.companion?.protocol === "acp" || engine.companion?.protocol === "stream-json" || engine.id === "claude" || engine.binary === "claude");
9752
+ const printOptOut = process.env.AGON_CLAUDE_PRINT;
9753
+ const usingPrint = printOptOut === "1" || printOptOut === "true";
9754
+ const isClaudePtyBrain = !!binaryPath && (engine.id === "claude" || engine.binary === "claude") && !usingPrint;
9755
+ let answerChannelPath;
9577
9756
  if (isCompanion) {
9578
9757
  ensureAgonHome();
9579
9758
  const signalDir = join12(getAgonHome(), "signals");
9580
9759
  mkdirSync11(signalDir, { recursive: true });
9581
9760
  const sessionSignalId = `cesar-${Date.now()}`;
9582
- const mcpServerPath = join12(dirname5(fileURLToPath(import.meta.url)), "../../../../mcp/dist/index.js");
9761
+ const mcpServerPath = resolveAgonMcpServerPath();
9762
+ if (!existsSync12(mcpServerPath)) {
9763
+ console.error(`[agon] cesar: agon-orchestration MCP server not found at ${mcpServerPath} \u2014 orchestration tools (Forge/Tribunal/AgonBash/DeliverAnswer) will be UNAVAILABLE and Cesar will fall back to slow scraping.`);
9764
+ }
9765
+ const mcpEnv = { AGON_SIGNAL_DIR: signalDir, AGON_SESSION_ID: sessionSignalId };
9766
+ if (isClaudePtyBrain) mcpEnv.AGON_ANSWER_CHANNEL = "1";
9583
9767
  const agonMcpServer = {
9584
9768
  name: "agon-orchestration",
9585
9769
  command: "node",
9586
9770
  args: [mcpServerPath],
9587
- env: { AGON_SIGNAL_DIR: signalDir, AGON_SESSION_ID: sessionSignalId }
9771
+ env: mcpEnv
9588
9772
  };
9589
9773
  mcpServers = mcpServers ? [...mcpServers, agonMcpServer] : [agonMcpServer];
9590
9774
  ctx.cesar.mcpSignalPath = join12(signalDir, `${sessionSignalId}.json`);
9775
+ if (isClaudePtyBrain) answerChannelPath = join12(signalDir, `${sessionSignalId}-answer.json`);
9591
9776
  }
9592
9777
  const systemPrompt = buildCesarSystemPrompt(ctx);
9593
9778
  const toolRegistry = createCesarToolRegistry(cesarEngineId);
@@ -9599,6 +9784,9 @@ async function ensureCesarSession(ctx) {
9599
9784
  fullPrompt += "\n\nYou have tools available via function calling. Call them directly \u2014 do NOT describe them in XML or narrate what you would call. Just call the function.";
9600
9785
  } else if (isCompanion) {
9601
9786
  fullPrompt += "\n\nYou have tools available via the agon-orchestration MCP server:\n- Orchestration: Tribunal, Brainstorm, Campfire, Forge, Pipeline, Review, Agent, Delegate, QuickNero, ReportConfidence, ProposePlan, ExitPlanMode\n- Write operations: AgonBash (shell commands), AgonEdit (file edits), AgonWrite (file creation)\n\nCall them as MCP tools \u2014 NEVER via your native Bash/Edit/Write. Your native write tools are disabled. Use AgonBash for ALL shell commands (git, npm, etc.), AgonEdit for file edits, AgonWrite for new files. The user will be asked to approve write operations. After calling any orchestration tool except Delegate, QuickNero, and ReportConfidence: STOP and wait.";
9787
+ if (isClaudePtyBrain) {
9788
+ fullPrompt += '\n\nIMPORTANT \u2014 DELIVERING YOUR REPLY: You are running under a PTY answer-channel. DeliverAnswer is REQUIRED and is the FASTEST way to reply \u2014 calling it returns your answer to the user INSTANTLY. To show the user your response you MUST call the DeliverAnswer tool with your complete reply (markdown) in the `text` argument, then STOP. Plain printed/streamed text is only a draft preview, may not reach the user, AND is SLOWER (Agon then has to wait for the terminal to go idle before it can read anything). NEVER "respond directly", skip the tool, or avoid "tool round-trips" to save time \u2014 skipping DeliverAnswer makes the turn SLOWER and risks losing your reply entirely. Even a one-word answer goes through DeliverAnswer. Call it exactly once at the end of every turn \u2014 EXCEPT on turns where you STOP for an orchestration tool (Forge/Tribunal/Brainstorm/Campfire/Pipeline/Review/Agent/Delegate), ProposePlan, or ExitPlanMode (those already end your turn and Agon handles the rest). Always call ReportConfidence first as usual.';
9789
+ }
9602
9790
  } else {
9603
9791
  const toolPrompt = buildToolSystemPrompt(toolRegistry);
9604
9792
  fullPrompt += "\n\nTOOLS: XML format below. Never ask permission \u2014 just call. Never describe changes when you can execute.\n\n" + toolPrompt;
@@ -9615,7 +9803,8 @@ async function ensureCesarSession(ctx) {
9615
9803
  mcpServers,
9616
9804
  sessionContinuity: config.sessionContinuity === true,
9617
9805
  onToolCall: buildOnToolCall(ctx, toolRegistry, config),
9618
- onApproval: buildOnApproval(ctx, cesarEngineId)
9806
+ onApproval: buildOnApproval(ctx, cesarEngineId),
9807
+ answerChannelPath
9619
9808
  };
9620
9809
  const session = createPersistentSession(sessionConfig);
9621
9810
  await session.start();
@@ -9956,11 +10145,12 @@ async function handleCesarBrain(input, dispatch, ctx, images) {
9956
10145
  const outputDir = join14(RUNS_DIR, `cesar-fallback-${Date.now()}`);
9957
10146
  mkdirSync13(outputDir, { recursive: true });
9958
10147
  const primedPrompt = buildHistoryPrimedPrompt(ctx.chatSession, input);
10148
+ const fallbackMode = engine?.agent ? "agent" : "exec";
9959
10149
  const freshResult = await ctx.adapter.dispatch({
9960
10150
  engine,
9961
10151
  prompt: primedPrompt,
9962
10152
  cwd: resolveWorkingDir(),
9963
- mode: "exec",
10153
+ mode: fallbackMode,
9964
10154
  timeout: config.timeout ?? 120,
9965
10155
  outputDir,
9966
10156
  signal: abort.signal,
@@ -10151,7 +10341,7 @@ ${enrichedInput}`;
10151
10341
  const signalDir = ctx.cesar.mcpSignalPath ? join14(ctx.cesar.mcpSignalPath, "..") : null;
10152
10342
  const processMcpSideChannel = () => {
10153
10343
  try {
10154
- if (!signalDir || !existsSync12(signalDir)) return;
10344
+ if (!signalDir || !existsSync13(signalDir)) return;
10155
10345
  const completions = readdirSync(signalDir).filter((f) => f.includes("-tool-") && f.endsWith(".json"));
10156
10346
  for (const f of completions) {
10157
10347
  const donePath = join14(signalDir, f);
@@ -10190,7 +10380,7 @@ ${enrichedInput}`;
10190
10380
  continue;
10191
10381
  }
10192
10382
  const respPath = reqPath.replace(".json", "-response.json");
10193
- if (existsSync12(respPath)) continue;
10383
+ if (existsSync13(respPath)) continue;
10194
10384
  const cfg = loadConfig();
10195
10385
  const allowed = cfg.allowedCommands ?? [];
10196
10386
  const cmdBase = (req.args?.command ?? "").toString().trim().split(/\s+/)[0];
@@ -10607,7 +10797,7 @@ ${enrichedInput}`;
10607
10797
  if (!ctx.cesar.pendingDelegation && ctx.cesar.mcpSignalPath) {
10608
10798
  try {
10609
10799
  const signalPath = ctx.cesar.mcpSignalPath;
10610
- if (existsSync12(signalPath)) {
10800
+ if (existsSync13(signalPath)) {
10611
10801
  const signals = JSON.parse(readFileSync13(signalPath, "utf-8"));
10612
10802
  unlinkSync(signalPath);
10613
10803
  for (const signal of Array.isArray(signals) ? signals : [signals]) {
@@ -10662,7 +10852,7 @@ ${enrichedInput}`;
10662
10852
  });
10663
10853
  continue;
10664
10854
  }
10665
- const { handleProposePlan } = await import("./plan-mode-KIXDKD63.js");
10855
+ const { handleProposePlan } = await import("./plan-mode-PFLUPGSY.js");
10666
10856
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10667
10857
  if (planDispatch) {
10668
10858
  try {
@@ -10675,7 +10865,7 @@ ${enrichedInput}`;
10675
10865
  }
10676
10866
  } else if (signal.tool === "ExitPlanMode") {
10677
10867
  recordToolUse("ExitPlanMode", "mcp", JSON.stringify(signal.args ?? {}), "done");
10678
- const { handleExitPlanMode } = await import("./plan-mode-KIXDKD63.js");
10868
+ const { handleExitPlanMode } = await import("./plan-mode-PFLUPGSY.js");
10679
10869
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10680
10870
  try {
10681
10871
  const exitResult = handleExitPlanMode(String(signal.args?.reason ?? ""), planDispatch, ctx);
@@ -10891,7 +11081,7 @@ ${enrichedInput}`;
10891
11081
  output: "A Cesar plan is already active; nested plans are blocked. Resume or cancel the current plan before proposing another."
10892
11082
  });
10893
11083
  } else {
10894
- const { handleProposePlan } = await import("./plan-mode-KIXDKD63.js");
11084
+ const { handleProposePlan } = await import("./plan-mode-PFLUPGSY.js");
10895
11085
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10896
11086
  const plan = await handleProposePlan(ppArgs, planDispatch, ctx);
10897
11087
  if (ctx.setActivePlan) ctx.setActivePlan(plan);
@@ -10915,7 +11105,7 @@ ${enrichedInput}`;
10915
11105
  const epArgs = ctx.cesar._exitPlanModeArgs;
10916
11106
  delete ctx.cesar._exitPlanModeArgs;
10917
11107
  try {
10918
- const { handleExitPlanMode } = await import("./plan-mode-KIXDKD63.js");
11108
+ const { handleExitPlanMode } = await import("./plan-mode-PFLUPGSY.js");
10919
11109
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10920
11110
  const exitResult = handleExitPlanMode(String(epArgs?.reason ?? ""), planDispatch, ctx);
10921
11111
  dispatch({ type: "tool-call", engineId: cesarEngineId, tool: "ExitPlanMode", input: JSON.stringify(epArgs ?? {}), status: "done", output: exitResult });
@@ -11102,6 +11292,28 @@ ${qnResult.challengeText}` : ""
11102
11292
  dispatch({ type: "spinner-stop" });
11103
11293
  }
11104
11294
  }
11295
+ if (!ctx.cesar.pendingDelegation && session.alive && !abort.signal.aborted && detectFabricatedDelegation(response.trim())) {
11296
+ dispatch({ type: "warning", message: "Cesar claimed a job was running but never dispatched one \u2014 grounding..." });
11297
+ dispatch({ type: "spinner-start", message: "Cesar grounding\u2026", color });
11298
+ try {
11299
+ let groundResponse = "";
11300
+ const groundGen = session.send({
11301
+ message: '[SYSTEM] GROUNDING CHECK: You did NOT dispatch any review/forge/tribunal/brainstorm/agent/job this turn, and none is pending or running. Do NOT claim background work is "running", "in parallel", "kicked off", or that anyone "will report back" \u2014 that is false and misleads the user. If the user wants that work done, call the actual tool now (Review/Forge/Tribunal/Brainstorm/Agent). Otherwise tell the user plainly that nothing is currently running and ask whether to start it.',
11302
+ signal: abort.signal
11303
+ });
11304
+ for await (const chunk of groundGen) {
11305
+ if (chunk.type === "text") groundResponse += chunk.content;
11306
+ if (chunk.type === "done" || chunk.type === "error") break;
11307
+ }
11308
+ dispatch({ type: "spinner-stop" });
11309
+ if (groundResponse.trim()) {
11310
+ dispatch({ type: "engine-block", engineId: cesarEngineId, color, content: groundResponse.trim() });
11311
+ response = groundResponse.trim();
11312
+ }
11313
+ } catch {
11314
+ dispatch({ type: "spinner-stop" });
11315
+ }
11316
+ }
11105
11317
  const _trimmedResponse = response.trim();
11106
11318
  if (!hadToolActivity && !ranToolLoop && detectNarratedToolStall(_trimmedResponse)) {
11107
11319
  _narratedToolStalls++;
@@ -11198,9 +11410,7 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11198
11410
  const _AUTO_CONT_READONLY_DONE_RE = /\b(?:tests? passed|all (?:tests|checks) pass|no matches found|no issues found|no errors|all clean|nothing to (?:do|fix|change)|already (?:correct|fixed|in place|done))\b/i;
11199
11411
  const _detectTurnState = (resp, baselineToolCount) => {
11200
11412
  const wroteSinceBaseline = _toolsUsed.slice(baselineToolCount).some((t) => _AUTO_CONT_WRITE_TOOLS.has(t));
11201
- const lines = resp.split("\n").map((l) => l.trim()).filter(Boolean);
11202
- const last = lines[lines.length - 1] ?? "";
11203
- if (isUserDirectedQuestion(last)) return "asks-user";
11413
+ if (findTrailingUserQuestion(resp)) return "asks-user";
11204
11414
  if (wroteSinceBaseline && !_AUTO_CONT_CONTINUE_RE.test(resp)) return "done";
11205
11415
  const effectSummary = /(?:created|modified|deleted|updated|added|removed|fixed|implemented|renamed)\b[^.]{0,80}(?:\b(?:and|,)\b[^.]{0,80}\b(?:created|modified|deleted|updated|added|removed|fixed|implemented|renamed)\b)/i.test(resp);
11206
11416
  if (effectSummary) return "done";
@@ -11544,7 +11754,7 @@ ${cleanFinalAnswer}` : cleanFinalAnswer;
11544
11754
  if (followUp.trim()) dispatch({ type: "engine-block", engineId: cesarEngineId, color, content: followUp.trim() });
11545
11755
  }
11546
11756
  }
11547
- return { mode: usedQuickNero ? "self-nero" : "self", delegated: false, responded: true, decisionReason: usedQuickNero ? "self-challenge" : "self-executed", ...buildToolTelemetry() };
11757
+ return { mode: usedQuickNero ? "self-nero" : "self", delegated: false, responded: true, decisionReason: usedQuickNero ? "self-challenge" : "self-executed", awaitingUserInput: detectAwaitingUserInput(response), ...buildToolTelemetry() };
11548
11758
  } else {
11549
11759
  dispatch({ type: "spinner-stop" });
11550
11760
  }
@@ -11644,6 +11854,9 @@ export {
11644
11854
  buildRoutingContext,
11645
11855
  shouldUseAgentTeam,
11646
11856
  codeBlockBuffer,
11857
+ foldNarrationLines,
11858
+ getFoldedRawCount,
11859
+ getFoldedRaw,
11647
11860
  todosFromPlanSteps,
11648
11861
  getSessionAllowList,
11649
11862
  clearPermissionQueue,
@@ -11660,4 +11873,4 @@ export {
11660
11873
  ensureCesarSession,
11661
11874
  handleCesarBrain
11662
11875
  };
11663
- //# sourceMappingURL=chunk-4NTH3EAR.js.map
11876
+ //# sourceMappingURL=chunk-AONHRJRW.js.map