@kernlang/agon 0.1.0 → 0.1.2

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.
@@ -98,7 +98,7 @@ import {
98
98
  worktreeCreate,
99
99
  worktreeDiff,
100
100
  worktreeRemoveBestEffort
101
- } from "./chunk-GCXVT7RP.js";
101
+ } from "./chunk-7PMMOQZ7.js";
102
102
 
103
103
  // ../forge/src/generated/forge.ts
104
104
  import { randomUUID as randomUUID2 } from "crypto";
@@ -8434,6 +8434,13 @@ function detectNarratedToolStall(text) {
8434
8434
  const STALL_RE = /\b(?:let me (?:check|look|examine|read|search|find|see|review|explore|investigate|understand|get|grab|continue)|i (?:need|want|should|will) (?:to )?(?:check|look|examine|read|search|find|see|review|explore|investigate|understand|get|grab|continue)|now (?:let me|i'll)|continu(?:e|ing)|keep (?:reading|investigating|looking)|next[,.]?\s*(?:i|let)|before (?:i can|proceeding|implementing|deciding))\b/i;
8435
8435
  return FAKE_GATE_RE.test(tail) || READ_INTENT_RE.test(tail) || SEARCH_INTENT_RE.test(tail) || DIR_INTENT_RE.test(tail) || STALL_RE.test(tail);
8436
8436
  }
8437
+ function detectMutationIntentStall(text) {
8438
+ const body = String(text ?? "").trim();
8439
+ if (!body) return false;
8440
+ const MUTATION_INTENT_RE = /\b(?:edit|write|apply|patch|implement|insert|replace|land it|commit it|the (?:change|fix|diff|patch|edit)|make the (?:edit|change)s?|ready to (?:paste|apply))\b/i;
8441
+ 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;
8442
+ return MUTATION_INTENT_RE.test(body) && HANDBACK_RE.test(body);
8443
+ }
8437
8444
  function eagerFailedToolNames(results) {
8438
8445
  const names = [];
8439
8446
  for (const result of results ?? []) {
@@ -9354,7 +9361,7 @@ ${cleaned}`;
9354
9361
  }
9355
9362
  }
9356
9363
  if (name === "ExitPlanMode") {
9357
- const { handleExitPlanMode } = await import("./plan-mode-MWL3DAHY.js");
9364
+ const { handleExitPlanMode } = await import("./plan-mode-DCE7VGQV.js");
9358
9365
  return "[DELEGATION_BREAK] " + handleExitPlanMode(String(args.reason ?? ""), ctx.cesar?.planDispatch ?? null, ctx);
9359
9366
  }
9360
9367
  if (name === "ProposePlan") {
@@ -9377,7 +9384,7 @@ ${cleaned}`;
9377
9384
  }
9378
9385
  }
9379
9386
  }
9380
- const { handleProposePlan } = await import("./plan-mode-MWL3DAHY.js");
9387
+ const { handleProposePlan } = await import("./plan-mode-DCE7VGQV.js");
9381
9388
  const dispatch = ctx.cesar.planDispatch;
9382
9389
  if (!dispatch) {
9383
9390
  return "[PLAN_ERROR] Internal plan display dispatch unavailable. Retry the plan request so Agon can render the approval panel.";
@@ -10566,12 +10573,14 @@ ${enrichedInput}`;
10566
10573
  break;
10567
10574
  }
10568
10575
  dispatch({ type: "spinner-stop" });
10569
- const errBody = (chunk.content ?? "").toString().slice(0, 200) || "unknown stream error";
10570
- dispatch({ type: "warning", message: `Cesar (${cesarEngineId}) stream error before any output: ${errBody}. Try again or switch engine with /engine.` });
10576
+ const _errFull = (chunk.content ?? "").toString();
10577
+ const errBody = _errFull.slice(0, 200) || "unknown stream error";
10578
+ const _deterministic = /\b(?:400|401|403|404)\b|not found|unauthorized|invalid api key|authentication|no such (?:route|endpoint)/i.test(_errFull);
10579
+ dispatch({ type: "warning", message: `Cesar (${cesarEngineId}) stream error before any output: ${errBody}.${_deterministic ? " Looks like an engine config/auth issue \u2014 check the engine with /engines." : " Try again or switch engine with /engine."}` });
10571
10580
  clearInterval(heartbeat);
10572
10581
  processMcpSideChannel();
10573
10582
  if (mcpWatcherInterval) clearInterval(mcpWatcherInterval);
10574
- return { delegated: false, responded: false, decisionReason: "pre-stream-error" };
10583
+ return { delegated: false, responded: false, decisionReason: "pre-stream-error", deterministicFailure: _deterministic };
10575
10584
  }
10576
10585
  if (chunk.type === "done") break;
10577
10586
  if (chunk.type === "text") {
@@ -10857,7 +10866,7 @@ ${enrichedInput}`;
10857
10866
  });
