@xrxs-ai/dsh-xrxs-plugins-store 0.2.3 → 0.2.5

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/lib/client.js CHANGED
@@ -2208,7 +2208,7 @@ function runInstallOnce(args, retried) {
2208
2208
  }
2209
2209
  args.onToast(
2210
2210
  "success",
2211
- `${args.name}@${args.version} \u5B89\u88C5\u5B8C\u6210,\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u542F\u5E94\u7528\u540E\u751F\u6548`
2211
+ `${args.name}@${args.version} ${args.verb ?? "\u5B89\u88C5"}\u5B8C\u6210,\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u542F\u5E94\u7528\u540E\u751F\u6548`
2212
2212
  );
2213
2213
  return { applied: true };
2214
2214
  }).catch(async (error) => {
@@ -2216,7 +2216,7 @@ function runInstallOnce(args, retried) {
2216
2216
  const approved = await args.onBuildBlocked(error.pendingBuilds ?? []);
2217
2217
  if (approved) return runInstallOnce(args, true);
2218
2218
  }
2219
- notice({ title: `\u5B89\u88C5\u5931\u8D25:${args.name}@${args.version}`, body: messageOf(error) });
2219
+ notice({ title: `${args.verb ?? "\u5B89\u88C5"}\u5931\u8D25:${args.name}@${args.version}`, body: messageOf(error) });
2220
2220
  return { applied: false };
2221
2221
  });
2222
2222
  }
@@ -2556,15 +2556,20 @@ function InstallButton(props) {
2556
2556
  const [buildConfirm, setBuildConfirm] = (0, import_react6.useState)(null);
2557
2557
  const [approving, setApproving] = (0, import_react6.useState)(false);
2558
2558
  const compat = checkCompat(props.compatRange, props.dshVersion);
2559
+ const verb = props.installed?.updateAvailable === true ? "\u66F4\u65B0" : "\u5B89\u88C5";
2560
+ const variant = verb === "\u66F4\u65B0" ? "update" : "primary";
2561
+ if (props.installed !== void 0 && !props.installed.updateAvailable) {
2562
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "xps-mk-install", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { size: props.size ?? "medium", variant: "primary", disabled: true, title: "\u5DF2\u5B89\u88C5\u6700\u65B0\u7248\u672C,\u91CD\u88C5\u540C\u7248\u672C\u4E0D\u4F1A\u5237\u65B0", children: "\u5DF2\u5B89\u88C5" }) });
2563
+ }
2559
2564
  if (compat.ok === false) {
2560
2565
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "xps-mk-install", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2561
2566
  Button,
2562
2567
  {
2563
2568
  size: props.size ?? "medium",
2564
- variant: "primary",
2569
+ variant,
2565
2570
  disabled: true,
2566
2571
  title: compat.reason ?? "\u4E0E\u672C\u673A dsh \u7248\u672C\u4E0D\u517C\u5BB9",
2567
- children: "\u5B89\u88C5"
2572
+ children: verb
2568
2573
  }
2569
2574
  ) });
2570
2575
  }
@@ -2574,9 +2579,12 @@ function InstallButton(props) {
2574
2579
  name: props.pluginName,
2575
2580
  version: props.version,
2576
2581
  sourceType: props.sourceType,
2582
+ verb,
2577
2583
  onToast: props.onToast,
2578
2584
  onNotice: setNotice,
2579
2585
  onBuildBlocked: (packages) => new Promise((resolve) => setBuildConfirm({ packages, resolve }))
2586
+ }).then((result) => {
2587
+ if (result.applied) props.onInstalled?.();
2580
2588
  }).finally(() => setPhase("idle"));
2581
2589
  };
2582
2590
  const handleBuildApprove = () => {
@@ -2595,15 +2603,18 @@ function InstallButton(props) {
2595
2603
  };
2596
2604
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
2597
2605
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "xps-mk-install", onClick: (e) => e.stopPropagation(), children: phase === "confirm" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "xps-mk-confirm", children: [
2598
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { size: "small", variant: "primary", onClick: doInstall, title: `\u786E\u8BA4\u5B89\u88C5 ${props.pluginName}@${props.version}`, children: "\u786E\u8BA4\u5B89\u88C5" }),
2599
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { size: "small", variant: "ghost", onClick: () => setPhase("idle"), title: "\u53D6\u6D88\u5B89\u88C5", children: "\u53D6\u6D88" })
2606
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Button, { size: "small", variant, onClick: doInstall, title: `\u786E\u8BA4${verb} ${props.pluginName}@${props.version}`, children: [
2607
+ "\u786E\u8BA4",
2608
+ verb
2609
+ ] }),
2610
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Button, { size: "small", variant: "ghost", onClick: () => setPhase("idle"), title: `\u53D6\u6D88${verb}`, children: "\u53D6\u6D88" })
2600
2611
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2601
2612
  Button,
2602
2613
  {
2603
2614
  size: props.size ?? "medium",
2604
- variant: "primary",
2615
+ variant,
2605
2616
  disabled: phase === "installing",
2606
- title: phase === "installing" ? "\u5B89\u88C5\u4E2D\u2026" : compat.ok === null ? "\u517C\u5BB9\u6027\u672A\u77E5:\u65E0\u6CD5\u8BFB\u53D6\u672C\u673A dsh \u7248\u672C" : `\u5B89\u88C5 ${props.pluginName}@${props.version}`,
2617
+ title: phase === "installing" ? `${verb}\u4E2D\u2026` : compat.ok === null ? "\u517C\u5BB9\u6027\u672A\u77E5:\u65E0\u6CD5\u8BFB\u53D6\u672C\u673A dsh \u7248\u672C" : `${verb} ${props.pluginName}@${props.version}`,
2607
2618
  onClick: () => {
2608
2619
  if (compat.ok === null) {
2609
2620
  props.onToast("info", "\u65E0\u6CD5\u786E\u8BA4\u4E0E\u672C\u673A dsh \u7248\u672C\u7684\u517C\u5BB9\u6027");
@@ -2611,7 +2622,7 @@ function InstallButton(props) {
2611
2622
  }
2612
2623
  setPhase("confirm");
2613
2624
  },
2614
- children: phase === "installing" ? "\u5B89\u88C5\u4E2D\u2026" : "\u5B89\u88C5"
2625
+ children: phase === "installing" ? `${verb}\u4E2D\u2026` : verb
2615
2626
  }
2616
2627
  ) }),
2617
2628
  notice !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -2728,6 +2739,8 @@ function PluginRow(props) {
2728
2739
  compatRange: p.compatRange,
2729
2740
  sourceType: p.sourceType,
2730
2741
  dshVersion: props.dshVersion,
2742
+ installed,
2743
+ onInstalled: props.onInstalled,
2731
2744
  size: "small",
2732
2745
  onToast: props.onToast
2733
2746
  }
