termdock 1.4.127 → 1.4.129
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/.desktop-dist/main.js +157 -28
- package/dist/client/assets/{ModelPreview-B3caplvh.js → ModelPreview-DA71QiMN.js} +1 -1
- package/dist/client/assets/{abnfDiagram-VRR7QNED-Pm2cPR47.js → abnfDiagram-VRR7QNED-vwQxXhvY.js} +1 -1
- package/dist/client/assets/{arc-Du2jqJEu.js → arc-KcBV2d81.js} +1 -1
- package/dist/client/assets/{architectureDiagram-ZJ3FMSHR-UZZ-hCDJ.js → architectureDiagram-ZJ3FMSHR-BKm_EWca.js} +1 -1
- package/dist/client/assets/{blockDiagram-677ZJIJ3-DCdHiW0y.js → blockDiagram-677ZJIJ3-DAQx8c-B.js} +1 -1
- package/dist/client/assets/{c4Diagram-LMCZKHZV-CI2wB8cp.js → c4Diagram-LMCZKHZV-BeYeekky.js} +1 -1
- package/dist/client/assets/channel-jqLwHPeC.js +1 -0
- package/dist/client/assets/{chunk-2Q5K7J3B-BOWA0kur.js → chunk-2Q5K7J3B-DHqXZZU-.js} +1 -1
- package/dist/client/assets/{chunk-32BRIVSS-7oLxVo5n.js → chunk-32BRIVSS-D1m2Benc.js} +1 -1
- package/dist/client/assets/{chunk-5VM5RSS4-CmqxvKXC.js → chunk-5VM5RSS4-CtOKKO1w.js} +1 -1
- package/dist/client/assets/{chunk-EX3LRPZG-DORF3Bb-.js → chunk-EX3LRPZG-CXjhbuNm.js} +1 -1
- package/dist/client/assets/{chunk-JWPE2WC7-CPf240uh.js → chunk-JWPE2WC7-C0Zq6OdN.js} +1 -1
- package/dist/client/assets/{chunk-MOJQB5TN-BXWYBupN.js → chunk-MOJQB5TN-BlkCCLDm.js} +1 -1
- package/dist/client/assets/{chunk-RYQCIY6F-DZNPiduN.js → chunk-RYQCIY6F-Cz6TWAav.js} +1 -1
- package/dist/client/assets/{chunk-V7JOEXUC-CmDRmHMg.js → chunk-V7JOEXUC-DhLyQr8d.js} +1 -1
- package/dist/client/assets/{chunk-VR4S4FIN-DHHyq_Zz.js → chunk-VR4S4FIN-DSnFyHH_.js} +1 -1
- package/dist/client/assets/{chunk-XXDRQBXY-C8ImJLqT.js → chunk-XXDRQBXY-C2ISI6ro.js} +1 -1
- package/dist/client/assets/classDiagram-OUVF2IWQ-DFjGJuxW.js +1 -0
- package/dist/client/assets/classDiagram-v2-EOCWNBFH-DFjGJuxW.js +1 -0
- package/dist/client/assets/{cose-bilkent-JH36ORCC-9vG_EL3b.js → cose-bilkent-JH36ORCC-DQVr0EsM.js} +1 -1
- package/dist/client/assets/{cynefin-VYW2F7L2-CIs-32JD.js → cynefin-VYW2F7L2-BP6p28mL.js} +1 -1
- package/dist/client/assets/{cynefinDiagram-TSTJHNR4-DikbAwAV.js → cynefinDiagram-TSTJHNR4-CPUSyMuB.js} +1 -1
- package/dist/client/assets/{dagre-VKFMJZFB-CfrhX7w8.js → dagre-VKFMJZFB-C_zQd2eB.js} +1 -1
- package/dist/client/assets/{diagram-FQU43EPY-Dyrs6fiZ.js → diagram-FQU43EPY-RkUQLZyi.js} +1 -1
- package/dist/client/assets/{diagram-G47NLZAW-BpT0tI-h.js → diagram-G47NLZAW-CtjAPFXS.js} +1 -1
- package/dist/client/assets/{diagram-NH7WQ7WH-CFTgimjj.js → diagram-NH7WQ7WH-C5xtKZ-W.js} +1 -1
- package/dist/client/assets/{diagram-OA4YK3LP-ROVSgH9I.js → diagram-OA4YK3LP-CrbMkTb7.js} +1 -1
- package/dist/client/assets/{diagram-WEI45ONY-CGcDsOXD.js → diagram-WEI45ONY-DAF4URgC.js} +1 -1
- package/dist/client/assets/{ebnfDiagram-CCIWWBDH-BMAXtWJG.js → ebnfDiagram-CCIWWBDH-ni71VSx1.js} +1 -1
- package/dist/client/assets/{erDiagram-Q63AITRT-C80qorTS.js → erDiagram-Q63AITRT-DODYotxF.js} +1 -1
- package/dist/client/assets/{flowDiagram-23GEKE2U-SHOUH72g.js → flowDiagram-23GEKE2U-CN1Vp7G4.js} +1 -1
- package/dist/client/assets/{ganttDiagram-NO4QXBWP-DTCfORwE.js → ganttDiagram-NO4QXBWP-DoVPMnyV.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-IHSO6WYX--f38fniT.js → gitGraphDiagram-IHSO6WYX-jiV9FRlU.js} +1 -1
- package/dist/client/assets/{index-wAbbn4Kn.js → index-DPj6Kass.js} +67 -67
- package/dist/client/assets/{infoDiagram-FWYZ7A6U-Bjyyad06.js → infoDiagram-FWYZ7A6U-Bk78PinY.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-FXEZZL3T-DIRrTmK4.js → ishikawaDiagram-FXEZZL3T-C3lsh4Lh.js} +1 -1
- package/dist/client/assets/{journeyDiagram-5HDEW3XC-DscBOIxr.js → journeyDiagram-5HDEW3XC-CHLuYRBt.js} +1 -1
- package/dist/client/assets/{kanban-definition-HUTT4EX6-IDE8xWjr.js → kanban-definition-HUTT4EX6-UXjM1jpV.js} +1 -1
- package/dist/client/assets/{linear-EZXDqVdB.js → linear-BKUyrWyw.js} +1 -1
- package/dist/client/assets/{mermaid.core-Ctixq-l7.js → mermaid.core-Bhj0Bx21.js} +4 -4
- package/dist/client/assets/{mindmap-definition-LN4V7U3C-DbExuHFY.js → mindmap-definition-LN4V7U3C-Dxv1Vfld.js} +1 -1
- package/dist/client/assets/{pegDiagram-2B236MQR-BkPjbAG_.js → pegDiagram-2B236MQR-DYZ4d5zF.js} +1 -1
- package/dist/client/assets/{pieDiagram-ENE6RG2P-D_lAR-It.js → pieDiagram-ENE6RG2P-BoId8qhV.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-ABIIQ3AL-CVF1_nGt.js → quadrantDiagram-ABIIQ3AL-sswrNp8d.js} +1 -1
- package/dist/client/assets/{railroadDiagram-RFXS5EU6-C1TDrvOx.js → railroadDiagram-RFXS5EU6-BfYV2CjC.js} +1 -1
- package/dist/client/assets/{requirementDiagram-TGXJPOKE-5jOozNKC.js → requirementDiagram-TGXJPOKE-DZhZPZVt.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-HTMAVEWB-CKPHCzaS.js → sankeyDiagram-HTMAVEWB-DXKoOi7e.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-DBY2YBRQ-tBpAtlZ_.js → sequenceDiagram-DBY2YBRQ-CpulK2HV.js} +1 -1
- package/dist/client/assets/{sizeCapture-X5ZJPWSS-Ctwe0aFO.js → sizeCapture-X5ZJPWSS-D-mlzS9r.js} +1 -1
- package/dist/client/assets/{stateDiagram-2N3HPSRC-xJM2eLWM.js → stateDiagram-2N3HPSRC-l_ydCaW0.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-6OUMAXLB-Gh5mC4sm.js +1 -0
- package/dist/client/assets/{swimlanes-5IMT3BWC-DTWYG-dw.js → swimlanes-5IMT3BWC-eEUQLyov.js} +2 -2
- package/dist/client/assets/swimlanesDiagram-G3AALYLV-CFuSbo_y.js +8 -0
- package/dist/client/assets/{timeline-definition-FHXFAJF6-CDuhXHMB.js → timeline-definition-FHXFAJF6-Bu7sztn9.js} +1 -1
- package/dist/client/assets/{vennDiagram-L72KCM5P-BYljcRnF.js → vennDiagram-L72KCM5P-Bat45ZW0.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-EHGQE667-Q49XcSX3.js → wardleyDiagram-EHGQE667-Bxn0-4Oq.js} +1 -1
- package/dist/client/assets/{xychartDiagram-FW5EYKEG-0nmuMvBg.js → xychartDiagram-FW5EYKEG-C4BdUEul.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/client/sw.js +1 -1
- package/dist/server/routes/terminal.js +24 -17
- package/dist/server/utils/desktopRuntimeOwner.js +105 -0
- package/package.json +1 -1
- package/runtime-manifest.json +2 -2
- package/dist/client/assets/channel-j6Ch4-AO.js +0 -1
- package/dist/client/assets/classDiagram-OUVF2IWQ-DYdO3KAi.js +0 -1
- package/dist/client/assets/classDiagram-v2-EOCWNBFH-DYdO3KAi.js +0 -1
- package/dist/client/assets/stateDiagram-v2-6OUMAXLB-LbiwUd_W.js +0 -1
- package/dist/client/assets/swimlanesDiagram-G3AALYLV-D-h9Zx5q.js +0 -8
package/.desktop-dist/main.js
CHANGED
|
@@ -3,16 +3,19 @@ import { execFile, spawn } from 'node:child_process';
|
|
|
3
3
|
import crypto from 'node:crypto';
|
|
4
4
|
import dgram from 'node:dgram';
|
|
5
5
|
import fs from 'node:fs';
|
|
6
|
+
import http from 'node:http';
|
|
6
7
|
import https from 'node:https';
|
|
7
8
|
import os from 'node:os';
|
|
8
9
|
import path from 'node:path';
|
|
9
10
|
import { promisify } from 'node:util';
|
|
10
11
|
import { fileURLToPath } from 'node:url';
|
|
11
12
|
import { desktopStatusTooltip, formatCompactDesktopStatus, menuBarStatusRows, mergeServiceActivity, nextServiceOrigin, normalizeServiceActivity, summarizeServiceActivity, } from './activityStatus.js';
|
|
12
|
-
import { checkForDesktopUpdates, checkForRuntimeUpdates, configureDesktopUpdater, ensureLatestRuntime, getDesktopUpdateState, getDesktopRuntimeUpdateState, installDownloadedDesktopUpdate, markDesktopRuntimeRestarting, markDesktopRuntimeRunning, subscribeDesktopRuntimeUpdateState, subscribeDesktopUpdateState, } from './updater.js';
|
|
13
|
+
import { checkForDesktopUpdates, checkForRuntimeUpdates, configureDesktopUpdater, ensureLatestRuntime, getDesktopUpdateState, getDesktopRuntimeUpdateState, installDownloadedDesktopUpdate, markDesktopRuntimeRestartFailed, markDesktopRuntimeRestarting, markDesktopRuntimeRunning, subscribeDesktopRuntimeUpdateState, subscribeDesktopUpdateState, } from './updater.js';
|
|
13
14
|
import { resolvePackagedRuntime, rollbackDownloadedRuntime, } from './runtime.js';
|
|
14
15
|
import { isExternalLinkStagingUrl, isSafeExternalUrl } from './externalLinks.js';
|
|
15
16
|
import { shouldThrottleDesktopRenderer } from './windowPolicy.js';
|
|
17
|
+
import { checkConnectedServiceRuntime, getConnectedServiceRuntimeState, restartConnectedServiceRuntime, } from './connectedServiceRuntime.js';
|
|
18
|
+
import { isOwnedDesktopRuntimeTarget } from './runtimeTarget.js';
|
|
16
19
|
import { canOfferCertificateTrust, downloadCertificateAuthority, isCertificateTrustError, isLocalNetworkHostname, } from './certificateTrust.js';
|
|
17
20
|
const execFileAsync = promisify(execFile);
|
|
18
21
|
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -20,6 +23,7 @@ const projectRoot = path.resolve(currentDir, '..');
|
|
|
20
23
|
const termdockDir = path.join(os.homedir(), '.termdock');
|
|
21
24
|
const desktopConfigPath = path.join(termdockDir, 'desktop.json');
|
|
22
25
|
const serverStatePath = path.join(termdockDir, 'server.json');
|
|
26
|
+
const desktopRuntimeOwnerSocketPath = path.join(termdockDir, 'desktop-runtime-owner.sock');
|
|
23
27
|
const DEFAULT_LOCAL_URL = 'http://localhost:9834';
|
|
24
28
|
const PROTOCOL_VERSION = 1;
|
|
25
29
|
const HEALTH_TIMEOUT_MS = 3_500;
|
|
@@ -64,6 +68,9 @@ let menuBarStatus = null;
|
|
|
64
68
|
let menuBarStatusWidth = 0;
|
|
65
69
|
let floatingWidgetWindow = null;
|
|
66
70
|
let floatingPositionTimer = null;
|
|
71
|
+
let desktopRuntimeOwnerServer = null;
|
|
72
|
+
let connectedServiceRuntimePollTimer = null;
|
|
73
|
+
let connectedServiceRuntimePollInFlight = false;
|
|
67
74
|
let isQuitting = false;
|
|
68
75
|
const FLOATING_WIDGET_WIDTHS = [64, 108, 152];
|
|
69
76
|
const FLOATING_WIDGET_HEIGHT = 40;
|
|
@@ -989,6 +996,7 @@ function desktopRuntimeEnv(runtime = runtimePaths()) {
|
|
|
989
996
|
.filter(Boolean)
|
|
990
997
|
.join(path.delimiter),
|
|
991
998
|
TERMDOCK_DESKTOP: '1',
|
|
999
|
+
TERMDOCK_DESKTOP_OWNER_SOCKET: desktopRuntimeOwnerSocketPath,
|
|
992
1000
|
TERMDOCK_BUNDLED_RUNTIME: app.isPackaged ? '1' : '0',
|
|
993
1001
|
TERMDOCK_VERSION: runtime.version,
|
|
994
1002
|
TERMDOCK_DESKTOP_SHELL_VERSION: app.getVersion(),
|
|
@@ -1134,28 +1142,137 @@ async function startLocalService() {
|
|
|
1134
1142
|
}
|
|
1135
1143
|
async function restartDesktopManagedRuntime() {
|
|
1136
1144
|
const status = await getLocalServiceStatus();
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
+
const update = getDesktopRuntimeUpdateState();
|
|
1146
|
+
if (!status.running || status.probe?.desktopManaged !== true) {
|
|
1147
|
+
throw new Error('当前服务不是由这个 Termdock Desktop 宿主管理的。');
|
|
1148
|
+
}
|
|
1149
|
+
if (update.status !== 'ready' || !update.latestVersion) {
|
|
1150
|
+
throw new Error('没有等待重启的 Runtime 更新。');
|
|
1151
|
+
}
|
|
1152
|
+
markDesktopRuntimeRestarting();
|
|
1153
|
+
const restartTimer = setTimeout(() => {
|
|
1154
|
+
void (async () => {
|
|
1155
|
+
const pid = status.state?.pid;
|
|
1156
|
+
if (!pid || !isProcessRunning(pid)) {
|
|
1157
|
+
throw new Error('本机服务状态已失效,请重试。');
|
|
1158
|
+
}
|
|
1159
|
+
process.kill(pid, 'SIGTERM');
|
|
1160
|
+
const deadline = Date.now() + 15_000;
|
|
1161
|
+
while (isProcessRunning(pid) && Date.now() < deadline) {
|
|
1162
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
1163
|
+
}
|
|
1164
|
+
if (isProcessRunning(pid))
|
|
1165
|
+
throw new Error(`本机服务 PID ${pid} 未能正常退出。`);
|
|
1166
|
+
const latest = readServerState();
|
|
1167
|
+
if (latest?.pid === pid)
|
|
1168
|
+
fs.rmSync(serverStatePath, { force: true });
|
|
1169
|
+
await startLocalService();
|
|
1170
|
+
})().catch((error) => {
|
|
1171
|
+
markDesktopRuntimeRestartFailed(error);
|
|
1172
|
+
console.error('[desktop-runtime] restart failed', error);
|
|
1173
|
+
});
|
|
1174
|
+
}, 250);
|
|
1175
|
+
restartTimer.unref();
|
|
1176
|
+
return getDesktopRuntimeUpdateState();
|
|
1177
|
+
}
|
|
1178
|
+
function isOwnedDesktopRuntimeWindow(window, status) {
|
|
1179
|
+
const origin = windowServiceOrigins.get(window);
|
|
1180
|
+
if (!origin || !status.running || status.probe?.desktopManaged !== true || !status.state)
|
|
1181
|
+
return false;
|
|
1182
|
+
const localAddresses = new Set(Object.values(os.networkInterfaces())
|
|
1183
|
+
.flatMap((addresses) => addresses?.map((address) => address.address.toLowerCase()) ?? []));
|
|
1184
|
+
return isOwnedDesktopRuntimeTarget({
|
|
1185
|
+
origin,
|
|
1186
|
+
servicePort: status.state.port,
|
|
1187
|
+
desktopManaged: true,
|
|
1188
|
+
localAddresses,
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
async function routeRuntimeOperationForWindow(webContents, desktopOperation, serviceOperation) {
|
|
1192
|
+
const sourceWindow = BrowserWindow.fromWebContents(webContents);
|
|
1193
|
+
if (!sourceWindow || !windowServiceOrigins.has(sourceWindow)) {
|
|
1194
|
+
throw new Error('只能从已连接的 Termdock 服务窗口操作 Runtime。');
|
|
1195
|
+
}
|
|
1196
|
+
const status = await getLocalServiceStatus();
|
|
1197
|
+
return isOwnedDesktopRuntimeWindow(sourceWindow, status)
|
|
1198
|
+
? desktopOperation()
|
|
1199
|
+
: serviceOperation();
|
|
1200
|
+
}
|
|
1201
|
+
function startConnectedServiceRuntimePolling() {
|
|
1202
|
+
if (connectedServiceRuntimePollTimer)
|
|
1203
|
+
return;
|
|
1204
|
+
const poll = async () => {
|
|
1205
|
+
if (connectedServiceRuntimePollInFlight)
|
|
1206
|
+
return;
|
|
1207
|
+
connectedServiceRuntimePollInFlight = true;
|
|
1208
|
+
try {
|
|
1209
|
+
const status = await getLocalServiceStatus();
|
|
1210
|
+
await Promise.all(BrowserWindow.getAllWindows().map(async (window) => {
|
|
1211
|
+
if (window.isDestroyed() || !windowServiceOrigins.has(window))
|
|
1212
|
+
return;
|
|
1213
|
+
if (isOwnedDesktopRuntimeWindow(window, status))
|
|
1214
|
+
return;
|
|
1215
|
+
try {
|
|
1216
|
+
const state = await getConnectedServiceRuntimeState(window.webContents);
|
|
1217
|
+
if (!window.isDestroyed()) {
|
|
1218
|
+
window.webContents.send('desktop:runtime-update-state-changed', state);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
catch {
|
|
1222
|
+
// A disconnected or older service will be retried on the next poll.
|
|
1223
|
+
}
|
|
1224
|
+
}));
|
|
1145
1225
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
while (isProcessRunning(pid) && Date.now() < deadline) {
|
|
1149
|
-
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
1226
|
+
finally {
|
|
1227
|
+
connectedServiceRuntimePollInFlight = false;
|
|
1150
1228
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1229
|
+
};
|
|
1230
|
+
void poll();
|
|
1231
|
+
connectedServiceRuntimePollTimer = setInterval(() => void poll(), 2_000);
|
|
1232
|
+
connectedServiceRuntimePollTimer.unref();
|
|
1233
|
+
}
|
|
1234
|
+
function writeRuntimeOwnerResponse(response, statusCode, payload) {
|
|
1235
|
+
response.writeHead(statusCode, { 'content-type': 'application/json; charset=utf-8' });
|
|
1236
|
+
response.end(JSON.stringify(payload));
|
|
1237
|
+
}
|
|
1238
|
+
async function startDesktopRuntimeOwnerServer() {
|
|
1239
|
+
if (desktopRuntimeOwnerServer)
|
|
1240
|
+
return;
|
|
1241
|
+
fs.mkdirSync(termdockDir, { recursive: true, mode: 0o700 });
|
|
1242
|
+
fs.rmSync(desktopRuntimeOwnerSocketPath, { force: true });
|
|
1243
|
+
const server = http.createServer((request, response) => {
|
|
1244
|
+
void (async () => {
|
|
1245
|
+
if (request.method === 'GET' && request.url === '/runtime-update') {
|
|
1246
|
+
writeRuntimeOwnerResponse(response, 200, getDesktopRuntimeUpdateState());
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1249
|
+
if (request.method === 'POST' && request.url === '/runtime-update/check') {
|
|
1250
|
+
writeRuntimeOwnerResponse(response, 200, await checkForRuntimeUpdates());
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
if (request.method === 'POST' && request.url === '/runtime-update/restart') {
|
|
1254
|
+
writeRuntimeOwnerResponse(response, 202, await restartDesktopManagedRuntime());
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
writeRuntimeOwnerResponse(response, 404, { error: '未知的 Desktop Runtime 操作。' });
|
|
1258
|
+
})().catch((error) => {
|
|
1259
|
+
writeRuntimeOwnerResponse(response, 409, {
|
|
1260
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1261
|
+
});
|
|
1262
|
+
});
|
|
1263
|
+
});
|
|
1264
|
+
await new Promise((resolve, reject) => {
|
|
1265
|
+
server.once('error', reject);
|
|
1266
|
+
server.listen(desktopRuntimeOwnerSocketPath, () => {
|
|
1267
|
+
server.off('error', reject);
|
|
1268
|
+
resolve();
|
|
1269
|
+
});
|
|
1270
|
+
});
|
|
1271
|
+
server.on('error', (error) => {
|
|
1272
|
+
console.error('[desktop-runtime] owner socket failed', error);
|
|
1273
|
+
});
|
|
1274
|
+
fs.chmodSync(desktopRuntimeOwnerSocketPath, 0o600);
|
|
1275
|
+
desktopRuntimeOwnerServer = server;
|
|
1159
1276
|
}
|
|
1160
1277
|
function shellQuote(value) {
|
|
1161
1278
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
@@ -1650,9 +1767,9 @@ function installIpcHandlers() {
|
|
|
1650
1767
|
ipcMain.handle('desktop:update-state', () => getDesktopUpdateState());
|
|
1651
1768
|
ipcMain.handle('desktop:check-update', () => checkForDesktopUpdates());
|
|
1652
1769
|
ipcMain.handle('desktop:install-update', () => installDownloadedDesktopUpdate());
|
|
1653
|
-
ipcMain.handle('desktop:runtime-update-state', () => getDesktopRuntimeUpdateState());
|
|
1654
|
-
ipcMain.handle('desktop:check-runtime-update', () => checkForRuntimeUpdates());
|
|
1655
|
-
ipcMain.handle('desktop:restart-runtime', () => restartDesktopManagedRuntime());
|
|
1770
|
+
ipcMain.handle('desktop:runtime-update-state', (event) => routeRuntimeOperationForWindow(event.sender, () => getDesktopRuntimeUpdateState(), () => getConnectedServiceRuntimeState(event.sender)));
|
|
1771
|
+
ipcMain.handle('desktop:check-runtime-update', (event) => routeRuntimeOperationForWindow(event.sender, () => checkForRuntimeUpdates(), () => checkConnectedServiceRuntime(event.sender)));
|
|
1772
|
+
ipcMain.handle('desktop:restart-runtime', (event) => routeRuntimeOperationForWindow(event.sender, () => restartDesktopManagedRuntime(), () => restartConnectedServiceRuntime(event.sender)));
|
|
1656
1773
|
ipcMain.handle('desktop:show-connection-center', () => showConnectionCenter());
|
|
1657
1774
|
ipcMain.handle('desktop:reveal-data-directory', async () => {
|
|
1658
1775
|
fs.mkdirSync(termdockDir, { recursive: true, mode: 0o700 });
|
|
@@ -1924,6 +2041,7 @@ function installMenu() {
|
|
|
1924
2041
|
app.whenReady().then(async () => {
|
|
1925
2042
|
triggerLocalNetworkPermission();
|
|
1926
2043
|
configureLocalServiceCertificateTrust();
|
|
2044
|
+
await startDesktopRuntimeOwnerServer();
|
|
1927
2045
|
installIpcHandlers();
|
|
1928
2046
|
installMenu();
|
|
1929
2047
|
refreshDesktopStatusSurfaces();
|
|
@@ -1937,11 +2055,15 @@ app.whenReady().then(async () => {
|
|
|
1937
2055
|
}
|
|
1938
2056
|
});
|
|
1939
2057
|
subscribeDesktopRuntimeUpdateState((state) => {
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
window.
|
|
1943
|
-
|
|
2058
|
+
void getLocalServiceStatus().then((status) => {
|
|
2059
|
+
for (const window of BrowserWindow.getAllWindows()) {
|
|
2060
|
+
if (!window.isDestroyed() && isOwnedDesktopRuntimeWindow(window, status)) {
|
|
2061
|
+
window.webContents.send('desktop:runtime-update-state-changed', state);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
});
|
|
1944
2065
|
});
|
|
2066
|
+
startConnectedServiceRuntimePolling();
|
|
1945
2067
|
const startupConfig = readDesktopConfig();
|
|
1946
2068
|
const restoreUrls = startupConfig.openConnectionUrls;
|
|
1947
2069
|
startupRestoreActive = true;
|
|
@@ -2000,5 +2122,12 @@ app.on('window-all-closed', () => {
|
|
|
2000
2122
|
});
|
|
2001
2123
|
app.on('before-quit', () => {
|
|
2002
2124
|
isQuitting = true;
|
|
2125
|
+
desktopRuntimeOwnerServer?.close();
|
|
2126
|
+
desktopRuntimeOwnerServer = null;
|
|
2127
|
+
if (connectedServiceRuntimePollTimer)
|
|
2128
|
+
clearInterval(connectedServiceRuntimePollTimer);
|
|
2129
|
+
connectedServiceRuntimePollTimer = null;
|
|
2130
|
+
connectedServiceRuntimePollInFlight = false;
|
|
2131
|
+
fs.rmSync(desktopRuntimeOwnerSocketPath, { force: true });
|
|
2003
2132
|
});
|
|
2004
2133
|
export { PROTOCOL_VERSION };
|