sessix-server 0.2.6 → 0.2.7
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/index.js +190 -16
- package/dist/server.d.ts +2 -0
- package/dist/server.js +172 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -46,7 +46,10 @@ var zh = {
|
|
|
46
46
|
autoDiscoveryHint: " \u5982\u5728\u516C\u5171\u7F51\u7EDC\uFF0C\u5EFA\u8BAE\u5173\u95ED: SESSIX_AUTO_CONNECT=false npx sessix-server",
|
|
47
47
|
autoDiscoveryOff: " \u2139\uFE0F \u81EA\u52A8\u53D1\u73B0\u5DF2\u5173\u95ED\uFF0C\u624B\u673A\u9700\u624B\u52A8\u8F93\u5165\u5730\u5740\u8FDE\u63A5",
|
|
48
48
|
pairingOpen: " \u{1F513} \u914D\u5BF9\u6A21\u5F0F\u5DF2\u5F00\u542F\uFF085 \u5206\u949F\u5185\u6709\u6548\uFF09\u2014 \u6309 p \u91CD\u65B0\u5F00\u542F",
|
|
49
|
+
pressT: " \u{1F511} \u6309 t \u91CD\u7F6E Token\uFF08\u6CC4\u9732\u540E\u5237\u65B0\uFF09",
|
|
49
50
|
pairingReopened: "\u{1F513} \u914D\u5BF9\u6A21\u5F0F\u5DF2\u91CD\u65B0\u5F00\u542F\uFF085 \u5206\u949F\uFF09",
|
|
51
|
+
tokenRegenerated: "\u{1F511} Token \u5DF2\u91CD\u7F6E\uFF0C\u6240\u6709\u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\uFF0C\u8BF7\u91CD\u65B0\u626B\u7801\u914D\u5BF9",
|
|
52
|
+
tokenRegenerateFailed: "Token \u91CD\u7F6E\u5931\u8D25:",
|
|
50
53
|
updateAvailable: "\u53D1\u73B0\u65B0\u7248\u672C v{{latest}}\uFF08\u5F53\u524D v{{current}}\uFF09\uFF0C\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u66F4\u65B0\uFF1A",
|
|
51
54
|
receivedSignal: "\u6536\u5230 {{signal}}\uFF0C\u6B63\u5728\u4F18\u96C5\u5173\u95ED...",
|
|
52
55
|
goodbye: "\u6240\u6709\u670D\u52A1\u5DF2\u5173\u95ED\uFF0C\u518D\u89C1\uFF01",
|
|
@@ -75,7 +78,8 @@ var zh = {
|
|
|
75
78
|
activityPushEnabled: "ActivityKit Push \u5DF2\u542F\u7528",
|
|
76
79
|
activityPushFailed: "ActivityKit Push \u521D\u59CB\u5316\u5931\u8D25:",
|
|
77
80
|
activityPushContinue: "\u7EE7\u7EED\u542F\u52A8\uFF08Live Activity \u540E\u53F0\u63A8\u9001\u4E0D\u53EF\u7528\uFF09",
|
|
78
|
-
noActiveLoginProcess: "\u6CA1\u6709\u6D3B\u8DC3\u7684\u767B\u5F55\u8FDB\u7A0B"
|
|
81
|
+
noActiveLoginProcess: "\u6CA1\u6709\u6D3B\u8DC3\u7684\u767B\u5F55\u8FDB\u7A0B",
|
|
82
|
+
tokenRegenerated: "Token \u5DF2\u91CD\u7F6E: {{token}}"
|
|
79
83
|
},
|
|
80
84
|
ws: {
|
|
81
85
|
started: "WebSocket \u670D\u52A1\u5DF2\u542F\u52A8\uFF0C\u7AEF\u53E3 {{port}}",
|
|
@@ -152,7 +156,10 @@ var en = {
|
|
|
152
156
|
autoDiscoveryHint: " On public networks, disable with: SESSIX_AUTO_CONNECT=false npx sessix-server",
|
|
153
157
|
autoDiscoveryOff: " Auto-discovery disabled, phone must enter address manually",
|
|
154
158
|
pairingOpen: " \u{1F513} Pairing mode open (5 min) \u2014 press p to reopen",
|
|
159
|
+
pressT: " \u{1F511} Press t to regenerate token (refresh after leak)",
|
|
155
160
|
pairingReopened: "\u{1F513} Pairing mode reopened (5 min)",
|
|
161
|
+
tokenRegenerated: "\u{1F511} Token regenerated, all clients disconnected. Scan QR to re-pair",
|
|
162
|
+
tokenRegenerateFailed: "Token regeneration failed:",
|
|
156
163
|
updateAvailable: "New version v{{latest}} available (current v{{current}}). Update with:",
|
|
157
164
|
receivedSignal: "Received {{signal}}, graceful shutdown...",
|
|
158
165
|
goodbye: "All services closed, goodbye!",
|
|
@@ -181,7 +188,8 @@ var en = {
|
|
|
181
188
|
activityPushEnabled: "ActivityKit Push enabled",
|
|
182
189
|
activityPushFailed: "ActivityKit Push init failed:",
|
|
183
190
|
activityPushContinue: "Continuing startup (Live Activity background push unavailable)",
|
|
184
|
-
noActiveLoginProcess: "No active login process"
|
|
191
|
+
noActiveLoginProcess: "No active login process",
|
|
192
|
+
tokenRegenerated: "Token regenerated: {{token}}"
|
|
185
193
|
},
|
|
186
194
|
ws: {
|
|
187
195
|
started: "WebSocket server started on port {{port}}",
|
|
@@ -287,11 +295,11 @@ function t(key, params) {
|
|
|
287
295
|
}
|
|
288
296
|
|
|
289
297
|
// src/server.ts
|
|
290
|
-
var
|
|
298
|
+
var import_uuid5 = require("uuid");
|
|
291
299
|
var import_promises4 = require("fs/promises");
|
|
292
300
|
var import_node_os6 = require("os");
|
|
293
301
|
var import_node_path5 = require("path");
|
|
294
|
-
var
|
|
302
|
+
var import_node_child_process5 = require("child_process");
|
|
295
303
|
var import_node_util = require("util");
|
|
296
304
|
|
|
297
305
|
// src/providers/ProcessProvider.ts
|
|
@@ -1538,6 +1546,13 @@ var WsBridge = class _WsBridge {
|
|
|
1538
1546
|
getConnectionCount() {
|
|
1539
1547
|
return this.wss.clients.size;
|
|
1540
1548
|
}
|
|
1549
|
+
/** 更新 token 并断开所有现有连接(token 刷新后需重新配对) */
|
|
1550
|
+
updateToken(newToken) {
|
|
1551
|
+
this.token = newToken;
|
|
1552
|
+
for (const ws of this.wss.clients) {
|
|
1553
|
+
ws.close(4001, "Token regenerated");
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1541
1556
|
/** 优雅关闭 WebSocket 服务 */
|
|
1542
1557
|
close() {
|
|
1543
1558
|
return new Promise((resolve, reject) => {
|
|
@@ -1977,6 +1992,10 @@ var ApprovalProxy = class _ApprovalProxy {
|
|
|
1977
1992
|
});
|
|
1978
1993
|
}
|
|
1979
1994
|
}
|
|
1995
|
+
/** 更新 token(token 刷新时调用) */
|
|
1996
|
+
updateToken(newToken) {
|
|
1997
|
+
this.token = newToken;
|
|
1998
|
+
}
|
|
1980
1999
|
/** 返回连接 token(仅本机访问) */
|
|
1981
2000
|
handleToken(req, res) {
|
|
1982
2001
|
const remoteAddress = req.socket.remoteAddress;
|
|
@@ -3245,6 +3264,9 @@ var PairingManager = class {
|
|
|
3245
3264
|
this.close();
|
|
3246
3265
|
return result;
|
|
3247
3266
|
}
|
|
3267
|
+
updateToken(newToken) {
|
|
3268
|
+
this.token = newToken;
|
|
3269
|
+
}
|
|
3248
3270
|
getRemainingSeconds() {
|
|
3249
3271
|
if (this._state !== "open") return 0;
|
|
3250
3272
|
return Math.max(0, Math.ceil((this.deadline - Date.now()) / 1e3));
|
|
@@ -3377,9 +3399,98 @@ var AuthManager = class extends import_events2.EventEmitter {
|
|
|
3377
3399
|
|
|
3378
3400
|
// src/server.ts
|
|
3379
3401
|
var import_promises5 = require("fs/promises");
|
|
3402
|
+
|
|
3403
|
+
// src/terminal/TerminalExecutor.ts
|
|
3404
|
+
var import_node_child_process4 = require("child_process");
|
|
3405
|
+
var import_uuid4 = require("uuid");
|
|
3406
|
+
var EXEC_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
3407
|
+
var TerminalExecutor = class {
|
|
3408
|
+
processes = /* @__PURE__ */ new Map();
|
|
3409
|
+
eventCallbacks = [];
|
|
3410
|
+
onEvent(callback) {
|
|
3411
|
+
this.eventCallbacks.push(callback);
|
|
3412
|
+
return () => {
|
|
3413
|
+
const idx = this.eventCallbacks.indexOf(callback);
|
|
3414
|
+
if (idx !== -1) this.eventCallbacks.splice(idx, 1);
|
|
3415
|
+
};
|
|
3416
|
+
}
|
|
3417
|
+
emit(event) {
|
|
3418
|
+
for (const cb of this.eventCallbacks) {
|
|
3419
|
+
try {
|
|
3420
|
+
cb(event);
|
|
3421
|
+
} catch (err) {
|
|
3422
|
+
console.error("[TerminalExecutor] Event callback error:", err);
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
exec(sessionId, command, cwd) {
|
|
3427
|
+
const execId = (0, import_uuid4.v4)();
|
|
3428
|
+
const shell = isWindows ? "powershell" : "bash";
|
|
3429
|
+
const args = isWindows ? ["-Command", command] : ["-c", command];
|
|
3430
|
+
const proc = (0, import_node_child_process4.spawn)(shell, args, {
|
|
3431
|
+
cwd,
|
|
3432
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3433
|
+
env: { ...process.env }
|
|
3434
|
+
});
|
|
3435
|
+
this.processes.set(execId, proc);
|
|
3436
|
+
proc.stdout?.on("data", (chunk) => {
|
|
3437
|
+
this.emit({
|
|
3438
|
+
type: "terminal_output",
|
|
3439
|
+
sessionId,
|
|
3440
|
+
execId,
|
|
3441
|
+
stream: "stdout",
|
|
3442
|
+
data: chunk.toString()
|
|
3443
|
+
});
|
|
3444
|
+
});
|
|
3445
|
+
proc.stderr?.on("data", (chunk) => {
|
|
3446
|
+
this.emit({
|
|
3447
|
+
type: "terminal_output",
|
|
3448
|
+
sessionId,
|
|
3449
|
+
execId,
|
|
3450
|
+
stream: "stderr",
|
|
3451
|
+
data: chunk.toString()
|
|
3452
|
+
});
|
|
3453
|
+
});
|
|
3454
|
+
proc.on("exit", (code, signal) => {
|
|
3455
|
+
clearTimeout(timer);
|
|
3456
|
+
this.processes.delete(execId);
|
|
3457
|
+
this.emit({
|
|
3458
|
+
type: "terminal_exit",
|
|
3459
|
+
sessionId,
|
|
3460
|
+
execId,
|
|
3461
|
+
code,
|
|
3462
|
+
signal
|
|
3463
|
+
});
|
|
3464
|
+
});
|
|
3465
|
+
const timer = setTimeout(() => {
|
|
3466
|
+
if (this.processes.has(execId)) {
|
|
3467
|
+
killProcessCrossPlatform(proc);
|
|
3468
|
+
}
|
|
3469
|
+
}, EXEC_TIMEOUT_MS);
|
|
3470
|
+
console.log(`[TerminalExecutor] exec ${execId}: ${command.substring(0, 100)} (cwd: ${cwd})`);
|
|
3471
|
+
return execId;
|
|
3472
|
+
}
|
|
3473
|
+
kill(execId) {
|
|
3474
|
+
const proc = this.processes.get(execId);
|
|
3475
|
+
if (proc) {
|
|
3476
|
+
killProcessCrossPlatform(proc);
|
|
3477
|
+
console.log(`[TerminalExecutor] kill ${execId}`);
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
destroy() {
|
|
3481
|
+
for (const [execId, proc] of this.processes) {
|
|
3482
|
+
killProcessCrossPlatform(proc);
|
|
3483
|
+
console.log(`[TerminalExecutor] cleanup ${execId}`);
|
|
3484
|
+
}
|
|
3485
|
+
this.processes.clear();
|
|
3486
|
+
this.eventCallbacks.length = 0;
|
|
3487
|
+
}
|
|
3488
|
+
};
|
|
3489
|
+
|
|
3490
|
+
// src/server.ts
|
|
3380
3491
|
var WS_PORT = 3745;
|
|
3381
3492
|
var HTTP_PORT = 3746;
|
|
3382
|
-
var execAsync = (0, import_node_util.promisify)(
|
|
3493
|
+
var execAsync = (0, import_node_util.promisify)(import_node_child_process5.exec);
|
|
3383
3494
|
async function killPortProcess(port) {
|
|
3384
3495
|
try {
|
|
3385
3496
|
if (isWindows) {
|
|
@@ -3434,7 +3545,7 @@ async function start(opts = {}) {
|
|
|
3434
3545
|
try {
|
|
3435
3546
|
token = (await (0, import_promises4.readFile)(tokenFile, "utf8")).trim();
|
|
3436
3547
|
} catch {
|
|
3437
|
-
token = (0,
|
|
3548
|
+
token = (0, import_uuid5.v4)();
|
|
3438
3549
|
await (0, import_promises4.mkdir)(configDir, { recursive: true });
|
|
3439
3550
|
await (0, import_promises4.writeFile)(tokenFile, token, "utf8");
|
|
3440
3551
|
}
|
|
@@ -3442,6 +3553,20 @@ async function start(opts = {}) {
|
|
|
3442
3553
|
}
|
|
3443
3554
|
const provider = new ProcessProvider();
|
|
3444
3555
|
const sessionManager = new SessionManager(provider);
|
|
3556
|
+
const terminalExecutor = new TerminalExecutor();
|
|
3557
|
+
const wsBridge = await createWithRetry(
|
|
3558
|
+
"WsBridge",
|
|
3559
|
+
WS_PORT,
|
|
3560
|
+
() => WsBridge.create({ port: WS_PORT, token })
|
|
3561
|
+
);
|
|
3562
|
+
const unreadSessionIds = /* @__PURE__ */ new Set();
|
|
3563
|
+
sessionManager.onEvent((event) => {
|
|
3564
|
+
if (event.type === "status_change" && (event.status === "idle" || event.status === "error")) {
|
|
3565
|
+
if (!wsBridge.isViewingSession(event.sessionId)) {
|
|
3566
|
+
unreadSessionIds.add(event.sessionId);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
});
|
|
3445
3570
|
const expoChannel = new ExpoNotificationChannel();
|
|
3446
3571
|
const notificationService = new NotificationService(sessionManager, expoChannel);
|
|
3447
3572
|
notificationService.addChannel("expo", expoChannel, opts.enableExpoPush !== false);
|
|
@@ -3456,11 +3581,6 @@ async function start(opts = {}) {
|
|
|
3456
3581
|
console.log(`[Server] ${t("server.activityPushContinue")}`);
|
|
3457
3582
|
}
|
|
3458
3583
|
}
|
|
3459
|
-
const wsBridge = await createWithRetry(
|
|
3460
|
-
"WsBridge",
|
|
3461
|
-
WS_PORT,
|
|
3462
|
-
() => WsBridge.create({ port: WS_PORT, token })
|
|
3463
|
-
);
|
|
3464
3584
|
const sessionFileWatcher = new SessionFileWatcher((event) => {
|
|
3465
3585
|
wsBridge.broadcast(event);
|
|
3466
3586
|
});
|
|
@@ -3489,7 +3609,6 @@ async function start(opts = {}) {
|
|
|
3489
3609
|
});
|
|
3490
3610
|
}
|
|
3491
3611
|
});
|
|
3492
|
-
const unreadSessionIds = /* @__PURE__ */ new Set();
|
|
3493
3612
|
notificationService.setGlobalPendingCountProvider(
|
|
3494
3613
|
() => approvalProxy.getPendingCount() + sessionManager.getAllPendingQuestions().length + unreadSessionIds.size
|
|
3495
3614
|
);
|
|
@@ -3520,6 +3639,8 @@ async function start(opts = {}) {
|
|
|
3520
3639
|
switch (event.type) {
|
|
3521
3640
|
case "create_session": {
|
|
3522
3641
|
await (0, import_promises4.mkdir)(event.projectPath, { recursive: true });
|
|
3642
|
+
const resumeId = event.resumeSessionId ?? event.newSessionId;
|
|
3643
|
+
if (resumeId) sessionFileWatcher.unwatch(resumeId);
|
|
3523
3644
|
await sessionManager.createSession(
|
|
3524
3645
|
event.projectPath,
|
|
3525
3646
|
event.message,
|
|
@@ -3537,6 +3658,7 @@ async function start(opts = {}) {
|
|
|
3537
3658
|
break;
|
|
3538
3659
|
}
|
|
3539
3660
|
case "send_message": {
|
|
3661
|
+
sessionFileWatcher.unwatch(event.sessionId);
|
|
3540
3662
|
await sessionManager.sendMessage(event.sessionId, event.message, event.permissionMode, event.images);
|
|
3541
3663
|
wsBridge.broadcast({
|
|
3542
3664
|
type: "session_list",
|
|
@@ -3625,6 +3747,10 @@ async function start(opts = {}) {
|
|
|
3625
3747
|
code: "PROJECT_LIST_ERROR"
|
|
3626
3748
|
});
|
|
3627
3749
|
}
|
|
3750
|
+
wsBridge.send(ws, {
|
|
3751
|
+
type: "session_list",
|
|
3752
|
+
sessions: sessionManager.getActiveSessions()
|
|
3753
|
+
});
|
|
3628
3754
|
break;
|
|
3629
3755
|
}
|
|
3630
3756
|
case "list_sessions": {
|
|
@@ -3719,6 +3845,20 @@ async function start(opts = {}) {
|
|
|
3719
3845
|
notificationService.setSoundPreferences(event.preferences);
|
|
3720
3846
|
break;
|
|
3721
3847
|
}
|
|
3848
|
+
case "terminal_exec": {
|
|
3849
|
+
const activeSession = sessionManager.getActiveSessions().find((s) => s.id === event.sessionId);
|
|
3850
|
+
const cwd = activeSession?.projectPath ?? sessionManager.getSessionProjectPath(event.sessionId);
|
|
3851
|
+
if (!cwd) {
|
|
3852
|
+
wsBridge.send(ws, { type: "error", code: "TERMINAL_EXEC_ERROR", message: "Session not found or no project path", sessionId: event.sessionId });
|
|
3853
|
+
break;
|
|
3854
|
+
}
|
|
3855
|
+
terminalExecutor.exec(event.sessionId, event.command, cwd);
|
|
3856
|
+
break;
|
|
3857
|
+
}
|
|
3858
|
+
case "terminal_kill": {
|
|
3859
|
+
terminalExecutor.kill(event.execId);
|
|
3860
|
+
break;
|
|
3861
|
+
}
|
|
3722
3862
|
case "register_activity_push_token": {
|
|
3723
3863
|
notificationService.addActivityPushToken(event.sessionId, event.token);
|
|
3724
3864
|
break;
|
|
@@ -3790,12 +3930,14 @@ async function start(opts = {}) {
|
|
|
3790
3930
|
sessionManager.onEvent((event) => {
|
|
3791
3931
|
wsBridge.broadcast(event);
|
|
3792
3932
|
if (event.type === "status_change" && (event.status === "idle" || event.status === "error")) {
|
|
3793
|
-
if (
|
|
3794
|
-
unreadSessionIds.add(event.sessionId);
|
|
3933
|
+
if (unreadSessionIds.has(event.sessionId)) {
|
|
3795
3934
|
broadcastUnreadSessions();
|
|
3796
3935
|
}
|
|
3797
3936
|
}
|
|
3798
3937
|
});
|
|
3938
|
+
terminalExecutor.onEvent((event) => {
|
|
3939
|
+
wsBridge.broadcast(event);
|
|
3940
|
+
});
|
|
3799
3941
|
wsBridge.onDisconnect(() => {
|
|
3800
3942
|
if (wsBridge.getConnectionCount() === 0 && approvalProxy.getPendingCount() > 0) {
|
|
3801
3943
|
approvalProxy.approveAll(t("server.phoneDisconnected"));
|
|
@@ -3895,6 +4037,7 @@ async function start(opts = {}) {
|
|
|
3895
4037
|
await attempt(() => wsBridge.close(), "WebSocket");
|
|
3896
4038
|
await attempt(() => approvalProxy.close(), "ApprovalProxy");
|
|
3897
4039
|
await attempt(() => sessionManager.destroy(), "SessionManager");
|
|
4040
|
+
await attempt(() => terminalExecutor.destroy(), "TerminalExecutor");
|
|
3898
4041
|
await attempt(() => notificationService.destroy(), "NotificationService");
|
|
3899
4042
|
await attempt(() => sessionFileWatcher.destroy(), "SessionFileWatcher");
|
|
3900
4043
|
if (errors.length > 0) {
|
|
@@ -3903,7 +4046,7 @@ async function start(opts = {}) {
|
|
|
3903
4046
|
}
|
|
3904
4047
|
console.log(`[Server] ${t("server.shutdownComplete")}`);
|
|
3905
4048
|
};
|
|
3906
|
-
|
|
4049
|
+
const instance = {
|
|
3907
4050
|
token,
|
|
3908
4051
|
wsPort: WS_PORT,
|
|
3909
4052
|
httpPort: HTTP_PORT,
|
|
@@ -3921,8 +4064,21 @@ async function start(opts = {}) {
|
|
|
3921
4064
|
}
|
|
3922
4065
|
},
|
|
3923
4066
|
openPairing: (duration) => pairingManager.open(duration),
|
|
3924
|
-
closePairing: () => pairingManager.close()
|
|
4067
|
+
closePairing: () => pairingManager.close(),
|
|
4068
|
+
regenerateToken: async () => {
|
|
4069
|
+
const newToken = (0, import_uuid5.v4)();
|
|
4070
|
+
await (0, import_promises4.mkdir)(configDir, { recursive: true });
|
|
4071
|
+
await (0, import_promises4.writeFile)(tokenFile, newToken, "utf8");
|
|
4072
|
+
instance.token = newToken;
|
|
4073
|
+
wsBridge.updateToken(newToken);
|
|
4074
|
+
approvalProxy.updateToken(newToken);
|
|
4075
|
+
pairingManager.updateToken(newToken);
|
|
4076
|
+
pairingManager.open();
|
|
4077
|
+
console.log(`[Server] ${t("server.tokenRegenerated", { token: newToken })}`);
|
|
4078
|
+
return newToken;
|
|
4079
|
+
}
|
|
3925
4080
|
};
|
|
4081
|
+
return instance;
|
|
3926
4082
|
}
|
|
3927
4083
|
|
|
3928
4084
|
// src/index.ts
|
|
@@ -3994,6 +4150,7 @@ async function main() {
|
|
|
3994
4150
|
console.log(t("startup.waitingConnection"));
|
|
3995
4151
|
console.log();
|
|
3996
4152
|
console.log(t("startup.pairingOpen"));
|
|
4153
|
+
console.log(t("startup.pressT"));
|
|
3997
4154
|
console.log();
|
|
3998
4155
|
fetchLatestVersion().then((latest) => {
|
|
3999
4156
|
if (!latest || latest === PKG_VERSION) return;
|
|
@@ -4024,6 +4181,23 @@ async function main() {
|
|
|
4024
4181
|
console.log(`
|
|
4025
4182
|
${t("startup.pairingReopened")}`);
|
|
4026
4183
|
}
|
|
4184
|
+
if (key === "t" || key === "T") {
|
|
4185
|
+
server.regenerateToken().then((newToken) => {
|
|
4186
|
+
console.log();
|
|
4187
|
+
console.log(` ${t("startup.tokenRegenerated")}`);
|
|
4188
|
+
console.log(t("startup.token", { token: newToken }));
|
|
4189
|
+
console.log();
|
|
4190
|
+
const newQrUrl = buildQrUrl(getLocalIp(), server.wsPort, newToken);
|
|
4191
|
+
console.log(t("startup.scanToPair"));
|
|
4192
|
+
import_qrcode_terminal.default.generate(newQrUrl, { small: true }, (qr) => {
|
|
4193
|
+
qr.split("\n").forEach((line) => console.log(` ${line}`));
|
|
4194
|
+
});
|
|
4195
|
+
console.log();
|
|
4196
|
+
}).catch((err) => {
|
|
4197
|
+
console.error(`
|
|
4198
|
+
${t("startup.tokenRegenerateFailed")}`, err);
|
|
4199
|
+
});
|
|
4200
|
+
}
|
|
4027
4201
|
if (key === "") {
|
|
4028
4202
|
shutdown("SIGINT");
|
|
4029
4203
|
}
|
package/dist/server.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ interface ServerInstance {
|
|
|
19
19
|
openPairing: (duration?: number) => void;
|
|
20
20
|
/** 运行时关闭配对窗口 */
|
|
21
21
|
closePairing: () => void;
|
|
22
|
+
/** 重新生成 token(泄露后刷新),断开所有客户端并开启配对窗口 */
|
|
23
|
+
regenerateToken: () => Promise<string>;
|
|
22
24
|
}
|
|
23
25
|
interface ServerOptions {
|
|
24
26
|
/** 覆盖 token(默认读取 ~/.sessix/token 或自动生成) */
|
package/dist/server.js
CHANGED
|
@@ -52,7 +52,10 @@ var zh = {
|
|
|
52
52
|
autoDiscoveryHint: " \u5982\u5728\u516C\u5171\u7F51\u7EDC\uFF0C\u5EFA\u8BAE\u5173\u95ED: SESSIX_AUTO_CONNECT=false npx sessix-server",
|
|
53
53
|
autoDiscoveryOff: " \u2139\uFE0F \u81EA\u52A8\u53D1\u73B0\u5DF2\u5173\u95ED\uFF0C\u624B\u673A\u9700\u624B\u52A8\u8F93\u5165\u5730\u5740\u8FDE\u63A5",
|
|
54
54
|
pairingOpen: " \u{1F513} \u914D\u5BF9\u6A21\u5F0F\u5DF2\u5F00\u542F\uFF085 \u5206\u949F\u5185\u6709\u6548\uFF09\u2014 \u6309 p \u91CD\u65B0\u5F00\u542F",
|
|
55
|
+
pressT: " \u{1F511} \u6309 t \u91CD\u7F6E Token\uFF08\u6CC4\u9732\u540E\u5237\u65B0\uFF09",
|
|
55
56
|
pairingReopened: "\u{1F513} \u914D\u5BF9\u6A21\u5F0F\u5DF2\u91CD\u65B0\u5F00\u542F\uFF085 \u5206\u949F\uFF09",
|
|
57
|
+
tokenRegenerated: "\u{1F511} Token \u5DF2\u91CD\u7F6E\uFF0C\u6240\u6709\u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\uFF0C\u8BF7\u91CD\u65B0\u626B\u7801\u914D\u5BF9",
|
|
58
|
+
tokenRegenerateFailed: "Token \u91CD\u7F6E\u5931\u8D25:",
|
|
56
59
|
updateAvailable: "\u53D1\u73B0\u65B0\u7248\u672C v{{latest}}\uFF08\u5F53\u524D v{{current}}\uFF09\uFF0C\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u66F4\u65B0\uFF1A",
|
|
57
60
|
receivedSignal: "\u6536\u5230 {{signal}}\uFF0C\u6B63\u5728\u4F18\u96C5\u5173\u95ED...",
|
|
58
61
|
goodbye: "\u6240\u6709\u670D\u52A1\u5DF2\u5173\u95ED\uFF0C\u518D\u89C1\uFF01",
|
|
@@ -81,7 +84,8 @@ var zh = {
|
|
|
81
84
|
activityPushEnabled: "ActivityKit Push \u5DF2\u542F\u7528",
|
|
82
85
|
activityPushFailed: "ActivityKit Push \u521D\u59CB\u5316\u5931\u8D25:",
|
|
83
86
|
activityPushContinue: "\u7EE7\u7EED\u542F\u52A8\uFF08Live Activity \u540E\u53F0\u63A8\u9001\u4E0D\u53EF\u7528\uFF09",
|
|
84
|
-
noActiveLoginProcess: "\u6CA1\u6709\u6D3B\u8DC3\u7684\u767B\u5F55\u8FDB\u7A0B"
|
|
87
|
+
noActiveLoginProcess: "\u6CA1\u6709\u6D3B\u8DC3\u7684\u767B\u5F55\u8FDB\u7A0B",
|
|
88
|
+
tokenRegenerated: "Token \u5DF2\u91CD\u7F6E: {{token}}"
|
|
85
89
|
},
|
|
86
90
|
ws: {
|
|
87
91
|
started: "WebSocket \u670D\u52A1\u5DF2\u542F\u52A8\uFF0C\u7AEF\u53E3 {{port}}",
|
|
@@ -158,7 +162,10 @@ var en = {
|
|
|
158
162
|
autoDiscoveryHint: " On public networks, disable with: SESSIX_AUTO_CONNECT=false npx sessix-server",
|
|
159
163
|
autoDiscoveryOff: " Auto-discovery disabled, phone must enter address manually",
|
|
160
164
|
pairingOpen: " \u{1F513} Pairing mode open (5 min) \u2014 press p to reopen",
|
|
165
|
+
pressT: " \u{1F511} Press t to regenerate token (refresh after leak)",
|
|
161
166
|
pairingReopened: "\u{1F513} Pairing mode reopened (5 min)",
|
|
167
|
+
tokenRegenerated: "\u{1F511} Token regenerated, all clients disconnected. Scan QR to re-pair",
|
|
168
|
+
tokenRegenerateFailed: "Token regeneration failed:",
|
|
162
169
|
updateAvailable: "New version v{{latest}} available (current v{{current}}). Update with:",
|
|
163
170
|
receivedSignal: "Received {{signal}}, graceful shutdown...",
|
|
164
171
|
goodbye: "All services closed, goodbye!",
|
|
@@ -187,7 +194,8 @@ var en = {
|
|
|
187
194
|
activityPushEnabled: "ActivityKit Push enabled",
|
|
188
195
|
activityPushFailed: "ActivityKit Push init failed:",
|
|
189
196
|
activityPushContinue: "Continuing startup (Live Activity background push unavailable)",
|
|
190
|
-
noActiveLoginProcess: "No active login process"
|
|
197
|
+
noActiveLoginProcess: "No active login process",
|
|
198
|
+
tokenRegenerated: "Token regenerated: {{token}}"
|
|
191
199
|
},
|
|
192
200
|
ws: {
|
|
193
201
|
started: "WebSocket server started on port {{port}}",
|
|
@@ -293,11 +301,11 @@ function t(key, params) {
|
|
|
293
301
|
}
|
|
294
302
|
|
|
295
303
|
// src/server.ts
|
|
296
|
-
var
|
|
304
|
+
var import_uuid5 = require("uuid");
|
|
297
305
|
var import_promises4 = require("fs/promises");
|
|
298
306
|
var import_node_os6 = require("os");
|
|
299
307
|
var import_node_path5 = require("path");
|
|
300
|
-
var
|
|
308
|
+
var import_node_child_process5 = require("child_process");
|
|
301
309
|
var import_node_util = require("util");
|
|
302
310
|
|
|
303
311
|
// src/providers/ProcessProvider.ts
|
|
@@ -1544,6 +1552,13 @@ var WsBridge = class _WsBridge {
|
|
|
1544
1552
|
getConnectionCount() {
|
|
1545
1553
|
return this.wss.clients.size;
|
|
1546
1554
|
}
|
|
1555
|
+
/** 更新 token 并断开所有现有连接(token 刷新后需重新配对) */
|
|
1556
|
+
updateToken(newToken) {
|
|
1557
|
+
this.token = newToken;
|
|
1558
|
+
for (const ws of this.wss.clients) {
|
|
1559
|
+
ws.close(4001, "Token regenerated");
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1547
1562
|
/** 优雅关闭 WebSocket 服务 */
|
|
1548
1563
|
close() {
|
|
1549
1564
|
return new Promise((resolve, reject) => {
|
|
@@ -1983,6 +1998,10 @@ var ApprovalProxy = class _ApprovalProxy {
|
|
|
1983
1998
|
});
|
|
1984
1999
|
}
|
|
1985
2000
|
}
|
|
2001
|
+
/** 更新 token(token 刷新时调用) */
|
|
2002
|
+
updateToken(newToken) {
|
|
2003
|
+
this.token = newToken;
|
|
2004
|
+
}
|
|
1986
2005
|
/** 返回连接 token(仅本机访问) */
|
|
1987
2006
|
handleToken(req, res) {
|
|
1988
2007
|
const remoteAddress = req.socket.remoteAddress;
|
|
@@ -3251,6 +3270,9 @@ var PairingManager = class {
|
|
|
3251
3270
|
this.close();
|
|
3252
3271
|
return result;
|
|
3253
3272
|
}
|
|
3273
|
+
updateToken(newToken) {
|
|
3274
|
+
this.token = newToken;
|
|
3275
|
+
}
|
|
3254
3276
|
getRemainingSeconds() {
|
|
3255
3277
|
if (this._state !== "open") return 0;
|
|
3256
3278
|
return Math.max(0, Math.ceil((this.deadline - Date.now()) / 1e3));
|
|
@@ -3383,9 +3405,98 @@ var AuthManager = class extends import_events2.EventEmitter {
|
|
|
3383
3405
|
|
|
3384
3406
|
// src/server.ts
|
|
3385
3407
|
var import_promises5 = require("fs/promises");
|
|
3408
|
+
|
|
3409
|
+
// src/terminal/TerminalExecutor.ts
|
|
3410
|
+
var import_node_child_process4 = require("child_process");
|
|
3411
|
+
var import_uuid4 = require("uuid");
|
|
3412
|
+
var EXEC_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
3413
|
+
var TerminalExecutor = class {
|
|
3414
|
+
processes = /* @__PURE__ */ new Map();
|
|
3415
|
+
eventCallbacks = [];
|
|
3416
|
+
onEvent(callback) {
|
|
3417
|
+
this.eventCallbacks.push(callback);
|
|
3418
|
+
return () => {
|
|
3419
|
+
const idx = this.eventCallbacks.indexOf(callback);
|
|
3420
|
+
if (idx !== -1) this.eventCallbacks.splice(idx, 1);
|
|
3421
|
+
};
|
|
3422
|
+
}
|
|
3423
|
+
emit(event) {
|
|
3424
|
+
for (const cb of this.eventCallbacks) {
|
|
3425
|
+
try {
|
|
3426
|
+
cb(event);
|
|
3427
|
+
} catch (err) {
|
|
3428
|
+
console.error("[TerminalExecutor] Event callback error:", err);
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
exec(sessionId, command, cwd) {
|
|
3433
|
+
const execId = (0, import_uuid4.v4)();
|
|
3434
|
+
const shell = isWindows ? "powershell" : "bash";
|
|
3435
|
+
const args = isWindows ? ["-Command", command] : ["-c", command];
|
|
3436
|
+
const proc = (0, import_node_child_process4.spawn)(shell, args, {
|
|
3437
|
+
cwd,
|
|
3438
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3439
|
+
env: { ...process.env }
|
|
3440
|
+
});
|
|
3441
|
+
this.processes.set(execId, proc);
|
|
3442
|
+
proc.stdout?.on("data", (chunk) => {
|
|
3443
|
+
this.emit({
|
|
3444
|
+
type: "terminal_output",
|
|
3445
|
+
sessionId,
|
|
3446
|
+
execId,
|
|
3447
|
+
stream: "stdout",
|
|
3448
|
+
data: chunk.toString()
|
|
3449
|
+
});
|
|
3450
|
+
});
|
|
3451
|
+
proc.stderr?.on("data", (chunk) => {
|
|
3452
|
+
this.emit({
|
|
3453
|
+
type: "terminal_output",
|
|
3454
|
+
sessionId,
|
|
3455
|
+
execId,
|
|
3456
|
+
stream: "stderr",
|
|
3457
|
+
data: chunk.toString()
|
|
3458
|
+
});
|
|
3459
|
+
});
|
|
3460
|
+
proc.on("exit", (code, signal) => {
|
|
3461
|
+
clearTimeout(timer);
|
|
3462
|
+
this.processes.delete(execId);
|
|
3463
|
+
this.emit({
|
|
3464
|
+
type: "terminal_exit",
|
|
3465
|
+
sessionId,
|
|
3466
|
+
execId,
|
|
3467
|
+
code,
|
|
3468
|
+
signal
|
|
3469
|
+
});
|
|
3470
|
+
});
|
|
3471
|
+
const timer = setTimeout(() => {
|
|
3472
|
+
if (this.processes.has(execId)) {
|
|
3473
|
+
killProcessCrossPlatform(proc);
|
|
3474
|
+
}
|
|
3475
|
+
}, EXEC_TIMEOUT_MS);
|
|
3476
|
+
console.log(`[TerminalExecutor] exec ${execId}: ${command.substring(0, 100)} (cwd: ${cwd})`);
|
|
3477
|
+
return execId;
|
|
3478
|
+
}
|
|
3479
|
+
kill(execId) {
|
|
3480
|
+
const proc = this.processes.get(execId);
|
|
3481
|
+
if (proc) {
|
|
3482
|
+
killProcessCrossPlatform(proc);
|
|
3483
|
+
console.log(`[TerminalExecutor] kill ${execId}`);
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
destroy() {
|
|
3487
|
+
for (const [execId, proc] of this.processes) {
|
|
3488
|
+
killProcessCrossPlatform(proc);
|
|
3489
|
+
console.log(`[TerminalExecutor] cleanup ${execId}`);
|
|
3490
|
+
}
|
|
3491
|
+
this.processes.clear();
|
|
3492
|
+
this.eventCallbacks.length = 0;
|
|
3493
|
+
}
|
|
3494
|
+
};
|
|
3495
|
+
|
|
3496
|
+
// src/server.ts
|
|
3386
3497
|
var WS_PORT = 3745;
|
|
3387
3498
|
var HTTP_PORT = 3746;
|
|
3388
|
-
var execAsync = (0, import_node_util.promisify)(
|
|
3499
|
+
var execAsync = (0, import_node_util.promisify)(import_node_child_process5.exec);
|
|
3389
3500
|
async function killPortProcess(port) {
|
|
3390
3501
|
try {
|
|
3391
3502
|
if (isWindows) {
|
|
@@ -3440,7 +3551,7 @@ async function start(opts = {}) {
|
|
|
3440
3551
|
try {
|
|
3441
3552
|
token = (await (0, import_promises4.readFile)(tokenFile, "utf8")).trim();
|
|
3442
3553
|
} catch {
|
|
3443
|
-
token = (0,
|
|
3554
|
+
token = (0, import_uuid5.v4)();
|
|
3444
3555
|
await (0, import_promises4.mkdir)(configDir, { recursive: true });
|
|
3445
3556
|
await (0, import_promises4.writeFile)(tokenFile, token, "utf8");
|
|
3446
3557
|
}
|
|
@@ -3448,6 +3559,20 @@ async function start(opts = {}) {
|
|
|
3448
3559
|
}
|
|
3449
3560
|
const provider = new ProcessProvider();
|
|
3450
3561
|
const sessionManager = new SessionManager(provider);
|
|
3562
|
+
const terminalExecutor = new TerminalExecutor();
|
|
3563
|
+
const wsBridge = await createWithRetry(
|
|
3564
|
+
"WsBridge",
|
|
3565
|
+
WS_PORT,
|
|
3566
|
+
() => WsBridge.create({ port: WS_PORT, token })
|
|
3567
|
+
);
|
|
3568
|
+
const unreadSessionIds = /* @__PURE__ */ new Set();
|
|
3569
|
+
sessionManager.onEvent((event) => {
|
|
3570
|
+
if (event.type === "status_change" && (event.status === "idle" || event.status === "error")) {
|
|
3571
|
+
if (!wsBridge.isViewingSession(event.sessionId)) {
|
|
3572
|
+
unreadSessionIds.add(event.sessionId);
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
});
|
|
3451
3576
|
const expoChannel = new ExpoNotificationChannel();
|
|
3452
3577
|
const notificationService = new NotificationService(sessionManager, expoChannel);
|
|
3453
3578
|
notificationService.addChannel("expo", expoChannel, opts.enableExpoPush !== false);
|
|
@@ -3462,11 +3587,6 @@ async function start(opts = {}) {
|
|
|
3462
3587
|
console.log(`[Server] ${t("server.activityPushContinue")}`);
|
|
3463
3588
|
}
|
|
3464
3589
|
}
|
|
3465
|
-
const wsBridge = await createWithRetry(
|
|
3466
|
-
"WsBridge",
|
|
3467
|
-
WS_PORT,
|
|
3468
|
-
() => WsBridge.create({ port: WS_PORT, token })
|
|
3469
|
-
);
|
|
3470
3590
|
const sessionFileWatcher = new SessionFileWatcher((event) => {
|
|
3471
3591
|
wsBridge.broadcast(event);
|
|
3472
3592
|
});
|
|
@@ -3495,7 +3615,6 @@ async function start(opts = {}) {
|
|
|
3495
3615
|
});
|
|
3496
3616
|
}
|
|
3497
3617
|
});
|
|
3498
|
-
const unreadSessionIds = /* @__PURE__ */ new Set();
|
|
3499
3618
|
notificationService.setGlobalPendingCountProvider(
|
|
3500
3619
|
() => approvalProxy.getPendingCount() + sessionManager.getAllPendingQuestions().length + unreadSessionIds.size
|
|
3501
3620
|
);
|
|
@@ -3526,6 +3645,8 @@ async function start(opts = {}) {
|
|
|
3526
3645
|
switch (event.type) {
|
|
3527
3646
|
case "create_session": {
|
|
3528
3647
|
await (0, import_promises4.mkdir)(event.projectPath, { recursive: true });
|
|
3648
|
+
const resumeId = event.resumeSessionId ?? event.newSessionId;
|
|
3649
|
+
if (resumeId) sessionFileWatcher.unwatch(resumeId);
|
|
3529
3650
|
await sessionManager.createSession(
|
|
3530
3651
|
event.projectPath,
|
|
3531
3652
|
event.message,
|
|
@@ -3543,6 +3664,7 @@ async function start(opts = {}) {
|
|
|
3543
3664
|
break;
|
|
3544
3665
|
}
|
|
3545
3666
|
case "send_message": {
|
|
3667
|
+
sessionFileWatcher.unwatch(event.sessionId);
|
|
3546
3668
|
await sessionManager.sendMessage(event.sessionId, event.message, event.permissionMode, event.images);
|
|
3547
3669
|
wsBridge.broadcast({
|
|
3548
3670
|
type: "session_list",
|
|
@@ -3631,6 +3753,10 @@ async function start(opts = {}) {
|
|
|
3631
3753
|
code: "PROJECT_LIST_ERROR"
|
|
3632
3754
|
});
|
|
3633
3755
|
}
|
|
3756
|
+
wsBridge.send(ws, {
|
|
3757
|
+
type: "session_list",
|
|
3758
|
+
sessions: sessionManager.getActiveSessions()
|
|
3759
|
+
});
|
|
3634
3760
|
break;
|
|
3635
3761
|
}
|
|
3636
3762
|
case "list_sessions": {
|
|
@@ -3725,6 +3851,20 @@ async function start(opts = {}) {
|
|
|
3725
3851
|
notificationService.setSoundPreferences(event.preferences);
|
|
3726
3852
|
break;
|
|
3727
3853
|
}
|
|
3854
|
+
case "terminal_exec": {
|
|
3855
|
+
const activeSession = sessionManager.getActiveSessions().find((s) => s.id === event.sessionId);
|
|
3856
|
+
const cwd = activeSession?.projectPath ?? sessionManager.getSessionProjectPath(event.sessionId);
|
|
3857
|
+
if (!cwd) {
|
|
3858
|
+
wsBridge.send(ws, { type: "error", code: "TERMINAL_EXEC_ERROR", message: "Session not found or no project path", sessionId: event.sessionId });
|
|
3859
|
+
break;
|
|
3860
|
+
}
|
|
3861
|
+
terminalExecutor.exec(event.sessionId, event.command, cwd);
|
|
3862
|
+
break;
|
|
3863
|
+
}
|
|
3864
|
+
case "terminal_kill": {
|
|
3865
|
+
terminalExecutor.kill(event.execId);
|
|
3866
|
+
break;
|
|
3867
|
+
}
|
|
3728
3868
|
case "register_activity_push_token": {
|
|
3729
3869
|
notificationService.addActivityPushToken(event.sessionId, event.token);
|
|
3730
3870
|
break;
|
|
@@ -3796,12 +3936,14 @@ async function start(opts = {}) {
|
|
|
3796
3936
|
sessionManager.onEvent((event) => {
|
|
3797
3937
|
wsBridge.broadcast(event);
|
|
3798
3938
|
if (event.type === "status_change" && (event.status === "idle" || event.status === "error")) {
|
|
3799
|
-
if (
|
|
3800
|
-
unreadSessionIds.add(event.sessionId);
|
|
3939
|
+
if (unreadSessionIds.has(event.sessionId)) {
|
|
3801
3940
|
broadcastUnreadSessions();
|
|
3802
3941
|
}
|
|
3803
3942
|
}
|
|
3804
3943
|
});
|
|
3944
|
+
terminalExecutor.onEvent((event) => {
|
|
3945
|
+
wsBridge.broadcast(event);
|
|
3946
|
+
});
|
|
3805
3947
|
wsBridge.onDisconnect(() => {
|
|
3806
3948
|
if (wsBridge.getConnectionCount() === 0 && approvalProxy.getPendingCount() > 0) {
|
|
3807
3949
|
approvalProxy.approveAll(t("server.phoneDisconnected"));
|
|
@@ -3901,6 +4043,7 @@ async function start(opts = {}) {
|
|
|
3901
4043
|
await attempt(() => wsBridge.close(), "WebSocket");
|
|
3902
4044
|
await attempt(() => approvalProxy.close(), "ApprovalProxy");
|
|
3903
4045
|
await attempt(() => sessionManager.destroy(), "SessionManager");
|
|
4046
|
+
await attempt(() => terminalExecutor.destroy(), "TerminalExecutor");
|
|
3904
4047
|
await attempt(() => notificationService.destroy(), "NotificationService");
|
|
3905
4048
|
await attempt(() => sessionFileWatcher.destroy(), "SessionFileWatcher");
|
|
3906
4049
|
if (errors.length > 0) {
|
|
@@ -3909,7 +4052,7 @@ async function start(opts = {}) {
|
|
|
3909
4052
|
}
|
|
3910
4053
|
console.log(`[Server] ${t("server.shutdownComplete")}`);
|
|
3911
4054
|
};
|
|
3912
|
-
|
|
4055
|
+
const instance = {
|
|
3913
4056
|
token,
|
|
3914
4057
|
wsPort: WS_PORT,
|
|
3915
4058
|
httpPort: HTTP_PORT,
|
|
@@ -3927,8 +4070,21 @@ async function start(opts = {}) {
|
|
|
3927
4070
|
}
|
|
3928
4071
|
},
|
|
3929
4072
|
openPairing: (duration) => pairingManager.open(duration),
|
|
3930
|
-
closePairing: () => pairingManager.close()
|
|
4073
|
+
closePairing: () => pairingManager.close(),
|
|
4074
|
+
regenerateToken: async () => {
|
|
4075
|
+
const newToken = (0, import_uuid5.v4)();
|
|
4076
|
+
await (0, import_promises4.mkdir)(configDir, { recursive: true });
|
|
4077
|
+
await (0, import_promises4.writeFile)(tokenFile, newToken, "utf8");
|
|
4078
|
+
instance.token = newToken;
|
|
4079
|
+
wsBridge.updateToken(newToken);
|
|
4080
|
+
approvalProxy.updateToken(newToken);
|
|
4081
|
+
pairingManager.updateToken(newToken);
|
|
4082
|
+
pairingManager.open();
|
|
4083
|
+
console.log(`[Server] ${t("server.tokenRegenerated", { token: newToken })}`);
|
|
4084
|
+
return newToken;
|
|
4085
|
+
}
|
|
3931
4086
|
};
|
|
4087
|
+
return instance;
|
|
3932
4088
|
}
|
|
3933
4089
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3934
4090
|
0 && (module.exports = {
|