dsh-life-pack 0.3.49 → 0.3.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -159,14 +159,14 @@ window.__ModuleLoader__.load({
159
159
  path: "/api/ilife-manager"
160
160
  };
161
161
  //#endregion
162
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/config.js
162
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/config.js
163
163
  function assertPrefix(value, role) {
164
164
  if (typeof value !== "string" || value.length === 0) throw new Error("[dsh-plugin-update] " + role + " 非法:须为非空字符串(收到 " + JSON.stringify(value) + ")");
165
165
  if (value.includes(".") || value.includes("/") || value.includes("\\") || /\s/.test(value)) throw new Error("[dsh-plugin-update] " + role + " 非法:不得含有点、路径分隔符或空白(收到 " + JSON.stringify(value) + ")");
166
166
  return value;
167
167
  }
168
168
  //#endregion
169
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/redaction.js
169
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/redaction.js
170
170
  const COPY_BUDGET_CHARS = 1500;
171
171
  const REDACTED_PATH = "<路径>";
172
172
  const REDACTED_SECRET = "<脱敏>";
@@ -230,7 +230,7 @@ window.__ModuleLoader__.load({
230
230
  return truncateForCopy(scrubWithoutBudget(flat));
231
231
  }
232
232
  //#endregion
233
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/service.js
233
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/service.js
234
234
  function updateError(code) {
235
235
  return Object.assign(new Error(code), { code });
236
236
  }
@@ -317,7 +317,7 @@ window.__ModuleLoader__.load({
317
317
  return 0;
318
318
  }
319
319
  //#endregion
320
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/lang.js
320
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/lang.js
321
321
  function normalizeLangTag(tag) {
322
322
  if (typeof tag !== "string") return "zh";
323
323
  const s = tag.trim().toLowerCase().replace(/_/g, "-");
@@ -438,7 +438,7 @@ window.__ModuleLoader__.load({
438
438
  };
439
439
  }
440
440
  //#endregion
441
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/bilingual.js
441
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/bilingual.js
442
442
  const BILINGUAL_STRINGS = {
443
443
  "entry.label.idle": {
444
444
  en: "Check for updates",
@@ -2030,7 +2030,7 @@ window.__ModuleLoader__.load({
2030
2030
  }
2031
2031
  const BILINGUAL_CSS = [".dsh-upd-bi{display:inline;overflow-wrap:anywhere}", ".dsh-upd-bi [lang]{overflow-wrap:anywhere}"].join("\n");
2032
2032
  //#endregion
2033
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/changelog.js
2033
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/changelog.js
2034
2034
  const CHANGELOG_MAX_CHARS = 65536;
2035
2035
  const CHANGELOG_ALL_CATEGORIES = [
2036
2036
  "Added",
@@ -2507,12 +2507,12 @@ ${blocks.join("\n")}
2507
2507
  }
2508
2508
  }
2509
2509
  //#endregion
2510
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/log-events.js
2510
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/log-events.js
2511
2511
  const LOG_EVENT_CALL = "host.call";
2512
2512
  const LOG_EVENT_CALL_FAIL = "host.call.fail";
2513
2513
  const LOG_EVENT_INSTALL_EXEC = "update.install.exec";
2514
2514
  //#endregion
2515
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/panel.js
2515
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/panel.js
2516
2516
  function normalizePanelTheme(value) {
2517
2517
  return value === "archive" ? "archive" : "default";
2518
2518
  }
@@ -2539,6 +2539,8 @@ ${blocks.join("\n")}
2539
2539
  busyBg: "--dsh-update-busy-bg",
2540
2540
  busyBorder: "--dsh-update-busy-border",
2541
2541
  busyText: "--dsh-update-busy-text",
2542
+ newText: "--dsh-update-new-text",
2543
+ newOkText: "--dsh-update-new-ok-text",
2542
2544
  fontSans: "--dsh-update-font-sans",
2543
2545
  fontSerif: "--dsh-update-font-serif",
2544
2546
  fontMono: "--dsh-update-font-mono",
@@ -2573,7 +2575,9 @@ ${blocks.join("\n")}
2573
2575
  "badText",
2574
2576
  "busyBg",
2575
2577
  "busyBorder",
2576
- "busyText"
2578
+ "busyText",
2579
+ "newText",
2580
+ "newOkText"
2577
2581
  ]);
2578
2582
  function themeTokensError(raw) {
2579
2583
  return /* @__PURE__ */ new Error(`[dsh-plugin-update] \u4E3B\u9898\u53C2\u6570 themeTokens \u975E\u6CD5\uFF1A\u53EA\u6536\u5DF2\u77E5 token \u952E\uFF08\u989C\u8272\u7528 hex \u6216\u82F1\u6587\u540D\uFF0C\u5B57\u4F53/\u5706\u89D2/\u9634\u5F71/\u5C3A\u5BF8\u4E3A\u5B89\u5168 CSS \u503C\uFF0CentryScale \u4E3A\u5927\u4E8E 0 \u7684\u6709\u9650\u6570\uFF09\uFF08\u6536\u5230 ${JSON.stringify(raw ?? null)})`);
@@ -2751,6 +2755,59 @@ ${blocks.join("\n")}
2751
2755
  if (manual) lines.push(copyText("panel.diag.label.manual", l, { manual }));
2752
2756
  return redactForCopy(lines.join("\n"));
2753
2757
  }
2758
+ const DIAG_KNOWN_TYPES = {
2759
+ v: "number",
2760
+ stage: "string",
2761
+ route: "string",
2762
+ method: "string",
2763
+ httpStatus: "number",
2764
+ exitCode: "number",
2765
+ latencyMs: "number",
2766
+ detail: "string",
2767
+ targetPackageName: "string",
2768
+ runningVersion: "string",
2769
+ latestVersion: "string",
2770
+ environmentKind: "string",
2771
+ requestId: "string",
2772
+ checkId: "string",
2773
+ registryHost: "string",
2774
+ action: "string"
2775
+ };
2776
+ function readDiagTolerant(diag) {
2777
+ const empty = {
2778
+ stage: null,
2779
+ route: null,
2780
+ method: null,
2781
+ httpStatus: null,
2782
+ exitCode: null,
2783
+ latencyMs: null,
2784
+ detail: null,
2785
+ targetPackageName: null,
2786
+ runningVersion: null,
2787
+ latestVersion: null,
2788
+ environmentKind: null,
2789
+ requestId: null,
2790
+ checkId: null,
2791
+ registryHost: null,
2792
+ action: null,
2793
+ unknownKeys: []
2794
+ };
2795
+ if (!diag || typeof diag !== "object" || Array.isArray(diag)) return empty;
2796
+ const raw = diag;
2797
+ const out = {
2798
+ ...empty,
2799
+ unknownKeys: []
2800
+ };
2801
+ for (const key of Object.keys(DIAG_KNOWN_TYPES)) {
2802
+ if (!Object.prototype.hasOwnProperty.call(raw, key)) continue;
2803
+ const v = raw[key];
2804
+ if (v === void 0 || v === null) continue;
2805
+ if (typeof v !== DIAG_KNOWN_TYPES[key]) continue;
2806
+ out[key] = v;
2807
+ }
2808
+ for (const key of Object.keys(raw)) if (!Object.prototype.hasOwnProperty.call(DIAG_KNOWN_TYPES, key)) out.unknownKeys.push(key);
2809
+ return out;
2810
+ }
2754
2811
  function queueTextOf(queuePosition, lang, _diagQueuePos) {
2755
2812
  const l = normalizeLangTag(lang ?? "zh");
2756
2813
  const pos = typeof queuePosition === "number" ? queuePosition : null;
@@ -2978,19 +3035,6 @@ ${blocks.join("\n")}
2978
3035
  showReset: true,
2979
3036
  queueNote
2980
3037
  };
2981
- if (snapshot.blockedReason === "pending-restart") return {
2982
- banner: {
2983
- kind: "restart",
2984
- title: copyText("panel.banner.restart-title", l, { latest: snapshot.latestVersion ?? snapshot.installedVersion ?? "" }),
2985
- action: blockedCopy("pending-restart", l)?.action ?? ""
2986
- },
2987
- installEnabled: false,
2988
- installLabel: copyText("panel.action.install", l),
2989
- skippedLatest: false,
2990
- showManual: manual ? true : false,
2991
- showReset: false,
2992
- queueNote
2993
- };
2994
3038
  if (jobState === "installing" || jobState === "verifying") {
2995
3039
  const ver = typeof job?.targetVersion === "string" && job.targetVersion.trim() ? job.targetVersion.trim() : "";
2996
3040
  let installingTitle = copyText("panel.banner.installing-title", l, { version: ver || " " });
@@ -3031,6 +3075,19 @@ ${blocks.join("\n")}
3031
3075
  queueNote
3032
3076
  };
3033
3077
  }
3078
+ if (snapshot.blockedReason === "pending-restart") return {
3079
+ banner: {
3080
+ kind: "restart",
3081
+ title: copyText("panel.banner.restart-title", l, { latest: snapshot.latestVersion ?? snapshot.installedVersion ?? "" }),
3082
+ action: blockedCopy("pending-restart", l)?.action ?? ""
3083
+ },
3084
+ installEnabled: false,
3085
+ installLabel: copyText("panel.action.install", l),
3086
+ skippedLatest: false,
3087
+ showManual: manual ? true : false,
3088
+ showReset: false,
3089
+ queueNote
3090
+ };
3034
3091
  if (snapshot.blockedReason) {
3035
3092
  const copy = blockedCopy(snapshot.blockedReason, l);
3036
3093
  const stop = l === "en" ? "." : "。";
@@ -3079,13 +3136,13 @@ ${blocks.join("\n")}
3079
3136
  };
3080
3137
  }
3081
3138
  const UPDATE_PANEL_CSS = [
3082
- ".dsh-upd{font:14px/1.6 system-ui,\"Microsoft YaHei\",sans-serif;color:var(--dsh-update-text,#1f2937);",
3139
+ ".dsh-upd{font:14px/1.75 system-ui,\"Microsoft YaHei\",sans-serif;color:var(--dsh-update-text,#1f2937);",
3083
3140
  "background:var(--dsh-update-bg,#ffffff);border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:8px;padding:12px 14px;max-width:560px;",
3084
3141
  "--dsh-update-ok-bg:#ecfdf5;--dsh-update-ok-border:#059669;--dsh-update-warn-bg:#fffbeb;--dsh-update-warn-border:#d97706;",
3085
3142
  "--dsh-update-bad-bg:#fef2f2;--dsh-update-bad-border:#dc2626;--dsh-update-busy-bg:#eff6ff;--dsh-update-busy-border:#2563eb}",
3086
3143
  ".dsh-upd *{box-sizing:border-box}",
3087
3144
  ".dsh-upd button{font:inherit;border:1px solid var(--dsh-update-border-strong,#d1d5db);border-radius:var(--dsh-update-radius-button,6px);background:var(--dsh-update-button-bg,#f9fafb);",
3088
- "color:inherit;padding:4px 12px;cursor:pointer;margin:2px 6px 2px 0}",
3145
+ "color:inherit;padding:7px 14px;cursor:pointer;margin:2px 6px 2px 0}",
3089
3146
  ".dsh-upd button:disabled{opacity:.45;cursor:not-allowed}",
3090
3147
  ".dsh-upd button:focus-visible{outline:2px solid var(--dsh-update-focus,#2563eb);outline-offset:1px}",
3091
3148
  ".dsh-upd button[data-primary=\"1\"]{background:var(--dsh-update-primary,#2563eb);border-color:var(--dsh-update-primary,#2563eb);color:#fff}",
@@ -3114,7 +3171,8 @@ ${blocks.join("\n")}
3114
3171
  ".dsh-upd-overlay{position:fixed;inset:0;background:rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;z-index:9999}",
3115
3172
  ".dsh-upd-overlay .dsh-upd{background:var(--dsh-update-bg,#ffffff);max-height:85vh;display:flex;flex-direction:column;overflow:hidden}",
3116
3173
  ".dsh-upd-body{min-height:0}",
3117
- ".dsh-upd-overlay .dsh-upd-body{flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dsh-update-border,#e5e7eb) transparent}",
3174
+ ".dsh-upd-body *{min-width:0}",
3175
+ ".dsh-upd-overlay .dsh-upd-body{flex:1 1 auto;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dsh-update-border,#e5e7eb) transparent}",
3118
3176
  ".dsh-upd-overlay .dsh-upd-body::-webkit-scrollbar{width:8px}",
3119
3177
  ".dsh-upd-overlay .dsh-upd-body::-webkit-scrollbar-thumb{background:var(--dsh-update-border,#e5e7eb);border-radius:4px}",
3120
3178
  ".dsh-upd-overlay .dsh-upd-body::-webkit-scrollbar-track{background:transparent}",
@@ -3125,11 +3183,11 @@ ${blocks.join("\n")}
3125
3183
  ".dsh-upd-meta{font-size:12.5px;opacity:.75}",
3126
3184
  ".dsh-upd-proftag{font-family:Consolas,Menlo,monospace;font-size:11px;border:1px solid var(--dsh-update-border,#d1d5db);border-radius:3px;padding:0 5px;margin-left:6px;letter-spacing:.06em}",
3127
3185
  ".dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:4px;overflow:hidden;font-size:12.5px}",
3128
- ".dsh-upd-strip>div{flex:1 1 110px;padding:6px 10px;border-left:1px solid var(--dsh-update-border,#e5e7eb)}",
3186
+ ".dsh-upd-strip>div{flex:1 1 110px;min-width:0;padding:6px 10px;border-left:1px solid var(--dsh-update-border,#e5e7eb)}",
3129
3187
  ".dsh-upd-strip>div:first-child{border-left:0}",
3130
3188
  ".dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.14em;opacity:.7}",
3131
- ".dsh-upd-strip-v{font-family:Consolas,Menlo,monospace;font-size:12.5px}",
3132
- ".dsh-upd-chapter{margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3189
+ ".dsh-upd-strip-v{font-family:Consolas,Menlo,monospace;font-size:12.5px;word-break:break-all}",
3190
+ ".dsh-upd-chapter{margin-top:18px;padding-top:14px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3133
3191
  ".dsh-upd-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3134
3192
  ".dsh-upd-foot-note{margin-right:auto;font-size:12px;opacity:.7}",
3135
3193
  ".dsh-upd-footer button{margin:0}",
@@ -3139,7 +3197,7 @@ ${blocks.join("\n")}
3139
3197
  ".dsh-upd-chap-rule{flex:1;border-top:1px solid var(--dsh-update-border,#e5e7eb);transform:translateY(-3px)}",
3140
3198
  ".dsh-upd-chap-note{flex:none;font-size:12px;opacity:.75}",
3141
3199
  ".dsh-upd-chap-note button{margin:0}",
3142
- ".dsh-upd-qrow{display:flex;align-items:baseline;gap:10px;padding:6px 0}",
3200
+ ".dsh-upd-qrow{display:flex;align-items:baseline;flex-wrap:wrap;gap:10px;padding:6px 0;min-width:0}",
3143
3201
  ".dsh-upd-qrow+.dsh-upd-qrow{border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
3144
3202
  ".dsh-upd-qdot{width:8px;height:8px;border-radius:50%;flex:none;align-self:center;background:currentColor;opacity:.5}",
3145
3203
  ".dsh-upd-qdot[data-tone=\"busy\"]{background:var(--dsh-update-warn-border,#d97706);opacity:1}",
@@ -3182,6 +3240,14 @@ ${blocks.join("\n")}
3182
3240
  ".dsh-upd-actions button:first-child:not([aria-busy=\"true\"])::after{content:\"\";display:inline-block;width:11px;height:11px;margin-left:8px;visibility:hidden}",
3183
3241
  ".dsh-upd-banner{min-height:1.2em}",
3184
3242
  ".dsh-upd-strip{min-height:48px}",
3243
+ ".dsh-upd-actions{align-content:flex-start}",
3244
+ ".dsh-upd-actions button{white-space:nowrap}",
3245
+ ".dsh-upd-actions button:first-child{min-width:10em}",
3246
+ ".dsh-upd-actions button[data-primary=\"1\"]{min-width:9em}",
3247
+ ".dsh-upd-banner{min-height:3.4em;display:flex;flex-direction:column;justify-content:center}",
3248
+ ".dsh-upd-banner{animation:none}",
3249
+ ".dsh-upd-copy{min-height:1.75em}",
3250
+ ".dsh-upd-copy--empty{visibility:hidden}",
3185
3251
  "@media (prefers-color-scheme: dark){.dsh-upd{--dsh-update-text:#e5e7eb;--dsh-update-bg:#111827;--dsh-update-border:#374151;",
3186
3252
  "--dsh-update-button-bg:#1f2937;--dsh-update-bg-soft:#1f2937;--dsh-update-primary:#3b82f6;--dsh-update-focus:#93c5fd;",
3187
3253
  "--dsh-update-ok-bg:rgba(16,185,129,.14);--dsh-update-ok-border:#34d399;",
@@ -3368,8 +3434,10 @@ ${blocks.join("\n")}
3368
3434
  const busyAct = input.busyAct;
3369
3435
  const checkBusy = busyAct === "check";
3370
3436
  const installBusy = busyAct === "install";
3437
+ const jobState = snapshot?.job?.state;
3438
+ const macroBusy = busyAct === "check" || busyAct === "install" || jobState === "installing" || jobState === "verifying";
3371
3439
  actions.push("<div class=\"dsh-upd-actions\">");
3372
- actions.push((checkBusy ? `<button type="button" data-action="check" disabled aria-busy="true" title="${escapeHtml$2(copyText("panel.action.checking-busy-title", l))}">${escapeHtml$2(copyText("panel.action.checking-busy", l))}</button>` : `<button type="button" data-action="check" title="${escapeHtml$2(copyText("panel.action.check-title", l))}">${escapeHtml$2(copyText("panel.action.check", l))}</button>`) + (installBusy ? `<button type="button" data-action="install" data-primary="1" disabled aria-busy="true" title="${escapeHtml$2(copyText("panel.action.installing-busy-title", l))}">${escapeHtml$2(copyText("panel.action.installing-busy", l))}</button>` : `<button type="button" data-action="install" data-primary="1" title="${escapeHtml$2(copyText("panel.action.install-title", l))}"${view.installEnabled ? "" : " disabled"}>${escapeHtml$2(view.installLabel)}</button>`));
3440
+ actions.push((checkBusy ? `<button type="button" data-action="check" disabled aria-busy="true" title="${escapeHtml$2(copyText("panel.action.checking-busy-title", l))}">${escapeHtml$2(copyText("panel.action.checking-busy", l))}</button>` : `<button type="button" data-action="check" title="${escapeHtml$2(copyText("panel.action.check-title", l))}"${macroBusy ? " disabled" : ""}>${escapeHtml$2(copyText("panel.action.check", l))}</button>`) + (installBusy ? `<button type="button" data-action="install" data-primary="1" disabled aria-busy="true" title="${escapeHtml$2(copyText("panel.action.installing-busy-title", l))}">${escapeHtml$2(copyText("panel.action.installing-busy", l))}</button>` : `<button type="button" data-action="install" data-primary="1" title="${escapeHtml$2(copyText("panel.action.install-title", l))}"${macroBusy || !view.installEnabled ? " disabled" : ""}>${escapeHtml$2(view.installLabel)}</button>`));
3373
3441
  if (snapshot?.latestVersion && !view.skippedLatest && view.banner.kind === "update") actions.push(`<button type="button" data-action="skip" title="${escapeHtml$2(copyText("panel.action.skip-title", l))}">${escapeHtml$2(copyText("panel.action.skip", l))}</button>`);
3374
3442
  if (view.showReset && snapshot?.latestVersion) actions.push(`<button type="button" data-action="reset-skip" title="${escapeHtml$2(copyText("panel.action.unskip-title", l))}">${escapeHtml$2(copyText("panel.action.unskip", l, { version: snapshot.latestVersion }))}</button>`);
3375
3443
  if (view.showManual && manual) actions.push(`<button type="button" data-action="copy-manual" title="${escapeHtml$2(copyText("panel.action.copy-manual-title", l))}">${escapeHtml$2(copyText("panel.action.copy-manual", l))}</button>`);
@@ -3472,6 +3540,7 @@ ${changelogHTML}
3472
3540
  })}</div>`);
3473
3541
  }
3474
3542
  if (copyNotice) errLines.push(`<div class="dsh-upd-copy" role="status">${escapeHtml$2(copyNotice)}</div>`);
3543
+ else errLines.push("<div class=\"dsh-upd-copy dsh-upd-copy--empty\" aria-hidden=\"true\"></div>");
3475
3544
  chapters.push(chapterOf(4, errLines.join(""), "", l));
3476
3545
  }
3477
3546
  chapters.push(chapterOf(5, view.showManual && manual ? `<div class="dsh-upd-manual"><div>${escapeHtml$2(copyText("panel.manual.heading", l))}</div><code>${escapeHtml$2(manual)}</code></div>` : `<div class="dsh-upd-manual"><div class="dsh-upd-changelog-neutral">${escapeHtml$2(copyText("panel.manual.absent", l))}</div></div>`, "", l));
@@ -3498,7 +3567,7 @@ ${UPDATE_PANEL_ARCHIVE_CSS}` : UPDATE_PANEL_CSS}</style>
3498
3567
  ${body}`;
3499
3568
  }
3500
3569
  //#endregion
3501
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/entry.js
3570
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/entry.js
3502
3571
  const UPDATE_ENTRY_CSS = [
3503
3572
  ".dsh-upd-entry{display:inline-flex;align-items:center;gap:8px;font:13px/1.6 var(--dsh-update-font-sans,system-ui,\"Microsoft YaHei\",sans-serif);font-size:var(--dsh-update-entry-font-size,13px);color:var(--dsh-update-text,#1f2937)}",
3504
3573
  ".dsh-upd-entry-btn{font:inherit;border:1px solid var(--dsh-update-border,#d1d5db);border-radius:var(--dsh-update-entry-border-radius,6px);",
@@ -3519,6 +3588,8 @@ ${body}`;
3519
3588
  ".dsh-upd-entry[data-state=\"update\"] .dsh-upd-entry-dot{background:var(--dsh-update-ok-border,#059669)}",