10858
10867
  continue;
10859
10868
  }
10860
- const { handleProposePlan } = await import("./plan-mode-MWL3DAHY.js");
10869
+ const { handleProposePlan } = await import("./plan-mode-DCE7VGQV.js");
10861
10870
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10862
10871
  if (planDispatch) {
10863
10872
  try {
@@ -10870,7 +10879,7 @@ ${enrichedInput}`;
10870
10879
  }
10871
10880
  } else if (signal.tool === "ExitPlanMode") {
10872
10881
  recordToolUse("ExitPlanMode", "mcp", JSON.stringify(signal.args ?? {}), "done");
10873
- const { handleExitPlanMode } = await import("./plan-mode-MWL3DAHY.js");
10882
+ const { handleExitPlanMode } = await import("./plan-mode-DCE7VGQV.js");
10874
10883
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
10875
10884
  try {
10876
10885
  const exitResult = handleExitPlanMode(String(signal.args?.reason ?? ""), planDispatch, ctx);
@@ -11086,7 +11095,7 @@ ${enrichedInput}`;
11086
11095
  output: "A Cesar plan is already active; nested plans are blocked. Resume or cancel the current plan before proposing another."
11087
11096
  });
11088
11097
  } else {
11089
- const { handleProposePlan } = await import("./plan-mode-MWL3DAHY.js");
11098
+ const { handleProposePlan } = await import("./plan-mode-DCE7VGQV.js");
11090
11099
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
11091
11100
  const plan = await handleProposePlan(ppArgs, planDispatch, ctx);
11092
11101
  if (ctx.setActivePlan) ctx.setActivePlan(plan);
@@ -11110,7 +11119,7 @@ ${enrichedInput}`;
11110
11119
  const epArgs = ctx.cesar._exitPlanModeArgs;
11111
11120
  delete ctx.cesar._exitPlanModeArgs;
11112
11121
  try {
11113
- const { handleExitPlanMode } = await import("./plan-mode-MWL3DAHY.js");
11122
+ const { handleExitPlanMode } = await import("./plan-mode-DCE7VGQV.js");
11114
11123
  const planDispatch = ctx.cesar.planDispatch ?? dispatch;
11115
11124
  const exitResult = handleExitPlanMode(String(epArgs?.reason ?? ""), planDispatch, ctx);
11116
11125
  dispatch({ type: "tool-call", engineId: cesarEngineId, tool: "ExitPlanMode", input: JSON.stringify(epArgs ?? {}), status: "done", output: exitResult });
@@ -11194,11 +11203,18 @@ ${qnResult.challengeText}` : ""
11194
11203
  }
11195
11204
  }
11196
11205
  const investigationResponse = response;
11206
+ let mutationStallForced = false;
11207
+ if (!mutationDeferred && !inPlanMode && !ctx.cesar.pendingDelegation && (hadToolActivity || ranToolLoop) && session.alive && !abort.signal.aborted && detectMutationIntentStall(response)) {
11208
+ mutationDeferred = true;
11209
+ mutationStallForced = true;
11210
+ dispatch({ type: "warning", message: "Cesar described a write but called no tool \u2014 unlocking execution and pushing it to apply directly." });
11211
+ }
11197
11212
  if (mutationDeferred && toolRegistry && session.alive && !abort.signal.aborted) {
11198
11213
  toolCtx.readOnlyMode = false;
11199
11214
  dispatch({ type: "spinner-start", message: "Cesar executing\u2026", color });
11200
11215
  let execResponse = "";
11201
- const execGen = session.send({ message: "Investigation complete. You may now use write, edit, and bash tools to execute your plan. Proceed.", signal: abort.signal });
11216
+ const _execNudge = mutationStallForced ? "You HAVE Edit, Write, and Bash tools and you are NOT read-only. The investigation gate only DEFERS the first mutating call; calling Edit/Write/Bash is what unlocks execution \u2014 and it is unlocked now. Apply the change directly this turn with Edit/Write/Bash. Do NOT say you lack write tools, do NOT delegate to an Agent to do the writing, and do NOT ask the user to paste or apply it themselves." : "Investigation complete. You may now use write, edit, and bash tools to execute your plan. Proceed.";
11217
+ const execGen = session.send({ message: _execNudge, signal: abort.signal });
11202
11218
  for await (const chunk of execGen) {
11203
11219
  if (chunk.type === "text") execResponse += chunk.content;
11204
11220
  if (chunk.type === "done" || chunk.type === "error") break;
@@ -11872,4 +11888,4 @@ export {
11872
11888
  ensureCesarSession,
11873
11889
  handleCesarBrain
11874
11890
  };
11875
- //# sourceMappingURL=chunk-4HY7J7LY.js.map
11891
+ //# sourceMappingURL=chunk-IA4AR2R4.js.map