@@ -2966,6 +2979,7 @@ function MarketPage(props) {
2966
2979
  plugin: p,
2967
2980
  dshVersion,
2968
2981
  installed: installedMap.get(p.name),
2982
+ onInstalled: () => setReloadFlag((flag) => flag + 1),
2969
2983
  onOpen: props.onOpenDetail ?? (() => {
2970
2984
  }),
2971
2985
  onToast: toasts.push
@@ -3217,7 +3231,14 @@ function PluginDetailPage(props) {
3217
3231
  const [selectedVersion, setSelectedVersion] = (0, import_react8.useState)(null);
3218
3232
  const [reloadFlag, setReloadFlag] = (0, import_react8.useState)(0);
3219
3233
  const [dshVersion, setDshVersion] = (0, import_react8.useState)(null);
3234
+ const [installed, setInstalled] = (0, import_react8.useState)(null);
3220
3235
  const toasts = useToasts();
3236
+ const loadInstalled = (0, import_react8.useCallback)(
3237
+ (name) => {
3238
+ getInstalled().then((list) => setInstalled(list.find((item) => item.name === name) ?? null)).catch(() => setInstalled(null));
3239
+ },
3240
+ []
3241
+ );
3221
3242
  (0, import_react8.useEffect)(() => {
3222
3243
  let alive = true;
3223
3244
  getHostInfo().then((info) => {
@@ -3233,6 +3254,8 @@ function PluginDetailPage(props) {
3233
3254
  setStatus("loading");
3234
3255
  setDetail(null);
3235
3256
  setSelectedVersion(null);
3257
+ setInstalled(null);
3258
+ if (pluginId !== "") loadInstalled(pluginId);
3236
3259
  getPluginDetail(pluginId).then((d) => {
3237
3260
  if (!alive) return;
3238
3261
  if (d === null) {
@@ -3248,7 +3271,7 @@ function PluginDetailPage(props) {
3248
3271
  return () => {
3249
3272
  alive = false;
3250
3273
  };
3251
- }, [pluginId, reloadFlag]);
3274
+ }, [pluginId, reloadFlag, loadInstalled]);
3252
3275
  const backButton = /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "xps-mk-back", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { size: "small", variant: "ghost", onClick: () => props.onBack?.(), title: "\u8FD4\u56DE\u5E02\u573A\u5217\u8868", children: "\u2190 \u8FD4\u56DE\u5E02\u573A" }) });
3253
3276
  if (status === "loading") {
3254
3277
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "xps-mk-detail", children: [
@@ -3327,6 +3350,8 @@ function PluginDetailPage(props) {
3327
3350
  compatRange: displayCompatRange,
3328
3351
  sourceType: detail.sourceType,
3329
3352
  dshVersion,
3353
+ installed: installed ?? void 0,
3354
+ onInstalled: () => loadInstalled(detail.name),
3330
3355
  onToast: toasts.push
3331
3356
  }
3332
3357
  )
@@ -3380,7 +3405,7 @@ function PluginDetailPage(props) {
3380
3405
  }
3381
3406
 
3382
3407
  // src/client/theme.css
3383
- var theme_default = "/* \u85AA\u4EBA\u85AA\u4E8B\u5E02\u573A client \u4E3B\u9898:\u5BF9\u6807\u5BBF\u4E3B\u5B98\u65B9\u63D2\u4EF6\u7BA1\u7406\u5668(PluginManagerPage.module.css)\u89C6\u89C9\u8BED\u8A00,\n * \u5168\u90E8\u8D70\u5BBF\u4E3B --dsw-alias-* token(\u5E26\u515C\u5E95\u503C,token \u7F3A\u5931\u65F6\u53EF\u72EC\u7ACB\u9884\u89C8)\u3002 */\n\n/* ---------- \u9875\u9762\u9AA8\u67B6 ---------- */\n\n.xps-app {\n display: flex;\n width: 100%;\n height: 100%;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n color: var(--dsw-alias-label-primary, #1f2329);\n font-family: inherit;\n}\n\n/* \u5DE6\u4FA7\u4E8C\u7EA7\u5BFC\u822A(B \xB7 \u56FE\u6807\u5C45\u4E0A\u84DD\u8C03\u7EC6\u7EBF\u98CE:\u5706\u89D2\u5757 r10,\u9009\u4E2D\u6D45\u84DD\u5E95+\u54C1\u724C\u84DD\u5B57) */\n.xps-nav {\n flex: none;\n width: 92px;\n box-sizing: border-box;\n padding: 16px 10px;\n display: flex;\n flex-direction: column;\n gap: 3px;\n border-right: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n}\n\n.xps-nav-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 3px;\n padding: 9px 0 7px;\n border: none;\n border-radius: 10px;\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary, #646a73);\n font-family: inherit;\n font-size: 12px;\n line-height: 18px;\n}\n\n.xps-nav-item:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(0, 0, 0, 0.04));\n}\n\n.xps-nav-item-active,\n.xps-nav-item-active:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n color: var(--dsw-alias-brand-primary, #3370ff);\n font-weight: 600;\n}\n\n.xps-nav-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 0;\n}\n\n.xps-nav-label {\n white-space: nowrap;\n}\n\n/* \u5185\u5BB9\u533A:\u5B98\u65B9\u9875\u540C\u6B3E\u5C45\u4E2D\u5217(28px \u9876 / clamp \u4FA7 / 48px \u5E95,960 \u4E0A\u9650) */\n.xps-content {\n flex: 1;\n min-width: 0;\n overflow: auto;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 28px clamp(24px, 4vw, 48px) 48px;\n}\n\n.xps-content > * {\n width: 100%;\n max-width: 960px;\n box-sizing: border-box;\n}\n\n/* \u9875\u5934:flex space-between,\u6807\u9898 20/28/500,\u526F\u9898 13/20 secondary */\n.xps-page-head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.xps-page-title {\n margin: 0;\n font-size: 20px;\n line-height: 28px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u6807\u9898\u884C\u5185\u6302\u5FBD\u6807(\u8BA1\u6570\u7B49\u72B6\u6001\u4FE1\u606F\u8DDF\u968F\u6807\u9898,\u4E0D\u6DF7\u8FDB\u53F3\u4E0A\u89D2\u64CD\u4F5C\u533A) */\n.xps-title-with-badges {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.xps-page-intro {\n margin: 4px 0 0;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-page-actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* \u533A\u5757\u9898 14/22/500 */\n.xps-section-title {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* ---------- \u6587\u5B57\u8272\u9636\u5DE5\u5177\u7C7B ---------- */\n\n.xps-text-secondary {\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n/* \u8BF4\u660E/\u8BA1\u6570:12/18 tertiary */\n.xps-text-caption {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u5305\u540D/\u7248\u672C\u53F7\u7B49 mono */\n.xps-mono {\n font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n}\n\n/* ---------- \u6309\u94AE(\u80F6\u56CA) ---------- */\n\n.xps-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 32px;\n box-sizing: border-box;\n padding: 0 14px;\n border-radius: 16px;\n border: 0.5px solid var(--dsw-alias-border-l3, #d0d3d9);\n background: transparent;\n color: var(--dsw-alias-label-primary, #1f2329);\n font-family: inherit;\n font-size: 13px;\n line-height: 20px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.xps-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n}\n\n.xps-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* \u4E3B\u6309\u94AE(B \u65B9\u5411\u8BC6\u522B\u8272):\u5B9E\u5FC3\u54C1\u724C\u84DD + \u767D\u5B57,hover \u52A0\u6DF1 */\n.xps-btn-primary {\n background: var(--dsw-alias-brand-primary, #3370ff);\n border-color: transparent;\n color: var(--dsw-alias-label-primary-foreground, #ffffff);\n}\n\n.xps-btn-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 85%, #000000));\n}\n\n/* \u63CF\u8FB9\u4E3B\u6309\u94AE(\u5DF2\u5B89\u88C5/\u66F4\u65B0\u6001):\u54C1\u724C\u84DD\u63CF\u8FB9 + \u84DD\u5B57\u900F\u660E\u5E95 */\n.xps-btn-outline {\n border: 1px solid var(--dsw-alias-brand-primary, #3370ff);\n background: transparent;\n color: var(--dsw-alias-brand-primary, #3370ff);\n}\n\n.xps-btn-outline:hover:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 8%, transparent);\n}\n\n/* \u5371\u9669\u6309\u94AE:\u590D\u7528\u6B21\u6309\u94AE,\u7EA2\u5B57 + 30% \u7EA2\u6846,hover \u6362\u7EA2 wash */\n.xps-btn-danger {\n color: var(--dsw-alias-state-error-primary, #d83931);\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n}\n\n.xps-btn-danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 8%, transparent);\n}\n\n.xps-btn-ghost {\n border-color: transparent;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-btn-ghost:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-btn-sm {\n height: 26px;\n padding: 0 10px;\n font-size: 12px;\n line-height: 18px;\n border-radius: 13px;\n}\n\n/* \u56FE\u6807\u6309\u94AE:28\xD728 \u5168\u5706 */\n/* \u56FE\u6807\u6309\u94AE:\u4E0E .xps-btn \u540C\u9AD8(32px)\u3001\u540C 0.5px \u8FB9\u6846,\u73AF\u5F62\u5237\u65B0\u7B49\u56FE\u6807\u6309\u94AE\u4E0E\u6587\u5B57\u6309\u94AE\u5E76\u6392\u65F6\u6BD4\u4F8B\u4E00\u81F4 */\n.xps-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n flex: none;\n padding: 0;\n border: 0.5px solid var(--dsw-alias-border-l3, #d0d3d9);\n border-radius: 999px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #646a73);\n cursor: pointer;\n font-family: inherit;\n font-size: 14px;\n transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease,\n opacity 0.15s ease;\n}\n\n.xps-icon-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n border-color: var(--dsw-alias-border-l4, #a8abb2);\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-icon-btn:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n transform: scale(0.96);\n}\n\n.xps-icon-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* ---------- \u8F93\u5165\u6846 ---------- */\n\n.xps-input {\n width: 100%;\n box-sizing: border-box;\n height: 32px;\n padding: 0 10px;\n border-radius: 8px;\n border: 0.5px solid var(--dsw-alias-border-l4, #c9cdd4);\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n color: var(--dsw-alias-label-primary, #1f2329);\n font-family: inherit;\n font-size: 13px;\n line-height: 20px;\n outline: none;\n}\n\n.xps-input::placeholder {\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u8F93\u5165\u6846 hover:\u8FB9\u6846\u8F7B\u62AC\u4E00\u6863,\u4E0E focus \u7684\u54C1\u724C\u84DD\u533A\u5206 */\n.xps-input:hover:not(:disabled):not(:focus) {\n border-color: var(--dsw-alias-border-l4, #a8abb2);\n}\n\n.xps-input:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.xps-input:focus {\n border-color: var(--dsw-alias-brand-primary, #3370ff);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-brand-primary, #3370ff);\n}\n\n/* ---------- \u5FBD\u6807(\u80F6\u56CA 11/17/500) ---------- */\n\n.xps-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 8px;\n border-radius: 999px;\n border: 0.5px solid var(--dsw-alias-border-l3, #dee0e3);\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n background: var(--dsw-alias-bg-layer-2, #f5f6f7);\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-badge-success {\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary, #1f9d55) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-success-primary, #1f9d55) 30%, transparent);\n color: var(--dsw-alias-state-success-primary, #1f9d55);\n}\n\n.xps-badge-warning {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 30%, transparent);\n color: var(--dsw-alias-state-warn-primary, #d98708);\n}\n\n.xps-badge-error {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n color: var(--dsw-alias-state-error-primary, #d83931);\n}\n\n.xps-badge-info {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 30%, transparent);\n color: var(--dsw-alias-brand-primary, #3370ff);\n}\n\n/* ---------- \u5217\u8868\u884C(\u53D1\u4E1D\u7EBF\u6E05\u5355\u5F0F:\u4E0E\u5E02\u573A\u884C .xps-mk-row\u3001\u5F00\u53D1\u8005\u884C .xps-dev-item \u540C\u8303\u5F0F) ---------- */\n\n.xps-row-list {\n display: flex;\n flex-direction: column;\n}\n\n.xps-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 8px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 0;\n background: transparent;\n cursor: pointer;\n min-width: 0;\n transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease,\n opacity 0.15s ease;\n}\n\n/* \u6E05\u5355\u672B\u884C\u53BB\u53D1\u4E1D\u7EBF(\u4E0E .xps-dev-item:last-child \u540C\u505A\u6CD5) */\n.xps-row-list > .xps-row:last-child {\n border-bottom: none;\n}\n\n/* \u884C hover:\u6574\u884C\u80CC\u666F\u8F7B\u62AC,\u4E0E\u5E02\u573A\u884C\u540C\u5C42\u7EA7 */\n.xps-row:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n}\n\n/* \u56FE\u6807\u6846 40\xD740\u30010.5px hairline\u3001r10 */\n.xps-row-icon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border: 0.5px solid var(--dsw-alias-border-l3, #d0d3d9);\n border-radius: 10px;\n color: var(--dsw-alias-label-secondary, #646a73);\n font-size: 18px;\n line-height: 1;\n}\n\n.xps-row-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.xps-row-title {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n/* \u884C\u9898 14/20/500(\u5B98\u65B9\u884C\u6807\u9898\u89C4\u683C)\u3002\u5C55\u793A\u540D\u4E0E\u300C\u56DE\u9000\u7684\u5305\u540D\u300D\u90FD\u7528\u666E\u901A\u5B57\u4F53:\n * \u6807\u8BC6\u7B26\u53EA\u5728\u540E\u9762\u7684 .xps-row-pkg \u91CC\u8D70\u7B49\u5BBD,\u4E0E\u5E02\u573A/\u5F00\u53D1\u8005\u9875\u540C\u4E00\u89C4\u5219\u3002 */\n.xps-row-name {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* \u5C55\u793A\u540D\u4E4B\u540E\u7684\u5305\u540D(\u6807\u8BC6\u7B26,\u7B49\u5BBD\u5C0F\u5B57 11px;\u4E0E .xps-mk-row-pkg / .xps-dev-pkg \u540C\u89C4\u683C) */\n.xps-row-pkg {\n flex: none;\n font-size: 11px;\n line-height: 17px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u884C\u63CF\u8FF0 13/18 tertiary + \u5355\u884C\u622A\u65AD */\n.xps-row-desc {\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.xps-row-end {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n\n/* ---------- \u6A2A\u5E45/\u63D0\u793A\u6761 ---------- */\n\n.xps-banner {\n margin: 0 0 12px;\n padding: 8px 12px;\n border-radius: 10px;\n font-size: 12px;\n line-height: 18px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 12%, var(--dsw-alias-bg-layer-1, #ffffff));\n border: 0.5px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 30%, transparent);\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-banner-error {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n color: var(--dsw-alias-state-error-primary, #d83931);\n}\n\n/* ---------- \u7A7A\u6001(dashed 0.5px l2 + r8 + pad 18 \u5C45\u4E2D 13 tertiary) ---------- */\n\n.xps-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n /* \u56FE\u6807 / \u6807\u9898 / \u63CF\u8FF0\u7EDF\u4E00 8px \u8282\u594F */\n gap: 8px;\n padding: 18px;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n font-size: 13px;\n line-height: 20px;\n text-align: center;\n}\n\n.xps-empty-icon {\n font-size: 24px;\n line-height: 1;\n}\n\n.xps-empty-title {\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u6309\u94AE\u4E0E\u4E0A\u65B9\u6587\u6848\u5408\u8BA1 12px(\u7236\u7EA7 gap 8 + \u8FD9\u91CC 4) */\n.xps-empty-action {\n margin-top: 4px;\n}\n\n/* \u300C\u6211\u7684\u300D\u9875\u672A\u767B\u5F55\u5F15\u5BFC\u5361:\u6D41\u7A0B\u8BF4\u660E + \u524D\u5F80\u5F00\u53D1\u8005\u5E73\u53F0(\u65E0\u4EE4\u724C\u8F93\u5165\u5165\u53E3,\u767B\u5F55\u53EA\u5728\u8BBE\u7F6E\u91CC) */\n.xps-guide {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 20px 24px;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n}\n\n.xps-guide-title {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-guide-desc {\n margin: 0;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-guide-steps {\n margin: 0;\n padding-left: 20px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-guide-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n}\n\n.xps-guide-url {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n word-break: break-all;\n}\n\n/* ---------- \u4E0A\u4F20\u8868\u5355(\u6253\u5305\u63D0\u4EA4) ---------- */\n\n/* \u62D6\u5165 / \u9009\u62E9\u533A:dashed \u5927\u9776\u533A;\u62D6\u60AC\u65F6\u6574\u533A\u54C1\u724C\u84DD\u63CF\u8FB9 + \u6D45\u84DD wash(.xps-up-drop-over) */\n.xps-up-drop {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 28px 16px;\n margin-bottom: 12px;\n text-align: center;\n border: 0.5px dashed var(--dsw-alias-border-l4, #c9cdd4);\n border-radius: 12px;\n cursor: pointer;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n}\n\n.xps-up-drop:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.04));\n}\n\n.xps-up-drop-over,\n.xps-up-drop-over:hover {\n border-color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 8%, transparent);\n}\n\n.xps-up-drop-icon {\n font-size: 28px;\n line-height: 1;\n}\n\n.xps-up-drop-title {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-drop-actions {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n\n/* \u5206\u7EC4\u5361\u7247:\u8BC6\u522B\u7ED3\u679C / \u63D2\u4EF6\u4FE1\u606F\u5404\u4E00\u5F20,\u66FF\u4EE3\u6563\u843D\u7684\u884C\u5185\u8FB9\u8DDD */\n.xps-up-card {\n padding: 14px 16px;\n margin-bottom: 12px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 10px;\n}\n\n.xps-up-card-actions {\n margin-left: auto;\n display: flex;\n gap: 4px;\n}\n\n/* \u4E0A\u4F20\u9875\u53CC\u680F:\u5DE6\u300C\u9009\u62E9\u5185\u5BB9 + \u8BC6\u522B\u7ED3\u679C\u300D\u53F3\u300C\u63D2\u4EF6\u4FE1\u606F + \u63D0\u4EA4\u300D,\u4E0E\u5176\u4ED6\u9875\u5171\u7528\u6807\u51C6 960 \u5217\u3002\n * \u5B50\u5143\u7D20\u76F4\u63A5\u505A grid item \u5E76\u663E\u5F0F\u5B9A\u4F4D:\u5DE6\u680F 1 \u5217\u4E09\u4E2A\u5757,\u53F3\u680F 2 \u5217\u4E24\u4E2A\u5757(r2-5 \u62C9\u4F38),\n * \u4E24\u680F\u5E95\u8FB9\u5929\u7136\u5BF9\u9F50;\u7A84\u5C4F(<880px)\u9000\u5316\u4E3A\u5355\u5217\u3001\u6309 DOM \u987A\u5E8F\u5806\u53E0 */\n.xps-up-layout {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);\n gap: 16px 16px;\n align-items: stretch;\n}\n\n/* \u76F4\u63A5\u5B50\u5143\u7D20\u5373\u7F51\u683C\u9879:\u5757\u81EA\u8EAB\u7684\u5916\u8FB9\u8DDD\u5F52\u96F6,\u95F4\u8DDD\u7EDF\u4E00\u4EA4\u7ED9 grid gap */\n.xps-up-side-drop,\n.xps-up-side-notice,\n.xps-up-side-scan,\n.xps-up-main-form {\n margin-bottom: 0;\n}\n\n.xps-up-layout > * {\n min-width: 0;\n min-height: 0;\n}\n\n.xps-up-side-drop { grid-column: 1; grid-row: 1; }\n.xps-up-side-notice { grid-column: 1; grid-row: 2; }\n.xps-up-side-scan { grid-column: 1; grid-row: 3 / 6; }\n.xps-up-main-form { grid-column: 2; grid-row: 1 / 6; }\n.xps-up-main-submit { grid-column: 2; grid-row: 6; }\n\n/* \u7A84\u5C4F:\u53CC\u680F\u5148\u4E8E\u8868\u5355\u6805\u683C\u584C\u6210\u5355\u5217,\u907F\u514D\u5B57\u6BB5\u88AB\u538B\u5230\u6362\u884C\u96BE\u8BFB */\n@media (max-width: 1120px) {\n .xps-up-grid {\n grid-template-columns: 1fr;\n }\n}\n\n@media (max-width: 1024px) {\n .xps-up-layout {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .xps-up-layout > [class^='xps-up-'],\n .xps-up-layout > [class*=' xps-up-'] {\n grid-column: auto;\n grid-row: auto;\n }\n}\n\n/* \u53F3\u680F\u7A7A\u6001:\u4E0E\u5DE6\u4FA7\u62D6\u5165\u533A\u540C\u6B3E\u865A\u7EBF\u5361\u7247,\u7B49\u9AD8\u5C45\u4E2D;\u70B9\u51FB\u7B49\u540C\u300C\u9009\u62E9\u76EE\u5F55\u300D\u3002\n * \u62C9\u4F38\u7531 grid item \u81EA\u8EAB\u5B8C\u6210(display: flex \u6491\u6EE1\u5206\u914D\u5230\u7684\u884C),\u4E0D\u4F9D\u8D56\u767E\u5206\u6BD4\u9AD8\u5EA6 */\n.xps-up-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n box-sizing: border-box;\n align-self: stretch;\n height: 100%;\n min-height: 200px;\n padding: 28px 16px;\n text-align: center;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 12px;\n cursor: pointer;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n}\n\n.xps-up-empty:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.04));\n}\n\n/* \u7A7A\u6001\u53CC\u5361:\u5DE6\u62D6\u5165\u533A + \u53F3\u6D41\u7A0B\u8BF4\u660E,\u5355\u884C\u7F51\u683C\u5929\u7136\u7B49\u9AD8(\u5404\u81EA stretch) */\n.xps-up-empty-grid {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);\n gap: 16px;\n align-items: stretch;\n}\n\n.xps-up-empty-grid .xps-up-drop {\n justify-content: center;\n margin-bottom: 0;\n}\n\n/* \u6D41\u7A0B\u8BF4\u660E\u5361\u53EA\u505A\u5C55\u793A:\u53BB\u6389\u624B\u578B\u4E0E\u60AC\u505C\u53CD\u9988 */\n.xps-up-empty-static,\n.xps-up-empty-static:hover {\n justify-content: center;\n cursor: default;\n background: transparent;\n}\n\n@media (max-width: 1024px) {\n .xps-up-empty-grid {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n/* \u7B2C 1 \u6B65\u5361\u91CC\u300C\u8FD8\u5DEE\u4EE3\u7801\u76EE\u5F55\u300D\u7684\u5C31\u5730\u63D0\u793A\u6761 */\n.xps-up-source-missing {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n padding: 8px 10px;\n border-radius: 8px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warning-primary, #b25e09);\n background: color-mix(in srgb, var(--dsw-alias-state-warning-primary, #dc6803) 8%, transparent);\n}\n\n/* \u7A7A\u6001\u53F3\u680F\u7684\u53D1\u5E03\u6D41\u7A0B:\u586B\u5145\u539F\u672C\u7684\u6B7B\u7A7A\u95F4,\u517C\u505A\u5F15\u5BFC(\u5DE6\u5BF9\u9F50\u6E05\u5355,\u5C45\u4E2D\u653E\u7F6E) */\n.xps-up-flow {\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 100%;\n max-width: 380px;\n padding: 8px 4px;\n}\n\n.xps-up-flow-title {\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-flow-item {\n display: flex;\n gap: 10px;\n text-align: left;\n}\n\n.xps-up-flow-no {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n margin-top: 1px;\n border-radius: 50%;\n font-size: 11px;\n font-weight: 500;\n color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, transparent);\n}\n\n.xps-up-flow-main {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.xps-up-flow-item-title {\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-flow-item-desc {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u5361\u7247\u6807\u9898\u4E0A\u7684\u6B65\u9AA4\u5FBD\u6807(\u7B2C 1 \u6B65 / \u7B2C 2 \u6B65),\u5EFA\u7ACB\u300C\u9009\u5185\u5BB9 \u2192 \u586B\u4FE1\u606F\u300D\u7684\u6D41\u7A0B\u611F */\n.xps-up-step-chip {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, transparent);\n}\n\n/* \u9875\u811A\u300C\u53D1\u5E03\u8BF4\u660E\u300D:\u5E38\u9A7B\u5168\u6587\u8BF4\u660E\u5361 */\n.xps-up-guide {\n margin-top: 20px;\n padding: 16px 20px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 10px;\n}\n\n.xps-up-guide-title {\n margin-bottom: 10px;\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-guide ol {\n margin: 0;\n padding-left: 20px;\n display: grid;\n gap: 8px;\n}\n\n.xps-up-guide li {\n font-size: 12px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #4e5460);\n}\n\n.xps-up-guide li::marker {\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n.xps-up-guide b {\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u8BC6\u522B\u7ED3\u679C\u5361\u6807\u9898:\u957F\u6587\u6848\u5141\u8BB8\u6362\u884C,\u8865\u9009\u6309\u94AE\u56FA\u5B9A\u53F3\u4FA7\u4E0D\u53C2\u4E0E\u6362\u884C\u6324\u538B */\n.xps-up-card-title {\n display: flex;\n align-items: baseline;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u8865\u9009\u6309\u94AE\u56FA\u5B9A\u53F3\u4FA7;\u6807\u9898\u8BCD\u4E0D\u6362\u884C(\u53EA\u6709\u6807\u9898\u5355\u9879\u65F6\u4E0D\u53D7 margin-left:auto \u8BEF\u4F24) */\n.xps-up-card-title > .xps-up-card-actions {\n flex: none;\n margin-left: auto;\n}\n\n.xps-up-card-title > span:first-child {\n flex: none;\n}\n\n/* \u8868\u5355\u6805\u683C:\u4E24\u5217\u4E00\u884C(\u5355\u9879\u7528 .xps-up-grid-single \u6536\u6210\u6574\u884C)\u3002\n * align-items: end:\u5DE6\u53F3\u5B57\u6BB5\u6807\u7B7E\u884C\u6570\u4E0D\u540C\u65F6\u8F93\u5165\u6846\u5E95\u8FB9\u5BF9\u9F50,\u6807\u7B7E\u5404\u81EA\u5411\u4E0A\u751F\u957F */\n.xps-up-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px 12px;\n margin-bottom: 10px;\n align-items: end;\n}\n\n.xps-up-grid-single {\n grid-template-columns: 1fr;\n}\n\n/* \u4EA7\u7269 / \u6E90\u7801\u5019\u9009\u884C:radio + \u56FE\u6807 + \u540D\u79F0(\u4E00\u884C) + \u76F8\u5BF9\u8DEF\u5F84(\u5C0F\u5B57\u4E00\u884C,\u8D85\u957F\u622A\u65AD);\n * \u9009\u4E2D\u6001\u54C1\u724C\u84DD\u63CF\u8FB9 */\n.xps-up-candidate {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n margin-bottom: 4px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n font-size: 13px;\n line-height: 20px;\n cursor: pointer;\n min-width: 0;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n}\n\n.xps-up-candidate:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n}\n\n.xps-up-candidate-active,\n.xps-up-candidate-active:hover {\n border-color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 6%, transparent);\n}\n\n/* radio / \u56FE\u6807\u4E0D\u53C2\u4E0E\u6536\u7F29 */\n.xps-up-candidate > input,\n.xps-up-candidate > span:first-of-type {\n flex: none;\n}\n\n/* \u540D\u79F0 + \u8DEF\u5F84\u4E24\u884C\u5757:\u5360\u6EE1\u5269\u4F59\u5BBD\u5EA6,\u5185\u90E8\u5404\u81EA\u622A\u65AD */\n.xps-up-candidate-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.xps-up-candidate-name {\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.xps-up-candidate-path {\n font-size: 12px;\n line-height: 17px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n direction: rtl;\n text-align: left;\n}\n\n.xps-up-candidate-path > bdi {\n direction: ltr;\n unicode-bidi: isolate;\n}\n\n/* ---------- \u9AA8\u67B6\u5C4F ---------- */\n\n.xps-skeleton-group {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.xps-skeleton {\n height: 56px;\n border-radius: 12px;\n background: linear-gradient(\n 90deg,\n var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.05)) 25%,\n var(--dsw-alias-border-l2, rgba(31, 35, 41, 0.1)) 37%,\n var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.05)) 63%\n );\n background-size: 400% 100%;\n animation: xps-skeleton-loading 1.4s ease infinite;\n}\n\n@keyframes xps-skeleton-loading {\n 0% {\n background-position: 100% 50%;\n }\n 100% {\n background-position: 0 50%;\n }\n}\n\n/* ---------- Toast ---------- */\n\n.xps-toast-host {\n position: fixed;\n top: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n flex-direction: column;\n gap: 8px;\n z-index: 9999;\n}\n\n.xps-toast {\n padding: 8px 14px;\n border-radius: 10px;\n font-size: 13px;\n line-height: 20px;\n /* \u591A\u884C\u63D0\u793A\u4E0D\u88AB\u6298\u53E0\u6210\u4E00\u6BB5(\u957F\u6587\u6848\u6539\u8D70 .xps-dialog-pre,\u8FD9\u91CC\u515C\u4F4F\u77ED\u7684\u591A\u884C\u63D0\u793A) */\n white-space: pre-wrap;\n background: var(--dsw-alias-bg-layer-3, #f0f1f2);\n color: var(--dsw-alias-label-primary, #1f2329);\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n box-shadow: 0 4px 16px var(--dsw-alias-bg-mask-1, rgba(0, 0, 0, 0.12));\n cursor: pointer;\n /* \u5165\u573A:\u6DE1\u5165 + \u8F7B\u5FAE\u4E0A\u79FB(\u79BB\u573A\u7531 useToasts \u76F4\u63A5\u4ECE\u5217\u8868\u79FB\u9664,\u4E0D\u505A\u5EF6\u8FDF\u5378\u8F7D) */\n animation: xps-fade-slide-in 0.15s ease-out;\n}\n\n@keyframes xps-fade-slide-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.xps-toast-success {\n border-color: color-mix(in srgb, var(--dsw-alias-state-success-primary, #1f9d55) 30%, transparent);\n}\n\n.xps-toast-error {\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n}\n\n/* ---------- \u5BF9\u8BDD\u6846 ---------- */\n\n.xps-overlay {\n position: fixed;\n inset: 0;\n z-index: 9998;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--dsw-alias-bg-mask-2, rgba(0, 0, 0, 0.45));\n animation: xps-fade-in 0.15s ease-out;\n}\n\n@keyframes xps-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.xps-dialog {\n width: 360px;\n padding: 16px 20px;\n border-radius: 12px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n background: var(--dsw-alias-bg-layer-3, #ffffff);\n box-shadow: 0 8px 32px var(--dsw-alias-bg-mask-1, rgba(0, 0, 0, 0.18));\n /* \u5165\u573A:\u6DE1\u5165 + 0.98 \u2192 1 \u8F7B\u5FAE\u653E\u5927 */\n animation: xps-dialog-in 0.15s ease-out;\n}\n\n@keyframes xps-dialog-in {\n from { opacity: 0; transform: scale(0.98); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.xps-dialog-title {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n margin-bottom: 8px;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-dialog-body {\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n margin-bottom: 16px;\n}\n\n.xps-dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n\n/* \u957F\u6587\u672C\u5BF9\u8BDD\u6846(\u5B89\u88C5\u5931\u8D25\u7684\u591A\u884C\u65E5\u5FD7\u3001\u5F85\u624B\u52A8\u6267\u884C\u7684\u547D\u4EE4):\u6BD4\u901A\u7528\u5BF9\u8BDD\u6846\u5BBD,\u7A84\u5C4F\u81EA\u52A8\u6536\u7A84 */\n.xps-dialog.xps-dialog-wide {\n width: 520px;\n max-width: calc(100vw - 32px);\n box-sizing: border-box;\n}\n\n/* \u6B63\u6587\u539F\u6587\u5757:\u4FDD\u7559\u6362\u884C\u4E0E\u7F29\u8FDB,\u8FC7\u957F\u65F6\u5185\u90E8\u6EDA\u52A8,\u4E0D\u628A\u7A97\u53E3\u6491\u7206;\u53EF\u624B\u52A8\u9009\u4E2D\u590D\u5236 */\n.xps-dialog-pre {\n white-space: pre-wrap;\n max-height: 320px;\n overflow: auto;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2, #f5f6f7);\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary, #1f2329);\n text-align: left;\n word-break: break-word;\n user-select: text;\n}\n\n/* ---------- \u9875\u9762\u5360\u4F4D(\u9AA8\u67B6\u671F) ---------- */\n\n.xps-page-placeholder {\n padding: 18px;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* ---------- \u4EA4\u4E92\u72B6\u6001(\u5168\u7AD9\u7EDF\u4E00:\u8FC7\u6E21 / \u6309\u538B / \u7126\u70B9\u73AF) ----------\n * \u53EA\u8FC7\u6E21\u989C\u8272\u4E0E\u900F\u660E\u5EA6,\u4E0D\u505A\u4F4D\u79FB\u7F29\u653E\u52A8\u753B;\u6309\u538B\u7528\u4E00\u6863\u66F4\u6DF1\u7684 active \u5E95\u8272 + \u6781\u8F7B\u5FAE\u4E0B\u538B\u3002\n * \u9875\u9762\u79C1\u6709\u6837\u5F0F(market / admin)\u5728\u672C\u6587\u4EF6\u4E4B\u540E\u6CE8\u5165,\u5404\u81EA\u7684\u8FC7\u6E21\u4E0E\u6309\u538B\u6001\u5199\u5728\u5404\u81EA\u6A21\u5757\u91CC\u3002\n */\n\n/* .xps-row \u7684\u8FC7\u6E21\u5199\u5728\u81EA\u5DF1\u7684\u57FA\u7840\u89C4\u5219\u91CC(\u89C1\u4E0A),\u6B64\u5904\u4E0D\u518D\u91CD\u590D\u58F0\u660E */\n.xps-btn,\n.xps-icon-btn,\n.xps-nav-item,\n.xps-input {\n transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease,\n opacity 0.15s ease;\n}\n\n/* \u6309\u538B:\u80CC\u666F\u518D\u6DF1\u4E00\u6863(interactive-bg-active);\u4E3B/\u63CF\u8FB9/\u5371\u9669\u6309\u94AE\u6309\u5404\u81EA\u8272\u7CFB\u52A0\u6DF1 */\n.xps-btn:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n transform: scale(0.98);\n}\n\n.xps-btn-primary:active:not(:disabled) {\n /* \u4E3B\u6309\u94AE\u6CA1\u6709 -active token(\u53EA\u6709 -fill / -hover),\u6309\u538B\u76F4\u63A5\u6309\u54C1\u724C\u8272\u52A0\u6DF1 */\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 78%, #000000);\n}\n\n.xps-btn-outline:active:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 16%, transparent);\n}\n\n.xps-btn-danger:active:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 16%, transparent);\n}\n\n.xps-btn-ghost:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n}\n\n.xps-icon-btn:active:not(:disabled),\n.xps-nav-item:active {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n}\n\n.xps-row:active {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n}\n\n/* \u7126\u70B9\u73AF:\u53EA\u5728\u952E\u76D8\u5BFC\u822A\u65F6\u51FA\u73B0(:focus-visible),\u9F20\u6807\u70B9\u51FB\u4E0D\u753B\u73AF */\n.xps-btn:focus-visible,\n.xps-icon-btn:focus-visible,\n.xps-nav-item:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #3370ff);\n outline-offset: 2px;\n}\n\n/* \u6574\u884C\u5361\u7247\u7528\u5185\u63CF\u8FB9,\u907F\u514D\u8D34\u5230\u5185\u5BB9\u533A\u8FB9\u7F18\u88AB\u88C1\u6389 */\n.xps-row:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #3370ff);\n outline-offset: -2px;\n}\n\n/* \u7981\u7528\u6001:\u9664\u5404\u7EC4\u4EF6\u81EA\u5DF1\u7684 opacity \u5916,\u6E38\u6807\u7EDF\u4E00\u515C\u5E95 */\n.xps-app :disabled {\n cursor: not-allowed;\n}\n\n/* \u52A8\u6548\u504F\u597D:reduce \u65F6\u5173\u6389\u8FC7\u6E21\u4E0E\u5165\u573A\u52A8\u753B(\u6309\u538B\u7684\u7F29\u653E\u4E5F\u4E00\u5E76\u53D6\u6D88) */\n@media (prefers-reduced-motion: reduce) {\n .xps-btn,\n .xps-icon-btn,\n .xps-nav-item,\n .xps-input,\n .xps-row,\n .xps-toast,\n .xps-overlay,\n .xps-dialog {\n transition: none;\n animation: none;\n }\n\n .xps-btn:active:not(:disabled) {\n transform: none;\n }\n}\n";
3408
+ var theme_default = "/* \u85AA\u4EBA\u85AA\u4E8B\u5E02\u573A client \u4E3B\u9898:\u5BF9\u6807\u5BBF\u4E3B\u5B98\u65B9\u63D2\u4EF6\u7BA1\u7406\u5668(PluginManagerPage.module.css)\u89C6\u89C9\u8BED\u8A00,\n * \u5168\u90E8\u8D70\u5BBF\u4E3B --dsw-alias-* token(\u5E26\u515C\u5E95\u503C,token \u7F3A\u5931\u65F6\u53EF\u72EC\u7ACB\u9884\u89C8)\u3002 */\n\n/* ---------- \u9875\u9762\u9AA8\u67B6 ---------- */\n\n.xps-app {\n display: flex;\n width: 100%;\n height: 100%;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n color: var(--dsw-alias-label-primary, #1f2329);\n font-family: inherit;\n}\n\n/* \u5DE6\u4FA7\u4E8C\u7EA7\u5BFC\u822A(B \xB7 \u56FE\u6807\u5C45\u4E0A\u84DD\u8C03\u7EC6\u7EBF\u98CE:\u5706\u89D2\u5757 r10,\u9009\u4E2D\u6D45\u84DD\u5E95+\u54C1\u724C\u84DD\u5B57) */\n.xps-nav {\n flex: none;\n width: 92px;\n box-sizing: border-box;\n padding: 16px 10px;\n display: flex;\n flex-direction: column;\n gap: 3px;\n border-right: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n}\n\n.xps-nav-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 3px;\n padding: 9px 0 7px;\n border: none;\n border-radius: 10px;\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary, #646a73);\n font-family: inherit;\n font-size: 12px;\n line-height: 18px;\n}\n\n.xps-nav-item:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(0, 0, 0, 0.04));\n}\n\n.xps-nav-item-active,\n.xps-nav-item-active:hover {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n color: var(--dsw-alias-brand-primary, #3370ff);\n font-weight: 600;\n}\n\n.xps-nav-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 0;\n}\n\n.xps-nav-label {\n white-space: nowrap;\n}\n\n/* \u5185\u5BB9\u533A:\u5B98\u65B9\u9875\u540C\u6B3E\u5C45\u4E2D\u5217(28px \u9876 / clamp \u4FA7 / 48px \u5E95,960 \u4E0A\u9650) */\n.xps-content {\n flex: 1;\n min-width: 0;\n overflow: auto;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 28px clamp(24px, 4vw, 48px) 48px;\n}\n\n.xps-content > * {\n width: 100%;\n max-width: 960px;\n box-sizing: border-box;\n}\n\n/* \u9875\u5934:flex space-between,\u6807\u9898 20/28/500,\u526F\u9898 13/20 secondary */\n.xps-page-head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 20px;\n}\n\n.xps-page-title {\n margin: 0;\n font-size: 20px;\n line-height: 28px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u6807\u9898\u884C\u5185\u6302\u5FBD\u6807(\u8BA1\u6570\u7B49\u72B6\u6001\u4FE1\u606F\u8DDF\u968F\u6807\u9898,\u4E0D\u6DF7\u8FDB\u53F3\u4E0A\u89D2\u64CD\u4F5C\u533A) */\n.xps-title-with-badges {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.xps-page-intro {\n margin: 4px 0 0;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-page-actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* \u533A\u5757\u9898 14/22/500 */\n.xps-section-title {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* ---------- \u6587\u5B57\u8272\u9636\u5DE5\u5177\u7C7B ---------- */\n\n.xps-text-secondary {\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n/* \u8BF4\u660E/\u8BA1\u6570:12/18 tertiary */\n.xps-text-caption {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u5305\u540D/\u7248\u672C\u53F7\u7B49 mono */\n.xps-mono {\n font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n}\n\n/* ---------- \u6309\u94AE(\u80F6\u56CA) ---------- */\n\n.xps-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n height: 32px;\n box-sizing: border-box;\n padding: 0 14px;\n border-radius: 16px;\n border: 0.5px solid var(--dsw-alias-border-l3, #d0d3d9);\n background: transparent;\n color: var(--dsw-alias-label-primary, #1f2329);\n font-family: inherit;\n font-size: 13px;\n line-height: 20px;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.xps-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n}\n\n.xps-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* \u4E3B\u6309\u94AE(B \u65B9\u5411\u8BC6\u522B\u8272):\u5B9E\u5FC3\u54C1\u724C\u84DD + \u767D\u5B57,hover \u52A0\u6DF1 */\n.xps-btn-primary {\n background: var(--dsw-alias-brand-primary, #3370ff);\n border-color: transparent;\n color: var(--dsw-alias-label-primary-foreground, #ffffff);\n}\n\n.xps-btn-primary:hover:not(:disabled) {\n background: var(--dsw-alias-button-primary-hover, color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 85%, #000000));\n}\n\n/* \u63CF\u8FB9\u4E3B\u6309\u94AE(\u5DF2\u5B89\u88C5/\u66F4\u65B0\u6001):\u54C1\u724C\u84DD\u63CF\u8FB9 + \u84DD\u5B57\u900F\u660E\u5E95 */\n.xps-btn-outline {\n border: 1px solid var(--dsw-alias-brand-primary, #3370ff);\n background: transparent;\n color: var(--dsw-alias-brand-primary, #3370ff);\n}\n\n.xps-btn-outline:hover:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 8%, transparent);\n}\n\n/* \u66F4\u65B0\u6309\u94AE:\u4E0E\u300C\u2191 \u53EF\u66F4\u65B0\u300D\u5FBD\u6807\u540C\u6E90\u7684\u6A59\u8272\u63CF\u8FB9(\u4E0D\u8DDF\u4E3B\u9898 primary \u8D70,\u9ED1\u8272\u4E3B\u9898\u4E0B\u4E5F\u80FD\u548C\u5B89\u88C5\u62C9\u5F00) */\n.xps-btn-update {\n border: 1px solid var(--dsw-alias-state-warn-primary, #d98708);\n background: transparent;\n color: var(--dsw-alias-state-warn-primary, #d98708);\n}\n\n.xps-btn-update:hover:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 10%, transparent);\n}\n\n/* \u5371\u9669\u6309\u94AE:\u590D\u7528\u6B21\u6309\u94AE,\u7EA2\u5B57 + 30% \u7EA2\u6846,hover \u6362\u7EA2 wash */\n.xps-btn-danger {\n color: var(--dsw-alias-state-error-primary, #d83931);\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n}\n\n.xps-btn-danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 8%, transparent);\n}\n\n.xps-btn-ghost {\n border-color: transparent;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-btn-ghost:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-btn-sm {\n height: 26px;\n padding: 0 10px;\n font-size: 12px;\n line-height: 18px;\n border-radius: 13px;\n}\n\n/* \u56FE\u6807\u6309\u94AE:28\xD728 \u5168\u5706 */\n/* \u56FE\u6807\u6309\u94AE:\u4E0E .xps-btn \u540C\u9AD8(32px)\u3001\u540C 0.5px \u8FB9\u6846,\u73AF\u5F62\u5237\u65B0\u7B49\u56FE\u6807\u6309\u94AE\u4E0E\u6587\u5B57\u6309\u94AE\u5E76\u6392\u65F6\u6BD4\u4F8B\u4E00\u81F4 */\n.xps-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n flex: none;\n padding: 0;\n border: 0.5px solid var(--dsw-alias-border-l3, #d0d3d9);\n border-radius: 999px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #646a73);\n cursor: pointer;\n font-family: inherit;\n font-size: 14px;\n transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease,\n opacity 0.15s ease;\n}\n\n.xps-icon-btn:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n border-color: var(--dsw-alias-border-l4, #a8abb2);\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-icon-btn:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n transform: scale(0.96);\n}\n\n.xps-icon-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n/* ---------- \u8F93\u5165\u6846 ---------- */\n\n.xps-input {\n width: 100%;\n box-sizing: border-box;\n height: 32px;\n padding: 0 10px;\n border-radius: 8px;\n border: 0.5px solid var(--dsw-alias-border-l4, #c9cdd4);\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n color: var(--dsw-alias-label-primary, #1f2329);\n font-family: inherit;\n font-size: 13px;\n line-height: 20px;\n outline: none;\n}\n\n.xps-input::placeholder {\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u8F93\u5165\u6846 hover:\u8FB9\u6846\u8F7B\u62AC\u4E00\u6863,\u4E0E focus \u7684\u54C1\u724C\u84DD\u533A\u5206 */\n.xps-input:hover:not(:disabled):not(:focus) {\n border-color: var(--dsw-alias-border-l4, #a8abb2);\n}\n\n.xps-input:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.xps-input:focus {\n border-color: var(--dsw-alias-brand-primary, #3370ff);\n box-shadow: inset 0 0 0 0.5px var(--dsw-alias-brand-primary, #3370ff);\n}\n\n/* ---------- \u5FBD\u6807(\u80F6\u56CA 11/17/500) ---------- */\n\n.xps-badge {\n display: inline-flex;\n align-items: center;\n padding: 1px 8px;\n border-radius: 999px;\n border: 0.5px solid var(--dsw-alias-border-l3, #dee0e3);\n font-size: 11px;\n line-height: 17px;\n font-weight: 500;\n white-space: nowrap;\n background: var(--dsw-alias-bg-layer-2, #f5f6f7);\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-badge-success {\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary, #1f9d55) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-success-primary, #1f9d55) 30%, transparent);\n color: var(--dsw-alias-state-success-primary, #1f9d55);\n}\n\n.xps-badge-warning {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 30%, transparent);\n color: var(--dsw-alias-state-warn-primary, #d98708);\n}\n\n.xps-badge-error {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n color: var(--dsw-alias-state-error-primary, #d83931);\n}\n\n.xps-badge-info {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 30%, transparent);\n color: var(--dsw-alias-brand-primary, #3370ff);\n}\n\n/* ---------- \u5217\u8868\u884C(\u53D1\u4E1D\u7EBF\u6E05\u5355\u5F0F:\u4E0E\u5E02\u573A\u884C .xps-mk-row\u3001\u5F00\u53D1\u8005\u884C .xps-dev-item \u540C\u8303\u5F0F) ---------- */\n\n.xps-row-list {\n display: flex;\n flex-direction: column;\n}\n\n.xps-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 8px;\n border-bottom: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 0;\n background: transparent;\n cursor: pointer;\n min-width: 0;\n transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease,\n opacity 0.15s ease;\n}\n\n/* \u6E05\u5355\u672B\u884C\u53BB\u53D1\u4E1D\u7EBF(\u4E0E .xps-dev-item:last-child \u540C\u505A\u6CD5) */\n.xps-row-list > .xps-row:last-child {\n border-bottom: none;\n}\n\n/* \u884C hover:\u6574\u884C\u80CC\u666F\u8F7B\u62AC,\u4E0E\u5E02\u573A\u884C\u540C\u5C42\u7EA7 */\n.xps-row:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n}\n\n/* \u56FE\u6807\u6846 40\xD740\u30010.5px hairline\u3001r10 */\n.xps-row-icon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border: 0.5px solid var(--dsw-alias-border-l3, #d0d3d9);\n border-radius: 10px;\n color: var(--dsw-alias-label-secondary, #646a73);\n font-size: 18px;\n line-height: 1;\n}\n\n.xps-row-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.xps-row-title {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n}\n\n/* \u884C\u9898 14/20/500(\u5B98\u65B9\u884C\u6807\u9898\u89C4\u683C)\u3002\u5C55\u793A\u540D\u4E0E\u300C\u56DE\u9000\u7684\u5305\u540D\u300D\u90FD\u7528\u666E\u901A\u5B57\u4F53:\n * \u6807\u8BC6\u7B26\u53EA\u5728\u540E\u9762\u7684 .xps-row-pkg \u91CC\u8D70\u7B49\u5BBD,\u4E0E\u5E02\u573A/\u5F00\u53D1\u8005\u9875\u540C\u4E00\u89C4\u5219\u3002 */\n.xps-row-name {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* \u5C55\u793A\u540D\u4E4B\u540E\u7684\u5305\u540D(\u6807\u8BC6\u7B26,\u7B49\u5BBD\u5C0F\u5B57 11px;\u4E0E .xps-mk-row-pkg / .xps-dev-pkg \u540C\u89C4\u683C) */\n.xps-row-pkg {\n flex: none;\n font-size: 11px;\n line-height: 17px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u884C\u63CF\u8FF0 13/18 tertiary + \u5355\u884C\u622A\u65AD */\n.xps-row-desc {\n font-size: 13px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.xps-row-end {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n\n/* ---------- \u6A2A\u5E45/\u63D0\u793A\u6761 ---------- */\n\n.xps-banner {\n margin: 0 0 12px;\n padding: 8px 12px;\n border-radius: 10px;\n font-size: 12px;\n line-height: 18px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 12%, var(--dsw-alias-bg-layer-1, #ffffff));\n border: 0.5px solid color-mix(in srgb, var(--dsw-alias-state-warn-primary, #d98708) 30%, transparent);\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-banner-error {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 10%, var(--dsw-alias-bg-layer-1, #ffffff));\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n color: var(--dsw-alias-state-error-primary, #d83931);\n}\n\n/* ---------- \u7A7A\u6001(dashed 0.5px l2 + r8 + pad 18 \u5C45\u4E2D 13 tertiary) ---------- */\n\n.xps-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n /* \u56FE\u6807 / \u6807\u9898 / \u63CF\u8FF0\u7EDF\u4E00 8px \u8282\u594F */\n gap: 8px;\n padding: 18px;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n font-size: 13px;\n line-height: 20px;\n text-align: center;\n}\n\n.xps-empty-icon {\n font-size: 24px;\n line-height: 1;\n}\n\n.xps-empty-title {\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u6309\u94AE\u4E0E\u4E0A\u65B9\u6587\u6848\u5408\u8BA1 12px(\u7236\u7EA7 gap 8 + \u8FD9\u91CC 4) */\n.xps-empty-action {\n margin-top: 4px;\n}\n\n/* \u300C\u6211\u7684\u300D\u9875\u672A\u767B\u5F55\u5F15\u5BFC\u5361:\u6D41\u7A0B\u8BF4\u660E + \u524D\u5F80\u5F00\u53D1\u8005\u5E73\u53F0(\u65E0\u4EE4\u724C\u8F93\u5165\u5165\u53E3,\u767B\u5F55\u53EA\u5728\u8BBE\u7F6E\u91CC) */\n.xps-guide {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 20px 24px;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n}\n\n.xps-guide-title {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-guide-desc {\n margin: 0;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-guide-steps {\n margin: 0;\n padding-left: 20px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n}\n\n.xps-guide-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n}\n\n.xps-guide-url {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n word-break: break-all;\n}\n\n/* ---------- \u4E0A\u4F20\u8868\u5355(\u6253\u5305\u63D0\u4EA4) ---------- */\n\n/* \u62D6\u5165 / \u9009\u62E9\u533A:dashed \u5927\u9776\u533A;\u62D6\u60AC\u65F6\u6574\u533A\u54C1\u724C\u84DD\u63CF\u8FB9 + \u6D45\u84DD wash(.xps-up-drop-over) */\n.xps-up-drop {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n padding: 28px 16px;\n margin-bottom: 12px;\n text-align: center;\n border: 0.5px dashed var(--dsw-alias-border-l4, #c9cdd4);\n border-radius: 12px;\n cursor: pointer;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n}\n\n.xps-up-drop:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.04));\n}\n\n.xps-up-drop-over,\n.xps-up-drop-over:hover {\n border-color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 8%, transparent);\n}\n\n.xps-up-drop-icon {\n font-size: 28px;\n line-height: 1;\n}\n\n.xps-up-drop-title {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-drop-actions {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n\n/* \u5206\u7EC4\u5361\u7247:\u8BC6\u522B\u7ED3\u679C / \u63D2\u4EF6\u4FE1\u606F\u5404\u4E00\u5F20,\u66FF\u4EE3\u6563\u843D\u7684\u884C\u5185\u8FB9\u8DDD */\n.xps-up-card {\n padding: 14px 16px;\n margin-bottom: 12px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 10px;\n}\n\n.xps-up-card-actions {\n margin-left: auto;\n display: flex;\n gap: 4px;\n}\n\n/* \u4E0A\u4F20\u9875\u53CC\u680F:\u5DE6\u300C\u9009\u62E9\u5185\u5BB9 + \u8BC6\u522B\u7ED3\u679C\u300D\u53F3\u300C\u63D2\u4EF6\u4FE1\u606F + \u63D0\u4EA4\u300D,\u4E0E\u5176\u4ED6\u9875\u5171\u7528\u6807\u51C6 960 \u5217\u3002\n * \u5B50\u5143\u7D20\u76F4\u63A5\u505A grid item \u5E76\u663E\u5F0F\u5B9A\u4F4D:\u5DE6\u680F 1 \u5217\u4E09\u4E2A\u5757,\u53F3\u680F 2 \u5217\u4E24\u4E2A\u5757(r2-5 \u62C9\u4F38),\n * \u4E24\u680F\u5E95\u8FB9\u5929\u7136\u5BF9\u9F50;\u7A84\u5C4F(<880px)\u9000\u5316\u4E3A\u5355\u5217\u3001\u6309 DOM \u987A\u5E8F\u5806\u53E0 */\n.xps-up-layout {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);\n gap: 16px 16px;\n align-items: stretch;\n}\n\n/* \u76F4\u63A5\u5B50\u5143\u7D20\u5373\u7F51\u683C\u9879:\u5757\u81EA\u8EAB\u7684\u5916\u8FB9\u8DDD\u5F52\u96F6,\u95F4\u8DDD\u7EDF\u4E00\u4EA4\u7ED9 grid gap */\n.xps-up-side-drop,\n.xps-up-side-notice,\n.xps-up-side-scan,\n.xps-up-main-form {\n margin-bottom: 0;\n}\n\n.xps-up-layout > * {\n min-width: 0;\n min-height: 0;\n}\n\n.xps-up-side-drop { grid-column: 1; grid-row: 1; }\n.xps-up-side-notice { grid-column: 1; grid-row: 2; }\n.xps-up-side-scan { grid-column: 1; grid-row: 3 / 6; }\n.xps-up-main-form { grid-column: 2; grid-row: 1 / 6; }\n.xps-up-main-submit { grid-column: 2; grid-row: 6; }\n\n/* \u7A84\u5C4F:\u53CC\u680F\u5148\u4E8E\u8868\u5355\u6805\u683C\u584C\u6210\u5355\u5217,\u907F\u514D\u5B57\u6BB5\u88AB\u538B\u5230\u6362\u884C\u96BE\u8BFB */\n@media (max-width: 1120px) {\n .xps-up-grid {\n grid-template-columns: 1fr;\n }\n}\n\n@media (max-width: 1024px) {\n .xps-up-layout {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .xps-up-layout > [class^='xps-up-'],\n .xps-up-layout > [class*=' xps-up-'] {\n grid-column: auto;\n grid-row: auto;\n }\n}\n\n/* \u53F3\u680F\u7A7A\u6001:\u4E0E\u5DE6\u4FA7\u62D6\u5165\u533A\u540C\u6B3E\u865A\u7EBF\u5361\u7247,\u7B49\u9AD8\u5C45\u4E2D;\u70B9\u51FB\u7B49\u540C\u300C\u9009\u62E9\u76EE\u5F55\u300D\u3002\n * \u62C9\u4F38\u7531 grid item \u81EA\u8EAB\u5B8C\u6210(display: flex \u6491\u6EE1\u5206\u914D\u5230\u7684\u884C),\u4E0D\u4F9D\u8D56\u767E\u5206\u6BD4\u9AD8\u5EA6 */\n.xps-up-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n box-sizing: border-box;\n align-self: stretch;\n height: 100%;\n min-height: 200px;\n padding: 28px 16px;\n text-align: center;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 12px;\n cursor: pointer;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n}\n\n.xps-up-empty:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.04));\n}\n\n/* \u7A7A\u6001\u53CC\u5361:\u5DE6\u62D6\u5165\u533A + \u53F3\u6D41\u7A0B\u8BF4\u660E,\u5355\u884C\u7F51\u683C\u5929\u7136\u7B49\u9AD8(\u5404\u81EA stretch) */\n.xps-up-empty-grid {\n display: grid;\n grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);\n gap: 16px;\n align-items: stretch;\n}\n\n.xps-up-empty-grid .xps-up-drop {\n justify-content: center;\n margin-bottom: 0;\n}\n\n/* \u6D41\u7A0B\u8BF4\u660E\u5361\u53EA\u505A\u5C55\u793A:\u53BB\u6389\u624B\u578B\u4E0E\u60AC\u505C\u53CD\u9988 */\n.xps-up-empty-static,\n.xps-up-empty-static:hover {\n justify-content: center;\n cursor: default;\n background: transparent;\n}\n\n@media (max-width: 1024px) {\n .xps-up-empty-grid {\n grid-template-columns: minmax(0, 1fr);\n }\n}\n\n/* \u7B2C 1 \u6B65\u5361\u91CC\u300C\u8FD8\u5DEE\u4EE3\u7801\u76EE\u5F55\u300D\u7684\u5C31\u5730\u63D0\u793A\u6761 */\n.xps-up-source-missing {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n padding: 8px 10px;\n border-radius: 8px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warning-primary, #b25e09);\n background: color-mix(in srgb, var(--dsw-alias-state-warning-primary, #dc6803) 8%, transparent);\n}\n\n/* \u7A7A\u6001\u53F3\u680F\u7684\u53D1\u5E03\u6D41\u7A0B:\u586B\u5145\u539F\u672C\u7684\u6B7B\u7A7A\u95F4,\u517C\u505A\u5F15\u5BFC(\u5DE6\u5BF9\u9F50\u6E05\u5355,\u5C45\u4E2D\u653E\u7F6E) */\n.xps-up-flow {\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 100%;\n max-width: 380px;\n padding: 8px 4px;\n}\n\n.xps-up-flow-title {\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-flow-item {\n display: flex;\n gap: 10px;\n text-align: left;\n}\n\n.xps-up-flow-no {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n margin-top: 1px;\n border-radius: 50%;\n font-size: 11px;\n font-weight: 500;\n color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, transparent);\n}\n\n.xps-up-flow-main {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.xps-up-flow-item-title {\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-flow-item-desc {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* \u5361\u7247\u6807\u9898\u4E0A\u7684\u6B65\u9AA4\u5FBD\u6807(\u7B2C 1 \u6B65 / \u7B2C 2 \u6B65),\u5EFA\u7ACB\u300C\u9009\u5185\u5BB9 \u2192 \u586B\u4FE1\u606F\u300D\u7684\u6D41\u7A0B\u611F */\n.xps-up-step-chip {\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n font-size: 11px;\n line-height: 18px;\n font-weight: 500;\n color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 10%, transparent);\n}\n\n/* \u9875\u811A\u300C\u53D1\u5E03\u8BF4\u660E\u300D:\u5E38\u9A7B\u5168\u6587\u8BF4\u660E\u5361 */\n.xps-up-guide {\n margin-top: 20px;\n padding: 16px 20px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 10px;\n}\n\n.xps-up-guide-title {\n margin-bottom: 10px;\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-up-guide ol {\n margin: 0;\n padding-left: 20px;\n display: grid;\n gap: 8px;\n}\n\n.xps-up-guide li {\n font-size: 12px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #4e5460);\n}\n\n.xps-up-guide li::marker {\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n.xps-up-guide b {\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u8BC6\u522B\u7ED3\u679C\u5361\u6807\u9898:\u957F\u6587\u6848\u5141\u8BB8\u6362\u884C,\u8865\u9009\u6309\u94AE\u56FA\u5B9A\u53F3\u4FA7\u4E0D\u53C2\u4E0E\u6362\u884C\u6324\u538B */\n.xps-up-card-title {\n display: flex;\n align-items: baseline;\n gap: 8px;\n margin-bottom: 10px;\n font-size: 13px;\n line-height: 20px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n/* \u8865\u9009\u6309\u94AE\u56FA\u5B9A\u53F3\u4FA7;\u6807\u9898\u8BCD\u4E0D\u6362\u884C(\u53EA\u6709\u6807\u9898\u5355\u9879\u65F6\u4E0D\u53D7 margin-left:auto \u8BEF\u4F24) */\n.xps-up-card-title > .xps-up-card-actions {\n flex: none;\n margin-left: auto;\n}\n\n.xps-up-card-title > span:first-child {\n flex: none;\n}\n\n/* \u8868\u5355\u6805\u683C:\u4E24\u5217\u4E00\u884C(\u5355\u9879\u7528 .xps-up-grid-single \u6536\u6210\u6574\u884C)\u3002\n * align-items: end:\u5DE6\u53F3\u5B57\u6BB5\u6807\u7B7E\u884C\u6570\u4E0D\u540C\u65F6\u8F93\u5165\u6846\u5E95\u8FB9\u5BF9\u9F50,\u6807\u7B7E\u5404\u81EA\u5411\u4E0A\u751F\u957F */\n.xps-up-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px 12px;\n margin-bottom: 10px;\n align-items: end;\n}\n\n.xps-up-grid-single {\n grid-template-columns: 1fr;\n}\n\n/* \u4EA7\u7269 / \u6E90\u7801\u5019\u9009\u884C:radio + \u56FE\u6807 + \u540D\u79F0(\u4E00\u884C) + \u76F8\u5BF9\u8DEF\u5F84(\u5C0F\u5B57\u4E00\u884C,\u8D85\u957F\u622A\u65AD);\n * \u9009\u4E2D\u6001\u54C1\u724C\u84DD\u63CF\u8FB9 */\n.xps-up-candidate {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n margin-bottom: 4px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n font-size: 13px;\n line-height: 20px;\n cursor: pointer;\n min-width: 0;\n transition: background-color 0.15s ease, border-color 0.15s ease;\n}\n\n.xps-up-candidate:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.06));\n}\n\n.xps-up-candidate-active,\n.xps-up-candidate-active:hover {\n border-color: var(--dsw-alias-brand-primary, #3370ff);\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 6%, transparent);\n}\n\n/* radio / \u56FE\u6807\u4E0D\u53C2\u4E0E\u6536\u7F29 */\n.xps-up-candidate > input,\n.xps-up-candidate > span:first-of-type {\n flex: none;\n}\n\n/* \u540D\u79F0 + \u8DEF\u5F84\u4E24\u884C\u5757:\u5360\u6EE1\u5269\u4F59\u5BBD\u5EA6,\u5185\u90E8\u5404\u81EA\u622A\u65AD */\n.xps-up-candidate-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 1px;\n}\n\n.xps-up-candidate-name {\n font-weight: 500;\n color: var(--dsw-alias-label-primary, #1f2329);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.xps-up-candidate-path {\n font-size: 12px;\n line-height: 17px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n direction: rtl;\n text-align: left;\n}\n\n.xps-up-candidate-path > bdi {\n direction: ltr;\n unicode-bidi: isolate;\n}\n\n/* ---------- \u9AA8\u67B6\u5C4F ---------- */\n\n.xps-skeleton-group {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.xps-skeleton {\n height: 56px;\n border-radius: 12px;\n background: linear-gradient(\n 90deg,\n var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.05)) 25%,\n var(--dsw-alias-border-l2, rgba(31, 35, 41, 0.1)) 37%,\n var(--dsw-alias-interactive-bg-hover, rgba(31, 35, 41, 0.05)) 63%\n );\n background-size: 400% 100%;\n animation: xps-skeleton-loading 1.4s ease infinite;\n}\n\n@keyframes xps-skeleton-loading {\n 0% {\n background-position: 100% 50%;\n }\n 100% {\n background-position: 0 50%;\n }\n}\n\n/* ---------- Toast ---------- */\n\n.xps-toast-host {\n position: fixed;\n top: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n flex-direction: column;\n gap: 8px;\n z-index: 9999;\n}\n\n.xps-toast {\n padding: 8px 14px;\n border-radius: 10px;\n font-size: 13px;\n line-height: 20px;\n /* \u591A\u884C\u63D0\u793A\u4E0D\u88AB\u6298\u53E0\u6210\u4E00\u6BB5(\u957F\u6587\u6848\u6539\u8D70 .xps-dialog-pre,\u8FD9\u91CC\u515C\u4F4F\u77ED\u7684\u591A\u884C\u63D0\u793A) */\n white-space: pre-wrap;\n background: var(--dsw-alias-bg-layer-3, #f0f1f2);\n color: var(--dsw-alias-label-primary, #1f2329);\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n box-shadow: 0 4px 16px var(--dsw-alias-bg-mask-1, rgba(0, 0, 0, 0.12));\n cursor: pointer;\n /* \u5165\u573A:\u6DE1\u5165 + \u8F7B\u5FAE\u4E0A\u79FB(\u79BB\u573A\u7531 useToasts \u76F4\u63A5\u4ECE\u5217\u8868\u79FB\u9664,\u4E0D\u505A\u5EF6\u8FDF\u5378\u8F7D) */\n animation: xps-fade-slide-in 0.15s ease-out;\n}\n\n@keyframes xps-fade-slide-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.xps-toast-success {\n border-color: color-mix(in srgb, var(--dsw-alias-state-success-primary, #1f9d55) 30%, transparent);\n}\n\n.xps-toast-error {\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 30%, transparent);\n}\n\n/* ---------- \u5BF9\u8BDD\u6846 ---------- */\n\n.xps-overlay {\n position: fixed;\n inset: 0;\n z-index: 9998;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--dsw-alias-bg-mask-2, rgba(0, 0, 0, 0.45));\n animation: xps-fade-in 0.15s ease-out;\n}\n\n@keyframes xps-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.xps-dialog {\n width: 360px;\n padding: 16px 20px;\n border-radius: 12px;\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n background: var(--dsw-alias-bg-layer-3, #ffffff);\n box-shadow: 0 8px 32px var(--dsw-alias-bg-mask-1, rgba(0, 0, 0, 0.18));\n /* \u5165\u573A:\u6DE1\u5165 + 0.98 \u2192 1 \u8F7B\u5FAE\u653E\u5927 */\n animation: xps-dialog-in 0.15s ease-out;\n}\n\n@keyframes xps-dialog-in {\n from { opacity: 0; transform: scale(0.98); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.xps-dialog-title {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n margin-bottom: 8px;\n color: var(--dsw-alias-label-primary, #1f2329);\n}\n\n.xps-dialog-body {\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-secondary, #646a73);\n margin-bottom: 16px;\n}\n\n.xps-dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n\n/* \u957F\u6587\u672C\u5BF9\u8BDD\u6846(\u5B89\u88C5\u5931\u8D25\u7684\u591A\u884C\u65E5\u5FD7\u3001\u5F85\u624B\u52A8\u6267\u884C\u7684\u547D\u4EE4):\u6BD4\u901A\u7528\u5BF9\u8BDD\u6846\u5BBD,\u7A84\u5C4F\u81EA\u52A8\u6536\u7A84 */\n.xps-dialog.xps-dialog-wide {\n width: 520px;\n max-width: calc(100vw - 32px);\n box-sizing: border-box;\n}\n\n/* \u6B63\u6587\u539F\u6587\u5757:\u4FDD\u7559\u6362\u884C\u4E0E\u7F29\u8FDB,\u8FC7\u957F\u65F6\u5185\u90E8\u6EDA\u52A8,\u4E0D\u628A\u7A97\u53E3\u6491\u7206;\u53EF\u624B\u52A8\u9009\u4E2D\u590D\u5236 */\n.xps-dialog-pre {\n white-space: pre-wrap;\n max-height: 320px;\n overflow: auto;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-2, #f5f6f7);\n border: 0.5px solid var(--dsw-alias-border-l2, #dee0e3);\n font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n font-size: 12px;\n line-height: 1.6;\n color: var(--dsw-alias-label-primary, #1f2329);\n text-align: left;\n word-break: break-word;\n user-select: text;\n}\n\n/* ---------- \u9875\u9762\u5360\u4F4D(\u9AA8\u67B6\u671F) ---------- */\n\n.xps-page-placeholder {\n padding: 18px;\n border: 0.5px dashed var(--dsw-alias-border-l2, #dee0e3);\n border-radius: 8px;\n font-size: 13px;\n line-height: 20px;\n color: var(--dsw-alias-label-tertiary, #8f959e);\n}\n\n/* ---------- \u4EA4\u4E92\u72B6\u6001(\u5168\u7AD9\u7EDF\u4E00:\u8FC7\u6E21 / \u6309\u538B / \u7126\u70B9\u73AF) ----------\n * \u53EA\u8FC7\u6E21\u989C\u8272\u4E0E\u900F\u660E\u5EA6,\u4E0D\u505A\u4F4D\u79FB\u7F29\u653E\u52A8\u753B;\u6309\u538B\u7528\u4E00\u6863\u66F4\u6DF1\u7684 active \u5E95\u8272 + \u6781\u8F7B\u5FAE\u4E0B\u538B\u3002\n * \u9875\u9762\u79C1\u6709\u6837\u5F0F(market / admin)\u5728\u672C\u6587\u4EF6\u4E4B\u540E\u6CE8\u5165,\u5404\u81EA\u7684\u8FC7\u6E21\u4E0E\u6309\u538B\u6001\u5199\u5728\u5404\u81EA\u6A21\u5757\u91CC\u3002\n */\n\n/* .xps-row \u7684\u8FC7\u6E21\u5199\u5728\u81EA\u5DF1\u7684\u57FA\u7840\u89C4\u5219\u91CC(\u89C1\u4E0A),\u6B64\u5904\u4E0D\u518D\u91CD\u590D\u58F0\u660E */\n.xps-btn,\n.xps-icon-btn,\n.xps-nav-item,\n.xps-input {\n transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease,\n opacity 0.15s ease;\n}\n\n/* \u6309\u538B:\u80CC\u666F\u518D\u6DF1\u4E00\u6863(interactive-bg-active);\u4E3B/\u63CF\u8FB9/\u5371\u9669\u6309\u94AE\u6309\u5404\u81EA\u8272\u7CFB\u52A0\u6DF1 */\n.xps-btn:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n transform: scale(0.98);\n}\n\n.xps-btn-primary:active:not(:disabled) {\n /* \u4E3B\u6309\u94AE\u6CA1\u6709 -active token(\u53EA\u6709 -fill / -hover),\u6309\u538B\u76F4\u63A5\u6309\u54C1\u724C\u8272\u52A0\u6DF1 */\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 78%, #000000);\n}\n\n.xps-btn-outline:active:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-brand-primary, #3370ff) 16%, transparent);\n}\n\n.xps-btn-danger:active:not(:disabled) {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #d83931) 16%, transparent);\n}\n\n.xps-btn-ghost:active:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n}\n\n.xps-icon-btn:active:not(:disabled),\n.xps-nav-item:active {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n}\n\n.xps-row:active {\n background: var(--dsw-alias-interactive-bg-active, rgba(38, 49, 72, 0.1));\n}\n\n/* \u7126\u70B9\u73AF:\u53EA\u5728\u952E\u76D8\u5BFC\u822A\u65F6\u51FA\u73B0(:focus-visible),\u9F20\u6807\u70B9\u51FB\u4E0D\u753B\u73AF */\n.xps-btn:focus-visible,\n.xps-icon-btn:focus-visible,\n.xps-nav-item:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #3370ff);\n outline-offset: 2px;\n}\n\n/* \u6574\u884C\u5361\u7247\u7528\u5185\u63CF\u8FB9,\u907F\u514D\u8D34\u5230\u5185\u5BB9\u533A\u8FB9\u7F18\u88AB\u88C1\u6389 */\n.xps-row:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #3370ff);\n outline-offset: -2px;\n}\n\n/* \u7981\u7528\u6001:\u9664\u5404\u7EC4\u4EF6\u81EA\u5DF1\u7684 opacity \u5916,\u6E38\u6807\u7EDF\u4E00\u515C\u5E95 */\n.xps-app :disabled {\n cursor: not-allowed;\n}\n\n/* \u52A8\u6548\u504F\u597D:reduce \u65F6\u5173\u6389\u8FC7\u6E21\u4E0E\u5165\u573A\u52A8\u753B(\u6309\u538B\u7684\u7F29\u653E\u4E5F\u4E00\u5E76\u53D6\u6D88) */\n@media (prefers-reduced-motion: reduce) {\n .xps-btn,\n .xps-icon-btn,\n .xps-nav-item,\n .xps-input,\n .xps-row,\n .xps-toast,\n .xps-overlay,\n .xps-dialog {\n transition: none;\n animation: none;\n }\n\n .xps-btn:active:not(:disabled) {\n transform: none;\n }\n}\n";
3384
3409
 
3385
3410
  // src/client/theme-inject.ts
3386
3411
  function ensureThemeStyles() {
@@ -3627,21 +3652,82 @@ var rightStyle2 = {
3627
3652
  alignItems: "flex-end",
3628
3653
  gap: 4
3629
3654
  };
3655
+ var PENDING_UPDATE_KEY = "xrxs-plugins-store:self-update-pending";
3656
+ function readPendingUpdate() {
3657
+ try {
3658
+ const raw = localStorage.getItem(PENDING_UPDATE_KEY);
3659
+ if (raw === null) return null;
3660
+ const parsed = JSON.parse(raw);
3661
+ return typeof parsed.version === "string" ? parsed.version : null;
3662
+ } catch {
3663
+ return null;
3664
+ }
3665
+ }
3666
+ function writePendingUpdate(version) {
3667
+ try {
3668
+ localStorage.setItem(PENDING_UPDATE_KEY, JSON.stringify({ version }));
3669
+ } catch {
3670
+ }
3671
+ }
3672
+ function clearPendingUpdate() {
3673
+ try {
3674
+ localStorage.removeItem(PENDING_UPDATE_KEY);
3675
+ } catch {
3676
+ }
3677
+ }
3630
3678
  function messageOf3(error, fallback) {
3631
3679
  return error instanceof Error && error.message !== "" ? error.message : fallback;
3632
3680
  }
3681
+ function versionAtLeast(current, target) {
3682
+ const parse = (text) => text.trim().replace(/^v/, "").split(".").map((part) => {
3683
+ const numeric = /^\d+/.exec(part);
3684
+ return numeric === null ? 0 : Number(numeric[0]);
3685
+ });
3686
+ const left = parse(current);
3687
+ const right = parse(target);
3688
+ const length = Math.max(left.length, right.length);
3689
+ for (let index = 0; index < length; index += 1) {
3690
+ const diff = (left[index] ?? 0) - (right[index] ?? 0);
3691
+ if (diff !== 0) return diff > 0;
3692
+ }
3693
+ return true;
3694
+ }
3633
3695
  function GeneralUpdateRow() {
3634
- const [phase, setPhase] = (0, import_react11.useState)({ kind: "checking" });
3696
+ const [phase, setPhase] = (0, import_react11.useState)(() => {
3697
+ const pending = readPendingUpdate();
3698
+ return pending !== null ? { kind: "updated", version: pending } : { kind: "checking" };
3699
+ });
3635
3700
  const [error, setError] = (0, import_react11.useState)("");
3636
3701
  const check = () => {
3637
3702
  setPhase({ kind: "checking" });
3638
3703
  setError("");
3639
- void checkSelfUpdate().then((result) => setPhase({ kind: "checked", check: result })).catch((err) => {
3704
+ void checkSelfUpdate().then((result) => {
3705
+ const pending = readPendingUpdate();
3706
+ if (pending !== null && result.current !== null && versionAtLeast(result.current, pending)) {
3707
+ clearPendingUpdate();
3708
+ setPhase({ kind: "checked", check: result });
3709
+ return;
3710
+ }
3711
+ setPhase({ kind: "checked", check: result });
3712
+ }).catch((err) => {
3640
3713
  setPhase({ kind: "checked", check: { current: null, latest: null, updateAvailable: false } });
3641
3714
  setError(messageOf3(err, "\u68C0\u67E5\u66F4\u65B0\u5931\u8D25"));
3642
3715
  });
3643
3716
  };
3644
- (0, import_react11.useEffect)(check, []);
3717
+ (0, import_react11.useEffect)(() => {
3718
+ if (readPendingUpdate() !== null) {
3719
+ void checkSelfUpdate().then((result) => {
3720
+ const pending = readPendingUpdate();
3721
+ if (pending !== null && result.current !== null && versionAtLeast(result.current, pending)) {
3722
+ clearPendingUpdate();
3723
+ setPhase({ kind: "checked", check: result });
3724
+ }
3725
+ }).catch(() => {
3726
+ });
3727
+ return;
3728
+ }
3729
+ check();
3730
+ }, []);
3645
3731
  const handleUpdate = (target, check0) => {
3646
3732
  setPhase({ kind: "updating", check: check0 });
3647
3733
  setError("");
@@ -3650,6 +3736,7 @@ function GeneralUpdateRow() {
3650
3736
  setPhase({ kind: "degraded", command: result.command, version: target });
3651
3737
  return;
3652
3738
  }
3739
+ writePendingUpdate(target);
3653
3740
  setPhase({ kind: "updated", version: target });
3654
3741
  }).catch((err) => {
3655
3742
  setPhase({ kind: "checked", check: check0 });
@@ -64,7 +64,9 @@ export type KnownInstallErrorKind = 'minimum-release-age' | 'version-incompatibl
64
64
  /** 整个包在 registry 上不存在(404)。 */
65
65
  | 'package-not-found'
66
66
  /** 依赖的安装脚本被 pnpm 10+ 默认拦截(ERR_PNPM_IGNORED_BUILDS),需用户批准构建。 */
67
- | 'build-scripts-ignored';
67
+ | 'build-scripts-ignored'
68
+ /** desktop profile 由 Electron 应用独占管理,外部 CLI 被拒。 */
69
+ | 'desktop-profile-locked';
68
70
  export interface KnownInstallError {
69
71
  kind: KnownInstallErrorKind;
70
72
  hint: string;
@@ -3,7 +3,7 @@ import { spawn } from 'node:child_process';
3
3
  import { existsSync, readdirSync, statSync } from 'node:fs';
4
4
  import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
5
5
  import { homedir } from 'node:os';
6
- import { delimiter, dirname, join } from 'node:path';
6
+ import { basename, delimiter, dirname, join } from 'node:path';
7
7
  import { ApiError } from "./api-client.js";
8
8
  import { FATAL_TGZ_DEFECTS, inspectTgz } from "./tgz-inspect.js";
9
9
  /** shim 探测超时:只判「活不活」,5s 足够。 */
@@ -82,13 +82,26 @@ function appCliRelativePath(platform) {
82
82
  function runAsNodeFromCurrentProcess(execPath, platform) {
83
83
  if (execPath === '')
84
84
  return null;
85
- const execDir = dirname(execPath);
86
- const candidates = platform === 'darwin'
87
- ? [join(dirname(execDir), 'Resources', 'app', 'lib', 'desktop-cli.js')]
88
- : [join(execDir, 'resources', 'app', 'lib', 'desktop-cli.js')];
89
- for (const cliJs of candidates) {
90
- if (isRunnableFile(execPath, platform) && existsSync(cliJs))
91
- return { executable: execPath, cliJs };
85
+ // 沿 execPath 向上逐级找 Resources/resources 下的 app/lib/desktop-cli.js,锁定「安装本体」:
86
+ // 主进程(execPath = <App>.app/Contents/MacOS/<bin>)一层就命中;helper/utility 进程
87
+ // (路径更深,如 Contents/Frameworks/… Helper.app/Contents/MacOS/…)多级也能命中。
88
+ // 本体自带的 CLI 与本插件同宿主,peer 校验版本天然一致 —— 这是所有通道里最可靠的一条。
89
+ let dir = dirname(execPath);
90
+ for (let depth = 0; depth < 6; depth += 1) {
91
+ const cliJs = platform === 'darwin'
92
+ ? join(dir, 'Resources', 'app', 'lib', 'desktop-cli.js')
93
+ : join(dir, 'resources', 'app', 'lib', 'desktop-cli.js');
94
+ if (isRunnableFile(execPath, platform) && existsSync(cliJs)) {
95
+ const appRoot = dirname(dir);
96
+ const candidate = { executable: execPath, cliJs };
97
+ if (appRoot.endsWith('.app'))
98
+ candidate.appName = basename(appRoot).replace(/\.app$/i, '');
99
+ return candidate;
100
+ }
101
+ const parent = dirname(dir);
102
+ if (parent === dir)
103
+ break;
104
+ dir = parent;
92
105
  }
93
106
  return null;
94
107
  }
@@ -197,6 +210,14 @@ export async function resolveDshCli(env = process.env, execPath = process.execPa
197
210
  const home = env.HOME ?? env.USERPROFILE ?? homedir();
198
211
  const rejected = [];
199
212
  const notes = [];
213
+ // 本体 CLI 永远优先,shim 只作兜底:应用内入口(desktop-cli.js,manageDesktopProfile=true)
214
+ // 与本插件同宿主 —— peer 校验版本天然一致,不受 desktop profile 独占限制,也不吃外部 shim
215
+ // 的历史顽疾(缺 --profile、版本错位、陈旧 shim)。插件必然装在某个宿主应用里,所以这条
216
+ // 路几乎总能命中;只有应用不在标准位置 / desktop-cli.js 缺失时才轮到外部 shim。
217
+ const runAsNode = findRunAsNode(platform, env, home, execPath, notes, kind, appRoots);
218
+ if (runAsNode !== null)
219
+ return { cli: runAsNode, rejected, notes };
220
+ notes.push('未找到宿主应用内的 CLI 入口(desktop-cli.js),回落外部 dsh shim');
200
221
  const candidates = [
201
222
  ...findShimsIn((env.PATH ?? '').split(delimiter), platform),
202
223
  ...findShimsIn(commonShimDirs(platform, home), platform),
@@ -207,8 +228,7 @@ export async function resolveDshCli(env = process.env, execPath = process.execPa
207
228
  return { cli: { kind: 'shim', path: shimPath }, rejected, notes };
208
229
  rejected.push({ kind: 'shim', path: shimPath, reason: probe.reason });
209
230
  }
210
- const runAsNode = findRunAsNode(platform, env, home, execPath, notes, kind, appRoots);
211
- return { cli: runAsNode, rejected, notes };
231
+ return { cli: null, rejected, notes };
212
232
  }
213
233
  /** 只要通道(兼容旧调用形态)。 */
214
234
  export async function discoverDshCli(env = process.env, execPath = process.execPath) {
@@ -316,6 +336,12 @@ export function parseKnownInstallError(stderr, packageName, version, profile) {
316
336
  }
317
337
  // pnpm 10+ 默认不执行依赖的安装脚本(供应链防护):插件依赖带 postinstall 的包会触发。
318
338
  // 这不是包坏了,是「需要用户显式批准」—— 给出批准入口,不替用户做供应链决定。
339
+ if (/managed exclusively by the Electron application/i.test(stderr)) {
340
+ return {
341
+ kind: 'desktop-profile-locked',
342
+ hint: 'desktop profile 由桌面应用独占管理,外部 dsh 命令行不能直接操作它。请把「薪人薪事市场」插件更新到 0.2.4 或更高版本(新版会自动改用应用内 CLI 入口),或在桌面应用的插件管理器中操作。',
343
+ };
344
+ }
319
345
  if (/ERR_PNPM_IGNORED_BUILDS|Ignored build scripts/i.test(stderr)) {
320
346
  const packages = parseIgnoredBuildPackages(stderr);
321
347
  return {
@@ -12,7 +12,10 @@ import { type InstallOutcome, type InstallerDeps } from './installer.ts';
12
12
  export declare const SELF_PACKAGE_NAME = "@xrxs-ai/dsh-xrxs-plugins-store";
13
13
  /** 当前运行实例的版本(包根 package.json);读不到为 null(极端情况:裸文件运行)。
14
14
  * 依次尝试:模块相对层级(tsc 产物 lib/host/ 与源码 src/host/ 都是上一级的上一级)、
15
- * 按包名 resolve(profile 安装布局变化时的兜底);读到的包名必须匹配,防止层级猜错读成别的包。 */
15
+ * 按包名 resolve(profile 安装布局变化时的兜底);读到的包名必须匹配,防止层级猜错读成别的包。
16
+ * 模块级缓存且首次读取后不再重读:这里要报的是「运行实例」的版本,不是磁盘版本 ——
17
+ * 更新落盘后宿主可能只重挂 client 而不重载 host 模块,重读磁盘会把还在运行的旧实例
18
+ * 报成新版本;重启后 host 模块重新加载,缓存自然取到新版本。 */
16
19
  export declare function currentSelfVersion(): string | null;
17
20
  export interface SelfUpdateCheck {
18
21
  /** 当前运行实例版本;读不到为 null(无法比较,不可更新) */
@@ -21,7 +24,9 @@ export interface SelfUpdateCheck {
21
24
  latest: string | null;
22
25
  updateAvailable: boolean;
23
26
  }
24
- /** 查 npm latest 并与当前版本比较;registry 查询失败时 latest 为 null(不抛,便于 UI 展示「检查失败」)。 */
27
+ /** 查 npm latest 并与当前版本比较;registry 查询失败时 latest 为 null(不抛,便于 UI 展示「检查失败」)。
28
+ * 当前版本走模块级缓存:报运行实例的版本 —— 更新落盘、宿主尚未重载时,磁盘已是新版本,
29
+ * 但内存里跑的还是旧实例,报旧值才能让 client 半的「已更新待重启」记录正确保留到重启。 */
25
30
  export declare function checkSelfUpdate(): Promise<SelfUpdateCheck>;
26
31
  /** 应用更新:复用安装链路装确切版本(不装 latest tag,避免「检查到装的」漂移)。 */
27
32
  export declare function applySelfUpdate(version: string, deps: InstallerDeps): Promise<InstallOutcome>;
@@ -20,7 +20,10 @@ const LATEST_TIMEOUT_MS = 10_000;
20
20
  let cachedVersion = null;
21
21
  /** 当前运行实例的版本(包根 package.json);读不到为 null(极端情况:裸文件运行)。
22
22
  * 依次尝试:模块相对层级(tsc 产物 lib/host/ 与源码 src/host/ 都是上一级的上一级)、
23
- * 按包名 resolve(profile 安装布局变化时的兜底);读到的包名必须匹配,防止层级猜错读成别的包。 */
23
+ * 按包名 resolve(profile 安装布局变化时的兜底);读到的包名必须匹配,防止层级猜错读成别的包。
24
+ * 模块级缓存且首次读取后不再重读:这里要报的是「运行实例」的版本,不是磁盘版本 ——
25
+ * 更新落盘后宿主可能只重挂 client 而不重载 host 模块,重读磁盘会把还在运行的旧实例
26
+ * 报成新版本;重启后 host 模块重新加载,缓存自然取到新版本。 */
24
27
  export function currentSelfVersion() {
25
28
  if (cachedVersion !== null)
26
29
  return cachedVersion;
@@ -50,7 +53,9 @@ export function currentSelfVersion() {
50
53
  }
51
54
  return cachedVersion;
52
55
  }
53
- /** 查 npm latest 并与当前版本比较;registry 查询失败时 latest 为 null(不抛,便于 UI 展示「检查失败」)。 */
56
+ /** 查 npm latest 并与当前版本比较;registry 查询失败时 latest 为 null(不抛,便于 UI 展示「检查失败」)。
57
+ * 当前版本走模块级缓存:报运行实例的版本 —— 更新落盘、宿主尚未重载时,磁盘已是新版本,
58
+ * 但内存里跑的还是旧实例,报旧值才能让 client 半的「已更新待重启」记录正确保留到重启。 */
54
59
  export async function checkSelfUpdate() {
55
60
  const current = currentSelfVersion();
56
61
  let latest = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xrxs-ai/dsh-xrxs-plugins-store",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "DSH 私有插件市场插件(静态持久 bundle,双 face)",
5
5
  "type": "module",
6
6
  "license": "MIT",