@songsid/agend 2.1.3-beta.2 → 2.1.3-beta.4

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.
package/dist/config.js CHANGED
@@ -42,6 +42,7 @@ export const DEFAULT_DAILY_SUMMARY = {
42
42
  export const DEFAULT_INSTANCE_CONFIG = {
43
43
  auto_pause_after: 0, // minutes; 0 = disabled (opt-in)
44
44
  mcp_auto_restart: true, // restart (idle-gated) when the MCP server dies
45
+ mcp_proxy_reply: false, // opt-in: relaying raw pane text can leak more than regex redaction catches
45
46
  kiro_ui: "legacy",
46
47
  terminal: {
47
48
  enabled: true,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/daemon.d.ts CHANGED
@@ -176,6 +176,23 @@ export declare class FirstDeliveryDelay {
176
176
  }
177
177
  /** Redact likely credentials and control sequences before pane text reaches logs. */
178
178
  export declare function sanitizePaneTail(pane: string, lineCount?: number): string[];
179
+ /**
180
+ * Distill a pane capture into text worth relaying as a proxy reply.
181
+ *
182
+ * Used when the MCP server died and the turn ended with no reply: the agent's
183
+ * final answer exists only on screen. Everything up to and including the last
184
+ * line of the inbound message we pasted is cut (the reply starts after it),
185
+ * lines with no letters or digits are dropped (borders, separators, spinners,
186
+ * bare prompts), and the ready-prompt line is dropped by pattern. Returns null
187
+ * when what remains is trivial — a proxy message must carry an answer, not
188
+ * chrome. Secrets are redacted by sanitizePaneTail, same as stuck diagnostics.
189
+ */
190
+ export declare function extractProxyReplyText(pane: string, opts?: {
191
+ inboundMarker?: string;
192
+ readyPattern?: RegExp | null;
193
+ maxLines?: number;
194
+ maxChars?: number;
195
+ }): string | null;
179
196
  export type InteractivePromptKind = "sudo_password" | "password" | "confirmation" | "press_enter";
180
197
  export interface InteractivePromptDetection {
181
198
  kind: InteractivePromptKind;
@@ -270,6 +287,11 @@ export declare class Daemon extends EventEmitter {
270
287
  private instanceStateBusyPattern;
271
288
  private instanceStateMonitorActive;
272
289
  private statePollInFlight;
290
+ private turnHadInbound;
291
+ private turnOutboundDelivered;
292
+ private turnCorrelationId;
293
+ private turnInboundMarker;
294
+ private proxyReplySeq;
273
295
  private autoPauseController;
274
296
  private pauseRequested;
275
297
  /**
@@ -443,6 +465,23 @@ export declare class Daemon extends EventEmitter {
443
465
  /** Respawn the CLI in the preserved window and block until its prompt is ready. */
444
466
  wake(timeoutMs?: number): Promise<void>;
445
467
  private applyInstanceStateSnapshot;
468
+ /**
469
+ * An inbound message is in the CLI — the turn it starts owns the proxy-reply
470
+ * evidence. Called after deliverMessage confirms the paste, not on arrival: a
471
+ * message can arrive mid-turn and sit queued, and marking at arrival would let
472
+ * the PREVIOUS turn's idle edge consume (and reset) the new turn's state.
473
+ */
474
+ private markTurnStarted;
475
+ /**
476
+ * Turn ended (busy→idle edge): if the MCP server is dead and none of the
477
+ * channel tools verifiably delivered anything this turn, the agent's answer is
478
+ * stranded on screen — relay it. The daemon's own IPC route to the fleet
479
+ * manager does not pass through the dead MCP server. Consuming the turn state
480
+ * here (edge-triggered, then reset) is what makes it at most once per turn.
481
+ */
482
+ private maybeProxyReplyOnTurnEnd;
483
+ /** Relay the pane's final text to the channel, marked as a daemon proxy reply. */
484
+ private sendProxyReply;
446
485
  private clearInstanceStateIdleTimer;
447
486
  private clearInstanceStateStuckTimer;
448
487
  private scheduleInstanceStateStuckDeadline;
package/dist/daemon.js CHANGED
@@ -26,6 +26,9 @@ const CROSS_INSTANCE_TOOLS = new Set(["send_to_instance", "list_instances", "sta
26
26
  const SCHEDULE_TOOLS = new Set(["create_schedule", "list_schedules", "update_schedule", "delete_schedule"]);
27
27
  const DECISION_TOOLS = new Set(["post_decision", "list_decisions", "update_decision"]);
28
28
  const TASK_TOOL = "task";
29
+ // Tools whose success proves the agent got a message out this turn. While any
30
+ // of these succeeded, a dead-MCP proxy reply would double-post — suppress it.
31
+ const TURN_REPLY_TOOLS = new Set(["reply", "send_to_instance", "report_result", "request_information", "delegate_task", "broadcast"]);
29
32
  /** Point a resumed CLI at its one backend-native instruction source. */
30
33
  export function buildInstructionReloadNotice(binaryName, instanceName, instanceDir) {
31
34
  const source = binaryName === "codex" || binaryName === "grok"
@@ -412,6 +415,51 @@ export function sanitizePaneTail(pane, lineCount = 5) {
412
415
  .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "")
413
416
  .slice(0, 200));
414
417
  }
418
+ /**
419
+ * Distill a pane capture into text worth relaying as a proxy reply.
420
+ *
421
+ * Used when the MCP server died and the turn ended with no reply: the agent's
422
+ * final answer exists only on screen. Everything up to and including the last
423
+ * line of the inbound message we pasted is cut (the reply starts after it),
424
+ * lines with no letters or digits are dropped (borders, separators, spinners,
425
+ * bare prompts), and the ready-prompt line is dropped by pattern. Returns null
426
+ * when what remains is trivial — a proxy message must carry an answer, not
427
+ * chrome. Secrets are redacted by sanitizePaneTail, same as stuck diagnostics.
428
+ */
429
+ export function extractProxyReplyText(pane, opts = {}) {
430
+ const lines = sanitizePaneTail(pane, opts.maxLines ?? 40);
431
+ const marker = opts.inboundMarker?.trim();
432
+ // Require a distinctive marker: a short one ("ok") would match agent text.
433
+ if (marker && marker.length >= 8) {
434
+ for (let i = lines.length - 1; i >= 0; i--) {
435
+ if (lines[i].includes(marker)) {
436
+ lines.splice(0, i + 1);
437
+ break;
438
+ }
439
+ }
440
+ }
441
+ const ready = opts.readyPattern
442
+ ? new RegExp(opts.readyPattern.source, opts.readyPattern.flags.replace(/[gy]/g, ""))
443
+ : null;
444
+ const kept = lines.filter(line => {
445
+ const t = line.trim();
446
+ if (!t)
447
+ return true; // keep paragraph breaks; collapsed below
448
+ if (!/[\p{L}\p{N}]/u.test(t))
449
+ return false;
450
+ if (ready && ready.test(line))
451
+ return false;
452
+ return true;
453
+ });
454
+ const text = kept.join("\n").replace(/\n{3,}/g, "\n\n").trim();
455
+ // Trivial = nothing an operator could read as an answer.
456
+ const meaningful = text.replace(/[^\p{L}\p{N}]/gu, "");
457
+ if (meaningful.length < 2)
458
+ return null;
459
+ const maxChars = opts.maxChars ?? 3000;
460
+ // The end of the turn is the answer — when over budget, keep the tail.
461
+ return text.length > maxChars ? text.slice(text.length - maxChars) : text;
462
+ }
415
463
  const INTERACTIVE_PROMPT_PATTERNS = [
416
464
  { kind: "sudo_password", pattern: /^\s*\[sudo\]\s+password\s+for\s+[^:\n]+:\s*$/im },
417
465
  // macOS sudo and several package installers use this exact no-echo prompt.
@@ -553,6 +601,15 @@ export class Daemon extends EventEmitter {
553
601
  instanceStateBusyPattern = null;
554
602
  instanceStateMonitorActive = false;
555
603
  statePollInFlight = false;
604
+ // ── Dead-MCP proxy reply: per-turn evidence ─────────────────────────────
605
+ // Set when an inbound message lands in the CLI; cleared on the idle edge that
606
+ // ends the turn. With a dead MCP server and no successful channel tool call in
607
+ // between, the agent's answer exists only on screen — the daemon relays it.
608
+ turnHadInbound = false;
609
+ turnOutboundDelivered = false;
610
+ turnCorrelationId;
611
+ turnInboundMarker;
612
+ proxyReplySeq = 0;
556
613
  autoPauseController;
557
614
  pauseRequested = false;
558
615
  /**
@@ -1882,6 +1939,9 @@ export class Daemon extends EventEmitter {
1882
1939
  // tool_result (interrupted, crashed, cancelled), which would otherwise leave
1883
1940
  // the last tool pinned to the progress line for the rest of the session.
1884
1941
  this.publishActivity(null);
1942
+ // Must run before the mcpRestartPending branch below: the pane text is the
1943
+ // only copy of the answer, and the revival restart is about to clear it.
1944
+ this.maybeProxyReplyOnTurnEnd(pane);
1885
1945
  }
1886
1946
  if (snapshot.state !== previous) {
1887
1947
  this.logger.info({
@@ -1914,6 +1974,113 @@ export class Daemon extends EventEmitter {
1914
1974
  this.emit("auto_pause_requested", { name: this.name, idleSince: snapshot.stateChangedAt });
1915
1975
  }
1916
1976
  }
1977
+ /**
1978
+ * An inbound message is in the CLI — the turn it starts owns the proxy-reply
1979
+ * evidence. Called after deliverMessage confirms the paste, not on arrival: a
1980
+ * message can arrive mid-turn and sit queued, and marking at arrival would let
1981
+ * the PREVIOUS turn's idle edge consume (and reset) the new turn's state.
1982
+ */
1983
+ markTurnStarted(meta, deliveredText) {
1984
+ // Channel turns only. A cross-instance inbound (from_instance, empty
1985
+ // chat_id) does not update lastChatId, so its proxy reply would land in
1986
+ // whatever USER topic spoke to this instance last — the wrong audience for
1987
+ // a task result, and a stale one (sol's review of #515).
1988
+ if (meta.from_instance || !meta.chat_id)
1989
+ return;
1990
+ this.turnHadInbound = true;
1991
+ this.turnOutboundDelivered = false;
1992
+ this.turnCorrelationId = meta.correlation_id || undefined;
1993
+ // The last non-empty line of what we pasted: everything on screen after it
1994
+ // is the agent's own output.
1995
+ this.turnInboundMarker = deliveredText.split(/\r?\n/).map(l => l.trim()).filter(Boolean).pop();
1996
+ }
1997
+ /**
1998
+ * Turn ended (busy→idle edge): if the MCP server is dead and none of the
1999
+ * channel tools verifiably delivered anything this turn, the agent's answer is
2000
+ * stranded on screen — relay it. The daemon's own IPC route to the fleet
2001
+ * manager does not pass through the dead MCP server. Consuming the turn state
2002
+ * here (edge-triggered, then reset) is what makes it at most once per turn.
2003
+ */
2004
+ maybeProxyReplyOnTurnEnd(pane) {
2005
+ const hadInbound = this.turnHadInbound;
2006
+ const delivered = this.turnOutboundDelivered;
2007
+ const correlationId = this.turnCorrelationId;
2008
+ const inboundMarker = this.turnInboundMarker;
2009
+ this.turnHadInbound = false;
2010
+ this.turnOutboundDelivered = false;
2011
+ this.turnCorrelationId = undefined;
2012
+ this.turnInboundMarker = undefined;
2013
+ if (!hadInbound || delivered || this.isPaused)
2014
+ return;
2015
+ // Opt-in: raw pane text can carry secrets past the regex redaction.
2016
+ if (this.config.mcp_proxy_reply !== true)
2017
+ return;
2018
+ // "dead" only: unknown means not started or exited cleanly — never proxy on it.
2019
+ if (mcpServerState(this.instanceDir).state !== "dead")
2020
+ return;
2021
+ void this.sendProxyReply(pane, inboundMarker, correlationId);
2022
+ }
2023
+ /** Relay the pane's final text to the channel, marked as a daemon proxy reply. */
2024
+ async sendProxyReply(pane, inboundMarker, correlationId) {
2025
+ try {
2026
+ // The idle capture normally hands its pane in; fall back only when the
2027
+ // edge came from a path without one.
2028
+ if (pane === undefined)
2029
+ pane = await this.tmux?.capturePane();
2030
+ if (!pane)
2031
+ return;
2032
+ const text = extractProxyReplyText(pane, { inboundMarker, readyPattern: this.instanceStateReadyPattern });
2033
+ if (!text) {
2034
+ this.logger.debug("Dead-MCP proxy reply skipped — pane tail is trivial");
2035
+ return;
2036
+ }
2037
+ let body = `⚠️ [MCP unavailable — proxy reply]\n\n${text}`;
2038
+ if (correlationId)
2039
+ body += `\n\n(correlation_id: ${correlationId})`;
2040
+ const args = { text: body };
2041
+ // Same context-bound routing as the reply tool in handleToolCall.
2042
+ if (this.lastChatId) {
2043
+ args.chat_id = this.lastChatId;
2044
+ if (this.lastThreadId)
2045
+ args.thread_id = this.lastThreadId;
2046
+ }
2047
+ this.logger.warn({ correlationId }, "MCP server dead and the turn sent no reply — relaying the pane text as a proxy reply");
2048
+ this.emit("mcp_proxy_reply", { name: this.name, correlationId });
2049
+ const adapters = this.messageBus.getAllAdapters();
2050
+ if (adapters.length > 0) {
2051
+ routeToolCall(adapters[0], "reply", args, this.lastThreadId, (_result, error) => {
2052
+ if (error)
2053
+ this.logger.error({ error }, "Dead-MCP proxy reply failed");
2054
+ });
2055
+ return;
2056
+ }
2057
+ if (!this.ipcServer)
2058
+ return;
2059
+ const fleetReqId = `proxyreply_${++this.proxyReplySeq}`;
2060
+ this.ipcServer.broadcast({
2061
+ type: "fleet_outbound",
2062
+ tool: "reply",
2063
+ args,
2064
+ fleetRequestId: fleetReqId,
2065
+ adapterId: this.lastAdapterId,
2066
+ });
2067
+ const timeout = setTimeout(() => {
2068
+ this.pendingIpcRequests.delete(fleetReqId);
2069
+ this.logger.error("Dead-MCP proxy reply timed out waiting for the fleet manager");
2070
+ }, daemonBudgetMs("reply"));
2071
+ timeout.unref?.();
2072
+ this.pendingIpcRequests.set(fleetReqId, (respMsg) => {
2073
+ clearTimeout(timeout);
2074
+ if (respMsg.error)
2075
+ this.logger.error({ error: respMsg.error }, "Dead-MCP proxy reply failed");
2076
+ else
2077
+ this.logger.info("Dead-MCP proxy reply delivered");
2078
+ });
2079
+ }
2080
+ catch (err) {
2081
+ this.logger.error({ err: err.message }, "Dead-MCP proxy reply attempt failed");
2082
+ }
2083
+ }
1917
2084
  clearInstanceStateIdleTimer() {
1918
2085
  if (this.instanceStateIdleTimer)
1919
2086
  clearTimeout(this.instanceStateIdleTimer);
@@ -2282,7 +2449,8 @@ export class Daemon extends EventEmitter {
2282
2449
  const rawText = content.slice(5);
2283
2450
  this.logger.info({ user }, "Raw paste from topic mode user");
2284
2451
  this.pasteLock = this.pasteLock.then(async () => {
2285
- await this.deliverMessage(rawText);
2452
+ if (await this.deliverMessage(rawText))
2453
+ this.markTurnStarted(meta, rawText);
2286
2454
  }).catch(err => {
2287
2455
  this.logger.warn({ err: err.message }, "pasteLock raw delivery error");
2288
2456
  });
@@ -2343,7 +2511,8 @@ export class Daemon extends EventEmitter {
2343
2511
  const status = (chatId && messageId)
2344
2512
  ? { chatId: meta.thread_id || chatId, messageId }
2345
2513
  : undefined;
2346
- await this.deliverMessage(formatted, status);
2514
+ if (await this.deliverMessage(formatted, status))
2515
+ this.markTurnStarted(meta, formatted);
2347
2516
  }
2348
2517
  finally {
2349
2518
  this.pasteQueueDepth--;
@@ -2664,6 +2833,11 @@ export class Daemon extends EventEmitter {
2664
2833
  this.logger.debug({ tool, requestId }, "Tool call from MCP server");
2665
2834
  // For now, log and respond. Full adapter routing will be wired in fleet manager.
2666
2835
  const respond = (result, error) => {
2836
+ // A message that verifiably went out stands down the dead-MCP proxy reply
2837
+ // for this turn: the agent proved it can still speak for itself.
2838
+ if (!error && result != null && TURN_REPLY_TOOLS.has(tool)) {
2839
+ this.turnOutboundDelivered = true;
2840
+ }
2667
2841
  this.ipcServer?.send(socket, { requestId, result, error });
2668
2842
  };
2669
2843
  // Repo checkout — handled locally in daemon (no fleet-manager)