dsh-life-pack 0.3.67 → 0.3.69

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
@@ -471,7 +471,7 @@ window.__ModuleLoader__.load({
471
471
  path: "/api/ilife-manager"
472
472
  };
473
473
  //#endregion
474
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/config.js
474
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/config.js
475
475
  const DEFAULT_PANEL_POLL_MS = 1e3;
476
476
  function assertPrefix(value, role) {
477
477
  if (typeof value !== "string" || value.length === 0) throw new Error("[dsh-plugin-update] " + role + " 非法:须为非空字符串(收到 " + JSON.stringify(value) + ")");
@@ -493,7 +493,7 @@ window.__ModuleLoader__.load({
493
493
  return buildPhoneNames(prefix).logAppend;
494
494
  }
495
495
  //#endregion
496
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/version-judgment.js
496
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/version-judgment.js
497
497
  function updateError(code) {
498
498
  return Object.assign(new Error(code), { code });
499
499
  }
@@ -580,7 +580,7 @@ window.__ModuleLoader__.load({
580
580
  return 0;
581
581
  }
582
582
  //#endregion
583
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/lang.js
583
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/lang.js
584
584
  function normalizeLangTag(tag) {
585
585
  if (typeof tag !== "string") return "zh";
586
586
  const s = tag.trim().toLowerCase().replace(/_/g, "-");
@@ -722,7 +722,7 @@ window.__ModuleLoader__.load({
722
722
  };
723
723
  }
724
724
  //#endregion
725
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/bilingual.js
725
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/bilingual.js
726
726
  const BILINGUAL_STRINGS = {
727
727
  "entry.label.idle": {
728
728
  en: "Check for updates",
@@ -779,6 +779,16 @@ window.__ModuleLoader__.load({
779
779
  zh: "{count} 个待重启",
780
780
  draft: true
781
781
  },
782
+ "batch-entry.label.restart-unregistered": {
783
+ en: "{count} installed, not registered",
784
+ zh: "{count} 个已装未登记(重启不会加载)",
785
+ draft: true
786
+ },
787
+ "batch-entry.label.restart-mixed": {
788
+ en: "{count} restarts required, {unregistered} not registered",
789
+ zh: "{count} 个待重启,{unregistered} 个未登记",
790
+ draft: true
791
+ },
782
792
  "batch-entry.label.failed": {
783
793
  en: "{count} failed — View details",
784
794
  zh: "{count} 个失败,请查看详情",
@@ -835,8 +845,8 @@ window.__ModuleLoader__.load({
835
845
  draft: true
836
846
  },
837
847
  "panel.blocked.installation-changed.action": {
838
- en: "Reopen the host and check again; if it persists, reinstall.",
839
- zh: "重启宿主后重新查询;若持续,请重新安装",
848
+ en: "Reopen the host and check again; if it says you are already up to date, nothing to do; if it persists, reinstall.",
849
+ zh: "重启宿主后重新查询;若说明已是最新则无需操作;若持续,请重新安装",
840
850
  draft: true
841
851
  },
842
852
  "panel.blocked.pending-restart.title": {
@@ -869,6 +879,16 @@ window.__ModuleLoader__.load({
869
879
  zh: "请升级 Node 至 22 或更高版本后重新查询",
870
880
  draft: true
871
881
  },
882
+ "panel.blocked.incompatible-dsh.title": {
883
+ en: "New version requires a newer DSH runtime",
884
+ zh: "新版本要求更高的宿主运行时版本",
885
+ draft: true
886
+ },
887
+ "panel.blocked.incompatible-dsh.action": {
888
+ en: "The running DSH does not satisfy the new version; upgrade DSH first, then update.",
889
+ zh: "当前宿主运行时版本不满足新版本要求,请先升级宿主再更新",
890
+ draft: true
891
+ },
872
892
  "panel.blocked.recovery-required.title": {
873
893
  en: "Last install was interrupted, leaving a partial task",
874
894
  zh: "上次安装异常中断,存在未完成任务",
@@ -1094,6 +1114,16 @@ window.__ModuleLoader__.load({
1094
1114
  zh: "新版本 {latest} 已安装,重启宿主后生效。",
1095
1115
  draft: true
1096
1116
  },
1117
+ "panel.banner.restart-unregistered-title": {
1118
+ en: "Version {latest} is on disk, but this plugin is not registered in the scope selection, so restarting the host will not load it.",
1119
+ zh: "新版本 {latest} 已写入磁盘,但该插件未登记在使用范围清单,重启宿主也不会加载。",
1120
+ draft: true
1121
+ },
1122
+ "panel.banner.restart-unregistered-action": {
1123
+ en: "Select this plugin in the host plugin page first, then restart the host to load the new version.",
1124
+ zh: "请先在宿主插件页选中该插件,再重启宿主以加载新版本。",
1125
+ draft: true
1126
+ },
1097
1127
  "panel.banner.installing-title": {
1098
1128
  en: "Installing {version}… Closing the panel won’t interrupt it.",
1099
1129
  zh: "正在安装 {version}…关闭面板不会中断。",
@@ -1119,11 +1149,36 @@ window.__ModuleLoader__.load({
1119
1149
  zh: "选择安装将按精确版本安装;同一使用范围同时仅安装一项。",
1120
1150
  draft: true
1121
1151
  },
1152
+ "panel.banner.unknown-running-title": {
1153
+ en: "Running version unknown; cannot tell whether an update is available.",
1154
+ zh: "运行版本未知,无法判断是否有新版可装。",
1155
+ draft: true
1156
+ },
1157
+ "panel.banner.unknown-running-action": {
1158
+ en: "Check the plugin version in the host manifest and reopen the host, then check again.",
1159
+ zh: "请检查宿主清单里的插件版本,重启宿主后重新查询",
1160
+ draft: true
1161
+ },
1122
1162
  "panel.action.install-version": {
1123
1163
  en: "Install {latest}",
1124
1164
  zh: "安装版本 {latest}",
1125
1165
  draft: true
1126
1166
  },
1167
+ "panel.banner.first-install-title": {
1168
+ en: "First install: {latest} (new dependency).",
1169
+ zh: "首次安装 {latest}(新增依赖)。",
1170
+ draft: true
1171
+ },
1172
+ "panel.banner.first-install-action": {
1173
+ en: "Restart the host after installing for it to load.",
1174
+ zh: "装完需要重启宿主才会加载。",
1175
+ draft: true
1176
+ },
1177
+ "panel.action.first-install-version": {
1178
+ en: "Install {latest} (first time)",
1179
+ zh: "首次安装 {latest}",
1180
+ draft: true
1181
+ },
1127
1182
  "panel.banner.update-gated-title": {
1128
1183
  en: "Version {latest} was just published and is still gated ({unlock}); installing now will fail — use Install fallback build below if you cannot wait.",
1129
1184
  zh: "新版本 {latest} 刚发布未满门,{unlock}可装;现在点安装会失败,等不及可先装合规版。",
@@ -1599,6 +1654,16 @@ window.__ModuleLoader__.load({
1599
1654
  zh: "当前没有可用的手工命令(使用范围无法识别或源码安装场景不提供)。",
1600
1655
  draft: true
1601
1656
  },
1657
+ "panel.manual.updater-nested": {
1658
+ en: "This panel runs a nested copy of the updater ({version}), pinned by the plugin that declares it; update that plugin first (this panel picks up a newer updater only after that plugin widens its range). You can also install the updater at the profile level with the carrier CLI so other plugins sharing that copy get the fixes first: {command}",
1659
+ zh: "本面板的更新器是嵌套副本({version}),由声明它的插件钉住;请先更新那个插件(它发版抬了依赖范围后,本面板才会换新)。也可用载体命令行把更新器装到使用范围级,让共用那一份的其他插件先拿到修复:{command}",
1660
+ draft: true
1661
+ },
1662
+ "panel.manual.updater-nested-nocmd": {
1663
+ en: "This panel runs a nested copy of the updater ({version}), pinned by the plugin that declares it; update that plugin first (this panel picks up a newer updater only after that plugin widens its range).",
1664
+ zh: "本面板的更新器是嵌套副本({version}),由声明它的插件钉住;请先更新那个插件(它发版抬了依赖范围后,本面板才会换新)。",
1665
+ draft: true
1666
+ },
1602
1667
  "panel.footer.note": {
1603
1668
  en: "Closing never interrupts updates; come back anytime",
1604
1669
  zh: "关闭窗口,更新不受影响,可随时返回查看。",
@@ -1764,6 +1829,11 @@ window.__ModuleLoader__.load({
1764
1829
  zh: "队列={queue}",
1765
1830
  draft: true
1766
1831
  },
1832
+ "panel.diag.copy.field.updater": {
1833
+ en: "Updater={version} ({level})",
1834
+ zh: "更新器={version}({level})",
1835
+ draft: true
1836
+ },
1767
1837
  "panel.diag.copy.field.target": {
1768
1838
  en: "Target={version}",
1769
1839
  zh: "目标={version}",
@@ -1904,6 +1974,11 @@ window.__ModuleLoader__.load({
1904
1974
  zh: "{n} 个待重启",
1905
1975
  draft: true
1906
1976
  },
1977
+ "batch.summary.restart-unregistered": {
1978
+ en: "{n} not registered (restarting will not load them)",
1979
+ zh: "另有 {n} 个未登记,重启不会加载",
1980
+ draft: true
1981
+ },
1907
1982
  "batch.summary.failed": {
1908
1983
  en: "{n} failed",
1909
1984
  zh: "{n} 个失败",
@@ -1999,6 +2074,11 @@ window.__ModuleLoader__.load({
1999
2074
  zh: "{n} 个已安装完成,重启宿主后生效。",
2000
2075
  draft: true
2001
2076
  },
2077
+ "batch.hint.restart-unregistered": {
2078
+ en: "{n} installed but not registered; restarting the host will not load them.",
2079
+ zh: "{n} 个已安装但未登记,重启宿主不会加载。",
2080
+ draft: true
2081
+ },
2002
2082
  "batch.hint.pending": {
2003
2083
  en: "{n} not checked yet; select “Check for updates” for a round.",
2004
2084
  zh: "{n} 个尚未查询;请选择「检查更新」查询一轮。",
@@ -2074,6 +2154,21 @@ window.__ModuleLoader__.load({
2074
2154
  zh: "{n} 个已安装完成,重启宿主后生效。",
2075
2155
  draft: true
2076
2156
  },
2157
+ "batch.banner.restart-partial-title": {
2158
+ en: "{n} installed and will take effect after restart; {m} not registered (restarting will not load them).",
2159
+ zh: "已安装完成:{n} 个重启宿主后生效,{m} 个未登记(重启不会加载)。",
2160
+ draft: true
2161
+ },
2162
+ "batch.banner.restart-unregistered-title": {
2163
+ en: "Installed, but these plugins are not registered; restarting the host will not load them.",
2164
+ zh: "已安装完成,但这些插件未登记,重启宿主也不会加载。",
2165
+ draft: true
2166
+ },
2167
+ "batch.banner.restart-unregistered-hint": {
2168
+ en: "Unregistered plugins: select them in the host plugin page first; they will load after restart.",
2169
+ zh: "未登记的行:请先在宿主插件页选中该插件,重启后才会加载。",
2170
+ draft: true
2171
+ },
2077
2172
  "batch.banner.restart-action": {
2078
2173
  en: "Restart the host to run the new version; this is a normal end state, not a failure.",
2079
2174
  zh: "重启宿主以加载新版本;此为正常状态,非安装失败。",
@@ -2129,6 +2224,16 @@ window.__ModuleLoader__.load({
2129
2224
  zh: "已安装完成,重启宿主后生效。",
2130
2225
  draft: true
2131
2226
  },
2227
+ "batch.row.done-restart-unregistered": {
2228
+ en: "Installed; not registered (restart will not load it). Select it in the host plugin page first.",
2229
+ zh: "已安装,未登记(重启不会加载);请先在宿主插件页选中该插件",
2230
+ draft: true
2231
+ },
2232
+ "batch.row.unregistered-suffix": {
2233
+ en: " (not registered)",
2234
+ zh: "(未登记)",
2235
+ draft: true
2236
+ },
2132
2237
  "batch.row.done": {
2133
2238
  en: "Installed; nothing to do",
2134
2239
  zh: "已安装完成,无需操作。",
@@ -2289,6 +2394,16 @@ window.__ModuleLoader__.load({
2289
2394
  zh: "诊断信息已复制,请提交至插件作者(已脱敏)。",
2290
2395
  draft: true
2291
2396
  },
2397
+ "batch.toast.copy-all-diag-ok": {
2398
+ en: "Diagnostics for {n} plugin(s) copied; paste them to the plugin author (already redacted).",
2399
+ zh: "已复制 {n} 家插件的诊断,请提交至插件作者(已脱敏)。",
2400
+ draft: true
2401
+ },
2402
+ "batch.toast.copy-all-manual-ok": {
2403
+ en: "{n} manual command(s) copied (plugins without a command are marked as # comments); paste them into the terminal line by line.",
2404
+ zh: "已复制 {n} 条手工命令(无命令的插件已用 # 注释标注),请粘贴至终端逐行执行。",
2405
+ draft: true
2406
+ },
2292
2407
  "batch.toast.restart-delegated": {
2293
2408
  en: "Handled by the caller’s restart flow; the new version takes effect after restart.",
2294
2409
  zh: "已按调用方重启流程处理;重启后新版本生效。",
@@ -2429,6 +2544,11 @@ window.__ModuleLoader__.load({
2429
2544
  zh: "Node 运行时版本不兼容",
2430
2545
  draft: true
2431
2546
  },
2547
+ "diag.fallback.incompatible-dsh": {
2548
+ en: "New version needs a newer DSH runtime than the running one",
2549
+ zh: "宿主运行时版本不兼容",
2550
+ draft: true
2551
+ },
2432
2552
  "diag.fallback.registry-conflict": {
2433
2553
  en: "Declared version conflicts with the on-disk version",
2434
2554
  zh: "版本声明与磁盘实际版本冲突",
@@ -2499,7 +2619,7 @@ window.__ModuleLoader__.load({
2499
2619
  }
2500
2620
  const BILINGUAL_CSS = [".dsh-upd-bi{display:inline;overflow-wrap:anywhere}", ".dsh-upd-bi [lang]{overflow-wrap:anywhere}"].join("\n");
2501
2621
  //#endregion
2502
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/changelog.js
2622
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/changelog.js
2503
2623
  const CHANGELOG_MAX_CHARS = 65536;
2504
2624
  const CHANGELOG_ALL_CATEGORIES = [
2505
2625
  "Added",
@@ -3607,7 +3727,7 @@ ${note}${blocks.join("\n")}
3607
3727
  }
3608
3728
  }
3609
3729
  //#endregion
3610
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/log-events.js
3730
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/log-events.js
3611
3731
  const LOG_EVENT_CALL = "host.call";
3612
3732
  const LOG_EVENT_CALL_FAIL = "host.call.fail";
3613
3733
  const LOG_EVENT_INSTALL_EXEC = "update.install.exec";
@@ -3858,7 +3978,7 @@ ${note}${blocks.join("\n")}
3858
3978
  };
3859
3979
  }
3860
3980
  //#endregion
3861
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/codes.js
3981
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/codes.js
3862
3982
  const BLOCKED_REASONS = [
3863
3983
  "unknown-profile",
3864
3984
  "channel-mismatch",
@@ -3868,6 +3988,7 @@ ${note}${blocks.join("\n")}
3868
3988
  "pending-restart",
3869
3989
  "registry-conflict",
3870
3990
  "incompatible-node",
3991
+ "incompatible-dsh",
3871
3992
  "recovery-required",
3872
3993
  "dev-source"
3873
3994
  ];
@@ -3893,7 +4014,7 @@ ${note}${blocks.join("\n")}
3893
4014
  return typeof code === "string" && isOneOf(CHECK_SIDE_FAILURE_CODES, code.trim());
3894
4015
  }
3895
4016
  //#endregion
3896
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/install-cause.js
4017
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/install-cause.js
3897
4018
  const CAUSE_KINDS = ["minimum-release-age"];
3898
4019
  const CAUSE_SIGNATURES = [{
3899
4020
  kind: "minimum-release-age",
@@ -4013,12 +4134,14 @@ ${note}${blocks.join("\n")}
4013
4134
  }
4014
4135
  }
4015
4136
  //#endregion
4016
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/redaction.js
4137
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/redaction.js
4017
4138
  const COPY_BUDGET_CHARS = 1500;
4018
4139
  const REDACTED_PATH = "<路径>";
4019
4140
  const REDACTED_SECRET = "<脱敏>";
4020
4141
  const ABSOLUTE_PATH_RE = /[A-Za-z]:\\[^\s"']*|\\\\[^\s"'()\[\];]+|(^|[\s"'(\[=,])\/\/[^\s"'()\[\];]+|(^|[\s"'(\[=:,])\/(?!\/)[^\s"'()\[\];]+/g;
4021
4142
  const URL_USERINFO_RE = /[A-Za-z][A-Za-z0-9+.-]*:\/\/[^\s/]*@/;
4143
+ const URL_USERINFO_MASK_RE = /([A-Za-z][A-Za-z0-9+.-]*:\/\/)[^\s/]*@/g;
4144
+ const MASKED_CREDENTIAL_NOTE = "(原话里的账号密码已隐去;请核对源地址里的凭据后重试)";
4022
4145
  const NPM_TOKEN_RE = /\bnpm_[A-Za-z0-9_-]{8,}/g;
4023
4146
  const GITHUB_TOKEN_RE = /\b(?:gh[pousr]_[A-Za-z0-9]{8,}|github_pat_[A-Za-z0-9_]{10,})/g;
4024
4147
  const SK_TOKEN_RE = /\bsk-[A-Za-z0-9_-]{6,}/g;
@@ -4049,9 +4172,16 @@ ${note}${blocks.join("\n")}
4049
4172
  EMAIL_RE.lastIndex = 0;
4050
4173
  return text.replace(EMAIL_RE, REDACTED_SECRET);
4051
4174
  }
4052
- function hasUserinfo(text) {
4053
- URL_USERINFO_RE.lastIndex = 0;
4054
- return URL_USERINFO_RE.test(text);
4175
+ function applyUserinfoRule(text) {
4176
+ if (!URL_USERINFO_RE.test(text)) return {
4177
+ text,
4178
+ masked: false
4179
+ };
4180
+ URL_USERINFO_MASK_RE.lastIndex = 0;
4181
+ return {
4182
+ text: text.replace(URL_USERINFO_MASK_RE, `$1${REDACTED_SECRET}@`),
4183
+ masked: true
4184
+ };
4055
4185
  }
4056
4186
  function truncateToWordBoundary(text, max) {
4057
4187
  const input = String(text ?? "");
@@ -4067,17 +4197,24 @@ ${note}${blocks.join("\n")}
4067
4197
  function truncateForCopy(text) {
4068
4198
  return truncateToWordBoundary(text, COPY_BUDGET_CHARS);
4069
4199
  }
4200
+ function truncateWithMaskNote(text, budget) {
4201
+ const room = budget - 27 - 1;
4202
+ if (room <= 0) return MASKED_CREDENTIAL_NOTE;
4203
+ const head = truncateToWordBoundary(text, room);
4204
+ return head ? `${head}\uFF1B${MASKED_CREDENTIAL_NOTE}` : MASKED_CREDENTIAL_NOTE;
4205
+ }
4070
4206
  function scrubWithoutBudget(text) {
4071
4207
  return applyEmailRule(applyCredPairRule(applyTokenRule(applyPathRule(text))));
4072
4208
  }
4073
4209
  function sanitizeForCopy(text) {
4074
4210
  const flat = flattenWhitespace(String(text ?? ""));
4075
4211
  if (!flat) return "";
4076
- if (hasUserinfo(flat)) return "";
4077
- return truncateForCopy(scrubWithoutBudget(flat));
4212
+ const userinfo = applyUserinfoRule(flat);
4213
+ const scrubbed = scrubWithoutBudget(userinfo.text);
4214
+ return userinfo.masked ? truncateWithMaskNote(scrubbed, COPY_BUDGET_CHARS) : truncateForCopy(scrubbed);
4078
4215
  }
4079
4216
  //#endregion
4080
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/panel-copy.js
4217
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/panel-copy.js
4081
4218
  const BLOCKED_KEYS = {
4082
4219
  "unknown-profile": {
4083
4220
  title: "panel.blocked.unknown-profile.title",
@@ -4111,6 +4248,10 @@ ${note}${blocks.join("\n")}
4111
4248
  title: "panel.blocked.incompatible-node.title",
4112
4249
  action: "panel.blocked.incompatible-node.action"
4113
4250
  },
4251
+ "incompatible-dsh": {
4252
+ title: "panel.blocked.incompatible-dsh.title",
4253
+ action: "panel.blocked.incompatible-dsh.action"
4254
+ },
4114
4255
  "recovery-required": {
4115
4256
  title: "panel.blocked.recovery-required.title",
4116
4257
  action: "panel.blocked.recovery-required.action"
@@ -4220,6 +4361,23 @@ ${note}${blocks.join("\n")}
4220
4361
  function redactForCopy(text) {
4221
4362
  return sanitizeForCopy(text);
4222
4363
  }
4364
+ function updaterPartsOf(updater) {
4365
+ if (!updater || typeof updater !== "object") return null;
4366
+ const version = typeof updater.version === "string" && updater.version.trim() ? updater.version.trim() : null;
4367
+ if (!version) return null;
4368
+ return {
4369
+ version,
4370
+ level: typeof updater.level === "string" && updater.level.trim() ? updater.level.trim() : "unknown"
4371
+ };
4372
+ }
4373
+ function updaterFieldText(updater, lang) {
4374
+ const parts = updaterPartsOf(updater);
4375
+ if (!parts) return null;
4376
+ return copyText("panel.diag.copy.field.updater", lang, {
4377
+ version: parts.version,
4378
+ level: parts.level
4379
+ });
4380
+ }
4223
4381
  function buildDiagnosticText(input, langOverride) {
4224
4382
  const l = normalizeLangTag(langOverride ?? input.lang ?? "zh");
4225
4383
  const unknown = copyText("panel.diag.copy.unknown", l);
@@ -4241,6 +4399,8 @@ ${note}${blocks.join("\n")}
4241
4399
  const hostLine = [copyText("panel.diag.label.host", l, { host: input.hostKind ?? unknown })];
4242
4400
  if (typeof input.profileName === "string" && input.profileName) hostLine.push(copyText("panel.diag.label.profile", l, { profile: input.profileName }));
4243
4401
  hostLine.push(copyText("panel.diag.label.queue", l, { queue }));
4402
+ const updaterLine = updaterFieldText(input.updater, l);
4403
+ if (updaterLine) hostLine.push(updaterLine);
4244
4404
  lines.push(hostLine.join(" / ") + (input.requestId ? ` / ${copyText("panel.diag.label.request", l, { requestId: input.requestId })}` : ""));
4245
4405
  const manual = redactForCopy(input.manual ?? "");
4246
4406
  if (manual) lines.push(copyText("panel.diag.label.manual", l, { manual }));
@@ -4377,6 +4537,8 @@ ${note}${blocks.join("\n")}
4377
4537
  if (typeof requestRaw === "string" && requestRaw.trim()) prov.push(copyText("panel.diag.copy.field.request", l, { request: requestRaw.trim() }));
4378
4538
  if (typeof checkRaw === "string" && checkRaw.trim()) prov.push(copyText("panel.diag.copy.field.check", l, { check: checkRaw.trim() }));
4379
4539
  prov.push(copyText("panel.diag.copy.field.queue", l, { queue }));
4540
+ const updaterText = updaterFieldText(input.updater, l);
4541
+ if (updaterText) prov.push(updaterText);
4380
4542
  const format = input.format === "line" ? "line" : "block";
4381
4543
  const provLine = redactForCopy(prov.join(" · "));
4382
4544
  if (format === "line") return redactForCopy(`[update-diag] code=${rawCode} \xB7 ${copy.zh} \xB7 ${copyText("panel.diag.copy.line.summary", l, { summary: detail })} \xB7 ${provLine} \xB7 ${copyText("panel.diag.copy.line.remedy", l, { remedy })}`);
@@ -4388,7 +4550,7 @@ ${note}${blocks.join("\n")}
4388
4550
  ].join("\n");
4389
4551
  }
4390
4552
  //#endregion
4391
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/panel.js
4553
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/panel.js
4392
4554
  function normalizePanelTheme(value) {
4393
4555
  return value === "archive" ? "archive" : "default";
4394
4556
  }
@@ -4770,19 +4932,23 @@ ${note}${blocks.join("\n")}
4770
4932
  queueNote
4771
4933
  };
4772
4934
  }
4773
- if (snapshot.blockedReason === "pending-restart") return {
4774
- banner: {
4775
- kind: "restart",
4776
- title: copyText("panel.banner.restart-title", l, { latest: snapshot.latestVersion ?? snapshot.installedVersion ?? "" }),
4777
- action: blockedCopy("pending-restart", l)?.action ?? ""
4778
- },
4779
- installEnabled: false,
4780
- installLabel: copyText("panel.action.install", l),
4781
- skippedLatest: false,
4782
- showManual: manual ? true : false,
4783
- showReset: false,
4784
- queueNote
4785
- };
4935
+ if (snapshot.blockedReason === "pending-restart") {
4936
+ const latest = snapshot.latestVersion ?? snapshot.installedVersion ?? "";
4937
+ const unregistered = snapshot.registered === false;
4938
+ return {
4939
+ banner: {
4940
+ kind: "restart",
4941
+ title: unregistered ? copyText("panel.banner.restart-unregistered-title", l, { latest }) : copyText("panel.banner.restart-title", l, { latest }),
4942
+ action: unregistered ? copyText("panel.banner.restart-unregistered-action", l) : blockedCopy("pending-restart", l)?.action ?? ""
4943
+ },
4944
+ installEnabled: false,
4945
+ installLabel: copyText("panel.action.install", l),
4946
+ skippedLatest: false,
4947
+ showManual: manual ? true : false,
4948
+ showReset: false,
4949
+ queueNote
4950
+ };
4951
+ }
4786
4952
  if (snapshot.blockedReason) {
4787
4953
  const copy = blockedCopy(snapshot.blockedReason, l);
4788
4954
  const stop = l === "en" ? "." : "。";
@@ -4800,8 +4966,34 @@ ${note}${blocks.join("\n")}
4800
4966
  queueNote
4801
4967
  };
4802
4968
  }
4969
+ if (snapshot.installed !== false && snapshot.runningVersion === null) return {
4970
+ banner: {
4971
+ kind: "blocked",
4972
+ title: copyText("panel.banner.unknown-running-title", l),
4973
+ action: copyText("panel.banner.unknown-running-action", l)
4974
+ },
4975
+ installEnabled: false,
4976
+ installLabel: copyText("panel.action.install", l),
4977
+ skippedLatest: false,
4978
+ showManual: manual ? true : false,
4979
+ showReset: false,
4980
+ queueNote
4981
+ };
4803
4982
  if (snapshot.canInstall && snapshot.latestVersion) {
4804
- const running = snapshot.installed === false ? copyText("panel.banner.not-installed", l) : snapshot.runningVersion;
4983
+ if (snapshot.identity === "first-install") return {
4984
+ banner: {
4985
+ kind: "update",
4986
+ title: copyText("panel.banner.first-install-title", l, { latest: snapshot.latestVersion }),
4987
+ action: copyText("panel.banner.first-install-action", l)
4988
+ },
4989
+ installEnabled: true,
4990
+ installLabel: copyText("panel.action.first-install-version", l, { latest: snapshot.latestVersion }),
4991
+ skippedLatest: false,
4992
+ showManual: manual ? true : false,
4993
+ showReset: false,
4994
+ queueNote
4995
+ };
4996
+ const running = snapshot.installed === false ? copyText("panel.banner.not-installed", l) : snapshot.runningVersion ?? copyText("panel.meta.unknown", l);
4805
4997
  if (gated) {
4806
4998
  const unlock = formatUnlockAt(gated.unlockAtMs, l) ?? "";
4807
4999
  return {
@@ -4936,6 +5128,9 @@ ${note}${blocks.join("\n")}
4936
5128
  ".dsh-upd-chapter{margin-top:18px;padding-top:14px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
4937
5129
  ".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)}",
4938
5130
  ".dsh-upd-foot-note{margin-right:auto;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.7}",
5131
+ ".dsh-upd-updater-note{font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.55;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;white-space:nowrap}",
5132
+ ".dsh-upd-updater-id{margin-top:8px;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.55;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}",
5133
+ ".dsh-upd-updater-nested{margin-top:8px;font-size:var(--dsh-update-panel-small-font-size,12px);opacity:.8;line-height:1.5;word-break:break-word}",
4939
5134
  ".dsh-upd-footer button{margin:0}",
4940
5135
  ".dsh-upd-chap-head{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}",
4941
5136
  ".dsh-upd-chap-no{font-size:var(--dsh-update-panel-chapter-font-size,13px);font-style:italic;opacity:.6}",
@@ -4963,6 +5158,7 @@ ${note}${blocks.join("\n")}
4963
5158
  "@keyframes dsh-upd-shimmer{to{background-position:-200% 0}}",
4964
5159
  ".dsh-upd-tag{display:inline-block;border:1px dashed currentColor;border-radius:3px;padding:1px 8px;margin-right:8px;font-family:Consolas,Menlo,monospace;font-size:var(--dsh-update-panel-small-font-size,12px)}",
4965
5160
  ".dsh-upd-err{font-size:var(--dsh-update-panel-log-font-size,13px);margin:0 0 6px}",
5161
+ ".dsh-upd-log,.dsh-upd-err{overflow-wrap:anywhere}",
4966
5162
  ".dsh-upd button{transition:background-color .15s ease,border-color .15s ease,color .15s ease,transform .06s ease}",
4967
5163
  ".dsh-upd button:hover:not(:disabled){border-color:var(--dsh-update-focus,#2563eb)}",
4968
5164
  ".dsh-upd button[data-primary=\"1\"]:hover:not(:disabled){filter:brightness(.93)}",
@@ -5290,6 +5486,15 @@ ${note}${blocks.join("\n")}
5290
5486
  const width = state === "installing" ? 60 : 90;
5291
5487
  return `<div class="dsh-upd-prog" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${width}"><i class="dsh-upd-prog-bar" style="width:${width}%"></i></div><div class="dsh-upd-progtxt">${escapeHtml$3(state === "installing" ? copyText("panel.progress.installing", l) : copyText("panel.progress.verifying", l))}</div>`;
5292
5488
  }
5489
+ function updaterIdentityOf(input) {
5490
+ const parts = updaterPartsOf(input.updater);
5491
+ return parts ? `dsh-plugin-update@${parts.version} (${parts.level})` : null;
5492
+ }
5493
+ function selfUpgradeCommandOf(profileName) {
5494
+ const profile = typeof profileName === "string" ? profileName.trim() : "";
5495
+ if (!profile) return null;
5496
+ return `dsh plugin --profile ${profile} add --save-exact dsh-plugin-update@latest`;
5497
+ }
5293
5498
  function renderUpdatePanelKernel(input, view, lang) {
5294
5499
  const { snapshot, manual, queue, mode, showOthers, pluginId, copyNotice } = input;
5295
5500
  const l = normalizeLangTag(lang ?? input.lang ?? "zh");
@@ -5359,7 +5564,7 @@ ${note}${blocks.join("\n")}
5359
5564
  lang: l,
5360
5565
  truncated: report.truncation
5361
5566
  });
5362
- const fromText = snapshot.installed === false ? copyText("panel.banner.not-installed", l) : String(snapshot.runningVersion ?? "");
5567
+ const fromText = snapshot.installed === false ? copyText("panel.banner.not-installed", l) : snapshot.runningVersion ?? copyText("panel.meta.unknown", l);
5363
5568
  const toText = String(snapshot.latestVersion ?? "");
5364
5569
  const rangeTitle = fromText && toText ? copyText("panel.changelog.heading-range", l, {
5365
5570
  from: fromText,
@@ -5454,9 +5659,20 @@ ${changelogHTML}
5454
5659
  else errLines.push("<div class=\"dsh-upd-copy dsh-upd-copy--empty\" aria-hidden=\"true\"></div>");
5455
5660
  chapters.push(chapterOf(4, errLines.join(""), "", l));
5456
5661
  }
5457
- chapters.push(chapterOf(5, view.showManual && manual ? `<div class="dsh-upd-manual"><div>${escapeHtml$3(copyText("panel.manual.heading", l))}</div><code>${escapeHtml$3(manual)}</code></div>` : `<div class="dsh-upd-manual"><div class="dsh-upd-changelog-neutral">${escapeHtml$3(copyText("panel.manual.absent", l))}</div></div>`, "", l));
5662
+ let manualHtml = view.showManual && manual ? `<div class="dsh-upd-manual"><div>${escapeHtml$3(copyText("panel.manual.heading", l))}</div><code>${escapeHtml$3(manual)}</code></div>` : `<div class="dsh-upd-manual"><div class="dsh-upd-changelog-neutral">${escapeHtml$3(copyText("panel.manual.absent", l))}</div></div>`;
5663
+ const selfParts = updaterPartsOf(input.updater);
5664
+ if (selfParts && selfParts.level === "nested") {
5665
+ const command = selfUpgradeCommandOf(profileName);
5666
+ manualHtml += `<div class="dsh-upd-updater-nested">` + escapeHtml$3(command ? copyText("panel.manual.updater-nested", l, {
5667
+ version: selfParts.version,
5668
+ command
5669
+ }) : copyText("panel.manual.updater-nested-nocmd", l, { version: selfParts.version })) + `</div>`;
5670
+ }
5671
+ const updaterIdentity = updaterIdentityOf(input);
5672
+ if (updaterIdentity && !(showActions && mode === "dialog")) manualHtml += `<div class="dsh-upd-updater-id">${escapeHtml$3(updaterIdentity)}</div>`;
5673
+ chapters.push(chapterOf(5, manualHtml, "", l));
5458
5674
  parts.push("<div class=\"dsh-upd-body\">" + chapters.join("\n") + "</div>");
5459
- if (showActions && mode === "dialog") parts.push("<div class=\"dsh-upd-footer\"><span class=\"dsh-upd-foot-note\">" + escapeHtml$3(copyText("panel.footer.note", l)) + `</span><button type="button" data-action="close-view" title="${escapeHtml$3(copyText("panel.footer.close-title", l))}">${escapeHtml$3(copyText("panel.footer.close", l))}</button></div>`);
5675
+ if (showActions && mode === "dialog") parts.push("<div class=\"dsh-upd-footer\"><span class=\"dsh-upd-foot-note\">" + escapeHtml$3(copyText("panel.footer.note", l)) + "</span>" + (updaterIdentity ? `<span class="dsh-upd-updater-note">${escapeHtml$3(updaterIdentity)}</span>` : "") + `<button type="button" data-action="close-view" title="${escapeHtml$3(copyText("panel.footer.close-title", l))}">${escapeHtml$3(copyText("panel.footer.close", l))}</button></div>`);
5460
5676
  return parts.join("\n");
5461
5677
  }
5462
5678
  function renderUpdatePanelHTML(input, lang) {
@@ -5478,7 +5694,7 @@ ${UPDATE_PANEL_ARCHIVE_CSS}` : UPDATE_PANEL_CSS}</style>
5478
5694
  ${body}`;
5479
5695
  }
5480
5696
  //#endregion
5481
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/entry.js
5697
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/entry.js
5482
5698
  const UPDATE_ENTRY_CSS = [
5483
5699
  ".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)}",
5484
5700
  ".dsh-upd-entry-btn{font:inherit;border:1px solid var(--dsh-update-border,#d1d5db);border-radius:var(--dsh-update-entry-border-radius,6px);",
@@ -5592,7 +5808,7 @@ ${body}`;
5592
5808
  }
5593
5809
  }
5594
5810
  //#endregion
5595
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/panel-batch.js
5811
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/panel-batch.js
5596
5812
  const BATCH_PANEL_POLL = {
5597
5813
  defaultMs: 1500,
5598
5814
  minMs: 250
@@ -5609,12 +5825,17 @@ ${body}`;
5609
5825
  prefsSave: p + ".batchPrefsSave"
5610
5826
  };
5611
5827
  }
5828
+ function noteRestart(counts, row) {
5829
+ if (restartUnregistered(row)) counts.restartUnregistered += 1;
5830
+ else counts.restart += 1;
5831
+ }
5612
5832
  function batchLedgerCounts(rows, inventory, session, compliantDone) {
5613
5833
  const counts = {
5614
5834
  updatable: 0,
5615
5835
  installing: 0,
5616
5836
  pending: 0,
5617
5837
  restart: 0,
5838
+ restartUnregistered: 0,
5618
5839
  failed: 0,
5619
5840
  skipped: 0,
5620
5841
  settled: 0
@@ -5623,18 +5844,18 @@ ${body}`;
5623
5844
  const phase = asBatchPhase(row.phase);
5624
5845
  const doneRestart = phase === "failed" ? compliantDone?.get(row.key) : void 0;
5625
5846
  if (doneRestart !== void 0) {
5626
- if (doneRestart) counts.restart += 1;
5847
+ if (doneRestart) noteRestart(counts, row);
5627
5848
  else counts.settled += 1;
5628
5849
  } else if (isQueueBusyRow(row)) counts.updatable += 1;
5629
5850
  else if (phase === "failed") {
5630
- if (row.error === "pending-restart") counts.restart += 1;
5851
+ if (row.error === "pending-restart") noteRestart(counts, row);
5631
5852
  else counts.failed += 1;
5632
5853
  } else if (phase === "installing") counts.installing += 1;
5633
5854
  else if (phase === "ready") counts.updatable += 1;
5634
5855
  else if (phase === "pending") counts[isInUnfinishedRound(session, row.key) ? "pending" : ledgerKnowledgeBucket(knowledgeEntryOf(inventory, row.key))] += 1;
5635
5856
  else if (phase === "checking") counts.pending += 1;
5636
5857
  else if (phase === "skipped") counts.skipped += 1;
5637
- else if (row.restartRequired === true) counts.restart += 1;
5858
+ else if (row.restartRequired === true) noteRestart(counts, row);
5638
5859
  else counts[worldUpdateVersion(row, knowledgeEntryOf(inventory, row.key), sessionUpdatedAtOf(session, row.key)) ? "updatable" : "settled"] += 1;
5639
5860
  }
5640
5861
  return counts;
@@ -5652,6 +5873,7 @@ ${body}`;
5652
5873
  if (counts.installing > 0) parts.push(batchText("batch.summary.installing", l, { n: String(counts.installing) }));
5653
5874
  if (counts.pending > 0) parts.push(batchText("batch.summary.pending", l, { n: String(counts.pending) }));
5654
5875
  if (counts.restart > 0) parts.push(batchText("batch.summary.restart", l, { n: String(counts.restart) }));
5876
+ if (counts.restartUnregistered > 0) parts.push(batchText("batch.summary.restart-unregistered", l, { n: String(counts.restartUnregistered) }));
5655
5877
  if (counts.failed > 0) parts.push(batchText("batch.summary.failed", l, { n: String(counts.failed) }));
5656
5878
  if (counts.skipped > 0) parts.push(batchText("batch.summary.skipped", l, { n: String(counts.skipped) }));
5657
5879
  if (counts.settled > 0) parts.push(batchText("batch.summary.settled", l, { n: String(counts.settled) }));
@@ -5748,6 +5970,10 @@ ${body}`;
5748
5970
  if (entries === null) return 0;
5749
5971
  return entries.filter(isUnfinishedEntry).length;
5750
5972
  }
5973
+ function restartUnregistered(row) {
5974
+ const snapshot = row.snapshot;
5975
+ return !!snapshot && typeof snapshot === "object" && snapshot.registered === false;
5976
+ }
5751
5977
  function batchRowStatus(row, skippedVersion, lang) {
5752
5978
  const l = langOf(lang);
5753
5979
  const skipped = typeof skippedVersion === "string" && skippedVersion ? skippedVersion : null;
@@ -5758,7 +5984,9 @@ ${body}`;
5758
5984
  case "ready": return row.targetVersion ? batchText("batch.row.cta-version", l, { version: row.targetVersion }) : batchText("batch.row.cta-generic", l);
5759
5985
  case "installing": return batchText("batch.row.installing", l);
5760
5986
  case "current": return batchText("batch.row.current", l);
5761
- case "done": return row.restartRequired === true ? batchText("batch.row.done-restart", l) : batchText("batch.row.done", l);
5987
+ case "done":
5988
+ if (row.restartRequired !== true) return batchText("batch.row.done", l);
5989
+ return restartUnregistered(row) ? batchText("batch.row.done-restart-unregistered", l) : batchText("batch.row.done-restart", l);
5762
5990
  case "failed": return isCheckSideFailureCode(jobFailureOf(row)?.code ?? (typeof row.error === "string" && row.error ? row.error : null)) ? batchText("batch.row.failed", l) : batchText("batch.row.failed-retry", l);
5763
5991
  case "skipped": return batchText("batch.row.skipped-idle", l);
5764
5992
  default: return batchText("batch.row.unknown", l);
@@ -6014,6 +6242,7 @@ ${body}`;
6014
6242
  if (counts.failed > 0) return batchText("batch.hint.failed", l, { n: String(counts.failed) });
6015
6243
  if (counts.updatable > 0) return batchText("batch.hint.updatable", l, { n: String(counts.updatable) });
6016
6244
  if (counts.restart > 0) return batchText("batch.hint.restart", l, { n: String(counts.restart) });
6245
+ if (counts.restartUnregistered > 0) return batchText("batch.hint.restart-unregistered", l, { n: String(counts.restartUnregistered) });
6017
6246
  if (counts.pending > 0) return batchText("batch.hint.pending", l, { n: String(counts.pending) });
6018
6247
  return batchText("batch.hint.done", l);
6019
6248
  }
@@ -6023,7 +6252,7 @@ ${body}`;
6023
6252
  text,
6024
6253
  tone: "red"
6025
6254
  };
6026
- if (counts.installing > 0 || counts.restart > 0) return {
6255
+ if (counts.installing > 0 || counts.restart > 0 || counts.restartUnregistered > 0) return {
6027
6256
  text,
6028
6257
  tone: "yellow"
6029
6258
  };
@@ -6075,7 +6304,7 @@ ${body}`;
6075
6304
  if (act) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$2(act) + "</div>");
6076
6305
  }
6077
6306
  const pendingRestartRow = (row) => asBatchPhase(row.phase) === "failed" && row.error === "pending-restart";
6078
- const failed = rows.filter((row) => asBatchPhase(row.phase) === "failed" && !isQueueBusyRow(row) && !pendingRestartRow(row) && !done.has(row.key));
6307
+ const failed = batchFailedRows(rows);
6079
6308
  if (failed.length > 0) {
6080
6309
  const lines = failed.map((row) => {
6081
6310
  const code = row.error || "install-failed";
@@ -6083,7 +6312,8 @@ ${body}`;
6083
6312
  return "<div>" + escapeHtml$2(titleOf(row, titles)) + ":<code>" + escapeHtml$2(code) + "</code> " + escapeHtml$2(copy?.zh ?? failureCopy("unknown", l)?.zh ?? "") + "</div>";
6084
6313
  }).join("");
6085
6314
  const failedAct = batchText("batch.banner.failed-action", l);
6086
- parts.push("<div class=\"dsh-upd-banner\" data-kind=\"failed\" data-mini=\"阻\" role=\"status\"><div><span class=\"dsh-upd-sealmini\" aria-hidden=\"true\">阻</span><strong>" + escapeHtml$2(batchText("batch.banner.failed-title", l, { n: String(failed.length) })) + "</strong></div><div class=\"dsh-upd-blist\">" + lines + "</div></div>");
6315
+ const manualAbsent = batchFailedManualText(failed, l, titles).commands === 0;
6316
+ parts.push("<div class=\"dsh-upd-banner\" data-kind=\"failed\" data-mini=\"阻\" role=\"status\"><div><span class=\"dsh-upd-sealmini\" aria-hidden=\"true\">阻</span><strong>" + escapeHtml$2(batchText("batch.banner.failed-title", l, { n: String(failed.length) })) + "</strong></div><div class=\"dsh-upd-blist\">" + lines + "</div><div class=\"dsh-upd-browline\"><span class=\"dsh-upd-bcopy\"><button type=\"button\" data-act=\"copy-all-diag\">" + escapeHtml$2(batchText("batch.row-action.copy-diag", l)) + "</button><button type=\"button\" data-act=\"copy-all-manual\"" + (manualAbsent ? " disabled title=\"" + escapeHtml$2(batchText("panel.manual.absent", l)) + "\"" : "") + ">" + escapeHtml$2(batchText("batch.row-action.copy-manual", l)) + "</button></span></div></div>");
6087
6317
  if (failedAct) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$2(failedAct) + "</div>");
6088
6318
  }
6089
6319
  if (confirmList) parts.push("<div class=\"dsh-upd-banner\" data-kind=\"update\" role=\"status\"><div><strong>" + escapeHtml$2(batchText("batch.banner.compliant-confirm", l, { list: confirmList })) + "</strong></div><div class=\"dsh-upd-browline\"><span class=\"dsh-upd-blist\">" + escapeHtml$2(confirmList) + "</span><button type=\"button\" data-act=\"batch-fallback-confirm\" data-primary=\"1\"" + (compliantBusy ? " disabled" : "") + ">" + escapeHtml$2(batchText("batch.action.install-compliant-confirm", l, { n: String(confirmCount) })) + "</button></div></div>");
@@ -6104,8 +6334,16 @@ ${body}`;
6104
6334
  const restart = rows.filter((row) => row.restartRequired === true || pendingRestartRow(row) || done.get(row.key)?.needsRestart === true);
6105
6335
  if (restart.length > 0) {
6106
6336
  const restartAct = batchText("batch.banner.restart-action", l);
6107
- parts.push("<div class=\"dsh-upd-banner\" data-kind=\"restart\" role=\"status\"><div><strong>" + escapeHtml$2(batchText("batch.banner.restart-title", l, { n: String(restart.length) })) + "</strong></div><div class=\"dsh-upd-browline\"><span class=\"dsh-upd-blist\">" + restart.map((row) => escapeHtml$2(titleOf(row, titles))).join("、") + "</span><button type=\"button\" data-act=\"restart\">" + escapeHtml$2(batchText("batch.banner.restart-button", l)) + "</button></div></div>");
6108
- if (restartAct) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$2(restartAct) + "</div>");
6337
+ const unregistered = restart.filter(restartUnregistered);
6338
+ const registered = restart.filter((row) => !restartUnregistered(row));
6339
+ const title = unregistered.length === 0 ? batchText("batch.banner.restart-title", l, { n: String(restart.length) }) : registered.length === 0 ? batchText("batch.banner.restart-unregistered-title", l) : batchText("batch.banner.restart-partial-title", l, {
6340
+ n: String(registered.length),
6341
+ m: String(unregistered.length)
6342
+ });
6343
+ const names = restart.map((row) => escapeHtml$2(titleOf(row, titles)) + (restartUnregistered(row) ? escapeHtml$2(batchText("batch.row.unregistered-suffix", l)) : "")).join("、");
6344
+ parts.push("<div class=\"dsh-upd-banner\" data-kind=\"restart\" role=\"status\"><div><strong>" + escapeHtml$2(title) + "</strong></div><div class=\"dsh-upd-browline\"><span class=\"dsh-upd-blist\">" + names + "</span>" + (registered.length > 0 ? "<button type=\"button\" data-act=\"restart\">" + escapeHtml$2(batchText("batch.banner.restart-button", l)) + "</button>" : "") + "</div></div>");
6345
+ if (registered.length > 0 && restartAct) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$2(restartAct) + "</div>");
6346
+ if (unregistered.length > 0) parts.push("<div class=\"dsh-upd-banner-sub\">" + escapeHtml$2(batchText("batch.banner.restart-unregistered-hint", l)) + "</div>");
6109
6347
  }
6110
6348
  return parts.join("");
6111
6349
  }
@@ -6143,7 +6381,7 @@ ${body}`;
6143
6381
  actions.push("<button type=\"button\" data-act=\"row-install\" data-key=\"" + keyAttr + "\"" + off + ">" + escapeHtml$2(ctx.busy ? batchText("batch.row-action.queue", ctx.lang) : batchText("batch.row-action.retry", ctx.lang)) + "</button>");
6144
6382
  if (!queued && rowDone === null) actions.push(rowFallbackButtonHTML(row, ctx));
6145
6383
  }
6146
- if (row.restartRequired === true) actions.push("<button type=\"button\" data-act=\"restart\" data-key=\"" + keyAttr + "\">" + escapeHtml$2(batchText("batch.row-action.restart", ctx.lang)) + "</button>");
6384
+ if (row.restartRequired === true && !restartUnregistered(row)) actions.push("<button type=\"button\" data-act=\"restart\" data-key=\"" + keyAttr + "\">" + escapeHtml$2(batchText("batch.row-action.restart", ctx.lang)) + "</button>");
6147
6385
  actions.push("<button type=\"button\" data-act=\"toggle-details\" data-key=\"" + keyAttr + "\">" + escapeHtml$2(ctx.expanded ? batchText("batch.row-action.hide-detail", ctx.lang) : batchText("batch.row-action.show-detail", ctx.lang)) + "</button>");
6148
6386
  const failLine = phase === "failed" && !queued ? rowDone !== null ? (() => {
6149
6387
  const vars = {
@@ -6276,6 +6514,8 @@ ${body}`;
6276
6514
  ".dsh-upd-browline{display:flex;align-items:center;gap:10px;flex-wrap:wrap}",
6277
6515
  ".dsh-upd-browline>.dsh-upd-blist{flex:1 1 auto;min-width:0;text-align:left;margin:0}",
6278
6516
  ".dsh-upd-browline>button{flex:none;margin:0;margin-left:auto}",
6517
+ ".dsh-upd-browline>.dsh-upd-bcopy{display:inline-flex;align-items:center;gap:10px;flex:none;margin-left:auto}",
6518
+ ".dsh-upd-browline>.dsh-upd-bcopy>button{flex:none;margin:0}",
6279
6519
  ".dsh-upd-batch-ledger{margin:8px 0 0;font-size:var(--dsh-update-panel-log-font-size,13px);opacity:.85}",
6280
6520
  ".dsh-upd-batch-more{margin-top:6px}",
6281
6521
  ".dsh-upd-batch-more button{font-size:12px}",
@@ -6450,12 +6690,23 @@ ${body}`;
6450
6690
  return null;
6451
6691
  }
6452
6692
  }
6693
+ function batchFailedRows(rows) {
6694
+ const out = [];
6695
+ for (const row of rows) {
6696
+ if (asBatchPhase(row.phase) !== "failed") continue;
6697
+ if (isQueueBusyRow(row)) continue;
6698
+ if (row.error === "pending-restart") continue;
6699
+ if (compliantInstalledOf(row) !== null) continue;
6700
+ out.push(row);
6701
+ }
6702
+ return out;
6703
+ }
6453
6704
  function asBatchPhase(value) {
6454
6705
  return typeof value === "string" && BATCH_PHASES.includes(value) ? value : "pending";
6455
6706
  }
6456
6707
  function asSnapshotLike(value) {
6457
6708
  if (!isObject$2(value)) return null;
6458
- if (typeof value["runningVersion"] !== "string") return null;
6709
+ if (value["runningVersion"] !== null && typeof value["runningVersion"] !== "string") return null;
6459
6710
  if (typeof value["canInstall"] !== "boolean") return null;
6460
6711
  return value;
6461
6712
  }
@@ -6562,6 +6813,27 @@ ${body}`;
6562
6813
  lang: lang ?? "zh"
6563
6814
  });
6564
6815
  }
6816
+ function batchFailedDiagText(rows, lang) {
6817
+ return batchFailedRows(rows).map((row) => diagTextOf(row, lang)).join("\n\n");
6818
+ }
6819
+ function batchFailedManualText(rows, lang, titles = {}) {
6820
+ const l = langOf(lang);
6821
+ const lines = [];
6822
+ let commands = 0;
6823
+ for (const row of batchFailedRows(rows)) {
6824
+ const manual = typeof row.manual === "string" ? row.manual : "";
6825
+ if (manual) {
6826
+ lines.push(manual);
6827
+ commands += 1;
6828
+ continue;
6829
+ }
6830
+ lines.push("# " + titleOf(row, titles) + ":" + batchText("panel.manual.absent", l));
6831
+ }
6832
+ return {
6833
+ text: lines.join("\n"),
6834
+ commands
6835
+ };
6836
+ }
6565
6837
  function isBusyReply(reply) {
6566
6838
  if (!isObject$2(reply) || reply["ok"] === true) return false;
6567
6839
  const kind = typeof reply["errorKind"] === "string" ? reply["errorKind"] : "";
@@ -7299,6 +7571,19 @@ ${body}`;
7299
7571
  await copyWith(diagTextOf(row, currentLang()), batchText("batch.toast.copy-diag-ok", currentLang()), row.key);
7300
7572
  return;
7301
7573
  }
7574
+ case "copy-all-diag": {
7575
+ const failed = batchFailedRows(rows);
7576
+ if (failed.length === 0) return;
7577
+ await copyWith(batchFailedDiagText(rows, currentLang()), batchText("batch.toast.copy-all-diag-ok", currentLang(), { n: String(failed.length) }), null);
7578
+ return;
7579
+ }
7580
+ case "copy-all-manual": {
7581
+ if (batchFailedRows(rows).length === 0) return;
7582
+ const all = batchFailedManualText(rows, currentLang(), titles);
7583
+ if (all.commands === 0) return;
7584
+ await copyWith(all.text, batchText("batch.toast.copy-all-manual-ok", currentLang(), { n: String(all.commands) }), null);
7585
+ return;
7586
+ }
7302
7587
  case "row-fallback": {
7303
7588
  const row = typeof key === "string" && key ? rowOfKey(key) : null;
7304
7589
  if (!row) return;
@@ -7684,7 +7969,7 @@ ${body}`;
7684
7969
  };
7685
7970
  }
7686
7971
  //#endregion
7687
- //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.7/node_modules/dsh-plugin-update/dist/entry-batch.js
7972
+ //#region ../../node_modules/.pnpm/dsh-plugin-update@0.18.24/node_modules/dsh-plugin-update/dist/entry-batch.js
7688
7973
  function isObject$1(value) {
7689
7974
  return !!value && typeof value === "object" && !Array.isArray(value);
7690
7975
  }
@@ -7714,13 +7999,13 @@ ${body}`;
7714
7999
  if (!Array.isArray(rows) || rows.length === 0) kind = state?.error ? "failed" : "idle";
7715
8000
  else if (counts.installing > 0) kind = "busy";
7716
8001
  else if (counts.failed > 0) kind = "failed";
7717
- else if (counts.restart > 0) kind = "restart";
8002
+ else if (counts.restart > 0 || counts.restartUnregistered > 0) kind = "restart";
7718
8003
  else if (counts.updatable > 0) kind = "update";
7719
8004
  else kind = "idle";
7720
8005
  if (kind !== "busy" && state?.error) {
7721
8006
  if (Array.isArray(rows) && rows.length > 0 && counts.failed === 0 && counts.installing === 0) kind = "failed";
7722
8007
  }
7723
- const hasUpdate = counts.installing > 0 || counts.failed > 0 || counts.restart > 0 || counts.updatable > 0;
8008
+ const hasUpdate = counts.installing > 0 || counts.failed > 0 || counts.restart > 0 || counts.restartUnregistered > 0 || counts.updatable > 0;
7724
8009
  const l = lang !== void 0 && lang !== null ? normalizeLangTag(lang) : resolveLang();
7725
8010
  let label;
7726
8011
  switch (kind) {
@@ -7731,7 +8016,10 @@ ${body}`;
7731
8016
  label = counts.failed > 0 ? copyText("batch-entry.label.failed", l, { count: String(counts.failed) }) : copyText("entry.label.failed", l);
7732
8017
  break;
7733
8018
  case "restart":
7734
- label = copyText("batch-entry.label.restart", l, { count: String(counts.restart) });
8019
+ label = counts.restartUnregistered > 0 ? counts.restart > 0 ? copyText("batch-entry.label.restart-mixed", l, {
8020
+ count: String(counts.restart),
8021
+ unregistered: String(counts.restartUnregistered)
8022
+ }) : copyText("batch-entry.label.restart-unregistered", l, { count: String(counts.restartUnregistered) }) : copyText("batch-entry.label.restart", l, { count: String(counts.restart) });
7735
8023
  break;
7736
8024
  case "update":
7737
8025
  label = copyText("batch-entry.label.update", l, { count: String(counts.updatable) });
@@ -7745,6 +8033,7 @@ ${body}`;
7745
8033
  installing: counts.installing,
7746
8034
  pending: counts.pending,
7747
8035
  restart: counts.restart,
8036
+ restartUnregistered: counts.restartUnregistered,
7748
8037
  failed: counts.failed,
7749
8038
  skipped: counts.skipped,
7750
8039
  settled: counts.settled,
@@ -7757,7 +8046,9 @@ ${body}`;
7757
8046
  switch (s.kind) {
7758
8047
  case "busy": return "batch-entry.label.busy";
7759
8048
  case "failed": return s.failed > 0 ? "batch-entry.label.failed" : "entry.label.failed";
7760
- case "restart": return "batch-entry.label.restart";
8049
+ case "restart":
8050
+ if (s.restartUnregistered > 0) return s.restart > 0 ? "batch-entry.label.restart-mixed" : "batch-entry.label.restart-unregistered";
8051
+ return "batch-entry.label.restart";
7761
8052
  case "update": return "batch-entry.label.update";
7762
8053
  default: return "batch-entry.label.idle";
7763
8054
  }
@@ -7766,7 +8057,12 @@ ${body}`;
7766
8057
  const s = batchEntrySummary(state);
7767
8058
  switch (s.kind) {
7768
8059
  case "update": return { count: String(s.updatable) };
7769
- case "restart": return { count: String(s.restart) };
8060
+ case "restart":
8061
+ if (s.restartUnregistered > 0) return s.restart > 0 ? {
8062
+ count: String(s.restart),
8063
+ unregistered: String(s.restartUnregistered)
8064
+ } : { count: String(s.restartUnregistered) };
8065
+ return { count: String(s.restart) };
7770
8066
  case "failed": return s.failed > 0 ? { count: String(s.failed) } : {};
7771
8067
  default: return {};
7772
8068
  }
@@ -7971,6 +8267,7 @@ ${body}`;
7971
8267
  installing: summary.installing,
7972
8268
  pending: summary.pending,
7973
8269
  restart: summary.restart,
8270
+ restartUnregistered: summary.restartUnregistered,
7974
8271
  failed: summary.failed,
7975
8272
  skipped: summary.skipped,
7976
8273
  settled: summary.settled
@@ -11844,7 +12141,7 @@ ${body}`;
11844
12141
  }, 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)))));
11845
12142
  }
11846
12143
  /** 版本胶囊那一行字:只在这里拼一次,屏上与用例读的是同一串。 */
11847
- const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.67";
12144
+ const MANAGER_VERSION_TEXT = "dsh-life-pack · 0.3.69";
11848
12145
  /** 右下角那本书离面板两沿的距离:用户口径「一直处于面板右下角、不随列表滑动消失」
11849
12146
  * ⇒ sticky 吸附(面板相对,视口多大都落在面板角上);INSET=右沿,BOTTOM=底沿。 */
11850
12147
  const MANUAL_ENTRY_INSET = 16;