@slock-ai/daemon 0.56.1 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -15110,10 +15110,22 @@ var channelAddMemberOperationSchema = external_exports.object({
15110
15110
  agents: external_exports.array(idOrHandleSchema).max(64).optional(),
15111
15111
  draftHint: draftHintSchema
15112
15112
  });
15113
+ var integrationApproveAgentLoginOperationSchema = external_exports.object({
15114
+ type: external_exports.literal("integration:approve_agent_login"),
15115
+ requestId: uuidSchema,
15116
+ agentId: uuidSchema,
15117
+ agentName: external_exports.string().trim().min(1).max(120),
15118
+ clientId: uuidSchema,
15119
+ clientKey: external_exports.string().trim().min(1).max(120),
15120
+ clientName: external_exports.string().trim().min(1).max(120),
15121
+ scopes: external_exports.array(external_exports.string().trim().min(1).max(120)).max(64),
15122
+ draftHint: draftHintSchema
15123
+ });
15113
15124
  var actionCardActionSchema = external_exports.discriminatedUnion("type", [
15114
15125
  channelCreateOperationSchema,
15115
15126
  agentCreateOperationSchema,
15116
- channelAddMemberOperationSchema
15127
+ channelAddMemberOperationSchema,
15128
+ integrationApproveAgentLoginOperationSchema
15117
15129
  ]);
15118
15130
  function validateActionCardAction(action) {
15119
15131
  if (action.type === "agent:create") {
@@ -15741,7 +15753,8 @@ var knowledgeGetCommand = defineCommand(
15741
15753
  flags: "--trace-id <id>",
15742
15754
  description: "Optional trace id for correlation in the knowledge event"
15743
15755
  }
15744
- ]
15756
+ ],
15757
+ helpAfter: "\nTopics:\n Run `slock manual get index` to list available manual topics.\n"
15745
15758
  },
15746
15759
  async (ctx, topic, opts) => {
15747
15760
  const agentContext = ctx.loadAgentContext();
@@ -17766,6 +17779,24 @@ function formatIntegrationList(data) {
17766
17779
  return lines.join("\n");
17767
17780
  }
17768
17781
  function formatIntegrationLogin(data) {
17782
+ if (data.status === "approval_required") {
17783
+ const lines2 = [
17784
+ `Human approval required: ${data.service.name}`,
17785
+ `service: ${data.service.clientId}`,
17786
+ `id: ${data.service.id}`,
17787
+ `scopes: ${data.scopes.length > 0 ? data.scopes.join(", ") : "-"}`,
17788
+ `request id: ${data.approval?.requestId ?? data.requestId}`
17789
+ ];
17790
+ if (data.approval?.actionCardMessageId) {
17791
+ lines2.push(`approval card: ${data.approval.actionCardMessageId}`);
17792
+ lines2.push(`target: ${data.approval.target ?? "-"}`);
17793
+ lines2.push("next: ask a server owner/admin to approve the card, then rerun this command");
17794
+ } else {
17795
+ lines2.push("approval card: not posted");
17796
+ lines2.push("next: rerun with --target <channel-or-thread> to post a human approval card, or ask a server owner/admin to approve this request");
17797
+ }
17798
+ return lines2.join("\n");
17799
+ }
17769
17800
  const verb = data.status === "already_logged_in" ? "Already logged in" : "Agent login ready";
17770
17801
  const lines = [
17771
17802
  `${verb}: ${data.service.name}`,
@@ -17845,6 +17876,7 @@ var integrationLoginCommand = defineCommand(
17845
17876
  return previous;
17846
17877
  }
17847
17878
  },
17879
+ { flags: "--target <target>", description: "Conversation target to post a human approval card when approval is required" },
17848
17880
  { flags: "--json", description: "Emit machine-readable JSON" }
17849
17881
  ]
17850
17882
  },
@@ -17861,7 +17893,8 @@ var integrationLoginCommand = defineCommand(
17861
17893
  `/internal/agent/${encodeURIComponent(agentContext.agentId)}/integrations/login`,
17862
17894
  {
17863
17895
  service,
17864
- scopes
17896
+ scopes,
17897
+ target: opts.target?.trim() || void 0
17865
17898
  }
17866
17899
  );
