@agentconnect.md/daemon 1.0.0-rc.215 → 1.0.0-rc.217

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.
@@ -3,11 +3,16 @@ import { n as require_ms, t as require_src$2 } from "./src-DDtlVutj.js";
3
3
  import { t as DAEMON_VERSION } from "./version-DGaRXjBK.js";
4
4
  import { a as agentChildEnv, i as selectAgent, n as findAgentFiles, o as loadConfig, r as loadAgents, s as persistDaemonId } from "./load-agents-nWFFmN5-.js";
5
5
  import { l as resolveRoot, o as mcpSocketPath, u as statePath } from "./paths-DEcUO8lC.js";
6
- import { _ as resolveRuntimes, a as initGitInjection, c as simpleGit, d as MAX_FRAME_BYTES, f as buildEnvelope, g as cachedRuntimeVersions, h as cachedRuntimeNames, i as prepareWorkspace, m as encode, n as installedRuntimes, o as probeGitVersion, p as decodeEnvelope, r as prefetchWorkspace, s as sessionGitEnv, t as AcpHost, u as normalizeGitUrl } from "./acp-host-C1MZcqZo.js";
6
+ import { _ as resolveRuntimes, a as initGitInjection, c as simpleGit, d as MAX_FRAME_BYTES, f as buildEnvelope, g as cachedRuntimeVersions, h as cachedRuntimeNames, i as prepareWorkspace, m as encode, n as installedRuntimes, o as probeGitVersion, p as decodeEnvelope, r as prefetchWorkspace, s as sessionGitEnv, t as AcpHost, u as normalizeGitUrl } from "./acp-host-CeJJZbtg.js";
7
7
  import { i as GitCredentialCache, n as gitcredSocketPath, r as writeGitcredShim, t as GitCredServer } from "./gitcred-server-Dcsq6QJe.js";
8
8
  import { n as encodeFrame, t as decodeFrames } from "./ipc-2Xbxe7uu.js";
9
+ import { URL as URL$1 } from "url";
10
+ import * as tls from "tls";
11
+ import * as net$2 from "net";
9
12
  import * as sp from "node:path";
10
13
  import { dirname, join, relative, resolve, sep } from "node:path";
14
+ import * as http$6 from "http";
15
+ import { Agent } from "https";
11
16
  import { chmodSync, existsSync, mkdirSync, mkdtempSync, promises, readFileSync, rmSync, stat, unwatchFile, watch, watchFile, writeFileSync } from "node:fs";
12
17
  import { EventEmitter } from "node:events";
13
18
  import { hostname, tmpdir, type } from "node:os";
@@ -16,6 +21,7 @@ import { Readable } from "node:stream";
16
21
  import net from "node:net";
17
22
  import { lstat, open, readdir, realpath, stat as stat$1 } from "node:fs/promises";
18
23
  import { DatabaseSync } from "node:sqlite";
24
+ import assert from "assert";
19
25
  //#region ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/constants.js
20
26
  var require_constants$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21
