@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
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  parseProseToRichLines,
27
27
  saveDismissedVersion,
28
28
  updateCommand
29
- } from "./chunk-GPYWJO2Q.js";
29
+ } from "./chunk-6WWOJXG4.js";
30
30
  import {
31
31
  buildAgentApprovalCallback,
32
32
  buildConsensus,
@@ -38,10 +38,10 @@ import {
38
38
  runAgentTeam,
39
39
  runReviewCore,
40
40
  selectReviewEngine
41
- } from "./chunk-46WNYE4R.js";
41
+ } from "./chunk-RKXVKX25.js";
42
42
  import {
43
43
  parsePatchPreview
44
- } from "./chunk-HSPQEDHX.js";
44
+ } from "./chunk-SUT2HDOY.js";
45
45
  import {
46
46
  buildCheckpoint,
47
47
  createScoreboard,
@@ -54,7 +54,7 @@ import {
54
54
  renderScoreboard,
55
55
  scoreboardFailEngine,
56
56
  scoreboardFinishEngine
57
- } from "./chunk-73ETZFDH.js";
57
+ } from "./chunk-WDT5NJOA.js";
58
58
  import {
59
59
  buildCesarSystemPrompt,
60
60
  buildOracleCheatPrompt,
@@ -65,8 +65,11 @@ import {
65
65
  codeBlockBuffer,
66
66
  deriveRoutingHints,
67
67
  filterDefaultOrchestrationEngines,
68
+ foldNarrationLines,
68
69
  formatCesarReliabilityLine,
69
70
  formatModeRationale,
71
+ getFoldedRaw,
72
+ getFoldedRawCount,
70
73
  goalDir,
71
74
  handleCesarBrain,
72
75
  handleOutputEvent,
@@ -105,7 +108,7 @@ import {
105
108
  synthesisRoutingAdvice,
106
109
  todosFromPlanSteps,
107
110
  yieldToInk
108
- } from "./chunk-4NTH3EAR.js";
111
+ } from "./chunk-AONHRJRW.js";
109
112
  import {
110
113
  ENGINE_COLORS,
111
114
  bold,
@@ -127,7 +130,7 @@ import {
127
130
  truncateCodeLine,
128
131
  warn,
129
132
  yellow
130
- } from "./chunk-DGTU4UWQ.js";
133
+ } from "./chunk-I2PMSXJ3.js";
131
134
  import {
132
135
  AGON_HOME,
133
136
  CommandRegistry,
@@ -275,14 +278,16 @@ import {
275
278
  undoPatch,
276
279
  updateChatSummary,
277
280
  worktreeCreate,
281
+ worktreePruneAll,
282
+ worktreePruneOrphaned,
278
283
  worktreeRemoveBestEffort,
279
284
  writeProvenanceReport,
280
285
  writeRunStatus
281
- } from "./chunk-HAJIKZGU.js";
286
+ } from "./chunk-BPKY4OF2.js";
282
287
  import {
283
288
  apiDispatch,
284
289
  apiStreamDispatch
285
- } from "./chunk-SOUF7XTW.js";
290
+ } from "./chunk-45YTXJWJ.js";
286
291
 
287
292
  // src/index.ts
288
293
  import { defineCommand as defineCommand31, runMain } from "citty";
@@ -488,8 +493,8 @@ function buildCommand(engine, mode, prompt2, cwd, timeout, binaryPath, images) {
488
493
  }
489
494
  return { command: binaryPath, args };
490
495
  }
