@iasiv5/dsh-skins 1.5.26 → 1.5.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm](https://img.shields.io/npm/v/@iasiv5/dsh-skins?label=npm)](https://www.npmjs.com/package/@iasiv5/dsh-skins)
4
4
  [![CI](https://img.shields.io/github/actions/workflow/status/iasiv5/dsh-skins/ci.yml?branch=main&label=CI)](../../actions/workflows/ci.yml)
5
5
  [![License](https://img.shields.io/github/license/iasiv5/dsh-skins?label=License)](./LICENSE)
6
- [![DSH](https://img.shields.io/badge/DSH-0.2.1--rc.5%20verified-2563eb)](#faq)
6
+ [![DSH](https://img.shields.io/badge/DSH-0.2.2--rc.1%20verified-2563eb)](#faq)
7
7
 
8
8
  English · [中文](./README.md)
9
9
 
@@ -181,7 +181,7 @@ Pick "DeepSeek Harness (Official)" in the skin switcher, or open `/?skin=officia
181
181
  Update duty has moved to the dsh-m marketplace and the DSH CLI (ADR-0008); the skin switcher only handles skins and personalization.
182
182
 
183
183
  **Which DSH Web versions are supported?**
184
- Verified with DSH Web `0.2.0-rc.2`, `0.2.1-rc.3` and `0.2.1-rc.4` (the 1.5.21 gate suite ran green on rc.4). `0.2.1-rc.5` is a contract-surface equivalent re-release of the same series (host web-app patch is zero-diff against rc.4), so the rc.4 conclusions carry over to rc.5. Later rc builds of the same series are expected to work, but unverified versions carry no promise. Requires DSH `0.2.0-rc.1` or later; older DSH versions are blocked from upgrading to 1.5.8+ by the peer dependency floor.
184
+ Verified with DSH Web `0.2.0-rc.2`, `0.2.1-rc.3` and `0.2.1-rc.4` (the 1.5.21 gate suite ran green on rc.4). `0.2.1-rc.5` is a contract-surface equivalent re-release of the same series (host web-app patch is zero-diff against rc.4), so the rc.4 conclusions carry over to rc.5. `0.2.2-rc.1`, the first release of a new minor line, has been live-verified (2026-11-04: settings endpoint 200, client bundle delivered normally through the upgraded host static-asset path; the host webserver/frontend-static evolution was audited dimension-by-dimension as non-replacement-surface). Later rc builds of the same series are expected to work, but unverified versions carry no promise. Requires DSH `0.2.0-rc.1` or later; older DSH versions are blocked from upgrading to 1.5.8+ by the peer dependency floor.
185
185
 
186
186
  **Is the Desktop profile supported?**
187
187
  Yes. The DSH Desktop app and the Web profile are installed independently and do not affect each other; the desktop form (solid chrome + wallpaper in the conversation area) is described under "The Desktop profile". Verified with DSH Desktop `0.2.1-rc.5`.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # node scripts/verify-readme-pairing.mjs --write
5
- README.md: 45bc273f96d976a8769236a075571436626855a3
6
- README.en.md: 93599a1f0c93bf21da5d38e58b531a8446cb44c6
5
+ README.md: 4be212a7b82fc54cfbc2be9ff748b8b01028ac08
6
+ README.en.md: 2500fc04090a27ad6392207de2bda045531e5e18
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm](https://img.shields.io/npm/v/@iasiv5/dsh-skins?label=npm)](https://www.npmjs.com/package/@iasiv5/dsh-skins)
4
4
  [![CI](https://img.shields.io/github/actions/workflow/status/iasiv5/dsh-skins/ci.yml?branch=main&label=CI)](../../actions/workflows/ci.yml)
5
5
  [![License](https://img.shields.io/github/license/iasiv5/dsh-skins?label=License)](./LICENSE)
6
- [![DSH](https://img.shields.io/badge/DSH-0.2.1--rc.5%20verified-2563eb)](#faq)
6
+ [![DSH](https://img.shields.io/badge/DSH-0.2.2--rc.1%20verified-2563eb)](#faq)
7
7
 
8
8
  [English](./README.en.md) · 中文
9
9
 
@@ -181,7 +181,7 @@ URL 也能切皮肤:`/?skin=official`、`/?skin=openbmc`、`/?skin=uefi-harnes
181
181
  更新职责已移交 dsh-m 市场与 DSH CLI(ADR-0008);皮肤切换器只负责换肤与个性化。
182
182
 
183
183
  **支持哪些 DSH Web 版本?**
184
- 已使用 DSH Web `0.2.0-rc.2`、`0.2.1-rc.3` 与 `0.2.1-rc.4` 验证(1.5.21 全量门禁在 rc.4 上跑绿);`0.2.1-rc.5` 为同系列契约面等价重发布(宿主 web-app patch 相对 rc.4 零 diff),rc.4 的核验结论按等价口径覆盖 rc.5。同系列后续 rc 版本理论上兼容,未经验证的版本不作承诺。最低支持 DSH `0.2.0-rc.1`:更旧的 DSH 版本会被 peer 依赖门槛挡住,无法升级到 1.5.8+。
184
+ 已使用 DSH Web `0.2.0-rc.2`、`0.2.1-rc.3` 与 `0.2.1-rc.4` 验证(1.5.21 全量门禁在 rc.4 上跑绿);`0.2.1-rc.5` 为同系列契约面等价重发布(宿主 web-app patch 相对 rc.4 零 diff),rc.4 的核验结论按等价口径覆盖 rc.5;`0.2.2-rc.1` 为新 minor 线首轮,已实机验证(2026-11-04:设置端点 200、客户端产物经宿主升级后的静态资源通道正常下发,宿主 webserver/frontend-static 演进经逐维审计定性为非替换面)。同系列后续 rc 版本理论上兼容,未经验证的版本不作承诺。最低支持 DSH `0.2.0-rc.1`:更旧的 DSH 版本会被 peer 依赖门槛挡住,无法升级到 1.5.8+。
185
185
 
186
186
  **支持 Desktop profile 吗?**
187
187
  支持。DSH Desktop 应用与 Web profile 各自独立安装、互不影响;桌面形态(实色外壳 + 会话区壁纸)见「Desktop profile 上的形态」。已使用 DSH Desktop `0.2.1-rc.5` 验证。
package/lib/client.js CHANGED
@@ -1867,7 +1867,11 @@ ${references.join("\n")}`,
1867
1867
  // paid, and — combined with the fixed 360px list column — clipped the
1868
1868
  // gear column at the pop's own edge on phones (field report 2026-10-14:
1869
1869
  // 手机上齿轮被截半 + 横向滚动条).
1870
- ".dsh-skins-pop{position:fixed;z-index:60;box-sizing:border-box;display:flex;flex-direction:column;gap:8px;width:min(390px,calc(100vw - 32px));max-height:calc(100vh - 24px);padding:14px;border:1px solid var(--dsw-alias-border-l2);border-radius:14px;background:var(--dsw-alias-bg-elevated,var(--dsw-alias-bg-overlay));background:color-mix(in srgb,var(--dsw-alias-bg-base,#1f1f1f) 86%,transparent);backdrop-filter:blur(14px) saturate(1.3);-webkit-backdrop-filter:blur(14px) saturate(1.3);color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3,0 8px 24px rgba(0,0,0,.14));overflow-y:auto;transition:width .2s ease-out}",
1870
+ // 窄屏抽屉层叠(2026-11-05 修复):弹层经 portal 挂在 body 下,与官方侧栏
1871
+ // 抽屉同层竞争。dsh-client-ui-layout 在视口 <768px 时抽屉遮罩为 z-70、侧栏
1872
+ // 列为 z-71;旧值 z-60 让弹层整块压在抽屉之下(只余遮罩模糊后的轮廓,点不到)。
1873
+ // z-80 高于抽屉、低于宿主 z-100 起的各层(ADR-0021 的 z 全集)。
1874
+ ".dsh-skins-pop{position:fixed;z-index:80;box-sizing:border-box;display:flex;flex-direction:column;gap:8px;width:min(390px,calc(100vw - 32px));max-height:calc(100vh - 24px);padding:14px;border:1px solid var(--dsw-alias-border-l2);border-radius:14px;background:var(--dsw-alias-bg-elevated,var(--dsw-alias-bg-overlay));background:color-mix(in srgb,var(--dsw-alias-bg-base,#1f1f1f) 86%,transparent);backdrop-filter:blur(14px) saturate(1.3);-webkit-backdrop-filter:blur(14px) saturate(1.3);color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3,0 8px 24px rgba(0,0,0,.14));overflow-y:auto;transition:width .2s ease-out}",
1871
1875
  // Slim themed scrollbars for the shell's own scroll region (list-only
1872
1876
  // popover): thin + token-colored thumb, WebKit and Firefox both covered.
1873
1877
  ".dsh-skins-pop{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent}",
@@ -2969,7 +2973,7 @@ ${references.join("\n")}`,
2969
2973
  if (typeof extension !== "string" || !/^[a-z0-9]+$/.test(extension)) {
2970
2974
  throw new RangeError(`builtinAssetUrl: invalid extension ${JSON.stringify(extension)}`);
2971
2975
  }
2972
- const rev = "1.5.26";
2976
+ const rev = "1.5.28";
2973
2977
  return `/dsh-skins/assets/b_${skinId}_${assetKey}.${extension}?v=${rev}`;
2974
2978
  }
2975
2979
 
@@ -3176,6 +3180,10 @@ ${references.join("\n")}`,
3176
3180
  }
3177
3181
 
3178
3182
  // src/client/skins/define-skin.js
3183
+ var FONT_TOKENS = {
3184
+ text: "--dsh-font-family-text-default",
3185
+ code: "--dsh-font-family-code-default"
3186
+ };
3179
3187
  var REQUIRED = [
3180
3188
  "id",
3181
3189
  "label",
@@ -3185,6 +3193,7 @@ ${references.join("\n")}`,
3185
3193
  "anchor",
3186
3194
  "bodyAttribute",
3187
3195
  "riding",
3196
+ "fonts",
3188
3197
  "scrim",
3189
3198
  "blur",
3190
3199
  "glassVar",
@@ -3241,6 +3250,28 @@ ${references.join("\n")}`,
3241
3250
  }
3242
3251
  return wallpaper;
3243
3252
  }
3253
+ function deriveFonts(fonts) {
3254
+ if (fonts === null || typeof fonts !== "object" || Array.isArray(fonts)) {
3255
+ throw new Error("fonts must be an object keyed by font slot");
3256
+ }
3257
+ const derived = {};
3258
+ for (const [slot, value] of Object.entries(fonts)) {
3259
+ if (!Object.hasOwn(FONT_TOKENS, slot)) throw new Error(`Unknown font slot: ${slot}`);
3260
+ const bad = `font slot "${slot}": value must be null, a non-empty string, or { light, dark }`;
3261
+ if (value === null) continue;
3262
+ if (typeof value === "string") {
3263
+ if (value === "") throw new Error(bad);
3264
+ derived[FONT_TOKENS[slot]] = { light: value, dark: value };
3265
+ continue;
3266
+ }
3267
+ const keys = typeof value === "object" && !Array.isArray(value) ? Object.keys(value) : [];
3268
+ if (keys.length !== 2 || !keys.includes("light") || !keys.includes("dark") || typeof value.light !== "string" || value.light === "" || typeof value.dark !== "string" || value.dark === "") {
3269
+ throw new Error(bad);
3270
+ }
3271
+ derived[FONT_TOKENS[slot]] = { light: value.light, dark: value.dark };
3272
+ }
3273
+ return derived;
3274
+ }
3244
3275
  function defineSkin(spec) {
3245
3276
  for (const key of Object.keys(spec)) {
3246
3277
  if (!KNOWN_KEYS.has(key)) throw new Error(`Unknown spec key: ${key}`);
@@ -3259,13 +3290,16 @@ ${references.join("\n")}`,
3259
3290
  spec.backgroundArt ? { art: { mime: spec.backgroundArt.mime, url: spec.backgroundArt.url } } : {},
3260
3291
  spec.builtinAssets ?? {}
3261
3292
  );
3293
+ const fontTokens = deriveFonts(spec.fonts);
3294
+ const constantBase = spec.constantTokens ?? {};
3295
+ const constantTokens = Object.keys(fontTokens).length > 0 || Object.keys(constantBase).length > 0 ? { ...constantBase, ...fontTokens } : null;
3262
3296
  const table = {
3263
3297
  bodyAttribute: spec.bodyAttribute,
3264
3298
  titleBrand: spec.titleBrand,
3265
3299
  favicon: spec.favicon,
3266
3300
  anchor: spec.anchor,
3267
3301
  riding: spec.riding,
3268
- constantTokens: spec.constantTokens ?? null,
3302
+ constantTokens,
3269
3303
  scrim: buildScrim(spec),
3270
3304
  blur: spec.blur,
3271
3305
  glassVar: spec.glassVar,
@@ -3321,6 +3355,8 @@ ${references.join("\n")}`,
3321
3355
  "--dsw-specific-bubble": { light: "rgba(184, 67, 63, 0.10)", dark: "rgba(24, 24, 34, 0.90)" },
3322
3356
  "--dsw-specific-bubble-highlight": { light: "rgba(184, 67, 63, 0.18)", dark: "rgba(40, 40, 56, 0.92)" }
3323
3357
  },
3358
+ // 字体槽位(ADR-0025):宿主跟随。
3359
+ fonts: { text: null, code: null },
3324
3360
  scrim: { kind: "overlay", coefficient: 30, light: "252, 250, 246", dark: "16, 16, 26" },
3325
3361
  blur: { max: 12 },
3326
3362
  glassVar: "--dsh-mrz-glass-blur",
@@ -3496,17 +3532,13 @@ ${references.join("\n")}`,
3496
3532
  "--dsw-alias-interactive-bg-hover-accent": { light: "rgba(140, 206, 63, 0.14)", dark: "rgba(165, 212, 64, 0.16)" },
3497
3533
  "--dsw-specific-bubble": { light: "rgba(0, 138, 191, 0.10)", dark: "rgba(20, 41, 60, 0.90)" },
3498
3534
  "--dsw-specific-bubble-highlight": { light: "rgba(0, 138, 191, 0.18)", dark: "rgba(29, 61, 85, 0.90)" },
3499
- "--dsw-font-family": {
3500
- light: '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif',
3501
- dark: '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif'
3502
- },
3503
- "--ds-font-family-code": {
3504
- light: '"JetBrains Mono", ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace',
3505
- dark: '"JetBrains Mono", ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace'
3506
- },
3507
3535
  "--dsh-scrollbar-thumb": { light: "var(--dsw-alias-scrollbar-bg-l2)", dark: "var(--dsw-alias-scrollbar-bg-l2)" },
3508
3536
  "--dsh-scrollbar-thumb-hover": { light: "var(--dsw-alias-scrollbar-hover-l2)", dark: "var(--dsw-alias-scrollbar-hover-l2)" }
3509
3537
  },
3538
+ // 字体槽位(ADR-0025):宿主跟随。JetBrains Mono 历史代码栈封存于
3539
+ // docs/adr/0025-font-slots-and-host-tracking.md「JBM 封存」,一行
3540
+ // code: '<封存栈>' 即复活。
3541
+ fonts: { text: null, code: null },
3510
3542
  scrim: {
3511
3543
  kind: "baked-gradient",
3512
3544
  stops: {
@@ -3667,12 +3699,10 @@ ${references.join("\n")}`,
3667
3699
  "--dsw-alias-interactive-bg-hover": { light: "rgba(101, 83, 216, 0.09)", dark: "rgba(169, 156, 255, 0.11)" },
3668
3700
  "--dsw-alias-interactive-bg-active": { light: "rgba(101, 83, 216, 0.15)", dark: "rgba(169, 156, 255, 0.18)" },
3669
3701
  "--dsw-specific-bubble": { light: "rgba(101, 83, 216, 0.11)", dark: "rgba(60, 48, 108, 0.90)" },
3670
- "--dsw-specific-bubble-highlight": { light: "rgba(101, 83, 216, 0.18)", dark: "rgba(78, 63, 138, 0.92)" },
3671
- "--dsw-font-family": {
3672
- light: '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif',
3673
- dark: '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif'
3674
- }
3702
+ "--dsw-specific-bubble-highlight": { light: "rgba(101, 83, 216, 0.18)", dark: "rgba(78, 63, 138, 0.92)" }
3675
3703
  },
3704
+ // 字体槽位(ADR-0025):宿主跟随。
3705
+ fonts: { text: null, code: null },
3676
3706
  scrim: {
3677
3707
  kind: "baked-gradient",
3678
3708
  stops: {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@iasiv5/dsh-skins",
3
3
  "description": "DSH Web 皮肤插件:多套品牌皮肤侧栏热切换。",
4
4
  "icon": "./icon.svg",
5
- "version": "1.5.26",
5
+ "version": "1.5.28",
6
6
  "homepage": "https://github.com/iasiv5/dsh-skins#readme",
7
7
  "repository": {
8
8
  "type": "git",