termdock 1.4.127 → 1.4.128

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.desktop-dist/main.js +80 -22
  2. package/dist/client/assets/{ModelPreview-B3caplvh.js → ModelPreview-Ki--VGiC.js} +1 -1
  3. package/dist/client/assets/{abnfDiagram-VRR7QNED-Pm2cPR47.js → abnfDiagram-VRR7QNED-_MScG92N.js} +1 -1
  4. package/dist/client/assets/{arc-Du2jqJEu.js → arc-t9qRCmSV.js} +1 -1
  5. package/dist/client/assets/{architectureDiagram-ZJ3FMSHR-UZZ-hCDJ.js → architectureDiagram-ZJ3FMSHR-sFlMCTBw.js} +1 -1
  6. package/dist/client/assets/{blockDiagram-677ZJIJ3-DCdHiW0y.js → blockDiagram-677ZJIJ3-ssxX4KkU.js} +1 -1
  7. package/dist/client/assets/{c4Diagram-LMCZKHZV-CI2wB8cp.js → c4Diagram-LMCZKHZV-BCz5LtTX.js} +1 -1
  8. package/dist/client/assets/channel-DLbt-DA1.js +1 -0
  9. package/dist/client/assets/{chunk-2Q5K7J3B-BOWA0kur.js → chunk-2Q5K7J3B-CDimwARA.js} +1 -1
  10. package/dist/client/assets/{chunk-32BRIVSS-7oLxVo5n.js → chunk-32BRIVSS-CDmUf83L.js} +1 -1
  11. package/dist/client/assets/{chunk-5VM5RSS4-CmqxvKXC.js → chunk-5VM5RSS4-DLtTCYUg.js} +1 -1
  12. package/dist/client/assets/{chunk-EX3LRPZG-DORF3Bb-.js → chunk-EX3LRPZG-w_FWq-tH.js} +1 -1
  13. package/dist/client/assets/{chunk-JWPE2WC7-CPf240uh.js → chunk-JWPE2WC7-B0zV1WOe.js} +1 -1
  14. package/dist/client/assets/{chunk-MOJQB5TN-BXWYBupN.js → chunk-MOJQB5TN-C2VFDFd0.js} +1 -1
  15. package/dist/client/assets/{chunk-RYQCIY6F-DZNPiduN.js → chunk-RYQCIY6F-BaaZmXwK.js} +1 -1
  16. package/dist/client/assets/{chunk-V7JOEXUC-CmDRmHMg.js → chunk-V7JOEXUC-p5cKhdl6.js} +1 -1
  17. package/dist/client/assets/{chunk-VR4S4FIN-DHHyq_Zz.js → chunk-VR4S4FIN-DzfT9at0.js} +1 -1
  18. package/dist/client/assets/{chunk-XXDRQBXY-C8ImJLqT.js → chunk-XXDRQBXY-C1zTdwEh.js} +1 -1
  19. package/dist/client/assets/classDiagram-OUVF2IWQ-CtCQ5VTR.js +1 -0
  20. package/dist/client/assets/classDiagram-v2-EOCWNBFH-CtCQ5VTR.js +1 -0
  21. package/dist/client/assets/{cose-bilkent-JH36ORCC-9vG_EL3b.js → cose-bilkent-JH36ORCC-BGHVpXFF.js} +1 -1
  22. package/dist/client/assets/{cynefin-VYW2F7L2-CIs-32JD.js → cynefin-VYW2F7L2-BwZxg1VK.js} +1 -1
  23. package/dist/client/assets/{cynefinDiagram-TSTJHNR4-DikbAwAV.js → cynefinDiagram-TSTJHNR4-D49XyIFA.js} +1 -1
  24. package/dist/client/assets/{dagre-VKFMJZFB-CfrhX7w8.js → dagre-VKFMJZFB-DXoRuv6O.js} +1 -1
  25. package/dist/client/assets/{diagram-FQU43EPY-Dyrs6fiZ.js → diagram-FQU43EPY-D0vgZCfK.js} +1 -1
  26. package/dist/client/assets/{diagram-G47NLZAW-BpT0tI-h.js → diagram-G47NLZAW-9K9fR0Z0.js} +1 -1
  27. package/dist/client/assets/{diagram-NH7WQ7WH-CFTgimjj.js → diagram-NH7WQ7WH-CIIC3eUC.js} +1 -1
  28. package/dist/client/assets/{diagram-OA4YK3LP-ROVSgH9I.js → diagram-OA4YK3LP-CA3Uw6Ea.js} +1 -1
  29. package/dist/client/assets/{diagram-WEI45ONY-CGcDsOXD.js → diagram-WEI45ONY-dhaSf1fa.js} +1 -1
  30. package/dist/client/assets/{ebnfDiagram-CCIWWBDH-BMAXtWJG.js → ebnfDiagram-CCIWWBDH-0bWc11Yz.js} +1 -1
  31. package/dist/client/assets/{erDiagram-Q63AITRT-C80qorTS.js → erDiagram-Q63AITRT-C4FPyL3a.js} +1 -1
  32. package/dist/client/assets/{flowDiagram-23GEKE2U-SHOUH72g.js → flowDiagram-23GEKE2U-DXY0Jxj_.js} +1 -1
  33. package/dist/client/assets/{ganttDiagram-NO4QXBWP-DTCfORwE.js → ganttDiagram-NO4QXBWP-RPMjjnRd.js} +1 -1
  34. package/dist/client/assets/{gitGraphDiagram-IHSO6WYX--f38fniT.js → gitGraphDiagram-IHSO6WYX-Bf4HUqTl.js} +1 -1
  35. package/dist/client/assets/{index-wAbbn4Kn.js → index-D75wYB98.js} +67 -67
  36. package/dist/client/assets/{infoDiagram-FWYZ7A6U-Bjyyad06.js → infoDiagram-FWYZ7A6U-ZqP7Ocf3.js} +1 -1
  37. package/dist/client/assets/{ishikawaDiagram-FXEZZL3T-DIRrTmK4.js → ishikawaDiagram-FXEZZL3T-BzdFAcyT.js} +1 -1
  38. package/dist/client/assets/{journeyDiagram-5HDEW3XC-DscBOIxr.js → journeyDiagram-5HDEW3XC-BfSvMq6y.js} +1 -1
  39. package/dist/client/assets/{kanban-definition-HUTT4EX6-IDE8xWjr.js → kanban-definition-HUTT4EX6-Dpf9hCl5.js} +1 -1
  40. package/dist/client/assets/{linear-EZXDqVdB.js → linear-ZmI28AZz.js} +1 -1
  41. package/dist/client/assets/{mermaid.core-Ctixq-l7.js → mermaid.core-BTzHsVSr.js} +4 -4
  42. package/dist/client/assets/{mindmap-definition-LN4V7U3C-DbExuHFY.js → mindmap-definition-LN4V7U3C-By5Ie3jN.js} +1 -1
  43. package/dist/client/assets/{pegDiagram-2B236MQR-BkPjbAG_.js → pegDiagram-2B236MQR--NolZ5bc.js} +1 -1
  44. package/dist/client/assets/{pieDiagram-ENE6RG2P-D_lAR-It.js → pieDiagram-ENE6RG2P-DI-Y6Yz-.js} +1 -1
  45. package/dist/client/assets/{quadrantDiagram-ABIIQ3AL-CVF1_nGt.js → quadrantDiagram-ABIIQ3AL-DYnBddBB.js} +1 -1
  46. package/dist/client/assets/{railroadDiagram-RFXS5EU6-C1TDrvOx.js → railroadDiagram-RFXS5EU6-DOOkdA8K.js} +1 -1
  47. package/dist/client/assets/{requirementDiagram-TGXJPOKE-5jOozNKC.js → requirementDiagram-TGXJPOKE-BO_adPJj.js} +1 -1
  48. package/dist/client/assets/{sankeyDiagram-HTMAVEWB-CKPHCzaS.js → sankeyDiagram-HTMAVEWB-LVYAe84b.js} +1 -1
  49. package/dist/client/assets/{sequenceDiagram-DBY2YBRQ-tBpAtlZ_.js → sequenceDiagram-DBY2YBRQ-DAkGCs0T.js} +1 -1
  50. package/dist/client/assets/{sizeCapture-X5ZJPWSS-Ctwe0aFO.js → sizeCapture-X5ZJPWSS-CszARDsf.js} +1 -1
  51. package/dist/client/assets/{stateDiagram-2N3HPSRC-xJM2eLWM.js → stateDiagram-2N3HPSRC-DUs3aedx.js} +1 -1
  52. package/dist/client/assets/stateDiagram-v2-6OUMAXLB-B8crJAxl.js +1 -0
  53. package/dist/client/assets/{swimlanes-5IMT3BWC-DTWYG-dw.js → swimlanes-5IMT3BWC-Duig5jF-.js} +2 -2
  54. package/dist/client/assets/swimlanesDiagram-G3AALYLV-Di4AbqD1.js +8 -0
  55. package/dist/client/assets/{timeline-definition-FHXFAJF6-CDuhXHMB.js → timeline-definition-FHXFAJF6-BKW9IU-6.js} +1 -1
  56. package/dist/client/assets/{vennDiagram-L72KCM5P-BYljcRnF.js → vennDiagram-L72KCM5P-Cet4IXwa.js} +1 -1
  57. package/dist/client/assets/{wardleyDiagram-EHGQE667-Q49XcSX3.js → wardleyDiagram-EHGQE667-DgoE-0pr.js} +1 -1
  58. package/dist/client/assets/{xychartDiagram-FW5EYKEG-0nmuMvBg.js → xychartDiagram-FW5EYKEG-BqJ_UrZL.js} +1 -1
  59. package/dist/client/index.html +1 -1
  60. package/dist/client/sw.js +1 -1
  61. package/dist/server/routes/terminal.js +24 -17
  62. package/dist/server/utils/desktopRuntimeOwner.js +105 -0
  63. package/package.json +1 -1
  64. package/runtime-manifest.json +2 -2
  65. package/dist/client/assets/channel-j6Ch4-AO.js +0 -1
  66. package/dist/client/assets/classDiagram-OUVF2IWQ-DYdO3KAi.js +0 -1
  67. package/dist/client/assets/classDiagram-v2-EOCWNBFH-DYdO3KAi.js +0 -1
  68. package/dist/client/assets/stateDiagram-v2-6OUMAXLB-LbiwUd_W.js +0 -1
  69. package/dist/client/assets/swimlanesDiagram-G3AALYLV-D-h9Zx5q.js +0 -8