491
- function stripStreamJson(stdout) {
492
- const lines = stdout.split("\n");
496
+ function stripStreamJson(stdout2) {
497
+ const lines = stdout2.split("\n");
493
498
  const textParts = [];
494
499
  for (const line of lines) {
495
500
  const trimmed = line.trim();
@@ -4359,6 +4364,7 @@ var reviewCommand = defineCommand18({
4359
4364
  const concurrencyNote = requested.length > 1 ? maxParallel >= requested.length ? "all in parallel" : `${maxParallel} at a time` : "single engine";
4360
4365
  if (!quiet) {
4361
4366
  header(`Review: ${target.label}`);
4367
+ info(`Repo: ${cwd}`);
4362
4368
  info(`Engines: ${requested.join(", ")} (${concurrencyNote})`);
4363
4369
  info(`Per-engine timeout: ${timeoutSec}s (auto-cancel, others unaffected)`);
4364
4370
  }
@@ -4399,7 +4405,7 @@ var reviewCommand = defineCommand18({
4399
4405
  ${body.join("\n")}`);
4400
4406
  };
4401
4407
  try {
4402
- const result = await runReviewCore(target.diff, target.label, engineId, ctx, controller.signal);
4408
+ const result = await runReviewCore(target.diff, target.label, engineId, ctx, controller.signal, void 0, cwd);
4403
4409
  const rawResponse = result.response ?? "";
4404
4410
  writeOutput(rawResponse);
4405
4411
  if (timedOut) {
@@ -5859,6 +5865,10 @@ judge ${judge} errored (${e instanceof Error ? e.message : String(e)}); ${consen
5859
5865
  }
5860
5866
  } finally {
5861
5867
  process.removeListener("SIGINT", onSig);
5868
+ try {
5869
+ worktreePruneOrphaned(repoRoot2);
5870
+ } catch (e) {
5871
+ }
5862
5872
  }
5863
5873
  }
5864
5874
  });
@@ -7019,9 +7029,20 @@ var worktreeCommand = defineCommand29({
7019
7029
  if (removed.length === 0) {
7020
7030
  info(`No session worktrees older than ${olderThan} (dirty worktrees are skipped unless --force).`);
7021
7031
  } else if (dryRun) {
7022
- info(`Would prune ${removed.length}: ${removed.join(", ")}`);
7032
+ info(`Would prune ${removed.length} session worktree(s): ${removed.join(", ")}`);
7023
7033
  } else {
7024
- success(`Pruned ${removed.length}: ${removed.join(", ")}`);
7034
+ success(`Pruned ${removed.length} session worktree(s): ${removed.join(", ")}`);
7035
+ }
7036
+ if (!dryRun) {
7037
+ try {
7038
+ worktreePruneAll(root, ms);
7039
+ worktreePruneOrphaned(root);
7040
+ success(`Pruned stale agent/competition worktrees and cleaned up registry.`);
7041
+ } catch (e) {
7042
+ warn(`Failed to prune agent/competition worktrees: ${e instanceof Error ? e.message : String(e)}`);
7043
+ }
7044
+ } else {
7045
+ info(`Would prune stale agent/competition worktrees older than ${olderThan}`);
7025
7046
  }
7026
7047
  break;
7027
7048
  }
@@ -7165,7 +7186,7 @@ import { Box as Box9, Static, Text as Text9, render } from "ink";
7165
7186
  import { ScrollBox, AlternateScreen } from "@kernlang/terminal/runtime";
7166
7187
 
7167
7188
  // src/generated/signals/intent.ts
7168
- var SLASH_COMMANDS = [{ cmd: "/forge", desc: "<task> test with <cmd> [--hardened] \u2014 competitive code generation" }, { cmd: "/brainstorm", desc: "<question> \u2014 confidence-bidding answers" }, { cmd: "/tribunal", desc: "[mode] <question> \u2014 debate (adversarial|socratic|red-team|steelman|synthesis|postmortem)" }, { cmd: "/campfire", desc: "<topic> \u2014 think together, no competition" }, { cmd: "/think", desc: "<problem> [--strategy reflexion] [--steps 8] \u2014 sequential thinking, one engine" }, { cmd: "/council", desc: "<decision> \u2014 roundtable: every engine a role, top-rated chairs" }, { cmd: "/synthesis", desc: "<task> [--swaps 2] \u2014 engines draft, swap, improve; judge picks winner" }, { cmd: "/workspace", desc: "add|remove|list|switch \u2014 manage project repos" }, { cmd: "/ws", desc: " \u2014 list workspaces (shortcut)" }, { cmd: "/cesar", desc: "<engine> \u2014 set Cesar brain engine (e.g. /cesar codex)" }, { cmd: "/models", desc: " \u2014 browse & add provider models + CLI models" }, { cmd: "/tokens", desc: " \u2014 show token usage & costs" }, { cmd: "/engines", desc: " \u2014 select active engines" }, { cmd: "/leaderboard", desc: " \u2014 Glicko rankings" }, { cmd: "/cesar-report", desc: " \u2014 Cesar routing calibration report" }, { cmd: "/cesar-hints", desc: "<task> \u2014 inspect Cesar routing hints for a prompt" }, { cmd: "/history", desc: "[id] \u2014 past forge runs" }, { cmd: "/config", desc: "[list|get|set] \u2014 settings" }, { cmd: "/plan", desc: "<task> or no args \u2014 plan mode or show plan" }, { cmd: "/auto", desc: "[on|off|toggle|status] or <task> \u2014 autonomous mode control" }, { cmd: "/plans", desc: " \u2014 list recent plans" }, { cmd: "/approve", desc: " \u2014 approve current plan" }, { cmd: "/retry", desc: " \u2014 retry failed plan step" }, { cmd: "/cancel", desc: " \u2014 cancel current plan" }, { cmd: "/apply", desc: "[path] [--force] \u2014 apply winning forge patch" }, { cmd: "/cp", desc: "[N] \u2014 copy code block N to clipboard" }, { cmd: "/img", desc: "<path> \u2014 attach image to next prompt" }, { cmd: "/flow", desc: " \u2014 log this session" }, { cmd: "/flows", desc: " \u2014 flow analytics dashboard" }, { cmd: "/chats", desc: "[id|resume <id>] \u2014 chat history or resume session" }, { cmd: "/build", desc: "<task> \u2014 agent builds in cwd (reads/edits/tests)" }, { cmd: "/goal", desc: '<intent> --queue <dir> --gate "<cmd>" [--push] \u2014 autonomous queue: build\u2192review(all)\u2192judge\u2192fix\u2192commit\u2192push per task (background job)' }, { cmd: "/conquer", desc: '<task> --gate "<cmd>" [--builder X] [-e a,b] \u2014 supervised-autonomous build: Cesar drives a builder CLI, convenes nero/tribunal/council on forks, stops at a human merge gate (background job)' }, { cmd: "/agent", desc: "<task> \u2014 autonomous agent loop (solo or shadow, auto-routed)" }, { cmd: "/agent-solo", desc: "<task> \u2014 force solo agent mode, no shadow worker" }, { cmd: "/speculate", desc: "<task> \u2014 parallel speculation: N engines race in worktrees, winner applied" }, { cmd: "/team-forge", desc: "[2v2|3v3] <task> test with <cmd> \u2014 team code competition" }, { cmd: "/team-tribunal", desc: "[2v2|3v3] [mode] <question> \u2014 team debate" }, { cmd: "/team-brainstorm", desc: "[2v2|3v3] <question> \u2014 team ideation" }, { cmd: "/pipeline", desc: "<task> [test with <cmd>] \u2014 build\u2192review\u2192fix loop" }, { cmd: "/review", desc: "[with <engine>] [<target>] \u2014 code review (uncommitted|branch:NAME|commit:SHA)" }, { cmd: "/provider", desc: "add|remove|list|key \u2014 providers & keys (key set/clear/list)" }, { cmd: "/run", desc: "<cmd> \u2014 run shell command inline" }, { cmd: "/commit", desc: "[message] \u2014 stage & commit with auto-generated message" }, { cmd: "/status", desc: " \u2014 live engine telemetry snapshot" }, { cmd: "/doctor", desc: "[engines|harness] \u2014 diagnose engines, worktree, or Cesar harness" }, { cmd: "/harness-replay", desc: "[turnId] \u2014 replay Cesar tool timeline + approval ledger" }, { cmd: "/undo", desc: " \u2014 revert last patch or Cesar checkpoint" }, { cmd: "/checkpoints", desc: " \u2014 list recent file checkpoints" }, { cmd: "/jobs", desc: " \u2014 list running/completed jobs" }, { cmd: "/focus", desc: "<id> \u2014 switch to background job output" }, { cmd: "/explore", desc: " \u2014 toggle exploration mode (read-only)" }, { cmd: "/nero", desc: "[<decision>] \u2014 toggle Nero mode, or challenge a decision (top-rated critic)" }, { cmd: "/btw", desc: "<question> \u2014 ask something while engines work (side-channel)" }, { cmd: "/compact", desc: " \u2014 shrink Cesar context without clearing transcript" }, { cmd: "/mcp", desc: "connect <name|url> | disconnect <name> | list \u2014 manage session MCP servers" }, { cmd: "/init", desc: " \u2014 create AGON.md config wizard" }, { cmd: "/create-skill", desc: "<name> \u2014 scaffold a new skill (.agon/skills/)" }, { cmd: "/clear", desc: " \u2014 reset session (saves chat, clears brain)" }, { cmd: "/clean", desc: " \u2014 alias for /clear" }, { cmd: "/extensions", desc: " \u2014 list installed extensions" }, { cmd: "/help", desc: " \u2014 show this help" }, { cmd: "/exit", desc: " \u2014 quit" }];
7189
+ var SLASH_COMMANDS = [{ cmd: "/forge", desc: "<task> test with <cmd> [--hardened] \u2014 competitive code generation" }, { cmd: "/brainstorm", desc: "<question> \u2014 confidence-bidding answers" }, { cmd: "/tribunal", desc: "[mode] <question> \u2014 debate (adversarial|socratic|red-team|steelman|synthesis|postmortem)" }, { cmd: "/campfire", desc: "<topic> \u2014 think together, no competition" }, { cmd: "/think", desc: "<problem> [--strategy reflexion] [--steps 8] \u2014 sequential thinking, one engine" }, { cmd: "/council", desc: "<decision> \u2014 roundtable: every engine a role, top-rated chairs" }, { cmd: "/synthesis", desc: "<task> [--swaps 2] \u2014 engines draft, swap, improve; judge picks winner" }, { cmd: "/workspace", desc: "add|remove|list|switch \u2014 manage project repos" }, { cmd: "/ws", desc: " \u2014 list workspaces (shortcut)" }, { cmd: "/cesar", desc: "<engine> \u2014 set Cesar brain engine (e.g. /cesar codex)" }, { cmd: "/models", desc: " \u2014 browse & add provider models + CLI models" }, { cmd: "/tokens", desc: " \u2014 show token usage & costs" }, { cmd: "/raw", desc: " \u2014 reprint last folded engine output (unfolded)" }, { cmd: "/engines", desc: " \u2014 select active engines" }, { cmd: "/leaderboard", desc: " \u2014 Glicko rankings" }, { cmd: "/cesar-report", desc: " \u2014 Cesar routing calibration report" }, { cmd: "/cesar-hints", desc: "<task> \u2014 inspect Cesar routing hints for a prompt" }, { cmd: "/history", desc: "[id] \u2014 past forge runs" }, { cmd: "/config", desc: "[list|get|set] \u2014 settings" }, { cmd: "/plan", desc: "<task> or no args \u2014 plan mode or show plan" }, { cmd: "/auto", desc: "[on|off|toggle|status] or <task> \u2014 autonomous mode control" }, { cmd: "/plans", desc: " \u2014 list recent plans" }, { cmd: "/approve", desc: " \u2014 approve current plan" }, { cmd: "/retry", desc: " \u2014 retry failed plan step" }, { cmd: "/cancel", desc: " \u2014 cancel current plan" }, { cmd: "/apply", desc: "[path] [--force] \u2014 apply winning forge patch" }, { cmd: "/cp", desc: "[N] \u2014 copy code block N to clipboard" }, { cmd: "/img", desc: "<path> \u2014 attach image to next prompt" }, { cmd: "/flow", desc: " \u2014 log this session" }, { cmd: "/flows", desc: " \u2014 flow analytics dashboard" }, { cmd: "/chats", desc: "[id|resume <id>] \u2014 chat history or resume session" }, { cmd: "/build", desc: "<task> \u2014 agent builds in cwd (reads/edits/tests)" }, { cmd: "/goal", desc: '<intent> --queue <dir> --gate "<cmd>" [--push] \u2014 autonomous queue: build\u2192review(all)\u2192judge\u2192fix\u2192commit\u2192push per task (background job)' }, { cmd: "/conquer", desc: '<task> --gate "<cmd>" [--builder X] [-e a,b] \u2014 supervised-autonomous build: Cesar drives a builder CLI, convenes nero/tribunal/council on forks, stops at a human merge gate (background job)' }, { cmd: "/agent", desc: "<task> \u2014 autonomous agent loop (solo or shadow, auto-routed)" }, { cmd: "/agent-solo", desc: "<task> \u2014 force solo agent mode, no shadow worker" }, { cmd: "/speculate", desc: "<task> \u2014 parallel speculation: N engines race in worktrees, winner applied" }, { cmd: "/team-forge", desc: "[2v2|3v3] <task> test with <cmd> \u2014 team code competition" }, { cmd: "/team-tribunal", desc: "[2v2|3v3] [mode] <question> \u2014 team debate" }, { cmd: "/team-brainstorm", desc: "[2v2|3v3] <question> \u2014 team ideation" }, { cmd: "/pipeline", desc: "<task> [test with <cmd>] \u2014 build\u2192review\u2192fix loop" }, { cmd: "/review", desc: "[with <engine>] [<target>] \u2014 code review (uncommitted|branch:NAME|commit:SHA)" }, { cmd: "/provider", desc: "add|remove|list|key \u2014 providers & keys (key set/clear/list)" }, { cmd: "/run", desc: "<cmd> \u2014 run shell command inline" }, { cmd: "/commit", desc: "[message] \u2014 stage & commit with auto-generated message" }, { cmd: "/status", desc: " \u2014 live engine telemetry snapshot" }, { cmd: "/doctor", desc: "[engines|harness] \u2014 diagnose engines, worktree, or Cesar harness" }, { cmd: "/harness-replay", desc: "[turnId] \u2014 replay Cesar tool timeline + approval ledger" }, { cmd: "/undo", desc: " \u2014 revert last patch or Cesar checkpoint" }, { cmd: "/checkpoints", desc: " \u2014 list recent file checkpoints" }, { cmd: "/jobs", desc: " \u2014 list running/completed jobs" }, { cmd: "/focus", desc: "<id> \u2014 switch to background job output" }, { cmd: "/explore", desc: " \u2014 toggle exploration mode (read-only)" }, { cmd: "/nero", desc: "[<decision>] \u2014 toggle Nero mode, or challenge a decision (top-rated critic)" }, { cmd: "/btw", desc: "<question> \u2014 ask something while engines work (side-channel)" }, { cmd: "/compact", desc: " \u2014 shrink Cesar context without clearing transcript" }, { cmd: "/mcp", desc: "connect <name|url> | disconnect <name> | list \u2014 manage session MCP servers" }, { cmd: "/init", desc: " \u2014 create AGON.md config wizard" }, { cmd: "/create-skill", desc: "<name> \u2014 scaffold a new skill (.agon/skills/)" }, { cmd: "/clear", desc: " \u2014 reset session (saves chat, clears brain)" }, { cmd: "/clean", desc: " \u2014 alias for /clear" }, { cmd: "/extensions", desc: " \u2014 list installed extensions" }, { cmd: "/help", desc: " \u2014 show this help" }, { cmd: "/exit", desc: " \u2014 quit" }];
7169
7190
  var FITNESS_PATTERN = /\b(?:test with|test:|--test|fitness:)\s+(.+)/i;
7170
7191
  var LEADERBOARD_KEYWORDS = /\b(leaderboard|elo|rankings?)\b/i;
7171
7192
  var HISTORY_KEYWORDS = /\b(history|last runs?|recent)\b/i;
@@ -7180,6 +7201,7 @@ var CODE_ARTIFACT_PATTERN = /(?:at \w+.*:\d+|\.[tj]sx?\b|\.[a-z]{2,4}:\d+|^[+-]{
7180
7201
  var AGENT_TRIGGER_PATTERN = /^(?:agent(?:\s+mode)?|autonomous(?:\s+agent)?|run\s+agent)\s+([\s\S]+)$/i;
7181
7202
  var AUTOCREDIT_OFF_KEYWORDS = /\b(?:schalt(?:e|)?\s+(?:das|es|autoCredit)\s+ab|mach(?:e|)?\s+(?:das|es|autoCredit)\s+(?:aus|weg)|das\s+nervt|(?:autoCredit|co[\s-]?authored?|contributor)\s+(?:aus|ab|weg|nervt))\b/i;
7182
7203
  var AUTOCREDIT_ON_KEYWORDS = /\b(?:schalt(?:e|)?\s+(?:das|es|autoCredit)\s+an|mach(?:e|)?\s+(?:das|es|autoCredit)\s+an|(?:autoCredit|co[\s-]?authored?|contributor)\s+an)\b/i;
7204
+ var KNOWN_COLLAB_ENGINE_IDS = /* @__PURE__ */ new Set(["claude", "codex", "agy", "antigravity", "qwen", "kimi", "opencode", "open-code", "minimax", "zai", "aider", "cursor", "gpt", "openai"]);
7183
7205
  function classifyTask(input) {
7184
7206
  if (QUESTION_PATTERN.test(input)) {
7185
7207
  return "question";
@@ -7212,6 +7234,62 @@ function parseAgentShortcut(input) {
7212
7234
  }
7213
7235
  return { type: "agent", input: task };
7214
7236
  }
7237
+ function normalizeEngineToken(part) {
7238
+ const cleaned = part.trim().toLowerCase().replace(/^@+/, "").replace(/^[^\w-]+|[^\w-]+$/g, "");
7239
+ if (!cleaned) {
7240
+ return null;
7241
+ }
7242
+ if (cleaned === "antigravity") {
7243
+ return "agy";
7244
+ }
7245
+ if (KNOWN_COLLAB_ENGINE_IDS.has(cleaned)) {
7246
+ return cleaned;
7247
+ }
7248
+ if (/^(?:claude|codex|agy|antigravity|qwen|kimi|opencode|open-code|minimax|zai|aider|cursor|gpt|openai)[\w.-]*$/i.test(cleaned)) {
7249
+ return cleaned;
7250
+ }
7251
+ return null;
7252
+ }
7253
+ function parseExplicitEngineIds(input) {
7254
+ const engineIds = [];
7255
+ const add = (value) => {
7256
+ if (value && !engineIds.includes(value)) engineIds.push(value);
7257
+ };
7258
+ const collect = (segment) => {
7259
+ segment.split(/(?:,|\s+and\s+|\s+or\s+|\s+plus\s+|\s+with\s+|\s+)/i).map((part) => normalizeEngineToken(part)).forEach(add);
7260
+ };
7261
+ const withMatch = input.match(/\bwith\s+([a-z0-9@_.-]+(?:(?:\s*,\s*|\s+and\s+|\s+or\s+|\s+plus\s+|\s+)[a-z0-9@_.-]+)*)/i);
7262
+ if (withMatch) collect(withMatch[1]);
7263
+ const askMatch = input.match(/\b(?:ask|have|get)\s+([a-z0-9@_.-]+(?:\s*(?:,|and|or|plus)\s*[a-z0-9@_.-]+)*)\s+(?:to\s+)?(?:review|check|audit|look|inspect|compare|weigh|think|debate)\b/i);
7264
+ if (askMatch) collect(askMatch[1]);
7265
+ return engineIds;
7266
+ }
7267
+ function parseSemanticReviewShortcut(input) {
7268
+ const lower = input.toLowerCase();
7269
+ const reviewVerb = /\b(?:review|check|audit|inspect|look\s+over)\b/i.test(input);
7270
+ if (!reviewVerb) {
7271
+ return null;
7272
+ }
7273
+ const hasDelegationShape = /\bwith\s+[a-z0-9@_.-]+/i.test(input) || /\b(?:ask|have|get)\s+[a-z0-9@_.-]+(?:\s*(?:,|and|or|plus)\s*[a-z0-9@_.-]+)*\s+(?:to\s+)?(?:review|check|audit|look|inspect)\b/i.test(input);
7274
+ if (!hasDelegationShape) {
7275
+ return null;
7276
+ }
7277
+ if (/\breview\b[\s\S]*\b(?:fix|address|resolve|apply|patch)\b/i.test(input) || /\b(?:fix|address|resolve|apply|patch)\b[\s\S]*\b(?:review|findings?|issues?)\b/i.test(input)) {
7278
+ return null;
7279
+ }
7280
+ const IMPLEMENTATION_LEAD_RE = /^(?:fix(?:e[sd]|ing)?|add(?:ed|ing|s)?|implement(?:ed|ing|s)?|build(?:ing|s)?|built|creat(?:e[sd]?|ing)|refactor(?:ed|ing|s)?|rewrit(?:e|es|ing|ten)|migrat(?:e[sd]?|ing)|wir(?:e[sd]?|ing)|chang(?:e[sd]?|ing)|updat(?:e[sd]?|ing)|optimi[sz](?:e[sd]?|ing)|remov(?:e[sd]?|ing)|delet(?:e[sd]?|ing)|patch(?:ed|ing|es)?)\b/i;
7281
+ const normalized = input.trim().replace(/^(?:can\s+you\s+|could\s+you\s+|please\s+)?/i, "");
7282
+ if (IMPLEMENTATION_LEAD_RE.test(normalized)) {
7283
+ return null;
7284
+ }
7285
+ const engineIds = parseExplicitEngineIds(input);
7286
+ if (engineIds.length === 0) {
7287
+ return null;
7288
+ }
7289
+ const targetMatch = lower.match(/\b(uncommitted|branch:[\w./-]+|commit:[a-f0-9]{4,40})\b/i);
7290
+ const target = targetMatch ? targetMatch[1] : void 0;
7291
+ return { type: "review", engineId: engineIds[0], engineIds, target };
7292
+ }
7215
7293
  function parseSemanticDelegationShortcut(input) {
7216
7294
  return null;
7217
7295
  }
@@ -7456,6 +7534,10 @@ function parseSlashCommand(input, commandRegistry) {
7456
7534
  case "usage":
7457
7535
  case "cost":
7458
7536
  return { type: "tokens" };
7537
+ case "raw": {
7538
+ const rawN = parseInt(rest.trim(), 10);
7539
+ return { type: "raw", index: Number.isFinite(rawN) && rawN > 0 ? rawN : void 0 };
7540
+ }
7459
7541
  case "doctor":
7460
7542
  return { type: "doctor", scope: rest || "engines" };
7461
7543
  case "harness-replay":
@@ -7655,6 +7737,10 @@ function detectIntent(raw, commandRegistry) {
7655
7737
  if (delegationShortcut) {
7656
7738
  return delegationShortcut;
7657
7739
  }
7740
+ const reviewShortcut = parseSemanticReviewShortcut(input);
7741
+ if (reviewShortcut) {
7742
+ return reviewShortcut;
7743
+ }
7658
7744
  if (AUTOCREDIT_OFF_KEYWORDS.test(input)) {
7659
7745
  return { type: "toggleAutoCredit", autoCredit: false, input };
7660
7746
  }
@@ -7789,8 +7875,11 @@ function recordPastePlaceholder(hashMap, placeholder, fullHash) {
7789
7875
  hashes.push(fullHash);
7790
7876
  hashMap.set(placeholder, JSON.stringify(hashes));
7791
7877
  }
7878
+ function sanitizeInlinePaste(text) {
7879
+ return text.replace(/\x1b\[[0-?]*[ -\/]*[@-~]/g, "").replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "").replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "");
7880
+ }
7792
7881
  function processPasteContent(raw) {
7793
- const normalized = raw.replace(/\r\n/g, "\n");
7882
+ const normalized = raw.replace(/\r\n?/g, "\n");
7794
7883
  const content = normalized.trimEnd();
7795
7884
  if (!content) {
7796
7885
  return { type: "empty" };
@@ -7806,7 +7895,7 @@ function processPasteContent(raw) {
7806
7895
  } catch (e) {
7807
7896
  }
7808
7897
  }
7809
- return { type: "direct", content: normalized };
7898
+ return { type: "direct", content: sanitizeInlinePaste(normalized) };
7810
7899
  }
7811
7900
  function expandPastePlaceholders(input, hashMap) {
7812
7901
  const takeHash = (key) => {
@@ -8162,20 +8251,21 @@ function buildPlanCallbacks(initialPlan, cb) {
8162
8251
  },
8163
8252
  onStepDone: (stepId, result) => {
8164
8253
  const step = currentPlan.steps.find((s) => s.id === stepId);
8165
- const icon = result.status === "success" ? "\u2713" : "\u2717";
8166
- const msgType = result.status === "success" ? "success" : "error";
8254
+ const isPausedResult = result.status === "paused";
8255
+ const icon = result.status === "success" ? "\u2713" : isPausedResult ? "\u23F8" : "\u2717";
8256
+ const msgType = result.status === "success" ? "success" : isPausedResult ? "warning" : "error";
8167
8257
  cb.dispatch({ type: "spinner-stop" });
8168
8258
  cb.dispatch({
8169
8259
  type: "tool-call",
8170
8260
  engineId: "cesar",
8171
8261
  tool: "PlanStep",
8172
8262
  input: JSON.stringify(buildPlanStepToolInput(stepId)),
8173
- status: result.status === "success" ? "done" : "error",
8263
+ status: result.status === "success" || isPausedResult ? "done" : "error",
8174
8264
  output: result.output ? result.output.slice(0, 4e3) : "",
8175
- error: result.error
8265
+ error: isPausedResult ? void 0 : result.error
8176
8266
  });
8177
8267
  cb.dispatch({ type: msgType, message: `${icon} ${step?.description ?? stepId} \u2014 ${result.status}${result.error ? ": " + result.error : ""} (${(result.durationMs / 1e3).toFixed(1)}s, $${result.actualCostUsd.toFixed(4)})` });
8178
- cb.dispatch({ type: "todos-update", id: stepId, state: result.status === "success" ? "done" : "failed", note: result.error ? result.error.slice(0, 80) : void 0 });
8268
+ cb.dispatch({ type: "todos-update", id: stepId, state: result.status === "success" ? "done" : isPausedResult ? "pending" : "failed", note: result.error ? result.error.slice(0, 80) : void 0 });
8179
8269
  },
8180
8270
  onPlanUpdate: (updated) => {
8181
8271
  const previousState = currentPlan.state;
@@ -9710,6 +9800,21 @@ function handleCesar(engineId, dispatch, ctx) {
9710
9800
  dispatch({ type: "success", message: `Cesar brain set to: ${id} (backend: ${backend})` });
9711
9801
  dispatch({ type: "info", message: "Conversation context + memory preserved. Forge/tribunal engines unchanged \u2014 use /use to change those." });
9712
9802
  }
9803
+ function handleRaw(dispatch, index) {
9804
+ const count = getFoldedRawCount();
9805
+ if (count === 0) {
9806
+ dispatch({ type: "info", message: "Nothing folded yet \u2014 /raw reprints the full text of a recently folded engine block." });
9807
+ return;
9808
+ }
9809
+ const n = index && index > 0 ? Math.floor(index) : 1;
9810
+ const raw = getFoldedRaw(n) ?? "";
9811
+ if (!raw.trim()) {
9812
+ dispatch({ type: "info", message: `No folded block #${n} \u2014 ${count} recent fold${count === 1 ? "" : "s"} kept (try /raw 1..${count}).` });
9813
+ return;
9814
+ }
9815
+ dispatch({ type: "header", title: count > 1 ? `Raw engine output (unfolded) \u2014 ${n} of ${count} recent` : "Raw engine output (unfolded)" });
9816
+ dispatch({ type: "engine-block", engineId: "raw", color: 244, content: raw, foldedSteps: 0 });
9817
+ }
9713
9818
  function handleTokens(dispatch) {
9714
9819
  const stats = tracker.getStats();
9715
9820
  dispatch({ type: "header", title: "Token Usage \u2014 This Session" });
@@ -9878,7 +9983,7 @@ async function handlePlanShow(dispatch, ctx, planId) {
9878
9983
  savePlan(approved);
9879
9984
  dispatch({ type: "success", message: "Plan approved." });
9880
9985
  if (approved.action.type === "forge") {
9881
- const { handleForge: handleForge2 } = await import("./forge-ZI7NE73F.js");
9986
+ const { handleForge: handleForge2 } = await import("./forge-O2SJ5JIQ.js");
9882
9987
  await handleForge2(approved.action.task, approved.action.fitnessCmd ?? null, dispatch, ctx, approved, approved.action.hardened);
9883
9988
  } else {
9884
9989
  dispatch({ type: "info", message: "Run the build again to execute." });
@@ -9904,7 +10009,7 @@ async function handleApprove(dispatch, ctx) {
9904
10009
  savePlan(plan);
9905
10010
  dispatch({ type: "success", message: "Plan approved." });
9906
10011
  if (plan.action.type === "forge") {
9907
- const { handleForge: handleForge2 } = await import("./forge-ZI7NE73F.js");
10012
+ const { handleForge: handleForge2 } = await import("./forge-O2SJ5JIQ.js");
9908
10013
  await handleForge2(plan.action.task, plan.action.fitnessCmd ?? null, dispatch, ctx, plan, plan.action.hardened);
9909
10014
  } else {
9910
10015
  dispatch({ type: "info", message: "Run the build again to execute." });
@@ -9932,7 +10037,7 @@ async function handleRetry(dispatch, ctx) {
9932
10037
  plan = startPlan(plan);
9933
10038
  ctx.setCurrentPlan(plan);
9934
10039
  savePlan(plan);
9935
- const { handleForge: handleForge2 } = await import("./forge-ZI7NE73F.js");
10040
+ const { handleForge: handleForge2 } = await import("./forge-O2SJ5JIQ.js");
9936
10041
  await handleForge2(plan.action.task, plan.action.fitnessCmd ?? null, dispatch, ctx, plan, plan.action.hardened);
9937
10042
  } else {
9938
10043
  dispatch({ type: "info", message: "Plan reset to approved. Run the build again to execute." });
@@ -10675,7 +10780,7 @@ ${diffStat}
10675
10780
  return;
10676
10781
  }
10677
10782
  for (const f of modifiedFiles) {
10678
- gitExec(`git add "${f}"`, cwd);
10783
+ execFileSync2("git", ["add", f], { cwd, encoding: "utf-8", timeout: 1e4, stdio: ["ignore", "pipe", "pipe"] });
10679
10784
  }
10680
10785
  dispatch({ type: "success", message: `Staged ${modifiedFiles.length} file(s)` });
10681
10786
  }
@@ -12905,7 +13010,7 @@ async function runCesarBrainFallback(input, cb, crashDel, priorDeterministic) {
12905
13010
  const cesarEngine = cesarEngineDef ?? cb.ctx.registry.get(cesarId);
12906
13011
  const { join: join47 } = await import("path");
12907
13012
  const { mkdirSync: mkdirSync30 } = await import("fs");
12908
- const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-4A5FVACG.js");
13013
+ const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-253BUXEF.js");
12909
13014
  const outDir = join47(RUNS_DIR3, `cesar-fallback-${Date.now()}`);
12910
13015
  mkdirSync30(outDir, { recursive: true });
12911
13016
  if (!_silentMode) cb.dispatch({ type: "warning", message: formatCesarRecoveryStatus("retry", cesarId, `log: ${outDir}`) });
@@ -13086,18 +13191,19 @@ ${historyContext}
13086
13191
  ` : ""}## USER MESSAGE
13087
13192
  ${input}`;
13088
13193
  try {
13089
- const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-4A5FVACG.js");
13194
+ const { resolveWorkingDir: resolveWorkingDir3, RUNS_DIR: RUNS_DIR3, appendMessage: appendMessage3 } = await import("./src-253BUXEF.js");
13090
13195
  const { join: join47 } = await import("path");
13091
13196
  const { mkdirSync: mkdirSync30 } = await import("fs");
13092
13197
  const actingEngine = cb.ctx.registry.get(actingCesar);
13093
13198
  const outDir = join47(RUNS_DIR3, `acting-cesar-${Date.now()}`);
13094
13199
  mkdirSync30(outDir, { recursive: true });
13095
13200
  if (!_silentMode) cb.dispatch({ type: "info", message: formatCesarRecoveryStatus("acting", actingCesar, `log: ${outDir}`) });
13201
+ const actingMode = actingEngine?.agent ? "agent" : "exec";
13096
13202
  const actingResult = await cb.ctx.adapter.dispatch({
13097
13203
  engine: actingEngine,
13098
13204
  prompt: actingPrompt,
13099
13205
  cwd: resolveWorkingDir3(),
13100
- mode: "exec",
13206
+ mode: actingMode,
13101
13207
  timeout: cesarConfig.timeout ?? 120,
13102
13208
  outputDir: outDir,
13103
13209
  systemPrompt: buildCesarSystemPrompt(cb.ctx)
@@ -14012,13 +14118,16 @@ async function dispatchSessionInfoIntent(intent, input, cb) {
14012
14118
  case "tokens":
14013
14119
  handleTokens(cb.dispatch);
14014
14120
  break;
14121
+ case "raw":
14122
+ handleRaw(cb.dispatch, intent.index);
14123
+ break;
14015
14124
  case "models": {
14016
14125
  cb.setModelPickerTargetEngine?.(null);
14017
14126
  cb.setModelPickerInitialFilter?.("");
14018
14127
  cb.setModelPickerTitle?.("Select model");
14019
14128
  cb.setModelPickerLoading(true);
14020
14129
  cb.setModelPickerOpen(true);
14021
- import("./src-4A5FVACG.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
14130
+ import("./src-253BUXEF.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
14022
14131
  let cliGroups = buildCliGroupsImmediate();
14023
14132
  cb.setModelPickerCliGroups?.(cliGroups);
14024
14133
  for (const g of cliGroups) {
@@ -14076,7 +14185,7 @@ async function dispatchSessionInfoIntent(intent, input, cb) {
14076
14185
  await handlePlanShow(cb.dispatch, cb.ctx, intent.planId);
14077
14186
  break;
14078
14187
  case "plan-task": {
14079
- const { createCesarPlan } = await import("./src-4A5FVACG.js");
14188
+ const { createCesarPlan } = await import("./src-253BUXEF.js");
14080
14189
  const cesarPlan = createCesarPlan(intent.task, []);
14081
14190
  cb.setActivePlan(cesarPlan);
14082
14191
  if (!cb.ctx.cesar) {
@@ -15513,15 +15622,20 @@ function resolveKeyboardInput(ctx) {
15513
15622
  }
15514
15623
  if (hasCtrlSignal && normalizedCtrlInput === "l") return { type: "submit", value: "/clear" };
15515
15624
  if (ctx.activePlanState === "awaiting_approval" && ctx.inputValue === "" && !hasCtrlSignal && !key.escape && !key.tab && !ctx.slashPickerOpen && !ctx.enginePickerOpen && !ctx.reviewEventOpen && !ctx.toolDetailOpen && !ctx.questionState) {
15516
- const pcur = (ctx.planApprovalIndex ?? 0) === 1 ? 1 : 0;
15517
- if (key.upArrow || key.downArrow) return { type: "movePlanApproval", index: pcur === 0 ? 1 : 0 };
15625
+ const pcur = Math.max(0, Math.min(2, ctx.planApprovalIndex ?? 0));
15626
+ const next = pcur === 2 ? 0 : pcur + 1;
15627
+ const prev = pcur === 0 ? 2 : pcur - 1;
15628
+ if (key.downArrow) return { type: "movePlanApproval", index: next };
15629
+ if (key.upArrow) return { type: "movePlanApproval", index: prev };
15518
15630
  if (key.return || input === "\r" || input === "\n") {
15519
- return { type: "planControl", action: pcur === 1 ? "cancel" : "approve" };
15631
+ const action = pcur === 1 ? "revise" : pcur === 2 ? "cancel" : "approve";
15632
+ return { type: "planControl", action };
15520
15633
  }
15521
15634
  if (typeof input === "string" && input.length === 1) {
15522
15635
  const lowered = input.toLowerCase();
15523
15636
  if (lowered === "y" || lowered === "1") return { type: "movePlanApproval", index: 0 };
15524
- if (lowered === "n" || lowered === "2") return { type: "movePlanApproval", index: 1 };
15637
+ if (lowered === "o" || lowered === "2") return { type: "movePlanApproval", index: 1 };
15638
+ if (lowered === "n" || lowered === "3") return { type: "movePlanApproval", index: 2 };
15525
15639
  }
15526
15640
  }
15527
15641
  if (ctx.fileRailFocused) {
@@ -18400,8 +18514,98 @@ function ToolDetailBlock({ title, subtitle, accentColor, rows, maxVisibleRows, o
18400
18514
  ] });
18401
18515
  }
18402
18516
  var StreamingView = React7.memo(function StreamingView2({ streamingText, mode, liveProgress, liveToolStreams, liveToolTailFrozen }) {
18403
- const toolStreams = Object.values(liveToolStreams ?? {});
18404
18517
  const frozenToolOutputRef = useRef3({});
18518
+ const narrationPolicy = useMemo4(() => {
18519
+ try {
18520
+ return String(loadConfig().narrationFold ?? "safe");
18521
+ } catch {
18522
+ return "safe";
18523
+ }
18524
+ }, []);
18525
+ const [renderedText, setRenderedText] = useState4(null);
18526
+ const textRef = useRef3(null);
18527
+ textRef.current = streamingText;
18528
+ useEffect5(() => {
18529
+ if (!streamingText) {
18530
+ setRenderedText(null);
18531
+ return;
18532
+ }
18533
+ let lastHash = "";
18534
+ let frameTimer = null;
18535
+ const updateTick = () => {
18536
+ const current = textRef.current;
18537
+ if (!current) {
18538
+ setRenderedText(null);
18539
+ return;
18540
+ }
18541
+ const content = current.content;
18542
+ const hash = `${current.engineId}:${content.length}:${content.slice(-20)}`;
18543
+ if (hash !== lastHash) {
18544
+ lastHash = hash;
18545
+ if (process.stdout.cork) {
18546
+ process.stdout.cork();
18547
+ }
18548
+ setRenderedText(current);
18549
+ if (process.stdout.uncork) {
18550
+ process.nextTick(() => {
18551
+ process.stdout.uncork();
18552
+ });
18553
+ }
18554
+ }
18555
+ frameTimer = setTimeout(updateTick, 42);
18556
+ };
18557
+ updateTick();
18558
+ return () => {
18559
+ if (frameTimer) {
18560
+ clearTimeout(frameTimer);
18561
+ }
18562
+ };
18563
+ }, [streamingText ? streamingText.engineId : null]);
18564
+ const [renderedToolStreams, setRenderedToolStreams] = useState4({});
18565
+ const toolRef = useRef3({});
18566
+ toolRef.current = liveToolStreams ?? {};
18567
+ useEffect5(() => {
18568
+ if (!liveToolStreams || Object.keys(liveToolStreams).length === 0) {
18569
+ setRenderedToolStreams({});
18570
+ return;
18571
+ }
18572
+ let lastHash = "";
18573
+ let frameTimer = null;
18574
+ const updateTick = () => {
18575
+ const current = toolRef.current;
18576
+ if (!current || Object.keys(current).length === 0) {
18577
+ setRenderedToolStreams({});
18578
+ return;
18579
+ }
18580
+ let hash = "";
18581
+ const keys = Object.keys(current).sort();
18582
+ for (const key of keys) {
18583
+ const entry = current[key];
18584
+ const output = String(entry.output ?? "");
18585
+ hash += `|${key}:${entry.engineId}:${entry.tool}:${output.length}:${output.slice(-20)}`;
18586
+ }
18587
+ if (hash !== lastHash) {
18588
+ lastHash = hash;
18589
+ if (process.stdout.cork) {
18590
+ process.stdout.cork();
18591
+ }
18592
+ setRenderedToolStreams(current);
18593
+ if (process.stdout.uncork) {
18594
+ process.nextTick(() => {
18595
+ process.stdout.uncork();
18596
+ });
18597
+ }
18598
+ }
18599
+ frameTimer = setTimeout(updateTick, 50);
18600
+ };
18601
+ updateTick();
18602
+ return () => {
18603
+ if (frameTimer) {
18604
+ clearTimeout(frameTimer);
18605
+ }
18606
+ };
18607
+ }, [liveToolStreams ? Object.keys(liveToolStreams).join(",") : null]);
18608
+ const toolStreams = Object.values(renderedToolStreams ?? {});
18405
18609
  useEffect5(() => {
18406
18610
  const activeIds = new Set(Object.keys(liveToolStreams ?? {}));
18407
18611
  for (const id of Object.keys(frozenToolOutputRef.current)) {
@@ -18411,37 +18615,54 @@ var StreamingView = React7.memo(function StreamingView2({ streamingText, mode, l
18411
18615
  }
18412
18616
  }, [liveToolStreams, liveToolTailFrozen]);
18413
18617
  return /* @__PURE__ */ jsxs7(Fragment3, { children: [
18414
- streamingText && (() => {
18415
- const c = engineColor(streamingText.engineId);
18416
- const rawStream = streamingText.content;
18417
- const slicedStream = rawStream.length > 6e3 ? rawStream.slice(-6e3) : rawStream;
18418
- const firstNl = rawStream.length > 6e3 ? slicedStream.indexOf("\n") : -1;
18618
+ renderedText && (() => {
18619
+ const c = engineColor(renderedText.engineId);
18620
+ const rawStream = renderedText.content;
18621
+ const rawTailLen = 6e3;
18622
+ const slicedStream = rawStream.length > rawTailLen ? rawStream.slice(-rawTailLen) : rawStream;
18623
+ const firstNl = rawStream.length > rawTailLen ? slicedStream.indexOf("\n") : -1;
18419
18624
  const windowed = firstNl >= 0 ? slicedStream.slice(firstNl + 1) : slicedStream;
18420
18625
  const cleaned = cleanEngineOutput(windowed);
18421
18626
  const wrapWidth = contentWidth(mode === "chat" ? 6 : 8);
18422
18627
  if (mode === "chat") {
18423
18628
  const lines = cleaned.split("\n").filter((line) => line.trim());
18424
18629
  const lastLine = lines.length > 0 ? lines[lines.length - 1].trim() : "";
18425
- const previewLimit = Math.max(24, wrapWidth - streamingText.engineId.length - 6);
18630
+ const previewLimit = Math.max(24, wrapWidth - renderedText.engineId.length - 6);
18426
18631
  const preview = lastLine.length > previewLimit ? lastLine.slice(0, previewLimit - 1) + "\u2026" : lastLine;
18427
18632
  return /* @__PURE__ */ jsxs7(Box7, { marginY: 1, paddingLeft: 1, children: [
18428
18633
  /* @__PURE__ */ jsxs7(Text7, { color: c, bold: true, children: [
18429
18634
  icons().dotOn + " ",
18430
- streamingText.engineId
18635
+ renderedText.engineId
18431
18636
  ] }),
18432
18637
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: preview ? ` ${preview}` : " thinking\u2026" })
18433
18638
  ] });
18434
18639
  }
18435
18640
  const allLines = cleaned.split("\n");
18436
18641
  const tailLines = allLines.length > 24 ? allLines.slice(-24).join("\n") : cleaned;
18437
- const segments = parseMarkdownBlocks(tailLines);
18642
+ const live = foldNarrationLines(tailLines, narrationPolicy);
18643
+ const foldedTail = live.visible;
18644
+ const cleanedPrefix = allLines.length > 24 ? allLines.slice(0, -24).join("\n") + "\n" : "";
18645
+ const contextualized = contextualizeSlicedMarkdown(cleanedPrefix, foldedTail);
18646
+ const segments = parseMarkdownBlocks(contextualized);
18647
+ const stepLimit = Math.max(16, wrapWidth - 14);
18648
+ const stepHint = live.lastStep.length > stepLimit ? live.lastStep.slice(0, stepLimit - 1) + "\u2026" : live.lastStep;
18438
18649
  return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginY: 1, paddingLeft: 2, children: [
18439
18650
  /* @__PURE__ */ jsxs7(Text7, { color: c, bold: true, children: [
18440
18651
  "\u250C\u2500\u2500 ",
18441
- streamingText.engineId
18652
+ renderedText.engineId
18442
18653
  ] }),
18654
+ live.foldedSteps > 0 ? /* @__PURE__ */ jsxs7(Text7, { color: c, children: [
18655
+ "\u2502 ",
18656
+ /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
18657
+ "\u25B8 ",
18658
+ String(live.foldedSteps),
18659
+ " step",
18660
+ live.foldedSteps === 1 ? "" : "s",
18661
+ stepHint ? ` \xB7 ${stepHint}` : ""
18662
+ ] })
18663
+ ] }) : null,
18443
18664
  /* @__PURE__ */ jsx7(Text7, { color: c, children: "\u2502" }),
18444
- /* @__PURE__ */ jsx7(RenderedSegments, { segments, borderColor: c, wrapWidth })
18665
+ foldedTail.trim() ? /* @__PURE__ */ jsx7(RenderedSegments, { segments, borderColor: c, wrapWidth }) : null
18445
18666
  ] });
18446
18667
  })(),
18447
18668
  toolStreams.length > 0 && /* @__PURE__ */ jsx7(Box7, { flexDirection: "column", paddingLeft: mode === "chat" ? 1 : 2, children: toolStreams.map((entry) => {
@@ -18458,13 +18679,16 @@ var StreamingView = React7.memo(function StreamingView2({ streamingText, mode, l
18458
18679
  const nonEmptyLines = displayOutput.split("\n").filter((line) => line.trim());
18459
18680
  const previewOutput = nonEmptyLines.slice(-2).join(" ");
18460
18681
  const preview = previewOutput.length > 96 ? previewOutput.slice(0, 95) + "\u2026" : previewOutput;
18461
- const rawTail = displayOutput.length > 6e3 ? displayOutput.slice(-6e3) : displayOutput;
18462
- const firstNl = displayOutput.length > 6e3 ? rawTail.indexOf("\n") : -1;
18682
+ const rawTailLen = 6e3;
18683
+ const rawTail = displayOutput.length > rawTailLen ? displayOutput.slice(-rawTailLen) : displayOutput;
18684
+ const firstNl = displayOutput.length > rawTailLen ? rawTail.indexOf("\n") : -1;
18463
18685
  const windowedTail = firstNl >= 0 ? rawTail.slice(firstNl + 1) : rawTail;
18464
18686
  const cleanedTail = cleanEngineOutput(windowedTail);
18465
18687
  const tailLines = cleanedTail.split("\n");
18466
18688
  const boundedTail = tailLines.length > 12 ? tailLines.slice(-12).join("\n") : cleanedTail;
18467
- const segments = parseMarkdownBlocks(boundedTail);
18689
+ const cleanedPrefix = tailLines.length > 12 ? tailLines.slice(0, -12).join("\n") + "\n" : "";
18690
+ const contextualized = contextualizeSlicedMarkdown(cleanedPrefix, boundedTail);
18691
+ const segments = parseMarkdownBlocks(contextualized);
18468
18692
  const wrapWidth = contentWidth(mode === "chat" ? 8 : 10);
18469
18693
  return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginBottom: 1, children: [
18470
18694
  /* @__PURE__ */ jsxs7(Text7, { children: [
@@ -18540,6 +18764,17 @@ function buildPlanChromeSummary(activePlan, activePlanState, planModeQueued, aut
18540
18764
  const failed = Number(gauge.failed ?? 0);
18541
18765
  return { visible: true, label, color: gauge.visible ? gauge.color : "#c084fc", shortId: gauge.shortId ?? "", bar: gauge.bar ?? "", pct: Number(gauge.pct ?? 0), stepLabel: gauge.label ?? "", current: gauge.current ?? "", failed, action };
18542
18766
  }
18767
+ function contextualizeSlicedMarkdown(prefix, slicedText) {
18768
+ const parts = prefix.split("```");
18769
+ if (parts.length % 2 === 0) {
18770
+ const lastPart = parts[parts.length - 1];
18771
+ const firstLine = lastPart.split("\n")[0].trim();
18772
+ const lang = /^[a-zA-Z0-9_\-]+$/.test(firstLine) ? firstLine : "";
18773
+ return `\`\`\`${lang}
18774
+ ${slicedText}`;
18775
+ }
18776
+ return slicedText;
18777
+ }
18543
18778
 
18544
18779
  // src/generated/blocks/file-rail.tsx
18545
18780
  import React8 from "react";
@@ -18944,6 +19179,27 @@ function formatSessionResults(results) {
18944
19179
  return sections.join("\n");
18945
19180
  }
18946
19181
 
19182
+ // src/generated/lib/terminal-notify.ts
19183
+ import { stdout } from "process";
19184
+ function bell() {
19185
+ if (!stdout.isTTY) {
19186
+ return;
19187
+ }
19188
+ if (process.env.AGON_NO_BELL) {
19189
+ return;
19190
+ }
19191
+ stdout.write("\x07");
19192
+ }
19193
+ function setWindowTitle(label) {
19194
+ if (!stdout.isTTY) {
19195
+ return;
19196
+ }
19197
+ if (process.env.AGON_NO_TITLE) {
19198
+ return;
19199
+ }
19200
+ stdout.write("\x1B]0;" + label + "\x07");
19201
+ }
19202
+
18947
19203
  // src/generated/surfaces/app-composer.ts
18948
19204
  import { join as join45 } from "path";
18949
19205
  import { readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
@@ -19599,8 +19855,27 @@ function parseMarkdownToRows(baseKey, text, wrapWidth, paddingLeft, borderColor)
19599
19855
  if (segment.type === "table") {
19600
19856
  const headers = segment.headers ?? [];
19601
19857
  const tableRows = segment.rows ?? [];
19602
- const headerLine = headers.join(" \u2502 ");
19603
- const ruleWidth = Math.max(12, Math.min(wrapWidth, headerLine.length));
19858
+ const alignments = segment.alignments ?? [];
19859
+ const colWidths = headers.map((h, i) => {
19860
+ let max = h.length;
19861
+ for (const row of tableRows) {
19862
+ if (row[i] && row[i].length > max) max = row[i].length;
19863
+ }
19864
+ return max;
19865
+ });
19866
+ const padCell = (text2, colIdx) => {
19867
+ const w = colWidths[colIdx] ?? text2.length;
19868
+ const align = alignments[colIdx] ?? "left";
19869
+ if (align === "right") return text2.padStart(w);
19870
+ if (align === "center") {
19871
+ const pad = w - text2.length;
19872
+ const left = Math.floor(pad / 2);
19873
+ return " ".repeat(left) + text2 + " ".repeat(pad - left);
19874
+ }
19875
+ return text2.padEnd(w);
19876
+ };
19877
+ const headerLine = headers.map((h, i) => padCell(h, i)).join(" \u2502 ");
19878
+ const sepLine = colWidths.map((w) => "\u2500".repeat(w)).join("\u2500\u253C\u2500");
19604
19879
  rows.push({
19605
19880
  key: `${baseKey}-table-head-${rowIndex++}`,
19606
19881
  kind: "segments",
@@ -19613,15 +19888,16 @@ function parseMarkdownToRows(baseKey, text, wrapWidth, paddingLeft, borderColor)
19613
19888
  kind: "segments",
19614
19889
  paddingLeft,
19615
19890
  borderColor,
19616
- segments: [{ text: "\u2500".repeat(ruleWidth), dimColor: true }]
19891
+ segments: [{ text: sepLine, dimColor: true }]
19617
19892
  });
19618
19893
  tableRows.forEach((tableRow, index) => {
19894
+ const rowLine = tableRow.map((cell, i) => padCell(cell, i)).join(" \u2502 ");
19619
19895
  rows.push({
19620
19896
  key: `${baseKey}-table-row-${rowIndex++}-${index}`,
19621
19897
  kind: "segments",
19622
19898
  paddingLeft,
19623
19899
  borderColor,
19624
- segments: [{ text: tableRow.join(" \u2502 ") }]
19900
+ segments: [{ text: rowLine }]
19625
19901
  });
19626
19902
  });
19627
19903
  }
@@ -20118,8 +20394,10 @@ function buildTranscriptRows(blocks, mode, toolOutputExpanded, thinkingExpanded)
20118
20394
  if (!cleaned.trim()) return;
20119
20395
  const accentColor = color256toHex(event.color ?? (ENGINE_COLORS[event.engineId] ?? 124));
20120
20396
  if (rows.length > 0) pushSpacer(`${baseKey}-gap`);
20397
+ const foldNote = event.foldedSteps && event.foldedSteps > 0 ? `\u25B8 ${event.foldedSteps} reasoning steps folded \xB7 /raw to inspect` : "";
20121
20398
  if (mode === "chat") {
20122
20399
  pushSegmentsRow(`${baseKey}-chat-head`, 1, [{ text: `${icons().dotOn} ${event.engineId}`, color: accentColor, bold: true }]);
20400
+ if (foldNote) pushSegmentsRow(`${baseKey}-chat-fold`, 1, [{ text: foldNote, dimColor: true }]);
20123
20401
  pushSpacer(`${baseKey}-chat-space`);
20124
20402
  rows.push(...cachedMarkdownRows(baseKey, cleaned, chatWidth, 1, ""));
20125
20403
  return;
@@ -20128,6 +20406,12 @@ function buildTranscriptRows(blocks, mode, toolOutputExpanded, thinkingExpanded)
20128
20406
  { text: "\u250C\u2500\u2500 ", color: accentColor },
20129
20407
  { text: event.engineId, color: accentColor, bold: true }
20130
20408
  ]);
20409
+ if (foldNote) {
20410
+ pushSegmentsRow(`${baseKey}-engine-fold`, 2, [
20411
+ { text: "\u2502 ", color: accentColor },
20412
+ { text: foldNote, dimColor: true }
20413
+ ]);
20414
+ }
20131
20415
  pushSegmentsRow(`${baseKey}-engine-rule`, 2, [{ text: "\u2502", color: accentColor }]);
20132
20416
  rows.push(...cachedMarkdownRows(baseKey, cleaned, engineWidth, 2, accentColor));
20133
20417
  pushSegmentsRow(`${baseKey}-engine-foot`, 2, [{ text: "\u2514\u2500\u2500", color: accentColor }]);
@@ -21442,6 +21726,8 @@ function App() {
21442
21726
  const activeAbortRef = useRef4(null);
21443
21727
  const activeTurnRef = useRef4(null);
21444
21728
  const lastActivityTimeRef = useRef4(Date.now());
21729
+ const pendingBellRef = useRef4(false);
21730
+ const awaitingPlanAnnouncedRef = useRef4("");
21445
21731
  const blockArchivePathRef = useRef4(makeBlockArchivePath(Date.now()));
21446
21732
  const nestedCtrlShortcutRef = useRef4({ key: "", at: 0 });
21447
21733
  const displayRowCountRef = useRef4(0);
@@ -21694,12 +21980,20 @@ function App() {
21694
21980
  const transition = useCallback((fn) => {
21695
21981
  setReplState((prev) => {
21696
21982
  try {
21697
- return fn({ state: prev }).state;
21983
+ const next = fn({ state: prev }).state;
21984
+ if (next === "idle" && prev !== "idle") {
21985
+ if (!pendingBellRef.current) {
21986
+ bell();
21987
+ pendingBellRef.current = true;
21988
+ }
21989
+ setWindowTitle("agon");
21990
+ }
21991
+ return next;
21698
21992
  } catch {
21699
21993
  return prev;
21700
21994
  }
21701
21995
  });
21702
- }, []);
21996
+ }, [bell, setWindowTitle, pendingBellRef]);
21703
21997
  const trackAbort = useCallback((abort) => {
21704
21998
  if (activeAbortRef.current) {
21705
21999
  _activeAborts.delete(activeAbortRef.current);
@@ -21821,6 +22115,11 @@ function App() {
21821
22115
  dispatch({ type: "warning", message });
21822
22116
  }
21823
22117
  setReplState((prev) => prev === "idle" ? prev : cancelReplState({ state: prev }).state);
22118
+ if (!pendingBellRef.current) {
22119
+ bell();
22120
+ pendingBellRef.current = true;
22121
+ }
22122
+ setWindowTitle("agon");
21824
22123
  }
21825
22124
  if (clearChat) {
21826
22125
  dispatch({ type: "clear" });
@@ -21881,6 +22180,8 @@ function App() {
21881
22180
  }, []);
21882
22181
  const handleInputChange = useCallback((value) => {
21883
22182
  keyT0Ref.current = perfNow();
22183
+ pendingBellRef.current = false;
22184
+ awaitingPlanAnnouncedRef.current = "";
21884
22185
  if (questionState && questionState.choices) {
21885
22186
  return;
21886
22187
  }
@@ -21927,7 +22228,7 @@ function App() {
21927
22228
  const updatedValue = nextValue.slice(0, change.start) + replacement + nextValue.slice(change.start + change.inserted.length);
21928
22229
  inputValueRef.current = updatedValue;
21929
22230
  setInputValue(updatedValue);
21930
- }, [slashPickerOpen, enginePickerOpen, modelPickerOpen, questionState, planModeQueued, autoModeQueued, livePaneVisible]);
22231
+ }, [slashPickerOpen, enginePickerOpen, modelPickerOpen, questionState, planModeQueued, autoModeQueued, livePaneVisible, pendingBellRef]);
21931
22232
  const sendBtwMessage = useCallback((question) => {
21932
22233
  const q = (question ?? "").trim();
21933
22234
  if (!q) return;
@@ -22013,6 +22314,8 @@ function App() {
22013
22314
  const handleSubmit = useCallback(async (value) => {
22014
22315
  inputEpochRef.current += 1;
22015
22316
  let input = cleanSubmitValue(value);
22317
+ pendingBellRef.current = false;
22318
+ awaitingPlanAnnouncedRef.current = "";
22016
22319
  if (!input) return;
22017
22320
  if (input === "/") {
22018
22321
  if (planModeQueued) setPlanModeQueued(false);
@@ -22098,6 +22401,8 @@ function App() {
22098
22401
  const autoModeForTurn = autoModeQueued && input.trim() && !input.startsWith("/");
22099
22402
  if (planModeQueued) setPlanModeQueued(false);
22100
22403
  transition(startCommandReplState);
22404
+ pendingBellRef.current = false;
22405
+ setWindowTitle("\u25CF agon \u2014 running");
22101
22406
  dispatch({ type: "separator" });
22102
22407
  dispatch({ type: "user-message", content: input });
22103
22408
  const { text: cleanInput, images: detectedImages } = extractImagesFromInput(input, resolveWorkingDir());
@@ -22129,10 +22434,14 @@ function App() {
22129
22434
  fn().then(() => {
22130
22435
  jobManager.complete(job.id);
22131
22436
  setJobList([...jobManager.list()]);
22437
+ bell();
22438
+ setWindowTitle("agon");
22132
22439
  }).catch((err) => {
22133
22440
  jobManager.fail(job.id, err instanceof Error ? err.message : String(err));
22134
22441
  setJobList([...jobManager.list()]);
22135
22442
  dispatch({ type: "error", message: err instanceof Error ? err.message : String(err) });
22443
+ bell();
22444
+ setWindowTitle("agon");
22136
22445
  });
22137
22446
  },
22138
22447
  setMode,
@@ -22190,9 +22499,9 @@ function App() {
22190
22499
  dispatch({ type: "error", message: err instanceof Error ? err.message : String(err) });
22191
22500
  } finally {
22192
22501
  if (activeTurnRef.current?.input === input) activeTurnRef.current = null;
22193
- setReplState((prev) => prev === "idle" ? prev : finishReplState({ state: prev }).state);
22502
+ transition(finishReplState);
22194
22503
  }
22195
- }, [replState, dispatch, buildContext, mode, pendingImages, jobManager, loadedExtensions, extensionSkills, commandRegistry, eventBus, planModeQueued, autoModeQueued, setPersistentAutoMode, setActivePlanWrapped, outputBlocks, btwPanel, sendBtwMessage]);
22504
+ }, [replState, dispatch, buildContext, mode, pendingImages, jobManager, loadedExtensions, extensionSkills, commandRegistry, eventBus, planModeQueued, autoModeQueued, setPersistentAutoMode, setActivePlanWrapped, outputBlocks, btwPanel, sendBtwMessage, pendingBellRef, awaitingPlanAnnouncedRef]);
22196
22505
  const handleReviewActionCb = useCallback((action) => {
22197
22506
  if (!reviewEvent) {
22198
22507
  return;
@@ -22231,7 +22540,7 @@ function App() {
22231
22540
  setEnginePickerOpen(false);
22232
22541
  setModelPickerOpen(true);
22233
22542
  setModelPickerCliGroups([]);
22234
- import("./src-4A5FVACG.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
22543
+ import("./src-253BUXEF.js").then(({ fetchModelsRegistry: fetchModelsRegistry2, buildModelEntries: buildModelEntries2, buildCliGroupsImmediate, refreshCliGroup, refreshCliGroupVersion }) => {
22235
22544
  let cliGroups = buildCliGroupsImmediate();
22236
22545
  setModelPickerCliGroups(cliGroups);
22237
22546
  for (const g of cliGroups) {
@@ -22392,7 +22701,7 @@ function App() {
22392
22701
  if (ans === "later") return;
22393
22702
  if (ans === "update") {
22394
22703
  setUpdateInfo(null);
22395
- import("./update-DLPMYTF3.js").then((m) => m.runUpdate(latest)).catch((err) => {
22704
+ import("./update-ODAAXWOD.js").then((m) => m.runUpdate(latest)).catch((err) => {
22396
22705
  console.error("[agon] failed to launch update:", err && err.message ? err.message : String(err));
22397
22706
  });
22398
22707
  return;
@@ -22674,6 +22983,12 @@ function App() {
22674
22983
  case "planControl":
22675
22984
  ctrlKeyHandledRef.current = true;
22676
22985
  setPlanApprovalIndex(0);
22986
+ if (action.action === "revise") {
22987
+ setPendingPlanProposal(null);
22988
+ setInputValue("Revise the plan: ");
22989
+ dispatch({ type: "info", message: "Type your revision and press Enter (Esc clears)." });
22990
+ return;
22991
+ }
22677
22992
  handleSubmit(action.action === "approve" ? "/approve" : "/cancel");
22678
22993
  return;
22679
22994
  case "movePlanApproval":
@@ -22810,6 +23125,27 @@ function App() {
22810
23125
  useEffect6(() => {
22811
23126
  modeRef.current = mode;
22812
23127
  }, [mode]);
23128
+ useEffect6(() => {
23129
+ const planState = String(activePlan?.state ?? "");
23130
+ const planAwaiting = planState === "awaiting_approval";
23131
+ const planId = String(activePlan?.id ?? "");
23132
+ if (questionState || planAwaiting) {
23133
+ const freshPlan = planAwaiting && planId && planId !== awaitingPlanAnnouncedRef.current;
23134
+ if (!pendingBellRef.current || freshPlan) {
23135
+ bell();
23136
+ pendingBellRef.current = true;
23137
+ }
23138
+ if (freshPlan) awaitingPlanAnnouncedRef.current = planId;
23139
+ setWindowTitle("\u25CF agon \u2014 input needed");
23140
+ } else if (replState === "idle") {
23141
+ setWindowTitle("agon");
23142
+ } else {
23143
+ setWindowTitle("\u25CF agon \u2014 running");
23144
+ }
23145
+ if (!planAwaiting) {
23146
+ awaitingPlanAnnouncedRef.current = "";
23147
+ }
23148
+ }, [questionState, activePlan, replState, bell, setWindowTitle, pendingBellRef, awaitingPlanAnnouncedRef]);
22813
23149
  useEffect6(() => {
22814
23150
  mouseSelectionRef.current = mouseSelection;
22815
23151
  }, [mouseSelection]);
@@ -23898,7 +24234,7 @@ maybeNotifyIsolationMigration();
23898
24234
  var main = defineCommand31({
23899
24235
  meta: {
23900
24236
  name: "agon",
23901
- version: "0.1.5",
24237
+ version: "0.1.7",
23902
24238
  description: "Any AI can join. They compete. You ship."
23903
24239
  },
23904
24240
  subCommands: {