auvezy-terminal-remote 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +170 -25
- package/frontend-dist/assets/eruda-BDAnC9QA.js +366 -0
- package/frontend-dist/assets/index-UEuOXzz9.css +32 -0
- package/frontend-dist/assets/index-jocTDNTY.js +335 -0
- package/frontend-dist/index.html +8 -6
- package/frontend-dist/sw.js +1 -1
- package/package.json +1 -1
- package/frontend-dist/assets/index-BALTbT9e.js +0 -325
- package/frontend-dist/assets/index-DUpRzupd.css +0 -32
package/dist/cli.js
CHANGED
|
@@ -61,9 +61,11 @@ function ensureDefaultUserConfig(input) {
|
|
|
61
61
|
const userCommands = Array.isArray(src.commands) && src.commands.length > 0 ? src.commands : null;
|
|
62
62
|
const commandsLegacy = userCommands !== null && userCommands.some((c) => typeof c.group !== "string" || c.group.length === 0);
|
|
63
63
|
const commands = userCommands === null || commandsLegacy ? DEFAULT_COMMANDS : userCommands;
|
|
64
|
-
|
|
64
|
+
const useInputBarValue = typeof src.input?.useInputBar === "boolean" ? src.input.useInputBar : DEFAULT_INPUT.useInputBar;
|
|
65
|
+
const inputPrefs = { useInputBar: useInputBarValue };
|
|
66
|
+
return { ...src, shortcuts, commands, input: inputPrefs };
|
|
65
67
|
}
|
|
66
|
-
var SHORTCUT_GROUPS, DEFAULT_SHORTCUTS, COMMAND_GROUPS, DEFAULT_COMMANDS;
|
|
68
|
+
var SHORTCUT_GROUPS, DEFAULT_SHORTCUTS, COMMAND_GROUPS, DEFAULT_COMMANDS, DEFAULT_INPUT;
|
|
67
69
|
var init_defaults = __esm({
|
|
68
70
|
"shared/dist/defaults.js"() {
|
|
69
71
|
"use strict";
|
|
@@ -253,6 +255,9 @@ var init_defaults = __esm({
|
|
|
253
255
|
}
|
|
254
256
|
];
|
|
255
257
|
DEFAULT_COMMANDS = COMMAND_GROUPS.flatMap((g) => g.items.map((c) => ({ ...c, group: g.id })));
|
|
258
|
+
DEFAULT_INPUT = {
|
|
259
|
+
useInputBar: true
|
|
260
|
+
};
|
|
256
261
|
}
|
|
257
262
|
});
|
|
258
263
|
|
|
@@ -818,7 +823,7 @@ var init_config_routes = __esm({
|
|
|
818
823
|
});
|
|
819
824
|
|
|
820
825
|
// backend/dist/constants.js
|
|
821
|
-
var WS_FLUSH_INTERVAL_MS, WS_MAX_CHUNK_BYTES, WS_HIGH_WATERMARK_BYTES, FILE_LOCK_RETRIES, FILE_LOCK_RETRY_INTERVAL_MS, FILE_LOCK_STALE_MS, IP_MONITOR_INTERVAL_MS, IP_MONITOR_STABILITY_THRESHOLD, PTY_DEFAULT_COLS, PTY_DEFAULT_ROWS, PTY_TERM_NAME, SHUTDOWN_WS_FLUSH_DELAY_MS, SHUTDOWN_FORCE_EXIT_MS, DOUBLE_CTRL_C_WINDOW_MS, PORT_FINDER_MAX_ATTEMPTS, STOP_INSTANCE_GRACE_MS, STOP_INSTANCE_POLL_INTERVAL_MS, ATTACH_RECONNECT_DELAYS_MS;
|
|
826
|
+
var WS_FLUSH_INTERVAL_MS, WS_MAX_CHUNK_BYTES, WS_HIGH_WATERMARK_BYTES, FILE_LOCK_RETRIES, FILE_LOCK_RETRY_INTERVAL_MS, FILE_LOCK_STALE_MS, IP_MONITOR_INTERVAL_MS, IP_MONITOR_STABILITY_THRESHOLD, PTY_DEFAULT_COLS, PTY_DEFAULT_ROWS, PTY_TERM_NAME, DOUBLE_PULSE_DELAY_MS, SHUTDOWN_WS_FLUSH_DELAY_MS, SHUTDOWN_FORCE_EXIT_MS, DOUBLE_CTRL_C_WINDOW_MS, PORT_FINDER_MAX_ATTEMPTS, STOP_INSTANCE_GRACE_MS, STOP_INSTANCE_POLL_INTERVAL_MS, ATTACH_RECONNECT_DELAYS_MS;
|
|
822
827
|
var init_constants2 = __esm({
|
|
823
828
|
"backend/dist/constants.js"() {
|
|
824
829
|
"use strict";
|
|
@@ -833,6 +838,7 @@ var init_constants2 = __esm({
|
|
|
833
838
|
PTY_DEFAULT_COLS = 80;
|
|
834
839
|
PTY_DEFAULT_ROWS = 24;
|
|
835
840
|
PTY_TERM_NAME = "xterm-256color";
|
|
841
|
+
DOUBLE_PULSE_DELAY_MS = 50;
|
|
836
842
|
SHUTDOWN_WS_FLUSH_DELAY_MS = 500;
|
|
837
843
|
SHUTDOWN_FORCE_EXIT_MS = 2e3;
|
|
838
844
|
DOUBLE_CTRL_C_WINDOW_MS = 500;
|
|
@@ -1627,6 +1633,16 @@ var init_pty_manager = __esm({
|
|
|
1627
1633
|
_exited = false;
|
|
1628
1634
|
_cols = PTY_DEFAULT_COLS;
|
|
1629
1635
|
_rows = PTY_DEFAULT_ROWS;
|
|
1636
|
+
/**
|
|
1637
|
+
* 当前是否处于 alt-screen(DECSET 1049 / 1047 / 47)。
|
|
1638
|
+
* 通过扫描 PTY 输出序列实时维护:
|
|
1639
|
+
* - vim/htop/tmux/less 等全屏 TUI 进入时切 true(它们自己整屏重画,对
|
|
1640
|
+
* resize 反应正常,不需要 double-pulse hack)
|
|
1641
|
+
* - claude/zsh prompt 等增量重画 TUI 始终为 false → 需要 double-pulse
|
|
1642
|
+
*/
|
|
1643
|
+
_inAltScreen = false;
|
|
1644
|
+
/** double-pulse resize 的中间帧定时器 */
|
|
1645
|
+
_doublePulseTimer = null;
|
|
1630
1646
|
get cols() {
|
|
1631
1647
|
return this._cols;
|
|
1632
1648
|
}
|
|
@@ -1662,6 +1678,7 @@ var init_pty_manager = __esm({
|
|
|
1662
1678
|
env: { ...process.env, ...opts.env }
|
|
1663
1679
|
});
|
|
1664
1680
|
this.process.onData((data) => {
|
|
1681
|
+
this.scanAltScreenToggle(data);
|
|
1665
1682
|
this.emit("data", data);
|
|
1666
1683
|
});
|
|
1667
1684
|
this.process.onExit(({ exitCode, signal }) => {
|
|
@@ -1699,6 +1716,18 @@ var init_pty_manager = __esm({
|
|
|
1699
1716
|
* webapp resize → ws → PTY.resize → emit 'resize' → broadcast →
|
|
1700
1717
|
* webapp 收到 terminal_resize → 触发 fit → 又算出同尺寸 → 再发 resize → ...
|
|
1701
1718
|
* 同尺寸跳过让链路在第二步就断掉
|
|
1719
|
+
*
|
|
1720
|
+
* Double-pulse hack(仅 normal-screen / 增量重画 TUI):
|
|
1721
|
+
* Claude Code (Ink) / blessed / prompt-toolkit / readline REPL 等用相对
|
|
1722
|
+
* 坐标增量重画的程序,收到 SIGWINCH 后只对"宽度变窄"分支才会清屏 +
|
|
1723
|
+
* 重新 layout(Ink 源码:`if (currentWidth < lastTerminalWidth) clear()`)。
|
|
1724
|
+
* 宽度变宽时既不清前帧也不重排已渲染历史 → 视觉上"没响应"。
|
|
1725
|
+
*
|
|
1726
|
+
* workaround:先 resize(cols-1) 让 Ink 走 width-shrink 分支强制清屏,
|
|
1727
|
+
* 50ms 后再 resize(cols) 回到目标尺寸。代价是程序会多一帧重画。
|
|
1728
|
+
*
|
|
1729
|
+
* alt-screen 程序(vim/tmux/htop/less)自己会在 SIGWINCH 时整屏重画,
|
|
1730
|
+
* 不需要也不应该 double-pulse(多余 SIGWINCH 让它们闪一下)→ 短路。
|
|
1702
1731
|
*/
|
|
1703
1732
|
resize(cols, rows) {
|
|
1704
1733
|
if (!this.process || this._exited)
|
|
@@ -1707,8 +1736,30 @@ var init_pty_manager = __esm({
|
|
|
1707
1736
|
logger.debug({ cols, rows }, "PTY resize \u8DF3\u8FC7\uFF08\u540C\u5C3A\u5BF8\uFF09");
|
|
1708
1737
|
return;
|
|
1709
1738
|
}
|
|
1710
|
-
logger.info({ cols, rows, prevCols: this._cols, prevRows: this._rows }, "PTY resize \u6267\u884C");
|
|
1739
|
+
logger.info({ cols, rows, prevCols: this._cols, prevRows: this._rows, alt: this._inAltScreen }, "PTY resize \u6267\u884C");
|
|
1711
1740
|
try {
|
|
1741
|
+
if (this._doublePulseTimer) {
|
|
1742
|
+
clearTimeout(this._doublePulseTimer);
|
|
1743
|
+
this._doublePulseTimer = null;
|
|
1744
|
+
}
|
|
1745
|
+
const shouldDoublePulse = !this._inAltScreen && cols > this._cols && cols > 2;
|
|
1746
|
+
if (shouldDoublePulse) {
|
|
1747
|
+
this.process.resize(cols - 1, rows);
|
|
1748
|
+
this._doublePulseTimer = setTimeout(() => {
|
|
1749
|
+
this._doublePulseTimer = null;
|
|
1750
|
+
if (!this.process || this._exited)
|
|
1751
|
+
return;
|
|
1752
|
+
try {
|
|
1753
|
+
this.process.resize(cols, rows);
|
|
1754
|
+
this._cols = cols;
|
|
1755
|
+
this._rows = rows;
|
|
1756
|
+
this.emit("resize", cols, rows);
|
|
1757
|
+
} catch (err) {
|
|
1758
|
+
logger.error({ err, cols, rows }, "PTY resize \u7B2C\u4E8C\u8109\u51B2\u5931\u8D25");
|
|
1759
|
+
}
|
|
1760
|
+
}, DOUBLE_PULSE_DELAY_MS);
|
|
1761
|
+
return;
|
|
1762
|
+
}
|
|
1712
1763
|
this.process.resize(cols, rows);
|
|
1713
1764
|
this._cols = cols;
|
|
1714
1765
|
this._rows = rows;
|
|
@@ -1723,6 +1774,10 @@ var init_pty_manager = __esm({
|
|
|
1723
1774
|
* 幂等:多次调用安全
|
|
1724
1775
|
*/
|
|
1725
1776
|
destroy() {
|
|
1777
|
+
if (this._doublePulseTimer) {
|
|
1778
|
+
clearTimeout(this._doublePulseTimer);
|
|
1779
|
+
this._doublePulseTimer = null;
|
|
1780
|
+
}
|
|
1726
1781
|
if (!this.process)
|
|
1727
1782
|
return;
|
|
1728
1783
|
try {
|
|
@@ -1733,6 +1788,32 @@ var init_pty_manager = __esm({
|
|
|
1733
1788
|
}
|
|
1734
1789
|
this.process = null;
|
|
1735
1790
|
}
|
|
1791
|
+
/**
|
|
1792
|
+
* 当前是否处于 alt-screen(仅供 resize 决策用,不暴露给上层)
|
|
1793
|
+
*/
|
|
1794
|
+
get inAltScreen() {
|
|
1795
|
+
return this._inAltScreen;
|
|
1796
|
+
}
|
|
1797
|
+
/**
|
|
1798
|
+
* 扫描 PTY 输出,识别 alt-screen 切换序列:
|
|
1799
|
+
* - DECSET 1049(最常用,xterm 标准 + 保存光标位置):进入 / 退出
|
|
1800
|
+
* - DECSET 1047(仅 alt buffer 切换):进入 / 退出
|
|
1801
|
+
* - DECSET 47(最老的 alt-buffer,无光标保存):进入 / 退出
|
|
1802
|
+
*
|
|
1803
|
+
* 不需要完整 ANSI 解析器——这三个序列形态固定,正则简单匹配即可。
|
|
1804
|
+
* 同一 chunk 内可能既有 enter 又有 exit(罕见,但可能),按顺序处理。
|
|
1805
|
+
*/
|
|
1806
|
+
scanAltScreenToggle(data) {
|
|
1807
|
+
const re = /\x1b\[\?(1049|1047|47)([hl])/g;
|
|
1808
|
+
let m;
|
|
1809
|
+
while ((m = re.exec(data)) !== null) {
|
|
1810
|
+
const isEnter = m[2] === "h";
|
|
1811
|
+
if (this._inAltScreen !== isEnter) {
|
|
1812
|
+
this._inAltScreen = isEnter;
|
|
1813
|
+
logger.debug({ inAltScreen: isEnter }, "PTY alt-screen \u72B6\u6001\u5207\u6362");
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1736
1817
|
};
|
|
1737
1818
|
}
|
|
1738
1819
|
});
|
|
@@ -2008,7 +2089,7 @@ function handleWsMessage(ws, raw, cb) {
|
|
|
2008
2089
|
break;
|
|
2009
2090
|
case "resize":
|
|
2010
2091
|
if (typeof msg.cols === "number" && typeof msg.rows === "number") {
|
|
2011
|
-
cb.onResize(msg.cols, msg.rows);
|
|
2092
|
+
cb.onResize(msg.cols, msg.rows, ws, msg.master === true);
|
|
2012
2093
|
} else {
|
|
2013
2094
|
logger.warn({ msg }, "resize \u7F3A cols/rows \u5B57\u6BB5\u6216\u7C7B\u578B\u9519\u8BEF");
|
|
2014
2095
|
}
|
|
@@ -2018,6 +2099,13 @@ function handleWsMessage(ws, raw, cb) {
|
|
|
2018
2099
|
ws.send(JSON.stringify({ type: "heartbeat", timestamp: Date.now() }));
|
|
2019
2100
|
}
|
|
2020
2101
|
break;
|
|
2102
|
+
case "client_log":
|
|
2103
|
+
if (typeof msg.message === "string" && typeof msg.level === "string") {
|
|
2104
|
+
const ts = typeof msg.ts === "number" ? new Date(msg.ts).toISOString().slice(11, 23) : "?";
|
|
2105
|
+
process.stderr.write(`[client ${ts} ${msg.level}] ${msg.message}
|
|
2106
|
+
`);
|
|
2107
|
+
}
|
|
2108
|
+
break;
|
|
2021
2109
|
default: {
|
|
2022
2110
|
const t = msg.type;
|
|
2023
2111
|
logger.warn({ type: t }, "\u672A\u77E5 WS \u6D88\u606F\u7C7B\u578B\uFF0C\u5DF2\u5FFD\u7565");
|
|
@@ -2124,6 +2212,7 @@ var init_ansi_filter = __esm({
|
|
|
2124
2212
|
});
|
|
2125
2213
|
|
|
2126
2214
|
// backend/dist/session/session-controller.js
|
|
2215
|
+
import { WebSocket as WebSocket3 } from "ws";
|
|
2127
2216
|
var SessionController;
|
|
2128
2217
|
var init_session_controller = __esm({
|
|
2129
2218
|
"backend/dist/session/session-controller.js"() {
|
|
@@ -2157,6 +2246,12 @@ var init_session_controller = __esm({
|
|
|
2157
2246
|
wsBackpressureEvents = 0;
|
|
2158
2247
|
/** 可选的 hook 接收器(阶段 3 启用) */
|
|
2159
2248
|
hookReceiver = null;
|
|
2249
|
+
/**
|
|
2250
|
+
* PTY 尺寸主控连接:声明 master=true 的客户端 WebSocket 引用。
|
|
2251
|
+
* 仅它能改 PTY cols/rows;其他客户端的 resize 被忽略。断开时自动释放
|
|
2252
|
+
* (onDisconnect 处理)。null = 无主控,先到先得
|
|
2253
|
+
*/
|
|
2254
|
+
masterClient = null;
|
|
2160
2255
|
/** ANSI 过滤器(阶段 8 启用;null = 关闭过滤直接透传) */
|
|
2161
2256
|
ansiFilter;
|
|
2162
2257
|
/** 可选的 PushService(阶段 9 启用;用于 hook 触发时推送通知) */
|
|
@@ -2340,8 +2435,18 @@ var init_session_controller = __esm({
|
|
|
2340
2435
|
onUserInput: (data) => {
|
|
2341
2436
|
this.pty.write(data);
|
|
2342
2437
|
},
|
|
2343
|
-
onResize: (cols, rows) => {
|
|
2438
|
+
onResize: (cols, rows, source, master) => {
|
|
2344
2439
|
const counts = this.ws.getClientCounts();
|
|
2440
|
+
if (master) {
|
|
2441
|
+
this.masterClient = source;
|
|
2442
|
+
logger.info({ cols, rows, type }, "PTY \u4E3B\u63A7\u5207\u6362\uFF1A\u5BA2\u6237\u7AEF\u58F0\u660E master");
|
|
2443
|
+
this.pty.resize(cols, rows);
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
if (this.masterClient && this.masterClient !== source) {
|
|
2447
|
+
logger.debug({ cols, rows }, "\u4E3B\u63A7\u88AB\u5176\u4ED6\u5BA2\u6237\u7AEF\u6301\u6709\uFF0C\u5FFD\u7565\u6B64 resize");
|
|
2448
|
+
return;
|
|
2449
|
+
}
|
|
2345
2450
|
if (counts.webapp > 0 && type === "attach") {
|
|
2346
2451
|
logger.debug({ type, cols, rows, counts }, "webapp \u5728\u7EBF\uFF0Cattach \u7684 resize \u88AB\u5FFD\u7565");
|
|
2347
2452
|
return;
|
|
@@ -2363,6 +2468,10 @@ var init_session_controller = __esm({
|
|
|
2363
2468
|
});
|
|
2364
2469
|
this.ws.onDisconnect((counts) => {
|
|
2365
2470
|
logger.debug(counts, "\u5BA2\u6237\u7AEF\u65AD\u5F00\u540E\u5269\u4F59\u7EDF\u8BA1");
|
|
2471
|
+
if (this.masterClient && this.masterClient.readyState !== WebSocket3.OPEN) {
|
|
2472
|
+
logger.info("PTY \u4E3B\u63A7\u8FDE\u63A5\u5DF2\u65AD\u5F00\uFF0C\u91CA\u653E\u4E3B\u63A7\u9501");
|
|
2473
|
+
this.masterClient = null;
|
|
2474
|
+
}
|
|
2366
2475
|
if (counts.webapp === 0 && counts.attach > 0) {
|
|
2367
2476
|
this.ws.broadcast({
|
|
2368
2477
|
type: "terminal_resize",
|
|
@@ -4215,18 +4324,30 @@ ${hint}
|
|
|
4215
4324
|
if (isHeadless) {
|
|
4216
4325
|
startPty("immediate");
|
|
4217
4326
|
} else if (mustWaitEnter) {
|
|
4218
|
-
|
|
4327
|
+
const wait = waitForUserConfirm();
|
|
4328
|
+
void wait.promise.then((r) => {
|
|
4329
|
+
if (r.done === "enter")
|
|
4330
|
+
startPty("enter");
|
|
4331
|
+
}).catch((err) => {
|
|
4219
4332
|
logger.error({ err }, "\u7B49\u5F85 Enter \u5931\u8D25");
|
|
4220
4333
|
shutdown(1);
|
|
4221
4334
|
});
|
|
4222
4335
|
} else {
|
|
4336
|
+
const wait = waitForUserConfirm({ silent: true });
|
|
4337
|
+
const triggerSpawn = (reason) => {
|
|
4338
|
+
wait.cancel();
|
|
4339
|
+
startPty(reason);
|
|
4340
|
+
};
|
|
4223
4341
|
ws.onConnect((_ws, type) => {
|
|
4224
4342
|
if (type === "webapp")
|
|
4225
|
-
|
|
4343
|
+
triggerSpawn("webapp");
|
|
4344
|
+
});
|
|
4345
|
+
void wait.promise.then((r) => {
|
|
4346
|
+
if (r.done === "enter")
|
|
4347
|
+
triggerSpawn("enter");
|
|
4226
4348
|
});
|
|
4227
|
-
void waitForUserConfirm({ silent: true }).then(() => startPty("enter"));
|
|
4228
4349
|
if (cfg.spawnTimeoutSec > 0) {
|
|
4229
|
-
setTimeout(() =>
|
|
4350
|
+
setTimeout(() => triggerSpawn("timeout"), cfg.spawnTimeoutSec * 1e3).unref();
|
|
4230
4351
|
}
|
|
4231
4352
|
}
|
|
4232
4353
|
void registry.register({
|
|
@@ -4308,28 +4429,52 @@ function collectLocalHostnames() {
|
|
|
4308
4429
|
return set;
|
|
4309
4430
|
}
|
|
4310
4431
|
function waitForUserConfirm(opts = {}) {
|
|
4311
|
-
if (!process.stdin.isTTY)
|
|
4312
|
-
return
|
|
4432
|
+
if (!process.stdin.isTTY) {
|
|
4433
|
+
return {
|
|
4434
|
+
promise: Promise.resolve({ done: "enter" }),
|
|
4435
|
+
cancel: () => {
|
|
4436
|
+
}
|
|
4437
|
+
};
|
|
4438
|
+
}
|
|
4313
4439
|
if (!opts.silent) {
|
|
4314
4440
|
process.stderr.write(" \u6309 Enter \u542F\u52A8\u5B50\u8FDB\u7A0B\uFF08\u6216 Ctrl+C \u9000\u51FA backend\uFF09...");
|
|
4315
4441
|
}
|
|
4316
|
-
|
|
4317
|
-
|
|
4442
|
+
let cancelled = false;
|
|
4443
|
+
let onData = null;
|
|
4444
|
+
let resolveFn = null;
|
|
4445
|
+
const detach = () => {
|
|
4446
|
+
if (onData) {
|
|
4447
|
+
process.stdin.removeListener("data", onData);
|
|
4448
|
+
onData = null;
|
|
4449
|
+
}
|
|
4450
|
+
};
|
|
4451
|
+
const promise = new Promise((resolve9) => {
|
|
4452
|
+
resolveFn = resolve9;
|
|
4453
|
+
onData = (chunk) => {
|
|
4454
|
+
if (cancelled)
|
|
4455
|
+
return;
|
|
4318
4456
|
if (chunk.length === 0)
|
|
4319
4457
|
return;
|
|
4320
|
-
|
|
4321
|
-
if (!opts.silent)
|
|
4458
|
+
detach();
|
|
4459
|
+
if (!opts.silent)
|
|
4322
4460
|
process.stderr.write("\r\x1B[K");
|
|
4323
|
-
}
|
|
4324
|
-
resolve9();
|
|
4325
|
-
};
|
|
4326
|
-
const cleanup = () => {
|
|
4327
|
-
process.stdin.removeListener("data", onData);
|
|
4328
|
-
process.stdin.pause();
|
|
4461
|
+
resolve9({ done: "enter" });
|
|
4329
4462
|
};
|
|
4330
4463
|
process.stdin.resume();
|
|
4331
4464
|
process.stdin.on("data", onData);
|
|
4332
4465
|
});
|
|
4466
|
+
return {
|
|
4467
|
+
promise,
|
|
4468
|
+
cancel: () => {
|
|
4469
|
+
if (cancelled)
|
|
4470
|
+
return;
|
|
4471
|
+
cancelled = true;
|
|
4472
|
+
detach();
|
|
4473
|
+
if (!opts.silent)
|
|
4474
|
+
process.stderr.write("\r\x1B[K");
|
|
4475
|
+
resolveFn?.({ done: "cancelled" });
|
|
4476
|
+
}
|
|
4477
|
+
};
|
|
4333
4478
|
}
|
|
4334
4479
|
var BUILTIN_FULL_ALT_TUIS;
|
|
4335
4480
|
var init_index = __esm({
|
|
@@ -4454,7 +4599,7 @@ var init_cli_stop = __esm({
|
|
|
4454
4599
|
});
|
|
4455
4600
|
|
|
4456
4601
|
// backend/dist/attach/attach-client.js
|
|
4457
|
-
import
|
|
4602
|
+
import WebSocket4 from "ws";
|
|
4458
4603
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
4459
4604
|
function normalizeAttachUrl(input) {
|
|
4460
4605
|
let url;
|
|
@@ -4509,7 +4654,7 @@ var init_attach_client = __esm({
|
|
|
4509
4654
|
if (this.destroyed)
|
|
4510
4655
|
return;
|
|
4511
4656
|
this.setStatus("connecting");
|
|
4512
|
-
const ws = new
|
|
4657
|
+
const ws = new WebSocket4(this.url);
|
|
4513
4658
|
this.ws = ws;
|
|
4514
4659
|
ws.on("open", () => {
|
|
4515
4660
|
this.reconnectAttempt = 0;
|
|
@@ -4574,7 +4719,7 @@ var init_attach_client = __esm({
|
|
|
4574
4719
|
}
|
|
4575
4720
|
// ────────────────── 内部 ──────────────────
|
|
4576
4721
|
send(msg) {
|
|
4577
|
-
if (!this.ws || this.ws.readyState !==
|
|
4722
|
+
if (!this.ws || this.ws.readyState !== WebSocket4.OPEN)
|
|
4578
4723
|
return;
|
|
4579
4724
|
try {
|
|
4580
4725
|
this.ws.send(JSON.stringify(msg));
|