17867
17900
  if (!res.ok || !res.data) {
@@ -17885,6 +17918,13 @@ import fs3 from "fs";
17885
17918
  import os3 from "os";
17886
17919
  import path5 from "path";
17887
17920
  var AGENT_MANIFEST_MAX_BYTES = 64 * 1024;
17921
+ var AgentManifestFetchError = class extends Error {
17922
+ constructor(message, status) {
17923
+ super(message);
17924
+ this.status = status;
17925
+ this.name = "AgentManifestFetchError";
17926
+ }
17927
+ };
17888
17928
  function isRecord(value) {
17889
17929
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
17890
17930
  }
@@ -17971,7 +18011,7 @@ async function fetchAgentManifest(url2) {
17971
18011
  throw new Error("manifest redirects must remain on credential-free HTTPS URLs");
17972
18012
  }
17973
18013
  if (!response.ok) {
17974
- throw new Error(`manifest fetch failed with HTTP ${response.status}`);
18014
+ throw new AgentManifestFetchError(`manifest fetch failed with HTTP ${response.status}`, response.status);
17975
18015
  }
17976
18016
  const contentType = response.headers.get("content-type") ?? "";
17977
18017
  if (contentType && !contentType.includes("application/json")) {
@@ -18079,6 +18119,12 @@ function describeNoLocalEnv(manifest) {
18079
18119
  }
18080
18120
  return "manifest does not request local CLI env exports";
18081
18121
  }
18122
+ function describeMissingManifest(input) {
18123
+ if (input.manifestUrl) {
18124
+ return "agent behavior manifest was not found; no local CLI env is required";
18125
+ }
18126
+ return `${input.service.name} does not expose an agent behavior manifest; no local CLI env is required`;
18127
+ }
18082
18128
  var IntegrationEnvError = class extends Error {
18083
18129
  constructor(code, message) {
18084
18130
  super(message);
@@ -18088,16 +18134,28 @@ var IntegrationEnvError = class extends Error {
18088
18134
  };
18089
18135
  async function resolveIntegrationEnv(input) {
18090
18136
  if (!input.service.agentManifestUrl) {
18091
- throw new IntegrationEnvError(
18092
- "INTEGRATION_MANIFEST_MISSING",
18093
- `${input.service.name} does not expose an agent behavior manifest`
18094
- );
18137
+ return {
18138
+ kind: "no-local-env",
18139
+ service: input.service,
18140
+ manifestUrl: null,
18141
+ manifest: null,
18142
+ message: describeMissingManifest({ service: input.service })
18143
+ };
18095
18144
  }
18096
18145
  const fetchManifestImpl = input.fetchManifest ?? fetchAgentManifest;
18097
18146
  let manifest;
18098
18147
  try {
18099
18148
  manifest = await fetchManifestImpl(input.service.agentManifestUrl);
18100
18149
  } catch (err) {
18150
+ if (err instanceof AgentManifestFetchError && (err.status === 404 || err.status === 410)) {
18151
+ return {
18152
+ kind: "no-local-env",
18153
+ service: input.service,
18154
+ manifestUrl: input.service.agentManifestUrl,
18155
+ manifest: null,
18156
+ message: describeMissingManifest({ service: input.service, manifestUrl: input.service.agentManifestUrl })
18157
+ };
18158
+ }
18101
18159
  throw new IntegrationEnvError("INTEGRATION_MANIFEST_INVALID", err.message);
18102
18160
  }
18103
18161
  if (manifest.execution.mode !== "local_cli" || manifest.credential_boundary?.storage !== "per_agent_home") {
@@ -18128,8 +18186,8 @@ async function resolveIntegrationEnv(input) {
18128
18186
  function formatNoLocalEnv(input) {
18129
18187
  return [
18130
18188
  `# Slock integration profile for ${input.service}`,
18131
- `# manifest: ${input.manifestUrl}`,
18132
- "# No local CLI environment exports are required by this manifest.",
18189
+ input.manifestUrl ? `# manifest: ${input.manifestUrl}` : "# manifest: none declared",
18190
+ "# No local CLI environment exports are required for this service.",
18133
18191
  `# ${input.message}`,
18134
18192
  "# Slock did not set HOME/XDG exports and did not execute manifest commands."
18135
18193
  ].join("\n");
@@ -18175,7 +18233,7 @@ var integrationEnvCommand = defineCommand(
18175
18233
  service: resolution.service.clientId,
18176
18234
  manifestUrl: resolution.manifestUrl,
18177
18235
  requiresLocalEnv: false,
18178
- command: resolution.manifest.execution.command ?? null,
18236
+ command: resolution.manifest?.execution.command ?? null,
18179
18237
  env: {},
18180
18238
  message: resolution.message
18181
18239
  }
package/dist/core.js CHANGED
@@ -5,14 +5,11 @@ import {
5
5
  detectRuntimes,
6
6
  parseDaemonCliArgs,
7
7
  readDaemonVersion,
8
- resolveChatBridgePath,
9
8
  resolveSlockCliPath,
10
9
  resolveWorkspaceDirectoryPath,
11
- scanWorkspaceDirectories
12
- } from "./chunk-RIBO24KM.js";
13
- import {
10
+ scanWorkspaceDirectories,
14
11
  subscribeDaemonLogs
15
- } from "./chunk-M2KQBJR3.js";
12
+ } from "./chunk-DQN3TW2I.js";
16
13
  export {
17
14
  DAEMON_CLI_USAGE,
18
15
  DaemonCore,
@@ -20,7 +17,6 @@ export {
20
17
  detectRuntimes,
21
18
  parseDaemonCliArgs,
22
19
  readDaemonVersion,
23
- resolveChatBridgePath,
24
20
  resolveSlockCliPath,
25
21
  resolveWorkspaceDirectoryPath,
26
22
  scanWorkspaceDirectories,
package/dist/index.js CHANGED
@@ -3,8 +3,7 @@ import {
3
3
  DAEMON_CLI_USAGE,
4
4
  DaemonCore,
5
5
  parseDaemonCliArgs
6
- } from "./chunk-RIBO24KM.js";
7
- import "./chunk-M2KQBJR3.js";
6
+ } from "./chunk-DQN3TW2I.js";
8
7
 
9
8
  // src/index.ts
10
9
  var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slock-ai/daemon",
3
- "version": "0.56.1",
3
+ "version": "0.57.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "slock-daemon": "dist/index.js"
@@ -30,6 +30,8 @@
30
30
  "prepack": "pnpm run build",
31
31
  "prepublishOnly": "pnpm run build",
32
32
  "typecheck": "tsc --noEmit",
33
+ "generate:slock-cli-guide": "tsx scripts/generate-slock-cli-guide.ts",
34
+ "check:slock-cli-guide-fresh": "pnpm generate:slock-cli-guide && git diff --exit-code ../../docs/agent-knowledge/slock-cli-overview.mdx",
33
35
  "release:patch": "npm version patch --no-git-tag-version && cd ../.. && pnpm install --lockfile-only && git add packages/daemon/package.json pnpm-lock.yaml && git commit -m \"chore: bump @slock-ai/daemon to v$(node -p \"require('./packages/daemon/package.json').version\")\" && git tag daemon-v$(node -p \"require('./packages/daemon/package.json').version\") && git push && git push --tags",
34
36
  "release:minor": "npm version minor --no-git-tag-version && cd ../.. && pnpm install --lockfile-only && git add packages/daemon/package.json pnpm-lock.yaml && git commit -m \"chore: bump @slock-ai/daemon to v$(node -p \"require('./packages/daemon/package.json').version\")\" && git tag daemon-v$(node -p \"require('./packages/daemon/package.json').version\") && git push && git push --tags",
35
37
  "release:major": "npm version major --no-git-tag-version && cd ../.. && pnpm install --lockfile-only && git add packages/daemon/package.json pnpm-lock.yaml && git commit -m \"chore: bump @slock-ai/daemon to v$(node -p \"require('./packages/daemon/package.json').version\")\" && git tag daemon-v$(node -p \"require('./packages/daemon/package.json').version\") && git push && git push --tags",
@@ -1,96 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- daemonFetch,
4
- executeJsonRequest
5
- } from "./chunk-M2KQBJR3.js";
6
-
7
- // src/chat-bridge.ts
8
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
10
- import { z } from "zod";
11
-
12
- // src/perfAttribution.ts
13
- var PERF_CALLER_CONTEXT_HEADER = "X-Perf-Caller-Context";
14
- var AGENT_ORIGINATED_CALLER_CONTEXT = "agent_originated";
15
- function buildChatBridgeCommonHeaders(authToken2, { includeContentType = true } = {}) {
16
- const headers = {
17
- [PERF_CALLER_CONTEXT_HEADER]: AGENT_ORIGINATED_CALLER_CONTEXT
18
- };
19
- if (includeContentType) {
20
- headers["Content-Type"] = "application/json";
21
- }
22
- if (authToken2) {
23
- headers.Authorization = `Bearer ${authToken2}`;
24
- }
25
- return headers;
26
- }
27
-
28
- // src/chat-bridge.ts
29
- var args = process.argv.slice(2);
30
- var agentId = "";
31
- var serverUrl = "http://localhost:3001";
32
- var authToken = "";
33
- var launchId = "";
34
- for (let i = 0; i < args.length; i++) {
35
- if (args[i] === "--agent-id" && args[i + 1]) agentId = args[++i];
36
- if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
37
- if (args[i] === "--auth-token" && args[i + 1]) authToken = args[++i];
38
- if (args[i] === "--launch-id" && args[i + 1]) launchId = args[++i];
39
- }
40
- if (!agentId) {
41
- console.error("Missing --agent-id");
42
- process.exit(1);
43
- }
44
- var commonHeaders = buildChatBridgeCommonHeaders(authToken);
45
- var runtimeActionHeaders = {
46
- ...commonHeaders,
47
- ...launchId ? { "X-Agent-Launch-Id": launchId } : {}
48
- };
49
- function bridgeFetch(url, init = {}) {
50
- return daemonFetch(url, init);
51
- }
52
- var server = new McpServer({
53
- name: "chat",
54
- version: "1.0.0"
55
- });
56
- var RUNTIME_PROFILE_MIGRATION_DONE_TOOL_NAME = "runtime_profile_migration_done";
57
- server.tool(
58
- RUNTIME_PROFILE_MIGRATION_DONE_TOOL_NAME,
59
- "Deprecated compatibility no-op. Runtime Profile changes now reset the session automatically; this tool is kept so old prompts can acknowledge without blocking.",
60
- {
61
- migration_key: z.string().optional().describe("Ignored legacy migration key, if an old prompt provided one")
62
- },
63
- async ({ migration_key }) => {
64
- const key = migration_key?.trim() ?? "";
65
- try {
66
- const { response: res, data } = await executeJsonRequest(
67
- `${serverUrl}/internal/agent/${agentId}/runtime-profile/migration-done`,
68
- {
69
- method: "POST",
70
- headers: runtimeActionHeaders,
71
- body: JSON.stringify({ migrationKey: key })
72
- },
73
- {
74
- toolName: RUNTIME_PROFILE_MIGRATION_DONE_TOOL_NAME,
75
- fetchImpl: bridgeFetch
76
- }
77
- );
78
- if (!res.ok) {
79
- return {
80
- isError: true,
81
- content: [{ type: "text", text: `Error: ${data.error || "Runtime Profile reset acknowledgment failed"}` }]
82
- };
83
- }
84
- return {
85
- content: [{ type: "text", text: data.message || "Runtime Profile migration acknowledgments are deprecated; runtime changes reset the session automatically." }]
86
- };
87
- } catch (err) {
88
- return {
89
- isError: true,
90
- content: [{ type: "text", text: `Error: ${err.message}` }]
91
- };
92
- }
93
- }
94
- );
95
- var transport = new StdioServerTransport();
96
- await server.connect(transport);
@@ -1,260 +0,0 @@
1
- // src/logger.ts
2
- var listeners = /* @__PURE__ */ new Set();
3
- function timestamp() {
4
- const d = /* @__PURE__ */ new Date();
5
- const pad = (n) => String(n).padStart(2, "0");
6
- return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
7
- }
8
- function format(level, msg) {
9
- return `${timestamp()} [${level}] ${msg}`;
10
- }
11
- function emit(event) {
12
- for (const listener of listeners) {
13
- listener(event);
14
- }
15
- }
16
- function subscribeDaemonLogs(listener) {
17
- listeners.add(listener);
18
- return () => {
19
- listeners.delete(listener);
20
- };
21
- }
22
- var logger = {
23
- info(msg) {
24
- const line = format("INFO", msg);
25
- console.log(line);
26
- emit({ level: "INFO", line, message: msg });
27
- },
28
- warn(msg) {
29
- const line = format("WARN", msg);
30
- console.warn(line);
31
- emit({ level: "WARN", line, message: msg });
32
- },
33
- error(msg, err) {
34
- const line = format("ERROR", msg);
35
- if (err) {
36
- console.error(line, err);
37
- } else {
38
- console.error(line);
39
- }
40
- emit({ level: "ERROR", line, message: msg, error: err });
41
- }
42
- };
43
-
44
- // src/chatBridgeRequest.ts
45
- var DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS = Number.parseInt(
46
- process.env.SLOCK_CHAT_BRIDGE_TOOL_TIMEOUT_MS || "",
47
- 10
48
- ) || 6e4;
49
- var ChatBridgeToolTimeoutError = class extends Error {
50
- toolName;
51
- target;
52
- timeoutMs;
53
- durationMs;
54
- constructor(toolName, target, timeoutMs, durationMs) {
55
- super(`${toolName} timed out after ${timeoutMs}ms${target ? ` (target: ${target})` : ""}`);
56
- this.name = "ChatBridgeToolTimeoutError";
57
- this.toolName = toolName;
58
- this.target = target;
59
- this.timeoutMs = timeoutMs;
60
- this.durationMs = durationMs;
61
- }
62
- };
63
- function describeError(err) {
64
- if (err instanceof Error) return `${err.name}: ${err.message}`;
65
- return String(err);
66
- }
67
- async function executeJsonRequest(url, init, {
68
- toolName,
69
- target = null,
70
- timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
71
- fetchImpl,
72
- now = () => Date.now(),
73
- warn = (message) => logger.warn(message)
74
- }) {
75
- const startedAt = now();
76
- const timeoutController = new AbortController();
77
- const signals = [timeoutController.signal];
78
- if (init.signal) signals.push(init.signal);
79
- const signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
80
- const timeout = setTimeout(() => {
81
- timeoutController.abort();
82
- }, timeoutMs);
83
- timeout.unref?.();
84
- try {
85
- const response = await fetchImpl(url, { ...init, signal });
86
- const data = await response.json();
87
- return { response, data, durationMs: now() - startedAt };
88
- } catch (err) {
89
- const durationMs = now() - startedAt;
90
- if (timeoutController.signal.aborted && !init.signal?.aborted) {
91
- warn(
92
- `[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
93
- );
94
- throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
95
- }
96
- warn(
97
- `[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
98
- );
99
- throw err;
100
- } finally {
101
- clearTimeout(timeout);
102
- }
103
- }
104
- async function executeResponseRequest(url, init, {
105
- toolName,
106
- target = null,
107
- timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
108
- fetchImpl,
109
- now = () => Date.now(),
110
- warn = (message) => logger.warn(message)
111
- }) {
112
- const startedAt = now();
113
- const timeoutController = new AbortController();
114
- const signals = [timeoutController.signal];
115
- if (init.signal) signals.push(init.signal);
116
- const signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
117
- const timeout = setTimeout(() => {
118
- timeoutController.abort();
119
- }, timeoutMs);
120
- timeout.unref?.();
121
- try {
122
- const response = await fetchImpl(url, { ...init, signal });
123
- return { response, durationMs: now() - startedAt };
124
- } catch (err) {
125
- const durationMs = now() - startedAt;
126
- if (timeoutController.signal.aborted && !init.signal?.aborted) {
127
- warn(
128
- `[ChatBridgeTimeout] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} timeout_ms=${timeoutMs} outcome=timeout`
129
- );
130
- throw new ChatBridgeToolTimeoutError(toolName, target, timeoutMs, durationMs);
131
- }
132
- warn(
133
- `[ChatBridgeError] tool=${toolName} target=${target ?? "-"} duration_ms=${durationMs} outcome=error error=${describeError(err)}`
134
- );
135
- throw err;
136
- } finally {
137
- clearTimeout(timeout);
138
- }
139
- }
140
-
141
- // src/proxy.ts
142
- import { HttpsProxyAgent } from "https-proxy-agent";
143
- import { ProxyAgent } from "undici";
144
- var fetchDispatcherCache = /* @__PURE__ */ new Map();
145
- function getFetchPreResponseTimeoutMs(env) {
146
- const parsed = Number.parseInt(env.SLOCK_DAEMON_FETCH_PRE_RESPONSE_TIMEOUT_MS || "", 10);
147
- return Number.isFinite(parsed) && parsed > 0 ? parsed : 3e4;
148
- }
149
- function getDefaultPort(protocol) {
150
- switch (protocol) {
151
- case "https:":
152
- case "wss:":
153
- return "443";
154
- case "http:":
155
- case "ws:":
156
- return "80";
157
- default:
158
- return "";
159
- }
160
- }
161
- function hostMatchesNoProxyEntry(hostname, ruleHost) {
162
- if (!ruleHost) return false;
163
- const normalizedRule = ruleHost.replace(/^\*\./, ".").replace(/^\./, "").toLowerCase();
164
- const normalizedHost = hostname.toLowerCase();
165
- return normalizedHost === normalizedRule || normalizedHost.endsWith(`.${normalizedRule}`);
166
- }
167
- function getProxyUrlForTarget(targetUrl, env) {
168
- const protocol = new URL(targetUrl).protocol;
169
- switch (protocol) {
170
- case "wss:":
171
- return env.WSS_PROXY || env.wss_proxy || env.HTTPS_PROXY || env.https_proxy || env.ALL_PROXY || env.all_proxy;
172
- case "ws:":
173
- return env.WS_PROXY || env.ws_proxy || env.HTTP_PROXY || env.http_proxy || env.ALL_PROXY || env.all_proxy;
174
- case "https:":
175
- return env.HTTPS_PROXY || env.https_proxy || env.ALL_PROXY || env.all_proxy;
176
- case "http:":
177
- return env.HTTP_PROXY || env.http_proxy || env.ALL_PROXY || env.all_proxy;
178
- default:
179
- return env.ALL_PROXY || env.all_proxy;
180
- }
181
- }
182
- function shouldBypassProxy(targetUrl, env) {
183
- const rawNoProxy = env.NO_PROXY || env.no_proxy;
184
- if (!rawNoProxy) return false;
185
- const url = new URL(targetUrl);
186
- const hostname = url.hostname.toLowerCase();
187
- const port = url.port || getDefaultPort(url.protocol);
188
- return rawNoProxy.split(",").map((entry) => entry.trim()).filter(Boolean).some((entry) => {
189
- if (entry === "*") return true;
190
- const [ruleHost, rulePort] = entry.split(":", 2);
191
- if (rulePort && rulePort !== port) return false;
192
- return hostMatchesNoProxyEntry(hostname, ruleHost);
193
- });
194
- }
195
- function buildWebSocketOptions(wsUrl, env) {
196
- const proxyUrl = getProxyUrlForTarget(wsUrl, env);
197
- if (!proxyUrl) return void 0;
198
- if (shouldBypassProxy(wsUrl, env)) return void 0;
199
- return {
200
- agent: new HttpsProxyAgent(proxyUrl)
201
- };
202
- }
203
- function resolveProxyUrl(targetUrl, env) {
204
- const proxyUrl = getProxyUrlForTarget(targetUrl, env);
205
- if (!proxyUrl) return void 0;
206
- if (shouldBypassProxy(targetUrl, env)) return void 0;
207
- return proxyUrl;
208
- }
209
- function buildFetchDispatcher(targetUrl, env) {
210
- const proxyUrl = resolveProxyUrl(targetUrl, env);
211
- if (!proxyUrl) return void 0;
212
- const cached = fetchDispatcherCache.get(proxyUrl);
213
- if (cached) return cached;
214
- const timeoutMs = getFetchPreResponseTimeoutMs(env);
215
- const dispatcher = new ProxyAgent({
216
- uri: proxyUrl,
217
- // All three are pre-response and body-agnostic (see getFetchPreResponseTimeoutMs):
218
- // headersTimeout = headers-hang leg; requestTls.timeout = CONNECT-tunnel
219
- // establish leg; connect.timeout = socket to the proxy itself (defensive).
220
- connect: { timeout: timeoutMs },
221
- requestTls: { timeout: timeoutMs },
222
- headersTimeout: timeoutMs
223
- });
224
- fetchDispatcherCache.set(proxyUrl, dispatcher);
225
- return dispatcher;
226
- }
227
- function evictFetchDispatcher(targetUrl, env) {
228
- const proxyUrl = resolveProxyUrl(targetUrl, env);
229
- if (!proxyUrl) return false;
230
- const cached = fetchDispatcherCache.get(proxyUrl);
231
- if (!cached) return false;
232
- fetchDispatcherCache.delete(proxyUrl);
233
- void Promise.resolve().then(() => cached.close()).catch(() => cached.destroy?.(new Error("evicted"))).catch(() => {
234
- });
235
- return true;
236
- }
237
-
238
- // src/daemonFetch.ts
239
- function withDaemonFetchProxy(input, init = {}, env = process.env) {
240
- const dispatcher = buildFetchDispatcher(input.toString(), env);
241
- return dispatcher ? { ...init, dispatcher } : init;
242
- }
243
- async function daemonFetch(input, init, env = process.env) {
244
- try {
245
- return await fetch(input, withDaemonFetchProxy(input, init, env));
246
- } catch (err) {
247
- evictFetchDispatcher(input.toString(), env);
248
- throw err;
249
- }
250
- }
251
-
252
- export {
253
- subscribeDaemonLogs,
254
- logger,
255
- DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
256
- executeJsonRequest,
257
- executeResponseRequest,
258
- buildWebSocketOptions,
259
- daemonFetch
260
- };