@linxin666/dsh-remote-web-ui 0.1.10 → 0.1.11
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 +17 -6
- package/lib/client.js +403 -14
- package/lib/client.js.map +1 -1
- package/lib/index.js +406 -17
- package/lib/types/client/RemoteEntry.d.ts.map +1 -1
- package/lib/types/client/RemoteEntry.js +9 -7
- package/lib/types/client/UpdateEntry.d.ts +14 -0
- package/lib/types/client/UpdateEntry.d.ts.map +1 -0
- package/lib/types/client/UpdateEntry.js +68 -0
- package/lib/types/client/UpdatePanel.d.ts +40 -0
- package/lib/types/client/UpdatePanel.d.ts.map +1 -0
- package/lib/types/client/UpdatePanel.js +82 -0
- package/lib/types/client/index.d.ts +2 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +56 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +58 -0
- package/lib/types/client/update-api.d.ts +19 -0
- package/lib/types/client/update-api.d.ts.map +1 -0
- package/lib/types/client/update-api.js +27 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +45 -1
- package/lib/types/routes.d.ts +15 -0
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +1 -1
- package/lib/types/update-routes.d.ts +30 -0
- package/lib/types/update-routes.d.ts.map +1 -0
- package/lib/types/update-routes.js +52 -0
- package/lib/types/update.d.ts +191 -0
- package/lib/types/update.d.ts.map +1 -0
- package/lib/types/update.js +333 -0
- package/package.json +1 -1
- package/src/client/RemoteEntry.tsx +12 -7
- package/src/client/UpdateEntry.tsx +96 -0
- package/src/client/UpdatePanel.tsx +203 -0
- package/src/client/index.ts +2 -0
- package/src/client/locales.ts +58 -0
- package/src/client/remote.module.css +109 -0
- package/src/client/update-api.ts +29 -0
- package/src/index.ts +51 -1
- package/src/routes.ts +1 -1
- package/src/update-routes.ts +71 -0
- package/src/update.ts +435 -0
package/README.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# DSH Remote Web UI
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> 移动端远程控制 + 一键远程更新:扫码配对后用手机远程使用当前 dsh web 工作区;
|
|
4
|
+
> 点击侧边栏更新按钮自动检查并更新 dsh-web-ui 全家桶。
|
|
4
5
|
|
|
5
6
|
This repository is an external plugin package for DeepSeek Harness (DSH):
|
|
6
|
-
scan-to-pair mobile remote control for the dsh web GUI
|
|
7
|
-
|
|
8
|
-
the `/api/pair` route family
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
scan-to-pair mobile remote control for the dsh web GUI, plus a one-click
|
|
8
|
+
self-update for the dsh-web-ui family. It is a single dual-face package — the
|
|
9
|
+
host half owns pairing tokens, device sessions, the `/api/pair` route family,
|
|
10
|
+
and the `/api/update` surface; the browser half renders the sidebar-foot
|
|
11
|
+
entries (the download trigger and the phone icon beside the settings button),
|
|
12
|
+
the pairing panel with a QR code, live device status, and stop/refresh/copy
|
|
13
|
+
actions, and the update panel that probes and runs the update.
|
|
11
14
|
|
|
12
15
|
## What it does
|
|
13
16
|
|
|
@@ -30,6 +33,14 @@ QR code, live device status, and stop/refresh/copy actions.
|
|
|
30
33
|
device cookie, so the QR is the only way into a LAN-exposed dsh web.
|
|
31
34
|
- **Live status**: the desktop panel mirrors the pairing state in real time
|
|
32
35
|
(waiting → connected → disconnected) over an SSE stream.
|
|
36
|
+
- **Remote update**: the download trigger in the sidebar foot (left of the
|
|
37
|
+
phone icon) opens the update panel, which probes the npm registry for the
|
|
38
|
+
installed `@linxin666/dsh-*` family releases. When a newer release exists
|
|
39
|
+
the panel runs the update automatically (`pnpm update` inside the owning
|
|
40
|
+
dsh profile; the loopback-only `/api/update/status` + `/api/update/run`
|
|
41
|
+
endpoints drive it) and asks for a dsh web restart to pick it up. Local
|
|
42
|
+
link installs (development mode) are detected and report the npm state
|
|
43
|
+
without updating.
|
|
33
44
|
|
|
34
45
|
## Screenshots
|
|
35
46
|
|
package/lib/client.js
CHANGED
|
@@ -1343,7 +1343,7 @@ window.__ModuleLoader__.load({
|
|
|
1343
1343
|
}
|
|
1344
1344
|
//#endregion
|
|
1345
1345
|
//#region \0dsh-css:/home/runner/work/dsh-web-ui/dsh-web-ui/packages/dsh-remote-web-ui/src/client/remote.module.css.mjs
|
|
1346
|
-
const css$1 = ".uw-Msq_overlay{z-index:1000;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.uw-Msq_mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}.uw-Msq_trigger{width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;transition:background-color .12s,color .12s,box-shadow .12s;display:inline-flex}.uw-Msq_trigger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.uw-Msq_trigger:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}.uw-Msq_trigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);outline:none}.uw-Msq_trigger:disabled{opacity:.5;cursor:default}.uw-Msq_panel{z-index:1;box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);width:560px;max-width:calc(100vw - 48px);max-height:calc(100vh - 48px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:24px;flex-direction:column;gap:14px;padding:24px;font-size:14px;line-height:22px;display:flex;position:relative;overflow:auto}.uw-Msq_header{align-items:flex-start;gap:12px;display:flex}.uw-Msq_heading{flex:1;min-width:0}.uw-Msq_title{margin:0;font-size:18px;font-weight:600;line-height:26px}.uw-Msq_subtitle{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:13px}.uw-Msq_close{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;transition:background-color .12s,color .12s,box-shadow .12s;display:inline-flex}.uw-Msq_close:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_close:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}.uw-Msq_close:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);outline:none}.uw-Msq_close:disabled{opacity:.5;cursor:default}.uw-Msq_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;align-items:center;gap:12px;padding:16px;display:flex}.uw-Msq_cardHeader{justify-content:space-between;align-items:center;gap:12px;width:100%;display:flex}.uw-Msq_cardTitle{font-weight:500}.uw-Msq_badge{white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:6px;min-width:0;padding:2px 10px;font-size:12px;line-height:18px;display:inline-flex}.uw-Msq_badge:before{content:\"\";background:currentColor;border-radius:50%;width:8px;height:8px}.uw-Msq_badge-waiting{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badge-connected{color:var(--dsw-alias-state-success-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badge-disconnected{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badge-stopped{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badgePublic{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badges{flex:none;align-items:center;gap:6px;display:inline-flex}.uw-Msq_qrWrap{background:var(--dsw-alias-bg-base);border-radius:12px;justify-content:center;align-items:center;padding:12px;display:flex}.uw-Msq_qr{display:block}.uw-Msq_expired{color:var(--dsw-alias-state-error-primary);margin:0;font-size:13px}.uw-Msq_expiry{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px}.uw-Msq_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px}.uw-Msq_link{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-caption);font-family:var(--dsw-font-mono,ui-monospace, monospace);margin:0;font-size:12px;overflow:hidden}.uw-Msq_stoppedHint{color:var(--dsw-alias-state-error-primary);margin:0;font-size:13px}.uw-Msq_tunnelNote{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px}.uw-Msq_tunnelFailed{color:var(--dsw-alias-state-error-primary);margin:0;font-size:13px}.uw-Msq_actions{gap:8px;display:flex}.uw-Msq_action{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-elevated-fill);height:34px;color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;border-radius:10px;justify-content:center;align-items:center;gap:6px;padding:0 14px;font-size:13px;transition:background-color .12s,border-color .12s,box-shadow .12s;display:inline-flex}.uw-Msq_action:hover:not(:disabled){background:var(--dsw-alias-button-floating-hover)}.uw-Msq_action:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}.uw-Msq_action:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);outline:none}.uw-Msq_action:disabled{opacity:.5;cursor:default}.uw-Msq_banner{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:16px;padding:16px}.uw-Msq_bannerTitle{color:var(--dsw-alias-state-warn-primary);margin:0;font-weight:500}.uw-Msq_bannerHint{color:var(--dsw-alias-label-secondary);margin:6px 0 0;font-size:13px}.uw-Msq_notice{z-index:2000;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);max-width:min(420px,100vw - 32px);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;padding:12px 16px;position:fixed;top:16px;left:50%;transform:translate(-50%)}.uw-Msq_noticeTitle{color:var(--dsw-alias-state-error-primary);margin:0;font-weight:500}.uw-Msq_noticeDetail{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:13px}.uw-Msq_addresses{border:none;margin:12px 0 0;padding:0}.uw-Msq_addresses legend{color:var(--dsw-alias-label-secondary);padding:0;font-size:13px}.uw-Msq_address{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;cursor:pointer;border-radius:6px;align-items:center;gap:8px;margin-top:6px;padding:4px 6px;font-size:13px;transition:background-color .12s;display:flex}.uw-Msq_address:hover{background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_address input:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);border-radius:50%;outline:none}.uw-Msq_addressValue{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;overflow:hidden}.uw-Msq_addressHint{color:var(--dsw-alias-label-tertiary);margin:6px 0 0;font-size:12px}@media (prefers-reduced-motion:reduce){.uw-Msq_trigger,.uw-Msq_close,.uw-Msq_action,.uw-Msq_address{transition:none}}";
|
|
1346
|
+
const css$1 = ".uw-Msq_overlay{z-index:1000;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.uw-Msq_mask{background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);position:absolute;inset:0}.uw-Msq_trigger{width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;transition:background-color .12s,color .12s,box-shadow .12s;display:inline-flex}.uw-Msq_trigger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.uw-Msq_trigger:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}.uw-Msq_trigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);outline:none}.uw-Msq_trigger:disabled{opacity:.5;cursor:default}.uw-Msq_panel{z-index:1;box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);width:560px;max-width:calc(100vw - 48px);max-height:calc(100vh - 48px);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);border-radius:24px;flex-direction:column;gap:14px;padding:24px;font-size:14px;line-height:22px;display:flex;position:relative;overflow:auto}.uw-Msq_header{align-items:flex-start;gap:12px;display:flex}.uw-Msq_heading{flex:1;min-width:0}.uw-Msq_title{margin:0;font-size:18px;font-weight:600;line-height:26px}.uw-Msq_subtitle{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:13px}.uw-Msq_close{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;transition:background-color .12s,color .12s,box-shadow .12s;display:inline-flex}.uw-Msq_close:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_close:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}.uw-Msq_close:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);outline:none}.uw-Msq_close:disabled{opacity:.5;cursor:default}.uw-Msq_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:16px;flex-direction:column;align-items:center;gap:12px;padding:16px;display:flex}.uw-Msq_cardHeader{justify-content:space-between;align-items:center;gap:12px;width:100%;display:flex}.uw-Msq_cardTitle{font-weight:500}.uw-Msq_badge{white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:6px;min-width:0;padding:2px 10px;font-size:12px;line-height:18px;display:inline-flex}.uw-Msq_badge:before{content:\"\";background:currentColor;border-radius:50%;width:8px;height:8px}.uw-Msq_badge-waiting{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badge-connected{color:var(--dsw-alias-state-success-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badge-disconnected{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badge-stopped{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badgePublic{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_badges{flex:none;align-items:center;gap:6px;display:inline-flex}.uw-Msq_qrWrap{background:var(--dsw-alias-bg-base);border-radius:12px;justify-content:center;align-items:center;padding:12px;display:flex}.uw-Msq_qr{display:block}.uw-Msq_expired{color:var(--dsw-alias-state-error-primary);margin:0;font-size:13px}.uw-Msq_expiry{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px}.uw-Msq_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px}.uw-Msq_link{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-caption);font-family:var(--dsw-font-mono,ui-monospace, monospace);margin:0;font-size:12px;overflow:hidden}.uw-Msq_stoppedHint{color:var(--dsw-alias-state-error-primary);margin:0;font-size:13px}.uw-Msq_tunnelNote{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px}.uw-Msq_tunnelFailed{color:var(--dsw-alias-state-error-primary);margin:0;font-size:13px}.uw-Msq_actions{gap:8px;display:flex}.uw-Msq_action{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-button-elevated-fill);height:34px;color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;border-radius:10px;justify-content:center;align-items:center;gap:6px;padding:0 14px;font-size:13px;transition:background-color .12s,border-color .12s,box-shadow .12s;display:inline-flex}.uw-Msq_action:hover:not(:disabled){background:var(--dsw-alias-button-floating-hover)}.uw-Msq_action:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}.uw-Msq_action:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);outline:none}.uw-Msq_action:disabled{opacity:.5;cursor:default}.uw-Msq_banner{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:16px;padding:16px}.uw-Msq_bannerTitle{color:var(--dsw-alias-state-warn-primary);margin:0;font-weight:500}.uw-Msq_bannerHint{color:var(--dsw-alias-label-secondary);margin:6px 0 0;font-size:13px}.uw-Msq_notice{z-index:2000;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);max-width:min(420px,100vw - 32px);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;padding:12px 16px;position:fixed;top:16px;left:50%;transform:translate(-50%)}.uw-Msq_noticeTitle{color:var(--dsw-alias-state-error-primary);margin:0;font-weight:500}.uw-Msq_noticeDetail{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:13px}.uw-Msq_addresses{border:none;margin:12px 0 0;padding:0}.uw-Msq_addresses legend{color:var(--dsw-alias-label-secondary);padding:0;font-size:13px}.uw-Msq_address{color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;cursor:pointer;border-radius:6px;align-items:center;gap:8px;margin-top:6px;padding:4px 6px;font-size:13px;transition:background-color .12s;display:flex}.uw-Msq_address:hover{background:var(--dsw-alias-interactive-bg-hover)}.uw-Msq_address input:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-bg-layer-2), 0 0 0 4px var(--dsw-alias-brand-primary);border-radius:50%;outline:none}.uw-Msq_addressValue{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;overflow:hidden}.uw-Msq_addressHint{color:var(--dsw-alias-label-tertiary);margin:6px 0 0;font-size:12px}@media (prefers-reduced-motion:reduce){.uw-Msq_trigger,.uw-Msq_close,.uw-Msq_action,.uw-Msq_address{transition:none}}.uw-Msq_entryRow{flex:none;align-items:center;gap:6px;display:flex}.uw-Msq_entryRow[data-rail=rail]{flex-direction:column-reverse;gap:4px}.uw-Msq_updateStatus{margin:0;font-weight:600}.uw-Msq_updateDetail{color:var(--dsw-alias-label-secondary);margin:6px 0 0;font-size:13px}.uw-Msq_updateError{color:var(--dsw-alias-text-danger,var(--dsw-alias-label-primary));margin:0;font-weight:600}.uw-Msq_updateOutput{background:var(--dsw-alias-bg-layer-1);max-height:180px;color:var(--dsw-alias-label-secondary);white-space:pre-wrap;word-break:break-all;border-radius:10px;margin:10px 0 0;padding:10px 12px;font-size:12px;line-height:18px;overflow:auto}.uw-Msq_updateList{flex-direction:column;gap:6px;margin:12px 0 0;padding:0;list-style:none;display:flex}.uw-Msq_updateListItem{justify-content:space-between;align-items:baseline;gap:12px;font-size:13px;display:flex}.uw-Msq_updateListName{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);overflow:hidden}.uw-Msq_updateListVersions{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none}.uw-Msq_updateActions{justify-content:flex-end;margin-top:16px;display:flex}.uw-Msq_updateRetry{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:10px;align-items:center;gap:6px;padding:8px 14px;font-size:13px;transition:background-color .12s,color .12s;display:inline-flex}.uw-Msq_updateRetry:hover{background:var(--dsw-alias-interactive-bg-active)}@media (prefers-reduced-motion:reduce){.uw-Msq_updateRetry{transition:none}}";
|
|
1347
1347
|
const tagId$1 = "@linxin666/dsh-remote-web-ui/remote.module.css";
|
|
1348
1348
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
1349
1349
|
const tag = document.createElement("style");
|
|
@@ -1373,6 +1373,7 @@ window.__ModuleLoader__.load({
|
|
|
1373
1373
|
"cardHeader": "uw-Msq_cardHeader",
|
|
1374
1374
|
"cardTitle": "uw-Msq_cardTitle",
|
|
1375
1375
|
"close": "uw-Msq_close",
|
|
1376
|
+
"entryRow": "uw-Msq_entryRow",
|
|
1376
1377
|
"expired": "uw-Msq_expired",
|
|
1377
1378
|
"expiry": "uw-Msq_expiry",
|
|
1378
1379
|
"header": "uw-Msq_header",
|
|
@@ -1392,7 +1393,17 @@ window.__ModuleLoader__.load({
|
|
|
1392
1393
|
"title": "uw-Msq_title",
|
|
1393
1394
|
"trigger": "uw-Msq_trigger",
|
|
1394
1395
|
"tunnelFailed": "uw-Msq_tunnelFailed",
|
|
1395
|
-
"tunnelNote": "uw-Msq_tunnelNote"
|
|
1396
|
+
"tunnelNote": "uw-Msq_tunnelNote",
|
|
1397
|
+
"updateActions": "uw-Msq_updateActions",
|
|
1398
|
+
"updateDetail": "uw-Msq_updateDetail",
|
|
1399
|
+
"updateError": "uw-Msq_updateError",
|
|
1400
|
+
"updateList": "uw-Msq_updateList",
|
|
1401
|
+
"updateListItem": "uw-Msq_updateListItem",
|
|
1402
|
+
"updateListName": "uw-Msq_updateListName",
|
|
1403
|
+
"updateListVersions": "uw-Msq_updateListVersions",
|
|
1404
|
+
"updateOutput": "uw-Msq_updateOutput",
|
|
1405
|
+
"updateRetry": "uw-Msq_updateRetry",
|
|
1406
|
+
"updateStatus": "uw-Msq_updateStatus"
|
|
1396
1407
|
};
|
|
1397
1408
|
//#endregion
|
|
1398
1409
|
//#region src/client/RemotePanel.tsx
|
|
@@ -1638,14 +1649,329 @@ window.__ModuleLoader__.load({
|
|
|
1638
1649
|
});
|
|
1639
1650
|
}
|
|
1640
1651
|
//#endregion
|
|
1652
|
+
//#region src/client/update-api.ts
|
|
1653
|
+
/**
|
|
1654
|
+
* Probe the update status: install mode, owning profile, and the
|
|
1655
|
+
* current-vs-latest comparison for every family package.
|
|
1656
|
+
* @returns the status snapshot.
|
|
1657
|
+
*/
|
|
1658
|
+
async function fetchUpdateStatus() {
|
|
1659
|
+
const response = await fetch("/api/update/status");
|
|
1660
|
+
if (!response.ok) throw new Error("update status unavailable");
|
|
1661
|
+
return await response.json();
|
|
1662
|
+
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Run the update (pnpm update in the owning profile). Blocks until pnpm
|
|
1665
|
+
* exits — the panel shows an in-flight state meanwhile.
|
|
1666
|
+
* @returns the run outcome.
|
|
1667
|
+
*/
|
|
1668
|
+
async function runUpdate() {
|
|
1669
|
+
const response = await fetch("/api/update/run", { method: "POST" });
|
|
1670
|
+
if (!response.ok) throw new Error("update run unavailable");
|
|
1671
|
+
return await response.json();
|
|
1672
|
+
}
|
|
1673
|
+
//#endregion
|
|
1674
|
+
//#region src/client/UpdatePanel.tsx
|
|
1675
|
+
/** The anchor package name (aggregate first) for copy purposes. */
|
|
1676
|
+
function anchorName(status) {
|
|
1677
|
+
return status?.anchor ?? status?.packages[0]?.name;
|
|
1678
|
+
}
|
|
1679
|
+
/** The latest npm release of the anchor, for reference copy. */
|
|
1680
|
+
function anchorLatest(status) {
|
|
1681
|
+
return status?.packages[0]?.latest;
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* Render the update panel.
|
|
1685
|
+
* @param props - copy, view state, and actions.
|
|
1686
|
+
* @returns the panel element tree.
|
|
1687
|
+
*/
|
|
1688
|
+
function UpdatePanel({ t, view, onClose, onRecheck }) {
|
|
1689
|
+
const status = view.kind === "result" || view.kind === "updating" ? view.status : void 0;
|
|
1690
|
+
const title = view.kind === "done" && view.result.ok ? t("update.done") : t("update.title");
|
|
1691
|
+
const subtitle = subtitleOf(t, view);
|
|
1692
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1693
|
+
className: remote_module_css_default.panel,
|
|
1694
|
+
role: "dialog",
|
|
1695
|
+
"aria-modal": "true",
|
|
1696
|
+
"aria-label": title,
|
|
1697
|
+
children: [
|
|
1698
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1699
|
+
className: remote_module_css_default.header,
|
|
1700
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1701
|
+
className: remote_module_css_default.heading,
|
|
1702
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
1703
|
+
className: remote_module_css_default.title,
|
|
1704
|
+
children: title
|
|
1705
|
+
}), subtitle !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1706
|
+
className: remote_module_css_default.subtitle,
|
|
1707
|
+
children: subtitle
|
|
1708
|
+
})]
|
|
1709
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1710
|
+
type: "button",
|
|
1711
|
+
className: remote_module_css_default.close,
|
|
1712
|
+
"aria-label": t("update.close"),
|
|
1713
|
+
onClick: onClose,
|
|
1714
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, {})
|
|
1715
|
+
})]
|
|
1716
|
+
}),
|
|
1717
|
+
view.kind === "checking" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1718
|
+
className: remote_module_css_default.updateStatus,
|
|
1719
|
+
children: t("update.checking")
|
|
1720
|
+
}),
|
|
1721
|
+
view.kind === "result" && status !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResultBody, {
|
|
1722
|
+
t,
|
|
1723
|
+
status
|
|
1724
|
+
}),
|
|
1725
|
+
view.kind === "updating" && status !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1726
|
+
className: remote_module_css_default.updateStatus,
|
|
1727
|
+
children: t("update.updating", {
|
|
1728
|
+
name: anchorName(status) ?? "",
|
|
1729
|
+
version: anchorLatest(status) ?? ""
|
|
1730
|
+
})
|
|
1731
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PackageList, { status })] }),
|
|
1732
|
+
view.kind === "done" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DoneBody, {
|
|
1733
|
+
t,
|
|
1734
|
+
result: view.result
|
|
1735
|
+
}),
|
|
1736
|
+
view.kind === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1737
|
+
className: remote_module_css_default.updateError,
|
|
1738
|
+
children: view.message
|
|
1739
|
+
}), view.detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
1740
|
+
className: remote_module_css_default.updateOutput,
|
|
1741
|
+
children: view.detail
|
|
1742
|
+
})] }),
|
|
1743
|
+
(view.kind === "done" || view.kind === "error") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1744
|
+
className: remote_module_css_default.updateActions,
|
|
1745
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1746
|
+
type: "button",
|
|
1747
|
+
className: remote_module_css_default.updateRetry,
|
|
1748
|
+
onClick: onRecheck,
|
|
1749
|
+
children: [
|
|
1750
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, {}),
|
|
1751
|
+
" ",
|
|
1752
|
+
t("update.retry")
|
|
1753
|
+
]
|
|
1754
|
+
})
|
|
1755
|
+
})
|
|
1756
|
+
]
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
/** The subtitle copy per view state (absent on plain results). */
|
|
1760
|
+
function subtitleOf(t, view) {
|
|
1761
|
+
switch (view.kind) {
|
|
1762
|
+
case "checking": return t("update.checking");
|
|
1763
|
+
case "updating": return t("update.updatingTitle");
|
|
1764
|
+
case "result": return;
|
|
1765
|
+
case "done": return view.result.ok ? t("update.doneDetail") : t("update.error");
|
|
1766
|
+
case "error": return;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
/** The checked result body: mode banner + version list. */
|
|
1770
|
+
function ResultBody({ t, status }) {
|
|
1771
|
+
const anchor = anchorName(status);
|
|
1772
|
+
const latest = anchorLatest(status);
|
|
1773
|
+
if (status.mode === "link") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1774
|
+
className: remote_module_css_default.updateStatus,
|
|
1775
|
+
children: t("update.linkMode")
|
|
1776
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1777
|
+
className: remote_module_css_default.updateDetail,
|
|
1778
|
+
children: t("update.linkModeDetail", { version: latest ?? "-" })
|
|
1779
|
+
})] });
|
|
1780
|
+
if (status.mode === "missing") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1781
|
+
className: remote_module_css_default.updateStatus,
|
|
1782
|
+
children: t("update.missing")
|
|
1783
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1784
|
+
className: remote_module_css_default.updateDetail,
|
|
1785
|
+
children: t("update.missingDetail")
|
|
1786
|
+
})] });
|
|
1787
|
+
if (status.error === "registry-unreachable") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1788
|
+
className: remote_module_css_default.updateStatus,
|
|
1789
|
+
children: t("update.offline")
|
|
1790
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1791
|
+
className: remote_module_css_default.updateDetail,
|
|
1792
|
+
children: t("update.offlineDetail")
|
|
1793
|
+
})] });
|
|
1794
|
+
if (status.outdated) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1795
|
+
className: remote_module_css_default.updateStatus,
|
|
1796
|
+
children: t("update.found")
|
|
1797
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1798
|
+
className: remote_module_css_default.updateDetail,
|
|
1799
|
+
children: anchor !== void 0 ? t("update.foundDetail", {
|
|
1800
|
+
name: anchor,
|
|
1801
|
+
version: latest ?? ""
|
|
1802
|
+
}) : ""
|
|
1803
|
+
})] });
|
|
1804
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
1805
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1806
|
+
className: remote_module_css_default.updateStatus,
|
|
1807
|
+
children: t("update.upToDate")
|
|
1808
|
+
}),
|
|
1809
|
+
anchor !== void 0 && latest !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1810
|
+
className: remote_module_css_default.updateDetail,
|
|
1811
|
+
children: t("update.upToDateDetail", {
|
|
1812
|
+
name: anchor,
|
|
1813
|
+
version: latest
|
|
1814
|
+
})
|
|
1815
|
+
}),
|
|
1816
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PackageList, { status })
|
|
1817
|
+
] });
|
|
1818
|
+
}
|
|
1819
|
+
/** The per-package current → latest comparison list. */
|
|
1820
|
+
function PackageList({ status }) {
|
|
1821
|
+
if (status.packages.length === 0) return null;
|
|
1822
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
1823
|
+
className: remote_module_css_default.updateList,
|
|
1824
|
+
children: status.packages.map((packageStatus) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
1825
|
+
className: remote_module_css_default.updateListItem,
|
|
1826
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1827
|
+
className: remote_module_css_default.updateListName,
|
|
1828
|
+
children: packageStatus.name
|
|
1829
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1830
|
+
className: remote_module_css_default.updateListVersions,
|
|
1831
|
+
children: [packageStatus.current, packageStatus.latest !== void 0 && packageStatus.latest !== packageStatus.current && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [" → ", packageStatus.latest] })]
|
|
1832
|
+
})]
|
|
1833
|
+
}, packageStatus.name))
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
/** The outcome body: success + restart hint, or the translated failure. */
|
|
1837
|
+
function DoneBody({ t, result }) {
|
|
1838
|
+
if (result.ok) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1839
|
+
className: remote_module_css_default.updateDetail,
|
|
1840
|
+
children: t("update.doneDetail")
|
|
1841
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1842
|
+
className: remote_module_css_default.updateDetail,
|
|
1843
|
+
children: t("update.restartHint")
|
|
1844
|
+
})] });
|
|
1845
|
+
const message = errorMessageOf(t, result);
|
|
1846
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1847
|
+
className: remote_module_css_default.updateError,
|
|
1848
|
+
children: message
|
|
1849
|
+
}), result.output.trim() !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
1850
|
+
className: remote_module_css_default.updateOutput,
|
|
1851
|
+
children: result.output.trim()
|
|
1852
|
+
})] });
|
|
1853
|
+
}
|
|
1854
|
+
/** Translate a structured failure code; fall back to the raw message. */
|
|
1855
|
+
function errorMessageOf(t, result) {
|
|
1856
|
+
switch (result.errorCode) {
|
|
1857
|
+
case "pnpm-missing": return t("update.error.pnpmMissing");
|
|
1858
|
+
case "timeout": return t("update.error.timeout");
|
|
1859
|
+
case "not-found": return t("update.error.notFound");
|
|
1860
|
+
case "link": return t("update.error.link");
|
|
1861
|
+
case "pnpm-failed": return t("update.error.pnpmFailed", { code: String(result.exitCode ?? "?") });
|
|
1862
|
+
default: return result.error ?? t("update.error.unknown");
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
//#endregion
|
|
1866
|
+
//#region src/client/UpdateEntry.tsx
|
|
1867
|
+
/**
|
|
1868
|
+
* The sidebar update seat: the download trigger beside the remote-control
|
|
1869
|
+
* trigger plus the update panel modal. Owns the flow — probe the registry
|
|
1870
|
+
* on open, auto-run the update when a newer release exists, report the
|
|
1871
|
+
* outcome (restart hint on success, translated failure on error).
|
|
1872
|
+
* Component-local state per the client stack rules.
|
|
1873
|
+
*/
|
|
1874
|
+
/**
|
|
1875
|
+
* Render the update trigger and panel.
|
|
1876
|
+
* @param props - column state and locale seat.
|
|
1877
|
+
* @returns the entry element tree.
|
|
1878
|
+
*/
|
|
1879
|
+
function UpdateEntry({ wide, t }) {
|
|
1880
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
1881
|
+
const [view, setView] = (0, react.useState)({ kind: "checking" });
|
|
1882
|
+
const runToken = (0, react.useRef)(0);
|
|
1883
|
+
const check = (0, react.useCallback)(async () => {
|
|
1884
|
+
setView({ kind: "checking" });
|
|
1885
|
+
let status;
|
|
1886
|
+
try {
|
|
1887
|
+
status = await fetchUpdateStatus();
|
|
1888
|
+
} catch {
|
|
1889
|
+
setView({
|
|
1890
|
+
kind: "error",
|
|
1891
|
+
message: t("update.offline"),
|
|
1892
|
+
detail: t("update.offlineDetail")
|
|
1893
|
+
});
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1896
|
+
if (status.error === "registry-unreachable") {
|
|
1897
|
+
setView({
|
|
1898
|
+
kind: "result",
|
|
1899
|
+
status
|
|
1900
|
+
});
|
|
1901
|
+
return;
|
|
1902
|
+
}
|
|
1903
|
+
setView({
|
|
1904
|
+
kind: "result",
|
|
1905
|
+
status
|
|
1906
|
+
});
|
|
1907
|
+
if (status.mode !== "npm" || !status.outdated) return;
|
|
1908
|
+
setView({
|
|
1909
|
+
kind: "updating",
|
|
1910
|
+
status
|
|
1911
|
+
});
|
|
1912
|
+
const token = ++runToken.current;
|
|
1913
|
+
try {
|
|
1914
|
+
const result = await runUpdate();
|
|
1915
|
+
if (token !== runToken.current) return;
|
|
1916
|
+
setView({
|
|
1917
|
+
kind: "done",
|
|
1918
|
+
result
|
|
1919
|
+
});
|
|
1920
|
+
} catch {
|
|
1921
|
+
if (token !== runToken.current) return;
|
|
1922
|
+
setView({
|
|
1923
|
+
kind: "error",
|
|
1924
|
+
message: t("update.error"),
|
|
1925
|
+
detail: t("update.offlineDetail")
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
}, [t]);
|
|
1929
|
+
const openPanel = (0, react.useCallback)(() => {
|
|
1930
|
+
setOpen(true);
|
|
1931
|
+
check();
|
|
1932
|
+
}, [check]);
|
|
1933
|
+
const closePanel = (0, react.useCallback)(() => {
|
|
1934
|
+
runToken.current++;
|
|
1935
|
+
setOpen(false);
|
|
1936
|
+
}, []);
|
|
1937
|
+
(0, react.useEffect)(() => () => {
|
|
1938
|
+
runToken.current++;
|
|
1939
|
+
}, []);
|
|
1940
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1941
|
+
type: "button",
|
|
1942
|
+
className: remote_module_css_default.trigger,
|
|
1943
|
+
"data-wide": wide ? void 0 : "rail",
|
|
1944
|
+
"aria-label": t("update.label"),
|
|
1945
|
+
title: t("update.label"),
|
|
1946
|
+
onClick: openPanel,
|
|
1947
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, { size: wide ? 16 : 18 })
|
|
1948
|
+
}), open && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1949
|
+
className: remote_module_css_default.overlay,
|
|
1950
|
+
role: "presentation",
|
|
1951
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1952
|
+
className: remote_module_css_default.mask,
|
|
1953
|
+
"aria-hidden": "true",
|
|
1954
|
+
onClick: closePanel
|
|
1955
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UpdatePanel, {
|
|
1956
|
+
t,
|
|
1957
|
+
view,
|
|
1958
|
+
onClose: closePanel,
|
|
1959
|
+
onRecheck: () => {
|
|
1960
|
+
check();
|
|
1961
|
+
}
|
|
1962
|
+
})]
|
|
1963
|
+
}), document.body)] });
|
|
1964
|
+
}
|
|
1965
|
+
//#endregion
|
|
1641
1966
|
//#region src/client/RemoteEntry.tsx
|
|
1642
1967
|
/**
|
|
1643
|
-
* The sidebar remote-control seat: the
|
|
1644
|
-
* settings button
|
|
1645
|
-
* token minting on open, the status SSE subscription,
|
|
1646
|
-
* and renders the pure {@link RemotePanel} body.
|
|
1647
|
-
* the
|
|
1648
|
-
*
|
|
1968
|
+
* The sidebar remote-control seat: the update trigger plus the phone-icon
|
|
1969
|
+
* trigger beside the settings button, and the pairing panel modal. Owns the
|
|
1970
|
+
* panel behavior — token minting on open, the status SSE subscription,
|
|
1971
|
+
* stop/refresh/copy — and renders the pure {@link RemotePanel} body. The
|
|
1972
|
+
* update seat (the dsh-web-ui self-update flow) rides the same footer row,
|
|
1973
|
+
* rendered by {@link UpdateEntry}. Component-local state per the client
|
|
1974
|
+
* stack rules: nothing here survives remounts or crosses entries.
|
|
1649
1975
|
*/
|
|
1650
1976
|
/** Apply one status frame onto the current ready state. */
|
|
1651
1977
|
function mergeFrame(state, frame) {
|
|
@@ -1769,10 +2095,17 @@ window.__ModuleLoader__.load({
|
|
|
1769
2095
|
}, 1500);
|
|
1770
2096
|
});
|
|
1771
2097
|
}, [state]);
|
|
1772
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
2098
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2099
|
+
className: remote_module_css_default.entryRow,
|
|
2100
|
+
"data-rail": wide ? void 0 : "rail",
|
|
2101
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(UpdateEntry, {
|
|
2102
|
+
wide,
|
|
2103
|
+
t
|
|
2104
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipAnchor, {
|
|
2105
|
+
wide,
|
|
2106
|
+
label: t("entry.label"),
|
|
2107
|
+
onClick: openPanel
|
|
2108
|
+
})]
|
|
1776
2109
|
}), open && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1777
2110
|
className: remote_module_css_default.overlay,
|
|
1778
2111
|
role: "presentation",
|
|
@@ -2601,7 +2934,35 @@ window.__ModuleLoader__.load({
|
|
|
2601
2934
|
"settings.discard": "放弃",
|
|
2602
2935
|
"settings.unsaved": "未保存",
|
|
2603
2936
|
"settings.saveFailed": "部署未接受这些值,已保留供你修改。",
|
|
2604
|
-
"settings.invalidNumber": "请输入数字,留空则使用默认值。"
|
|
2937
|
+
"settings.invalidNumber": "请输入数字,留空则使用默认值。",
|
|
2938
|
+
"update.label": "检查更新",
|
|
2939
|
+
"update.title": "检查更新",
|
|
2940
|
+
"update.checking": "正在检查远程仓库中的新版本…",
|
|
2941
|
+
"update.upToDate": "当前已是最新版本",
|
|
2942
|
+
"update.upToDateDetail": "{name} 已是最新版本 v{version}。",
|
|
2943
|
+
"update.found": "发现新版本",
|
|
2944
|
+
"update.foundDetail": "{name} 有新版本 v{version},正在自动更新…",
|
|
2945
|
+
"update.updating": "正在更新 {name} 至 v{version},可能需要 1-2 分钟…",
|
|
2946
|
+
"update.updatingTitle": "正在自动更新…",
|
|
2947
|
+
"update.done": "更新完成",
|
|
2948
|
+
"update.doneDetail": "所有组件已更新到最新版本。",
|
|
2949
|
+
"update.restartHint": "请重启 dsh web 使新版本生效:在终端按 Ctrl+C 停止后重新运行 dsh web。",
|
|
2950
|
+
"update.linkMode": "当前为本地开发模式",
|
|
2951
|
+
"update.linkModeDetail": "dsh-web-ui 通过本地链接安装(开发模式),无法自动更新。npm 上最新版本:{version}。请在仓库中执行 git pull 更新。",
|
|
2952
|
+
"update.missing": "未找到 dsh-web-ui 安装",
|
|
2953
|
+
"update.missingDetail": "无法定位已安装的 dsh-web-ui 聚合包。请先运行 dsh plugin --profile <profile> add @linxin666/dsh-web-ui-all。",
|
|
2954
|
+
"update.offline": "无法连接更新源",
|
|
2955
|
+
"update.offlineDetail": "网络不可用或更新服务异常,请稍后重试。",
|
|
2956
|
+
"update.error": "更新失败",
|
|
2957
|
+
"update.packages": "组件版本",
|
|
2958
|
+
"update.retry": "重新检查",
|
|
2959
|
+
"update.close": "关闭更新面板",
|
|
2960
|
+
"update.error.pnpmMissing": "未找到 pnpm,请先安装 pnpm(brew install pnpm 或 corepack enable)。",
|
|
2961
|
+
"update.error.timeout": "更新超时,已终止安装进程,请重试。",
|
|
2962
|
+
"update.error.notFound": "未找到 dsh-web-ui 聚合包安装,无法更新。",
|
|
2963
|
+
"update.error.link": "当前为本地开发模式(链接安装),无法自动更新。",
|
|
2964
|
+
"update.error.pnpmFailed": "更新执行失败(pnpm 退出码 {code}),详见下方输出。",
|
|
2965
|
+
"update.error.unknown": "更新失败,请重试。"
|
|
2605
2966
|
};
|
|
2606
2967
|
/** English dictionary, checked complete against the zh key set. */
|
|
2607
2968
|
const en = {
|
|
@@ -2671,7 +3032,35 @@ window.__ModuleLoader__.load({
|
|
|
2671
3032
|
"settings.discard": "Discard",
|
|
2672
3033
|
"settings.unsaved": "Unsaved",
|
|
2673
3034
|
"settings.saveFailed": "The deployment did not accept these values; they were left for you to correct.",
|
|
2674
|
-
"settings.invalidNumber": "Enter a number, or leave blank to use the default."
|
|
3035
|
+
"settings.invalidNumber": "Enter a number, or leave blank to use the default.",
|
|
3036
|
+
"update.label": "Check for updates",
|
|
3037
|
+
"update.title": "Check for updates",
|
|
3038
|
+
"update.checking": "Checking the remote repository for newer releases…",
|
|
3039
|
+
"update.upToDate": "Everything is up to date",
|
|
3040
|
+
"update.upToDateDetail": "{name} is at the latest version v{version}.",
|
|
3041
|
+
"update.found": "A new version is available",
|
|
3042
|
+
"update.foundDetail": "{name} has a newer release v{version}; updating automatically…",
|
|
3043
|
+
"update.updating": "Updating {name} to v{version}; this may take 1-2 minutes…",
|
|
3044
|
+
"update.updatingTitle": "Updating automatically…",
|
|
3045
|
+
"update.done": "Update complete",
|
|
3046
|
+
"update.doneDetail": "All components are up to date.",
|
|
3047
|
+
"update.restartHint": "Restart dsh web for the new version to take effect: stop it with Ctrl+C in the terminal, then run dsh web again.",
|
|
3048
|
+
"update.linkMode": "Local development mode",
|
|
3049
|
+
"update.linkModeDetail": "dsh-web-ui is installed via a local link (development mode) and cannot be updated remotely. Latest npm release: {version}. Run git pull in the repository to update.",
|
|
3050
|
+
"update.missing": "dsh-web-ui not found",
|
|
3051
|
+
"update.missingDetail": "Could not locate the installed dsh-web-ui aggregate package. Install it with: dsh plugin --profile <profile> add @linxin666/dsh-web-ui-all",
|
|
3052
|
+
"update.offline": "Cannot reach the update source",
|
|
3053
|
+
"update.offlineDetail": "The network is unavailable or the update service is failing; try again later.",
|
|
3054
|
+
"update.error": "Update failed",
|
|
3055
|
+
"update.packages": "Component versions",
|
|
3056
|
+
"update.retry": "Check again",
|
|
3057
|
+
"update.close": "Close update panel",
|
|
3058
|
+
"update.error.pnpmMissing": "pnpm was not found. Install it first (brew install pnpm or corepack enable).",
|
|
3059
|
+
"update.error.timeout": "The update timed out and the install process was killed; try again.",
|
|
3060
|
+
"update.error.notFound": "The dsh-web-ui aggregate package is not installed; nothing to update.",
|
|
3061
|
+
"update.error.link": "Local development mode (link install) — automatic update is unavailable.",
|
|
3062
|
+
"update.error.pnpmFailed": "The update failed (pnpm exited with code {code}); see the output below.",
|
|
3063
|
+
"update.error.unknown": "Update failed; try again."
|
|
2675
3064
|
};
|
|
2676
3065
|
//#endregion
|
|
2677
3066
|
//#region src/client/deep-link.ts
|