3520
3589
  ".dsh-upd-entry[data-state=\"busy\"] .dsh-upd-entry-dot,.dsh-upd-entry[data-state=\"restart\"] .dsh-upd-entry-dot{background:var(--dsh-update-warn-border,#d97706)}",
3521
3590
  ".dsh-upd-entry[data-state=\"failed\"] .dsh-upd-entry-dot{background:var(--dsh-update-bad-border,#dc2626)}",
3591
+ ".dsh-upd-entry[data-known=\"uptodate\"] .dsh-upd-entry-btn{border-color:var(--dsh-update-border,#d1d5db);color:var(--dsh-update-text-muted,#6b7280)}",
3592
+ ".dsh-upd-entry[data-known=\"uptodate\"] .dsh-upd-entry-btn:hover{border-color:var(--dsh-update-primary,#2563eb);color:var(--dsh-update-primary,#2563eb)}",
3522
3593
  ".dsh-upd-entry-note{font-size:12.5px;opacity:.9;background:var(--dsh-update-bg,#ffffff);border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:var(--dsh-update-radius-badge,4px);padding:1px 8px}",
3523
3594
  ".dsh-upd-entry[data-theme=\"archive\"] .dsh-upd-entry-note{background:var(--dsh-update-bg);border-color:var(--dsh-update-border-strong);color:var(--dsh-update-text)}",
