@memtensor/memos-local-openclaw-plugin 1.0.4-beta.16 → 1.0.4-beta.18
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/README.md +94 -27
- package/dist/hub/server.d.ts +1 -0
- package/dist/hub/server.d.ts.map +1 -1
- package/dist/hub/server.js +74 -7
- package/dist/hub/server.js.map +1 -1
- package/dist/ingest/providers/index.js +2 -2
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/shared/llm-call.d.ts.map +1 -1
- package/dist/shared/llm-call.js +2 -1
- package/dist/shared/llm-call.js.map +1 -1
- package/dist/viewer/html.d.ts.map +1 -1
- package/dist/viewer/html.js +214 -67
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +6 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +152 -42
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +7 -4
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/hub/server.ts +70 -8
- package/src/ingest/providers/index.ts +2 -2
- package/src/shared/llm-call.ts +2 -1
- package/src/viewer/html.ts +214 -67
- package/src/viewer/server.ts +145 -41
package/dist/viewer/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":";;AAAA,
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/viewer/html.ts"],"names":[],"mappings":";;AAAA,gCA41RC;AA51RD,SAAgB,UAAU,CAAC,aAAsB;IACjD,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,gCAAgC,aAAa,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3F,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qKAwqC8J,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAirPnK,CAAC;AACT,CAAC"}
|
package/dist/viewer/server.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface ViewerServerOptions {
|
|
|
8
8
|
log: Logger;
|
|
9
9
|
dataDir: string;
|
|
10
10
|
ctx?: PluginContext;
|
|
11
|
+
defaultHubPort?: number;
|
|
11
12
|
}
|
|
12
13
|
export declare class ViewerServer {
|
|
13
14
|
private server;
|
|
@@ -19,6 +20,8 @@ export declare class ViewerServer {
|
|
|
19
20
|
private readonly authFile;
|
|
20
21
|
private readonly auth;
|
|
21
22
|
private readonly ctx?;
|
|
23
|
+
private readonly cookieName;
|
|
24
|
+
private readonly defaultHubPort;
|
|
22
25
|
private static readonly SESSION_TTL;
|
|
23
26
|
private static readonly PLUGIN_VERSION;
|
|
24
27
|
private resetToken;
|
|
@@ -36,6 +39,7 @@ export declare class ViewerServer {
|
|
|
36
39
|
private hubHeartbeatTimer?;
|
|
37
40
|
private static readonly HUB_HEARTBEAT_INTERVAL_MS;
|
|
38
41
|
constructor(opts: ViewerServerOptions);
|
|
42
|
+
private getHubPort;
|
|
39
43
|
start(): Promise<string>;
|
|
40
44
|
private autoCleanupPolluted;
|
|
41
45
|
stop(): void;
|
|
@@ -137,7 +141,9 @@ export declare class ViewerServer {
|
|
|
137
141
|
private serveConfig;
|
|
138
142
|
private handleSaveConfig;
|
|
139
143
|
private autoJoinOnSave;
|
|
144
|
+
private handleLeaveTeam;
|
|
140
145
|
private notifyHubLeave;
|
|
146
|
+
private withdrawOrLeaveHub;
|
|
141
147
|
private notifyHubShutdown;
|
|
142
148
|
private handleUpdateUsername;
|
|
143
149
|
private handleTestHubConnection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/viewer/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAY7C,OAAO,KAAK,EAAE,MAAM,EAAS,aAAa,EAAoB,MAAM,UAAU,CAAC;AAS/E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/viewer/server.ts"],"names":[],"mappings":"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"}
|
package/dist/viewer/server.js
CHANGED
|
@@ -72,6 +72,8 @@ class ViewerServer {
|
|
|
72
72
|
authFile;
|
|
73
73
|
auth;
|
|
74
74
|
ctx;
|
|
75
|
+
cookieName;
|
|
76
|
+
defaultHubPort;
|
|
75
77
|
static SESSION_TTL = 24 * 60 * 60 * 1000;
|
|
76
78
|
static PLUGIN_VERSION = (() => {
|
|
77
79
|
try {
|
|
@@ -105,16 +107,31 @@ class ViewerServer {
|
|
|
105
107
|
this.ctx = opts.ctx;
|
|
106
108
|
this.authFile = node_path_1.default.join(opts.dataDir, "viewer-auth.json");
|
|
107
109
|
this.auth = { passwordHash: null, sessions: new Map() };
|
|
110
|
+
this.cookieName = `memos_token_${opts.port}`;
|
|
111
|
+
this.defaultHubPort = opts.defaultHubPort ?? 18800;
|
|
108
112
|
this.resetToken = node_crypto_1.default.randomBytes(16).toString("hex");
|
|
109
113
|
this.loadAuth();
|
|
110
114
|
}
|
|
115
|
+
getHubPort() {
|
|
116
|
+
const configured = this.ctx?.config?.sharing?.hub?.port;
|
|
117
|
+
if (configured && configured !== 18800)
|
|
118
|
+
return configured;
|
|
119
|
+
return this.defaultHubPort;
|
|
120
|
+
}
|
|
111
121
|
start() {
|
|
122
|
+
const MAX_PORT_RETRIES = 5;
|
|
112
123
|
return new Promise((resolve, reject) => {
|
|
124
|
+
let retries = 0;
|
|
113
125
|
this.server = node_http_1.default.createServer((req, res) => this.handleRequest(req, res));
|
|
114
126
|
this.server.on("error", (err) => {
|
|
115
|
-
if (err.code === "EADDRINUSE") {
|
|
116
|
-
|
|
117
|
-
this.
|
|
127
|
+
if (err.code === "EADDRINUSE" && retries < MAX_PORT_RETRIES) {
|
|
128
|
+
retries++;
|
|
129
|
+
const nextPort = this.port + retries;
|
|
130
|
+
this.log.warn(`Viewer port ${this.port + retries - 1} in use, trying ${nextPort}`);
|
|
131
|
+
this.server.listen(nextPort, "0.0.0.0");
|
|
132
|
+
}
|
|
133
|
+
else if (err.code === "EADDRINUSE") {
|
|
134
|
+
reject(new Error(`Viewer failed to find open port after ${MAX_PORT_RETRIES} retries (tried ${this.port}–${this.port + MAX_PORT_RETRIES})`));
|
|
118
135
|
}
|
|
119
136
|
else {
|
|
120
137
|
reject(err);
|
|
@@ -193,7 +210,8 @@ class ViewerServer {
|
|
|
193
210
|
}
|
|
194
211
|
isValidSession(req) {
|
|
195
212
|
const cookie = req.headers.cookie ?? "";
|
|
196
|
-
const
|
|
213
|
+
const re = new RegExp(`${this.cookieName}=([a-f0-9]+)`);
|
|
214
|
+
const match = cookie.match(re);
|
|
197
215
|
if (!match)
|
|
198
216
|
return false;
|
|
199
217
|
const expiry = this.auth.sessions.get(match[1]);
|
|
@@ -313,6 +331,8 @@ class ViewerServer {
|
|
|
313
331
|
this.handleSharingChangeRole(req, res);
|
|
314
332
|
else if (p === "/api/sharing/retry-join" && req.method === "POST")
|
|
315
333
|
this.handleRetryJoin(req, res);
|
|
334
|
+
else if (p === "/api/sharing/leave" && req.method === "POST")
|
|
335
|
+
this.handleLeaveTeam(req, res);
|
|
316
336
|
else if (p === "/api/sharing/search/memories" && req.method === "POST")
|
|
317
337
|
this.handleSharingMemorySearch(req, res);
|
|
318
338
|
else if (p === "/api/sharing/memories/list" && req.method === "GET")
|
|
@@ -440,7 +460,7 @@ class ViewerServer {
|
|
|
440
460
|
const token = this.createSession();
|
|
441
461
|
res.writeHead(200, {
|
|
442
462
|
"Content-Type": "application/json",
|
|
443
|
-
"Set-Cookie":
|
|
463
|
+
"Set-Cookie": `${this.cookieName}=${token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400`,
|
|
444
464
|
});
|
|
445
465
|
res.end(JSON.stringify({ ok: true, message: "Password set successfully" }));
|
|
446
466
|
}
|
|
@@ -462,7 +482,7 @@ class ViewerServer {
|
|
|
462
482
|
const token = this.createSession();
|
|
463
483
|
res.writeHead(200, {
|
|
464
484
|
"Content-Type": "application/json",
|
|
465
|
-
"Set-Cookie":
|
|
485
|
+
"Set-Cookie": `${this.cookieName}=${token}; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400`,
|
|
466
486
|
});
|
|
467
487
|
res.end(JSON.stringify({ ok: true }));
|
|
468
488
|
}
|
|
@@ -474,12 +494,13 @@ class ViewerServer {
|
|
|
474
494
|
}
|
|
475
495
|
handleLogout(req, res) {
|
|
476
496
|
const cookie = req.headers.cookie ?? "";
|
|
477
|
-
const
|
|
497
|
+
const re = new RegExp(`${this.cookieName}=([a-f0-9]+)`);
|
|
498
|
+
const match = cookie.match(re);
|
|
478
499
|
if (match)
|
|
479
500
|
this.auth.sessions.delete(match[1]);
|
|
480
501
|
res.writeHead(200, {
|
|
481
502
|
"Content-Type": "application/json",
|
|
482
|
-
"Set-Cookie":
|
|
503
|
+
"Set-Cookie": `${this.cookieName}=; Path=/; HttpOnly; Max-Age=0`,
|
|
483
504
|
});
|
|
484
505
|
res.end(JSON.stringify({ ok: true }));
|
|
485
506
|
}
|
|
@@ -505,7 +526,7 @@ class ViewerServer {
|
|
|
505
526
|
const sessionToken = this.createSession();
|
|
506
527
|
res.writeHead(200, {
|
|
507
528
|
"Content-Type": "application/json",
|
|
508
|
-
"Set-Cookie":
|
|
529
|
+
"Set-Cookie": `${this.cookieName}=${sessionToken}; Path=/; HttpOnly; SameSite=Strict; Max-Age=86400`,
|
|
509
530
|
});
|
|
510
531
|
res.end(JSON.stringify({ ok: true, message: "Password reset successfully" }));
|
|
511
532
|
}
|
|
@@ -1662,6 +1683,8 @@ class ViewerServer {
|
|
|
1662
1683
|
// ─── Helpers ───
|
|
1663
1684
|
// ─── Config API ───
|
|
1664
1685
|
getOpenClawConfigPath() {
|
|
1686
|
+
if (process.env.OPENCLAW_CONFIG_PATH)
|
|
1687
|
+
return process.env.OPENCLAW_CONFIG_PATH;
|
|
1665
1688
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
1666
1689
|
const ocHome = process.env.OPENCLAW_STATE_DIR || node_path_1.default.join(home, ".openclaw");
|
|
1667
1690
|
return node_path_1.default.join(ocHome, "openclaw.json");
|
|
@@ -1744,7 +1767,18 @@ class ViewerServer {
|
|
|
1744
1767
|
base.connection.apiVersion = info?.apiVersion ?? null;
|
|
1745
1768
|
}
|
|
1746
1769
|
catch { /* ignore */ }
|
|
1747
|
-
|
|
1770
|
+
const hubStats = { totalMembers: 0, onlineMembers: 0, pendingMembers: 0 };
|
|
1771
|
+
try {
|
|
1772
|
+
const activeUsers = this.store.listHubUsers("active");
|
|
1773
|
+
const pendingUsers = this.store.listHubUsers("pending");
|
|
1774
|
+
const now = Date.now();
|
|
1775
|
+
const OFFLINE_THRESHOLD = 120_000;
|
|
1776
|
+
hubStats.totalMembers = activeUsers.length;
|
|
1777
|
+
hubStats.onlineMembers = activeUsers.filter(u => u.lastActiveAt && (now - u.lastActiveAt < OFFLINE_THRESHOLD)).length;
|
|
1778
|
+
hubStats.pendingMembers = pendingUsers.length;
|
|
1779
|
+
}
|
|
1780
|
+
catch { /* best-effort */ }
|
|
1781
|
+
this.jsonResponse(res, { ...base, hubStats });
|
|
1748
1782
|
return;
|
|
1749
1783
|
}
|
|
1750
1784
|
const hasPendingConnection = Boolean(persisted?.hubUrl && persisted?.userId && !persisted?.userToken);
|
|
@@ -1925,16 +1959,6 @@ class ViewerServer {
|
|
|
1925
1959
|
}
|
|
1926
1960
|
try {
|
|
1927
1961
|
const hubUrl = (0, hub_1.normalizeHubUrl)(hubAddress);
|
|
1928
|
-
const localIPs = this.getLocalIPs();
|
|
1929
|
-
localIPs.push("127.0.0.1", "localhost", "0.0.0.0");
|
|
1930
|
-
try {
|
|
1931
|
-
const u = new URL(hubUrl);
|
|
1932
|
-
const targetPort = u.port || (u.protocol === "https:" ? "443" : "80");
|
|
1933
|
-
if (localIPs.includes(u.hostname) && targetPort === String(this.port)) {
|
|
1934
|
-
return this.jsonResponse(res, { ok: false, error: "cannot_join_self" });
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
catch { }
|
|
1938
1962
|
const os = await Promise.resolve().then(() => __importStar(require("os")));
|
|
1939
1963
|
const nickname = sharing.client?.nickname;
|
|
1940
1964
|
const username = nickname || os.userInfo().username || "user";
|
|
@@ -2391,7 +2415,7 @@ class ViewerServer {
|
|
|
2391
2415
|
// Hub 模式:连接自己,用 bootstrap admin token
|
|
2392
2416
|
const sharing = this.ctx.config.sharing;
|
|
2393
2417
|
if (sharing?.role === "hub") {
|
|
2394
|
-
const hubPort =
|
|
2418
|
+
const hubPort = this.getHubPort();
|
|
2395
2419
|
const hubUrl = `http://127.0.0.1:${hubPort}`;
|
|
2396
2420
|
try {
|
|
2397
2421
|
const authPath = node_path_1.default.join(this.dataDir, "hub-auth.json");
|
|
@@ -2827,13 +2851,14 @@ class ViewerServer {
|
|
|
2827
2851
|
if (merged.role === "client" && merged.client) {
|
|
2828
2852
|
const clientCfg = merged.client;
|
|
2829
2853
|
const addr = String(clientCfg.hubAddress || "");
|
|
2830
|
-
if (addr) {
|
|
2854
|
+
if (addr && oldSharingRole === "hub" && oldSharingEnabled) {
|
|
2855
|
+
const selfHubPort = oldSharing?.hub?.port ?? 18800;
|
|
2831
2856
|
const localIPs = this.getLocalIPs();
|
|
2832
2857
|
localIPs.push("127.0.0.1", "localhost", "0.0.0.0");
|
|
2833
2858
|
try {
|
|
2834
2859
|
const u = new URL(addr.startsWith("http") ? addr : `http://${addr}`);
|
|
2835
2860
|
const targetPort = u.port || (u.protocol === "https:" ? "443" : "80");
|
|
2836
|
-
if (localIPs.includes(u.hostname) && targetPort === String(
|
|
2861
|
+
if (localIPs.includes(u.hostname) && targetPort === String(selfHubPort)) {
|
|
2837
2862
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
2838
2863
|
res.end(JSON.stringify({ error: "cannot_join_self" }));
|
|
2839
2864
|
return;
|
|
@@ -2856,12 +2881,9 @@ class ViewerServer {
|
|
|
2856
2881
|
const wasClient = oldSharingEnabled && oldSharingRole === "client";
|
|
2857
2882
|
const isClient = newEnabled && newRole === "client";
|
|
2858
2883
|
if (wasClient && !isClient) {
|
|
2859
|
-
this.
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
this.store.setClientHubConnection({ ...oldConn, userToken: "", lastKnownStatus: "left" });
|
|
2863
|
-
}
|
|
2864
|
-
this.log.info("Client hub connection token cleared (sharing disabled or role changed), identity preserved");
|
|
2884
|
+
await this.withdrawOrLeaveHub();
|
|
2885
|
+
this.store.clearClientHubConnection();
|
|
2886
|
+
this.log.info("Client hub connection cleared (sharing disabled or role changed)");
|
|
2865
2887
|
}
|
|
2866
2888
|
if (wasClient && isClient) {
|
|
2867
2889
|
const newClientAddr = String(merged.client?.hubAddress || "");
|
|
@@ -2878,7 +2900,7 @@ class ViewerServer {
|
|
|
2878
2900
|
merged.client = { hubAddress: "", userToken: "", teamToken: "" };
|
|
2879
2901
|
}
|
|
2880
2902
|
else if (merged.role === "client") {
|
|
2881
|
-
merged.hub = {
|
|
2903
|
+
merged.hub = { teamName: "", teamToken: "" };
|
|
2882
2904
|
}
|
|
2883
2905
|
config.sharing = merged;
|
|
2884
2906
|
}
|
|
@@ -2899,7 +2921,16 @@ class ViewerServer {
|
|
|
2899
2921
|
this.log.warn(`Auto-join on save failed: ${e}`);
|
|
2900
2922
|
}
|
|
2901
2923
|
}
|
|
2902
|
-
this.jsonResponse(res, { ok: true, joinStatus });
|
|
2924
|
+
this.jsonResponse(res, { ok: true, joinStatus, restart: true });
|
|
2925
|
+
setTimeout(() => {
|
|
2926
|
+
this.log.info("config-save: triggering gateway restart via SIGUSR1...");
|
|
2927
|
+
try {
|
|
2928
|
+
process.kill(process.pid, "SIGUSR1");
|
|
2929
|
+
}
|
|
2930
|
+
catch (sig) {
|
|
2931
|
+
this.log.warn(`SIGUSR1 failed: ${sig}`);
|
|
2932
|
+
}
|
|
2933
|
+
}, 500);
|
|
2903
2934
|
}
|
|
2904
2935
|
catch (e) {
|
|
2905
2936
|
this.log.warn(`handleSaveConfig error: ${e}`);
|
|
@@ -2942,6 +2973,43 @@ class ViewerServer {
|
|
|
2942
2973
|
}
|
|
2943
2974
|
return result.status;
|
|
2944
2975
|
}
|
|
2976
|
+
handleLeaveTeam(_req, res) {
|
|
2977
|
+
this.readBody(_req, async () => {
|
|
2978
|
+
try {
|
|
2979
|
+
await this.withdrawOrLeaveHub();
|
|
2980
|
+
this.store.clearClientHubConnection();
|
|
2981
|
+
const configPath = this.getOpenClawConfigPath();
|
|
2982
|
+
if (configPath && node_fs_1.default.existsSync(configPath)) {
|
|
2983
|
+
const raw = JSON.parse(node_fs_1.default.readFileSync(configPath, "utf8"));
|
|
2984
|
+
const pluginKey = Object.keys(raw.plugins?.entries ?? {}).find(k => k.includes("memos-local"));
|
|
2985
|
+
if (pluginKey) {
|
|
2986
|
+
const cfg = raw.plugins.entries[pluginKey].config ?? {};
|
|
2987
|
+
if (cfg.sharing) {
|
|
2988
|
+
cfg.sharing.enabled = false;
|
|
2989
|
+
cfg.sharing.client = { hubAddress: "", userToken: "", teamToken: "" };
|
|
2990
|
+
}
|
|
2991
|
+
raw.plugins.entries[pluginKey].config = cfg;
|
|
2992
|
+
node_fs_1.default.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
|
|
2993
|
+
this.log.info("handleLeaveTeam: config updated, sharing disabled");
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
this.jsonResponse(res, { ok: true, restart: true });
|
|
2997
|
+
setTimeout(() => {
|
|
2998
|
+
this.log.info("handleLeaveTeam: triggering gateway restart via SIGUSR1...");
|
|
2999
|
+
try {
|
|
3000
|
+
process.kill(process.pid, "SIGUSR1");
|
|
3001
|
+
}
|
|
3002
|
+
catch (sig) {
|
|
3003
|
+
this.log.warn(`SIGUSR1 failed: ${sig}`);
|
|
3004
|
+
}
|
|
3005
|
+
}, 500);
|
|
3006
|
+
}
|
|
3007
|
+
catch (e) {
|
|
3008
|
+
this.log.warn(`handleLeaveTeam error: ${e}`);
|
|
3009
|
+
this.jsonResponse(res, { ok: false, error: String(e) });
|
|
3010
|
+
}
|
|
3011
|
+
});
|
|
3012
|
+
}
|
|
2945
3013
|
async notifyHubLeave() {
|
|
2946
3014
|
try {
|
|
2947
3015
|
const hub = this.resolveHubConnection();
|
|
@@ -2960,12 +3028,46 @@ class ViewerServer {
|
|
|
2960
3028
|
this.log.warn(`Failed to notify Hub of leave: ${e}`);
|
|
2961
3029
|
}
|
|
2962
3030
|
}
|
|
3031
|
+
async withdrawOrLeaveHub() {
|
|
3032
|
+
try {
|
|
3033
|
+
const persisted = this.store.getClientHubConnection();
|
|
3034
|
+
const sharing = this.ctx?.config?.sharing;
|
|
3035
|
+
if (persisted?.userToken && persisted?.hubUrl) {
|
|
3036
|
+
await (0, hub_1.hubRequestJson)(persisted.hubUrl, persisted.userToken, "/api/v1/hub/leave", { method: "POST" });
|
|
3037
|
+
this.log.info("Notified Hub of voluntary leave (had token)");
|
|
3038
|
+
return;
|
|
3039
|
+
}
|
|
3040
|
+
const hub = this.resolveHubConnection();
|
|
3041
|
+
if (hub?.userToken) {
|
|
3042
|
+
await (0, hub_1.hubRequestJson)(hub.hubUrl, hub.userToken, "/api/v1/hub/leave", { method: "POST" });
|
|
3043
|
+
this.log.info("Notified Hub of voluntary leave (resolved connection)");
|
|
3044
|
+
return;
|
|
3045
|
+
}
|
|
3046
|
+
const hubUrl = persisted?.hubUrl || (sharing?.client?.hubAddress ? (0, hub_1.normalizeHubUrl)(sharing.client.hubAddress) : null);
|
|
3047
|
+
const userId = persisted?.userId;
|
|
3048
|
+
const teamToken = sharing?.client?.teamToken;
|
|
3049
|
+
if (hubUrl && userId && teamToken) {
|
|
3050
|
+
const withdrawUrl = `${(0, hub_1.normalizeHubUrl)(hubUrl)}/api/v1/hub/withdraw-pending`;
|
|
3051
|
+
await fetch(withdrawUrl, {
|
|
3052
|
+
method: "POST",
|
|
3053
|
+
headers: { "content-type": "application/json" },
|
|
3054
|
+
body: JSON.stringify({ teamToken, userId }),
|
|
3055
|
+
});
|
|
3056
|
+
this.log.info("Withdrew pending application from Hub");
|
|
3057
|
+
return;
|
|
3058
|
+
}
|
|
3059
|
+
this.log.info("No hub connection to clean up (no token, no pending)");
|
|
3060
|
+
}
|
|
3061
|
+
catch (e) {
|
|
3062
|
+
this.log.warn(`Failed to withdraw/leave Hub: ${e}`);
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
2963
3065
|
async notifyHubShutdown() {
|
|
2964
3066
|
try {
|
|
2965
3067
|
const sharing = this.ctx?.config.sharing;
|
|
2966
3068
|
if (!sharing || sharing.role !== "hub")
|
|
2967
3069
|
return;
|
|
2968
|
-
const hubPort =
|
|
3070
|
+
const hubPort = this.getHubPort();
|
|
2969
3071
|
const authPath = node_path_1.default.join(this.dataDir, "hub-auth.json");
|
|
2970
3072
|
let adminToken;
|
|
2971
3073
|
try {
|
|
@@ -3060,13 +3162,17 @@ class ViewerServer {
|
|
|
3060
3162
|
return;
|
|
3061
3163
|
}
|
|
3062
3164
|
try {
|
|
3063
|
-
const
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3165
|
+
const sharing = this.ctx?.config?.sharing;
|
|
3166
|
+
if (sharing?.enabled && sharing.role === "hub") {
|
|
3167
|
+
const selfHubPort = this.getHubPort();
|
|
3168
|
+
const localIPs = this.getLocalIPs();
|
|
3169
|
+
localIPs.push("127.0.0.1", "localhost", "0.0.0.0");
|
|
3170
|
+
const parsed = new URL(hubUrl.startsWith("http") ? hubUrl : `http://${hubUrl}`);
|
|
3171
|
+
const targetPort = parsed.port || (parsed.protocol === "https:" ? "443" : "80");
|
|
3172
|
+
if (localIPs.includes(parsed.hostname) && targetPort === String(selfHubPort)) {
|
|
3173
|
+
this.jsonResponse(res, { ok: false, error: "cannot_join_self" });
|
|
3174
|
+
return;
|
|
3175
|
+
}
|
|
3070
3176
|
}
|
|
3071
3177
|
}
|
|
3072
3178
|
catch { }
|
|
@@ -3324,10 +3430,14 @@ class ViewerServer {
|
|
|
3324
3430
|
catch { }
|
|
3325
3431
|
this.log.info(`update-install: success! Updated to ${newVersion}`);
|
|
3326
3432
|
this.jsonResponse(res, { ok: true, version: newVersion });
|
|
3327
|
-
// Trigger Gateway restart after response is sent
|
|
3328
3433
|
setTimeout(() => {
|
|
3329
|
-
this.log.info(`update-install: triggering gateway restart...`);
|
|
3330
|
-
|
|
3434
|
+
this.log.info(`update-install: triggering gateway restart via SIGUSR1...`);
|
|
3435
|
+
try {
|
|
3436
|
+
process.kill(process.pid, "SIGUSR1");
|
|
3437
|
+
}
|
|
3438
|
+
catch (sig) {
|
|
3439
|
+
this.log.warn(`SIGUSR1 failed: ${sig}`);
|
|
3440
|
+
}
|
|
3331
3441
|
}, 500);
|
|
3332
3442
|
});
|
|
3333
3443
|
});
|