@agentconnect.md/daemon 1.0.0-rc.317 → 1.0.0-rc.319

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.
@@ -6,7 +6,7 @@ import { C as _coercedNumber, T as NEVER, a as array, d as literal, f as looseOb
6
6
  import { a as RELAY_DAEMON_WS_PATH, c as SHARED_CONFIG_ACTION_ID, d as encode, f as MAX_FRAME_BYTES, g as ZodIssueCode, h as RESERVED_MCP_SERVER_NAME, i as RELAY_DAEMON_SUBPROTOCOL, l as buildEnvelope, n as gitRepoLabel, o as buildRelayDaemonFrame, r as normalizeGitUrl, s as decodeRelayDaemonFrame, u as decodeEnvelope } from "./dist-BG425zHm.js";
7
7
  import { a as agentChildEnv, c as persistRelays, i as selectAgent, n as findAgentFiles, o as loadConfig, r as loadAgents, s as persistDaemonId } from "./load-agents-CROyMyq9.js";
8
8
  import { l as resolveRoot, o as mcpSocketPath, u as statePath } from "./paths-DEcUO8lC.js";
9
- import { C as cachedRuntimeVersions, S as cachedRuntimeNames, _ as resolveInMemoryDir, a as prepareWorkspace, b as MEMORY_TOOL_NAMES, c as sessionGitEnv, d as memoryKindOf, f as memoryProviderFor, g as listMemory, h as MemoryTooLargeError, i as prefetchWorkspace, l as simpleGit, m as MemoryPathError, n as turnFailureReason, o as initGitInjection, p as MemoryConflictError, r as installedRuntimes, s as probeGitVersion, t as AcpHost, u as createMemoryProvider, v as writeMemoryFile, w as resolveRuntimes, x as toolsForIntegrations, y as ALL_TOOL_NAMES } from "./acp-host-4pA0zUPK.js";
9
+ import { C as cachedRuntimeVersions, S as cachedRuntimeNames, _ as resolveInMemoryDir, a as prepareWorkspace, b as MEMORY_TOOL_NAMES, c as sessionGitEnv, d as memoryKindOf, f as memoryProviderFor, g as listMemory, h as MemoryTooLargeError, i as prefetchWorkspace, l as simpleGit, m as MemoryPathError, n as turnFailureReason, o as initGitInjection, p as MemoryConflictError, r as installedRuntimes, s as probeGitVersion, t as AcpHost, u as createMemoryProvider, v as writeMemoryFile, w as resolveRuntimes, x as toolsForIntegrations, y as ALL_TOOL_NAMES } from "./acp-host-Dsm0i9DH.js";
10
10
  import { i as GitCredentialCache, n as gitcredSocketPath, r as writeGitcredShim, t as GitCredServer } from "./gitcred-server-Bu-Svl7L.js";
11
11
  import { B as ToolListChangedNotificationSchema, D as ListPromptsResultSchema, E as ListChangedOptionsBaseSchema, F as PromptListChangedNotificationSchema, G as isZ4Schema, H as isJSONRPCRequest, I as ReadResourceResultSchema, J as encodeFrame, K as safeParse, L as ResourceListChangedNotificationSchema, M as ListToolsResultSchema, O as ListResourceTemplatesResultSchema, P as McpError, R as SUPPORTED_PROTOCOL_VERSIONS, S as InitializeResultSchema, T as LATEST_PROTOCOL_VERSION, U as isJSONRPCResultResponse, V as isInitializedNotification, W as getObjectShape, _ as ElicitResultSchema, a as AjvJsonSchemaValidator, b as GetPromptResultSchema, c as mergeCapabilities, d as CompleteResultSchema, f as CreateMessageRequestSchema, g as ElicitRequestSchema, h as CreateTaskResultSchema, i as assertToolsCallTaskCapability, k as ListResourcesResultSchema, m as CreateMessageResultWithToolsSchema, n as serializeMessage, o as require_fast_deep_equal, p as CreateMessageResultSchema, q as decodeFrames, r as assertClientRequestTaskCapability, s as Protocol, t as ReadBuffer, u as CallToolResultSchema, v as EmptyResultSchema, w as JSONRPCMessageSchema, y as ErrorCode } from "./stdio-DnS8WcXi.js";
12
12
  import { createRequire } from "node:module";
@@ -6381,7 +6381,7 @@ var LocalStore = class {
6381
6381
  seq INTEGER PRIMARY KEY AUTOINCREMENT,
6382
6382
  channel TEXT NOT NULL, thread TEXT NOT NULL, ts TEXT,
6383
6383
  sender TEXT NOT NULL, kind TEXT NOT NULL, text TEXT NOT NULL,
6384
- tool_call_id TEXT, body TEXT
6384
+ tool_call_id TEXT, body TEXT, recipient TEXT
6385
6385
  );
6386
6386
  CREATE INDEX IF NOT EXISTS transcript_thread_seq ON transcript (channel, thread, seq);
6387
6387
  -- Dedup conversational rows by platform ts (double-fired inbound / redelivery);
@@ -6480,6 +6480,13 @@ var LocalStore = class {
6480
6480
  this.migrateSessionMutes();
6481
6481
  this.migrateInboxLoopGuardCounted();
6482
6482
  this.migrateTranscriptToolBody();
6483
+ this.migrateTranscriptRecipient();
6484
+ }
6485
+ /** Add the `transcript.recipient` column (the agent a row was delivered to) to a
6486
+ * pre-existing DB. Legacy rows have NULL recipient, so they surface in a session view
6487
+ * only via `sender` — acceptable (pre-migration history predates per-agent scoping). */
6488
+ migrateTranscriptRecipient() {
6489
+ if (!this.db.prepare("PRAGMA table_info(transcript)").all().some((c) => c.name === "recipient")) this.db.exec("ALTER TABLE transcript ADD COLUMN recipient TEXT");
6483
6490
  }
6484
6491
  /** Backfill the durable mute tombstones from the legacy sessions.muted column.
6485
6492
  * Both writes in setSessionMuted stay transactional, so this idempotent sync cannot
@@ -6574,6 +6581,11 @@ var LocalStore = class {
6574
6581
  getSessionByAcpId(acpSessionId) {
6575
6582
  return this.db.prepare("SELECT * FROM sessions WHERE acpSessionId = ?").get(acpSessionId);
6576
6583
  }
6584
+ /** Agent-scoped ACP id lookup for callbacks from one runtime process. ACP ids
6585
+ * are runtime-owned and need not be globally unique across agents. */
6586
+ getSessionByAcpIdForAgent(agentId, acpSessionId) {
6587
+ return this.db.prepare("SELECT * FROM sessions WHERE agentId = ? AND acpSessionId = ?").get(agentId, acpSessionId);
6588
+ }
6577
6589
  /**
6578
6590
  * One newest-first page of a thread's full transcript (all kinds), for `session/history`.
6579
6591
  * Pages backward via `beforeSeq` (the lowest seq already seen; null ⇒ newest page).
@@ -6587,6 +6599,20 @@ var LocalStore = class {
6587
6599
  hasMore
6588
6600
  };
6589
6601
  }
6602
+ /** Like {@link transcriptPage} but scoped to what ONE agent's session actually received +
6603
+ * produced: rows delivered TO it (`recipient = agentId`) or sent BY it (`sender = agentId`).
6604
+ * Used by the console session view so it shows the agent's real conversation, not the whole
6605
+ * shared (channel, thread) thread — which matters now that agent-call turns are
6606
+ * context-isolated and a callee only ever saw the message handed to it. Other participants'
6607
+ * cross-talk in the same thread is correctly excluded. */
6608
+ transcriptPageForAgent(channel, thread, agentId, beforeSeq, limit) {
6609
+ const rows = beforeSeq !== null ? this.db.prepare("SELECT * FROM transcript WHERE channel = ? AND thread = ? AND (recipient = ? OR sender = ?) AND seq < ? ORDER BY seq DESC LIMIT ?").all(channel, thread, agentId, agentId, beforeSeq, limit + 1) : this.db.prepare("SELECT * FROM transcript WHERE channel = ? AND thread = ? AND (recipient = ? OR sender = ?) ORDER BY seq DESC LIMIT ?").all(channel, thread, agentId, agentId, limit + 1);
6610
+ const hasMore = rows.length > limit;
6611
+ return {
6612
+ rows: hasMore ? rows.slice(0, limit) : rows,
6613
+ hasMore
6614
+ };
6615
+ }
6590
6616
  upsertSession(rec) {
6591
6617
  this.db.prepare(`INSERT INTO sessions
6592
6618
  (key, agentId, platform, channel, thread, acpSessionId, state, lastDeliveredTs, updatedAt, muted, triggeredBy)
@@ -6635,7 +6661,7 @@ var LocalStore = class {
6635
6661
  throw err;
6636
6662
  }
6637
6663
  }
6638
- /** Human-facing session title from the runtime's `session_info_update` (latest
6664
+ /** Human-facing session title from ACP or the AgentConnect title tool (latest
6639
6665
  * wins; null clears per ACP semantics). No-op on an unknown key. */
6640
6666
  setSessionTitle(key, title) {
6641
6667
  this.db.prepare("UPDATE sessions SET title = ? WHERE key = ?").run(title, key);
@@ -6779,7 +6805,10 @@ var LocalStore = class {
6779
6805
  return rows;
6780
6806
  }
6781
6807
  appendTranscript(e) {
6782
- this.db.prepare("INSERT OR IGNORE INTO transcript (channel, thread, ts, sender, kind, text) VALUES (@channel, @thread, @ts, @sender, @kind, @text)").run(e);
6808
+ this.db.prepare("INSERT OR IGNORE INTO transcript (channel, thread, ts, sender, kind, text, recipient) VALUES (@channel, @thread, @ts, @sender, @kind, @text, @recipient)").run({
6809
+ ...e,
6810
+ recipient: e.recipient ?? null
6811
+ });
6783
6812
  }
6784
6813
  /** First sight of a tool call: insert its kind='tool' row (title in `text`, the
6785
6814
  * serialized ToolBody in `body`). INSERT OR IGNORE so a re-fired first update is a
@@ -6817,10 +6846,10 @@ var LocalStore = class {
6817
6846
  return this.db.prepare("SELECT * FROM transcript WHERE channel = ? AND thread = ? AND kind = 'text' AND ts > ? ORDER BY ts ASC").all(channel, thread, sinceTs);
6818
6847
  }
6819
6848
  /** The earliest inbound (non-agent) `text` message in a thread — the triggering user
6820
- * message. Used as a session-title fallback when the runtime never pushed one
6821
- * (`setSessionTitle`): many runtimes don't (e.g. the webchat/playground path), so
6822
- * without this the console shows only "Session <id>". Returns undefined when the
6823
- * thread holds no non-agent text row yet. Indexed by (channel, thread, seq). */
6849
+ * message. Used as a session-title fallback when neither ACP nor the title tool
6850
+ * supplied one. Before the first meaningful request, this avoids showing only
6851
+ * "Session <id>". Returns undefined when the thread holds no non-agent text row
6852
+ * yet. Indexed by (channel, thread, seq). */
6824
6853
  firstMessageText(channel, thread, agentId) {
6825
6854
  return this.db.prepare("SELECT text FROM transcript WHERE channel = ? AND thread = ? AND kind = 'text' AND sender != ? ORDER BY seq ASC LIMIT 1").get(channel, thread, agentId)?.text;
6826
6855
  }
@@ -7251,7 +7280,7 @@ var SessionManager = class {
7251
7280
  const dormant = this.deps.store.closedSessionAgents(channel, thread);
7252
7281
  return dormant.length === 1 ? dormant[0] : null;
7253
7282
  }
7254
- async handle(agentId, msg, signal) {
7283
+ async handle(agentId, msg, signal, integrationId) {
7255
7284
  const agent = this.deps.agentById(agentId);
7256
7285
  if (!agent) throw new Error(`unknown agent ${agentId}`);
7257
7286
  this.deps.memory.ensure({ agentId }, agent.name);
@@ -7264,6 +7293,7 @@ var SessionManager = class {
7264
7293
  thread,
7265
7294
  ts,
7266
7295
  sender: msg.sender.id,
7296
+ recipient: agentId,
7267
7297
  kind: "text",
7268
7298
  text: mention ? `${msg.text}\n${mention}`.trim() : msg.text
7269
7299
  });
@@ -7281,7 +7311,12 @@ You keep a persistent memory across sessions; below is its INDEX. Your context i
7281
7311
  `- Source: ${msg.platform}`,
7282
7312
  `- Channel: ${msg.channel}`,
7283
7313
  ...channelName ? [`- Channel name: ${channelName}`] : [],
7284
- ...agent.description ? ["", agent.description] : []
7314
+ ...agent.description ? ["", agent.description] : [],
7315
+ ...this.deps.mcpServersFor ? [
7316
+ "",
7317
+ "# Session naming",
7318
+ "Before sending your first substantive answer, after you understand the first meaningful user request (not a greeting or acknowledgement), call `setSessionTitle` with a concise, specific title. Call it again only if the task focus materially changes. Do not mention this housekeeping action."
7319
+ ] : []
7285
7320
  ].join("\n");
7286
7321
  const sessionContext = [
7287
7322
  agentMeta,
@@ -7297,7 +7332,9 @@ You keep a persistent memory across sessions; below is its INDEX. Your context i
7297
7332
  agent,
7298
7333
  platform: msg.platform,
7299
7334
  channel: msg.channel,
7300
- thread
7335
+ thread,
7336
+ ...integrationId !== void 0 ? { integrationId } : {},
7337
+ isDm: msg.isDm
7301
7338
  }) ?? [];
7302
7339
  const acpSessionId = await abortable(() => host.newSession(cwd, mcpServers, effortOverride, metaContext), signal);
7303
7340
  created = true;
@@ -7321,7 +7358,9 @@ You keep a persistent memory across sessions; below is its INDEX. Your context i
7321
7358
  agent,
7322
7359
  platform: msg.platform,
7323
7360
  channel: msg.channel,
7324
- thread
7361
+ thread,
7362
+ ...integrationId !== void 0 ? { integrationId } : {},
7363
+ isDm: msg.isDm
7325
7364
  }) ?? [];
7326
7365
  let resumed = false;
7327
7366
  if (host.loadSupported?.()) {
@@ -7354,6 +7393,7 @@ You keep a persistent memory across sessions; below is its INDEX. Your context i
7354
7393
  thread,
7355
7394
  ts: h.ts,
7356
7395
  sender: h.sender,
7396
+ recipient: agentId,
7357
7397
  kind: "text",
7358
7398
  text: h.text
7359
7399
  });
@@ -7539,6 +7579,21 @@ function guessMimeFromUrl(url) {
7539
7579
  */
7540
7580
  async function executeTool(ctx, name, args, deps) {
7541
7581
  if (deps.canRun && !deps.canRun(ctx)) throw new Error("this agent turn has been stopped");
7582
+ if (name === "setSessionTitle") {
7583
+ const title = requireString(args, "title").replace(/\s+/g, " ").trim();
7584
+ if (!title) throw new Error("missing required string argument: title");
7585
+ if ([...title].length > 80) throw new Error("session title must be at most 80 characters");
7586
+ await deps.setSessionTitle({
7587
+ agentId: ctx.agentId,
7588
+ platform: ctx.platform,
7589
+ ...ctx.integrationId !== void 0 ? { integrationId: ctx.integrationId } : {},
7590
+ isDm: ctx.isDm,
7591
+ channel: ctx.channel,
7592
+ thread: ctx.thread,
7593
+ title
7594
+ });
7595
+ return { mcpContent: [] };
7596
+ }
7542
7597
  if (name === "listMemory" || name === "readMemory" || name === "writeMemory") {
7543
7598
  const scope = { agentId: ctx.agentId };
7544
7599
  try {
@@ -198561,7 +198616,7 @@ function createSessionReader(store, workspaceUrlFor) {
198561
198616
  messages: []
198562
198617
  };
198563
198618
  const before = req.cursor != null && Number.isFinite(Number(req.cursor)) ? Number(req.cursor) : null;
198564
- const { rows, hasMore } = store.transcriptPage(rec.channel, rec.thread, before, req.limit);
198619
+ const { rows, hasMore } = store.transcriptPageForAgent(rec.channel, rec.thread, rec.agentId, before, req.limit);
198565
198620
  const ordered = rows.slice().reverse();
198566
198621
  const names = store.getDisplayNames(ordered.flatMap((r) => [r.sender, ...mentionedUserIds(r.text)]));
198567
198622
  const built = ordered.map((r) => {
@@ -215458,7 +215513,10 @@ const IDLE_FLUSH_MS = 2e3;
215458
215513
  /** Public Web App console origin used for session deep links when neither a local
215459
215514
  * `webAppUrl` config nor a CP-provided one is set — so "View session" always resolves. */
215460
215515
  const DEFAULT_WEB_APP_URL = "https://app.agentconnect.md";
215461
- /** Per-in-flight-turn rendering state, keyed by ACP sessionId in `this.pending`. */
215516
+ /** ACP session ids are scoped to one agent runtime, not globally unique. */
215517
+ function pendingTurnKey(agentId, acpSessionId) {
215518
+ return JSON.stringify([agentId, acpSessionId]);
215519
+ }
215462
215520
  /** Cap on agent→agent hop depth (design §2.4/§4.5) — reject a `messageAgent` that
215463
215521
  * would push the outgoing hopCount past this, so an A↔B wake loop can't run away. */
215464
215522
  const MAX_AGENT_CALL_HOPS = 8;
@@ -215590,6 +215648,9 @@ var Daemon = class Daemon {
215590
215648
  activeDispatchesByAgent = /* @__PURE__ */ new Map();
215591
215649
  activeDispatchDoneByKey = /* @__PURE__ */ new Map();
215592
215650
  activeReplyConnectionUses = /* @__PURE__ */ new Map();
215651
+ sessionDeliveryBindings = /* @__PURE__ */ new Map();
215652
+ sessionInitializationsByAgent = /* @__PURE__ */ new Map();
215653
+ earlySessionMetadata = /* @__PURE__ */ new Map();
215593
215654
  hostStopping = /* @__PURE__ */ new Map();
215594
215655
  idleSweepTimer;
215595
215656
  cancelTimers = /* @__PURE__ */ new Map();
@@ -215713,6 +215774,7 @@ var Daemon = class Daemon {
215713
215774
  const active = this.activeGateEntries.get(key);
215714
215775
  return !this.paused(ctx.agentId) && active !== void 0 && !active.cancelledReason;
215715
215776
  },
215777
+ setSessionTitle: (req) => this.setSessionTitleFromTool(req),
215716
215778
  gatewayFor: (integrationId) => this.connByIntegration.get(integrationId) ?? this.tgConnByIntegration.get(integrationId) ?? this.dcConnByIntegration.get(integrationId),
215717
215779
  channelAgents: (req) => {
215718
215780
  const client = this.cpClient;
@@ -215741,16 +215803,16 @@ var Daemon = class Daemon {
215741
215803
  hostFor: (agentId) => this.ensureHostAsync(agentId),
215742
215804
  agentById: (id) => this.agents.get(id),
215743
215805
  memory: this.memory,
215744
- mcpServersFor: ({ agent, platform, channel, thread }) => {
215806
+ mcpServersFor: ({ agent, platform, channel, thread, integrationId, isDm }) => {
215745
215807
  const servers = [];
215746
215808
  let tools = toolsForIntegrations(agent.integrations);
215747
215809
  if (memoryKindOf(agent) === "native") tools = tools.filter((t) => !MEMORY_TOOL_NAMES.has(t.name));
215748
- const integrationId = agent.integrations[0]?.id;
215749
215810
  if (tools.length > 0) {
215750
215811
  const token = this.mcp.register({
215751
215812
  agentId: agent.id,
215752
215813
  platform,
215753
215814
  ...integrationId ? { integrationId } : {},
215815
+ isDm,
215754
215816
  channel,
215755
215817
  thread,
215756
215818
  tools
@@ -216651,7 +216713,7 @@ var Daemon = class Daemon {
216651
216713
  const host = this.hosts.get(rec.agentId);
216652
216714
  if (!acpSessionId || !host?.hasSession(acpSessionId)) return;
216653
216715
  host.setSessionModel(acpSessionId, model).then((applied) => {
216654
- const p = this.pending.get(acpSessionId);
216716
+ const p = this.pending.get(pendingTurnKey(rec.agentId, acpSessionId));
216655
216717
  if (applied && p) this.emitStatusBar(p);
216656
216718
  }).catch((err) => this.log.warn(`set-model failed: ${err.message}`));
216657
216719
  }
@@ -216717,7 +216779,7 @@ var Daemon = class Daemon {
216717
216779
  * (model / effort / fast) is reflected. No-op when the session is idle. */
216718
216780
  refreshStatusBarForKey(key) {
216719
216781
  const rec = this.store.getSession(key);
216720
- const p = rec?.acpSessionId ? this.pending.get(rec.acpSessionId) : void 0;
216782
+ const p = rec?.acpSessionId ? this.pending.get(pendingTurnKey(rec.agentId, rec.acpSessionId)) : void 0;
216721
216783
  if (p) this.emitStatusBar(p);
216722
216784
  }
216723
216785
  /** Set a session's Slack output verbosity by its local key. Purely daemon-side (no ACP):
@@ -216733,8 +216795,8 @@ var Daemon = class Daemon {
216733
216795
  * the conversation's in-flight turn like `!cancel` (no mute; follow-ups still dispatch).
216734
216796
  * Resolved by conversationId (the op carries no agentId). No-op when idle. */
216735
216797
  handleWebchatCancel(conversationId) {
216736
- for (const [acpSessionId, p] of this.pending) if (p.webchat?.conversationId === conversationId) {
216737
- this.interruptTurn(p.agentId, p.sessionKey, "cancel", acpSessionId);
216798
+ for (const p of this.pending.values()) if (p.webchat?.conversationId === conversationId) {
216799
+ this.interruptTurn(p.agentId, p.sessionKey, "cancel", p.acpSessionId);
216738
216800
  return;
216739
216801
  }
216740
216802
  for (const [key, entry] of this.activeGateEntries) if (entry.webchat?.conversationId === conversationId) {
@@ -218036,9 +218098,9 @@ var Daemon = class Daemon {
218036
218098
  entry.cancelledReason = "loop protection";
218037
218099
  targets.set(key, { agentId: entry.agentId });
218038
218100
  }
218039
- for (const [acpSessionId, pending] of this.pending) if (pending.loopGuardScope === scope) targets.set(pending.sessionKey, {
218101
+ for (const pending of this.pending.values()) if (pending.loopGuardScope === scope) targets.set(pending.sessionKey, {
218040
218102
  agentId: pending.agentId,
218041
- acpSessionId
218103
+ acpSessionId: pending.acpSessionId
218042
218104
  });
218043
218105
  for (const [key, queued] of this.serialQueue) {
218044
218106
  const entry = queued.find((candidate) => loopGuardScope(candidate.msg) === scope);
@@ -218345,10 +218407,26 @@ var Daemon = class Daemon {
218345
218407
  const conv = msg.platform === "telegram" ? new TelegramConverger(mode) : msg.platform === "discord" ? new DiscordConverger(mode) : new OutputConverger(mode);
218346
218408
  this.showActivity(replyConn, msg.channel, statusThread, wasRunning ? "is thinking…" : "is starting up…");
218347
218409
  const releaseReplyConn = this.holdReplyConnection(replyConn);
218410
+ const previousDeliveryBinding = this.sessionDeliveryBindings.get(key);
218411
+ const deliveryBinding = {
218412
+ agentId,
218413
+ platform: msg.platform,
218414
+ ...integrationId !== void 0 ? { integrationId } : {},
218415
+ isDm: msg.isDm
218416
+ };
218417
+ this.sessionDeliveryBindings.set(key, deliveryBinding);
218418
+ this.sessionInitializationsByAgent.set(agentId, (this.sessionInitializationsByAgent.get(agentId) ?? 0) + 1);
218419
+ const restoreDeliveryBinding = () => {
218420
+ if (this.sessionDeliveryBindings.get(key) !== deliveryBinding) return;
218421
+ if (previousDeliveryBinding) this.sessionDeliveryBindings.set(key, previousDeliveryBinding);
218422
+ else this.sessionDeliveryBindings.delete(key);
218423
+ };
218348
218424
  let handled;
218349
218425
  try {
218350
- handled = await this.sessions.handle(agentId, msg, entry.initAbort.signal);
218426
+ handled = await this.sessions.handle(agentId, msg, entry.initAbort.signal, integrationId);
218351
218427
  } catch (err) {
218428
+ this.finishSessionInitialization(agentId);
218429
+ restoreDeliveryBinding();
218352
218430
  const interrupted = this.dispatchGateReason(entry);
218353
218431
  try {
218354
218432
  this.store.setSessionState(key, "idle", this.clock.now());
@@ -218372,6 +218450,8 @@ var Daemon = class Daemon {
218372
218450
  const { sessionId, blocks, created } = handled;
218373
218451
  const initializedGate = this.dispatchGateReason(entry);
218374
218452
  if (initializedGate) {
218453
+ this.finishSessionInitialization(agentId);
218454
+ restoreDeliveryBinding();
218375
218455
  const interruptedSession = this.store.getSession(key);
218376
218456
  if (created && interruptedSession?.acpSessionId === sessionId) this.store.upsertSession({
218377
218457
  ...interruptedSession,
@@ -218395,6 +218475,7 @@ var Daemon = class Daemon {
218395
218475
  channel: msg.channel,
218396
218476
  thread: statusThread
218397
218477
  });
218478
+ this.finishSessionInitialization(agentId, sessionId);
218398
218479
  let resolveDone;
218399
218480
  const done = new Promise((r) => resolveDone = r);
218400
218481
  const pendingWebchat = webchat ? Object.assign(webchat, {
@@ -218427,7 +218508,7 @@ var Daemon = class Daemon {
218427
218508
  deferredFinalTranscript: false
218428
218509
  } } : {}
218429
218510
  };
218430
- this.pending.set(sessionId, p);
218511
+ this.pending.set(pendingTurnKey(agentId, sessionId), p);
218431
218512
  if (callMeta) this.activeTurnCallMeta.set(key, callMeta);
218432
218513
  let finalPhase = "end";
218433
218514
  try {
@@ -218546,12 +218627,12 @@ var Daemon = class Daemon {
218546
218627
  }
218547
218628
  throw err;
218548
218629
  } finally {
218549
- this.clearCancelBackstop(sessionId);
218630
+ this.clearCancelBackstop(agentId, sessionId);
218550
218631
  if (p.outputSuppressed) await p.applyChain.catch(() => {});
218551
218632
  releaseReplyConn();
218552
218633
  this.clearIdle(p);
218553
- this.releasePermissions(sessionId);
218554
- this.releaseElicits(sessionId);
218634
+ this.releasePermissions(agentId, sessionId);
218635
+ this.releaseElicits(agentId, sessionId);
218555
218636
  if (callMeta) this.activeTurnCallMeta.delete(key);
218556
218637
  const githubFinal = p.github && !p.outputSuppressed && finalPhase === "end" ? p.github.collector.finalText(true) : void 0;
218557
218638
  if (p.github?.deferredFinalTranscript && githubFinal?.trim()) this.store.appendTranscript({
@@ -218563,7 +218644,7 @@ var Daemon = class Daemon {
218563
218644
  text: githubFinal
218564
218645
  });
218565
218646
  if (p.github && !p.outputSuppressed) await p.github.poster.publish(githubFinal).catch((err) => this.log.warn(`github poster: final publish failed (${formatErr(err)})`));
218566
- this.pending.delete(sessionId);
218647
+ this.pending.delete(pendingTurnKey(agentId, sessionId));
218567
218648
  this.store.setSessionState(key, "idle", this.clock.now());
218568
218649
  this.emitSessionMetadataSnapshot({
218569
218650
  sessionId,
@@ -218601,9 +218682,8 @@ var Daemon = class Daemon {
218601
218682
  else e.reject(new FailStopError(key));
218602
218683
  }
218603
218684
  }
218604
- const livePair = acpSessionId ? [acpSessionId, this.pending.get(acpSessionId)] : [...this.pending.entries()].find(([, pending]) => pending.sessionKey === key);
218605
- const liveSessionId = livePair?.[0];
218606
- const live = livePair?.[1];
218685
+ const live = acpSessionId ? this.pending.get(pendingTurnKey(agentId, acpSessionId)) : [...this.pending.values()].find((pending) => pending.sessionKey === key);
218686
+ const liveSessionId = acpSessionId ?? live?.acpSessionId;
218607
218687
  if (live) {
218608
218688
  live.outputSuppressed ??= reason;
218609
218689
  this.clearIdle(live);
@@ -218626,8 +218706,8 @@ var Daemon = class Daemon {
218626
218706
  if (activeEntry && active) this.armColdCancelBackstop(agentId, key, reason, active);
218627
218707
  return;
218628
218708
  }
218629
- this.releasePermissions(liveSessionId);
218630
- this.releaseElicits(liveSessionId);
218709
+ this.releasePermissions(agentId, liveSessionId);
218710
+ this.releaseElicits(agentId, liveSessionId);
218631
218711
  this.store.setSessionState(key, "cancelling", this.clock.now());
218632
218712
  this.hosts.get(agentId)?.cancel(liveSessionId).catch((err) => this.log.error(`command ${reason}: cancel failed: ${err.message}`));
218633
218713
  this.armCancelBackstop(agentId, liveSessionId, key, reason);
@@ -218644,7 +218724,7 @@ var Daemon = class Daemon {
218644
218724
  entry.cancelledReason = reason;
218645
218725
  targets.set(key, void 0);
218646
218726
  }
218647
- for (const [acpSessionId, p] of this.pending) if (p.agentId === agentId) targets.set(p.sessionKey, acpSessionId);
218727
+ for (const p of this.pending.values()) if (p.agentId === agentId) targets.set(p.sessionKey, p.acpSessionId);
218648
218728
  for (const [key, queued] of this.serialQueue) if (queued.some((entry) => entry.agentId === agentId) && !targets.has(key)) targets.set(key, this.store.getSession(key)?.acpSessionId ?? void 0);
218649
218729
  if (targets.size > 0) this.log.info(`${reason}: interrupting ${targets.size} active session(s) for agent "${agentId}"`);
218650
218730
  for (const [key, acpSessionId] of targets) this.interruptTurn(agentId, key, reason, acpSessionId, { dropQueued: true });
@@ -218655,21 +218735,23 @@ var Daemon = class Daemon {
218655
218735
  * can't be stuck in `cancelling` forever. dispatch's finally clears this timer
218656
218736
  * the moment the turn yields on its own. */
218657
218737
  armCancelBackstop(agentId, acpSessionId, key, reason) {
218658
- this.clearCancelBackstop(acpSessionId);
218738
+ this.clearCancelBackstop(agentId, acpSessionId);
218659
218739
  const ms = this.cfg.limits.cancelBackstopMs;
218660
- this.cancelTimers.set(acpSessionId, this.clock.setTimeout(() => {
218661
- this.cancelTimers.delete(acpSessionId);
218662
- if (!this.pending.has(acpSessionId)) return;
218740
+ const pendingKey = pendingTurnKey(agentId, acpSessionId);
218741
+ this.cancelTimers.set(pendingKey, this.clock.setTimeout(() => {
218742
+ this.cancelTimers.delete(pendingKey);
218743
+ if (!this.pending.has(pendingKey)) return;
218663
218744
  this.log.warn(`${reason}: agent "${agentId}" ignored session/cancel for ${ms}ms — force-stopping host (session ${acpSessionId})`);
218664
218745
  this.stopHost(agentId, 0).catch((err) => this.log.error(`${reason}: force-stop failed for agent "${agentId}": ${formatErr(err)}`));
218665
218746
  this.store.setSessionState(key, "idle", this.clock.now());
218666
218747
  }, ms));
218667
218748
  }
218668
- clearCancelBackstop(acpSessionId) {
218669
- const t = this.cancelTimers.get(acpSessionId);
218749
+ clearCancelBackstop(agentId, acpSessionId) {
218750
+ const key = pendingTurnKey(agentId, acpSessionId);
218751
+ const t = this.cancelTimers.get(key);
218670
218752
  if (t !== void 0) {
218671
218753
  this.clock.clearTimeout(t);
218672
- this.cancelTimers.delete(acpSessionId);
218754
+ this.cancelTimers.delete(key);
218673
218755
  }
218674
218756
  }
218675
218757
  armColdCancelBackstop(agentId, key, reason, active) {
@@ -218998,7 +219080,7 @@ var Daemon = class Daemon {
218998
219080
  if (row?.threadUrl !== void 0) event.threadUrl = row.threadUrl;
218999
219081
  const agent = this.agents.get(input.agentId);
219000
219082
  if (agent?.runtime) event.runtime = agent.runtime;
219001
- const storeKey = this.store.getSessionByAcpId(input.sessionId)?.key;
219083
+ const storeKey = this.store.getSessionByAcpIdForAgent(input.agentId, input.sessionId)?.key;
219002
219084
  const model = (storeKey ? this.store.getModelOverride(storeKey) : void 0) ?? agent?.runtimeOverrides?.model;
219003
219085
  if (model !== void 0) event.model = model;
219004
219086
  const effort = (storeKey ? this.store.getEffortOverride(storeKey) : void 0) ?? agent?.reasoningEffort;
@@ -219151,6 +219233,7 @@ var Daemon = class Daemon {
219151
219233
  if (p.idleTimer) clearTimeout(p.idleTimer);
219152
219234
  p.idleTimer = void 0;
219153
219235
  }
219236
+ /** In-flight rendering state keyed by (agentId, ACP sessionId). */
219154
219237
  pending = /* @__PURE__ */ new Map();
219155
219238
  /**
219156
219239
  * DAEMON-PRIVATE trusted call metadata of the CURRENTLY in-flight turn, keyed by the
@@ -219173,7 +219256,7 @@ var Daemon = class Daemon {
219173
219256
  * promise stays pending until the user taps a button (handlePermissionChoice) or the
219174
219257
  * turn is cancelled/ends (releasePermissions).
219175
219258
  */
219176
- async onAcpPermission(_agentId, sessionId, params) {
219259
+ async onAcpPermission(agentId, sessionId, params) {
219177
219260
  if (isBuiltinSystemTool(params)) {
219178
219261
  const allow = params.options.find((o) => o.kind === "allow_always" || o.kind === "allow_once");
219179
219262
  if (allow) return { outcome: {
@@ -219181,7 +219264,7 @@ var Daemon = class Daemon {
219181
219264
  optionId: allow.optionId
219182
219265
  } };
219183
219266
  }
219184
- const p = this.pending.get(sessionId);
219267
+ const p = this.pending.get(pendingTurnKey(agentId, sessionId));
219185
219268
  if (!p) return void 0;
219186
219269
  if (p.outputSuppressed) return { outcome: { outcome: "cancelled" } };
219187
219270
  const conn = p.conn;
@@ -219192,6 +219275,7 @@ var Daemon = class Daemon {
219192
219275
  let resolveResult;
219193
219276
  const result = new Promise((resolve) => resolveResult = resolve);
219194
219277
  this.pendingPerms.set(requestId, {
219278
+ agentId,
219195
219279
  sessionId,
219196
219280
  params,
219197
219281
  conn,
@@ -219230,9 +219314,9 @@ var Daemon = class Daemon {
219230
219314
  /** Resolve every outstanding permission request for a session as `cancelled` — ACP
219231
219315
  * requires this when a prompt turn is cancelled, and it also unblocks a turn whose
219232
219316
  * card the user abandoned. Edits each card to a neutral cancelled state. */
219233
- releasePermissions(sessionId) {
219317
+ releasePermissions(agentId, sessionId) {
219234
219318
  for (const [id, rec] of this.pendingPerms) {
219235
- if (rec.sessionId !== sessionId) continue;
219319
+ if (rec.agentId !== agentId || rec.sessionId !== sessionId) continue;
219236
219320
  this.pendingPerms.delete(id);
219237
219321
  if (rec.ts) rec.conn.updateBlocks(rec.channel, rec.ts, buildPermissionResolvedCard(rec.params, "Cancelled", void 0), "Permission cancelled").catch(() => {});
219238
219322
  rec.resolve({ outcome: { outcome: "cancelled" } });
@@ -219247,8 +219331,8 @@ var Daemon = class Daemon {
219247
219331
  * Slack, or the form has no field we can render inline. Stays pending until the user
219248
219332
  * taps a button (handleElicitChoice) or the turn ends/cancels (releaseElicits).
219249
219333
  */
219250
- async onAcpElicit(_agentId, sessionId, params) {
219251
- const p = this.pending.get(sessionId);
219334
+ async onAcpElicit(agentId, sessionId, params) {
219335
+ const p = this.pending.get(pendingTurnKey(agentId, sessionId));
219252
219336
  if (!p) return void 0;
219253
219337
  if (p.outputSuppressed) return { action: "cancel" };
219254
219338
  const conn = p.conn;
@@ -219262,6 +219346,7 @@ var Daemon = class Daemon {
219262
219346
  let resolveResult;
219263
219347
  const result = new Promise((resolve) => resolveResult = resolve);
219264
219348
  this.pendingElicits.set(requestId, {
219349
+ agentId,
219265
219350
  sessionId,
219266
219351
  params,
219267
219352
  propName: target.propName,
@@ -219309,9 +219394,9 @@ var Daemon = class Daemon {
219309
219394
  }
219310
219395
  /** Resolve every outstanding elicitation for a session as `cancel` — ACP's cancellation
219311
219396
  * contract, and it unblocks a turn whose card the user abandoned. */
219312
- releaseElicits(sessionId) {
219397
+ releaseElicits(agentId, sessionId) {
219313
219398
  for (const [id, rec] of this.pendingElicits) {
219314
- if (rec.sessionId !== sessionId) continue;
219399
+ if (rec.agentId !== agentId || rec.sessionId !== sessionId) continue;
219315
219400
  this.pendingElicits.delete(id);
219316
219401
  if (rec.ts) rec.conn.updateBlocks(rec.channel, rec.ts, buildElicitationResolvedCard(rec.params, ":hourglass: Cancelled"), "Cancelled").catch(() => {});
219317
219402
  rec.resolve({ action: "cancel" });
@@ -219335,11 +219420,105 @@ var Daemon = class Daemon {
219335
219420
  this.log.debug(`${late ? "late " : ""}usage report emit failed (session ${sessionId}): ${err.message}`);
219336
219421
  }
219337
219422
  }
219338
- onAcpUpdate(_agentId, sessionId, update) {
219339
- const p = this.pending.get(sessionId);
219423
+ bufferEarlySessionMetadata(agentId, sessionId, update) {
219424
+ if ((this.sessionInitializationsByAgent.get(agentId) ?? 0) === 0) return false;
219425
+ const key = pendingTurnKey(agentId, sessionId);
219426
+ const entry = this.earlySessionMetadata.get(key) ?? {
219427
+ agentId,
219428
+ sessionId,
219429
+ updates: []
219430
+ };
219431
+ const previous = entry.updates.findIndex((candidate) => candidate.sessionUpdate === update.sessionUpdate);
219432
+ if (previous >= 0) entry.updates[previous] = update;
219433
+ else entry.updates.push(update);
219434
+ this.earlySessionMetadata.set(key, entry);
219435
+ return true;
219436
+ }
219437
+ /** Complete one SessionManager initialization and replay any metadata the ACP
219438
+ * adapter emitted before its local session row existed. Leftover unknown ids
219439
+ * are discarded once the agent has no other initialization in flight. */
219440
+ finishSessionInitialization(agentId, sessionId) {
219441
+ if (sessionId) {
219442
+ const key = pendingTurnKey(agentId, sessionId);
219443
+ const entry = this.earlySessionMetadata.get(key);
219444
+ this.earlySessionMetadata.delete(key);
219445
+ if (entry) for (const update of entry.updates) this.onAcpUpdate(agentId, sessionId, update);
219446
+ }
219447
+ const remaining = Math.max(0, (this.sessionInitializationsByAgent.get(agentId) ?? 1) - 1);
219448
+ if (remaining > 0) {
219449
+ this.sessionInitializationsByAgent.set(agentId, remaining);
219450
+ return;
219451
+ }
219452
+ this.sessionInitializationsByAgent.delete(agentId);
219453
+ for (const [key, entry] of this.earlySessionMetadata) if (entry.agentId === agentId) this.earlySessionMetadata.delete(key);
219454
+ }
219455
+ /** Persist one authoritative title and push the CP metadata projection. */
219456
+ persistSessionTitle(rec, title) {
219457
+ this.store.setSessionTitle(rec.key, title);
219458
+ if (!rec.acpSessionId) return;
219459
+ this.emitSessionMetadataSnapshot({
219460
+ sessionId: rec.acpSessionId,
219461
+ agentId: rec.agentId,
219462
+ phase: "plan",
219463
+ platform: rec.platform,
219464
+ channel: rec.channel,
219465
+ thread: rec.thread
219466
+ });
219467
+ }
219468
+ /** Rename a Slack app-DM through the exact integration that delivered this
219469
+ * session. The connection lease prevents reconcile from closing it mid-call. */
219470
+ async setSlackTitleForBinding(rec, binding, title) {
219471
+ if (binding.agentId !== rec.agentId || binding.platform !== "slack" || rec.platform !== "slack" || !binding.isDm || !binding.integrationId || !title) return;
219472
+ const conn = this.connByIntegration.get(binding.integrationId);
219473
+ if (!conn) return;
219474
+ const release = this.holdReplyConnection(conn);
219475
+ try {
219476
+ await conn.setTitle(rec.channel, rec.thread, title);
219477
+ } catch (err) {
219478
+ this.log.debug(`session title: Slack update failed (${formatErr(err)})`);
219479
+ } finally {
219480
+ release();
219481
+ }
219482
+ }
219483
+ /** MCP callback for runtimes (notably Codex ACP) that do not generate semantic
219484
+ * ACP session titles themselves. The tool input contains only the title; every
219485
+ * coordinate and delivery route was captured in the trusted SessionContext. */
219486
+ async setSessionTitleFromTool(req) {
219487
+ const key = sessionKey(req.platform, req.channel, req.thread, req.agentId);
219488
+ const rec = this.store.getSession(key);
219489
+ if (!rec?.acpSessionId) throw new Error("the current session is not addressable yet");
219490
+ const binding = this.sessionDeliveryBindings.get(key) ?? {
219491
+ agentId: req.agentId,
219492
+ platform: req.platform,
219493
+ ...req.integrationId !== void 0 ? { integrationId: req.integrationId } : {},
219494
+ isDm: req.isDm
219495
+ };
219496
+ this.persistSessionTitle(rec, req.title);
219497
+ const p = this.pending.get(pendingTurnKey(rec.agentId, rec.acpSessionId));
219498
+ if (p && p.sessionKey === key && !p.outputSuppressed) {
219499
+ if (p.webchat) this.emitWebchatUpdate(p, {
219500
+ sessionUpdate: "session_info_update",
219501
+ title: req.title
219502
+ });
219503
+ if (p.platform === "slack" && p.isDm && p.conn) {
219504
+ this.enqueueApply(p, {
219505
+ kind: "set-title",
219506
+ text: req.title
219507
+ });
219508
+ await p.applyChain;
219509
+ return;
219510
+ }
219511
+ }
219512
+ await this.setSlackTitleForBinding(rec, binding, req.title);
219513
+ }
219514
+ onAcpUpdate(agentId, sessionId, update) {
219515
+ const p = this.pending.get(pendingTurnKey(agentId, sessionId));
219340
219516
  if (p?.outputSuppressed) return;
219517
+ const isEarlyMetadata = update?.sessionUpdate === "usage_update" || update?.sessionUpdate === "session_info_update" && update.title !== void 0;
219518
+ const detachedRec = !p && isEarlyMetadata ? this.store.getSessionByAcpIdForAgent(agentId, sessionId) : void 0;
219519
+ if (!p && isEarlyMetadata && !detachedRec && this.bufferEarlySessionMetadata(agentId, sessionId, update)) return;
219341
219520
  if (update?.sessionUpdate === "usage_update") {
219342
- const rec = p ? void 0 : this.store.getSessionByAcpId(sessionId);
219521
+ const rec = p ? void 0 : detachedRec;
219343
219522
  const key = p?.sessionKey ?? rec?.key;
219344
219523
  if (key) {
219345
219524
  if (p && update.cost?.amount !== void 0) p.runtimeCostReported = true;
@@ -219355,23 +219534,22 @@ var Daemon = class Daemon {
219355
219534
  } else if (rec) this.emitStoredUsageReport(sessionId, rec.agentId, rec.platform, rec.channel, key, true);
219356
219535
  }
219357
219536
  }
219358
- if (!p) return;
219359
219537
  if (update?.sessionUpdate === "session_info_update" && update.title !== void 0) {
219360
- this.store.setSessionTitle(p.sessionKey, update.title);
219361
- this.emitSessionMetadataSnapshot({
219362
- sessionId,
219363
- agentId: p.agentId,
219364
- phase: "plan",
219365
- platform: p.platform,
219366
- channel: p.channel,
219367
- thread: p.statusThread
219368
- });
219369
- const slackTitle = typeof update.title === "string" ? update.title.trim() : "";
219370
- if (p.platform === "slack" && p.isDm && slackTitle) this.enqueueApply(p, {
219371
- kind: "set-title",
219372
- text: slackTitle
219373
- });
219538
+ const rec = p ? this.store.getSession(p.sessionKey) : detachedRec;
219539
+ if (rec?.agentId === agentId && rec.acpSessionId === sessionId) {
219540
+ this.persistSessionTitle(rec, update.title);
219541
+ const slackTitle = typeof update.title === "string" ? update.title.trim() : "";
219542
+ if (p?.platform === "slack" && p.isDm && slackTitle) this.enqueueApply(p, {
219543
+ kind: "set-title",
219544
+ text: slackTitle
219545
+ });
219546
+ else if (!p && slackTitle) {
219547
+ const binding = this.sessionDeliveryBindings.get(rec.key);
219548
+ if (binding) this.setSlackTitleForBinding(rec, binding, slackTitle);
219549
+ }
219550
+ }
219374
219551
  }
219552
+ if (!p) return;
219375
219553
  const isHeadlessGithubFinal = p.github !== void 0 && p.platform === "hook" && update?.sessionUpdate === "agent_message_chunk" && update?._meta?.codex?.phase === "final_answer";
219376
219554
  if (p.github) {
219377
219555
  p.github.collector.onUpdate(update);
@@ -219591,12 +219769,22 @@ var Daemon = class Daemon {
219591
219769
  const host = this.hosts.get(agentId);
219592
219770
  this.hosts.delete(agentId);
219593
219771
  this.hostStartedAt.delete(agentId);
219594
- if (!host) return;
219772
+ const clearDeliveryBindings = () => {
219773
+ for (const [key, binding] of this.sessionDeliveryBindings) if (binding.agentId === agentId) this.sessionDeliveryBindings.delete(key);
219774
+ };
219775
+ if (!host) {
219776
+ clearDeliveryBindings();
219777
+ return;
219778
+ }
219595
219779
  const stop = Promise.resolve(host.stop(deadlineMs)).finally(() => {
219596
219780
  if (this.hostStopping.get(agentId) === stop) this.hostStopping.delete(agentId);
219597
219781
  });
219598
219782
  this.hostStopping.set(agentId, stop);
219599
- await stop;
219783
+ try {
219784
+ await stop;
219785
+ } finally {
219786
+ clearDeliveryBindings();
219787
+ }
219600
219788
  }
219601
219789
  /** Recurring idle sweep (§7.2/§7.3): reap idle adapter children and TTL-close
219602
219790
  * idle sessions. Driven by the injected Clock so a FakeClock advances it in tests. */
@@ -219689,10 +219877,10 @@ var Daemon = class Daemon {
219689
219877
  })));
219690
219878
  const res = await this.raceDeadline(work, deadlineMs);
219691
219879
  settled = true;
219692
- if (res === "timeout") for (const [sid, p] of this.pending) {
219880
+ if (res === "timeout") for (const p of this.pending.values()) {
219693
219881
  if (!match(p)) continue;
219694
- this.log.warn(`drain[${scope.kind}]: cancelling straggler turn (session ${sid})`);
219695
- await this.hosts.get(p.agentId)?.cancel(sid).catch(() => {});
219882
+ this.log.warn(`drain[${scope.kind}]: cancelling straggler turn (session ${p.acpSessionId})`);
219883
+ await this.hosts.get(p.agentId)?.cancel(p.acpSessionId).catch(() => {});
219696
219884
  }
219697
219885
  return {
219698
219886
  matched: [...matched.values()],
@@ -219801,11 +219989,11 @@ var Daemon = class Daemon {
219801
219989
  entry.initAbort.abort(/* @__PURE__ */ new Error("daemon shutdown deadline"));
219802
219990
  forceAgents.add(entry.agentId);
219803
219991
  }
219804
- for (const [sid, p] of this.pending) {
219992
+ for (const p of this.pending.values()) {
219805
219993
  p.outputSuppressed ??= "shutdown";
219806
- this.releasePermissions(sid);
219807
- this.releaseElicits(sid);
219808
- this.hosts.get(p.agentId)?.cancel(sid).catch(() => {});
219994
+ this.releasePermissions(p.agentId, p.acpSessionId);
219995
+ this.releaseElicits(p.agentId, p.acpSessionId);
219996
+ this.hosts.get(p.agentId)?.cancel(p.acpSessionId).catch(() => {});
219809
219997
  }
219810
219998
  const forceStops = [...forceAgents].filter((id) => !coldAgents.has(id)).map(stopFailClosed);
219811
219999
  await Promise.all([
@@ -220485,4 +220673,4 @@ async function runForeground(opts, deps = {}) {
220485
220673
  //#endregion
220486
220674
  export { ClientTransport as i, CP_SUBPROTOCOL as n, CP_WS_PATH as r, runForeground as t };
220487
220675
 
220488
- //# sourceMappingURL=run-foreground-B4hOtHPl.js.map
220676
+ //# sourceMappingURL=run-foreground-BRT8VM8Q.js.map