@@ -3,13 +3,14 @@ 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';
@@ -20,6 +21,7 @@ const projectRoot = path.resolve(currentDir, '..');
20
21
  const termdockDir = path.join(os.homedir(), '.termdock');
21
22
  const desktopConfigPath = path.join(termdockDir, 'desktop.json');
22
23
  const serverStatePath = path.join(termdockDir, 'server.json');
24
+ const desktopRuntimeOwnerSocketPath = path.join(termdockDir, 'desktop-runtime-owner.sock');
23
25
  const DEFAULT_LOCAL_URL = 'http://localhost:9834';
24
26
  const PROTOCOL_VERSION = 1;
25
27
  const HEALTH_TIMEOUT_MS = 3_500;
@@ -64,6 +66,7 @@ let menuBarStatus = null;
64
66
  let menuBarStatusWidth = 0;
65
67
  let floatingWidgetWindow = null;
66
68
  let floatingPositionTimer = null;
69
+ let desktopRuntimeOwnerServer = null;
67
70
  let isQuitting = false;
68
71
  const FLOATING_WIDGET_WIDTHS = [64, 108, 152];
69
72
  const FLOATING_WIDGET_HEIGHT = 40;
@@ -989,6 +992,7 @@ function desktopRuntimeEnv(runtime = runtimePaths()) {
989
992
  .filter(Boolean)
990
993
  .join(path.delimiter),
991
994
  TERMDOCK_DESKTOP: '1',
995
+ TERMDOCK_DESKTOP_OWNER_SOCKET: desktopRuntimeOwnerSocketPath,
992
996
  TERMDOCK_BUNDLED_RUNTIME: app.isPackaged ? '1' : '0',
993
997
  TERMDOCK_VERSION: runtime.version,
994
998
  TERMDOCK_DESKTOP_SHELL_VERSION: app.getVersion(),
@@ -1134,29 +1138,79 @@ async function startLocalService() {
1134
1138
  }
1135
1139
  async function restartDesktopManagedRuntime() {
1136
1140
  const status = await getLocalServiceStatus();
1137
- if (status.running) {
1138
- if (status.probe?.desktopManaged !== true) {
1139
- throw new Error('当前本机服务不是由桌面版启动的,不能由桌面版自动重启。');
1140
- }
1141
- markDesktopRuntimeRestarting();
1142
- const pid = status.state?.pid;
1143
- if (!pid || !isProcessRunning(pid)) {
1144
- throw new Error('桌面服务状态已失效,请重新打开连接中心。');
1145
- }
1146
- process.kill(pid, 'SIGTERM');
1147
- const deadline = Date.now() + 15_000;
1148
- while (isProcessRunning(pid) && Date.now() < deadline) {
1149
- await new Promise((resolve) => setTimeout(resolve, 150));
1150
- }
1151
- if (isProcessRunning(pid))
1152
- throw new Error(`桌面服务 PID ${pid} 未能正常退出。`);
1153
- const latest = readServerState();
1154
- if (latest?.pid === pid)
1155
- fs.rmSync(serverStatePath, { force: true });
1156
- }
1157
- await startLocalService();
1141
+ const update = getDesktopRuntimeUpdateState();
1142
+ if (!status.running || status.probe?.desktopManaged !== true) {
1143
+ throw new Error('当前服务不是由这个 Termdock Desktop 宿主管理的。');
1144
+ }
1145
+ if (update.status !== 'ready' || !update.latestVersion) {
1146
+ throw new Error('没有等待重启的 Runtime 更新。');
1147
+ }
1148
+ markDesktopRuntimeRestarting();
1149
+ const restartTimer = setTimeout(() => {
1150
+ void (async () => {
1151
+ const pid = status.state?.pid;
1152
+ if (!pid || !isProcessRunning(pid)) {
1153
+ throw new Error('本机服务状态已失效,请重试。');
1154
+ }
1155
+ process.kill(pid, 'SIGTERM');
1156
+ const deadline = Date.now() + 15_000;
1157
+ while (isProcessRunning(pid) && Date.now() < deadline) {
1158
+ await new Promise((resolve) => setTimeout(resolve, 150));
1159
+ }
1160
+ if (isProcessRunning(pid))
1161
+ throw new Error(`本机服务 PID ${pid} 未能正常退出。`);
1162
+ const latest = readServerState();
1163
+ if (latest?.pid === pid)
1164
+ fs.rmSync(serverStatePath, { force: true });
1165
+ await startLocalService();
1166
+ })().catch((error) => {
1167
+ markDesktopRuntimeRestartFailed(error);
1168
+ console.error('[desktop-runtime] restart failed', error);
1169
+ });
1170
+ }, 250);
1171
+ restartTimer.unref();
1158
1172
  return getDesktopRuntimeUpdateState();
1159
1173
  }
1174
+ function writeRuntimeOwnerResponse(response, statusCode, payload) {
1175
+ response.writeHead(statusCode, { 'content-type': 'application/json; charset=utf-8' });
1176
+ response.end(JSON.stringify(payload));
1177
+ }
1178
+ async function startDesktopRuntimeOwnerServer() {
1179
+ if (desktopRuntimeOwnerServer)
1180
+ return;
1181
+ fs.mkdirSync(termdockDir, { recursive: true, mode: 0o700 });
1182
+ fs.rmSync(desktopRuntimeOwnerSocketPath, { force: true });
1183
+ const server = http.createServer((request, response) => {
1184
+ void (async () => {
1185
+ if (request.method === 'GET' && request.url === '/runtime-update') {
1186
+ writeRuntimeOwnerResponse(response, 200, getDesktopRuntimeUpdateState());
1187
+ return;
1188
+ }
1189
+ if (request.method === 'POST' && request.url === '/runtime-update/check') {
1190
+ writeRuntimeOwnerResponse(response, 200, await checkForRuntimeUpdates());
1191
+ return;
1192
+ }
1193
+ if (request.method === 'POST' && request.url === '/runtime-update/restart') {
1194
+ writeRuntimeOwnerResponse(response, 202, await restartDesktopManagedRuntime());
1195
+ return;
1196
+ }
1197
+ writeRuntimeOwnerResponse(response, 404, { error: '未知的 Desktop Runtime 操作。' });
1198
+ })().catch((error) => {
1199
+ writeRuntimeOwnerResponse(response, 409, {
1200
+ error: error instanceof Error ? error.message : String(error),
1201
+ });
1202
+ });
1203
+ });
1204
+ await new Promise((resolve, reject) => {
1205
+ server.once('error', reject);
1206
+ server.listen(desktopRuntimeOwnerSocketPath, () => {
1207
+ server.off('error', reject);
1208
+ resolve();
1209
+ });
1210
+ });
1211
+ fs.chmodSync(desktopRuntimeOwnerSocketPath, 0o600);
1212
+ desktopRuntimeOwnerServer = server;
1213
+ }
1160
1214
  function shellQuote(value) {
1161
1215
  return `'${value.replace(/'/g, `'\\''`)}'`;
1162
1216
  }
@@ -1924,6 +1978,7 @@ function installMenu() {
1924
1978
  app.whenReady().then(async () => {
1925
1979
  triggerLocalNetworkPermission();
1926
1980
  configureLocalServiceCertificateTrust();
1981
+ await startDesktopRuntimeOwnerServer();
1927
1982
  installIpcHandlers();
1928
1983
  installMenu();
1929
1984
  refreshDesktopStatusSurfaces();
@@ -2000,5 +2055,8 @@ app.on('window-all-closed', () => {
2000
2055
  });
2001
2056
  app.on('before-quit', () => {
2002
2057
  isQuitting = true;
2058
+ desktopRuntimeOwnerServer?.close();
2059
+ desktopRuntimeOwnerServer = null;
2060
+ fs.rmSync(desktopRuntimeOwnerSocketPath, { force: true });
2003
2061
  });
2004
2062
  export { PROTOCOL_VERSION };