@dreb/coding-agent 2.70.1 → 2.71.0

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.
@@ -19,17 +19,17 @@ import { DailyCostTracker, dailyCostSourcesForSession, } from "../../core/daily-
19
19
  import { acquireDreamLock, buildDreamPrompt, cleanupDreamTmpDirs, parseDreamCommand, performDreamBackup, pruneOldBackups, resolveDreamContext, validateArchivePath, validateMemoryLinks, } from "../../core/dream.js";
20
20
  import { getGitBranch } from "../../core/git-branch.js";
21
21
  import { parseModelPattern, resolveModelScopePatterns } from "../../core/model-resolver.js";
22
- import { takeOverStdout, writeRawStdout } from "../../core/output-guard.js";
22
+ import { isFatalExitPending, takeOverStdout, writeRawStdout } from "../../core/output-guard.js";
23
23
  import { SessionManager } from "../../core/session-manager.js";
24
24
  import { BUILTIN_SLASH_COMMANDS, parseBuiltinSlashCommand } from "../../core/slash-commands.js";
25
25
  import { SubagentSessionCostTracker } from "../../core/subagent-session-cost-tracker.js";
26
26
  import { TabTitleGenerator } from "../../core/tab-title.js";
27
27
  import { validateThinkingLevelForModel } from "../../core/thinking.js";
28
28
  import { resolveToCwd } from "../../core/tools/path-utils.js";
29
- import { discoverAgentTypes, getBackgroundAgentPendingSteering, getBackgroundAgents, rehydrateBackgroundAgentsFromDisk, steerBackgroundAgent, } from "../../core/tools/subagent.js";
29
+ import { discoverAgentTypes, getBackgroundAgentPendingSteering, getBackgroundAgents, rehydrateBackgroundAgentsFromDisk, setSubagentRpcFullMessageUpdates, steerBackgroundAgent, } from "../../core/tools/subagent.js";
30
30
  import { theme } from "../interactive/theme/theme.js";
31
31
  import { attachJsonlLineReader, serializeJsonLine } from "./jsonl.js";
32
- import { createDashboardRpcEventProjector } from "./rpc-event-projection.js";
32
+ import { createDashboardRpcEventProjector, projectRpcMessageUpdates } from "./rpc-event-projection.js";
33
33
  /**
34
34
  * Map a core {@link SessionInfo} to the RPC DTO, converting Date fields to ISO strings.
35
35
  * Shared by the `list_sessions` and `list_all_sessions` handlers so their shapes cannot drift.
@@ -1419,7 +1419,7 @@ export function cancelPendingRpcExtensionRequests(pendingExtensionRequests) {
1419
1419
  pending.resolve({ type: "extension_ui_response", id, cancelled: true });
1420
1420
  }
1421
1421
  }
1422
- export async function runRpcMode(session, modelFallbackMessage) {
1422
+ export async function runRpcMode(session, modelFallbackMessage, options = {}) {
1423
1423
  takeOverStdout();
1424
1424
  const output = (obj) => {
1425
1425
  writeRawStdout(serializeJsonLine(obj));
@@ -1524,17 +1524,25 @@ export async function runRpcMode(session, modelFallbackMessage) {
1524
1524
  },
1525
1525
  })
1526
1526
  : undefined;
1527
- // Dashboard-launched runtimes (--ui dashboard) get events projected before
1528
- // serialization: message_update's cumulative `message` and
1529
- // `assistantMessageEvent.partial` fields are quadratic in response length on
1530
- // the JSONL pipe, and no dashboard consumer reads them (deltas, message_end,
1531
- // and get_dashboard_snapshot responses carry the authoritative data). Inline
1532
- // image blocks are deduped over the process lifetime so each unique image
1533
- // crosses stdout at most once — later occurrences become image_references
1534
- // the dashboard resolves from its image cache (issue 495). Generic RPC
1535
- // consumers keep the full protocol unchanged. Only the event stream is
1527
+ // Events are projected before serialization. message_update's cumulative
1528
+ // `message` and `assistantMessageEvent.partial` fields are quadratic in
1529
+ // response length on the JSONL pipe (issues 448, 535), so every RPC runtime
1530
+ // strips them by default; deltas, message_end, and command responses carry
1531
+ // the authoritative data. `--rpc-full-message-updates` restores the legacy
1532
+ // full frames for generic clients. Dashboard runtimes (--ui dashboard) are
1533
+ // always projected and additionally dedupe inline images over the process
1534
+ // lifetime — later occurrences become image_references the dashboard
1535
+ // resolves from its image cache (issue 495). Only the event stream is
1536
1536
  // projected — command responses (output() calls below) always stay complete.
1537
- const dashboardEventProjector = session.uiType === "dashboard" ? createDashboardRpcEventProjector() : undefined;
1537
+ const eventProjector = session.uiType === "dashboard"
1538
+ ? createDashboardRpcEventProjector()
1539
+ : options.fullMessageUpdates
1540
+ ? undefined
1541
+ : projectRpcMessageUpdates;
1542
+ // Forward the opt-in to RPC-controlled subagent children: their relayed
1543
+ // background_agent_event payloads are projected inside the child process and
1544
+ // cannot be restored here, so the child must emit full frames itself.
1545
+ setSubagentRpcFullMessageUpdates(eventProjector === undefined);
1538
1546
  // Output all agent events as JSON
1539
1547
  session.subscribe((event) => {
1540
1548
  if (event.type === "background_agent_end") {
@@ -1553,7 +1561,7 @@ export async function runRpcMode(session, modelFallbackMessage) {
1553
1561
  tabTitleGenerator.onMessageEnd(event.message);
1554
1562
  }
1555
1563
  }
1556
- output(dashboardEventProjector ? dashboardEventProjector(event) : event);
1564
+ output(eventProjector ? eventProjector(event) : event);
1557
1565
  });
1558
1566
  // Handle a single command
1559
1567
  const handleCommand = async (command) => {
@@ -1993,6 +2001,12 @@ export async function runRpcMode(session, modelFallbackMessage) {
1993
2001
  subagentSessionCostTracker?.dispose();
1994
2002
  detachInput();
1995
2003
  process.stdin.pause();
2004
+ if (isFatalExitPending()) {
2005
+ // A stdout write failure is already exiting the process nonzero (a dying
2006
+ // consumer often closes stdin and stdout together). Exiting 0 here would
2007
+ // truncate its diagnostic and report success; let the fatal path finish.
2008
+ return new Promise(() => { });
2009
+ }
1996
2010
  process.exit(0);
1997
2011
  }
1998
2012
  async function checkShutdownRequested() {