@cydm/pie 2.1.0 → 2.1.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 (37) hide show
  1. package/README.md +6 -3
  2. package/dist/builtin/extensions/ask-user/index.js +1 -1
  3. package/dist/builtin/extensions/computer-use/index.js +3993 -107
  4. package/dist/builtin/extensions/plan-mode/index.js +1 -1
  5. package/dist/builtin/extensions/subagent/index.js +2 -2
  6. package/dist/builtin/extensions/todo/index.js +1 -1
  7. package/dist/builtin/skills/chrome-devtools-axi/LICENSE +21 -0
  8. package/dist/builtin/skills/chrome-devtools-axi/SKILL.md +20 -1
  9. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-bridge.js +20034 -0
  10. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-cli.js +8 -2
  11. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-runtime.js +26 -0
  12. package/dist/builtin/skills/chrome-devtools-axi/chunk-42SGITKJ.js +11 -0
  13. package/dist/builtin/skills/chrome-devtools-axi/chunk-OJ6N23UZ.js +47 -0
  14. package/dist/builtin/skills/chrome-devtools-axi/chunk-UPATXALW.js +215 -0
  15. package/dist/builtin/skills/chrome-devtools-axi/cli-F2VCSVL4.js +4424 -0
  16. package/dist/builtin/skills/skill-creator/SKILL.md +5 -2
  17. package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.mjs +7 -20
  18. package/dist/builtin/skills/skill-creator/eval-viewer/viewer.html +15 -15
  19. package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.mjs +20 -19
  20. package/dist/builtin/skills/skill-creator/scripts/generate_report.mjs +3 -3
  21. package/dist/builtin/skills/skill-creator/scripts/improve_description.mjs +12 -8
  22. package/dist/builtin/skills/skill-creator/scripts/package_skill.mjs +1 -0
  23. package/dist/builtin/skills/skill-creator/scripts/pie_runner.mjs +77 -31
  24. package/dist/builtin/skills/skill-creator/scripts/run_eval.mjs +38 -11
  25. package/dist/builtin/skills/skill-creator/scripts/run_loop.mjs +12 -6
  26. package/dist/builtin/skills/skill-creator/scripts/skill_metadata.mjs +12 -1
  27. package/dist/builtin/skills/tui-use/LICENSE +21 -0
  28. package/dist/builtin/skills/tui-use/README.md +13 -3
  29. package/dist/builtin/skills/tui-use/SKILL.md +87 -39
  30. package/dist/builtin/skills/tui-use/tui-use-cli.cjs +10608 -0
  31. package/dist/builtin/skills/tui-use/tui-use-cli.js +39 -0
  32. package/dist/builtin/skills/tui-use/tui-use-daemon.cjs +7916 -0
  33. package/dist/chunks/{chunk-PMPD56N2.js → chunk-LU7RKALH.js} +82 -24
  34. package/dist/chunks/{chunk-G2POWIA5.js → chunk-TJ2F4FL5.js} +64 -16
  35. package/dist/cli.js +7503 -87
  36. package/package.json +26 -18
  37. package/scripts/repair-node-pty.mjs +45 -0