3524
3595
  ".dsh-upd-entry[data-theme=\"archive\"]{--dsh-update-text:#1a1a1a;--dsh-update-text-muted:#6f675a;--dsh-update-border-strong:#c4b896;--dsh-update-primary:#c8402a;--dsh-update-bg:#fffdf6;",
@@ -3527,7 +3598,7 @@ ${body}`;
3527
3598
  ".dsh-upd-entry[data-theme=\"archive\"] .dsh-upd-entry-btn{border-color:var(--dsh-update-border-strong);background:var(--dsh-update-bg);color:var(--dsh-update-text);border-radius:var(--dsh-update-entry-border-radius,3px)}",
3528
3599
  ".dsh-upd-entry[data-theme=\"archive\"] .dsh-upd-entry-btn:hover{border-color:var(--dsh-update-primary);color:var(--dsh-update-primary)}",
3529
3600
  "@media (prefers-color-scheme: dark){.dsh-upd-entry[data-theme=\"archive\"]{--dsh-update-text:#ece5d3;--dsh-update-text-muted:#a89c83;--dsh-update-border-strong:#5c4e3b;--dsh-update-primary:#e0684e;--dsh-update-bg:#1e1a15}}",
3530
- "@media (prefers-color-scheme: dark){.dsh-upd-entry{color:#e5e7eb}",
3601
+ "@media (prefers-color-scheme: dark){.dsh-upd-entry{color:#e5e7eb;--dsh-update-text-muted:#9ca3af}",
3531
3602
  ".dsh-upd-entry-btn{--dsh-update-button-bg:#1f2937;--dsh-update-border:#374151}}"
3532
3603
  ].join("\n");
3533
3604
  function isTerminalPhase(phase) {
@@ -3610,7 +3681,7 @@ ${body}`;
3610
3681
  }