27
  const BINARY_TYPES = [
@@ -2059,12 +2065,12 @@ var require_extension = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2059
2065
  var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2060
2066
  const EventEmitter$3 = __require("events");
2061
2067
  const https$3 = __require("https");
2062
- const http$7 = __require("http");
2063
- const net$2 = __require("net");
2064
- const tls = __require("tls");
2068
+ const http$8 = __require("http");
2069
+ const net$3 = __require("net");
2070
+ const tls$1 = __require("tls");
2065
2071
  const { randomBytes: randomBytes$1, createHash: createHash$1 } = __require("crypto");
2066
2072
  const { Duplex: Duplex$2, Readable: Readable$1 } = __require("stream");
2067
- const { URL: URL$1 } = __require("url");
2073
+ const { URL: URL$2 } = __require("url");
2068
2074
  const PerMessageDeflate = require_permessage_deflate();
2069
2075
  const Receiver = require_receiver$1();
2070
2076
  const Sender = require_sender();
@@ -2605,9 +2611,9 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2605
2611
  websocket._closeTimeout = opts.closeTimeout;
2606
2612
  if (!protocolVersions.includes(opts.protocolVersion)) throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`);
2607
2613
  let parsedUrl;
2608
- if (address instanceof URL$1) parsedUrl = address;
2614
+ if (address instanceof URL$2) parsedUrl = address;
2609
2615
  else try {
2610
- parsedUrl = new URL$1(address);
2616
+ parsedUrl = new URL$2(address);
2611
2617
  } catch {
2612
2618
  throw new SyntaxError(`Invalid URL: ${address}`);
2613
2619
  }
@@ -2630,7 +2636,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2630
2636
  }
2631
2637
  const defaultPort = isSecure ? 443 : 80;
2632
2638
  const key = randomBytes$1(16).toString("base64");
2633
- const request = isSecure ? https$3.request : http$7.request;
2639
+ const request = isSecure ? https$3.request : http$8.request;
2634
2640
  const protocolSet = /* @__PURE__ */ new Set();
2635
2641
  let perMessageDeflate;
2636
2642
  opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
@@ -2713,7 +2719,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2713
2719
  req.abort();
2714
2720
  let addr;
2715
2721
  try {
2716
- addr = new URL$1(location, address);
2722
+ addr = new URL$2(location, address);
2717
2723
  } catch (e) {
2718
2724
  emitErrorAndClose(websocket, /* @__PURE__ */ new SyntaxError(`Invalid URL: ${location}`));
2719
2725
  return;
@@ -2806,7 +2812,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2806
2812
  */
2807
2813
  function netConnect(options) {
2808
2814
  options.path = options.socketPath;
2809
- return net$2.connect(options);
2815
+ return net$3.connect(options);
2810
2816
  }
2811
2817
  /**
2812
2818
  * Create a `tls.TLSSocket` and initiate a connection.
@@ -2817,8 +2823,8 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2817
2823
  */
2818
2824
  function tlsConnect(options) {
2819
2825
  options.path = void 0;
2820
- if (!options.servername && options.servername !== "") options.servername = net$2.isIP(options.host) ? "" : options.host;
2821
- return tls.connect(options);
2826
+ if (!options.servername && options.servername !== "") options.servername = net$3.isIP(options.host) ? "" : options.host;
2827
+ return tls$1.connect(options);
2822
2828
  }
2823
2829
  /**
2824
2830
  * Abort the handshake and emit an error.
@@ -3202,7 +3208,7 @@ var require_subprotocol = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3202
3208
  //#region ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/lib/websocket-server.js
3203
3209
  var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3204
3210
  const EventEmitter$2 = __require("events");
3205
- const http$6 = __require("http");
3211
+ const http$7 = __require("http");
3206
3212
  const { Duplex } = __require("stream");
3207
3213
  const { createHash } = __require("crypto");
3208
3214
  const extension = require_extension();
@@ -3283,8 +3289,8 @@ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module)
3283
3289
  };
3284
3290
  if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) throw new TypeError("One and only one of the \"port\", \"server\", or \"noServer\" options must be specified");
3285
3291
  if (options.port != null) {
3286
- this._server = http$6.createServer((req, res) => {
3287
- const body = http$6.STATUS_CODES[426];
3292
+ this._server = http$7.createServer((req, res) => {
3293
+ const body = http$7.STATUS_CODES[426];
3288
3294
  res.writeHead(426, {
3289
3295
  "Content-Length": body.length,
3290
3296
  "Content-Type": "text/plain"
@@ -3554,7 +3560,7 @@ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module)
3554
3560
  * @private
3555
3561
  */
3556
3562
  function abortHandshake(socket, code, message, headers) {
3557
- message = message || http$6.STATUS_CODES[code];
3563
+ message = message || http$7.STATUS_CODES[code];
3558
3564
  headers = {
3559
3565
  Connection: "close",
3560
3566
  "Content-Type": "text/html",
@@ -3562,7 +3568,7 @@ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module)
3562
3568
  ...headers
3563
3569
  };
3564
3570
  socket.once("finish", socket.destroy);
3565
- socket.end(`HTTP/1.1 ${code} ${http$6.STATUS_CODES[code]}\r\n` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message);
3571
+ socket.end(`HTTP/1.1 ${code} ${http$7.STATUS_CODES[code]}\r\n` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message);
3566
3572
  }
3567
3573
  /**
3568
3574
  * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least
@@ -3584,6 +3590,9 @@ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module)
3584
3590
  } else abortHandshake(socket, code, message, headers);
3585
3591
  }
3586
3592
  }));
3593
+ //#endregion
3594
+ //#region ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/wrapper.mjs
3595
+ var import_src = /* @__PURE__ */ __toESM(require_src$2(), 1);
3587
3596
  require_stream();
3588
3597
  require_extension();
3589
3598
  require_permessage_deflate();
@@ -5280,20 +5289,23 @@ function watch$1(paths, options = {}) {
5280
5289
  /**
5281
5290
  * Runtime config surfaced to the ACP child as environment variables, under
5282
5291
  * `AGENTCONNECT_*` for runtimes that read them. ACP `session/new`/`initialize`
5283
- * carry no model / effort / system-prompt field (SDK v1); model + reasoning
5284
- * effort are additionally applied per session via ACP session config options
5292
+ * carry no model / effort field (SDK v1); model + reasoning effort are
5293
+ * additionally applied per session via ACP session config options
5285
5294
  * (`session/set_config_option`) when the runtime advertises the selectors —
5286
5295
  * see AcpHost.applySessionConfig — which is how claude-acp actually honors
5287
- * them. The env remains the only channel for the system prompt and for
5288
- * runtimes without config options. (`runtimeOverrides.env` is applied
5289
- * separately by `agentChildEnv`.) Only emits a key when the value is set.
5296
+ * them. The env stays the fallback for runtimes without config options.
5297
+ *
5298
+ * The system prompt is NOT here: it rides `_meta.systemPrompt` on
5299
+ * session/new|load for Claude runtimes (see claudeSessionMeta), and for other
5300
+ * runtimes it's inlined as the first prompt text block (see AcpHost.inlineSystemPrompt
5301
+ * + SessionManager). (`runtimeOverrides.env` is applied separately by
5302
+ * `agentChildEnv`.) Only emits a key when the value is set.
5290
5303
  */
5291
5304
  function cpRuntimeEnv(agent) {
5292
5305
  const out = {};
5293
5306
  if (agent.runtimeOverrides?.model) out.AGENTCONNECT_MODEL = agent.runtimeOverrides.model;
5294
5307
  if (agent.reasoningEffort) out.AGENTCONNECT_REASONING_EFFORT = agent.reasoningEffort;
5295
5308
  if (agent.executionMode) out.AGENTCONNECT_EXECUTION_MODE = agent.executionMode;
5296
- if (agent.description) out.AGENTCONNECT_SYSTEM_PROMPT = agent.description;
5297
5309
  return out;
5298
5310
  }
5299
5311
  //#endregion
@@ -5925,6 +5937,13 @@ var SessionManager = class {
5925
5937
  });
5926
5938
  blocks.push(...attBlocks);
5927
5939
  }
5940
+ if (created) {
5941
+ const inlineSystemPrompt = host.inlineSystemPrompt?.();
5942
+ if (inlineSystemPrompt) blocks.unshift({
5943
+ type: "text",
5944
+ text: inlineSystemPrompt
5945
+ });
5946
+ }
5928
5947
  rec.lastDeliveredTs = ts;
5929
5948
  rec.state = "prompting";
5930
5949
  rec.updatedAt = Date.now();
@@ -6597,6 +6616,342 @@ var CpRoutingLayer = class {
6597
6616
  }
6598
6617
  };
6599
6618
  //#endregion
6619
+ //#region ../../node_modules/.pnpm/agent-base@9.0.0/node_modules/agent-base/dist/index.js
6620
+ const INTERNAL = Symbol("AgentBaseInternalState");
6621
+ var Agent$1 = class extends http$6.Agent {
6622
+ constructor(opts) {
6623
+ super(opts);
6624
+ this[INTERNAL] = {};
6625
+ }
6626
+ /**
6627
+ * Determine whether this is an `http` or `https` request.
6628
+ */
6629
+ isSecureEndpoint(options) {
6630
+ if (options) {
6631
+ if (typeof options.secureEndpoint === "boolean") return options.secureEndpoint;
6632
+ if (typeof options.protocol === "string") return options.protocol === "https:";
6633
+ }
6634
+ const { stack } = /* @__PURE__ */ new Error();
6635
+ if (typeof stack !== "string") return false;
6636
+ return stack.split("\n").some((l) => l.indexOf("(https.js:") !== -1 || l.indexOf("node:https:") !== -1);
6637
+ }
6638
+ incrementSockets(name) {
6639
+ if (this.maxSockets === Infinity && this.maxTotalSockets === Infinity) return null;
6640
+ if (!this.sockets[name]) this.sockets[name] = [];
6641
+ const fakeSocket = new net$2.Socket({ writable: false });
6642
+ this.sockets[name].push(fakeSocket);
6643
+ this.totalSocketCount++;
6644
+ return fakeSocket;
6645
+ }
6646
+ decrementSockets(name, socket) {
6647
+ if (!this.sockets[name] || socket === null) return;
6648
+ const sockets = this.sockets[name];
6649
+ const index = sockets.indexOf(socket);
6650
+ if (index !== -1) {
6651
+ sockets.splice(index, 1);
6652
+ this.totalSocketCount--;
6653
+ if (sockets.length === 0) delete this.sockets[name];
6654
+ }
6655
+ }
6656
+ getName(options) {
6657
+ if (this.isSecureEndpoint(options)) return Agent.prototype.getName.call(this, options);
6658
+ return super.getName(options);
6659
+ }
6660
+ createSocket(req, options, cb) {
6661
+ const connectOpts = {
6662
+ ...options,
6663
+ secureEndpoint: this.isSecureEndpoint(options)
6664
+ };
6665
+ const name = this.getName(connectOpts);
6666
+ const fakeSocket = this.incrementSockets(name);
6667
+ Promise.resolve().then(() => this.connect(req, connectOpts)).then((socket) => {
6668
+ this.decrementSockets(name, fakeSocket);
6669
+ if (typeof socket.addRequest === "function") try {
6670
+ return socket.addRequest(req, connectOpts);
6671
+ } catch (err) {
6672
+ return cb(err);
6673
+ }
6674
+ this[INTERNAL].currentSocket = socket;
6675
+ super.createSocket(req, options, cb);
6676
+ }, (err) => {
6677
+ this.decrementSockets(name, fakeSocket);
6678
+ cb(err);
6679
+ });
6680
+ }
6681
+ createConnection() {
6682
+ const socket = this[INTERNAL].currentSocket;
6683
+ this[INTERNAL].currentSocket = void 0;
6684
+ if (!socket) throw new Error("No socket was returned in the `connect()` function");
6685
+ return socket;
6686
+ }
6687
+ get defaultPort() {
6688
+ return this[INTERNAL].defaultPort ?? (this.protocol === "https:" ? 443 : 80);
6689
+ }
6690
+ set defaultPort(v) {
6691
+ if (this[INTERNAL]) this[INTERNAL].defaultPort = v;
6692
+ }
6693
+ get protocol() {
6694
+ return this[INTERNAL].protocol ?? (this.isSecureEndpoint() ? "https:" : "http:");
6695
+ }
6696
+ set protocol(v) {
6697
+ if (this[INTERNAL]) this[INTERNAL].protocol = v;
6698
+ }
6699
+ };
6700
+ //#endregion
6701
+ //#region ../../node_modules/.pnpm/https-proxy-agent@9.1.0/node_modules/https-proxy-agent/dist/parse-proxy-response.js
6702
+ const debug$1 = (0, import_src.default)("https-proxy-agent:parse-proxy-response");
6703
+ function parseProxyResponse(socket) {
6704
+ return new Promise((resolve, reject) => {
6705
+ let buffersLength = 0;
6706
+ const buffers = [];
6707
+ function read() {
6708
+ const b = socket.read();
6709
+ if (b) ondata(b);
6710
+ else socket.once("readable", read);
6711
+ }
6712
+ function cleanup() {
6713
+ socket.removeListener("end", onend);
6714
+ socket.removeListener("error", onerror);
6715
+ socket.removeListener("readable", read);
6716
+ }
6717
+ function onend() {
6718
+ cleanup();
6719
+ debug$1("onend");
6720
+ reject(/* @__PURE__ */ new Error("Proxy connection ended before receiving CONNECT response"));
6721
+ }
6722
+ function onerror(err) {
6723
+ cleanup();
6724
+ debug$1("onerror %o", err);
6725
+ reject(err);
6726
+ }
6727
+ function ondata(b) {
6728
+ buffers.push(b);
6729
+ buffersLength += b.length;
6730
+ const buffered = Buffer.concat(buffers, buffersLength);
6731
+ const endOfHeaders = buffered.indexOf("\r\n\r\n");
6732
+ if (endOfHeaders === -1) {
6733
+ debug$1("have not received end of HTTP headers yet...");
6734
+ read();
6735
+ return;
6736
+ }
6737
+ const headerParts = buffered.slice(0, endOfHeaders).toString("ascii").split("\r\n");
6738
+ const firstLine = headerParts.shift();
6739
+ if (!firstLine) {
6740
+ socket.destroy();
6741
+ return reject(/* @__PURE__ */ new Error("No header received from proxy CONNECT response"));
6742
+ }
6743
+ const firstLineParts = firstLine.split(" ");
6744
+ const statusCode = +firstLineParts[1];
6745
+ const statusText = firstLineParts.slice(2).join(" ");
6746
+ const headers = {};
6747
+ for (const header of headerParts) {
6748
+ if (!header) continue;
6749
+ const firstColon = header.indexOf(":");
6750
+ if (firstColon === -1) {
6751
+ socket.destroy();
6752
+ return reject(/* @__PURE__ */ new Error(`Invalid header from proxy CONNECT response: "${header}"`));
6753
+ }
6754
+ const key = header.slice(0, firstColon).toLowerCase();
6755
+ const value = header.slice(firstColon + 1).trimStart();
6756
+ const current = headers[key];
6757
+ if (typeof current === "string") headers[key] = [current, value];
6758
+ else if (Array.isArray(current)) current.push(value);
6759
+ else headers[key] = value;
6760
+ }
6761
+ debug$1("got proxy server response: %o %o", firstLine, headers);
6762
+ cleanup();
6763
+ resolve({
6764
+ connect: {
6765
+ statusCode,
6766
+ statusText,
6767
+ headers
6768
+ },
6769
+ buffered
6770
+ });
6771
+ }
6772
+ socket.on("error", onerror);
6773
+ socket.on("end", onend);
6774
+ read();
6775
+ });
6776
+ }
6777
+ //#endregion
6778
+ //#region ../../node_modules/.pnpm/proxy-agent-negotiate@1.1.0/node_modules/proxy-agent-negotiate/dist/index.js
6779
+ function createNegotiateAuth() {
6780
+ return async ({ response, scheme }) => {
6781
+ if (scheme.toLowerCase() !== "negotiate") throw new Error(`Expected Negotiate scheme but got "${scheme}"`);
6782
+ let kerberos;
6783
+ try {
6784
+ kerberos = await import("kerberos");
6785
+ } catch {
6786
+ throw new Error("The \"kerberos\" package is required for Negotiate proxy authentication. Install it with: npm install kerberos");
6787
+ }
6788
+ const proxyAuthenticate = response.headers["proxy-authenticate"] || "";
6789
+ const challengeHeader = Array.isArray(proxyAuthenticate) ? proxyAuthenticate[0] : proxyAuthenticate;
6790
+ const serverToken = typeof challengeHeader === "string" && challengeHeader.includes(" ") ? challengeHeader.split(" ").slice(1).join(" ") : void 0;
6791
+ const token = await (await kerberos.initializeClient("HTTP@proxy", { mechOID: kerberos.GSS_MECH_OID_SPNEGO })).step(serverToken || "");
6792
+ if (!token) throw new Error("Kerberos client.step() returned no token");
6793
+ return { headers: { "Proxy-Authorization": `Negotiate ${token}` } };
6794
+ };
6795
+ }
6796
+ //#endregion
6797
+ //#region ../../node_modules/.pnpm/https-proxy-agent@9.1.0/node_modules/https-proxy-agent/dist/index.js
6798
+ const debug = (0, import_src.default)("https-proxy-agent");
6799
+ const setServernameFromNonIpHost = (options) => {
6800
+ if (options.servername === void 0 && options.host && !net$2.isIP(options.host)) return {
6801
+ ...options,
6802
+ servername: options.host
6803
+ };
6804
+ return options;
6805
+ };
6806
+ /**
6807
+ * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to
6808
+ * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests.
6809
+ *
6810
+ * Outgoing HTTP requests are first tunneled through the proxy server using the
6811
+ * `CONNECT` HTTP request method to establish a connection to the proxy server,
6812
+ * and then the proxy server connects to the destination target and issues the
6813
+ * HTTP request from the proxy server.
6814
+ *
6815
+ * `https:` requests have their socket connection upgraded to TLS once
6816
+ * the connection to the proxy server has been established.
6817
+ */
6818
+ var HttpsProxyAgent = class extends Agent$1 {
6819
+ constructor(proxy, opts) {
6820
+ super(opts);
6821
+ this.options = { path: void 0 };
6822
+ this.proxy = typeof proxy === "string" ? new URL$1(proxy) : proxy;
6823
+ this.proxyHeaders = opts?.headers ?? {};
6824
+ debug("Creating new HttpsProxyAgent instance: %o", this.proxy.href);
6825
+ if (opts?.negotiate) this.onProxyAuth = createNegotiateAuth();
6826
+ else if (opts?.onProxyAuth) this.onProxyAuth = opts.onProxyAuth;
6827
+ const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, "");
6828
+ const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.proxy.protocol === "https:" ? 443 : 80;
6829
+ this.connectOpts = {
6830
+ ALPNProtocols: ["http/1.1"],
6831
+ ...opts ? omit(opts, "headers", "onProxyAuth", "negotiate") : null,
6832
+ host,
6833
+ port
6834
+ };
6835
+ }
6836
+ /**
6837
+ * Called when the node-core HTTP client library is creating a
6838
+ * new HTTP request.
6839
+ */
6840
+ async connect(req, opts) {
6841
+ const { proxy } = this;
6842
+ if (!opts.host) throw new TypeError("No \"host\" provided");
6843
+ let socket;
6844
+ if (proxy.protocol === "https:") {
6845
+ debug("Creating `tls.Socket`: %o", this.connectOpts);
6846
+ socket = tls.connect(setServernameFromNonIpHost(this.connectOpts));
6847
+ } else {
6848
+ debug("Creating `net.Socket`: %o", this.connectOpts);
6849
+ socket = net$2.connect(this.connectOpts);
6850
+ }
6851
+ const headers = typeof this.proxyHeaders === "function" ? this.proxyHeaders() : { ...this.proxyHeaders };
6852
+ const host = net$2.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;
6853
+ let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r\n`;
6854
+ if (proxy.username || proxy.password) {
6855
+ const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`;
6856
+ headers["Proxy-Authorization"] = `Basic ${Buffer.from(auth).toString("base64")}`;
6857
+ }
6858
+ headers.Host = `${host}:${opts.port}`;
6859
+ if (!headers["Proxy-Connection"]) headers["Proxy-Connection"] = this.keepAlive ? "Keep-Alive" : "close";
6860
+ for (const name of Object.keys(headers)) payload += `${name}: ${headers[name]}\r\n`;
6861
+ const proxyResponsePromise = parseProxyResponse(socket);
6862
+ socket.write(`${payload}\r\n`);
6863
+ const { connect, buffered } = await proxyResponsePromise;
6864
+ req.emit("proxyConnect", connect);
6865
+ this.emit("proxyConnect", connect, req);
6866
+ req.emit("proxy", {
6867
+ proxy: this.proxy.href,
6868
+ socket
6869
+ });
6870
+ if (connect.statusCode === 200) {
6871
+ req.once("socket", resume);
6872
+ if (opts.secureEndpoint) {
6873
+ debug("Upgrading socket connection to TLS");
6874
+ return tls.connect({
6875
+ ...omit(setServernameFromNonIpHost(opts), "host", "path", "port"),
6876
+ socket
6877
+ });
6878
+ }
6879
+ return socket;
6880
+ }
6881
+ if (connect.statusCode === 407 && this.onProxyAuth) {
6882
+ debug("Got 407 response, invoking onProxyAuth callback");
6883
+ socket.destroy();
6884
+ const proxyAuthenticate = connect.headers["proxy-authenticate"] || "";
6885
+ const scheme = Array.isArray(proxyAuthenticate) ? proxyAuthenticate[0].split(/\s/)[0] : proxyAuthenticate.split(/\s/)[0];
6886
+ const authResponse = await this.onProxyAuth({
6887
+ response: connect,
6888
+ scheme
6889
+ });
6890
+ return this._connectWithAuth(req, opts, authResponse.headers);
6891
+ }
6892
+ socket.destroy();
6893
+ const fakeSocket = new net$2.Socket({ writable: false });
6894
+ fakeSocket.readable = true;
6895
+ req.once("socket", (s) => {
6896
+ debug("Replaying proxy buffer for failed request");
6897
+ assert(s.listenerCount("data") > 0);
6898
+ s.push(buffered);
6899
+ s.push(null);
6900
+ });
6901
+ return fakeSocket;
6902
+ }
6903
+ /**
6904
+ * Retry a CONNECT request with additional auth headers.
6905
+ */
6906
+ async _connectWithAuth(req, opts, authHeaders) {
6907
+ const { proxy } = this;
6908
+ let socket;
6909
+ if (proxy.protocol === "https:") socket = tls.connect(setServernameFromNonIpHost(this.connectOpts));
6910
+ else socket = net$2.connect(this.connectOpts);
6911
+ const headers = typeof this.proxyHeaders === "function" ? this.proxyHeaders() : { ...this.proxyHeaders };
6912
+ const host = net$2.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;
6913
+ let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r\n`;
6914
+ if (proxy.username || proxy.password) {
6915
+ const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`;
6916
+ headers["Proxy-Authorization"] = `Basic ${Buffer.from(auth).toString("base64")}`;
6917
+ }
6918
+ Object.assign(headers, authHeaders);
6919
+ headers.Host = `${host}:${opts.port}`;
6920
+ if (!headers["Proxy-Connection"]) headers["Proxy-Connection"] = this.keepAlive ? "Keep-Alive" : "close";
6921
+ for (const name of Object.keys(headers)) payload += `${name}: ${headers[name]}\r\n`;
6922
+ const proxyResponsePromise = parseProxyResponse(socket);
6923
+ socket.write(`${payload}\r\n`);
6924
+ const { connect } = await proxyResponsePromise;
6925
+ req.emit("proxyConnect", connect);
6926
+ this.emit("proxyConnect", connect, req);
6927
+ if (connect.statusCode === 200) {
6928
+ req.once("socket", resume);
6929
+ if (opts.secureEndpoint) {
6930
+ debug("Upgrading socket connection to TLS");
6931
+ return tls.connect({
6932
+ ...omit(setServernameFromNonIpHost(opts), "host", "path", "port"),
6933
+ socket
6934
+ });
6935
+ }
6936
+ return socket;
6937
+ }
6938
+ socket.destroy();
6939
+ throw new Error(`Proxy authentication failed with status ${connect.statusCode} after retry`);
6940
+ }
6941
+ };
6942
+ HttpsProxyAgent.protocols = ["http", "https"];
6943
+ function resume(socket) {
6944
+ setImmediate(() => {
6945
+ socket.resume();
6946
+ });
6947
+ }
6948
+ function omit(obj, ...keys) {
6949
+ const ret = {};
6950
+ let key;
6951
+ for (key in obj) if (!keys.includes(key)) ret[key] = obj[key];
6952
+ return ret;
6953
+ }
6954
+ //#endregion
6600
6955
  //#region ../../node_modules/.pnpm/@slack+logger@4.0.1/node_modules/@slack/logger/dist/index.js
6601
6956
  var require_dist$8 = /* @__PURE__ */ __commonJSMin(((exports) => {
6602
6957
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -16162,7 +16517,7 @@ var require_follow_redirects = /* @__PURE__ */ __commonJSMin(((exports, module)
16162
16517
  var http$4 = __require("http");
16163
16518
  var https$1 = __require("https");
16164
16519
  var Writable$1 = __require("stream").Writable;
16165
- var assert = __require("assert");
16520
+ var assert$1 = __require("assert");
16166
16521
  var debug = require_debug$1();
16167
16522
  // istanbul ignore next
16168
16523
  (function detectUnsupportedEnvironment() {
@@ -16173,7 +16528,7 @@ var require_follow_redirects = /* @__PURE__ */ __commonJSMin(((exports, module)
16173
16528
  })();
16174
16529
  var useNativeURL = false;
16175
16530
  try {
16176
- assert(new URL(""));
16531
+ assert$1(new URL(""));
16177
16532
  } catch (error) {
16178
16533
  useNativeURL = error.code === "ERR_INVALID_URL";
16179
16534
  }
@@ -16482,7 +16837,7 @@ var require_follow_redirects = /* @__PURE__ */ __commonJSMin(((exports, module)
16482
16837
  }, input, options);
16483
16838
  options.nativeProtocols = nativeProtocols;
16484
16839
  if (!isString(options.host) && !isString(options.hostname)) options.hostname = "::1";
16485
- assert.equal(options.protocol, protocol, "protocol mismatch");
16840
+ assert$1.equal(options.protocol, protocol, "protocol mismatch");
16486
16841
  debug("options", options);
16487
16842
  return new RedirectableRequest(options, callback);
16488
16843
  }
@@ -16571,7 +16926,7 @@ var require_follow_redirects = /* @__PURE__ */ __commonJSMin(((exports, module)
16571
16926
  request.destroy(error);
16572
16927
  }
16573
16928
  function isSubdomain(subdomain, domain) {
16574
- assert(isString(subdomain) && isString(domain));
16929
+ assert$1(isString(subdomain) && isString(domain));
16575
16930
  var dot = subdomain.length - domain.length - 1;
16576
16931
  return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain);
16577
16932
  }
@@ -62578,6 +62933,22 @@ function capOutput(s) {
62578
62933
  const t = s.trim();
62579
62934
  return t.length > MAX_TOOL_OUTPUT ? `${t.slice(0, MAX_TOOL_OUTPUT - 1)}…` : t;
62580
62935
  }
62936
+ /** The per-turn attribution footer: a Slack `context` block — small, secondary/gray text
62937
+ * reading "sent by agentconnect.md", the name linking to the Web App console (`webAppUrl`).
62938
+ * Context blocks use mrkdwn (`<url|text>`), not the CommonMark of `markdown` blocks. `text`
62939
+ * is the notification/accessibility fallback. */
62940
+ function attributionBlocks(webAppUrl) {
62941
+ return {
62942
+ text: "sent by agentconnect.md",
62943
+ blocks: [{
62944
+ type: "context",
62945
+ elements: [{
62946
+ type: "mrkdwn",
62947
+ text: `sent by <${webAppUrl}|agentconnect.md>`
62948
+ }]
62949
+ }]
62950
+ };
62951
+ }
62581
62952
  /** Pull human-readable output text out of an ACP tool_call/_update. Prefers the `content[]`
62582
62953
  * text blocks (the tool's reported output); falls back to a string `rawOutput`. diff /
62583
62954
  * terminal blocks and non-string rawOutput are skipped — they have no compact inline text. */
@@ -63017,12 +63388,20 @@ var OutputConverger = class {
63017
63388
  * — in medium/high — append a footer linking to the Web App session detail. The
63018
63389
  * link is omitted entirely when none is configured (no `local://` placeholder).
63019
63390
  */
63020
- onFinal(link) {
63391
+ onFinal(link, webAppUrl) {
63021
63392
  const clear = {
63022
63393
  kind: "set-status",
63023
63394
  text: ""
63024
63395
  };
63025
- if (this.mode === "low") return [...this.flush(), clear];
63396
+ const attribution = webAppUrl ? [{
63397
+ kind: "attribution",
63398
+ ...attributionBlocks(webAppUrl)
63399
+ }] : [];
63400
+ if (this.mode === "low") return [
63401
+ ...this.flush(),
63402
+ clear,
63403
+ ...attribution
63404
+ ];
63026
63405
  const reasoning = this.drainReasoning();
63027
63406
  const footer = link ? [{
63028
63407
  kind: "notice",
@@ -63032,7 +63411,8 @@ var OutputConverger = class {
63032
63411
  ...reasoning,
63033
63412
  ...this.flush(),
63034
63413
  clear,
63035
- ...footer
63414
+ ...footer,
63415
+ ...attribution
63036
63416
  ];
63037
63417
  }
63038
63418
  };
@@ -63086,16 +63466,21 @@ var SlackConnection = class {
63086
63466
  botToken;
63087
63467
  botId = "";
63088
63468
  workspaceUrl = "";
63089
- constructor(deps, factory = (o) => new App({
63090
- token: o.token,
63091
- appToken: o.appToken,
63092
- socketMode: true,
63093
- clientOptions: {
63094
- timeout: 1e4,
63095
- retryConfig: { retries: 2 }
63096
- },
63097
- ...deps.boltDebug ? { logLevel: LogLevel.DEBUG } : {}
63098
- })) {
63469
+ constructor(deps, factory = (o) => {
63470
+ const proxyUrl = process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY;
63471
+ const agent = proxyUrl ? new HttpsProxyAgent(proxyUrl) : void 0;
63472
+ return new App({
63473
+ token: o.token,
63474
+ appToken: o.appToken,
63475
+ socketMode: true,
63476
+ ...agent ? { agent } : {},
63477
+ clientOptions: {
63478
+ timeout: 3e4,
63479
+ retryConfig: { retries: 2 }
63480
+ },
63481
+ ...deps.boltDebug ? { logLevel: LogLevel.DEBUG } : {}
63482
+ });
63483
+ }) {
63099
63484
  this.deps = deps;
63100
63485
  this.appToken = deps.group.appToken;
63101
63486
  this.botToken = deps.group.botToken;
@@ -63252,6 +63637,22 @@ var SlackConnection = class {
63252
63637
  }))?.ts;
63253
63638
  });
63254
63639
  }
63640
+ /** Post a one-shot Block Kit `context` message — the per-turn "sent by agentconnect.md"
63641
+ * attribution footer (small secondary/gray text). Fire-and-forget: unlike the status bar
63642
+ * its ts is never kept for edits, so nothing is returned. `unfurl_*` off so the console
63643
+ * link doesn't sprout a preview card. */
63644
+ async postContext(channel, blocks, text, threadTs) {
63645
+ await this.queue.enqueue(async () => {
63646
+ await this.app.client.chat.postMessage({
63647
+ channel,
63648
+ thread_ts: threadTs,
63649
+ text,
63650
+ blocks,
63651
+ unfurl_links: false,
63652
+ unfurl_media: false
63653
+ });
63654
+ });
63655
+ }
63255
63656
  /** Edit a previously-posted Block Kit message in place (chat.update). Best-effort.
63256
63657
  * `unfurl_links: false` keeps an edit from unfurling the "View session" URL. */
63257
63658
  async updateBlocks(channel, ts, blocks, text) {
@@ -81774,6 +82175,7 @@ var Daemon = class Daemon {
81774
82175
  hostStopping = /* @__PURE__ */ new Map();
81775
82176
  idleSweepTimer;
81776
82177
  cancelTimers = /* @__PURE__ */ new Map();
82178
+ slackRetryTimers = /* @__PURE__ */ new Map();
81777
82179
  constructor(opts = {}) {
81778
82180
  this.opts = opts;
81779
82181
  this.clock = opts.clock ?? systemClock;
@@ -81833,7 +82235,10 @@ var Daemon = class Daemon {
81833
82235
  const skipped = Object.keys(resolvedRuntimes).filter((id) => !this.runtimes[id]);
81834
82236
  if (skipped.length) this.log.info(`runtimes not installed (skipped): ${skipped.join(", ")}`);
81835
82237
  this.store = new LocalStore(statePath(root));
81836
- this.nameResolver = new SlackNameResolver((id, name) => this.store.setDisplayName(id, name, Date.now()), this.log);
82238
+ this.nameResolver = new SlackNameResolver((id, name) => {
82239
+ this.store.setDisplayName(id, name, Date.now());
82240
+ this.emitSessionMetadataSnapshotsForDisplayName(id);
82241
+ }, this.log);
81837
82242
  this.cpRouting = new CpRoutingLayer({
81838
82243
  load: () => {
81839
82244
  const row = this.store.getCpRouting();
@@ -81921,14 +82326,24 @@ var Daemon = class Daemon {
81921
82326
  boltDebug: cfg.logging.level === "debug" || cfg.logging.level === "trace"
81922
82327
  });
81923
82328
  this.log.info(`slack: connecting (${group.integrations.length} integration(s): ${group.integrations.map((i) => i.agentId).join(", ")})…`);
81924
- await conn.start();
81925
- this.log.info(`slack: socket connected as bot user ${conn.botUserId}`);
81926
- for (const { integrationId } of group.integrations) {
81927
- this.botUserIds[integrationId] = conn.botUserId;
81928
- this.connByIntegration.set(integrationId, conn);
82329
+ try {
82330
+ await conn.start();
82331
+ this.log.info(`slack: socket connected as bot user ${conn.botUserId}`);
82332
+ for (const { integrationId } of group.integrations) {
82333
+ this.botUserIds[integrationId] = conn.botUserId;
82334
+ this.connByIntegration.set(integrationId, conn);
82335
+ }
82336
+ this.connections.push(conn);
82337
+ this.refreshChannels(conn);
82338
+ } catch (err) {
82339
+ await conn.stop().catch(() => {});
82340
+ this.log.warn(`slack: connection failed for appToken — retrying in 60s: ${formatErr(err)}`);
82341
+ const timer = this.clock.setTimeout(() => {
82342
+ if (this.draining) return;
82343
+ this.retrySlackConnection(group).catch((e) => this.log.error(`slack: retry loop error: ${formatErr(e)}`));
82344
+ }, 6e4);
82345
+ this.slackRetryTimers.set(group.appToken, timer);
81929
82346
  }
81930
- this.connections.push(conn);
81931
- this.refreshChannels(conn);
81932
82347
  }
81933
82348
  for (const a of agents) this.scheduler.sync(a.id, a.crons);
81934
82349
  const cronCount = agents.reduce((n, a) => n + this.scheduler.count(a.id), 0);
@@ -82108,6 +82523,11 @@ var Daemon = class Daemon {
82108
82523
  }
82109
82524
  this.connections.push(conn);
82110
82525
  this.refreshChannels(conn);
82526
+ const pending = this.slackRetryTimers.get(group.appToken);
82527
+ if (pending !== void 0) {
82528
+ this.clock.clearTimeout(pending);
82529
+ this.slackRetryTimers.delete(group.appToken);
82530
+ }
82111
82531
  } catch (err) {
82112
82532
  this.log.error(`slack: failed to open runtime socket for appToken — leaving existing sockets intact: ${formatErr(err)}`);
82113
82533
  }
@@ -82125,7 +82545,11 @@ var Daemon = class Daemon {
82125
82545
  try {
82126
82546
  const channels = await conn.listBotChannels();
82127
82547
  if (!channels) return;
82128
- for (const c of channels) if (c.name) this.store.setDisplayName(c.id, c.name, Date.now());
82548
+ for (const c of channels) {
82549
+ if (!c.name) continue;
82550
+ this.store.setDisplayName(c.id, c.name, Date.now());
82551
+ this.emitSessionMetadataSnapshotsForDisplayName(c.id);
82552
+ }
82129
82553
  for (const [integrationId, c] of this.connByIntegration) {
82130
82554
  if (c !== conn) continue;
82131
82555
  this.channelSnapshots.set(integrationId, channels);
@@ -82139,6 +82563,54 @@ var Daemon = class Daemon {
82139
82563
  this.log.debug(`slack: channel snapshot refresh failed: ${formatErr(err)}`);
82140
82564
  }
82141
82565
  }
82566
+ /**
82567
+ * Background retry loop for a Slack connection that failed at initial startup.
82568
+ * Creates a fresh SlackConnection (the old one is in an unknown state) and, on
82569
+ * success, wires it into `botUserIds` / `connByIntegration` / `connections` so
82570
+ * the agent can begin processing messages. On failure, schedules another retry
82571
+ * at a slow, fixed interval — never gives up, so a temporary network outage
82572
+ * self-heals without manual daemon restart.
82573
+ */
82574
+ async retrySlackConnection(group) {
82575
+ if (this.draining) return;
82576
+ if ([...this.connByIntegration.values()].some((c) => c.appToken === group.appToken)) {
82577
+ this.slackRetryTimers.delete(group.appToken);
82578
+ return;
82579
+ }
82580
+ this.log.info(`slack: background retry for appToken (${group.integrations.length} integration(s): ${group.integrations.map((i) => i.agentId).join(", ")})…`);
82581
+ const conn = new SlackConnection({
82582
+ group,
82583
+ newTraceId: () => randomUUID(),
82584
+ onMessage: (msg) => {
82585
+ this.nameResolver?.noteMessage(conn, msg);
82586
+ this.onInbound(msg);
82587
+ },
82588
+ onChannelsChanged: () => void this.refreshChannels(conn),
82589
+ onStatusAction: (a) => this.handleSlackStatusAction(a),
82590
+ onStatusInfo: (key) => this.statusInfoForKey(key),
82591
+ log: this.log,
82592
+ boltDebug: this.cfg.logging.level === "debug" || this.cfg.logging.level === "trace"
82593
+ });
82594
+ try {
82595
+ await conn.start();
82596
+ this.log.info(`slack: background retry succeeded — connected as bot user ${conn.botUserId}`);
82597
+ this.slackRetryTimers.delete(group.appToken);
82598
+ for (const { integrationId } of group.integrations) {
82599
+ this.botUserIds[integrationId] = conn.botUserId;
82600
+ this.connByIntegration.set(integrationId, conn);
82601
+ }
82602
+ this.connections.push(conn);
82603
+ this.refreshChannels(conn);
82604
+ } catch (err) {
82605
+ await conn.stop().catch(() => {});
82606
+ this.log.warn(`slack: background retry failed — scheduling next attempt in 60s: ${formatErr(err)}`);
82607
+ const timer = this.clock.setTimeout(() => {
82608
+ if (this.draining) return;
82609
+ this.retrySlackConnection(group).catch((e) => this.log.error(`slack: retry loop error: ${formatErr(e)}`));
82610
+ }, 6e4);
82611
+ this.slackRetryTimers.set(group.appToken, timer);
82612
+ }
82613
+ }
82142
82614
  ensureHost(agentId, cfg) {
82143
82615
  let host = this.hosts.get(agentId);
82144
82616
  if (host) return host;
@@ -82158,7 +82630,8 @@ var Daemon = class Daemon {
82158
82630
  configPrefs: {
82159
82631
  model: agent.runtimeOverrides?.model,
82160
82632
  reasoningEffort: agent.reasoningEffort,
82161
- fastMode: agent.fastMode
82633
+ fastMode: agent.fastMode,
82634
+ systemPrompt: agent.description
82162
82635
  },
82163
82636
  log: this.log
82164
82637
  });
@@ -82656,7 +83129,7 @@ var Daemon = class Daemon {
82656
83129
  });
82657
83130
  } else {
82658
83131
  const link = this.sessionLink(sessionId);
82659
- for (const action of conv.onFinal(link)) this.enqueueApply(p, action);
83132
+ for (const action of conv.onFinal(link, this.webAppBase())) this.enqueueApply(p, action);
82660
83133
  }
82661
83134
  for (const ev of rec.onFinal()) this.recordEvent(agentId, msg.channel, statusThread, ev);
82662
83135
  await p.applyChain;
@@ -82756,6 +83229,9 @@ var Daemon = class Daemon {
82756
83229
  case "tool-output":
82757
83230
  await conn.postMessage(p.channel, action.text, p.thread);
82758
83231
  return;
83232
+ case "attribution":
83233
+ await conn.postContext(p.channel, action.blocks, action.text, p.thread);
83234
+ return;
82759
83235
  case "progress":
82760
83236
  if (p.progressTs) await conn.updateMessage(p.channel, p.progressTs, action.text);
82761
83237
  else if (!p.progressAttempted) {
@@ -82799,7 +83275,14 @@ var Daemon = class Daemon {
82799
83275
  * known; without it the link falls back to `<base>/sessions/<id>`. Always resolves, so
82800
83276
  * the View-session link is always available. */
82801
83277
  sessionLink(acpSessionId) {
82802
- return `${(this.cfg.webAppUrl ?? this.cpWebAppUrl ?? DEFAULT_WEB_APP_URL).replace(/\/$/, "")}${this.cpOrgSlug ? `/${encodeURIComponent(this.cpOrgSlug)}` : ""}/sessions/${acpSessionId}`;
83278
+ const orgSeg = this.cpOrgSlug ? `/${encodeURIComponent(this.cpOrgSlug)}` : "";
83279
+ return `${this.webAppBase()}${orgSeg}/sessions/${acpSessionId}`;
83280
+ }
83281
+ /** The Web App console origin (trailing slash stripped): the explicit local `webAppUrl`,
83282
+ * else the CP-provided origin, else the public default. Backs both the session deep link
83283
+ * and the per-turn "sent by agentconnect.md" attribution footer. Always resolves. */
83284
+ webAppBase() {
83285
+ return (this.cfg.webAppUrl ?? this.cpWebAppUrl ?? DEFAULT_WEB_APP_URL).replace(/\/$/, "");
82803
83286
  }
82804
83287
  sessionListProjection(sessionId, agentId) {
82805
83288
  return createSessionReader(this.store, (id) => this.replyConnFor(id)?.workspaceUrl).list({ agentId }).sessions.find((s) => s.sessionId === sessionId);
@@ -82838,6 +83321,21 @@ var Daemon = class Daemon {
82838
83321
  this.log.debug(`event/session emit failed (session ${input.sessionId}): ${err.message}`);
82839
83322
  }
82840
83323
  }
83324
+ emitSessionMetadataSnapshotsForDisplayName(id) {
83325
+ if (!this.cpClient) return;
83326
+ for (const row of this.store.listSessions()) {
83327
+ if (!row.acpSessionId) continue;
83328
+ if (row.channel !== id && row.triggeredBy !== id) continue;
83329
+ this.emitSessionMetadataSnapshot({
83330
+ sessionId: row.acpSessionId,
83331
+ agentId: row.agentId,
83332
+ phase: "plan",
83333
+ platform: row.platform,
83334
+ channel: row.channel,
83335
+ thread: row.thread
83336
+ });
83337
+ }
83338
+ }
82841
83339
  /** Assemble a status snapshot from the parts (agent config + host model selector +
82842
83340
  * folded ACP usage). Shared by `buildStatusInfo` (per-turn Pending) and
82843
83341
  * `statusInfoForKey` (the ⚙-modal, keyed by session). */
@@ -82951,7 +83449,17 @@ var Daemon = class Daemon {
82951
83449
  });
82952
83450
  this.emitStatusBar(p);
82953
83451
  }
82954
- if (update?.sessionUpdate === "session_info_update" && update.title !== void 0) this.store.setSessionTitle(p.sessionKey, update.title);
83452
+ if (update?.sessionUpdate === "session_info_update" && update.title !== void 0) {
83453
+ this.store.setSessionTitle(p.sessionKey, update.title);
83454
+ this.emitSessionMetadataSnapshot({
83455
+ sessionId,
83456
+ agentId: p.agentId,
83457
+ phase: "plan",
83458
+ platform: p.platform,
83459
+ channel: p.channel,
83460
+ thread: p.statusThread
83461
+ });
83462
+ }
82955
83463
  if (p.webchat) this.emitWebchatUpdate(p, update);
82956
83464
  else {
82957
83465
  for (const action of p.conv.onUpdate(update)) this.enqueueApply(p, action);
@@ -83561,6 +84069,8 @@ var Daemon = class Daemon {
83561
84069
  }
83562
84070
  for (const t of this.cancelTimers.values()) this.clock.clearTimeout(t);
83563
84071
  this.cancelTimers.clear();
84072
+ for (const t of this.slackRetryTimers.values()) this.clock.clearTimeout(t);
84073
+ this.slackRetryTimers.clear();
83564
84074
  this.metrics?.stop();
83565
84075
  await this.watcher?.close();
83566
84076
  await this.drainForShutdown();
@@ -83603,4 +84113,4 @@ async function runForeground(opts, deps = {}) {
83603
84113
  //#endregion
83604
84114
  export { ClientTransport as n, runForeground as t };
83605
84115
 
83606
- //# sourceMappingURL=run-foreground-CD2uFFvp.js.map
84116
+ //# sourceMappingURL=run-foreground-CK2rQc1c.js.map