@@ -5,16 +5,3703 @@ import {
5
5
  import {
6
6
  Type
7
7
  } from "../../../chunks/chunk-XXGYUYXI.js";
8
- import "../../../chunks/chunk-LZQXQOPJ.js";
8
+ import {
9
+ __commonJS,
10
+ __require,
11
+ __toESM
12
+ } from "../../../chunks/chunk-LZQXQOPJ.js";
13
+
14
+ // ../../node_modules/ws/lib/constants.js
15
+ var require_constants = __commonJS({
16
+ "../../node_modules/ws/lib/constants.js"(exports, module) {
17
+ "use strict";
18
+ var BINARY_TYPES = ["nodebuffer", "arraybuffer", "fragments"];
19
+ var hasBlob = typeof Blob !== "undefined";
20
+ if (hasBlob) BINARY_TYPES.push("blob");
21
+ module.exports = {
22
+ BINARY_TYPES,
23
+ CLOSE_TIMEOUT: 3e4,
24
+ EMPTY_BUFFER: Buffer.alloc(0),
25
+ GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
26
+ hasBlob,
27
+ kForOnEventAttribute: /* @__PURE__ */ Symbol("kIsForOnEventAttribute"),
28
+ kListener: /* @__PURE__ */ Symbol("kListener"),
29
+ kStatusCode: /* @__PURE__ */ Symbol("status-code"),
30
+ kWebSocket: /* @__PURE__ */ Symbol("websocket"),
31
+ NOOP: () => {
32
+ }
33
+ };
34
+ }
35
+ });
36
+
37
+ // ../../node_modules/ws/lib/buffer-util.js
38
+ var require_buffer_util = __commonJS({
39
+ "../../node_modules/ws/lib/buffer-util.js"(exports, module) {
40
+ "use strict";
41
+ var { EMPTY_BUFFER } = require_constants();
42
+ var FastBuffer = Buffer[Symbol.species];
43
+ function concat(list, totalLength) {
44
+ if (list.length === 0) return EMPTY_BUFFER;
45
+ if (list.length === 1) return list[0];
46
+ const target = Buffer.allocUnsafe(totalLength);
47
+ let offset = 0;
48
+ for (let i = 0; i < list.length; i++) {
49
+ const buf = list[i];
50
+ target.set(buf, offset);
51
+ offset += buf.length;
52
+ }
53
+ if (offset < totalLength) {
54
+ return new FastBuffer(target.buffer, target.byteOffset, offset);
55
+ }
56
+ return target;
57
+ }
58
+ function _mask(source, mask, output, offset, length) {
59
+ for (let i = 0; i < length; i++) {
60
+ output[offset + i] = source[i] ^ mask[i & 3];
61
+ }
62
+ }
63
+ function _unmask(buffer, mask) {
64
+ for (let i = 0; i < buffer.length; i++) {
65
+ buffer[i] ^= mask[i & 3];
66
+ }
67
+ }
68
+ function toArrayBuffer(buf) {
69
+ if (buf.length === buf.buffer.byteLength) {
70
+ return buf.buffer;
71
+ }
72
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
73
+ }
74
+ function toBuffer(data) {
75
+ toBuffer.readOnly = true;
76
+ if (Buffer.isBuffer(data)) return data;
77
+ let buf;
78
+ if (data instanceof ArrayBuffer) {
79
+ buf = new FastBuffer(data);
80
+ } else if (ArrayBuffer.isView(data)) {
81
+ buf = new FastBuffer(data.buffer, data.byteOffset, data.byteLength);
82
+ } else {
83
+ buf = Buffer.from(data);
84
+ toBuffer.readOnly = false;
85
+ }
86
+ return buf;
87
+ }
88
+ module.exports = {
89
+ concat,
90
+ mask: _mask,
91
+ toArrayBuffer,
92
+ toBuffer,
93
+ unmask: _unmask
94
+ };
95
+ if (!process.env.WS_NO_BUFFER_UTIL) {
96
+ try {
97
+ const bufferUtil = __require("bufferutil");
98
+ module.exports.mask = function(source, mask, output, offset, length) {
99
+ if (length < 48) _mask(source, mask, output, offset, length);
100
+ else bufferUtil.mask(source, mask, output, offset, length);
101
+ };
102
+ module.exports.unmask = function(buffer, mask) {
103
+ if (buffer.length < 32) _unmask(buffer, mask);
104
+ else bufferUtil.unmask(buffer, mask);
105
+ };
106
+ } catch (e) {
107
+ }
108
+ }
109
+ }
110
+ });
111
+
112
+ // ../../node_modules/ws/lib/limiter.js
113
+ var require_limiter = __commonJS({
114
+ "../../node_modules/ws/lib/limiter.js"(exports, module) {
115
+ "use strict";
116
+ var kDone = /* @__PURE__ */ Symbol("kDone");
117
+ var kRun = /* @__PURE__ */ Symbol("kRun");
118
+ var Limiter = class {
119
+ /**
120
+ * Creates a new `Limiter`.
121
+ *
122
+ * @param {Number} [concurrency=Infinity] The maximum number of jobs allowed
123
+ * to run concurrently
124
+ */
125
+ constructor(concurrency) {
126
+ this[kDone] = () => {
127
+ this.pending--;
128
+ this[kRun]();
129
+ };
130
+ this.concurrency = concurrency || Infinity;
131
+ this.jobs = [];
132
+ this.pending = 0;
133
+ }
134
+ /**
135
+ * Adds a job to the queue.
136
+ *
137
+ * @param {Function} job The job to run
138
+ * @public
139
+ */
140
+ add(job) {
141
+ this.jobs.push(job);
142
+ this[kRun]();
143
+ }
144
+ /**
145
+ * Removes a job from the queue and runs it if possible.
146
+ *
147
+ * @private
148
+ */
149
+ [kRun]() {
150
+ if (this.pending === this.concurrency) return;
151
+ if (this.jobs.length) {
152
+ const job = this.jobs.shift();
153
+ this.pending++;
154
+ job(this[kDone]);
155
+ }
156
+ }
157
+ };
158
+ module.exports = Limiter;
159
+ }
160
+ });
161
+
162
+ // ../../node_modules/ws/lib/permessage-deflate.js
163
+ var require_permessage_deflate = __commonJS({
164
+ "../../node_modules/ws/lib/permessage-deflate.js"(exports, module) {
165
+ "use strict";
166
+ var zlib = __require("zlib");
167
+ var bufferUtil = require_buffer_util();
168
+ var Limiter = require_limiter();
169
+ var { kStatusCode } = require_constants();
170
+ var FastBuffer = Buffer[Symbol.species];
171
+ var TRAILER = Buffer.from([0, 0, 255, 255]);
172
+ var kPerMessageDeflate = /* @__PURE__ */ Symbol("permessage-deflate");
173
+ var kTotalLength = /* @__PURE__ */ Symbol("total-length");
174
+ var kCallback = /* @__PURE__ */ Symbol("callback");
175
+ var kBuffers = /* @__PURE__ */ Symbol("buffers");
176
+ var kError = /* @__PURE__ */ Symbol("error");
177
+ var zlibLimiter;
178
+ var PerMessageDeflate2 = class {
179
+ /**
180
+ * Creates a PerMessageDeflate instance.
181
+ *
182
+ * @param {Object} [options] Configuration options
183
+ * @param {(Boolean|Number)} [options.clientMaxWindowBits] Advertise support
184
+ * for, or request, a custom client window size
185
+ * @param {Boolean} [options.clientNoContextTakeover=false] Advertise/
186
+ * acknowledge disabling of client context takeover
187
+ * @param {Number} [options.concurrencyLimit=10] The number of concurrent
188
+ * calls to zlib
189
+ * @param {Boolean} [options.isServer=false] Create the instance in either
190
+ * server or client mode
191
+ * @param {Number} [options.maxPayload=0] The maximum allowed message length
192
+ * @param {(Boolean|Number)} [options.serverMaxWindowBits] Request/confirm the
193
+ * use of a custom server window size
194
+ * @param {Boolean} [options.serverNoContextTakeover=false] Request/accept
195
+ * disabling of server context takeover
196
+ * @param {Number} [options.threshold=1024] Size (in bytes) below which
197
+ * messages should not be compressed if context takeover is disabled
198
+ * @param {Object} [options.zlibDeflateOptions] Options to pass to zlib on
199
+ * deflate
200
+ * @param {Object} [options.zlibInflateOptions] Options to pass to zlib on
201
+ * inflate
202
+ */
203
+ constructor(options) {
204
+ this._options = options || {};
205
+ this._threshold = this._options.threshold !== void 0 ? this._options.threshold : 1024;
206
+ this._maxPayload = this._options.maxPayload | 0;
207
+ this._isServer = !!this._options.isServer;
208
+ this._deflate = null;
209
+ this._inflate = null;
210
+ this.params = null;
211
+ if (!zlibLimiter) {
212
+ const concurrency = this._options.concurrencyLimit !== void 0 ? this._options.concurrencyLimit : 10;
213
+ zlibLimiter = new Limiter(concurrency);
214
+ }
215
+ }
216
+ /**
217
+ * @type {String}
218
+ */
219
+ static get extensionName() {
220
+ return "permessage-deflate";
221
+ }
222
+ /**
223
+ * Create an extension negotiation offer.
224
+ *
225
+ * @return {Object} Extension parameters
226
+ * @public
227
+ */
228
+ offer() {
229
+ const params = {};
230
+ if (this._options.serverNoContextTakeover) {
231
+ params.server_no_context_takeover = true;
232
+ }
233
+ if (this._options.clientNoContextTakeover) {
234
+ params.client_no_context_takeover = true;
235
+ }
236
+ if (this._options.serverMaxWindowBits) {
237
+ params.server_max_window_bits = this._options.serverMaxWindowBits;
238
+ }
239
+ if (this._options.clientMaxWindowBits) {
240
+ params.client_max_window_bits = this._options.clientMaxWindowBits;
241
+ } else if (this._options.clientMaxWindowBits == null) {
242
+ params.client_max_window_bits = true;
243
+ }
244
+ return params;
245
+ }
246
+ /**
247
+ * Accept an extension negotiation offer/response.
248
+ *
249
+ * @param {Array} configurations The extension negotiation offers/reponse
250
+ * @return {Object} Accepted configuration
251
+ * @public
252
+ */
253
+ accept(configurations) {
254
+ configurations = this.normalizeParams(configurations);
255
+ this.params = this._isServer ? this.acceptAsServer(configurations) : this.acceptAsClient(configurations);
256
+ return this.params;
257
+ }
258
+ /**
259
+ * Releases all resources used by the extension.
260
+ *
261
+ * @public
262
+ */
263
+ cleanup() {
264
+ if (this._inflate) {
265
+ this._inflate.close();
266
+ this._inflate = null;
267
+ }
268
+ if (this._deflate) {
269
+ const callback = this._deflate[kCallback];
270
+ this._deflate.close();
271
+ this._deflate = null;
272
+ if (callback) {
273
+ callback(
274
+ new Error(
275
+ "The deflate stream was closed while data was being processed"
276
+ )
277
+ );
278
+ }
279
+ }
280
+ }
281
+ /**
282
+ * Accept an extension negotiation offer.
283
+ *
284
+ * @param {Array} offers The extension negotiation offers
285
+ * @return {Object} Accepted configuration
286
+ * @private
287
+ */
288
+ acceptAsServer(offers) {
289
+ const opts = this._options;
290
+ const accepted = offers.find((params) => {
291
+ if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && (typeof params.client_max_window_bits === "number" ? opts.clientMaxWindowBits > params.client_max_window_bits : !params.client_max_window_bits)) {
292
+ return false;
293
+ }
294
+ return true;
295
+ });
296
+ if (!accepted) {
297
+ throw new Error("None of the extension offers can be accepted");
298
+ }
299
+ if (opts.serverNoContextTakeover) {
300
+ accepted.server_no_context_takeover = true;
301
+ }
302
+ if (opts.clientNoContextTakeover) {
303
+ accepted.client_no_context_takeover = true;
304
+ }
305
+ if (typeof opts.serverMaxWindowBits === "number") {
306
+ accepted.server_max_window_bits = opts.serverMaxWindowBits;
307
+ }
308
+ if (typeof opts.clientMaxWindowBits === "number") {
309
+ accepted.client_max_window_bits = opts.clientMaxWindowBits;
310
+ } else if (accepted.client_max_window_bits === true || opts.clientMaxWindowBits === false) {
311
+ delete accepted.client_max_window_bits;
312
+ }
313
+ return accepted;
314
+ }
315
+ /**
316
+ * Accept the extension negotiation response.
317
+ *
318
+ * @param {Array} response The extension negotiation response
319
+ * @return {Object} Accepted configuration
320
+ * @private
321
+ */
322
+ acceptAsClient(response) {
323
+ const params = response[0];
324
+ if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) {
325
+ throw new Error('Unexpected parameter "client_no_context_takeover"');
326
+ }
327
+ if (!params.client_max_window_bits) {
328
+ if (typeof this._options.clientMaxWindowBits === "number") {
329
+ params.client_max_window_bits = this._options.clientMaxWindowBits;
330
+ }
331
+ } else if (this._options.clientMaxWindowBits === false || typeof this._options.clientMaxWindowBits === "number" && params.client_max_window_bits > this._options.clientMaxWindowBits) {
332
+ throw new Error(
333
+ 'Unexpected or invalid parameter "client_max_window_bits"'
334
+ );
335
+ }
336
+ return params;
337
+ }
338
+ /**
339
+ * Normalize parameters.
340
+ *
341
+ * @param {Array} configurations The extension negotiation offers/reponse
342
+ * @return {Array} The offers/response with normalized parameters
343
+ * @private
344
+ */
345
+ normalizeParams(configurations) {
346
+ configurations.forEach((params) => {
347
+ Object.keys(params).forEach((key) => {
348
+ let value = params[key];
349
+ if (value.length > 1) {
350
+ throw new Error(`Parameter "${key}" must have only a single value`);
351
+ }
352
+ value = value[0];
353
+ if (key === "client_max_window_bits") {
354
+ if (value !== true) {
355
+ const num = +value;
356
+ if (!Number.isInteger(num) || num < 8 || num > 15) {
357
+ throw new TypeError(
358
+ `Invalid value for parameter "${key}": ${value}`
359
+ );
360
+ }
361
+ value = num;
362
+ } else if (!this._isServer) {
363
+ throw new TypeError(
364
+ `Invalid value for parameter "${key}": ${value}`
365
+ );
366
+ }
367
+ } else if (key === "server_max_window_bits") {
368
+ const num = +value;
369
+ if (!Number.isInteger(num) || num < 8 || num > 15) {
370
+ throw new TypeError(
371
+ `Invalid value for parameter "${key}": ${value}`
372
+ );
373
+ }
374
+ value = num;
375
+ } else if (key === "client_no_context_takeover" || key === "server_no_context_takeover") {
376
+ if (value !== true) {
377
+ throw new TypeError(
378
+ `Invalid value for parameter "${key}": ${value}`
379
+ );
380
+ }
381
+ } else {
382
+ throw new Error(`Unknown parameter "${key}"`);
383
+ }
384
+ params[key] = value;
385
+ });
386
+ });
387
+ return configurations;
388
+ }
389
+ /**
390
+ * Decompress data. Concurrency limited.
391
+ *
392
+ * @param {Buffer} data Compressed data
393
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
394
+ * @param {Function} callback Callback
395
+ * @public
396
+ */
397
+ decompress(data, fin, callback) {
398
+ zlibLimiter.add((done) => {
399
+ this._decompress(data, fin, (err, result) => {
400
+ done();
401
+ callback(err, result);
402
+ });
403
+ });
404
+ }
405
+ /**
406
+ * Compress data. Concurrency limited.
407
+ *
408
+ * @param {(Buffer|String)} data Data to compress
409
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
410
+ * @param {Function} callback Callback
411
+ * @public
412
+ */
413
+ compress(data, fin, callback) {
414
+ zlibLimiter.add((done) => {
415
+ this._compress(data, fin, (err, result) => {
416
+ done();
417
+ callback(err, result);
418
+ });
419
+ });
420
+ }
421
+ /**
422
+ * Decompress data.
423
+ *
424
+ * @param {Buffer} data Compressed data
425
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
426
+ * @param {Function} callback Callback
427
+ * @private
428
+ */
429
+ _decompress(data, fin, callback) {
430
+ const endpoint = this._isServer ? "client" : "server";
431
+ if (!this._inflate) {
432
+ const key = `${endpoint}_max_window_bits`;
433
+ const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
434
+ this._inflate = zlib.createInflateRaw({
435
+ ...this._options.zlibInflateOptions,
436
+ windowBits
437
+ });
438
+ this._inflate[kPerMessageDeflate] = this;
439
+ this._inflate[kTotalLength] = 0;
440
+ this._inflate[kBuffers] = [];
441
+ this._inflate.on("error", inflateOnError);
442
+ this._inflate.on("data", inflateOnData);
443
+ }
444
+ this._inflate[kCallback] = callback;
445
+ this._inflate.write(data);
446
+ if (fin) this._inflate.write(TRAILER);
447
+ this._inflate.flush(() => {
448
+ const err = this._inflate[kError];
449
+ if (err) {
450
+ this._inflate.close();
451
+ this._inflate = null;
452
+ callback(err);
453
+ return;
454
+ }
455
+ const data2 = bufferUtil.concat(
456
+ this._inflate[kBuffers],
457
+ this._inflate[kTotalLength]
458
+ );
459
+ if (this._inflate._readableState.endEmitted) {
460
+ this._inflate.close();
461
+ this._inflate = null;
462
+ } else {
463
+ this._inflate[kTotalLength] = 0;
464
+ this._inflate[kBuffers] = [];
465
+ if (fin && this.params[`${endpoint}_no_context_takeover`]) {
466
+ this._inflate.reset();
467
+ }
468
+ }
469
+ callback(null, data2);
470
+ });
471
+ }
472
+ /**
473
+ * Compress data.
474
+ *
475
+ * @param {(Buffer|String)} data Data to compress
476
+ * @param {Boolean} fin Specifies whether or not this is the last fragment
477
+ * @param {Function} callback Callback
478
+ * @private
479
+ */
480
+ _compress(data, fin, callback) {
481
+ const endpoint = this._isServer ? "server" : "client";
482
+ if (!this._deflate) {
483
+ const key = `${endpoint}_max_window_bits`;
484
+ const windowBits = typeof this.params[key] !== "number" ? zlib.Z_DEFAULT_WINDOWBITS : this.params[key];
485
+ this._deflate = zlib.createDeflateRaw({
486
+ ...this._options.zlibDeflateOptions,
487
+ windowBits
488
+ });
489
+ this._deflate[kTotalLength] = 0;
490
+ this._deflate[kBuffers] = [];
491
+ this._deflate.on("data", deflateOnData);
492
+ }
493
+ this._deflate[kCallback] = callback;
494
+ this._deflate.write(data);
495
+ this._deflate.flush(zlib.Z_SYNC_FLUSH, () => {
496
+ if (!this._deflate) {
497
+ return;
498
+ }
499
+ let data2 = bufferUtil.concat(
500
+ this._deflate[kBuffers],
501
+ this._deflate[kTotalLength]
502
+ );
503
+ if (fin) {
504
+ data2 = new FastBuffer(data2.buffer, data2.byteOffset, data2.length - 4);
505
+ }
506
+ this._deflate[kCallback] = null;
507
+ this._deflate[kTotalLength] = 0;
508
+ this._deflate[kBuffers] = [];
509
+ if (fin && this.params[`${endpoint}_no_context_takeover`]) {
510
+ this._deflate.reset();
511
+ }
512
+ callback(null, data2);
513
+ });
514
+ }
515
+ };
516
+ module.exports = PerMessageDeflate2;
517
+ function deflateOnData(chunk) {
518
+ this[kBuffers].push(chunk);
519
+ this[kTotalLength] += chunk.length;
520
+ }
521
+ function inflateOnData(chunk) {
522
+ this[kTotalLength] += chunk.length;
523
+ if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) {
524
+ this[kBuffers].push(chunk);
525
+ return;
526
+ }
527
+ this[kError] = new RangeError("Max payload size exceeded");
528
+ this[kError].code = "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH";
529
+ this[kError][kStatusCode] = 1009;
530
+ this.removeListener("data", inflateOnData);
531
+ this.reset();
532
+ }
533
+ function inflateOnError(err) {
534
+ this[kPerMessageDeflate]._inflate = null;
535
+ if (this[kError]) {
536
+ this[kCallback](this[kError]);
537
+ return;
538
+ }
539
+ err[kStatusCode] = 1007;
540
+ this[kCallback](err);
541
+ }
542
+ }
543
+ });
544
+
545
+ // ../../node_modules/ws/lib/validation.js
546
+ var require_validation = __commonJS({
547
+ "../../node_modules/ws/lib/validation.js"(exports, module) {
548
+ "use strict";
549
+ var { isUtf8 } = __require("buffer");
550
+ var { hasBlob } = require_constants();
551
+ var tokenChars = [
552
+ 0,
553
+ 0,
554
+ 0,
555
+ 0,
556
+ 0,
557
+ 0,
558
+ 0,
559
+ 0,
560
+ 0,
561
+ 0,
562
+ 0,
563
+ 0,
564
+ 0,
565
+ 0,
566
+ 0,
567
+ 0,
568
+ // 0 - 15
569
+ 0,
570
+ 0,
571
+ 0,
572
+ 0,
573
+ 0,
574
+ 0,
575
+ 0,
576
+ 0,
577
+ 0,
578
+ 0,
579
+ 0,
580
+ 0,
581
+ 0,
582
+ 0,
583
+ 0,
584
+ 0,
585
+ // 16 - 31
586
+ 0,
587
+ 1,
588
+ 0,
589
+ 1,
590
+ 1,
591
+ 1,
592
+ 1,
593
+ 1,
594
+ 0,
595
+ 0,
596
+ 1,
597
+ 1,
598
+ 0,
599
+ 1,
600
+ 1,
601
+ 0,
602
+ // 32 - 47
603
+ 1,
604
+ 1,
605
+ 1,
606
+ 1,
607
+ 1,
608
+ 1,
609
+ 1,
610
+ 1,
611
+ 1,
612
+ 1,
613
+ 0,
614
+ 0,
615
+ 0,
616
+ 0,
617
+ 0,
618
+ 0,
619
+ // 48 - 63
620
+ 0,
621
+ 1,
622
+ 1,
623
+ 1,
624
+ 1,
625
+ 1,
626
+ 1,
627
+ 1,
628
+ 1,
629
+ 1,
630
+ 1,
631
+ 1,
632
+ 1,
633
+ 1,
634
+ 1,
635
+ 1,
636
+ // 64 - 79
637
+ 1,
638
+ 1,
639
+ 1,
640
+ 1,
641
+ 1,
642
+ 1,
643
+ 1,
644
+ 1,
645
+ 1,
646
+ 1,
647
+ 1,
648
+ 0,
649
+ 0,
650
+ 0,
651
+ 1,
652
+ 1,
653
+ // 80 - 95
654
+ 1,
655
+ 1,
656
+ 1,
657
+ 1,
658
+ 1,
659
+ 1,
660
+ 1,
661
+ 1,
662
+ 1,
663
+ 1,
664
+ 1,
665
+ 1,
666
+ 1,
667
+ 1,
668
+ 1,
669
+ 1,
670
+ // 96 - 111
671
+ 1,
672
+ 1,
673
+ 1,
674
+ 1,
675
+ 1,
676
+ 1,
677
+ 1,
678
+ 1,
679
+ 1,
680
+ 1,
681
+ 1,
682
+ 0,
683
+ 1,
684
+ 0,
685
+ 1,
686
+ 0
687
+ // 112 - 127
688
+ ];
689
+ function isValidStatusCode(code) {
690
+ return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999;
691
+ }
692
+ function _isValidUTF8(buf) {
693
+ const len = buf.length;
694
+ let i = 0;
695
+ while (i < len) {
696
+ if ((buf[i] & 128) === 0) {
697
+ i++;
698
+ } else if ((buf[i] & 224) === 192) {
699
+ if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) {
700
+ return false;
701
+ }
702
+ i += 2;
703
+ } else if ((buf[i] & 240) === 224) {
704
+ if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || // Overlong
705
+ buf[i] === 237 && (buf[i + 1] & 224) === 160) {
706
+ return false;
707
+ }
708
+ i += 3;
709
+ } else if ((buf[i] & 248) === 240) {
710
+ if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || // Overlong
711
+ buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) {
712
+ return false;
713
+ }
714
+ i += 4;
715
+ } else {
716
+ return false;
717
+ }
718
+ }
719
+ return true;
720
+ }
721
+ function isBlob(value) {
722
+ return hasBlob && typeof value === "object" && typeof value.arrayBuffer === "function" && typeof value.type === "string" && typeof value.stream === "function" && (value[Symbol.toStringTag] === "Blob" || value[Symbol.toStringTag] === "File");
723
+ }
724
+ module.exports = {
725
+ isBlob,
726
+ isValidStatusCode,
727
+ isValidUTF8: _isValidUTF8,
728
+ tokenChars
729
+ };
730
+ if (isUtf8) {
731
+ module.exports.isValidUTF8 = function(buf) {
732
+ return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);
733
+ };
734
+ } else if (!process.env.WS_NO_UTF_8_VALIDATE) {
735
+ try {
736
+ const isValidUTF8 = __require("utf-8-validate");
737
+ module.exports.isValidUTF8 = function(buf) {
738
+ return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);
739
+ };
740
+ } catch (e) {
741
+ }
742
+ }
743
+ }
744
+ });
745
+
746
+ // ../../node_modules/ws/lib/receiver.js
747
+ var require_receiver = __commonJS({
748
+ "../../node_modules/ws/lib/receiver.js"(exports, module) {
749
+ "use strict";
750
+ var { Writable } = __require("stream");
751
+ var PerMessageDeflate2 = require_permessage_deflate();
752
+ var {
753
+ BINARY_TYPES,
754
+ EMPTY_BUFFER,
755
+ kStatusCode,
756
+ kWebSocket
757
+ } = require_constants();
758
+ var { concat, toArrayBuffer, unmask } = require_buffer_util();
759
+ var { isValidStatusCode, isValidUTF8 } = require_validation();
760
+ var FastBuffer = Buffer[Symbol.species];
761
+ var GET_INFO = 0;
762
+ var GET_PAYLOAD_LENGTH_16 = 1;
763
+ var GET_PAYLOAD_LENGTH_64 = 2;
764
+ var GET_MASK = 3;
765
+ var GET_DATA = 4;
766
+ var INFLATING = 5;
767
+ var DEFER_EVENT = 6;
768
+ var Receiver2 = class extends Writable {
769
+ /**
770
+ * Creates a Receiver instance.
771
+ *
772
+ * @param {Object} [options] Options object
773
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
774
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
775
+ * multiple times in the same tick
776
+ * @param {String} [options.binaryType=nodebuffer] The type for binary data
777
+ * @param {Object} [options.extensions] An object containing the negotiated
778
+ * extensions
779
+ * @param {Boolean} [options.isServer=false] Specifies whether to operate in
780
+ * client or server mode
781
+ * @param {Number} [options.maxBufferedChunks=0] The maximum number of
782
+ * buffered data chunks
783
+ * @param {Number} [options.maxFragments=0] The maximum number of message
784
+ * fragments
785
+ * @param {Number} [options.maxPayload=0] The maximum allowed message length
786
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
787
+ * not to skip UTF-8 validation for text and close messages
788
+ */
789
+ constructor(options = {}) {
790
+ super();
791
+ this._allowSynchronousEvents = options.allowSynchronousEvents !== void 0 ? options.allowSynchronousEvents : true;
792
+ this._binaryType = options.binaryType || BINARY_TYPES[0];
793
+ this._extensions = options.extensions || {};
794
+ this._isServer = !!options.isServer;
795
+ this._maxBufferedChunks = options.maxBufferedChunks | 0;
796
+ this._maxFragments = options.maxFragments | 0;
797
+ this._maxPayload = options.maxPayload | 0;
798
+ this._skipUTF8Validation = !!options.skipUTF8Validation;
799
+ this[kWebSocket] = void 0;
800
+ this._bufferedBytes = 0;
801
+ this._buffers = [];
802
+ this._compressed = false;
803
+ this._payloadLength = 0;
804
+ this._mask = void 0;
805
+ this._fragmented = 0;
806
+ this._masked = false;
807
+ this._fin = false;
808
+ this._opcode = 0;
809
+ this._totalPayloadLength = 0;
810
+ this._messageLength = 0;
811
+ this._numFragments = 0;
812
+ this._fragments = [];
813
+ this._errored = false;
814
+ this._loop = false;
815
+ this._state = GET_INFO;
816
+ }
817
+ /**
818
+ * Implements `Writable.prototype._write()`.
819
+ *
820
+ * @param {Buffer} chunk The chunk of data to write
821
+ * @param {String} encoding The character encoding of `chunk`
822
+ * @param {Function} cb Callback
823
+ * @private
824
+ */
825
+ _write(chunk, encoding, cb) {
826
+ if (this._opcode === 8 && this._state == GET_INFO) return cb();
827
+ if (this._maxBufferedChunks > 0 && this._buffers.length >= this._maxBufferedChunks) {
828
+ cb(
829
+ this.createError(
830
+ RangeError,
831
+ "Too many buffered chunks",
832
+ false,
833
+ 1008,
834
+ "WS_ERR_TOO_MANY_BUFFERED_PARTS"
835
+ )
836
+ );
837
+ return;
838
+ }
839
+ this._bufferedBytes += chunk.length;
840
+ this._buffers.push(chunk);
841
+ this.startLoop(cb);
842
+ }
843
+ /**
844
+ * Consumes `n` bytes from the buffered data.
845
+ *
846
+ * @param {Number} n The number of bytes to consume
847
+ * @return {Buffer} The consumed bytes
848
+ * @private
849
+ */
850
+ consume(n) {
851
+ this._bufferedBytes -= n;
852
+ if (n === this._buffers[0].length) return this._buffers.shift();
853
+ if (n < this._buffers[0].length) {
854
+ const buf = this._buffers[0];
855
+ this._buffers[0] = new FastBuffer(
856
+ buf.buffer,
857
+ buf.byteOffset + n,
858
+ buf.length - n
859
+ );
860
+ return new FastBuffer(buf.buffer, buf.byteOffset, n);
861
+ }
862
+ const dst = Buffer.allocUnsafe(n);
863
+ do {
864
+ const buf = this._buffers[0];
865
+ const offset = dst.length - n;
866
+ if (n >= buf.length) {
867
+ dst.set(this._buffers.shift(), offset);
868
+ } else {
869
+ dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
870
+ this._buffers[0] = new FastBuffer(
871
+ buf.buffer,
872
+ buf.byteOffset + n,
873
+ buf.length - n
874
+ );
875
+ }
876
+ n -= buf.length;
877
+ } while (n > 0);
878
+ return dst;
879
+ }
880
+ /**
881
+ * Starts the parsing loop.
882
+ *
883
+ * @param {Function} cb Callback
884
+ * @private
885
+ */
886
+ startLoop(cb) {
887
+ this._loop = true;
888
+ do {
889
+ switch (this._state) {
890
+ case GET_INFO:
891
+ this.getInfo(cb);
892
+ break;
893
+ case GET_PAYLOAD_LENGTH_16:
894
+ this.getPayloadLength16(cb);
895
+ break;
896
+ case GET_PAYLOAD_LENGTH_64:
897
+ this.getPayloadLength64(cb);
898
+ break;
899
+ case GET_MASK:
900
+ this.getMask();
901
+ break;
902
+ case GET_DATA:
903
+ this.getData(cb);
904
+ break;
905
+ case INFLATING:
906
+ case DEFER_EVENT:
907
+ this._loop = false;
908
+ return;
909
+ }
910
+ } while (this._loop);
911
+ if (!this._errored) cb();
912
+ }
913
+ /**
914
+ * Reads the first two bytes of a frame.
915
+ *
916
+ * @param {Function} cb Callback
917
+ * @private
918
+ */
919
+ getInfo(cb) {
920
+ if (this._bufferedBytes < 2) {
921
+ this._loop = false;
922
+ return;
923
+ }
924
+ const buf = this.consume(2);
925
+ if ((buf[0] & 48) !== 0) {
926
+ const error = this.createError(
927
+ RangeError,
928
+ "RSV2 and RSV3 must be clear",
929
+ true,
930
+ 1002,
931
+ "WS_ERR_UNEXPECTED_RSV_2_3"
932
+ );
933
+ cb(error);
934
+ return;
935
+ }
936
+ const compressed = (buf[0] & 64) === 64;
937
+ if (compressed && !this._extensions[PerMessageDeflate2.extensionName]) {
938
+ const error = this.createError(
939
+ RangeError,
940
+ "RSV1 must be clear",
941
+ true,
942
+ 1002,
943
+ "WS_ERR_UNEXPECTED_RSV_1"
944
+ );
945
+ cb(error);
946
+ return;
947
+ }
948
+ this._fin = (buf[0] & 128) === 128;
949
+ this._opcode = buf[0] & 15;
950
+ this._payloadLength = buf[1] & 127;
951
+ if (this._opcode === 0) {
952
+ if (compressed) {
953
+ const error = this.createError(
954
+ RangeError,
955
+ "RSV1 must be clear",
956
+ true,
957
+ 1002,
958
+ "WS_ERR_UNEXPECTED_RSV_1"
959
+ );
960
+ cb(error);
961
+ return;
962
+ }
963
+ if (!this._fragmented) {
964
+ const error = this.createError(
965
+ RangeError,
966
+ "invalid opcode 0",
967
+ true,
968
+ 1002,
969
+ "WS_ERR_INVALID_OPCODE"
970
+ );
971
+ cb(error);
972
+ return;
973
+ }
974
+ this._opcode = this._fragmented;
975
+ } else if (this._opcode === 1 || this._opcode === 2) {
976
+ if (this._fragmented) {
977
+ const error = this.createError(
978
+ RangeError,
979
+ `invalid opcode ${this._opcode}`,
980
+ true,
981
+ 1002,
982
+ "WS_ERR_INVALID_OPCODE"
983
+ );
984
+ cb(error);
985
+ return;
986
+ }
987
+ this._compressed = compressed;
988
+ } else if (this._opcode > 7 && this._opcode < 11) {
989
+ if (!this._fin) {
990
+ const error = this.createError(
991
+ RangeError,
992
+ "FIN must be set",
993
+ true,
994
+ 1002,
995
+ "WS_ERR_EXPECTED_FIN"
996
+ );
997
+ cb(error);
998
+ return;
999
+ }
1000
+ if (compressed) {
1001
+ const error = this.createError(
1002
+ RangeError,
1003
+ "RSV1 must be clear",
1004
+ true,
1005
+ 1002,
1006
+ "WS_ERR_UNEXPECTED_RSV_1"
1007
+ );
1008
+ cb(error);
1009
+ return;
1010
+ }
1011
+ if (this._payloadLength > 125 || this._opcode === 8 && this._payloadLength === 1) {
1012
+ const error = this.createError(
1013
+ RangeError,
1014
+ `invalid payload length ${this._payloadLength}`,
1015
+ true,
1016
+ 1002,
1017
+ "WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH"
1018
+ );
1019
+ cb(error);
1020
+ return;
1021
+ }
1022
+ } else {
1023
+ const error = this.createError(
1024
+ RangeError,
1025
+ `invalid opcode ${this._opcode}`,
1026
+ true,
1027
+ 1002,
1028
+ "WS_ERR_INVALID_OPCODE"
1029
+ );
1030
+ cb(error);
1031
+ return;
1032
+ }
1033
+ if (!this._fin && !this._fragmented) this._fragmented = this._opcode;
1034
+ this._masked = (buf[1] & 128) === 128;
1035
+ if (this._isServer) {
1036
+ if (!this._masked) {
1037
+ const error = this.createError(
1038
+ RangeError,
1039
+ "MASK must be set",
1040
+ true,
1041
+ 1002,
1042
+ "WS_ERR_EXPECTED_MASK"
1043
+ );
1044
+ cb(error);
1045
+ return;
1046
+ }
1047
+ } else if (this._masked) {
1048
+ const error = this.createError(
1049
+ RangeError,
1050
+ "MASK must be clear",
1051
+ true,
1052
+ 1002,
1053
+ "WS_ERR_UNEXPECTED_MASK"
1054
+ );
1055
+ cb(error);
1056
+ return;
1057
+ }
1058
+ if (this._payloadLength === 126) this._state = GET_PAYLOAD_LENGTH_16;
1059
+ else if (this._payloadLength === 127) this._state = GET_PAYLOAD_LENGTH_64;
1060
+ else this.haveLength(cb);
1061
+ }
1062
+ /**
1063
+ * Gets extended payload length (7+16).
1064
+ *
1065
+ * @param {Function} cb Callback
1066
+ * @private
1067
+ */
1068
+ getPayloadLength16(cb) {
1069
+ if (this._bufferedBytes < 2) {
1070
+ this._loop = false;
1071
+ return;
1072
+ }
1073
+ this._payloadLength = this.consume(2).readUInt16BE(0);
1074
+ this.haveLength(cb);
1075
+ }
1076
+ /**
1077
+ * Gets extended payload length (7+64).
1078
+ *
1079
+ * @param {Function} cb Callback
1080
+ * @private
1081
+ */
1082
+ getPayloadLength64(cb) {
1083
+ if (this._bufferedBytes < 8) {
1084
+ this._loop = false;
1085
+ return;
1086
+ }
1087
+ const buf = this.consume(8);
1088
+ const num = buf.readUInt32BE(0);
1089
+ if (num > Math.pow(2, 53 - 32) - 1) {
1090
+ const error = this.createError(
1091
+ RangeError,
1092
+ "Unsupported WebSocket frame: payload length > 2^53 - 1",
1093
+ false,
1094
+ 1009,
1095
+ "WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH"
1096
+ );
1097
+ cb(error);
1098
+ return;
1099
+ }
1100
+ this._payloadLength = num * Math.pow(2, 32) + buf.readUInt32BE(4);
1101
+ this.haveLength(cb);
1102
+ }
1103
+ /**
1104
+ * Payload length has been read.
1105
+ *
1106
+ * @param {Function} cb Callback
1107
+ * @private
1108
+ */
1109
+ haveLength(cb) {
1110
+ if (this._payloadLength && this._opcode < 8) {
1111
+ this._totalPayloadLength += this._payloadLength;
1112
+ if (this._totalPayloadLength > this._maxPayload && this._maxPayload > 0) {
1113
+ const error = this.createError(
1114
+ RangeError,
1115
+ "Max payload size exceeded",
1116
+ false,
1117
+ 1009,
1118
+ "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"
1119
+ );
1120
+ cb(error);
1121
+ return;
1122
+ }
1123
+ }
1124
+ if (this._masked) this._state = GET_MASK;
1125
+ else this._state = GET_DATA;
1126
+ }
1127
+ /**
1128
+ * Reads mask bytes.
1129
+ *
1130
+ * @private
1131
+ */
1132
+ getMask() {
1133
+ if (this._bufferedBytes < 4) {
1134
+ this._loop = false;
1135
+ return;
1136
+ }
1137
+ this._mask = this.consume(4);
1138
+ this._state = GET_DATA;
1139
+ }
1140
+ /**
1141
+ * Reads data bytes.
1142
+ *
1143
+ * @param {Function} cb Callback
1144
+ * @private
1145
+ */
1146
+ getData(cb) {
1147
+ let data = EMPTY_BUFFER;
1148
+ if (this._payloadLength) {
1149
+ if (this._bufferedBytes < this._payloadLength) {
1150
+ this._loop = false;
1151
+ return;
1152
+ }
1153
+ data = this.consume(this._payloadLength);
1154
+ if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) {
1155
+ unmask(data, this._mask);
1156
+ }
1157
+ }
1158
+ if (this._opcode > 7) {
1159
+ this.controlMessage(data, cb);
1160
+ return;
1161
+ }
1162
+ if (this._maxFragments > 0 && ++this._numFragments > this._maxFragments) {
1163
+ const error = this.createError(
1164
+ RangeError,
1165
+ "Too many message fragments",
1166
+ false,
1167
+ 1008,
1168
+ "WS_ERR_TOO_MANY_BUFFERED_PARTS"
1169
+ );
1170
+ cb(error);
1171
+ return;
1172
+ }
1173
+ if (this._compressed) {
1174
+ this._state = INFLATING;
1175
+ this.decompress(data, cb);
1176
+ return;
1177
+ }
1178
+ if (data.length) {
1179
+ this._messageLength = this._totalPayloadLength;
1180
+ this._fragments.push(data);
1181
+ }
1182
+ this.dataMessage(cb);
1183
+ }
1184
+ /**
1185
+ * Decompresses data.
1186
+ *
1187
+ * @param {Buffer} data Compressed data
1188
+ * @param {Function} cb Callback
1189
+ * @private
1190
+ */
1191
+ decompress(data, cb) {
1192
+ const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
1193
+ perMessageDeflate.decompress(data, this._fin, (err, buf) => {
1194
+ if (err) return cb(err);
1195
+ if (buf.length) {
1196
+ this._messageLength += buf.length;
1197
+ if (this._messageLength > this._maxPayload && this._maxPayload > 0) {
1198
+ const error = this.createError(
1199
+ RangeError,
1200
+ "Max payload size exceeded",
1201
+ false,
1202
+ 1009,
1203
+ "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH"
1204
+ );
1205
+ cb(error);
1206
+ return;
1207
+ }
1208
+ this._fragments.push(buf);
1209
+ }
1210
+ this.dataMessage(cb);
1211
+ if (this._state === GET_INFO) this.startLoop(cb);
1212
+ });
1213
+ }
1214
+ /**
1215
+ * Handles a data message.
1216
+ *
1217
+ * @param {Function} cb Callback
1218
+ * @private
1219
+ */
1220
+ dataMessage(cb) {
1221
+ if (!this._fin) {
1222
+ this._state = GET_INFO;
1223
+ return;
1224
+ }
1225
+ const messageLength = this._messageLength;
1226
+ const fragments = this._fragments;
1227
+ this._totalPayloadLength = 0;
1228
+ this._messageLength = 0;
1229
+ this._fragmented = 0;
1230
+ this._numFragments = 0;
1231
+ this._fragments = [];
1232
+ if (this._opcode === 2) {
1233
+ let data;
1234
+ if (this._binaryType === "nodebuffer") {
1235
+ data = concat(fragments, messageLength);
1236
+ } else if (this._binaryType === "arraybuffer") {
1237
+ data = toArrayBuffer(concat(fragments, messageLength));
1238
+ } else if (this._binaryType === "blob") {
1239
+ data = new Blob(fragments);
1240
+ } else {
1241
+ data = fragments;
1242
+ }
1243
+ if (this._allowSynchronousEvents) {
1244
+ this.emit("message", data, true);
1245
+ this._state = GET_INFO;
1246
+ } else {
1247
+ this._state = DEFER_EVENT;
1248
+ setImmediate(() => {
1249
+ this.emit("message", data, true);
1250
+ this._state = GET_INFO;
1251
+ this.startLoop(cb);
1252
+ });
1253
+ }
1254
+ } else {
1255
+ const buf = concat(fragments, messageLength);
1256
+ if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
1257
+ const error = this.createError(
1258
+ Error,
1259
+ "invalid UTF-8 sequence",
1260
+ true,
1261
+ 1007,
1262
+ "WS_ERR_INVALID_UTF8"
1263
+ );
1264
+ cb(error);
1265
+ return;
1266
+ }
1267
+ if (this._state === INFLATING || this._allowSynchronousEvents) {
1268
+ this.emit("message", buf, false);
1269
+ this._state = GET_INFO;
1270
+ } else {
1271
+ this._state = DEFER_EVENT;
1272
+ setImmediate(() => {
1273
+ this.emit("message", buf, false);
1274
+ this._state = GET_INFO;
1275
+ this.startLoop(cb);
1276
+ });
1277
+ }
1278
+ }
1279
+ }
1280
+ /**
1281
+ * Handles a control message.
1282
+ *
1283
+ * @param {Buffer} data Data to handle
1284
+ * @return {(Error|RangeError|undefined)} A possible error
1285
+ * @private
1286
+ */
1287
+ controlMessage(data, cb) {
1288
+ if (this._opcode === 8) {
1289
+ if (data.length === 0) {
1290
+ this._loop = false;
1291
+ this.emit("conclude", 1005, EMPTY_BUFFER);
1292
+ this.end();
1293
+ } else {
1294
+ const code = data.readUInt16BE(0);
1295
+ if (!isValidStatusCode(code)) {
1296
+ const error = this.createError(
1297
+ RangeError,
1298
+ `invalid status code ${code}`,
1299
+ true,
1300
+ 1002,
1301
+ "WS_ERR_INVALID_CLOSE_CODE"
1302
+ );
1303
+ cb(error);
1304
+ return;
1305
+ }
1306
+ const buf = new FastBuffer(
1307
+ data.buffer,
1308
+ data.byteOffset + 2,
1309
+ data.length - 2
1310
+ );
1311
+ if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
1312
+ const error = this.createError(
1313
+ Error,
1314
+ "invalid UTF-8 sequence",
1315
+ true,
1316
+ 1007,
1317
+ "WS_ERR_INVALID_UTF8"
1318
+ );
1319
+ cb(error);
1320
+ return;
1321
+ }
1322
+ this._loop = false;
1323
+ this.emit("conclude", code, buf);
1324
+ this.end();
1325
+ }
1326
+ this._state = GET_INFO;
1327
+ return;
1328
+ }
1329
+ if (this._allowSynchronousEvents) {
1330
+ this.emit(this._opcode === 9 ? "ping" : "pong", data);
1331
+ this._state = GET_INFO;
1332
+ } else {
1333
+ this._state = DEFER_EVENT;
1334
+ setImmediate(() => {
1335
+ this.emit(this._opcode === 9 ? "ping" : "pong", data);
1336
+ this._state = GET_INFO;
1337
+ this.startLoop(cb);
1338
+ });
1339
+ }
1340
+ }
1341
+ /**
1342
+ * Builds an error object.
1343
+ *
1344
+ * @param {function(new:Error|RangeError)} ErrorCtor The error constructor
1345
+ * @param {String} message The error message
1346
+ * @param {Boolean} prefix Specifies whether or not to add a default prefix to
1347
+ * `message`
1348
+ * @param {Number} statusCode The status code
1349
+ * @param {String} errorCode The exposed error code
1350
+ * @return {(Error|RangeError)} The error
1351
+ * @private
1352
+ */
1353
+ createError(ErrorCtor, message, prefix, statusCode, errorCode) {
1354
+ this._loop = false;
1355
+ this._errored = true;
1356
+ const err = new ErrorCtor(
1357
+ prefix ? `Invalid WebSocket frame: ${message}` : message
1358
+ );
1359
+ Error.captureStackTrace(err, this.createError);
1360
+ err.code = errorCode;
1361
+ err[kStatusCode] = statusCode;
1362
+ return err;
1363
+ }
1364
+ };
1365
+ module.exports = Receiver2;
1366
+ }
1367
+ });
1368
+
1369
+ // ../../node_modules/ws/lib/sender.js
1370
+ var require_sender = __commonJS({
1371
+ "../../node_modules/ws/lib/sender.js"(exports, module) {
1372
+ "use strict";
1373
+ var { Duplex } = __require("stream");
1374
+ var { randomFillSync } = __require("crypto");
1375
+ var {
1376
+ types: { isUint8Array }
1377
+ } = __require("util");
1378
+ var PerMessageDeflate2 = require_permessage_deflate();
1379
+ var { EMPTY_BUFFER, kWebSocket, NOOP } = require_constants();
1380
+ var { isBlob, isValidStatusCode } = require_validation();
1381
+ var { mask: applyMask, toBuffer } = require_buffer_util();
1382
+ var kByteLength = /* @__PURE__ */ Symbol("kByteLength");
1383
+ var maskBuffer = Buffer.alloc(4);
1384
+ var RANDOM_POOL_SIZE = 8 * 1024;
1385
+ var randomPool;
1386
+ var randomPoolPointer = RANDOM_POOL_SIZE;
1387
+ var DEFAULT = 0;
1388
+ var DEFLATING = 1;
1389
+ var GET_BLOB_DATA = 2;
1390
+ var Sender2 = class _Sender {
1391
+ /**
1392
+ * Creates a Sender instance.
1393
+ *
1394
+ * @param {Duplex} socket The connection socket
1395
+ * @param {Object} [extensions] An object containing the negotiated extensions
1396
+ * @param {Function} [generateMask] The function used to generate the masking
1397
+ * key
1398
+ */
1399
+ constructor(socket, extensions, generateMask) {
1400
+ this._extensions = extensions || {};
1401
+ if (generateMask) {
1402
+ this._generateMask = generateMask;
1403
+ this._maskBuffer = Buffer.alloc(4);
1404
+ }
1405
+ this._socket = socket;
1406
+ this._firstFragment = true;
1407
+ this._compress = false;
1408
+ this._bufferedBytes = 0;
1409
+ this._queue = [];
1410
+ this._state = DEFAULT;
1411
+ this.onerror = NOOP;
1412
+ this[kWebSocket] = void 0;
1413
+ }
1414
+ /**
1415
+ * Frames a piece of data according to the HyBi WebSocket protocol.
1416
+ *
1417
+ * @param {(Buffer|String)} data The data to frame
1418
+ * @param {Object} options Options object
1419
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
1420
+ * FIN bit
1421
+ * @param {Function} [options.generateMask] The function used to generate the
1422
+ * masking key
1423
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1424
+ * `data`
1425
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
1426
+ * key
1427
+ * @param {Number} options.opcode The opcode
1428
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
1429
+ * modified
1430
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
1431
+ * RSV1 bit
1432
+ * @return {(Buffer|String)[]} The framed data
1433
+ * @public
1434
+ */
1435
+ static frame(data, options) {
1436
+ let mask;
1437
+ let merge = false;
1438
+ let offset = 2;
1439
+ let skipMasking = false;
1440
+ if (options.mask) {
1441
+ mask = options.maskBuffer || maskBuffer;
1442
+ if (options.generateMask) {
1443
+ options.generateMask(mask);
1444
+ } else {
1445
+ if (randomPoolPointer === RANDOM_POOL_SIZE) {
1446
+ if (randomPool === void 0) {
1447
+ randomPool = Buffer.alloc(RANDOM_POOL_SIZE);
1448
+ }
1449
+ randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);
1450
+ randomPoolPointer = 0;
1451
+ }
1452
+ mask[0] = randomPool[randomPoolPointer++];
1453
+ mask[1] = randomPool[randomPoolPointer++];
1454
+ mask[2] = randomPool[randomPoolPointer++];
1455
+ mask[3] = randomPool[randomPoolPointer++];
1456
+ }
1457
+ skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
1458
+ offset = 6;
1459
+ }
1460
+ let dataLength;
1461
+ if (typeof data === "string") {
1462
+ if ((!options.mask || skipMasking) && options[kByteLength] !== void 0) {
1463
+ dataLength = options[kByteLength];
1464
+ } else {
1465
+ data = Buffer.from(data);
1466
+ dataLength = data.length;
1467
+ }
1468
+ } else {
1469
+ dataLength = data.length;
1470
+ merge = options.mask && options.readOnly && !skipMasking;
1471
+ }
1472
+ let payloadLength = dataLength;
1473
+ if (dataLength >= 65536) {
1474
+ offset += 8;
1475
+ payloadLength = 127;
1476
+ } else if (dataLength > 125) {
1477
+ offset += 2;
1478
+ payloadLength = 126;
1479
+ }
1480
+ const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
1481
+ target[0] = options.fin ? options.opcode | 128 : options.opcode;
1482
+ if (options.rsv1) target[0] |= 64;
1483
+ target[1] = payloadLength;
1484
+ if (payloadLength === 126) {
1485
+ target.writeUInt16BE(dataLength, 2);
1486
+ } else if (payloadLength === 127) {
1487
+ target[2] = target[3] = 0;
1488
+ target.writeUIntBE(dataLength, 4, 6);
1489
+ }
1490
+ if (!options.mask) return [target, data];
1491
+ target[1] |= 128;
1492
+ target[offset - 4] = mask[0];
1493
+ target[offset - 3] = mask[1];
1494
+ target[offset - 2] = mask[2];
1495
+ target[offset - 1] = mask[3];
1496
+ if (skipMasking) return [target, data];
1497
+ if (merge) {
1498
+ applyMask(data, mask, target, offset, dataLength);
1499
+ return [target];
1500
+ }
1501
+ applyMask(data, mask, data, 0, dataLength);
1502
+ return [target, data];
1503
+ }
1504
+ /**
1505
+ * Sends a close message to the other peer.
1506
+ *
1507
+ * @param {Number} [code] The status code component of the body
1508
+ * @param {(String|Buffer)} [data] The message component of the body
1509
+ * @param {Boolean} [mask=false] Specifies whether or not to mask the message
1510
+ * @param {Function} [cb] Callback
1511
+ * @public
1512
+ */
1513
+ close(code, data, mask, cb) {
1514
+ let buf;
1515
+ if (code === void 0) {
1516
+ buf = EMPTY_BUFFER;
1517
+ } else if (typeof code !== "number" || !isValidStatusCode(code)) {
1518
+ throw new TypeError("First argument must be a valid error code number");
1519
+ } else if (data === void 0 || !data.length) {
1520
+ buf = Buffer.allocUnsafe(2);
1521
+ buf.writeUInt16BE(code, 0);
1522
+ } else {
1523
+ const length = Buffer.byteLength(data);
1524
+ if (length > 123) {
1525
+ throw new RangeError("The message must not be greater than 123 bytes");
1526
+ }
1527
+ buf = Buffer.allocUnsafe(2 + length);
1528
+ buf.writeUInt16BE(code, 0);
1529
+ if (typeof data === "string") {
1530
+ buf.write(data, 2);
1531
+ } else if (isUint8Array(data)) {
1532
+ buf.set(data, 2);
1533
+ } else {
1534
+ throw new TypeError("Second argument must be a string or a Uint8Array");
1535
+ }
1536
+ }
1537
+ const options = {
1538
+ [kByteLength]: buf.length,
1539
+ fin: true,
1540
+ generateMask: this._generateMask,
1541
+ mask,
1542
+ maskBuffer: this._maskBuffer,
1543
+ opcode: 8,
1544
+ readOnly: false,
1545
+ rsv1: false
1546
+ };
1547
+ if (this._state !== DEFAULT) {
1548
+ this.enqueue([this.dispatch, buf, false, options, cb]);
1549
+ } else {
1550
+ this.sendFrame(_Sender.frame(buf, options), cb);
1551
+ }
1552
+ }
1553
+ /**
1554
+ * Sends a ping message to the other peer.
1555
+ *
1556
+ * @param {*} data The message to send
1557
+ * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
1558
+ * @param {Function} [cb] Callback
1559
+ * @public
1560
+ */
1561
+ ping(data, mask, cb) {
1562
+ let byteLength;
1563
+ let readOnly;
1564
+ if (typeof data === "string") {
1565
+ byteLength = Buffer.byteLength(data);
1566
+ readOnly = false;
1567
+ } else if (isBlob(data)) {
1568
+ byteLength = data.size;
1569
+ readOnly = false;
1570
+ } else {
1571
+ data = toBuffer(data);
1572
+ byteLength = data.length;
1573
+ readOnly = toBuffer.readOnly;
1574
+ }
1575
+ if (byteLength > 125) {
1576
+ throw new RangeError("The data size must not be greater than 125 bytes");
1577
+ }
1578
+ const options = {
1579
+ [kByteLength]: byteLength,
1580
+ fin: true,
1581
+ generateMask: this._generateMask,
1582
+ mask,
1583
+ maskBuffer: this._maskBuffer,
1584
+ opcode: 9,
1585
+ readOnly,
1586
+ rsv1: false
1587
+ };
1588
+ if (isBlob(data)) {
1589
+ if (this._state !== DEFAULT) {
1590
+ this.enqueue([this.getBlobData, data, false, options, cb]);
1591
+ } else {
1592
+ this.getBlobData(data, false, options, cb);
1593
+ }
1594
+ } else if (this._state !== DEFAULT) {
1595
+ this.enqueue([this.dispatch, data, false, options, cb]);
1596
+ } else {
1597
+ this.sendFrame(_Sender.frame(data, options), cb);
1598
+ }
1599
+ }
1600
+ /**
1601
+ * Sends a pong message to the other peer.
1602
+ *
1603
+ * @param {*} data The message to send
1604
+ * @param {Boolean} [mask=false] Specifies whether or not to mask `data`
1605
+ * @param {Function} [cb] Callback
1606
+ * @public
1607
+ */
1608
+ pong(data, mask, cb) {
1609
+ let byteLength;
1610
+ let readOnly;
1611
+ if (typeof data === "string") {
1612
+ byteLength = Buffer.byteLength(data);
1613
+ readOnly = false;
1614
+ } else if (isBlob(data)) {
1615
+ byteLength = data.size;
1616
+ readOnly = false;
1617
+ } else {
1618
+ data = toBuffer(data);
1619
+ byteLength = data.length;
1620
+ readOnly = toBuffer.readOnly;
1621
+ }
1622
+ if (byteLength > 125) {
1623
+ throw new RangeError("The data size must not be greater than 125 bytes");
1624
+ }
1625
+ const options = {
1626
+ [kByteLength]: byteLength,
1627
+ fin: true,
1628
+ generateMask: this._generateMask,
1629
+ mask,
1630
+ maskBuffer: this._maskBuffer,
1631
+ opcode: 10,
1632
+ readOnly,
1633
+ rsv1: false
1634
+ };
1635
+ if (isBlob(data)) {
1636
+ if (this._state !== DEFAULT) {
1637
+ this.enqueue([this.getBlobData, data, false, options, cb]);
1638
+ } else {
1639
+ this.getBlobData(data, false, options, cb);
1640
+ }
1641
+ } else if (this._state !== DEFAULT) {
1642
+ this.enqueue([this.dispatch, data, false, options, cb]);
1643
+ } else {
1644
+ this.sendFrame(_Sender.frame(data, options), cb);
1645
+ }
1646
+ }
1647
+ /**
1648
+ * Sends a data message to the other peer.
1649
+ *
1650
+ * @param {*} data The message to send
1651
+ * @param {Object} options Options object
1652
+ * @param {Boolean} [options.binary=false] Specifies whether `data` is binary
1653
+ * or text
1654
+ * @param {Boolean} [options.compress=false] Specifies whether or not to
1655
+ * compress `data`
1656
+ * @param {Boolean} [options.fin=false] Specifies whether the fragment is the
1657
+ * last one
1658
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1659
+ * `data`
1660
+ * @param {Function} [cb] Callback
1661
+ * @public
1662
+ */
1663
+ send(data, options, cb) {
1664
+ const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
1665
+ let opcode = options.binary ? 2 : 1;
1666
+ let rsv1 = options.compress;
1667
+ let byteLength;
1668
+ let readOnly;
1669
+ if (typeof data === "string") {
1670
+ byteLength = Buffer.byteLength(data);
1671
+ readOnly = false;
1672
+ } else if (isBlob(data)) {
1673
+ byteLength = data.size;
1674
+ readOnly = false;
1675
+ } else {
1676
+ data = toBuffer(data);
1677
+ byteLength = data.length;
1678
+ readOnly = toBuffer.readOnly;
1679
+ }
1680
+ if (this._firstFragment) {
1681
+ this._firstFragment = false;
1682
+ if (rsv1 && perMessageDeflate && perMessageDeflate.params[perMessageDeflate._isServer ? "server_no_context_takeover" : "client_no_context_takeover"]) {
1683
+ rsv1 = byteLength >= perMessageDeflate._threshold;
1684
+ }
1685
+ this._compress = rsv1;
1686
+ } else {
1687
+ rsv1 = false;
1688
+ opcode = 0;
1689
+ }
1690
+ if (options.fin) this._firstFragment = true;
1691
+ const opts = {
1692
+ [kByteLength]: byteLength,
1693
+ fin: options.fin,
1694
+ generateMask: this._generateMask,
1695
+ mask: options.mask,
1696
+ maskBuffer: this._maskBuffer,
1697
+ opcode,
1698
+ readOnly,
1699
+ rsv1
1700
+ };
1701
+ if (isBlob(data)) {
1702
+ if (this._state !== DEFAULT) {
1703
+ this.enqueue([this.getBlobData, data, this._compress, opts, cb]);
1704
+ } else {
1705
+ this.getBlobData(data, this._compress, opts, cb);
1706
+ }
1707
+ } else if (this._state !== DEFAULT) {
1708
+ this.enqueue([this.dispatch, data, this._compress, opts, cb]);
1709
+ } else {
1710
+ this.dispatch(data, this._compress, opts, cb);
1711
+ }
1712
+ }
1713
+ /**
1714
+ * Gets the contents of a blob as binary data.
1715
+ *
1716
+ * @param {Blob} blob The blob
1717
+ * @param {Boolean} [compress=false] Specifies whether or not to compress
1718
+ * the data
1719
+ * @param {Object} options Options object
1720
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
1721
+ * FIN bit
1722
+ * @param {Function} [options.generateMask] The function used to generate the
1723
+ * masking key
1724
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1725
+ * `data`
1726
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
1727
+ * key
1728
+ * @param {Number} options.opcode The opcode
1729
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
1730
+ * modified
1731
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
1732
+ * RSV1 bit
1733
+ * @param {Function} [cb] Callback
1734
+ * @private
1735
+ */
1736
+ getBlobData(blob, compress, options, cb) {
1737
+ this._bufferedBytes += options[kByteLength];
1738
+ this._state = GET_BLOB_DATA;
1739
+ blob.arrayBuffer().then((arrayBuffer) => {
1740
+ if (this._socket.destroyed) {
1741
+ const err = new Error(
1742
+ "The socket was closed while the blob was being read"
1743
+ );
1744
+ process.nextTick(callCallbacks, this, err, cb);
1745
+ return;
1746
+ }
1747
+ this._bufferedBytes -= options[kByteLength];
1748
+ const data = toBuffer(arrayBuffer);
1749
+ if (!compress) {
1750
+ this._state = DEFAULT;
1751
+ this.sendFrame(_Sender.frame(data, options), cb);
1752
+ this.dequeue();
1753
+ } else {
1754
+ this.dispatch(data, compress, options, cb);
1755
+ }
1756
+ }).catch((err) => {
1757
+ process.nextTick(onError, this, err, cb);
1758
+ });
1759
+ }
1760
+ /**
1761
+ * Dispatches a message.
1762
+ *
1763
+ * @param {(Buffer|String)} data The message to send
1764
+ * @param {Boolean} [compress=false] Specifies whether or not to compress
1765
+ * `data`
1766
+ * @param {Object} options Options object
1767
+ * @param {Boolean} [options.fin=false] Specifies whether or not to set the
1768
+ * FIN bit
1769
+ * @param {Function} [options.generateMask] The function used to generate the
1770
+ * masking key
1771
+ * @param {Boolean} [options.mask=false] Specifies whether or not to mask
1772
+ * `data`
1773
+ * @param {Buffer} [options.maskBuffer] The buffer used to store the masking
1774
+ * key
1775
+ * @param {Number} options.opcode The opcode
1776
+ * @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
1777
+ * modified
1778
+ * @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
1779
+ * RSV1 bit
1780
+ * @param {Function} [cb] Callback
1781
+ * @private
1782
+ */
1783
+ dispatch(data, compress, options, cb) {
1784
+ if (!compress) {
1785
+ this.sendFrame(_Sender.frame(data, options), cb);
1786
+ return;
1787
+ }
1788
+ const perMessageDeflate = this._extensions[PerMessageDeflate2.extensionName];
1789
+ this._bufferedBytes += options[kByteLength];
1790
+ this._state = DEFLATING;
1791
+ perMessageDeflate.compress(data, options.fin, (_, buf) => {
1792
+ if (this._socket.destroyed) {
1793
+ const err = new Error(
1794
+ "The socket was closed while data was being compressed"
1795
+ );
1796
+ callCallbacks(this, err, cb);
1797
+ return;
1798
+ }
1799
+ this._bufferedBytes -= options[kByteLength];
1800
+ this._state = DEFAULT;
1801
+ options.readOnly = false;
1802
+ this.sendFrame(_Sender.frame(buf, options), cb);
1803
+ this.dequeue();
1804
+ });
1805
+ }
1806
+ /**
1807
+ * Executes queued send operations.
1808
+ *
1809
+ * @private
1810
+ */
1811
+ dequeue() {
1812
+ while (this._state === DEFAULT && this._queue.length) {
1813
+ const params = this._queue.shift();
1814
+ this._bufferedBytes -= params[3][kByteLength];
1815
+ Reflect.apply(params[0], this, params.slice(1));
1816
+ }
1817
+ }
1818
+ /**
1819
+ * Enqueues a send operation.
1820
+ *
1821
+ * @param {Array} params Send operation parameters.
1822
+ * @private
1823
+ */
1824
+ enqueue(params) {
1825
+ this._bufferedBytes += params[3][kByteLength];
1826
+ this._queue.push(params);
1827
+ }
1828
+ /**
1829
+ * Sends a frame.
1830
+ *
1831
+ * @param {(Buffer | String)[]} list The frame to send
1832
+ * @param {Function} [cb] Callback
1833
+ * @private
1834
+ */
1835
+ sendFrame(list, cb) {
1836
+ if (list.length === 2) {
1837
+ this._socket.cork();
1838
+ this._socket.write(list[0]);
1839
+ this._socket.write(list[1], cb);
1840
+ this._socket.uncork();
1841
+ } else {
1842
+ this._socket.write(list[0], cb);
1843
+ }
1844
+ }
1845
+ };
1846
+ module.exports = Sender2;
1847
+ function callCallbacks(sender, err, cb) {
1848
+ if (typeof cb === "function") cb(err);
1849
+ for (let i = 0; i < sender._queue.length; i++) {
1850
+ const params = sender._queue[i];
1851
+ const callback = params[params.length - 1];
1852
+ if (typeof callback === "function") callback(err);
1853
+ }
1854
+ }
1855
+ function onError(sender, err, cb) {
1856
+ callCallbacks(sender, err, cb);
1857
+ sender.onerror(err);
1858
+ }
1859
+ }
1860
+ });
1861
+
1862
+ // ../../node_modules/ws/lib/event-target.js
1863
+ var require_event_target = __commonJS({
1864
+ "../../node_modules/ws/lib/event-target.js"(exports, module) {
1865
+ "use strict";
1866
+ var { kForOnEventAttribute, kListener } = require_constants();
1867
+ var kCode = /* @__PURE__ */ Symbol("kCode");
1868
+ var kData = /* @__PURE__ */ Symbol("kData");
1869
+ var kError = /* @__PURE__ */ Symbol("kError");
1870
+ var kMessage = /* @__PURE__ */ Symbol("kMessage");
1871
+ var kReason = /* @__PURE__ */ Symbol("kReason");
1872
+ var kTarget = /* @__PURE__ */ Symbol("kTarget");
1873
+ var kType = /* @__PURE__ */ Symbol("kType");
1874
+ var kWasClean = /* @__PURE__ */ Symbol("kWasClean");
1875
+ var Event = class {
1876
+ /**
1877
+ * Create a new `Event`.
1878
+ *
1879
+ * @param {String} type The name of the event
1880
+ * @throws {TypeError} If the `type` argument is not specified
1881
+ */
1882
+ constructor(type) {
1883
+ this[kTarget] = null;
1884
+ this[kType] = type;
1885
+ }
1886
+ /**
1887
+ * @type {*}
1888
+ */
1889
+ get target() {
1890
+ return this[kTarget];
1891
+ }
1892
+ /**
1893
+ * @type {String}
1894
+ */
1895
+ get type() {
1896
+ return this[kType];
1897
+ }
1898
+ };
1899
+ Object.defineProperty(Event.prototype, "target", { enumerable: true });
1900
+ Object.defineProperty(Event.prototype, "type", { enumerable: true });
1901
+ var CloseEvent = class extends Event {
1902
+ /**
1903
+ * Create a new `CloseEvent`.
1904
+ *
1905
+ * @param {String} type The name of the event
1906
+ * @param {Object} [options] A dictionary object that allows for setting
1907
+ * attributes via object members of the same name
1908
+ * @param {Number} [options.code=0] The status code explaining why the
1909
+ * connection was closed
1910
+ * @param {String} [options.reason=''] A human-readable string explaining why
1911
+ * the connection was closed
1912
+ * @param {Boolean} [options.wasClean=false] Indicates whether or not the
1913
+ * connection was cleanly closed
1914
+ */
1915
+ constructor(type, options = {}) {
1916
+ super(type);
1917
+ this[kCode] = options.code === void 0 ? 0 : options.code;
1918
+ this[kReason] = options.reason === void 0 ? "" : options.reason;
1919
+ this[kWasClean] = options.wasClean === void 0 ? false : options.wasClean;
1920
+ }
1921
+ /**
1922
+ * @type {Number}
1923
+ */
1924
+ get code() {
1925
+ return this[kCode];
1926
+ }
1927
+ /**
1928
+ * @type {String}
1929
+ */
1930
+ get reason() {
1931
+ return this[kReason];
1932
+ }
1933
+ /**
1934
+ * @type {Boolean}
1935
+ */
1936
+ get wasClean() {
1937
+ return this[kWasClean];
1938
+ }
1939
+ };
1940
+ Object.defineProperty(CloseEvent.prototype, "code", { enumerable: true });
1941
+ Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true });
1942
+ Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true });
1943
+ var ErrorEvent = class extends Event {
1944
+ /**
1945
+ * Create a new `ErrorEvent`.
1946
+ *
1947
+ * @param {String} type The name of the event
1948
+ * @param {Object} [options] A dictionary object that allows for setting
1949
+ * attributes via object members of the same name
1950
+ * @param {*} [options.error=null] The error that generated this event
1951
+ * @param {String} [options.message=''] The error message
1952
+ */
1953
+ constructor(type, options = {}) {
1954
+ super(type);
1955
+ this[kError] = options.error === void 0 ? null : options.error;
1956
+ this[kMessage] = options.message === void 0 ? "" : options.message;
1957
+ }
1958
+ /**
1959
+ * @type {*}
1960
+ */
1961
+ get error() {
1962
+ return this[kError];
1963
+ }
1964
+ /**
1965
+ * @type {String}
1966
+ */
1967
+ get message() {
1968
+ return this[kMessage];
1969
+ }
1970
+ };
1971
+ Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true });
1972
+ Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true });
1973
+ var MessageEvent = class extends Event {
1974
+ /**
1975
+ * Create a new `MessageEvent`.
1976
+ *
1977
+ * @param {String} type The name of the event
1978
+ * @param {Object} [options] A dictionary object that allows for setting
1979
+ * attributes via object members of the same name
1980
+ * @param {*} [options.data=null] The message content
1981
+ */
1982
+ constructor(type, options = {}) {
1983
+ super(type);
1984
+ this[kData] = options.data === void 0 ? null : options.data;
1985
+ }
1986
+ /**
1987
+ * @type {*}
1988
+ */
1989
+ get data() {
1990
+ return this[kData];
1991
+ }
1992
+ };
1993
+ Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true });
1994
+ var EventTarget = {
1995
+ /**
1996
+ * Register an event listener.
1997
+ *
1998
+ * @param {String} type A string representing the event type to listen for
1999
+ * @param {(Function|Object)} handler The listener to add
2000
+ * @param {Object} [options] An options object specifies characteristics about
2001
+ * the event listener
2002
+ * @param {Boolean} [options.once=false] A `Boolean` indicating that the
2003
+ * listener should be invoked at most once after being added. If `true`,
2004
+ * the listener would be automatically removed when invoked.
2005
+ * @public
2006
+ */
2007
+ addEventListener(type, handler, options = {}) {
2008
+ for (const listener of this.listeners(type)) {
2009
+ if (!options[kForOnEventAttribute] && listener[kListener] === handler && !listener[kForOnEventAttribute]) {
2010
+ return;
2011
+ }
2012
+ }
2013
+ let wrapper;
2014
+ if (type === "message") {
2015
+ wrapper = function onMessage(data, isBinary) {
2016
+ const event = new MessageEvent("message", {
2017
+ data: isBinary ? data : data.toString()
2018
+ });
2019
+ event[kTarget] = this;
2020
+ callListener(handler, this, event);
2021
+ };
2022
+ } else if (type === "close") {
2023
+ wrapper = function onClose(code, message) {
2024
+ const event = new CloseEvent("close", {
2025
+ code,
2026
+ reason: message.toString(),
2027
+ wasClean: this._closeFrameReceived && this._closeFrameSent
2028
+ });
2029
+ event[kTarget] = this;
2030
+ callListener(handler, this, event);
2031
+ };
2032
+ } else if (type === "error") {
2033
+ wrapper = function onError(error) {
2034
+ const event = new ErrorEvent("error", {
2035
+ error,
2036
+ message: error.message
2037
+ });
2038
+ event[kTarget] = this;
2039
+ callListener(handler, this, event);
2040
+ };
2041
+ } else if (type === "open") {
2042
+ wrapper = function onOpen() {
2043
+ const event = new Event("open");
2044
+ event[kTarget] = this;
2045
+ callListener(handler, this, event);
2046
+ };
2047
+ } else {
2048
+ return;
2049
+ }
2050
+ wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];
2051
+ wrapper[kListener] = handler;
2052
+ if (options.once) {
2053
+ this.once(type, wrapper);
2054
+ } else {
2055
+ this.on(type, wrapper);
2056
+ }
2057
+ },
2058
+ /**
2059
+ * Remove an event listener.
2060
+ *
2061
+ * @param {String} type A string representing the event type to remove
2062
+ * @param {(Function|Object)} handler The listener to remove
2063
+ * @public
2064
+ */
2065
+ removeEventListener(type, handler) {
2066
+ for (const listener of this.listeners(type)) {
2067
+ if (listener[kListener] === handler && !listener[kForOnEventAttribute]) {
2068
+ this.removeListener(type, listener);
2069
+ break;
2070
+ }
2071
+ }
2072
+ }
2073
+ };
2074
+ module.exports = {
2075
+ CloseEvent,
2076
+ ErrorEvent,
2077
+ Event,
2078
+ EventTarget,
2079
+ MessageEvent
2080
+ };
2081
+ function callListener(listener, thisArg, event) {
2082
+ if (typeof listener === "object" && listener.handleEvent) {
2083
+ listener.handleEvent.call(listener, event);
2084
+ } else {
2085
+ listener.call(thisArg, event);
2086
+ }
2087
+ }
2088
+ }
2089
+ });
2090
+
2091
+ // ../../node_modules/ws/lib/extension.js
2092
+ var require_extension = __commonJS({
2093
+ "../../node_modules/ws/lib/extension.js"(exports, module) {
2094
+ "use strict";
2095
+ var { tokenChars } = require_validation();
2096
+ function push(dest, name, elem) {
2097
+ if (dest[name] === void 0) dest[name] = [elem];
2098
+ else dest[name].push(elem);
2099
+ }
2100
+ function parse(header) {
2101
+ const offers = /* @__PURE__ */ Object.create(null);
2102
+ let params = /* @__PURE__ */ Object.create(null);
2103
+ let mustUnescape = false;
2104
+ let isEscaping = false;
2105
+ let inQuotes = false;
2106
+ let extensionName;
2107
+ let paramName;
2108
+ let start = -1;
2109
+ let code = -1;
2110
+ let end = -1;
2111
+ let i = 0;
2112
+ for (; i < header.length; i++) {
2113
+ code = header.charCodeAt(i);
2114
+ if (extensionName === void 0) {
2115
+ if (end === -1 && tokenChars[code] === 1) {
2116
+ if (start === -1) start = i;
2117
+ } else if (i !== 0 && (code === 32 || code === 9)) {
2118
+ if (end === -1 && start !== -1) end = i;
2119
+ } else if (code === 59 || code === 44) {
2120
+ if (start === -1) {
2121
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2122
+ }
2123
+ if (end === -1) end = i;
2124
+ const name = header.slice(start, end);
2125
+ if (code === 44) {
2126
+ push(offers, name, params);
2127
+ params = /* @__PURE__ */ Object.create(null);
2128
+ } else {
2129
+ extensionName = name;
2130
+ }
2131
+ start = end = -1;
2132
+ } else {
2133
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2134
+ }
2135
+ } else if (paramName === void 0) {
2136
+ if (end === -1 && tokenChars[code] === 1) {
2137
+ if (start === -1) start = i;
2138
+ } else if (code === 32 || code === 9) {
2139
+ if (end === -1 && start !== -1) end = i;
2140
+ } else if (code === 59 || code === 44) {
2141
+ if (start === -1) {
2142
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2143
+ }
2144
+ if (end === -1) end = i;
2145
+ push(params, header.slice(start, end), true);
2146
+ if (code === 44) {
2147
+ push(offers, extensionName, params);
2148
+ params = /* @__PURE__ */ Object.create(null);
2149
+ extensionName = void 0;
2150
+ }
2151
+ start = end = -1;
2152
+ } else if (code === 61 && start !== -1 && end === -1) {
2153
+ paramName = header.slice(start, i);
2154
+ start = end = -1;
2155
+ } else {
2156
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2157
+ }
2158
+ } else {
2159
+ if (isEscaping) {
2160
+ if (tokenChars[code] !== 1) {
2161
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2162
+ }
2163
+ if (start === -1) start = i;
2164
+ else if (!mustUnescape) mustUnescape = true;
2165
+ isEscaping = false;
2166
+ } else if (inQuotes) {
2167
+ if (tokenChars[code] === 1) {
2168
+ if (start === -1) start = i;
2169
+ } else if (code === 34 && start !== -1) {
2170
+ inQuotes = false;
2171
+ end = i;
2172
+ } else if (code === 92) {
2173
+ isEscaping = true;
2174
+ } else {
2175
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2176
+ }
2177
+ } else if (code === 34 && header.charCodeAt(i - 1) === 61) {
2178
+ inQuotes = true;
2179
+ } else if (end === -1 && tokenChars[code] === 1) {
2180
+ if (start === -1) start = i;
2181
+ } else if (start !== -1 && (code === 32 || code === 9)) {
2182
+ if (end === -1) end = i;
2183
+ } else if (code === 59 || code === 44) {
2184
+ if (start === -1) {
2185
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2186
+ }
2187
+ if (end === -1) end = i;
2188
+ let value = header.slice(start, end);
2189
+ if (mustUnescape) {
2190
+ value = value.replace(/\\/g, "");
2191
+ mustUnescape = false;
2192
+ }
2193
+ push(params, paramName, value);
2194
+ if (code === 44) {
2195
+ push(offers, extensionName, params);
2196
+ params = /* @__PURE__ */ Object.create(null);
2197
+ extensionName = void 0;
2198
+ }
2199
+ paramName = void 0;
2200
+ start = end = -1;
2201
+ } else {
2202
+ throw new SyntaxError(`Unexpected character at index ${i}`);
2203
+ }
2204
+ }
2205
+ }
2206
+ if (start === -1 || inQuotes || code === 32 || code === 9) {
2207
+ throw new SyntaxError("Unexpected end of input");
2208
+ }
2209
+ if (end === -1) end = i;
2210
+ const token = header.slice(start, end);
2211
+ if (extensionName === void 0) {
2212
+ push(offers, token, params);
2213
+ } else {
2214
+ if (paramName === void 0) {
2215
+ push(params, token, true);
2216
+ } else if (mustUnescape) {
2217
+ push(params, paramName, token.replace(/\\/g, ""));
2218
+ } else {
2219
+ push(params, paramName, token);
2220
+ }
2221
+ push(offers, extensionName, params);
2222
+ }
2223
+ return offers;
2224
+ }
2225
+ function format(extensions) {
2226
+ return Object.keys(extensions).map((extension2) => {
2227
+ let configurations = extensions[extension2];
2228
+ if (!Array.isArray(configurations)) configurations = [configurations];
2229
+ return configurations.map((params) => {
2230
+ return [extension2].concat(
2231
+ Object.keys(params).map((k) => {
2232
+ let values = params[k];
2233
+ if (!Array.isArray(values)) values = [values];
2234
+ return values.map((v) => v === true ? k : `${k}=${v}`).join("; ");
2235
+ })
2236
+ ).join("; ");
2237
+ }).join(", ");
2238
+ }).join(", ");
2239
+ }
2240
+ module.exports = { format, parse };
2241
+ }
2242
+ });
2243
+
2244
+ // ../../node_modules/ws/lib/websocket.js
2245
+ var require_websocket = __commonJS({
2246
+ "../../node_modules/ws/lib/websocket.js"(exports, module) {
2247
+ "use strict";
2248
+ var EventEmitter = __require("events");
2249
+ var https = __require("https");
2250
+ var http = __require("http");
2251
+ var net3 = __require("net");
2252
+ var tls = __require("tls");
2253
+ var { randomBytes, createHash } = __require("crypto");
2254
+ var { Duplex, Readable } = __require("stream");
2255
+ var { URL: URL2 } = __require("url");
2256
+ var PerMessageDeflate2 = require_permessage_deflate();
2257
+ var Receiver2 = require_receiver();
2258
+ var Sender2 = require_sender();
2259
+ var { isBlob } = require_validation();
2260
+ var {
2261
+ BINARY_TYPES,
2262
+ CLOSE_TIMEOUT,
2263
+ EMPTY_BUFFER,
2264
+ GUID,
2265
+ kForOnEventAttribute,
2266
+ kListener,
2267
+ kStatusCode,
2268
+ kWebSocket,
2269
+ NOOP
2270
+ } = require_constants();
2271
+ var {
2272
+ EventTarget: { addEventListener, removeEventListener }
2273
+ } = require_event_target();
2274
+ var { format, parse } = require_extension();
2275
+ var { toBuffer } = require_buffer_util();
2276
+ var kAborted = /* @__PURE__ */ Symbol("kAborted");
2277
+ var protocolVersions = [8, 13];
2278
+ var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
2279
+ var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
2280
+ var WebSocket2 = class _WebSocket extends EventEmitter {
2281
+ /**
2282
+ * Create a new `WebSocket`.
2283
+ *
2284
+ * @param {(String|URL)} address The URL to which to connect
2285
+ * @param {(String|String[])} [protocols] The subprotocols
2286
+ * @param {Object} [options] Connection options
2287
+ */
2288
+ constructor(address, protocols, options) {
2289
+ super();
2290
+ this._binaryType = BINARY_TYPES[0];
2291
+ this._closeCode = 1006;
2292
+ this._closeFrameReceived = false;
2293
+ this._closeFrameSent = false;
2294
+ this._closeMessage = EMPTY_BUFFER;
2295
+ this._closeTimer = null;
2296
+ this._errorEmitted = false;
2297
+ this._extensions = {};
2298
+ this._paused = false;
2299
+ this._protocol = "";
2300
+ this._readyState = _WebSocket.CONNECTING;
2301
+ this._receiver = null;
2302
+ this._sender = null;
2303
+ this._socket = null;
2304
+ if (address !== null) {
2305
+ this._bufferedAmount = 0;
2306
+ this._isServer = false;
2307
+ this._redirects = 0;
2308
+ if (protocols === void 0) {
2309
+ if (!options || options.protocols === void 0) {
2310
+ protocols = [];
2311
+ } else if (Array.isArray(options.protocols)) {
2312
+ protocols = options.protocols;
2313
+ } else {
2314
+ protocols = [options.protocols];
2315
+ }
2316
+ } else if (!Array.isArray(protocols)) {
2317
+ if (typeof protocols === "object" && protocols !== null) {
2318
+ options = protocols;
2319
+ if (options.protocols === void 0) {
2320
+ protocols = [];
2321
+ } else if (Array.isArray(options.protocols)) {
2322
+ protocols = options.protocols;
2323
+ } else {
2324
+ protocols = [options.protocols];
2325
+ }
2326
+ } else {
2327
+ protocols = [protocols];
2328
+ }
2329
+ }
2330
+ initAsClient(this, address, protocols, options);
2331
+ } else {
2332
+ this._autoPong = options.autoPong;
2333
+ this._closeTimeout = options.closeTimeout;
2334
+ this._isServer = true;
2335
+ }
2336
+ }
2337
+ /**
2338
+ * For historical reasons, the custom "nodebuffer" type is used by the default
2339
+ * instead of "blob".
2340
+ *
2341
+ * @type {String}
2342
+ */
2343
+ get binaryType() {
2344
+ return this._binaryType;
2345
+ }
2346
+ set binaryType(type) {
2347
+ if (!BINARY_TYPES.includes(type)) return;
2348
+ this._binaryType = type;
2349
+ if (this._receiver) this._receiver._binaryType = type;
2350
+ }
2351
+ /**
2352
+ * @type {Number}
2353
+ */
2354
+ get bufferedAmount() {
2355
+ if (!this._socket) return this._bufferedAmount;
2356
+ return this._socket._writableState.length + this._sender._bufferedBytes;
2357
+ }
2358
+ /**
2359
+ * @type {String}
2360
+ */
2361
+ get extensions() {
2362
+ return Object.keys(this._extensions).join();
2363
+ }
2364
+ /**
2365
+ * @type {Boolean}
2366
+ */
2367
+ get isPaused() {
2368
+ return this._paused;
2369
+ }
2370
+ /**
2371
+ * @type {Function}
2372
+ */
2373
+ /* istanbul ignore next */
2374
+ get onclose() {
2375
+ return null;
2376
+ }
2377
+ /**
2378
+ * @type {Function}
2379
+ */
2380
+ /* istanbul ignore next */
2381
+ get onerror() {
2382
+ return null;
2383
+ }
2384
+ /**
2385
+ * @type {Function}
2386
+ */
2387
+ /* istanbul ignore next */
2388
+ get onopen() {
2389
+ return null;
2390
+ }
2391
+ /**
2392
+ * @type {Function}
2393
+ */
2394
+ /* istanbul ignore next */
2395
+ get onmessage() {
2396
+ return null;
2397
+ }
2398
+ /**
2399
+ * @type {String}
2400
+ */
2401
+ get protocol() {
2402
+ return this._protocol;
2403
+ }
2404
+ /**
2405
+ * @type {Number}
2406
+ */
2407
+ get readyState() {
2408
+ return this._readyState;
2409
+ }
2410
+ /**
2411
+ * @type {String}
2412
+ */
2413
+ get url() {
2414
+ return this._url;
2415
+ }
2416
+ /**
2417
+ * Set up the socket and the internal resources.
2418
+ *
2419
+ * @param {Duplex} socket The network socket between the server and client
2420
+ * @param {Buffer} head The first packet of the upgraded stream
2421
+ * @param {Object} options Options object
2422
+ * @param {Boolean} [options.allowSynchronousEvents=false] Specifies whether
2423
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
2424
+ * multiple times in the same tick
2425
+ * @param {Function} [options.generateMask] The function used to generate the
2426
+ * masking key
2427
+ * @param {Number} [options.maxBufferedChunks=0] The maximum number of
2428
+ * buffered data chunks
2429
+ * @param {Number} [options.maxFragments=0] The maximum number of message
2430
+ * fragments
2431
+ * @param {Number} [options.maxPayload=0] The maximum allowed message size
2432
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
2433
+ * not to skip UTF-8 validation for text and close messages
2434
+ * @private
2435
+ */
2436
+ setSocket(socket, head, options) {
2437
+ const receiver = new Receiver2({
2438
+ allowSynchronousEvents: options.allowSynchronousEvents,
2439
+ binaryType: this.binaryType,
2440
+ extensions: this._extensions,
2441
+ isServer: this._isServer,
2442
+ maxBufferedChunks: options.maxBufferedChunks,
2443
+ maxFragments: options.maxFragments,
2444
+ maxPayload: options.maxPayload,
2445
+ skipUTF8Validation: options.skipUTF8Validation
2446
+ });
2447
+ const sender = new Sender2(socket, this._extensions, options.generateMask);
2448
+ this._receiver = receiver;
2449
+ this._sender = sender;
2450
+ this._socket = socket;
2451
+ receiver[kWebSocket] = this;
2452
+ sender[kWebSocket] = this;
2453
+ socket[kWebSocket] = this;
2454
+ receiver.on("conclude", receiverOnConclude);
2455
+ receiver.on("drain", receiverOnDrain);
2456
+ receiver.on("error", receiverOnError);
2457
+ receiver.on("message", receiverOnMessage);
2458
+ receiver.on("ping", receiverOnPing);
2459
+ receiver.on("pong", receiverOnPong);
2460
+ sender.onerror = senderOnError;
2461
+ if (socket.setTimeout) socket.setTimeout(0);
2462
+ if (socket.setNoDelay) socket.setNoDelay();
2463
+ if (head.length > 0) socket.unshift(head);
2464
+ socket.on("close", socketOnClose);
2465
+ socket.on("data", socketOnData);
2466
+ socket.on("end", socketOnEnd);
2467
+ socket.on("error", socketOnError);
2468
+ this._readyState = _WebSocket.OPEN;
2469
+ this.emit("open");
2470
+ }
2471
+ /**
2472
+ * Emit the `'close'` event.
2473
+ *
2474
+ * @private
2475
+ */
2476
+ emitClose() {
2477
+ if (!this._socket) {
2478
+ this._readyState = _WebSocket.CLOSED;
2479
+ this.emit("close", this._closeCode, this._closeMessage);
2480
+ return;
2481
+ }
2482
+ if (this._extensions[PerMessageDeflate2.extensionName]) {
2483
+ this._extensions[PerMessageDeflate2.extensionName].cleanup();
2484
+ }
2485
+ this._receiver.removeAllListeners();
2486
+ this._readyState = _WebSocket.CLOSED;
2487
+ this.emit("close", this._closeCode, this._closeMessage);
2488
+ }
2489
+ /**
2490
+ * Start a closing handshake.
2491
+ *
2492
+ * +----------+ +-----------+ +----------+
2493
+ * - - -|ws.close()|-->|close frame|-->|ws.close()|- - -
2494
+ * | +----------+ +-----------+ +----------+ |
2495
+ * +----------+ +-----------+ |
2496
+ * CLOSING |ws.close()|<--|close frame|<--+-----+ CLOSING
2497
+ * +----------+ +-----------+ |
2498
+ * | | | +---+ |
2499
+ * +------------------------+-->|fin| - - - -
2500
+ * | +---+ | +---+
2501
+ * - - - - -|fin|<---------------------+
2502
+ * +---+
2503
+ *
2504
+ * @param {Number} [code] Status code explaining why the connection is closing
2505
+ * @param {(String|Buffer)} [data] The reason why the connection is
2506
+ * closing
2507
+ * @public
2508
+ */
2509
+ close(code, data) {
2510
+ if (this.readyState === _WebSocket.CLOSED) return;
2511
+ if (this.readyState === _WebSocket.CONNECTING) {
2512
+ const msg = "WebSocket was closed before the connection was established";
2513
+ abortHandshake(this, this._req, msg);
2514
+ return;
2515
+ }
2516
+ if (this.readyState === _WebSocket.CLOSING) {
2517
+ if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) {
2518
+ this._socket.end();
2519
+ }
2520
+ return;
2521
+ }
2522
+ this._sender.close(code, data, !this._isServer, (err) => {
2523
+ if (err) return;
2524
+ this._closeFrameSent = true;
2525
+ if (this._closeFrameReceived || this._receiver._writableState.errorEmitted) {
2526
+ this._socket.end();
2527
+ }
2528
+ });
2529
+ this._readyState = _WebSocket.CLOSING;
2530
+ setCloseTimer(this);
2531
+ }
2532
+ /**
2533
+ * Pause the socket.
2534
+ *
2535
+ * @public
2536
+ */
2537
+ pause() {
2538
+ if (this.readyState === _WebSocket.CONNECTING || this.readyState === _WebSocket.CLOSED) {
2539
+ return;
2540
+ }
2541
+ this._paused = true;
2542
+ this._socket.pause();
2543
+ }
2544
+ /**
2545
+ * Send a ping.
2546
+ *
2547
+ * @param {*} [data] The data to send
2548
+ * @param {Boolean} [mask] Indicates whether or not to mask `data`
2549
+ * @param {Function} [cb] Callback which is executed when the ping is sent
2550
+ * @public
2551
+ */
2552
+ ping(data, mask, cb) {
2553
+ if (this.readyState === _WebSocket.CONNECTING) {
2554
+ throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
2555
+ }
2556
+ if (typeof data === "function") {
2557
+ cb = data;
2558
+ data = mask = void 0;
2559
+ } else if (typeof mask === "function") {
2560
+ cb = mask;
2561
+ mask = void 0;
2562
+ }
2563
+ if (typeof data === "number") data = data.toString();
2564
+ if (this.readyState !== _WebSocket.OPEN) {
2565
+ sendAfterClose(this, data, cb);
2566
+ return;
2567
+ }
2568
+ if (mask === void 0) mask = !this._isServer;
2569
+ this._sender.ping(data || EMPTY_BUFFER, mask, cb);
2570
+ }
2571
+ /**
2572
+ * Send a pong.
2573
+ *
2574
+ * @param {*} [data] The data to send
2575
+ * @param {Boolean} [mask] Indicates whether or not to mask `data`
2576
+ * @param {Function} [cb] Callback which is executed when the pong is sent
2577
+ * @public
2578
+ */
2579
+ pong(data, mask, cb) {
2580
+ if (this.readyState === _WebSocket.CONNECTING) {
2581
+ throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
2582
+ }
2583
+ if (typeof data === "function") {
2584
+ cb = data;
2585
+ data = mask = void 0;
2586
+ } else if (typeof mask === "function") {
2587
+ cb = mask;
2588
+ mask = void 0;
2589
+ }
2590
+ if (typeof data === "number") data = data.toString();
2591
+ if (this.readyState !== _WebSocket.OPEN) {
2592
+ sendAfterClose(this, data, cb);
2593
+ return;
2594
+ }
2595
+ if (mask === void 0) mask = !this._isServer;
2596
+ this._sender.pong(data || EMPTY_BUFFER, mask, cb);
2597
+ }
2598
+ /**
2599
+ * Resume the socket.
2600
+ *
2601
+ * @public
2602
+ */
2603
+ resume() {
2604
+ if (this.readyState === _WebSocket.CONNECTING || this.readyState === _WebSocket.CLOSED) {
2605
+ return;
2606
+ }
2607
+ this._paused = false;
2608
+ if (!this._receiver._writableState.needDrain) this._socket.resume();
2609
+ }
2610
+ /**
2611
+ * Send a data message.
2612
+ *
2613
+ * @param {*} data The message to send
2614
+ * @param {Object} [options] Options object
2615
+ * @param {Boolean} [options.binary] Specifies whether `data` is binary or
2616
+ * text
2617
+ * @param {Boolean} [options.compress] Specifies whether or not to compress
2618
+ * `data`
2619
+ * @param {Boolean} [options.fin=true] Specifies whether the fragment is the
2620
+ * last one
2621
+ * @param {Boolean} [options.mask] Specifies whether or not to mask `data`
2622
+ * @param {Function} [cb] Callback which is executed when data is written out
2623
+ * @public
2624
+ */
2625
+ send(data, options, cb) {
2626
+ if (this.readyState === _WebSocket.CONNECTING) {
2627
+ throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
2628
+ }
2629
+ if (typeof options === "function") {
2630
+ cb = options;
2631
+ options = {};
2632
+ }
2633
+ if (typeof data === "number") data = data.toString();
2634
+ if (this.readyState !== _WebSocket.OPEN) {
2635
+ sendAfterClose(this, data, cb);
2636
+ return;
2637
+ }
2638
+ const opts = {
2639
+ binary: typeof data !== "string",
2640
+ mask: !this._isServer,
2641
+ compress: true,
2642
+ fin: true,
2643
+ ...options
2644
+ };
2645
+ if (!this._extensions[PerMessageDeflate2.extensionName]) {
2646
+ opts.compress = false;
2647
+ }
2648
+ this._sender.send(data || EMPTY_BUFFER, opts, cb);
2649
+ }
2650
+ /**
2651
+ * Forcibly close the connection.
2652
+ *
2653
+ * @public
2654
+ */
2655
+ terminate() {
2656
+ if (this.readyState === _WebSocket.CLOSED) return;
2657
+ if (this.readyState === _WebSocket.CONNECTING) {
2658
+ const msg = "WebSocket was closed before the connection was established";
2659
+ abortHandshake(this, this._req, msg);
2660
+ return;
2661
+ }
2662
+ if (this._socket) {
2663
+ this._readyState = _WebSocket.CLOSING;
2664
+ this._socket.destroy();
2665
+ }
2666
+ }
2667
+ };
2668
+ Object.defineProperty(WebSocket2, "CONNECTING", {
2669
+ enumerable: true,
2670
+ value: readyStates.indexOf("CONNECTING")
2671
+ });
2672
+ Object.defineProperty(WebSocket2.prototype, "CONNECTING", {
2673
+ enumerable: true,
2674
+ value: readyStates.indexOf("CONNECTING")
2675
+ });
2676
+ Object.defineProperty(WebSocket2, "OPEN", {
2677
+ enumerable: true,
2678
+ value: readyStates.indexOf("OPEN")
2679
+ });
2680
+ Object.defineProperty(WebSocket2.prototype, "OPEN", {
2681
+ enumerable: true,
2682
+ value: readyStates.indexOf("OPEN")
2683
+ });
2684
+ Object.defineProperty(WebSocket2, "CLOSING", {
2685
+ enumerable: true,
2686
+ value: readyStates.indexOf("CLOSING")
2687
+ });
2688
+ Object.defineProperty(WebSocket2.prototype, "CLOSING", {
2689
+ enumerable: true,
2690
+ value: readyStates.indexOf("CLOSING")
2691
+ });
2692
+ Object.defineProperty(WebSocket2, "CLOSED", {
2693
+ enumerable: true,
2694
+ value: readyStates.indexOf("CLOSED")
2695
+ });
2696
+ Object.defineProperty(WebSocket2.prototype, "CLOSED", {
2697
+ enumerable: true,
2698
+ value: readyStates.indexOf("CLOSED")
2699
+ });
2700
+ [
2701
+ "binaryType",
2702
+ "bufferedAmount",
2703
+ "extensions",
2704
+ "isPaused",
2705
+ "protocol",
2706
+ "readyState",
2707
+ "url"
2708
+ ].forEach((property) => {
2709
+ Object.defineProperty(WebSocket2.prototype, property, { enumerable: true });
2710
+ });
2711
+ ["open", "error", "close", "message"].forEach((method) => {
2712
+ Object.defineProperty(WebSocket2.prototype, `on${method}`, {
2713
+ enumerable: true,
2714
+ get() {
2715
+ for (const listener of this.listeners(method)) {
2716
+ if (listener[kForOnEventAttribute]) return listener[kListener];
2717
+ }
2718
+ return null;
2719
+ },
2720
+ set(handler) {
2721
+ for (const listener of this.listeners(method)) {
2722
+ if (listener[kForOnEventAttribute]) {
2723
+ this.removeListener(method, listener);
2724
+ break;
2725
+ }
2726
+ }
2727
+ if (typeof handler !== "function") return;
2728
+ this.addEventListener(method, handler, {
2729
+ [kForOnEventAttribute]: true
2730
+ });
2731
+ }
2732
+ });
2733
+ });
2734
+ WebSocket2.prototype.addEventListener = addEventListener;
2735
+ WebSocket2.prototype.removeEventListener = removeEventListener;
2736
+ module.exports = WebSocket2;
2737
+ function initAsClient(websocket, address, protocols, options) {
2738
+ const opts = {
2739
+ allowSynchronousEvents: true,
2740
+ autoPong: true,
2741
+ closeTimeout: CLOSE_TIMEOUT,
2742
+ protocolVersion: protocolVersions[1],
2743
+ maxBufferedChunks: 256 * 1024,
2744
+ maxFragments: 16 * 1024,
2745
+ maxPayload: 100 * 1024 * 1024,
2746
+ skipUTF8Validation: false,
2747
+ perMessageDeflate: true,
2748
+ followRedirects: false,
2749
+ maxRedirects: 10,
2750
+ ...options,
2751
+ socketPath: void 0,
2752
+ hostname: void 0,
2753
+ protocol: void 0,
2754
+ protocols: void 0,
2755
+ timeout: void 0,
2756
+ method: "GET",
2757
+ host: void 0,
2758
+ path: void 0,
2759
+ port: void 0
2760
+ };
2761
+ websocket._autoPong = opts.autoPong;
2762
+ websocket._closeTimeout = opts.closeTimeout;
2763
+ if (!protocolVersions.includes(opts.protocolVersion)) {
2764
+ throw new RangeError(
2765
+ `Unsupported protocol version: ${opts.protocolVersion} (supported versions: ${protocolVersions.join(", ")})`
2766
+ );
2767
+ }
2768
+ let parsedUrl;
2769
+ if (address instanceof URL2) {
2770
+ parsedUrl = address;
2771
+ } else {
2772
+ try {
2773
+ parsedUrl = new URL2(address);
2774
+ } catch {
2775
+ throw new SyntaxError(`Invalid URL: ${address}`);
2776
+ }
2777
+ }
2778
+ if (parsedUrl.protocol === "http:") {
2779
+ parsedUrl.protocol = "ws:";
2780
+ } else if (parsedUrl.protocol === "https:") {
2781
+ parsedUrl.protocol = "wss:";
2782
+ }
2783
+ websocket._url = parsedUrl.href;
2784
+ const isSecure = parsedUrl.protocol === "wss:";
2785
+ const isIpcUrl = parsedUrl.protocol === "ws+unix:";
2786
+ let invalidUrlMessage;
2787
+ if (parsedUrl.protocol !== "ws:" && !isSecure && !isIpcUrl) {
2788
+ invalidUrlMessage = `The URL's protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"`;
2789
+ } else if (isIpcUrl && !parsedUrl.pathname) {
2790
+ invalidUrlMessage = "The URL's pathname is empty";
2791
+ } else if (parsedUrl.hash) {
2792
+ invalidUrlMessage = "The URL contains a fragment identifier";
2793
+ }
2794
+ if (invalidUrlMessage) {
2795
+ const err = new SyntaxError(invalidUrlMessage);
2796
+ if (websocket._redirects === 0) {
2797
+ throw err;
2798
+ } else {
2799
+ emitErrorAndClose(websocket, err);
2800
+ return;
2801
+ }
2802
+ }
2803
+ const defaultPort = isSecure ? 443 : 80;
2804
+ const key = randomBytes(16).toString("base64");
2805
+ const request = isSecure ? https.request : http.request;
2806
+ const protocolSet = /* @__PURE__ */ new Set();
2807
+ let perMessageDeflate;
2808
+ opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
2809
+ opts.defaultPort = opts.defaultPort || defaultPort;
2810
+ opts.port = parsedUrl.port || defaultPort;
2811
+ opts.host = parsedUrl.hostname.startsWith("[") ? parsedUrl.hostname.slice(1, -1) : parsedUrl.hostname;
2812
+ opts.headers = {
2813
+ ...opts.headers,
2814
+ "Sec-WebSocket-Version": opts.protocolVersion,
2815
+ "Sec-WebSocket-Key": key,
2816
+ Connection: "Upgrade",
2817
+ Upgrade: "websocket"
2818
+ };
2819
+ opts.path = parsedUrl.pathname + parsedUrl.search;
2820
+ opts.timeout = opts.handshakeTimeout;
2821
+ if (opts.perMessageDeflate) {
2822
+ perMessageDeflate = new PerMessageDeflate2({
2823
+ ...opts.perMessageDeflate,
2824
+ isServer: false,
2825
+ maxPayload: opts.maxPayload
2826
+ });
2827
+ opts.headers["Sec-WebSocket-Extensions"] = format({
2828
+ [PerMessageDeflate2.extensionName]: perMessageDeflate.offer()
2829
+ });
2830
+ }
2831
+ if (protocols.length) {
2832
+ for (const protocol of protocols) {
2833
+ if (typeof protocol !== "string" || !subprotocolRegex.test(protocol) || protocolSet.has(protocol)) {
2834
+ throw new SyntaxError(
2835
+ "An invalid or duplicated subprotocol was specified"
2836
+ );
2837
+ }
2838
+ protocolSet.add(protocol);
2839
+ }
2840
+ opts.headers["Sec-WebSocket-Protocol"] = protocols.join(",");
2841
+ }
2842
+ if (opts.origin) {
2843
+ if (opts.protocolVersion < 13) {
2844
+ opts.headers["Sec-WebSocket-Origin"] = opts.origin;
2845
+ } else {
2846
+ opts.headers.Origin = opts.origin;
2847
+ }
2848
+ }
2849
+ if (parsedUrl.username || parsedUrl.password) {
2850
+ opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
2851
+ }
2852
+ if (isIpcUrl) {
2853
+ const parts = opts.path.split(":");
2854
+ opts.socketPath = parts[0];
2855
+ opts.path = parts[1];
2856
+ }
2857
+ let req;
2858
+ if (opts.followRedirects) {
2859
+ if (websocket._redirects === 0) {
2860
+ websocket._originalIpc = isIpcUrl;
2861
+ websocket._originalSecure = isSecure;
2862
+ websocket._originalHostOrSocketPath = isIpcUrl ? opts.socketPath : parsedUrl.host;
2863
+ const headers = options && options.headers;
2864
+ options = { ...options, headers: {} };
2865
+ if (headers) {
2866
+ for (const [key2, value] of Object.entries(headers)) {
2867
+ options.headers[key2.toLowerCase()] = value;
2868
+ }
2869
+ }
2870
+ } else if (websocket.listenerCount("redirect") === 0) {
2871
+ const isSameHost = isIpcUrl ? websocket._originalIpc ? opts.socketPath === websocket._originalHostOrSocketPath : false : websocket._originalIpc ? false : parsedUrl.host === websocket._originalHostOrSocketPath;
2872
+ if (!isSameHost || websocket._originalSecure && !isSecure) {
2873
+ delete opts.headers.authorization;
2874
+ delete opts.headers.cookie;
2875
+ if (!isSameHost) delete opts.headers.host;
2876
+ opts.auth = void 0;
2877
+ }
2878
+ }
2879
+ if (opts.auth && !options.headers.authorization) {
2880
+ options.headers.authorization = "Basic " + Buffer.from(opts.auth).toString("base64");
2881
+ }
2882
+ req = websocket._req = request(opts);
2883
+ if (websocket._redirects) {
2884
+ websocket.emit("redirect", websocket.url, req);
2885
+ }
2886
+ } else {
2887
+ req = websocket._req = request(opts);
2888
+ }
2889
+ if (opts.timeout) {
2890
+ req.on("timeout", () => {
2891
+ abortHandshake(websocket, req, "Opening handshake has timed out");
2892
+ });
2893
+ }
2894
+ req.on("error", (err) => {
2895
+ if (req === null || req[kAborted]) return;
2896
+ req = websocket._req = null;
2897
+ emitErrorAndClose(websocket, err);
2898
+ });
2899
+ req.on("response", (res) => {
2900
+ const location = res.headers.location;
2901
+ const statusCode = res.statusCode;
2902
+ if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) {
2903
+ if (++websocket._redirects > opts.maxRedirects) {
2904
+ abortHandshake(websocket, req, "Maximum redirects exceeded");
2905
+ return;
2906
+ }
2907
+ req.abort();
2908
+ let addr;
2909
+ try {
2910
+ addr = new URL2(location, address);
2911
+ } catch (e) {
2912
+ const err = new SyntaxError(`Invalid URL: ${location}`);
2913
+ emitErrorAndClose(websocket, err);
2914
+ return;
2915
+ }
2916
+ initAsClient(websocket, addr, protocols, options);
2917
+ } else if (!websocket.emit("unexpected-response", req, res)) {
2918
+ abortHandshake(
2919
+ websocket,
2920
+ req,
2921
+ `Unexpected server response: ${res.statusCode}`
2922
+ );
2923
+ }
2924
+ });
2925
+ req.on("upgrade", (res, socket, head) => {
2926
+ websocket.emit("upgrade", res);
2927
+ if (websocket.readyState !== WebSocket2.CONNECTING) return;
2928
+ req = websocket._req = null;
2929
+ const upgrade = res.headers.upgrade;
2930
+ if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") {
2931
+ abortHandshake(websocket, socket, "Invalid Upgrade header");
2932
+ return;
2933
+ }
2934
+ const digest = createHash("sha1").update(key + GUID).digest("base64");
2935
+ if (res.headers["sec-websocket-accept"] !== digest) {
2936
+ abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
2937
+ return;
2938
+ }
2939
+ const serverProt = res.headers["sec-websocket-protocol"];
2940
+ let protError;
2941
+ if (serverProt !== void 0) {
2942
+ if (!protocolSet.size) {
2943
+ protError = "Server sent a subprotocol but none was requested";
2944
+ } else if (!protocolSet.has(serverProt)) {
2945
+ protError = "Server sent an invalid subprotocol";
2946
+ }
2947
+ } else if (protocolSet.size) {
2948
+ protError = "Server sent no subprotocol";
2949
+ }
2950
+ if (protError) {
2951
+ abortHandshake(websocket, socket, protError);
2952
+ return;
2953
+ }
2954
+ if (serverProt) websocket._protocol = serverProt;
2955
+ const secWebSocketExtensions = res.headers["sec-websocket-extensions"];
2956
+ if (secWebSocketExtensions !== void 0) {
2957
+ if (!perMessageDeflate) {
2958
+ const message = "Server sent a Sec-WebSocket-Extensions header but no extension was requested";
2959
+ abortHandshake(websocket, socket, message);
2960
+ return;
2961
+ }
2962
+ let extensions;
2963
+ try {
2964
+ extensions = parse(secWebSocketExtensions);
2965
+ } catch (err) {
2966
+ const message = "Invalid Sec-WebSocket-Extensions header";
2967
+ abortHandshake(websocket, socket, message);
2968
+ return;
2969
+ }
2970
+ const extensionNames = Object.keys(extensions);
2971
+ if (extensionNames.length !== 1 || extensionNames[0] !== PerMessageDeflate2.extensionName) {
2972
+ const message = "Server indicated an extension that was not requested";
2973
+ abortHandshake(websocket, socket, message);
2974
+ return;
2975
+ }
2976
+ try {
2977
+ perMessageDeflate.accept(extensions[PerMessageDeflate2.extensionName]);
2978
+ } catch (err) {
2979
+ const message = "Invalid Sec-WebSocket-Extensions header";
2980
+ abortHandshake(websocket, socket, message);
2981
+ return;
2982
+ }
2983
+ websocket._extensions[PerMessageDeflate2.extensionName] = perMessageDeflate;
2984
+ }
2985
+ websocket.setSocket(socket, head, {
2986
+ allowSynchronousEvents: opts.allowSynchronousEvents,
2987
+ generateMask: opts.generateMask,
2988
+ maxBufferedChunks: opts.maxBufferedChunks,
2989
+ maxFragments: opts.maxFragments,
2990
+ maxPayload: opts.maxPayload,
2991
+ skipUTF8Validation: opts.skipUTF8Validation
2992
+ });
2993
+ });
2994
+ if (opts.finishRequest) {
2995
+ opts.finishRequest(req, websocket);
2996
+ } else {
2997
+ req.end();
2998
+ }
2999
+ }
3000
+ function emitErrorAndClose(websocket, err) {
3001
+ websocket._readyState = WebSocket2.CLOSING;
3002
+ websocket._errorEmitted = true;
3003
+ websocket.emit("error", err);
3004
+ websocket.emitClose();
3005
+ }
3006
+ function netConnect(options) {
3007
+ options.path = options.socketPath;
3008
+ return net3.connect(options);
3009
+ }
3010
+ function tlsConnect(options) {
3011
+ options.path = void 0;
3012
+ if (!options.servername && options.servername !== "") {
3013
+ options.servername = net3.isIP(options.host) ? "" : options.host;
3014
+ }
3015
+ return tls.connect(options);
3016
+ }
3017
+ function abortHandshake(websocket, stream, message) {
3018
+ websocket._readyState = WebSocket2.CLOSING;
3019
+ const err = new Error(message);
3020
+ Error.captureStackTrace(err, abortHandshake);
3021
+ if (stream.setHeader) {
3022
+ stream[kAborted] = true;
3023
+ stream.abort();
3024
+ if (stream.socket && !stream.socket.destroyed) {
3025
+ stream.socket.destroy();
3026
+ }
3027
+ process.nextTick(emitErrorAndClose, websocket, err);
3028
+ } else {
3029
+ stream.destroy(err);
3030
+ stream.once("error", websocket.emit.bind(websocket, "error"));
3031
+ stream.once("close", websocket.emitClose.bind(websocket));
3032
+ }
3033
+ }
3034
+ function sendAfterClose(websocket, data, cb) {
3035
+ if (data) {
3036
+ const length = isBlob(data) ? data.size : toBuffer(data).length;
3037
+ if (websocket._socket) websocket._sender._bufferedBytes += length;
3038
+ else websocket._bufferedAmount += length;
3039
+ }
3040
+ if (cb) {
3041
+ const err = new Error(
3042
+ `WebSocket is not open: readyState ${websocket.readyState} (${readyStates[websocket.readyState]})`
3043
+ );
3044
+ process.nextTick(cb, err);
3045
+ }
3046
+ }
3047
+ function receiverOnConclude(code, reason) {
3048
+ const websocket = this[kWebSocket];
3049
+ websocket._closeFrameReceived = true;
3050
+ websocket._closeMessage = reason;
3051
+ websocket._closeCode = code;
3052
+ if (websocket._socket[kWebSocket] === void 0) return;
3053
+ websocket._socket.removeListener("data", socketOnData);
3054
+ process.nextTick(resume, websocket._socket);
3055
+ if (code === 1005) websocket.close();
3056
+ else websocket.close(code, reason);
3057
+ }
3058
+ function receiverOnDrain() {
3059
+ const websocket = this[kWebSocket];
3060
+ if (!websocket.isPaused) websocket._socket.resume();
3061
+ }
3062
+ function receiverOnError(err) {
3063
+ const websocket = this[kWebSocket];
3064
+ if (websocket._socket[kWebSocket] !== void 0) {
3065
+ websocket._socket.removeListener("data", socketOnData);
3066
+ process.nextTick(resume, websocket._socket);
3067
+ websocket.close(err[kStatusCode]);
3068
+ }
3069
+ if (!websocket._errorEmitted) {
3070
+ websocket._errorEmitted = true;
3071
+ websocket.emit("error", err);
3072
+ }
3073
+ }
3074
+ function receiverOnFinish() {
3075
+ this[kWebSocket].emitClose();
3076
+ }
3077
+ function receiverOnMessage(data, isBinary) {
3078
+ this[kWebSocket].emit("message", data, isBinary);
3079
+ }
3080
+ function receiverOnPing(data) {
3081
+ const websocket = this[kWebSocket];
3082
+ if (websocket._autoPong) websocket.pong(data, !this._isServer, NOOP);
3083
+ websocket.emit("ping", data);
3084
+ }
3085
+ function receiverOnPong(data) {
3086
+ this[kWebSocket].emit("pong", data);
3087
+ }
3088
+ function resume(stream) {
3089
+ stream.resume();
3090
+ }
3091
+ function senderOnError(err) {
3092
+ const websocket = this[kWebSocket];
3093
+ if (websocket.readyState === WebSocket2.CLOSED) return;
3094
+ if (websocket.readyState === WebSocket2.OPEN) {
3095
+ websocket._readyState = WebSocket2.CLOSING;
3096
+ setCloseTimer(websocket);
3097
+ }
3098
+ this._socket.end();
3099
+ if (!websocket._errorEmitted) {
3100
+ websocket._errorEmitted = true;
3101
+ websocket.emit("error", err);
3102
+ }
3103
+ }
3104
+ function setCloseTimer(websocket) {
3105
+ websocket._closeTimer = setTimeout(
3106
+ websocket._socket.destroy.bind(websocket._socket),
3107
+ websocket._closeTimeout
3108
+ );
3109
+ }
3110
+ function socketOnClose() {
3111
+ const websocket = this[kWebSocket];
3112
+ this.removeListener("close", socketOnClose);
3113
+ this.removeListener("data", socketOnData);
3114
+ this.removeListener("end", socketOnEnd);
3115
+ websocket._readyState = WebSocket2.CLOSING;
3116
+ if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && this._readableState.length !== 0) {
3117
+ const chunk = this.read(this._readableState.length);
3118
+ websocket._receiver.write(chunk);
3119
+ }
3120
+ websocket._receiver.end();
3121
+ this[kWebSocket] = void 0;
3122
+ clearTimeout(websocket._closeTimer);
3123
+ if (websocket._receiver._writableState.finished || websocket._receiver._writableState.errorEmitted) {
3124
+ websocket.emitClose();
3125
+ } else {
3126
+ websocket._receiver.on("error", receiverOnFinish);
3127
+ websocket._receiver.on("finish", receiverOnFinish);
3128
+ }
3129
+ }
3130
+ function socketOnData(chunk) {
3131
+ if (!this[kWebSocket]._receiver.write(chunk)) {
3132
+ this.pause();
3133
+ }
3134
+ }
3135
+ function socketOnEnd() {
3136
+ const websocket = this[kWebSocket];
3137
+ websocket._readyState = WebSocket2.CLOSING;
3138
+ websocket._receiver.end();
3139
+ this.end();
3140
+ }
3141
+ function socketOnError() {
3142
+ const websocket = this[kWebSocket];
3143
+ this.removeListener("error", socketOnError);
3144
+ this.on("error", NOOP);
3145
+ if (websocket) {
3146
+ websocket._readyState = WebSocket2.CLOSING;
3147
+ this.destroy();
3148
+ }
3149
+ }
3150
+ }
3151
+ });
3152
+
3153
+ // ../../node_modules/ws/lib/stream.js
3154
+ var require_stream = __commonJS({
3155
+ "../../node_modules/ws/lib/stream.js"(exports, module) {
3156
+ "use strict";
3157
+ var WebSocket2 = require_websocket();
3158
+ var { Duplex } = __require("stream");
3159
+ function emitClose(stream) {
3160
+ stream.emit("close");
3161
+ }
3162
+ function duplexOnEnd() {
3163
+ if (!this.destroyed && this._writableState.finished) {
3164
+ this.destroy();
3165
+ }
3166
+ }
3167
+ function duplexOnError(err) {
3168
+ this.removeListener("error", duplexOnError);
3169
+ this.destroy();
3170
+ if (this.listenerCount("error") === 0) {
3171
+ this.emit("error", err);
3172
+ }
3173
+ }
3174
+ function createWebSocketStream2(ws, options) {
3175
+ let terminateOnDestroy = true;
3176
+ const duplex = new Duplex({
3177
+ ...options,
3178
+ autoDestroy: false,
3179
+ emitClose: false,
3180
+ objectMode: false,
3181
+ writableObjectMode: false
3182
+ });
3183
+ ws.on("message", function message(msg, isBinary) {
3184
+ const data = !isBinary && duplex._readableState.objectMode ? msg.toString() : msg;
3185
+ if (!duplex.push(data)) ws.pause();
3186
+ });
3187
+ ws.once("error", function error(err) {
3188
+ if (duplex.destroyed) return;
3189
+ terminateOnDestroy = false;
3190
+ duplex.destroy(err);
3191
+ });
3192
+ ws.once("close", function close() {
3193
+ if (duplex.destroyed) return;
3194
+ duplex.push(null);
3195
+ });
3196
+ duplex._destroy = function(err, callback) {
3197
+ if (ws.readyState === ws.CLOSED) {
3198
+ callback(err);
3199
+ process.nextTick(emitClose, duplex);
3200
+ return;
3201
+ }
3202
+ let called = false;
3203
+ ws.once("error", function error(err2) {
3204
+ called = true;
3205
+ callback(err2);
3206
+ });
3207
+ ws.once("close", function close() {
3208
+ if (!called) callback(err);
3209
+ process.nextTick(emitClose, duplex);
3210
+ });
3211
+ if (terminateOnDestroy) ws.terminate();
3212
+ };
3213
+ duplex._final = function(callback) {
3214
+ if (ws.readyState === ws.CONNECTING) {
3215
+ ws.once("open", function open() {
3216
+ duplex._final(callback);
3217
+ });
3218
+ return;
3219
+ }
3220
+ if (ws._socket === null) return;
3221
+ if (ws._socket._writableState.finished) {
3222
+ callback();
3223
+ if (duplex._readableState.endEmitted) duplex.destroy();
3224
+ } else {
3225
+ ws._socket.once("finish", function finish() {
3226
+ callback();
3227
+ });
3228
+ ws.close();
3229
+ }
3230
+ };
3231
+ duplex._read = function() {
3232
+ if (ws.isPaused) ws.resume();
3233
+ };
3234
+ duplex._write = function(chunk, encoding, callback) {
3235
+ if (ws.readyState === ws.CONNECTING) {
3236
+ ws.once("open", function open() {
3237
+ duplex._write(chunk, encoding, callback);
3238
+ });
3239
+ return;
3240
+ }
3241
+ ws.send(chunk, callback);
3242
+ };
3243
+ duplex.on("end", duplexOnEnd);
3244
+ duplex.on("error", duplexOnError);
3245
+ return duplex;
3246
+ }
3247
+ module.exports = createWebSocketStream2;
3248
+ }
3249
+ });
3250
+
3251
+ // ../../node_modules/ws/lib/subprotocol.js
3252
+ var require_subprotocol = __commonJS({
3253
+ "../../node_modules/ws/lib/subprotocol.js"(exports, module) {
3254
+ "use strict";
3255
+ var { tokenChars } = require_validation();
3256
+ function parse(header) {
3257
+ const protocols = /* @__PURE__ */ new Set();
3258
+ let start = -1;
3259
+ let end = -1;
3260
+ let i = 0;
3261
+ for (i; i < header.length; i++) {
3262
+ const code = header.charCodeAt(i);
3263
+ if (end === -1 && tokenChars[code] === 1) {
3264
+ if (start === -1) start = i;
3265
+ } else if (i !== 0 && (code === 32 || code === 9)) {
3266
+ if (end === -1 && start !== -1) end = i;
3267
+ } else if (code === 44) {
3268
+ if (start === -1) {
3269
+ throw new SyntaxError(`Unexpected character at index ${i}`);
3270
+ }
3271
+ if (end === -1) end = i;
3272
+ const protocol2 = header.slice(start, end);
3273
+ if (protocols.has(protocol2)) {
3274
+ throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`);
3275
+ }
3276
+ protocols.add(protocol2);
3277
+ start = end = -1;
3278
+ } else {
3279
+ throw new SyntaxError(`Unexpected character at index ${i}`);
3280
+ }
3281
+ }
3282
+ if (start === -1 || end !== -1) {
3283
+ throw new SyntaxError("Unexpected end of input");
3284
+ }
3285
+ const protocol = header.slice(start, i);
3286
+ if (protocols.has(protocol)) {
3287
+ throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
3288
+ }
3289
+ protocols.add(protocol);
3290
+ return protocols;
3291
+ }
3292
+ module.exports = { parse };
3293
+ }
3294
+ });
3295
+
3296
+ // ../../node_modules/ws/lib/websocket-server.js
3297
+ var require_websocket_server = __commonJS({
3298
+ "../../node_modules/ws/lib/websocket-server.js"(exports, module) {
3299
+ "use strict";
3300
+ var EventEmitter = __require("events");
3301
+ var http = __require("http");
3302
+ var { Duplex } = __require("stream");
3303
+ var { createHash } = __require("crypto");
3304
+ var extension2 = require_extension();
3305
+ var PerMessageDeflate2 = require_permessage_deflate();
3306
+ var subprotocol2 = require_subprotocol();
3307
+ var WebSocket2 = require_websocket();
3308
+ var { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants();
3309
+ var keyRegex = /^[+/0-9A-Za-z]{22}==$/;
3310
+ var RUNNING = 0;
3311
+ var CLOSING = 1;
3312
+ var CLOSED = 2;
3313
+ var WebSocketServer2 = class extends EventEmitter {
3314
+ /**
3315
+ * Create a `WebSocketServer` instance.
3316
+ *
3317
+ * @param {Object} options Configuration options
3318
+ * @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
3319
+ * any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
3320
+ * multiple times in the same tick
3321
+ * @param {Boolean} [options.autoPong=true] Specifies whether or not to
3322
+ * automatically send a pong in response to a ping
3323
+ * @param {Number} [options.backlog=511] The maximum length of the queue of
3324
+ * pending connections
3325
+ * @param {Boolean} [options.clientTracking=true] Specifies whether or not to
3326
+ * track clients
3327
+ * @param {Number} [options.closeTimeout=30000] Duration in milliseconds to
3328
+ * wait for the closing handshake to finish after `websocket.close()` is
3329
+ * called
3330
+ * @param {Function} [options.handleProtocols] A hook to handle protocols
3331
+ * @param {String} [options.host] The hostname where to bind the server
3332
+ * @param {Number} [options.maxBufferedChunks=262144] The maximum number of
3333
+ * buffered data chunks
3334
+ * @param {Number} [options.maxFragments=16384] The maximum number of message
3335
+ * fragments
3336
+ * @param {Number} [options.maxPayload=104857600] The maximum allowed message
3337
+ * size
3338
+ * @param {Boolean} [options.noServer=false] Enable no server mode
3339
+ * @param {String} [options.path] Accept only connections matching this path
3340
+ * @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
3341
+ * permessage-deflate
3342
+ * @param {Number} [options.port] The port where to bind the server
3343
+ * @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S
3344
+ * server to use
3345
+ * @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
3346
+ * not to skip UTF-8 validation for text and close messages
3347
+ * @param {Function} [options.verifyClient] A hook to reject connections
3348
+ * @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`
3349
+ * class to use. It must be the `WebSocket` class or class that extends it
3350
+ * @param {Function} [callback] A listener for the `listening` event
3351
+ */
3352
+ constructor(options, callback) {
3353
+ super();
3354
+ options = {
3355
+ allowSynchronousEvents: true,
3356
+ autoPong: true,
3357
+ maxBufferedChunks: 256 * 1024,
3358
+ maxFragments: 16 * 1024,
3359
+ maxPayload: 100 * 1024 * 1024,
3360
+ skipUTF8Validation: false,
3361
+ perMessageDeflate: false,
3362
+ handleProtocols: null,
3363
+ clientTracking: true,
3364
+ closeTimeout: CLOSE_TIMEOUT,
3365
+ verifyClient: null,
3366
+ noServer: false,
3367
+ backlog: null,
3368
+ // use default (511 as implemented in net.js)
3369
+ server: null,
3370
+ host: null,
3371
+ path: null,
3372
+ port: null,
3373
+ WebSocket: WebSocket2,
3374
+ ...options
3375
+ };
3376
+ if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) {
3377
+ throw new TypeError(
3378
+ 'One and only one of the "port", "server", or "noServer" options must be specified'
3379
+ );
3380
+ }
3381
+ if (options.port != null) {
3382
+ this._server = http.createServer((req, res) => {
3383
+ const body = http.STATUS_CODES[426];
3384
+ res.writeHead(426, {
3385
+ "Content-Length": body.length,
3386
+ "Content-Type": "text/plain"
3387
+ });
3388
+ res.end(body);
3389
+ });
3390
+ this._server.listen(
3391
+ options.port,
3392
+ options.host,
3393
+ options.backlog,
3394
+ callback
3395
+ );
3396
+ } else if (options.server) {
3397
+ this._server = options.server;
3398
+ }
3399
+ if (this._server) {
3400
+ const emitConnection = this.emit.bind(this, "connection");
3401
+ this._removeListeners = addListeners(this._server, {
3402
+ listening: this.emit.bind(this, "listening"),
3403
+ error: this.emit.bind(this, "error"),
3404
+ upgrade: (req, socket, head) => {
3405
+ this.handleUpgrade(req, socket, head, emitConnection);
3406
+ }
3407
+ });
3408
+ }
3409
+ if (options.perMessageDeflate === true) options.perMessageDeflate = {};
3410
+ if (options.clientTracking) {
3411
+ this.clients = /* @__PURE__ */ new Set();
3412
+ this._shouldEmitClose = false;
3413
+ }
3414
+ this.options = options;
3415
+ this._state = RUNNING;
3416
+ }
3417
+ /**
3418
+ * Returns the bound address, the address family name, and port of the server
3419
+ * as reported by the operating system if listening on an IP socket.
3420
+ * If the server is listening on a pipe or UNIX domain socket, the name is
3421
+ * returned as a string.
3422
+ *
3423
+ * @return {(Object|String|null)} The address of the server
3424
+ * @public
3425
+ */
3426
+ address() {
3427
+ if (this.options.noServer) {
3428
+ throw new Error('The server is operating in "noServer" mode');
3429
+ }
3430
+ if (!this._server) return null;
3431
+ return this._server.address();
3432
+ }
3433
+ /**
3434
+ * Stop the server from accepting new connections and emit the `'close'` event
3435
+ * when all existing connections are closed.
3436
+ *
3437
+ * @param {Function} [cb] A one-time listener for the `'close'` event
3438
+ * @public
3439
+ */
3440
+ close(cb) {
3441
+ if (this._state === CLOSED) {
3442
+ if (cb) {
3443
+ this.once("close", () => {
3444
+ cb(new Error("The server is not running"));
3445
+ });
3446
+ }
3447
+ process.nextTick(emitClose, this);
3448
+ return;
3449
+ }
3450
+ if (cb) this.once("close", cb);
3451
+ if (this._state === CLOSING) return;
3452
+ this._state = CLOSING;
3453
+ if (this.options.noServer || this.options.server) {
3454
+ if (this._server) {
3455
+ this._removeListeners();
3456
+ this._removeListeners = this._server = null;
3457
+ }
3458
+ if (this.clients) {
3459
+ if (!this.clients.size) {
3460
+ process.nextTick(emitClose, this);
3461
+ } else {
3462
+ this._shouldEmitClose = true;
3463
+ }
3464
+ } else {
3465
+ process.nextTick(emitClose, this);
3466
+ }
3467
+ } else {
3468
+ const server = this._server;
3469
+ this._removeListeners();
3470
+ this._removeListeners = this._server = null;
3471
+ server.close(() => {
3472
+ emitClose(this);
3473
+ });
3474
+ }
3475
+ }
3476
+ /**
3477
+ * See if a given request should be handled by this server instance.
3478
+ *
3479
+ * @param {http.IncomingMessage} req Request object to inspect
3480
+ * @return {Boolean} `true` if the request is valid, else `false`
3481
+ * @public
3482
+ */
3483
+ shouldHandle(req) {
3484
+ if (this.options.path) {
3485
+ const index = req.url.indexOf("?");
3486
+ const pathname = index !== -1 ? req.url.slice(0, index) : req.url;
3487
+ if (pathname !== this.options.path) return false;
3488
+ }
3489
+ return true;
3490
+ }
3491
+ /**
3492
+ * Handle a HTTP Upgrade request.
3493
+ *
3494
+ * @param {http.IncomingMessage} req The request object
3495
+ * @param {Duplex} socket The network socket between the server and client
3496
+ * @param {Buffer} head The first packet of the upgraded stream
3497
+ * @param {Function} cb Callback
3498
+ * @public
3499
+ */
3500
+ handleUpgrade(req, socket, head, cb) {
3501
+ socket.on("error", socketOnError);
3502
+ const key = req.headers["sec-websocket-key"];
3503
+ const upgrade = req.headers.upgrade;
3504
+ const version = +req.headers["sec-websocket-version"];
3505
+ if (req.method !== "GET") {
3506
+ const message = "Invalid HTTP method";
3507
+ abortHandshakeOrEmitwsClientError(this, req, socket, 405, message);
3508
+ return;
3509
+ }
3510
+ if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") {
3511
+ const message = "Invalid Upgrade header";
3512
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
3513
+ return;
3514
+ }
3515
+ if (key === void 0 || !keyRegex.test(key)) {
3516
+ const message = "Missing or invalid Sec-WebSocket-Key header";
3517
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
3518
+ return;
3519
+ }
3520
+ if (version !== 13 && version !== 8) {
3521
+ const message = "Missing or invalid Sec-WebSocket-Version header";
3522
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {
3523
+ "Sec-WebSocket-Version": "13, 8"
3524
+ });
3525
+ return;
3526
+ }
3527
+ if (!this.shouldHandle(req)) {
3528
+ abortHandshake(socket, 400);
3529
+ return;
3530
+ }
3531
+ const secWebSocketProtocol = req.headers["sec-websocket-protocol"];
3532
+ let protocols = /* @__PURE__ */ new Set();
3533
+ if (secWebSocketProtocol !== void 0) {
3534
+ try {
3535
+ protocols = subprotocol2.parse(secWebSocketProtocol);
3536
+ } catch (err) {
3537
+ const message = "Invalid Sec-WebSocket-Protocol header";
3538
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
3539
+ return;
3540
+ }
3541
+ }
3542
+ const secWebSocketExtensions = req.headers["sec-websocket-extensions"];
3543
+ const extensions = {};
3544
+ if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) {
3545
+ const perMessageDeflate = new PerMessageDeflate2({
3546
+ ...this.options.perMessageDeflate,
3547
+ isServer: true,
3548
+ maxPayload: this.options.maxPayload
3549
+ });
3550
+ try {
3551
+ const offers = extension2.parse(secWebSocketExtensions);
3552
+ if (offers[PerMessageDeflate2.extensionName]) {
3553
+ perMessageDeflate.accept(offers[PerMessageDeflate2.extensionName]);
3554
+ extensions[PerMessageDeflate2.extensionName] = perMessageDeflate;
3555
+ }
3556
+ } catch (err) {
3557
+ const message = "Invalid or unacceptable Sec-WebSocket-Extensions header";
3558
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
3559
+ return;
3560
+ }
3561
+ }
3562
+ if (this.options.verifyClient) {
3563
+ const info = {
3564
+ origin: req.headers[`${version === 8 ? "sec-websocket-origin" : "origin"}`],
3565
+ secure: !!(req.socket.authorized || req.socket.encrypted),
3566
+ req
3567
+ };
3568
+ if (this.options.verifyClient.length === 2) {
3569
+ this.options.verifyClient(info, (verified, code, message, headers) => {
3570
+ if (!verified) {
3571
+ return abortHandshake(socket, code || 401, message, headers);
3572
+ }
3573
+ this.completeUpgrade(
3574
+ extensions,
3575
+ key,
3576
+ protocols,
3577
+ req,
3578
+ socket,
3579
+ head,
3580
+ cb
3581
+ );
3582
+ });
3583
+ return;
3584
+ }
3585
+ if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
3586
+ }
3587
+ this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
3588
+ }
3589
+ /**
3590
+ * Upgrade the connection to WebSocket.
3591
+ *
3592
+ * @param {Object} extensions The accepted extensions
3593
+ * @param {String} key The value of the `Sec-WebSocket-Key` header
3594
+ * @param {Set} protocols The subprotocols
3595
+ * @param {http.IncomingMessage} req The request object
3596
+ * @param {Duplex} socket The network socket between the server and client
3597
+ * @param {Buffer} head The first packet of the upgraded stream
3598
+ * @param {Function} cb Callback
3599
+ * @throws {Error} If called more than once with the same socket
3600
+ * @private
3601
+ */
3602
+ completeUpgrade(extensions, key, protocols, req, socket, head, cb) {
3603
+ if (!socket.readable || !socket.writable) return socket.destroy();
3604
+ if (socket[kWebSocket]) {
3605
+ throw new Error(
3606
+ "server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration"
3607
+ );
3608
+ }
3609
+ if (this._state > RUNNING) return abortHandshake(socket, 503);
3610
+ const digest = createHash("sha1").update(key + GUID).digest("base64");
3611
+ const headers = [
3612
+ "HTTP/1.1 101 Switching Protocols",
3613
+ "Upgrade: websocket",
3614
+ "Connection: Upgrade",
3615
+ `Sec-WebSocket-Accept: ${digest}`
3616
+ ];
3617
+ const ws = new this.options.WebSocket(null, void 0, this.options);
3618
+ if (protocols.size) {
3619
+ const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value;
3620
+ if (protocol) {
3621
+ headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
3622
+ ws._protocol = protocol;
3623
+ }
3624
+ }
3625
+ if (extensions[PerMessageDeflate2.extensionName]) {
3626
+ const params = extensions[PerMessageDeflate2.extensionName].params;
3627
+ const value = extension2.format({
3628
+ [PerMessageDeflate2.extensionName]: [params]
3629
+ });
3630
+ headers.push(`Sec-WebSocket-Extensions: ${value}`);
3631
+ ws._extensions = extensions;
3632
+ }
3633
+ this.emit("headers", headers, req);
3634
+ socket.write(headers.concat("\r\n").join("\r\n"));
3635
+ socket.removeListener("error", socketOnError);
3636
+ ws.setSocket(socket, head, {
3637
+ allowSynchronousEvents: this.options.allowSynchronousEvents,
3638
+ maxBufferedChunks: this.options.maxBufferedChunks,
3639
+ maxFragments: this.options.maxFragments,
3640
+ maxPayload: this.options.maxPayload,
3641
+ skipUTF8Validation: this.options.skipUTF8Validation
3642
+ });
3643
+ if (this.clients) {
3644
+ this.clients.add(ws);
3645
+ ws.on("close", () => {
3646
+ this.clients.delete(ws);
3647
+ if (this._shouldEmitClose && !this.clients.size) {
3648
+ process.nextTick(emitClose, this);
3649
+ }
3650
+ });
3651
+ }
3652
+ cb(ws, req);
3653
+ }
3654
+ };
3655
+ module.exports = WebSocketServer2;
3656
+ function addListeners(server, map) {
3657
+ for (const event of Object.keys(map)) server.on(event, map[event]);
3658
+ return function removeListeners() {
3659
+ for (const event of Object.keys(map)) {
3660
+ server.removeListener(event, map[event]);
3661
+ }
3662
+ };
3663
+ }
3664
+ function emitClose(server) {
3665
+ server._state = CLOSED;
3666
+ server.emit("close");
3667
+ }
3668
+ function socketOnError() {
3669
+ this.destroy();
3670
+ }
3671
+ function abortHandshake(socket, code, message, headers) {
3672
+ message = message || http.STATUS_CODES[code];
3673
+ headers = {
3674
+ Connection: "close",
3675
+ "Content-Type": "text/html",
3676
+ "Content-Length": Buffer.byteLength(message),
3677
+ ...headers
3678
+ };
3679
+ socket.once("finish", socket.destroy);
3680
+ socket.end(
3681
+ `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r
3682
+ ` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message
3683
+ );
3684
+ }
3685
+ function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) {
3686
+ if (server.listenerCount("wsClientError")) {
3687
+ const err = new Error(message);
3688
+ Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);
3689
+ server.emit("wsClientError", err, socket, req);
3690
+ } else {
3691
+ abortHandshake(socket, code, message, headers);
3692
+ }
3693
+ }
3694
+ }
3695
+ });
9
3696
 