3611
3682
  }
3612
3683
  //#endregion
3613
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/panel-batch.js
3684
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/panel-batch.js
3614
3685
  const BATCH_PANEL_POLL = {
3615
3686
  defaultMs: 1500,
3616
3687
  minMs: 250
@@ -3627,7 +3698,7 @@ ${body}`;
3627
3698
  prefsSave: p + ".batchPrefsSave"
3628
3699
  };
3629
3700
  }
3630
- function batchLedgerCounts(rows) {
3701
+ function batchLedgerCounts(rows, inventory, session) {
3631
3702
  const counts = {
3632
3703
  updatable: 0,
3633
3704
  installing: 0,
@@ -3643,13 +3714,20 @@ ${body}`;
3643
3714
  else if (phase === "failed") counts.failed += 1;
3644
3715
  else if (phase === "installing") counts.installing += 1;
3645
3716
  else if (phase === "ready") counts.updatable += 1;
3646
- else if (phase === "pending" || phase === "checking") counts.pending += 1;
3717
+ else if (phase === "pending") counts[isInUnfinishedRound(session, row.key) ? "pending" : ledgerKnowledgeBucket(knowledgeEntryOf(inventory, row.key))] += 1;
3718
+ else if (phase === "checking") counts.pending += 1;
3647
3719
  else if (phase === "skipped") counts.skipped += 1;
3648
3720
  else if (row.restartRequired === true) counts.restart += 1;
3649
- else counts.settled += 1;
3721
+ else counts[worldUpdateVersion(row, knowledgeEntryOf(inventory, row.key), sessionUpdatedAtOf(session, row.key)) ? "updatable" : "settled"] += 1;
3650
3722
  }
3651
3723
  return counts;
3652
3724
  }
3725
+ function ledgerKnowledgeBucket(entry) {
3726
+ const verdict = knowledgeVerdictOf(entry);
3727
+ if (verdict === "update") return "updatable";
3728
+ if (verdict === "current") return "settled";
3729
+ return "pending";
3730
+ }
3653
3731
  function batchLedgerText(counts, lang) {
3654
3732
  const l = langOf(lang);
3655
3733
  const parts = [];
@@ -3683,6 +3761,13 @@ ${body}`;
3683
3761
  error: typeof e["error"] === "string" ? e["error"] : null
3684
3762
  };
3685
3763
  }
3764
+ function knowledgeVerdictOf(entry) {
3765
+ if (!entry) return "never";
3766
+ if (entry.error) return "failed";
3767
+ if (entry.latestVersion && entry.installedVersion) return entry.latestVersion !== entry.installedVersion ? "update" : "current";
3768
+ if (entry.latestVersion && !entry.installedVersion) return "update";
3769
+ return "never";
3770
+ }
3686
3771
  function langOf(lang) {
3687
3772
  try {
3688
3773
  return normalizeLangTag(typeof lang === "string" ? lang : resolveLang(lang));
@@ -3697,34 +3782,52 @@ ${body}`;
3697
3782
  return "";
3698
3783
  }
3699
3784
  }
