@slock-ai/daemon 0.32.0 → 0.32.1

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.
Files changed (2) hide show
  1. package/dist/index.js +52 -1
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import { fileURLToPath } from "url";
10
10
 
11
11
  // src/connection.ts
12
12
  import WebSocket from "ws";
13
+ import { HttpsProxyAgent } from "https-proxy-agent";
13
14
 
14
15
  // src/logger.ts
15
16
  function timestamp() {
@@ -43,6 +44,52 @@ var systemClock = {
43
44
  clearTimeout: (timer) => clearTimeout(timer)
44
45
  };
45
46
  var INBOUND_WATCHDOG_MS = 7e4;
47
+ function getProxyUrlForWebSocket(wsUrl, env) {
48
+ const protocol = new URL(wsUrl).protocol;
49
+ if (protocol === "wss:") {
50
+ return env.WSS_PROXY || env.wss_proxy || env.HTTPS_PROXY || env.https_proxy || env.ALL_PROXY || env.all_proxy;
51
+ }
52
+ return env.WS_PROXY || env.ws_proxy || env.HTTP_PROXY || env.http_proxy || env.ALL_PROXY || env.all_proxy;
53
+ }
54
+ function getDefaultPort(protocol) {
55
+ switch (protocol) {
56
+ case "https:":
57
+ case "wss:":
58
+ return "443";
59
+ case "http:":
60
+ case "ws:":
61
+ return "80";
62
+ default:
63
+ return "";
64
+ }
65
+ }
66
+ function hostMatchesNoProxyEntry(hostname, ruleHost) {
67
+ if (!ruleHost) return false;
68
+ const normalizedRule = ruleHost.replace(/^\*\./, ".").replace(/^\./, "").toLowerCase();
69
+ const normalizedHost = hostname.toLowerCase();
70
+ return normalizedHost === normalizedRule || normalizedHost.endsWith(`.${normalizedRule}`);
71
+ }
72
+ function shouldBypassProxy(wsUrl, env) {
73
+ const rawNoProxy = env.NO_PROXY || env.no_proxy;
74
+ if (!rawNoProxy) return false;
75
+ const url = new URL(wsUrl);
76
+ const hostname = url.hostname.toLowerCase();
77
+ const port = url.port || getDefaultPort(url.protocol);
78
+ return rawNoProxy.split(",").map((entry) => entry.trim()).filter(Boolean).some((entry) => {
79
+ if (entry === "*") return true;
80
+ const [ruleHost, rulePort] = entry.split(":", 2);
81
+ if (rulePort && rulePort !== port) return false;
82
+ return hostMatchesNoProxyEntry(hostname, ruleHost);
83
+ });
84
+ }
85
+ function buildWebSocketOptions(wsUrl, env) {
86
+ const proxyUrl = getProxyUrlForWebSocket(wsUrl, env);
87
+ if (!proxyUrl) return void 0;
88
+ if (shouldBypassProxy(wsUrl, env)) return void 0;
89
+ return {
90
+ agent: new HttpsProxyAgent(proxyUrl)
91
+ };
92
+ }
46
93
  var DaemonConnection = class {
47
94
  ws = null;
48
95
  options;
@@ -96,8 +143,12 @@ var DaemonConnection = class {
96
143
  if (!this.shouldConnect) return;
97
144
  if (this.ws && this.ws.readyState !== WebSocket.CLOSED) return;
98
145
  const wsUrl = this.options.serverUrl.replace(/^http/, "ws") + `/daemon/connect?key=${this.options.apiKey}`;
146
+ const wsOptions = buildWebSocketOptions(wsUrl, this.options.proxyEnv ?? process.env);
99
147
  logger.info(`[Daemon] Connecting to ${this.options.serverUrl}...`);
100
- const ws = this.options.wsFactory ? this.options.wsFactory(wsUrl) : new WebSocket(wsUrl);
148
+ if (wsOptions?.agent) {
149
+ logger.info("[Daemon] Using configured proxy for WebSocket connection");
150
+ }
151
+ const ws = this.options.wsFactory ? this.options.wsFactory(wsUrl, wsOptions) : new WebSocket(wsUrl, wsOptions);
101
152
  this.ws = ws;
102
153
  ws.on("open", () => {
103
154
  if (this.ws !== ws) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slock-ai/daemon",
3
- "version": "0.32.0",
3
+ "version": "0.32.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "slock-daemon": "dist/index.js"
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@modelcontextprotocol/sdk": "^1.29.0",
21
+ "https-proxy-agent": "^7.0.6",
21
22
  "ws": "^8.20.0",
22
23
  "zod": "^4.3.6"
23
24
  },