10
3697
  // builtin/extensions/computer-use/src/bridge.ts
11
3698
  import { spawn as spawn4 } from "node:child_process";
12
3699
  import { randomUUID as randomUUID5 } from "node:crypto";
13
- import { constants as fsConstants5, rmSync as rmSync2 } from "node:fs";
3700
+ import { constants as fsConstants5, mkdtempSync as mkdtempSync2 } from "node:fs";
14
3701
  import { access as access4 } from "node:fs/promises";
15
3702
  import net2 from "node:net";
16
- import os4 from "node:os";
17
- import path9 from "node:path";
3703
+ import os5 from "node:os";
3704
+ import path10 from "node:path";
18
3705
 
19
3706
  // builtin/extensions/computer-use/src/platform/coerce.ts
20
3707
  function toBoolean(value) {
@@ -89,10 +3776,20 @@ function containsEditable(node) {
89
3776
  if (node.canSetValue || node.role.toLowerCase().includes("text")) return true;
90
3777
  return node.children.some(containsEditable);
91
3778
  }
3779
+ function recordActionFocus(action, state, node, coordinateFocus = false) {
3780
+ if (!["click", "press", "keypress", "typeText"].includes(action.action) || !action.ref && action.action !== "click") return;
3781
+ state.currentFocus = Boolean(node?.isTextInput && !node.pictureOnly) || coordinateFocus;
3782
+ state.focusRef = node?.isTextInput && node.wireRef && !node.pictureOnly ? node.ref : void 0;
3783
+ }
3784
+ function editorAtPoint(nodes, x, y) {
3785
+ const matches = nodes.filter((node) => node.isTextInput && node.wireRef && !node.pictureOnly && !node.offscreen && node.rect && x >= node.rect.x && x < node.rect.x + node.rect.w && y >= node.rect.y && y < node.rect.y + node.rect.h);
3786
+ return matches.length === 1 ? matches[0] : void 0;
3787
+ }
92
3788
  function prepareAction(action, state, env) {
93
3789
  const operation = action.action;
94
- const usesCurrentFocus = !env.headless && state.currentFocus && !action.ref && (operation === "typeText" || operation === "keypress");
95
- const target = usesCurrentFocus ? focusedTarget(env) : nativeTarget(action, operation, env);
3790
+ const focusedKeyboard = !env.headless && state.currentFocus && !action.ref && (operation === "typeText" || operation === "keypress");
3791
+ const usesCurrentFocus = focusedKeyboard && !state.focusRef;
3792
+ const target = usesCurrentFocus ? focusedTarget(env) : nativeTarget(focusedKeyboard && state.focusRef ? { ...action, ref: state.focusRef } : action, operation, env);
96
3793
  const establishesFocus = !env.headless && Boolean(action.ref) && (operation === "click" || operation === "press") && containsEditable(env.node(action.ref));
97
3794
  const needsForeground = !env.headless && (operation === "click" || operation === "press") && "x" in target;
98
3795
  switch (operation) {
@@ -121,6 +3818,12 @@ function outcomeAfterCheck(current, check) {
121
3818
  if (check === "failed") return "didnt";
122
3819
  return current;
123
3820
  }
3821
+ function actionFailureMessage(execution) {
3822
+ if (execution.outcome !== "didnt" && execution.verification?.status !== "failed") return void 0;
3823
+ const code = execution.error?.code ?? (execution.verification?.status === "failed" ? "postcondition_failed" : "action_failed");
3824
+ const message = execution.error?.message ?? "The requested UI action did not achieve its expected result.";
3825
+ return `${code}: ${message}`;
3826
+ }
124
3827
  function outcomeAfterObservedValues(current, actions, valueForRef) {
125
3828
  if (actions.length === 0 || actions.some((action) => action.action !== "setText" || !action.ref)) return current;
126
3829
  const matches = actions.every((action) => valueForRef(action.ref) === (action.text ?? ""));
@@ -130,6 +3833,17 @@ function outcomeAfterObservedValues(current, actions, valueForRef) {
130
3833
  // builtin/extensions/computer-use/src/cdp.ts
131
3834
  import { randomUUID } from "node:crypto";
132
3835
 
3836
+ // ../../node_modules/ws/wrapper.mjs
3837
+ var import_stream = __toESM(require_stream(), 1);
3838
+ var import_extension = __toESM(require_extension(), 1);
3839
+ var import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
3840
+ var import_receiver = __toESM(require_receiver(), 1);
3841
+ var import_sender = __toESM(require_sender(), 1);
3842
+ var import_subprotocol = __toESM(require_subprotocol(), 1);
3843
+ var import_websocket = __toESM(require_websocket(), 1);
3844
+ var import_websocket_server = __toESM(require_websocket_server(), 1);
3845
+ var wrapper_default = import_websocket.default;
3846
+
133
3847
  // builtin/extensions/computer-use/src/outline.ts
134
3848
  var DEFAULT_BUDGET = { maxDepth: 2, maxNodes: 150 };
135
3849
  function isRecord(value) {
@@ -598,6 +4312,13 @@ var CDP_CONTEXT_PREFIX = "browser:";
598
4312
  var NAVIGATE_LOAD_TIMEOUT_MS = 1e4;
599
4313
  var CONNECT_FAILURE_RETRY_MS = 5e3;
600
4314
  var CONSOLE_BUFFER_LIMIT = 20;
4315
+ var activeTabs = /* @__PURE__ */ new Set();
4316
+ var connectingSockets = /* @__PURE__ */ new Set();
4317
+ var connectionEpoch = 0;
4318
+ var disconnecting;
4319
+ function assertConnectionEpoch(epoch) {
4320
+ if (epoch !== connectionEpoch || disconnecting) throw new Error("CDP connection cancelled during shutdown.");
4321
+ }
601
4322
  var CdpTab = class _CdpTab {
602
4323
  constructor(ws, targetId, title) {
603
4324
  this.ws = ws;
@@ -611,8 +4332,10 @@ var CdpTab = class _CdpTab {
611
4332
  pending = /* @__PURE__ */ new Map();
612
4333
  consoleBuffer = [];
613
4334
  loadFired;
614
- static async connect(wsUrl, targetId, title) {
615
- const ws = new WebSocket(wsUrl);
4335
+ static async connect(wsUrl, targetId, title, epoch = connectionEpoch) {
4336
+ assertConnectionEpoch(epoch);
4337
+ const ws = new wrapper_default(wsUrl);
4338
+ connectingSockets.add(ws);
616
4339
  try {
617
4340
  await new Promise((resolve, reject) => {
618
4341
  const timer = setTimeout(() => reject(new Error(`Timed out connecting to CDP target at ${wsUrl}`)), COMMAND_TIMEOUT_MS);
@@ -624,33 +4347,60 @@ var CdpTab = class _CdpTab {
624
4347
  clearTimeout(timer);
625
4348
  reject(new Error(`Failed to connect to CDP target at ${wsUrl}`));
626
4349
  };
4350
+ ws.onclose = () => {
4351
+ clearTimeout(timer);
4352
+ reject(new Error("CDP connection closed during setup."));
4353
+ };
627
4354
  });
628
4355
  const tab = new _CdpTab(ws, targetId, title);
4356
+ activeTabs.add(tab);
4357
+ connectingSockets.delete(ws);
629
4358
  ws.onmessage = (event) => tab.handleMessage(String(event.data));
630
- ws.onclose = () => tab.rejectAllPending(new Error("CDP connection closed."));
4359
+ ws.onclose = () => {
4360
+ activeTabs.delete(tab);
4361
+ tab.rejectAllPending(new Error("CDP connection closed."));
4362
+ };
631
4363
  ws.onerror = () => tab.rejectAllPending(new Error("CDP connection error."));
632
4364
  await tab.send("Runtime.enable");
633
4365
  await tab.send("Page.enable");
4366
+ try {
4367
+ assertConnectionEpoch(epoch);
4368
+ } catch (error) {
4369
+ await tab.close();
4370
+ throw error;
4371
+ }
634
4372
  return tab;
635
4373
  } catch (error) {
636
4374
  try {
637
- ws.close();
4375
+ ws.terminate();
638
4376
  } catch {
639
4377
  }
640
4378
  throw error;
4379
+ } finally {
4380
+ connectingSockets.delete(ws);
641
4381
  }
642
4382
  }
643
4383
  get isOpen() {
644
- return this.ws.readyState === WebSocket.OPEN;
4384
+ return this.ws.readyState === wrapper_default.OPEN;
645
4385
  }
646
- close() {
4386
+ async close() {
4387
+ activeTabs.delete(this);
647
4388
  this.loadFired?.();
648
4389
  this.loadFired = void 0;
649
4390
  this.rejectAllPending(new Error("CDP connection closed."));
650
- try {
651
- this.ws.close();
652
- } catch {
653
- }
4391
+ if (this.ws.readyState === wrapper_default.CLOSED) return;
4392
+ await new Promise((resolve) => {
4393
+ const timer = setTimeout(() => {
4394
+ this.ws.terminate();
4395
+ resolve();
4396
+ }, 500);
4397
+ this.ws.once("close", () => {
4398
+ clearTimeout(timer);
4399
+ resolve();
4400
+ });
4401
+ if (this.ws.readyState === wrapper_default.CONNECTING) this.ws.terminate();
4402
+ else this.ws.close();
4403
+ });
654
4404
  }
655
4405
  /** Evaluates a JS expression in the page and returns its primitive value. */
656
4406
  async evaluate(expression) {
@@ -662,13 +4412,17 @@ var CdpTab = class _CdpTab {
662
4412
  return Array.isArray(result?.nodes) ? result.nodes : [];
663
4413
  }
664
4414
  async navigate(url) {
4415
+ let timer;
665
4416
  const loaded = new Promise((resolve) => {
666
4417
  this.loadFired = resolve;
667
4418
  });
668
4419
  try {
669
4420
  await this.send("Page.navigate", { url });
670
- await Promise.race([loaded, new Promise((resolve) => setTimeout(resolve, NAVIGATE_LOAD_TIMEOUT_MS))]);
4421
+ await Promise.race([loaded, new Promise((resolve) => {
4422
+ timer = setTimeout(resolve, NAVIGATE_LOAD_TIMEOUT_MS);
4423
+ })]);
671
4424
  } finally {
4425
+ clearTimeout(timer);
672
4426
  this.loadFired = void 0;
673
4427
  }
674
4428
  }
@@ -699,11 +4453,11 @@ var CdpTab = class _CdpTab {
699
4453
  async mouseAt(x, y, type, button = "left", clickCount2 = 1) {
700
4454
  await this.send("Input.dispatchMouseEvent", { type, x, y, button: type === "mouseMoved" ? "none" : button, clickCount: clickCount2 });
701
4455
  }
702
- async dragPath(path10) {
703
- if (path10.length < 2) throw new Error("CDP drag requires at least two points.");
704
- await this.mouseAt(path10[0].x, path10[0].y, "mousePressed");
705
- for (const point2 of path10.slice(1)) await this.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: point2.x, y: point2.y, button: "left", buttons: 1 });
706
- const end = path10[path10.length - 1];
4456
+ async dragPath(path11) {
4457
+ if (path11.length < 2) throw new Error("CDP drag requires at least two points.");
4458
+ await this.mouseAt(path11[0].x, path11[0].y, "mousePressed");
4459
+ for (const point2 of path11.slice(1)) await this.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: point2.x, y: point2.y, button: "left", buttons: 1 });
4460
+ const end = path11[path11.length - 1];
707
4461
  await this.mouseAt(end.x, end.y, "mouseReleased");
708
4462
  }
709
4463
  async withBackendNode(backendNodeId, functionDeclaration, args = []) {
@@ -809,26 +4563,40 @@ var connectedTabs = /* @__PURE__ */ new Map();
809
4563
  var connectingTabs = /* @__PURE__ */ new Map();
810
4564
  var lastConnectFailureAt = 0;
811
4565
  function disconnectCdp() {
812
- for (const tab of connectedTabs.values()) tab.close();
4566
+ if (disconnecting) return disconnecting;
4567
+ connectionEpoch++;
4568
+ const tabs = [...activeTabs];
4569
+ for (const ws of connectingSockets) ws.terminate();
4570
+ connectingSockets.clear();
813
4571
  connectedTabs.clear();
814
4572
  connectingTabs.clear();
815
4573
  lastConnectFailureAt = 0;
4574
+ disconnecting = Promise.all(tabs.map((tab) => tab.close())).then(() => void 0).finally(() => {
4575
+ disconnecting = void 0;
4576
+ });
4577
+ return disconnecting;
816
4578
  }
817
4579
  function cdpEnabled() {
818
4580
  const rawPort = process.env.PIE_COMPUTER_USE_CDP_PORT ?? "";
819
4581
  if (!/^\d+$/.test(rawPort)) return false;
820
4582
  const port = Number(rawPort);
821
- return Number.isInteger(port) && port > 0 && port <= 65535 && typeof WebSocket !== "undefined";
4583
+ return Number.isInteger(port) && port > 0 && port <= 65535 && typeof wrapper_default !== "undefined";
822
4584
  }
823
4585
  async function cdpTabForWindow(windowTitle, frame) {
4586
+ const epoch = connectionEpoch;
824
4587
  if (!cdpEnabled()) return void 0;
825
4588
  if (Date.now() - lastConnectFailureAt < CONNECT_FAILURE_RETRY_MS) return void 0;
826
- for (const tab of connectedTabs.values()) {
827
- if (tab.isOpen && titlesMatch(tab.title, windowTitle) && await tabMatchesFrame(tab, frame)) return tab;
828
- }
829
4589
  try {
830
- const pages = await cdpPages();
831
- const match = await pickTab(pages, windowTitle, frame);
4590
+ assertConnectionEpoch(epoch);
4591
+ for (const tab of connectedTabs.values()) {
4592
+ if (tab.isOpen && titlesMatch(tab.title, windowTitle) && await tabMatchesFrame(tab, frame)) {
4593
+ assertConnectionEpoch(epoch);
4594
+ if (tab.isOpen) return tab;
4595
+ }
4596
+ }
4597
+ const pages = await cdpPages(epoch);
4598
+ const match = await pickTab(pages, windowTitle, frame, epoch);
4599
+ assertConnectionEpoch(epoch);
832
4600
  if (!match) return void 0;
833
4601
  const existing = connectedTabs.get(match.id);
834
4602
  if (existing?.isOpen) {
@@ -837,19 +4605,20 @@ async function cdpTabForWindow(windowTitle, frame) {
837
4605
  }
838
4606
  let connecting = connectingTabs.get(match.id);
839
4607
  if (!connecting) {
840
- connecting = CdpTab.connect(match.webSocketDebuggerUrl, match.id, match.title);
4608
+ connecting = CdpTab.connect(match.webSocketDebuggerUrl, match.id, match.title, epoch);
841
4609
  connectingTabs.set(match.id, connecting);
842
4610
  }
843
4611
  let connected;
844
4612
  try {
845
4613
  connected = await connecting;
846
4614
  } finally {
847
- connectingTabs.delete(match.id);
4615
+ if (connectingTabs.get(match.id) === connecting) connectingTabs.delete(match.id);
848
4616
  }
4617
+ assertConnectionEpoch(epoch);
849
4618
  connectedTabs.set(match.id, connected);
850
4619
  return connected;
851
4620
  } catch {
852
- lastConnectFailureAt = Date.now();
4621
+ if (epoch === connectionEpoch && !disconnecting) lastConnectFailureAt = Date.now();
853
4622
  return void 0;
854
4623
  }
855
4624
  }
@@ -898,9 +4667,9 @@ async function cdpMouseForContext(contextId, x, y, type, button = "left", clickC
898
4667
  return true;
899
4668
  }) === true;
900
4669
  }
901
- async function cdpDragForContext(contextId, path10) {
4670
+ async function cdpDragForContext(contextId, path11) {
902
4671
  return await withCdpContextTab(contextId, async (tab) => {
903
- await tab.dragPath(path10);
4672
+ await tab.dragPath(path11);
904
4673
  return true;
905
4674
  }) === true;
906
4675
  }
@@ -911,24 +4680,29 @@ async function cdpNavigateContext(contextId, url) {
911
4680
  }) === true;
912
4681
  }
913
4682
  async function cdpEvaluateForContext(contextId, expression) {
914
- const page = await cdpPageForContext(contextId);
4683
+ const epoch = connectionEpoch;
4684
+ const page = await cdpPageForContext(contextId, epoch);
915
4685
  if (!page?.webSocketDebuggerUrl) return void 0;
916
- const tab = await CdpTab.connect(page.webSocketDebuggerUrl, page.id, page.title);
4686
+ const tab = await CdpTab.connect(page.webSocketDebuggerUrl, page.id, page.title, epoch);
917
4687
  try {
918
- return { contextId, value: await tab.evaluate(expression) };
4688
+ const value = await tab.evaluate(expression);
4689
+ assertConnectionEpoch(epoch);
4690
+ return { contextId, value };
919
4691
  } finally {
920
- tab.close();
4692
+ await tab.close();
921
4693
  }
922
4694
  }
923
4695
  async function cdpSnapshotForContext(contextId) {
924
- const page = await cdpPageForContext(contextId);
4696
+ const epoch = connectionEpoch;
4697
+ const page = await cdpPageForContext(contextId, epoch);
925
4698
  if (!page?.webSocketDebuggerUrl) return void 0;
926
- const tab = await CdpTab.connect(page.webSocketDebuggerUrl, page.id, page.title);
4699
+ const tab = await CdpTab.connect(page.webSocketDebuggerUrl, page.id, page.title, epoch);
927
4700
  try {
928
4701
  const [textValue, nodes] = await Promise.all([
929
4702
  tab.evaluate("document.body ? document.body.innerText : ''").catch(() => ""),
930
4703
  tab.accessibilityTree().catch(() => [])
931
4704
  ]);
4705
+ assertConnectionEpoch(epoch);
932
4706
  const snapshotId = randomUUID();
933
4707
  const { targets, outline } = cdpSnapshotOutline(snapshotId, nodes);
934
4708
  return {
@@ -944,30 +4718,35 @@ async function cdpSnapshotForContext(contextId) {
944
4718
  diagnostics: { cdp: "connected", targetCount: targets.length }
945
4719
  };
946
4720
  } finally {
947
- tab.close();
4721
+ await tab.close();
948
4722
  }
949
4723
  }
950
4724
  async function withCdpContextTab(contextId, run) {
951
- const page = await cdpPageForContext(contextId);
4725
+ const epoch = connectionEpoch;
4726
+ const page = await cdpPageForContext(contextId, epoch);
952
4727
  if (!page?.webSocketDebuggerUrl) return void 0;
953
- const tab = await CdpTab.connect(page.webSocketDebuggerUrl, page.id, page.title);
4728
+ const tab = await CdpTab.connect(page.webSocketDebuggerUrl, page.id, page.title, epoch);
954
4729
  try {
955
- return await run(tab);
4730
+ const result = await run(tab);
4731
+ assertConnectionEpoch(epoch);
4732
+ return result;
956
4733
  } finally {
957
- tab.close();
4734
+ await tab.close();
958
4735
  }
959
4736
  }
960
- async function cdpPageForContext(contextId) {
4737
+ async function cdpPageForContext(contextId, epoch) {
961
4738
  if (!contextId.startsWith(CDP_CONTEXT_PREFIX)) return void 0;
962
4739
  const targetId = contextId.slice(CDP_CONTEXT_PREFIX.length);
963
- const pages = await cdpPages();
4740
+ const pages = await cdpPages(epoch);
964
4741
  return pages.find((candidate) => candidate.id === targetId);
965
4742
  }
966
- async function cdpPages() {
4743
+ async function cdpPages(epoch = connectionEpoch) {
4744
+ assertConnectionEpoch(epoch);
967
4745
  if (!cdpEnabled()) return [];
968
4746
  const port = process.env.PIE_COMPUTER_USE_CDP_PORT;
969
4747
  const response = await fetch(`http://127.0.0.1:${port}/json/list`, { signal: AbortSignal.timeout(2e3) });
970
4748
  const targets = await response.json();
4749
+ assertConnectionEpoch(epoch);
971
4750
  return targets.filter(
972
4751
  (target) => target.type === "page" && target.webSocketDebuggerUrl && isLocalDebuggerWebSocket(target.webSocketDebuggerUrl, port)
973
4752
  );
@@ -1067,7 +4846,8 @@ function isLocalDebuggerWebSocket(wsUrl, expectedPort) {
1067
4846
  return false;
1068
4847
  }
1069
4848
  }
1070
- async function pickTab(pages, windowTitle, frame) {
4849
+ async function pickTab(pages, windowTitle, frame, epoch) {
4850
+ assertConnectionEpoch(epoch);
1071
4851
  const matches = pages.filter((target) => titlesMatch(target.title, windowTitle));
1072
4852
  if (matches.length === 0) return pages.length === 1 ? pages[0] : void 0;
1073
4853
  if (matches.length === 1) return matches[0];
@@ -1078,16 +4858,24 @@ async function pickTab(pages, windowTitle, frame) {
1078
4858
  let visibleFallback;
1079
4859
  for (const candidate of pool) {
1080
4860
  try {
1081
- const tab = await CdpTab.connect(candidate.webSocketDebuggerUrl, candidate.id, candidate.title);
1082
- const inFrame = await tabMatchesFrame(tab, frame, false);
1083
- const visibility = await tab.evaluate("document.visibilityState").catch(() => void 0);
1084
- tab.close();
4861
+ const tab = await CdpTab.connect(candidate.webSocketDebuggerUrl, candidate.id, candidate.title, epoch);
4862
+ let inFrame;
4863
+ let visibility;
4864
+ try {
4865
+ inFrame = await tabMatchesFrame(tab, frame, false);
4866
+ visibility = await tab.evaluate("document.visibilityState").catch(() => void 0);
4867
+ } finally {
4868
+ await tab.close();
4869
+ }
4870
+ assertConnectionEpoch(epoch);
1085
4871
  if (frame && inFrame && visibility === "visible") return candidate;
1086
4872
  if (frame && inFrame && !visibleFallback) visibleFallback = candidate;
1087
4873
  if (!frame && visibility === "visible") return candidate;
1088
4874
  } catch {
4875
+ assertConnectionEpoch(epoch);
1089
4876
  }
1090
4877
  }
4878
+ assertConnectionEpoch(epoch);
1091
4879
  return visibleFallback ?? pool[0];
1092
4880
  }
1093
4881
  async function tabMatchesFrame(tab, frame, trustOnUnknown = true) {
@@ -2022,6 +5810,9 @@ function allGranted(status, kinds) {
2022
5810
  function missingKinds(status, kinds) {
2023
5811
  return kinds.flatMap(({ kind }) => granted(status, kind) ? [] : [kind]);
2024
5812
  }
5813
+ function permissionStatusSuggestsHelperRestart(status) {
5814
+ return status.screenRecordingPreflight === true && status.screenRecording === false;
5815
+ }
2025
5816
  async function ensurePermissions(ctx, bridge, helperPath, signal) {
2026
5817
  let status = await bridge.checkPermissions(signal);
2027
5818
  if (allGranted(status, bridge.kinds)) return status;
@@ -2131,9 +5922,14 @@ async function checkPermissions(signal) {
2131
5922
  } : void 0
2132
5923
  };
2133
5924
  }
5925
+ var registeredForHelperPid;
2134
5926
  async function registerPermissions(signal) {
5927
+ const helperPid = macosHelper.diagnostics?.pid;
5928
+ if (helperPid !== void 0 && helperPid === registeredForHelperPid) return;
2135
5929
  await macosHelper.command("registerPermissions", {}, { signal, timeoutMs: 15e3 });
5930
+ registeredForHelperPid = helperPid;
2136
5931
  }
5932
+ var autoRestartAttempted = false;
2137
5933
  async function ensureMacosReady(ctx, state, signal) {
2138
5934
  await macosHelper.ensureInstalled(signal);
2139
5935
  if (!await macosHelper.ensureDaemon(signal)) {
@@ -2149,6 +5945,12 @@ async function ensureMacosReady(ctx, state, signal) {
2149
5945
  }
2150
5946
  let permissionStatus = await checkPermissions(signal);
2151
5947
  let lastPermissionCheckAt = now;
5948
+ if (!autoRestartAttempted && permissionStatusSuggestsHelperRestart(permissionStatus)) {
5949
+ autoRestartAttempted = true;
5950
+ await macosHelper.restart(signal).catch(() => void 0);
5951
+ permissionStatus = await checkPermissions(signal);
5952
+ lastPermissionCheckAt = Date.now();
5953
+ }
2152
5954
  if (!permissionStatus.accessibility || !permissionStatus.screenRecording) {
2153
5955
  const attributionHint = permissionStatus.source?.attribution === "caller" ? `Warning: the helper is not running as the installed pie-computer-use.app (executable: ${permissionStatus.source?.executablePath ?? "unknown"}). Grants made now would attach to the launching app instead. Restart Pie so the canonical helper is used.` : void 0;
2154
5956
  permissionStatus = await ensurePermissions(
@@ -3042,6 +6844,7 @@ var ResourceScheduler = class {
3042
6844
  record.tail = previous.catch(() => void 0).then(() => next);
3043
6845
  await previous.catch(() => void 0);
3044
6846
  try {
6847
+ if (this.closed) throw new Error("Computer-use session is shutting down.");
3045
6848
  return await work(record);
3046
6849
  } finally {
3047
6850
  release();
@@ -3049,6 +6852,83 @@ var ResourceScheduler = class {
3049
6852
  }
3050
6853
  };
3051
6854
 
6855
+ // builtin/extensions/computer-use/src/browser-owner.ts
6856
+ import { execFile } from "node:child_process";
6857
+ import { rm } from "node:fs/promises";
6858
+ import os4 from "node:os";
6859
+ import path9 from "node:path";
6860
+ async function requestBrowserClose(port) {
6861
+ const response = await fetch(`http://127.0.0.1:${port}/json/version`, { signal: AbortSignal.timeout(500) });
6862
+ const data = await response.json();
6863
+ if (!data.webSocketDebuggerUrl) return;
6864
+ const url = new URL(data.webSocketDebuggerUrl);
6865
+ if (url.hostname !== "127.0.0.1" && url.hostname !== "localhost") throw new Error("Owned browser exposed a non-local debugger.");
6866
+ if (url.port !== port) throw new Error("Owned browser debugger port changed.");
6867
+ await new Promise((resolve) => {
6868
+ const ws = new wrapper_default(url);
6869
+ let done = false;
6870
+ const finish = () => {
6871
+ if (done) return;
6872
+ done = true;
6873
+ clearTimeout(timer);
6874
+ ws.terminate();
6875
+ resolve();
6876
+ };
6877
+ const timer = setTimeout(finish, 700);
6878
+ ws.on("open", () => ws.send(JSON.stringify({ id: 1, method: "Browser.close" })));
6879
+ ws.on("message", finish);
6880
+ ws.on("close", finish);
6881
+ ws.on("error", finish);
6882
+ });
6883
+ }
6884
+ async function waitForExit(child, timeoutMs) {
6885
+ if (child.exitCode !== null || child.signalCode !== null) return true;
6886
+ return new Promise((resolve) => {
6887
+ const finish = () => {
6888
+ clearTimeout(timer);
6889
+ child.off("exit", finish);
6890
+ resolve(true);
6891
+ };
6892
+ const timer = setTimeout(() => {
6893
+ child.off("exit", finish);
6894
+ resolve(false);
6895
+ }, timeoutMs);
6896
+ child.once("exit", finish);
6897
+ });
6898
+ }
6899
+ async function releaseOwnedBrowser(child, port, profile) {
6900
+ if (child && child.exitCode === null && child.signalCode === null) {
6901
+ if (port) await requestBrowserClose(port).catch(() => void 0);
6902
+ if (!await waitForExit(child, 700)) {
6903
+ if (process.platform === "win32" && child.pid) {
6904
+ await new Promise((resolve, reject) => execFile("taskkill.exe", ["/PID", String(child.pid), "/T", "/F"], {
6905
+ windowsHide: true,
6906
+ timeout: 2e3
6907
+ }, (error) => {
6908
+ if (error && child.exitCode === null) reject(error);
6909
+ else resolve();
6910
+ }));
6911
+ } else child.kill("SIGTERM");
6912
+ if (!await waitForExit(child, 2e3)) {
6913
+ if (process.platform !== "win32") child.kill("SIGKILL");
6914
+ if (!await waitForExit(child, 2e3)) throw new Error("Owned browser did not exit.");
6915
+ }
6916
+ }
6917
+ }
6918
+ if (profile) {
6919
+ const resolved = path9.resolve(profile);
6920
+ if (path9.dirname(resolved) !== path9.resolve(os4.tmpdir()) || !/^pie-(chrome|helium)-cdp-/.test(path9.basename(resolved))) {
6921
+ throw new Error("Refusing to remove a profile outside the owned temporary browser directory.");
6922
+ }
6923
+ await rm(resolved, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
6924
+ }
6925
+ }
6926
+ async function releaseOwnedBrowserState(owner) {
6927
+ await releaseOwnedBrowser(owner.managedBrowser, owner.managedBrowserCdpPort, owner.managedBrowserProfileDir);
6928
+ owner.managedBrowser = void 0;
6929
+ owner.managedBrowserProfileDir = void 0;
6930
+ }
6931
+
3052
6932
  // builtin/extensions/computer-use/src/root-selection.ts
3053
6933
  function scoreWindow(window) {
3054
6934
  let score = 0;
@@ -3304,6 +7184,7 @@ var runtimeState = {
3304
7184
  };
3305
7185
  var savedStates = new SavedStates();
3306
7186
  var resourceScheduler = new ResourceScheduler();
7187
+ var shutdownInFlight;
3307
7188
  function operationState() {
3308
7189
  return savedStates.current();
3309
7190
  }
@@ -3316,17 +7197,19 @@ function persistOperation(state) {
3316
7197
  const epoch = state.epoch ?? resourceScheduler.epoch(resourceKey);
3317
7198
  savedStates.saveDesktop(state, resourceKey, epoch);
3318
7199
  }
3319
- async function shutdownComputerUseSession() {
3320
- await resourceScheduler.close();
3321
- resourceScheduler = new ResourceScheduler();
3322
- disconnectCdp();
3323
- const managedBrowser = runtimeState.managedBrowser;
3324
- runtimeState.managedBrowser = void 0;
3325
- if (managedBrowser) {
3326
- managedBrowser.kill("SIGTERM");
3327
- managedBrowser.unref();
3328
- }
3329
- removeManagedBrowserProfileDir();
7200
+ function shutdownComputerUseSession() {
7201
+ if (shutdownInFlight) return shutdownInFlight;
7202
+ shutdownInFlight = releaseComputerUseSession().finally(() => {
7203
+ shutdownInFlight = void 0;
7204
+ });
7205
+ return shutdownInFlight;
7206
+ }
7207
+ async function releaseComputerUseSession() {
7208
+ const drain = resourceScheduler.close();
7209
+ await disconnectCdp();
7210
+ await currentPlatformBackend.shutdown?.();
7211
+ await drain;
7212
+ await releaseOwnedBrowserState(runtimeState);
3330
7213
  if (runtimeState.managedBrowserCdpPort && process.env.PIE_COMPUTER_USE_CDP_PORT === runtimeState.managedBrowserCdpPort) {
3331
7214
  if (runtimeState.previousCdpPort === void 0) delete process.env.PIE_COMPUTER_USE_CDP_PORT;
3332
7215
  else process.env.PIE_COMPUTER_USE_CDP_PORT = runtimeState.previousCdpPort;
@@ -3343,7 +7226,7 @@ async function shutdownComputerUseSession() {
3343
7226
  runtimeState.permissionStatus = void 0;
3344
7227
  runtimeState.helperDiagnostics = void 0;
3345
7228
  runtimeState.lastPermissionCheckAt = 0;
3346
- await currentPlatformBackend.shutdown?.();
7229
+ resourceScheduler = new ResourceScheduler();
3347
7230
  }
3348
7231
  function currentRuntimeMode() {
3349
7232
  return isHeadlessMode() ? "stealth" : "default";
@@ -3896,6 +7779,7 @@ async function buildToolResult(tool, summary, result, execution, _signal, imageM
3896
7779
  const useDiff = Boolean(transition && !transition.useFullView);
3897
7780
  const folded = foldToBudget(result.outline);
3898
7781
  const renderedNote = renderNote(state.currentNote);
7782
+ const failure = tool === "act_ui" ? actionFailureMessage(execution) : void 0;
3899
7783
  const details = {
3900
7784
  tool,
3901
7785
  target: {
@@ -3925,7 +7809,7 @@ async function buildToolResult(tool, summary, result, execution, _signal, imageM
3925
7809
  note: state.currentNote,
3926
7810
  activation: result.activation,
3927
7811
  execution,
3928
- status: "ok",
7812
+ status: failure ? "failed" : "ok",
3929
7813
  config: getComputerUseConfig(),
3930
7814
  helper: runtimeState.helperDiagnostics,
3931
7815
  imageReason: fallbackReason?.reason
@@ -3958,12 +7842,13 @@ ${folded.text}`;
3958
7842
 
3959
7843
  ${fallbackReason.message}` : "";
3960
7844
  const deltaText = rootDeltaLines(execution).join("\n");
3961
- const content = [{ type: "text", text: `${summary}${deltaText ? `
7845
+ const outcomeSummary = failure ? `UI action failed (${failure}). Some actions may already have been delivered; do not replay blindly.` : summary;
7846
+ const content = [{ type: "text", text: `${outcomeSummary}${deltaText ? `
3962
7847
  ${deltaText}` : ""}${consoleText}${noteText}${outlineText}${fallbackText}` }];
3963
7848
  if (fallbackReason && result.look.image?.jpegBase64) {
3964
7849
  content.push({ type: "image", data: result.look.image.jpegBase64, mimeType: result.look.image.mimeType ?? "image/jpeg" });
3965
7850
  }
3966
- return { content, details };
7851
+ return { content, details, ...failure ? { isError: true } : {} };
3967
7852
  }
3968
7853
  function currentLookOrThrow() {
3969
7854
  const state = operationState();
@@ -4159,7 +8044,7 @@ async function performListWindows(params, signal) {
4159
8044
  kind: rawParams.kind
4160
8045
  };
4161
8046
  const config = getComputerUseConfig();
4162
- const desktopForest = await windowDetailsForFind(query, config, signal);
8047
+ const desktopForest = query.kind === "browser_page" ? [] : await windowDetailsForFind(query, config, signal);
4163
8048
  const includeBrowserPages = !query.pid && !query.bundleId && (!query.app || normalizeText2(query.app) === "browser") && config.browser_use;
4164
8049
  const browserForest = !includeBrowserPages ? [] : (await listCdpPageContexts().catch(() => [])).map((page) => ({
4165
8050
  app: "Browser",
@@ -4497,7 +8382,7 @@ async function performSearchUi(params, signal) {
4497
8382
  let matches = ranked.matches;
4498
8383
  let escalatedOCR = false;
4499
8384
  const look = state.currentLook;
4500
- if (shouldEscalateSearchOCR(matches, text) && look && look.readText?.requested !== "never" && !look.readText?.executed && state.lastSearchOcrEscalatedLookId !== look.lookId) {
8385
+ if (!state.contextId && shouldEscalateSearchOCR(matches, text) && look && look.readText?.requested !== "never" && !look.readText?.executed && state.lastSearchOcrEscalatedLookId !== look.lookId) {
4501
8386
  state.lastSearchOcrEscalatedLookId = look.lookId;
4502
8387
  const currentTarget = await ensureTargetWindowId(await resolveCurrentTarget(signal), signal);
4503
8388
  if (!state.resourceKey || state.epoch === void 0) throw new Error("The observation has no live resource identity. Observe again.");
@@ -4531,7 +8416,7 @@ async function performExpandUi(params, signal) {
4531
8416
  const depth = Math.max(1, Math.min(8, Math.trunc(toFiniteNumber(params.depth, 3))));
4532
8417
  const regionKey2 = noteRegionKeyForRef(outline, ref);
4533
8418
  const regionChanged = Boolean(regionKey2 && state.currentNote?.regions.some((region) => region.key === regionKey2 && region.status === "changed"));
4534
- if (target.truncated || regionChanged) {
8419
+ if (!state.contextId && (target.truncated || regionChanged)) {
4535
8420
  const currentTarget = await ensureTargetWindowId(await resolveCurrentTarget(signal), signal);
4536
8421
  const targetWireRef = wireRefForNode(target);
4537
8422
  if (!state.resourceKey || state.epoch === void 0) throw new Error("The observation has no live resource identity. Observe again.");
@@ -4602,8 +8487,10 @@ async function dispatchUiAction(action, target, look, headless, state, signal) {
4602
8487
  return executionTrace("wait", "stealth", { outcome: "worked" });
4603
8488
  }
4604
8489
  const trace = await helperAct(target, prepared, headless, signal);
4605
- if (!headless && (prepared.establishesFocus || prepared.action === "click" && "x" in prepared.target)) {
4606
- state.currentFocus = true;
8490
+ if (!headless) {
8491
+ const coordinateFocus = prepared.action === "click" && "x" in prepared.target;
8492
+ const node = action.ref ? outlineNodeByRef(action.ref.trim()) : coordinateFocus ? editorAtPoint(currentOutlineOrThrow().nodes, action.x, action.y) : void 0;
8493
+ recordActionFocus(action, state, node, coordinateFocus);
4607
8494
  }
4608
8495
  return trace;
4609
8496
  }
@@ -4842,8 +8729,8 @@ async function performBrowserTransaction(params, actions, signal) {
4842
8729
  return await refreshBrowserSnapshot(contextId, "act_ui", baseView);
4843
8730
  });
4844
8731
  }
4845
- function normalizeActionPath(path10) {
4846
- return (path10 ?? []).map((point2) => Array.isArray(point2) ? { x: toFiniteNumber(point2[0], 0), y: toFiniteNumber(point2[1], 0) } : { x: toFiniteNumber(point2.x, 0), y: toFiniteNumber(point2.y, 0) });
8732
+ function normalizeActionPath(path11) {
8733
+ return (path11 ?? []).map((point2) => Array.isArray(point2) ? { x: toFiniteNumber(point2[0], 0), y: toFiniteNumber(point2[1], 0) } : { x: toFiniteNumber(point2.x, 0), y: toFiniteNumber(point2.y, 0) });
4847
8734
  }
4848
8735
  function validateActionTarget(action) {
4849
8736
  const hasRef = Boolean(trimOrUndefined(action.ref));
@@ -4869,25 +8756,25 @@ async function performAct(params, signal) {
4869
8756
  function managedBrowserExecutableCandidates(browser) {
4870
8757
  const overrideName = browser === "helium" ? "PIE_COMPUTER_USE_HELIUM_EXECUTABLE" : "PIE_COMPUTER_USE_CHROME_EXECUTABLE";
4871
8758
  const override = trimOrUndefined(process.env[overrideName]);
4872
- if (override) return [path9.resolve(override)];
8759
+ if (override) return [path10.resolve(override)];
4873
8760
  const platformCandidates = process.platform === "darwin" ? browser === "helium" ? [
4874
8761
  "/Applications/Helium.app/Contents/MacOS/Helium",
4875
- path9.join(os4.homedir(), "Applications", "Helium.app", "Contents", "MacOS", "Helium")
8762
+ path10.join(os5.homedir(), "Applications", "Helium.app", "Contents", "MacOS", "Helium")
4876
8763
  ] : [
4877
8764
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
4878
- path9.join(os4.homedir(), "Applications", "Google Chrome.app", "Contents", "MacOS", "Google Chrome")
8765
+ path10.join(os5.homedir(), "Applications", "Google Chrome.app", "Contents", "MacOS", "Google Chrome")
4879
8766
  ] : process.platform === "win32" ? browser === "helium" ? [
4880
- process.env.LOCALAPPDATA && path9.join(process.env.LOCALAPPDATA, "Helium", "Application", "helium.exe"),
4881
- process.env.PROGRAMFILES && path9.join(process.env.PROGRAMFILES, "Helium", "Application", "helium.exe")
8767
+ process.env.LOCALAPPDATA && path10.join(process.env.LOCALAPPDATA, "Helium", "Application", "helium.exe"),
8768
+ process.env.PROGRAMFILES && path10.join(process.env.PROGRAMFILES, "Helium", "Application", "helium.exe")
4882
8769
  ] : [
4883
- process.env.LOCALAPPDATA && path9.join(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe"),
4884
- process.env.PROGRAMFILES && path9.join(process.env.PROGRAMFILES, "Google", "Chrome", "Application", "chrome.exe"),
4885
- process.env["PROGRAMFILES(X86)"] && path9.join(process.env["PROGRAMFILES(X86)"], "Google", "Chrome", "Application", "chrome.exe")
8770
+ process.env.LOCALAPPDATA && path10.join(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe"),
8771
+ process.env.PROGRAMFILES && path10.join(process.env.PROGRAMFILES, "Google", "Chrome", "Application", "chrome.exe"),
8772
+ process.env["PROGRAMFILES(X86)"] && path10.join(process.env["PROGRAMFILES(X86)"], "Google", "Chrome", "Application", "chrome.exe")
4886
8773
  ] : browser === "helium" ? [
4887
8774
  "/usr/bin/helium",
4888
8775
  "/usr/bin/helium-browser",
4889
8776
  "/opt/helium/chrome",
4890
- path9.join(os4.homedir(), ".local", "helium", "chrome")
8777
+ path10.join(os5.homedir(), ".local", "helium", "chrome")
4891
8778
  ] : [
4892
8779
  "/usr/bin/google-chrome",
4893
8780
  "/usr/bin/google-chrome-stable",
@@ -4896,7 +8783,7 @@ function managedBrowserExecutableCandidates(browser) {
4896
8783
  "/snap/bin/chromium"
4897
8784
  ];
4898
8785
  const pathNames = browser === "helium" ? process.platform === "win32" ? ["helium.exe"] : ["helium", "helium-browser"] : process.platform === "win32" ? ["chrome.exe"] : ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"];
4899
- const pathCandidates = (process.env.PATH ?? "").split(path9.delimiter).filter(Boolean).flatMap((directory) => pathNames.map((name) => path9.join(directory, name)));
8786
+ const pathCandidates = (process.env.PATH ?? "").split(path10.delimiter).filter(Boolean).flatMap((directory) => pathNames.map((name) => path10.join(directory, name)));
4900
8787
  return [.../* @__PURE__ */ new Set([...platformCandidates.filter((candidate) => Boolean(candidate)), ...pathCandidates])];
4901
8788
  }
4902
8789
  async function managedBrowserExecutable(browser) {
@@ -4938,15 +8825,6 @@ async function waitForCdpPort(port, signal) {
4938
8825
  }
4939
8826
  throw new Error(`Managed browser did not expose CDP on port ${port} within ${MANAGED_BROWSER_READY_TIMEOUT_MS}ms.`);
4940
8827
  }
4941
- function removeManagedBrowserProfileDir() {
4942
- const profileDir = runtimeState.managedBrowserProfileDir;
4943
- runtimeState.managedBrowserProfileDir = void 0;
4944
- if (!profileDir) return;
4945
- try {
4946
- rmSync2(profileDir, { recursive: true, force: true });
4947
- } catch {
4948
- }
4949
- }
4950
8828
  async function performLaunchBrowser(params, signal) {
4951
8829
  const browser = getComputerUseConfig().managed_browser;
4952
8830
  const executable = await managedBrowserExecutable(browser);
@@ -4954,10 +8832,9 @@ async function performLaunchBrowser(params, signal) {
4954
8832
  const requestedUrl = trimOrUndefined(params.url);
4955
8833
  if (requestedUrl && !/^https?:\/\//i.test(requestedUrl)) throw new Error("launch_browser.url must be an absolute HTTP(S) URL.");
4956
8834
  const url = requestedUrl ?? "about:blank";
4957
- const profileDir = path9.join(os4.tmpdir(), `pie-${browser}-cdp-${port}`);
4958
- disconnectCdp();
4959
- runtimeState.managedBrowser?.kill("SIGTERM");
4960
- removeManagedBrowserProfileDir();
8835
+ await disconnectCdp();
8836
+ await releaseOwnedBrowserState(runtimeState);
8837
+ const profileDir = mkdtempSync2(path10.join(os5.tmpdir(), `pie-${browser}-cdp-`));
4961
8838
  const args = [
4962
8839
  `--remote-debugging-port=${port}`,
4963
8840
  `--user-data-dir=${profileDir}`,
@@ -4978,9 +8855,7 @@ async function performLaunchBrowser(params, signal) {
4978
8855
  await waitForCdpPort(port, signal);
4979
8856
  } catch (error) {
4980
8857
  if (runtimeState.managedBrowser === managedBrowser) {
4981
- runtimeState.managedBrowser = void 0;
4982
- managedBrowser.kill("SIGTERM");
4983
- removeManagedBrowserProfileDir();
8858
+ await releaseOwnedBrowserState(runtimeState);
4984
8859
  if (runtimeState.previousCdpPort === void 0) delete process.env.PIE_COMPUTER_USE_CDP_PORT;
4985
8860
  else process.env.PIE_COMPUTER_USE_CDP_PORT = runtimeState.previousCdpPort;
4986
8861
  runtimeState.managedBrowserCdpPort = void 0;
@@ -5031,8 +8906,9 @@ async function performEvaluateBrowser(params) {
5031
8906
  return { content: [...successor.content, { type: "text", text: `Evaluation value: ${JSON.stringify(result.value)}` }], details };
5032
8907
  });
5033
8908
  }
5034
- async function executeTool(ctx, params, signal, run) {
5035
- const outputRef = trimOrUndefined(params?.ref)?.startsWith("@o") === true;
8909
+ async function executeTool(tool, ctx, params, signal, run) {
8910
+ if (shutdownInFlight) throw new Error("Computer-use resources are shutting down.");
8911
+ const outputRef = tool === "read_text" && trimOrUndefined(params?.ref)?.startsWith("@o") === true;
5036
8912
  const requestedStateId = outputRef ? void 0 : trimOrUndefined(params?.stateId);
5037
8913
  const stateRecord = requestedStateId ? savedStates.get(requestedStateId) : void 0;
5038
8914
  if (requestedStateId && !stateRecord) {
@@ -5040,7 +8916,15 @@ async function executeTool(ctx, params, signal, run) {
5040
8916
  }
5041
8917
  const operation = savedStates.hydrate(stateRecord);
5042
8918
  return await savedStates.operations.run(operation, async () => {
5043
- await resourceScheduler.read("session-lifecycle", async () => await ensureReady3(ctx, signal));
8919
+ const browserOnly = operation.contextId || ["launch_browser", "navigate_browser", "evaluate_browser"].includes(tool) || tool === "find_roots" && params.kind === "browser_page" || tool === "observe_ui" && runtimeState.browserContextByRoot.has(params.root ?? "");
8920
+ await resourceScheduler.read("session-lifecycle", async () => {
8921
+ if (browserOnly || outputRef) {
8922
+ loadComputerUseConfig(ctx.cwd);
8923
+ if (browserOnly && !outputRef && tool !== "find_roots" && !isBrowserUseEnabled()) {
8924
+ throw new Error("Browser use is disabled by computer-use config. Enable browser_use to control browser pages.");
8925
+ }
8926
+ } else await ensureReady3(ctx, signal);
8927
+ });
5044
8928
  throwIfAborted3(signal);
5045
8929
  const result = await run();
5046
8930
  persistOperation(operation);
@@ -5050,7 +8934,7 @@ async function executeTool(ctx, params, signal, run) {
5050
8934
  function makeToolExecutor(tool, perform) {
5051
8935
  return async (_toolCallId, params, signal, _onUpdate, ctx) => {
5052
8936
  try {
5053
- return applyOutputEnvelope(tool, await executeTool(ctx, params, signal, () => perform(params, signal)));
8937
+ return applyOutputEnvelope(tool, await executeTool(tool, ctx, params, signal, () => perform(params, signal)));
5054
8938
  } catch (error) {
5055
8939
  throw boundToolError(tool, error);
5056
8940
  }
@@ -5437,6 +9321,7 @@ async function initializeSessionState(ctx) {
5437
9321
  reconstructStateFromBranch(ctx);
5438
9322
  }
5439
9323
  function computerUseExtension(ctx) {
9324
+ ctx.registerCleanup?.(() => shutdownComputerUseSession());
5440
9325
  let actApproved = false;
5441
9326
  const confirmActOnce = async (args) => {
5442
9327
  if (actApproved) return true;
@@ -5456,9 +9341,10 @@ function computerUseExtension(ctx) {
5456
9341
  commandCtx.ui.notify(formatConfigStatus(), "info");
5457
9342
  }
5458
9343
  });
5459
- ctx.on("session:changed", () => {
9344
+ ctx.on("session:changed", async () => {
5460
9345
  actApproved = false;
5461
- void shutdownComputerUseSession().catch(() => void 0).then(() => initializeSessionState(ctx)).catch(() => void 0);
9346
+ await shutdownComputerUseSession().catch(() => void 0);
9347
+ await initializeSessionState(ctx);
5462
9348
  });
5463
9349
  }
5464
9350
  export {