3700
- function hasUnfinishedRows(rows, session) {
3701
- if (isObject$1(session)) {
3702
- const entries = session["entries"];
3703
- if (Array.isArray(entries)) {
3704
- for (const item of entries) {
3705
- if (!isObject$1(item)) continue;
3706
- const phase = item["phase"];
3707
- if (typeof phase === "string" && !isTerminalPhase(asBatchPhase(phase))) return true;
3708
- }
3709
- return false;
3710
- }
3785
+ function sessionEntriesOf(session) {
3786
+ if (!isObject$1(session)) return null;
3787
+ const entries = session["entries"];
3788
+ if (!Array.isArray(entries)) return null;
3789
+ return entries.filter((item) => isObject$1(item));
3790
+ }
3791
+ function entryPhaseOf(entry) {
3792
+ const phase = entry["phase"];
3793
+ return typeof phase === "string" ? asBatchPhase(phase) : null;
3794
+ }
3795
+ function isUnfinishedEntry(entry) {
3796
+ const phase = entryPhaseOf(entry);
3797
+ return phase !== null && !isTerminalPhase(phase);
3798
+ }
3799
+ function isInUnfinishedRound(session, key) {
3800
+ const entries = sessionEntriesOf(session);
3801
+ if (entries === null) return false;
3802
+ return entries.some((entry) => entry["key"] === key && isUnfinishedEntry(entry));
3803
+ }
3804
+ function sessionUpdatedAtOf(session, key) {
3805
+ const entries = sessionEntriesOf(session);
3806
+ if (entries === null) return null;
3807
+ for (const entry of entries) {
3808
+ if (entry["key"] !== key) continue;
3809
+ const at = entry["updatedAt"];
3810
+ if (typeof at === "number" && Number.isFinite(at)) return at;
3711
3811
  }
3812
+ return null;
3813
+ }
3814
+ function worldUpdateVersion(row, knowledge, sessionUpdatedAt) {
3815
+ const phase = asBatchPhase(row.phase);
3816
+ if (phase !== "current" && !(phase === "done" && row.restartRequired !== true)) return null;
3817
+ if (!knowledge || knowledge.error) return null;
3818
+ if (sessionUpdatedAt !== null && !(knowledge.lastCheckedAt > sessionUpdatedAt)) return null;
3819
+ const parts = batchRowVersionParts(row, knowledge);
3820
+ return parts.hasUpdate && parts.latest ? parts.latest : null;
3821
+ }
3822
+ function hasUnfinishedRows(rows, session) {
3823
+ const entries = sessionEntriesOf(session);
3824
+ if (entries !== null) return entries.some(isUnfinishedEntry);
3712
3825
  if (rows.length === 0) return false;
3713
3826
  return !rows.every((row) => isTerminalPhase(asBatchPhase(row.phase)));
3714
3827
  }
3715
3828
  function unfinishedCount(rows, session) {
3716
- if (isObject$1(session)) {
3717
- const entries = session["entries"];
3718
- if (Array.isArray(entries)) {
3719
- let n = 0;
3720
- for (const item of entries) {
3721
- if (!isObject$1(item)) continue;
3722
- const phase = item["phase"];
3723
- if (typeof phase === "string" && !isTerminalPhase(asBatchPhase(phase))) n += 1;
3724
- }
3725
- return n;
3726
- }
3727
- }
3829
+ const entries = sessionEntriesOf(session);
3830
+ if (entries !== null) return entries.filter(isUnfinishedEntry).length;
3728
3831
  return rows.filter((row) => !isTerminalPhase(asBatchPhase(row.phase))).length;
3729
3832
  }
3730
3833
  function batchRowStatus(row, skippedVersion, lang) {
@@ -3745,13 +3848,72 @@ ${body}`;
3745
3848
  }
3746
3849
  function batchRowKnowledgeText(row, entry, lang) {
3747
3850
  if (asBatchPhase(row.phase) !== "pending" || !entry) return null;
3748
- if (entry.error) return batchText("batch.row.failed", lang);
3749
- if (entry.latestVersion && entry.installedVersion && entry.latestVersion !== entry.installedVersion) return batchText("batch.row.update", lang, { version: entry.latestVersion });
3750
- if (entry.latestVersion && entry.installedVersion && entry.latestVersion === entry.installedVersion) return batchText("batch.row.current", lang);
3751
- if (entry.latestVersion && !entry.installedVersion) return batchText("batch.row.update", lang, { version: entry.latestVersion });
3752
- if (entry.lastCheckedAt > 0) return batchText("batch.row.current", lang);
3851
+ const verdict = knowledgeVerdictOf(entry);
3852
+ if (verdict === "update" && entry.latestVersion) return batchText("batch.row.update", lang, { version: entry.latestVersion });
3853
+ if (verdict === "current") return batchText("batch.row.current", lang);
3854
+ if (verdict === "failed") return batchText("batch.row.failed", lang);
3753
3855
  return batchText("batch.row.never", lang);
3754
3856
  }
3857
+ function batchRowVersionParts(row, knowledge) {
3858
+ const sessionTarget = typeof row.targetVersion === "string" && row.targetVersion ? row.targetVersion : null;
3859
+ if (sessionTarget) {
3860
+ const current2 = currentVersionOf(row);
3861
+ if (current2 === null) return {
3862
+ current: null,
3863
+ latest: sessionTarget,
3864
+ hasUpdate: true
3865
+ };
3866
+ if (current2 === sessionTarget) return {
3867
+ current: current2,
3868
+ latest: null,
3869
+ hasUpdate: false
3870
+ };
3871
+ return {
3872
+ current: current2,
3873
+ latest: sessionTarget,
3874
+ hasUpdate: true
3875
+ };
3876
+ }
3877
+ const current = currentVersionOf(row) ?? (knowledge && typeof knowledge.installedVersion === "string" && knowledge.installedVersion ? knowledge.installedVersion : null);
3878
+ const latest = knowledge && typeof knowledge.latestVersion === "string" && knowledge.latestVersion ? knowledge.latestVersion : null;
3879
+ if (current && latest && latest !== current) return {
3880
+ current,
3881
+ latest,
3882
+ hasUpdate: true
3883
+ };
3884
+ if (current) return {
3885
+ current,
3886
+ latest: null,
3887
+ hasUpdate: false
3888
+ };
3889
+ if (latest) return {
3890
+ current: null,
3891
+ latest,
3892
+ hasUpdate: true
3893
+ };
3894
+ return {
3895
+ current: null,
3896
+ latest: null,
3897
+ hasUpdate: false
3898
+ };
3899
+ }
3900
+ function batchRowVersionHTML(row, knowledge) {
3901
+ const parts = batchRowVersionParts(row, knowledge);
3902
+ if (parts.hasUpdate && parts.latest) {
3903
+ const cur = parts.current ?? "?";
3904
+ const newCls = asBatchPhase(row.phase) === "done" ? "dsh-upd-bver-new-ok" : "dsh-upd-bver-new";
3905
+ return "<span class=\"dsh-upd-bver\"><span class=\"dsh-upd-bver-cur\">" + escapeHtml$1(cur) + "</span><span class=\"dsh-upd-bver-arrow\" aria-hidden=\"true\"> → </span><span class=\"" + newCls + "\">" + escapeHtml$1(parts.latest) + "</span></span>";
3906
+ }
3907
+ if (parts.current) return "<span class=\"dsh-upd-bver\">" + escapeHtml$1(parts.current) + "</span>";
3908
+ return "";
3909
+ }
3910
+ function batchRowPendingStatus(row, knowledge, lang) {
3911
+ if (asBatchPhase(row.phase) !== "pending") return null;
3912
+ const known = batchRowKnowledgeText(row, knowledge, lang);
3913
+ if (known !== null) return known;
3914
+ if (!knowledge) return batchText("batch.row.never", lang);
3915
+ return null;
3916
+ }
3755
3917
  function renderBatchPanelHTML(input) {
3756
3918
  const rows = Array.isArray(input.rows) ? input.rows : [];
3757
3919
  const theme = normalizePanelTheme(input.theme);
@@ -3761,7 +3923,7 @@ ${body}`;
3761
3923
  const expandedKey = typeof input.expandedKey === "string" && input.expandedKey ? input.expandedKey : null;
3762
3924
  const lastError = typeof input.lastError === "string" && input.lastError ? input.lastError : null;
3763
3925
  const loaded = input.loaded === void 0 ? rows.length > 0 : input.loaded === true;
3764
- const counts = batchLedgerCounts(rows);
3926
+ const counts = batchLedgerCounts(rows, input.inventory, input.session);
3765
3927
  const installing = counts.installing > 0;
3766
3928
  const macroBusy = input.inFlight === true || installing;
3767
3929
  const total = rows.length;
@@ -3783,7 +3945,8 @@ ${body}`;
3783
3945
  changelogMarkdown: null,
3784
3946
  lang,
3785
3947
  knowledge: null,
3786
- inRound: false
3948
+ inRound: false,
3949
+ worldLatest: null
3787
3950
  };
3788
3951
  const parts = [];
3789
3952
  parts.push("<div class=\"dsh-upd-batch-head\">");
@@ -3802,24 +3965,13 @@ ${body}`;
3802
3965
  const showControls = total > 0 && hasUnfinishedRows(rows, session ?? void 0);
3803
3966
  const prefs = isObject$1(input.prefs) ? input.prefs : null;
3804
3967
  const checkOnOpen = prefs === null ? null : prefs["checkOnOpen"] === false ? false : true;
3805
- function roundEntryPhase(key) {
3806
- if (!session) return null;
3807
- const entries = session["entries"];
3808
- if (!Array.isArray(entries)) return null;
3809
- for (const item of entries) {
3810
- if (!isObject$1(item)) continue;
3811
- const e = item;
3812
- if (e["key"] === key && typeof e["phase"] === "string") return e["phase"];
3813
- }
3814
- return null;
3815
- }
3816
3968
  parts.push("<div class=\"dsh-upd-btable\">");
3817
3969
  for (const row of rows) {
3818
3970
  const raw = skippedVersions[row.key];
3819
3971
  const skipped = typeof raw === "string" && raw ? raw : null;
3820
3972
  const expanded = row.key === expandedKey;
3821
- const entryPhase = roundEntryPhase(row.key);
3822
- const inRound = entryPhase !== null && !isTerminalPhase(asBatchPhase(entryPhase));
3973
+ const inRound = isInUnfinishedRound(input.session, row.key);
3974
+ const knowledge = !inRound ? knowledgeEntryOf(input.inventory, row.key) : null;
3823
3975
  parts.push(rowSetHTML(row, {
3824
3976
  ...ctx,
3825
3977
  expanded,
@@ -3827,8 +3979,9 @@ ${body}`;
3827
3979
  notice: expanded && row.key === detailNoticeKey ? notice : null,
3828
3980
  changelogMarkdown: expanded && typeof changelogs[row.key] === "string" ? changelogs[row.key] : null,
3829
3981
  lang,
3830
- knowledge: asBatchPhase(row.phase) === "pending" && !inRound ? knowledgeEntryOf(input.inventory, row.key) : null,
3831
- inRound
3982
+ knowledge,
3983
+ inRound,
3984
+ worldLatest: worldUpdateVersion(row, knowledge, sessionUpdatedAtOf(input.session, row.key))
3832
3985
  }));
3833
3986
  }
3834
3987
  parts.push("</div>");
@@ -3927,8 +4080,8 @@ ${body}`;
3927
4080
  const skipped = ctx.skipped;
3928
4081
  const queued = isQueuedRow(row);
3929
4082
  const position = queued ? queuePositionOf(row) : null;
3930
- const current = currentVersionOf(row);
3931
- const version = row.targetVersion ? (current === null ? "?" : current) + " → " + row.targetVersion : current === null ? "" : current;
4083
+ const versionHTML = batchRowVersionHTML(row, ctx.knowledge);
4084
+ const rowStatusText = queued ? batchQueuedStatus(position, ctx.lang) : ctx.worldLatest !== null ? batchText("batch.row.update", ctx.lang, { version: ctx.worldLatest }) : ctx.inRound ? batchRowKnowledgeText(row, ctx.knowledge, ctx.lang) ?? batchRowStatus(row, skipped, ctx.lang) : batchRowPendingStatus(row, ctx.knowledge, ctx.lang) ?? batchRowStatus(row, skipped, ctx.lang);
3932
4085
  const actions = [];
3933
4086
  const off = ctx.inFlight ? " disabled" : "";
3934
4087
  if (phase === "installing") actions.push("<button type=\"button\" data-act=\"row-install\" data-key=\"" + keyAttr + "\" disabled>" + escapeHtml$1(batchText("batch.row-action.installing", ctx.lang)) + "</button>");
@@ -3949,7 +4102,7 @@ ${body}`;
3949
4102
  const codeEsc = escapeHtml$1(failCode);
3950
4103
  return "<span class=\"dsh-upd-bfail\">" + (escaped.includes(codeEsc) ? escaped.replace(codeEsc, "<code>" + codeEsc + "</code>") : escaped) + "</span>";
3951
4104
  })() : "";
3952
- const main = "<button type=\"button\" class=\"dsh-upd-brow-main\" data-act=\"toggle-details\" data-key=\"" + keyAttr + "\" aria-expanded=\"" + (ctx.expanded ? "true" : "false") + "\"><span class=\"dsh-upd-updot\" data-tone=\"" + dotToneOf(row, phase, skipped, queued) + "\"></span><span class=\"dsh-upd-bname\">" + escapeHtml$1(titleOf(row, ctx.titles)) + "</span>" + (version ? "<span class=\"dsh-upd-bver\">" + escapeHtml$1(version) + "</span>" : "") + "<span class=\"dsh-upd-bstat\">" + escapeHtml$1(queued ? batchQueuedStatus(position, ctx.lang) : batchRowKnowledgeText(row, ctx.knowledge, ctx.lang) ?? batchRowStatus(row, skipped, ctx.lang)) + (ctx.inRound && !queued ? "(" + escapeHtml$1(batchText("batch.row.unfinished-tag", ctx.lang)) + ")" : "") + "</span>" + failLine + "</button>";
4105
+ const main = "<button type=\"button\" class=\"dsh-upd-brow-main\" data-act=\"toggle-details\" data-key=\"" + keyAttr + "\" aria-expanded=\"" + (ctx.expanded ? "true" : "false") + "\"><span class=\"dsh-upd-updot\" data-tone=\"" + dotToneOf(row, phase, skipped, queued, ctx.worldLatest) + "\"></span><span class=\"dsh-upd-bname\">" + escapeHtml$1(titleOf(row, ctx.titles)) + "</span>" + versionHTML + "<span class=\"dsh-upd-bstat\">" + escapeHtml$1(rowStatusText) + (ctx.inRound && !queued ? "(" + escapeHtml$1(batchText("batch.row.unfinished-tag", ctx.lang)) + ")" : "") + "</span>" + failLine + "</button>";
3953
4106
  const detail = ctx.expanded ? "<div class=\"dsh-upd-bdetail\" data-key=\"" + keyAttr + "\">" + detailActionsHTML(row, ctx) + (ctx.notice !== null ? "<div class=\"dsh-upd-bdetail-notice\" role=\"status\">" + escapeHtml$1(ctx.notice) + "</div>" : "") + detailHTML(row, ctx) + "</div>" : "";
3954
4107
  return "<div class=\"dsh-upd-brow-set\" data-key=\"" + keyAttr + "\"><div class=\"dsh-upd-brow\" data-phase=\"" + escapeHtml$1(phase) + "\" data-key=\"" + keyAttr + "\"" + (queued ? " data-queued=\"1\"" : "") + ">" + main + "<span class=\"dsh-upd-brow-actions\">" + actions.join("") + "</span></div>" + detail + "</div>";
3955
4108
  }
@@ -3969,6 +4122,7 @@ ${body}`;
3969
4122
  theme: ctx.theme,
3970
4123
  themeTokens: ctx.themeTokens,
3971
4124
  profileName: typeof row.profileName === "string" && row.profileName ? row.profileName : null,
4125
+ hostKind: typeof row.hostKind === "string" && row.hostKind ? row.hostKind : null,
3972
4126
  actions: "none"
3973
4127
  }, ctx.lang));
3974
4128
  }
@@ -3984,6 +4138,7 @@ ${body}`;
3984
4138
  if (cancelQueuePhoneOf(row) !== null && queuedRequestIdOf(row) !== null) buttons.push("<button type=\"button\" data-act=\"row-cancel-queue\" data-key=\"" + keyAttr + "\"" + off + ">" + escapeHtml$1(batchText("batch.row-action.cancel-queue", ctx.lang)) + "</button>");
3985
4139
  } else if (phase === "failed") buttons.push("<button type=\"button\" data-act=\"row-install\" data-key=\"" + keyAttr + "\"" + off + ">" + escapeHtml$1(ctx.busy ? batchText("batch.row-action.queue", ctx.lang) : batchText("batch.row-action.retry", ctx.lang)) + "</button>");
3986
4140
  else if (phase === "ready" && ctx.skipped === null) buttons.push("<button type=\"button\" data-act=\"row-install\" data-key=\"" + keyAttr + "\" data-primary=\"1\"" + off + ">" + escapeHtml$1(ctx.busy ? batchText("batch.row-action.queue", ctx.lang) : version !== null ? batchText("batch.row-action.install-version", ctx.lang, { version }) : batchText("batch.row-action.install-generic", ctx.lang)) + "</button>");
4141
+ if (phase !== "installing" && singleCheckPhoneOf(row) !== null) buttons.push("<button type=\"button\" data-act=\"row-check\" data-key=\"" + keyAttr + "\"" + off + ">" + escapeHtml$1(batchText("batch.action.check", ctx.lang)) + "</button>");
3987
4142
  if (!queued && phase === "ready" && ctx.skipped === null && version !== null) buttons.push("<button type=\"button\" data-act=\"row-skip\" data-key=\"" + keyAttr + "\"" + off + ">" + escapeHtml$1(batchText("batch.row-action.skip", ctx.lang)) + "</button>");
3988
4143
  if (ctx.skipped !== null) buttons.push("<button type=\"button\" data-act=\"row-resume-skip\" data-key=\"" + keyAttr + "\"" + off + ">" + escapeHtml$1(batchText("batch.row-action.unskip", ctx.lang, { version: ctx.skipped })) + "</button>");
3989
4144
  if (typeof row.manual === "string" && row.manual) buttons.push("<button type=\"button\" data-act=\"row-copy-manual\" data-key=\"" + keyAttr + "\"" + off + ">" + escapeHtml$1(batchText("batch.row-action.copy-manual", ctx.lang)) + "</button>");
@@ -3993,11 +4148,12 @@ ${body}`;
3993
4148
  function stripActionButtons(html) {
3994
4149
  return html.replace(/<button\b[^>]*data-action=[^>]*>[\s\S]*?<\/button>/g, "");
3995
4150
  }
3996
- function dotToneOf(row, phase, skipped, queued) {
4151
+ function dotToneOf(row, phase, skipped, queued, worldLatest = null) {
3997
4152
  if (phase === "failed" && !queued) return "bad";
3998
4153
  if (phase === "installing" || phase === "checking") return "busy";
3999
4154
  if (queued) return "warn";
4000
4155
  if (row.restartRequired === true) return "warn";
4156
+ if (worldLatest !== null) return "todo";
4001
4157
  if (phase === "ready") return skipped === null ? "todo" : "idle";
4002
4158
  if (phase === "current" || phase === "done") return "ok";
4003
4159
  return "idle";
@@ -4013,7 +4169,7 @@ ${body}`;
4013
4169
  ".dsh-upd-brow-set{border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
4014
4170
  ".dsh-upd-brow-set:first-child{border-top:0}",
4015
4171
  ".dsh-upd-brow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:6px 0}",
4016
- ".dsh-upd .dsh-upd-brow-main{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1 1 260px;min-width:0;",
4172
+ ".dsh-upd .dsh-upd-brow-main{display:grid;grid-template-columns:auto minmax(5em,max-content) minmax(18ch,max-content) minmax(0,1fr);align-items:baseline;column-gap:8px;row-gap:2px;flex:1 1 260px;min-width:0;",
4017
4173
  "text-align:left;cursor:pointer;color:inherit;font:inherit;background:transparent;border:0;padding:2px 0;margin:0}",
4018
4174
  ".dsh-upd .dsh-upd-brow-main:hover{color:var(--dsh-update-primary,#2563eb)}",
4019
4175
  ".dsh-upd-brow-actions{flex:none;margin-left:auto}",
@@ -4024,10 +4180,20 @@ ${body}`;
4024
4180
  ".dsh-upd-updot[data-tone=\"busy\"]{background:var(--dsh-update-busy-border,#2563eb);opacity:1}",
4025
4181
  ".dsh-upd-updot[data-tone=\"warn\"]{background:var(--dsh-update-warn-border,#d97706);opacity:1}",
4026
4182
  ".dsh-upd-updot[data-tone=\"bad\"]{background:var(--dsh-update-bad-border,#dc2626);opacity:1}",
4027
- ".dsh-upd-bname{font-weight:700;flex:none}",
4028
- ".dsh-upd-bver{font-family:Consolas,Menlo,monospace;font-size:12px;opacity:.8;flex:none}",
4029
- ".dsh-upd-bstat{font-size:12.5px;opacity:.9}",
4030
- ".dsh-upd-bfail{flex:1 1 100%;display:block;font-size:12.5px;color:var(--dsh-update-bad-border,#dc2626)}",
4183
+ ".dsh-upd-bname{font-weight:700;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
4184
+ ".dsh-upd-bver{font-family:Consolas,Menlo,monospace;font-size:12px;white-space:nowrap;font-variant-numeric:tabular-nums;min-width:0}",
4185
+ ".dsh-upd-bver-cur{opacity:.65}",
4186
+ ".dsh-upd-bver-arrow{opacity:.6}",
4187
+ ".dsh-upd-bver-new{color:var(--dsh-update-new-text,#dc2626);font-weight:700}",
4188
+ ".dsh-upd-bver-new-ok{color:var(--dsh-update-new-ok-text,#047857);font-weight:700}",
4189
+ ".dsh-upd-bstat{font-size:12.5px;opacity:.9;min-width:0;overflow-wrap:anywhere}",
4190
+ ".dsh-upd-bfail{grid-column:1/-1;display:block;font-size:12.5px;color:var(--dsh-update-bad-border,#dc2626)}",
4191
+ ".dsh-upd-batch{--dsh-update-new-text:#dc2626}",
4192
+ ".dsh-upd-batch{--dsh-update-new-ok-text:#047857}",
4193
+ "@media (prefers-color-scheme: dark){.dsh-upd-batch{--dsh-update-new-text:#f87171}}",
4194
+ "@media (prefers-color-scheme: dark){.dsh-upd-batch{--dsh-update-new-ok-text:#34d399}}",
4195
+ "@media (forced-colors: active){.dsh-upd-bver-new{color:CanvasText}}",
4196
+ "@media (forced-colors: active){.dsh-upd-bver-new-ok{color:CanvasText}}",
4031
4197
  ".dsh-upd-blist{font-size:12.5px;margin-top:2px}",
4032
4198
  ".dsh-upd-batch-ledger{margin:8px 0 0;font-size:13px;opacity:.85}",
4033
4199
  ".dsh-upd-batch-more{margin-top:6px}",
@@ -4061,6 +4227,13 @@ ${body}`;
4061
4227
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-brow-main:hover{color:var(--dsh-update-primary)}",
4062
4228
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-bname{font-family:var(--dsh-update-font-serif)}",
4063
4229
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-bver{font-family:var(--dsh-update-font-mono);color:var(--dsh-update-text-muted)}",
4230
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-bver-cur{opacity:.75}",
4231
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-bver-new{color:var(--dsh-update-new-text,#b3261e)}",
4232
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-bver-new-ok{color:var(--dsh-update-new-ok-text,#1a7f37)}",
4233
+ "@media (prefers-color-scheme: dark){.dsh-upd[data-theme=\"archive\"] .dsh-upd-batch{--dsh-update-new-ok-text:#8fd6a4}}",
4234
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch{--dsh-update-new-text:#b3261e}",
4235
+ ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch{--dsh-update-new-ok-text:#1a7f37}",
4236
+ "@media (prefers-color-scheme: dark){.dsh-upd[data-theme=\"archive\"] .dsh-upd-batch{--dsh-update-new-text:#ef8a7d}}",
4064
4237
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-ledger{color:var(--dsh-update-text-muted)}",
4065
4238
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-batch-sum{color:var(--dsh-update-text)}",
4066
4239
  ".dsh-upd[data-theme=\"archive\"] .dsh-upd-brow-set{border-top-color:var(--dsh-update-border)}"
@@ -4103,6 +4276,12 @@ ${body}`;
4103
4276
  for (const entry of queue.waiting) if (entry && typeof entry.requestId === "string" && entry.requestId) return entry.requestId;
4104
4277
  return null;
4105
4278
  }
4279
+ function singleCheckPhoneOf(row) {
4280
+ const phones = isObject$1(row.phoneNames) ? row.phoneNames : null;
4281
+ if (!phones) return null;
4282
+ const check = phones["updateCheck"];
4283
+ return typeof check === "string" && check ? check : null;
4284
+ }
4106
4285
  function cancelQueuePhoneOf(row) {
4107
4286
  const phones = isObject$1(row.phoneNames) ? row.phoneNames : null;
4108
4287
  if (!phones) return null;
@@ -4180,6 +4359,21 @@ ${body}`;
4180
4359
  detail: detail || null
4181
4360
  };
4182
4361
  }
4362
+ function diagStructuredSuffix(diagValue) {
4363
+ const t = readDiagTolerant(diagValue);
4364
+ const parts = [];
4365
+ if (t.stage) parts.push("stage=" + t.stage);
4366
+ if (t.route) parts.push("route=" + t.route);
4367
+ if (t.method) parts.push("method=" + t.method);
4368
+ if (typeof t.httpStatus === "number") parts.push("HTTP=" + String(t.httpStatus));
4369
+ if (typeof t.exitCode === "number") parts.push("exit=" + String(t.exitCode));
4370
+ if (typeof t.latencyMs === "number") parts.push("latency=" + String(t.latencyMs) + "ms");
4371
+ if (t.registryHost) parts.push("source=" + t.registryHost);
4372
+ if (t.action) parts.push("action=" + t.action);
4373
+ if (t.requestId) parts.push("request=" + t.requestId);
4374
+ if (t.checkId) parts.push("check=" + t.checkId);
4375
+ return parts.length > 0 ? parts.join(" · ") : null;
4376
+ }
4183
4377
  function diagTextOf(row, lang) {
4184
4378
  const snapshot = isObject$1(row.snapshot) ? row.snapshot : null;
4185
4379
  const queue = isObject$1(row.queue) ? row.queue : null;
@@ -4187,7 +4381,9 @@ ${body}`;
4187
4381
  const text = (value) => typeof value === "string" && value ? value : null;
4188
4382
  const job = jobFailureOf(row);
4189
4383
  const diagDetail = diag ? text(diag["detail"]) : null;
4190
- const detail = diagDetail !== null ? diagDetail : job !== null && job.detail !== null ? job.detail + batchText("batch.diag.source-job", langOf(lang)) : null;
4384
+ const baseDetail = diagDetail !== null ? diagDetail : job !== null && job.detail !== null ? job.detail + batchText("batch.diag.source-job", langOf(lang)) : null;
4385
+ const structured = diagStructuredSuffix(row.diag);
4386
+ const detail = baseDetail !== null && structured !== null ? baseDetail + " [" + structured + "]" : baseDetail ?? structured;
4191
4387
  return buildDiagnosticText({
4192
4388
  pluginId: pluginIdOf(row),
4193
4389
  code: job !== null && job.code !== null ? job.code : row.error || "check-failed",
@@ -4296,6 +4492,7 @@ ${body}`;
4296
4492
  let notice = null;
4297
4493
  let noticeKey = null;
4298
4494
  let inFlight = false;
4495
+ let inFlightIsCheck = false;
4299
4496
  let loaded = false;
4300
4497
  let refreshing = false;
4301
4498
  let confirmCancelArmed = false;
@@ -4527,10 +4724,23 @@ ${body}`;
4527
4724
  return;
4528
4725
  }
4529
4726
  if (reply["ok"] === true) {
4530
- const session = normalizeBatchSession(reply["session"]);
4531
- const parsed = readRows(reply["rows"]);
4532
- rows = parsed.length > 0 ? parsed : rowsFromSession(session);
4533
- lastSession = session;
4727
+ const hasSession = "session" in reply && reply["session"] !== void 0;
4728
+ const hasRows = "rows" in reply && reply["rows"] !== void 0;
4729
+ if (!hasSession && !hasRows) {
4730
+ if (isObject$1(reply["prefs"])) lastPrefs = reply["prefs"];
4731
+ return;
4732
+ }
4733
+ if (hasSession) {
4734
+ const session = normalizeBatchSession(reply["session"]);
4735
+ lastSession = session;
4736
+ if (hasRows) {
4737
+ const parsed = readRows(reply["rows"]);
4738
+ rows = parsed.length > 0 ? parsed : rowsFromSession(session);
4739
+ } else rows = rowsFromSession(session);
4740
+ } else {
4741
+ const parsed = readRows(reply["rows"]);
4742
+ if (parsed.length > 0) rows = parsed;
4743
+ }
4534
4744
  if (isObject$1(reply["inventory"])) {
4535
4745
  lastInventory = reply["inventory"];
4536
4746
  const at = reply["inventory"]["updatedAt"];
@@ -4564,6 +4774,7 @@ ${body}`;
4564
4774
  async function phone(name, args, busyRowKey = null) {
4565
4775
  if (!mounted || inFlight) return null;
4566
4776
  inFlight = true;
4777
+ inFlightIsCheck = name === phones.check;
4567
4778
  clearNotice();
4568
4779
  render();
4569
4780
  let out = null;
@@ -4583,6 +4794,7 @@ ${body}`;
4583
4794
  out = null;
4584
4795
  } finally {
4585
4796
  inFlight = false;
4797
+ inFlightIsCheck = false;
4586
4798
  if (mounted) render();
4587
4799
  }
4588
4800
  maybeAutoRowChangelog(expandedKey);
@@ -4657,6 +4869,10 @@ ${body}`;
4657
4869
  const row = typeof key === "string" && key ? rowOfKey(key) : null;
4658
4870
  const version = row ? latestVersionOf(row) : null;
4659
4871
  if (!row || !version) return;
4872
+ if (!validReleaseVersion(version)) {
4873
+ render();
4874
+ return;
4875
+ }
4660
4876
  try {
4661
4877
  skipStoreFor(pluginIdOf(row)).skip(version);
4662
4878
  } catch {}
@@ -4675,6 +4891,46 @@ ${body}`;
4675
4891
  render();
4676
4892
  return;
4677
4893
  }
4894
+ case "row-check": {
4895
+ const row = typeof key === "string" && key ? rowOfKey(key) : null;
4896
+ if (!row) return;
4897
+ const phoneName = singleCheckPhoneOf(row);
4898
+ if (phoneName === null) return;
4899
+ if (inFlight) return;
4900
+ inFlight = true;
4901
+ inFlightIsCheck = true;
4902
+ clearNotice();
4903
+ render();
4904
+ try {
4905
+ const reply = await call(phoneName, {
4906
+ includeEnv: true,
4907
+ includeQueue: true
4908
+ });
4909
+ if (!mounted) return;
4910
+ if (isObject$1(reply) && reply["ok"] !== true) {
4911
+ const rec = reply;
4912
+ const kind2 = typeof rec["errorKind"] === "string" && rec["errorKind"].trim() ? rec["errorKind"].trim() : "";
4913
+ const err = typeof rec["error"] === "string" && rec["error"].trim() ? rec["error"].trim() : "";
4914
+ const code = kind2 || err || "check-failed";
4915
+ const copy = failureCopy(code, currentLang());
4916
+ say(copy ? copy.zh + "|" + copy.act : code, row.key);
4917
+ }
4918
+ } catch {
4919
+ if (mounted) {
4920
+ const copy = failureCopy("check-failed", currentLang());
4921
+ say(copy ? copy.zh + "|" + copy.act : "check-failed", row.key);
4922
+ }
4923
+ } finally {
4924
+ inFlight = false;
4925
+ inFlightIsCheck = false;
4926
+ }
4927
+ try {
4928
+ for (const k of [...rowFailedAt.keys()]) if (k === row.key || k.startsWith(row.key + "\0")) rowFailedAt.delete(k);
4929
+ } catch {}
4930
+ await refresh();
4931
+ maybeAutoRowChangelog(expandedKey);
4932
+ return;
4933
+ }
4678
4934
  case "row-cancel-queue": {
4679
4935
  const row = typeof key === "string" && key ? rowOfKey(key) : null;
4680
4936
  if (!row) return;
@@ -4864,7 +5120,7 @@ ${body}`;
4864
5120
  } catch {}
4865
5121
  const timer = getTimer();
4866
5122
  const handle = timer.set(() => {
4867
- if (inFlight) return;
5123
+ if (inFlight && inFlightIsCheck) return;
4868
5124
  refresh();
4869
5125
  }, pollMs);
4870
5126
  try {
@@ -4884,7 +5140,7 @@ ${body}`;
4884
5140
  };
4885
5141
  }
4886
5142
  //#endregion
4887
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.7.0/node_modules/dsh-plugin-update/dist/entry-batch.js
5143
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.9.0/node_modules/dsh-plugin-update/dist/entry-batch.js
4888
5144
  function isObject(value) {
4889
5145
  return !!value && typeof value === "object" && !Array.isArray(value);
4890
5146
  }
@@ -4897,7 +5153,9 @@ ${body}`;
4897
5153
  }
4898
5154
  function batchEntrySummary(state, lang) {
4899
5155
  const rows = state?.rows ?? null;
4900
- const counts = batchLedgerCounts(Array.isArray(rows) ? rows : []);
5156
+ const inventory = state?.inventory ?? void 0;
5157
+ const session = state?.session;
5158
+ const counts = batchLedgerCounts(Array.isArray(rows) ? rows : [], inventory, session);
4901
5159
  const total = Array.isArray(rows) ? rows.length : 0;
4902
5160
  let kind;
4903
5161
  if (!Array.isArray(rows) || rows.length === 0) kind = state?.error ? "failed" : "idle";
@@ -4995,6 +5253,8 @@ ${body}`;
4995
5253
  const ENTRY_SELECTOR = "[data-dsh-upd-entry]";
4996
5254
  let rows = null;
4997
5255
  let error = null;
5256
+ let inventory = null;
5257
+ let session = null;
4998
5258
  let note = null;
4999
5259
  let loaded = false;
5000
5260
  let activating = false;
@@ -5022,7 +5282,9 @@ ${body}`;
5022
5282
  function stateOf() {
5023
5283
  return {
5024
5284
  rows,
5025
- error
5285
+ error,
5286
+ inventory,
5287
+ session
5026
5288
  };
5027
5289
  }
5028
5290
  function summaryOf() {
@@ -5059,6 +5321,8 @@ ${body}`;
5059
5321
  }
5060
5322
  const next = asRows(reply["rows"]);
5061
5323
  if (next) rows = next;
5324
+ if (isObject(reply) && "inventory" in reply) inventory = reply["inventory"] ?? null;
5325
+ if (isObject(reply) && "session" in reply) session = reply["session"] ?? null;
5062
5326
  error = null;
5063
5327
  loaded = true;
5064
5328
  }
@@ -7181,7 +7445,7 @@ ${body}`;
7181
7445
  }, react.createElement("span", { style: S.morePkg }, row.pkg), react.createElement("span", { style: S.moreDesc }, row.desc), react.createElement("span", { style: S.moreIcon }, react.createElement(ExternalIcon, null)))));
7182
7446
  }
7183
7447
  /** 版本胶囊那一行字:只在这里拼一次,屏上与用例读的是同一串。 */
7184
- const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.49";
7448
+ const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.51";
7185
7449
  /** 爱生活面板:总设置区 + 检查更新(七家)+ 爱生活页签条(slot 驱动)+ 技能设置页投影/缺席卡。 */
7186
7450
  function LifePackSection(props) {
7187
7451
  const tabsId = react.useId();