@linxin666/dsh-client-ui-skin-center 0.3.2 → 0.3.4

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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the 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-docs.mjs --write <dir>
5
- README.md: 42f90dbff0368a591f28ced7509f7fe522ee0f64
6
- README.zh.md: f617359c4750785da8f0731aec2cca9cacf77e7f
5
+ README.md: 04b1c524d8222926a64008329b4fb9454ab2f0c0
6
+ README.zh.md: 56cd3679ad66705e5543409086911be3bf723fbd
package/README.md CHANGED
@@ -22,9 +22,9 @@ dsh plugin --profile web add @linxin666/dsh-client-ui-skin-center
22
22
  # From the repo (dev): dsh plugin --profile web add link:$(pwd)/packages/skins/skin-center
23
23
  ```
24
24
 
25
- `$(pwd)` is your clone of the dsh-web-ui monorepo. Only the default skin (blue-fantasy) ships inside this package; every other skin installs on demand from dsh-market.com into `$DSH_HOME/skins/<id>/`, and community skins are plain directories in the same place (no install command, no restart — reopen the card or reload to pick them up). A fresh install activates blue-fantasy by default (host seed); an update whose active skin is no longer available falls back to the stock look. The package ships `skins/blue-fantasy` only; the remaining skins stay in the repository under `skins/` as the market-build and gallery source and are never published in the package.
25
+ `$(pwd)` is your clone of the dsh-web monorepo. Only the default skin (blue-fantasy) ships inside this package; every other skin installs on demand from dsh-market.com into `$DSH_HOME/skins/<id>/`, and community skins are plain directories in the same place (no install command, no restart — reopen the card or reload to pick them up). A fresh install activates blue-fantasy by default (host seed); an update whose active skin is no longer available falls back to the stock look. The package ships `skins/blue-fantasy` only; the remaining skins stay in the repository under `skins/` as the market-build and gallery source and are never published in the package.
26
26
 
27
- skin-center is a self-contained bundle meeting the official DSH plugin standard (`dsh.bundle.patch` points to `cordis.patch.yml`); it can also be installed via git: `dsh plugin --profile web add github:<org>/dsh-web-ui#<sha>` (the `prepare` script builds `lib/` in place). pnpm ≥10 requires authorizing `allowBuilds` before installing a git dependency; a local `link:` install has no such requirement.
27
+ skin-center is a self-contained bundle meeting the official DSH plugin standard (`dsh.bundle.patch` points to `cordis.patch.yml`); it can also be installed via git: `dsh plugin --profile web add github:<org>/dsh-web#<sha>` (the `prepare` script builds `lib/` in place). pnpm ≥10 requires authorizing `allowBuilds` before installing a git dependency; a local `link:` install has no such requirement.
28
28
 
29
29
  ## Configuration
30
30
 
@@ -40,7 +40,7 @@ skin-center is a self-contained bundle meeting the official DSH plugin standard
40
40
  - All `/api/skin-center/*` routes are same-origin only: writes reject cross-site requests (Sec-Fetch-Site / Origin fence), and asset reads are contained inside each skin directory (path escapes fail closed).
41
41
  - Skin CSS is sanitized (whitelist) before serving; `patches.css` (L3) is arbitrary CSS by design and disclosed as such — it runs with full page styling power and is not a security boundary.
42
42
  - The custom-theme editor emits only fixed declarations from `CUSTOM_THEME_ALLOWED_TOKENS`, each verified against the official token registry. User input is normalized color/contrast data and never becomes a selector, URL or free-form CSS payload.
43
- - `hooks.mjs` is trusted code that shares this repository's review and release; it is served same-origin only and its import/apply errors can never take the static skin down.
43
+ - `hooks.mjs` is trusted code that shares this repository's review and release; it is served same-origin only and its import/apply errors can never take the static skin down. Hooks run for built-in skins, and for user-directory skins installed from the official DSH Market whose `dsh-market.provenance.json` sha256-pins the on-disk `skin.json` and hooks entry to the market-served bytes (verified by `src/provenance.ts`, issue #1073); a missing or mismatched provenance — hand-dropped or tampered directories — keeps the hooks facet refused while the declarative parts still load.
44
44
 
45
45
  ## Known limitations
46
46
 
@@ -48,6 +48,10 @@ skin-center is a self-contained bundle meeting the official DSH plugin standard
48
48
  - Plugins that do not output semantic attributes (and have no stable DOM anchors) receive L1 token coverage only.
49
49
  - A skin video background keeps playing regardless of the wallpaper pause-on-hidden setting; pause-on-hidden applies to the Wallpaper Engine bridge only.
50
50
 
51
+ ## Telemetry
52
+
53
+ The browser half sends one anonymous install heartbeat per UTC day to dsh-market.com: a random localStorage id plus this package's name, nothing else. The server stores only a salted hash of that id, never IP addresses, and exposes aggregate counts only. See [docs/telemetry.md](../../../docs/telemetry.md) for the full contract.
54
+
51
55
  ## Directory structure
52
56
 
53
57
  ```
@@ -57,6 +61,7 @@ skins/skin-center/
57
61
  src/core/css-safety/ # lightningcss scoping + whitelist pipeline
58
62
  src/index.ts # host entry: routes, tapIndex adapter, legacy bridge
59
63
  src/skin-repo.ts # dual-source skin catalog (built-in + $DSH_HOME/skins)
64
+ src/provenance.ts # official-market install provenance verification (hooks trust)
60
65
  src/routes-v2.ts # /api/skin-center/v2/* routes
61
66
  src/tap-index-adapter.ts # the single tapIndex adapter (anti-FOUC)
62
67
  src/active-state.ts # active-skin selection persistence
package/README.zh.md CHANGED
@@ -22,9 +22,9 @@ dsh plugin --profile web add @linxin666/dsh-client-ui-skin-center
22
22
  # 仓库开发:dsh plugin --profile web add link:$(pwd)/packages/skins/skin-center
23
23
  ```
24
24
 
25
- `$(pwd)` 是 dsh-web-ui monorepo 的本地克隆。只有默认皮肤(蓝色幻想)随这个包发布;其余皮肤在 dsh-market.com 按需安装到 `$DSH_HOME/skins/<id>/`,社区皮肤同样是放进该目录的普通目录(均无安装命令、无需重启——重开卡片或刷新页面即收录)。新装默认激活蓝色幻想(宿主种子);升级后原激活皮肤已不可用时回退官方主题。包内只发布 `skins/blue-fantasy`;其余皮肤保留在仓库 `skins/` 下,作为市场构建与画廊的目录来源,绝不进入 npm 包。
25
+ `$(pwd)` 是 dsh-web monorepo 的本地克隆。只有默认皮肤(蓝色幻想)随这个包发布;其余皮肤在 dsh-market.com 按需安装到 `$DSH_HOME/skins/<id>/`,社区皮肤同样是放进该目录的普通目录(均无安装命令、无需重启——重开卡片或刷新页面即收录)。新装默认激活蓝色幻想(宿主种子);升级后原激活皮肤已不可用时回退官方主题。包内只发布 `skins/blue-fantasy`;其余皮肤保留在仓库 `skins/` 下,作为市场构建与画廊的目录来源,绝不进入 npm 包。
26
26
 
27
- 皮肤中心是符合官方 DSH 插件标准的自包含 bundle(`dsh.bundle.patch` 指向 `cordis.patch.yml`);也可经 git 安装:`dsh plugin --profile web add github:<org>/dsh-web-ui#<sha>`(`prepare` 脚本就地构建 `lib/`)。pnpm ≥10 安装 git 依赖前需授权 `allowBuilds`;本地 `link:` 安装无此要求。
27
+ 皮肤中心是符合官方 DSH 插件标准的自包含 bundle(`dsh.bundle.patch` 指向 `cordis.patch.yml`);也可经 git 安装:`dsh plugin --profile web add github:<org>/dsh-web#<sha>`(`prepare` 脚本就地构建 `lib/`)。pnpm ≥10 安装 git 依赖前需授权 `allowBuilds`;本地 `link:` 安装无此要求。
28
28
 
29
29
  ## 配置
30
30
 
@@ -40,7 +40,7 @@ dsh plugin --profile web add @linxin666/dsh-client-ui-skin-center
40
40
  - 所有 `/api/skin-center/*` 路由仅接受同源请求:写操作拒绝跨站请求(Sec-Fetch-Site / Origin 围栏),资产读取限定在各皮肤目录之内(路径逃逸 fail-closed)。
41
41
  - 皮肤 CSS 在服务前经白名单净化;`patches.css`(L3)按设计就是任意 CSS 并如实公示——它拥有完整页面样式能力,不构成安全边界。
42
42
  - 自定义主题编辑器只会从 `CUSTOM_THEME_ALLOWED_TOKENS` 生成固定声明,且每个 token 都对照官方 token 注册表校验。用户输入只作为规范化后的颜色/对比度数据,不会成为选择器、URL 或自由 CSS 载荷。
43
- - `hooks.mjs` 是与本仓库同审同发的受信代码,仅同源 serve,其 import/apply 错误永远不会拖垮静态皮肤。
43
+ - `hooks.mjs` 是与本仓库同审同发的受信代码,仅同源 serve,其 import/apply 错误永远不会拖垮静态皮肤。hooks 对内置皮肤放行;对用户目录皮肤,仅当其从官方 DSH 市场安装且 `dsh-market.provenance.json` 以 sha256 钉住磁盘上的 `skin.json` 与 hooks 入口字节时放行(由 `src/provenance.ts` 校验,issue #1073);provenance 缺失或不匹配——手工投放或被篡改的目录——hooks facet 保持拒绝,声明式部分仍正常加载。
44
44
 
45
45
  ## 已知限制
46
46
 
@@ -48,6 +48,10 @@ dsh plugin --profile web add @linxin666/dsh-client-ui-skin-center
48
48
  - 不输出语义属性(且无稳定 DOM 锚点)的插件只享受 L1 token 覆盖。
49
49
  - 皮肤视频背景不受壁纸「隐藏时暂停」设置影响;该设置仅作用于 Wallpaper Engine 桥。
50
50
 
51
+ ## 数据遥测
52
+
53
+ 浏览器半区每个 UTC 日向 dsh-market.com 发送一次匿名安装心跳:仅含一个 localStorage 随机 ID 与本包名,无其他数据。服务端只存储该 ID 的加盐哈希,不存 IP,且只暴露聚合计数。完整契约见 [docs/telemetry.md](../../../docs/telemetry.md)。
54
+
51
55
  ## 目录结构
52
56
 
53
57
  ```
@@ -57,6 +61,7 @@ skins/skin-center/
57
61
  src/core/css-safety/ # lightningcss 作用域限定 + 白名单管线
58
62
  src/index.ts # host 入口:路由、tapIndex 适配器、旧版迁移桥
59
63
  src/skin-repo.ts # 双来源皮肤目录册(内置 + $DSH_HOME/skins)
64
+ src/provenance.ts # 官方市场安装 provenance 校验(hooks 信任)
60
65
  src/routes-v2.ts # /api/skin-center/v2/* 路由
61
66
  src/tap-index-adapter.ts # 单一 tapIndex 适配器(防 FOUC)
62
67
  src/active-state.ts # 活动皮肤选择持久化
@@ -37,6 +37,24 @@ manifests would be rejected by their own validator. Optional legal metadata
37
37
  (`license`, `licenseUrl`, `noticeUrl`, `sourceUrl`, `attribution`) is
38
38
  first-class in v2.
39
39
 
40
+ ## Hooks trust model
41
+
42
+ `hooks.mjs` is trusted executable code that shares this repository's review
43
+ and release. It is served verbatim over `GET /skins/<id>/hooks.mjs` only for:
44
+
45
+ - **built-in skins** — shipped inside the skin-center npm package, same
46
+ review and release by definition;
47
+ - **official-market installs** — user-directory skins carrying a
48
+ `dsh-market.provenance.json` whose sha256 pins the on-disk `skin.json`
49
+ and hooks entry to the bytes the official DSH Market served (the market
50
+ content is built from this repository, so a hash match means the bytes
51
+ are the reviewed ones). Verification lives in `src/provenance.ts` and
52
+ fails closed: any missing, foreign-source or mismatched provenance keeps
53
+ the hooks facet refused with a catalog warning while the declarative
54
+ parts (skin.css / patches.css / assets) still load (issue #1073).
55
+
56
+ Locally dropped or third-party skin directories never run hooks.
57
+
40
58
  ## Loader-side rules (pinned here, enforced in M2)
41
59
 
42
60
  - All skin CSS is force-scoped under `html[data-dsh-skin="<id>"]` by the
@@ -45,7 +45,7 @@
45
45
  | `data-dsh-wallpaper-active` | html + body(body/html 级,另行管理) | WE 壁纸挂载期间置 `true`,卸载 / 禁用清除;供皮肤 CSS 与壁纸中和规则锚定(#734) |
46
46
  | `data-dsh-wallpaper-surface` | 官方 shell 全视口背景元素 + 侧栏工作区淡化条(元素级) | `WallpaperController.markWallpaperSurfaces()` 在 WE 壁纸挂载期间打标(全视口 bg-base 背景 + `data-slot="sidebar.workspaces"` 内渐变淡化条),命中 `html[data-dsh-wallpaper-active] [data-dsh-wallpaper-surface]` 中和;卸载清除,不含哈希类依赖(#734) |
47
47
 
48
- ## part 组(31 行,含各 owner 行)
48
+ ## part 组(38 行,含各 owner 行)
49
49
 
50
50
  shell 区域(owner: shell):
51
51
 
@@ -59,6 +59,7 @@ shell 区域(owner: shell):
59
59
  | `queue-dock` | 排队条;`[data-queue-dock]` |
60
60
  | `turn-tail` | turn 尾行;`[data-turn-tail]` |
61
61
  | `resize-handle` | 列宽手柄;`[data-side]` |
62
+ | `new-session` | 侧栏新会话按钮;官方稳定属性落地前由兼容适配器从 `button[class*="newSession"]` 补打,皮肤不得依赖本地化文案 |
62
63
 
63
64
  family / 插件区域:
64
65
 
@@ -101,8 +102,14 @@ family / 插件区域:
101
102
  | `row` | session-id | 会话列表行;面板内行容器(`[data-dsh-part="row"]`) |
102
103
  | `copy` | session-id | 每行复制按钮;`button[data-dsh-part="copy"]` |
103
104
  | `search` | session-id | 面板搜索输入框;`input[type="search"][data-dsh-part="search"]` |
105
+ | `sprite` | miku-pet | 宠物帧舞台;`[data-dsh-plugin="miku-pet"] [data-dsh-part="sprite"]` |
106
+ | `menu` | miku-pet | 悬停菜单(两级);`[data-dsh-part="menu"]` |
107
+ | `stats` | miku-pet | 左侧属性彩条;`[data-dsh-part="stats"]` |
108
+ | `shop` | miku-pet | 商店居中窗口;`[data-dsh-part="shop"]` |
109
+ | `bubble` | miku-pet | 对话气泡;`[data-dsh-part="bubble"]` |
110
+ | `float` | miku-pet | 互动飘字;`[data-dsh-part="float"]` |
104
111
 
105
- ## plugin 组(12 个,含停更 aionui-panel)
112
+ ## plugin 组(13 个,含停更 aionui-panel)
106
113
 
107
114
  | data-dsh-plugin | owner | 锚定方式 |
108
115
  | --- | --- | --- |
@@ -111,13 +118,14 @@ family / 插件区域:
111
118
  | `git-graph` | dsh-git-graph | slot entry id `git-graph`;`[data-gitgraph-chip-anchor]` / `[data-gitgraph-dialog]` |
112
119
  | `pet` | dsh-pet | `[data-dsh-pet-root]`;一级设置分区 settings.section id `pet`(只列内置与已安装宠物) |
113
120
  | `remote-web-ui` | dsh-remote-web-ui | slot entry id `remote-web-ui` |
114
- | `web-ui-settings` | dsh-web-ui-settings | settings.section id `web-ui-plugins` |
121
+ | `web-ui-settings` | dsh-web-settings | settings.section id `web-ui-plugins` |
115
122
  | `skill-explorer` | dsh-skill-explorer | `[data-dsh-skill-explorer-view]` / `[data-dsh-skill-explorer-entry]` |
116
123
  | `doctor` | dsh-doctor | web-ui.plugin.item 槽 entry id `doctor`(设置 → Web UI 插件 → Doctor 卡片);卡片内 `[data-dsh-plugin="doctor"]` |
117
124
  | `aionui-panel` | dsh-aionui-panel(停更) | dock entry id `aionui-*` |
118
125
  | `dsh-web-ui-market` | dsh-market | 创意工坊商店一级页(settings.section id `dsh-web-ui-market`),商店卡与目录条目容器 |
119
126
  | `skin-center` | skins/skin-center | 一级设置分区 settings.section id `skin-center`(列已安装皮肤,属内置源时显式标记) |
120
127
  | `session-id` | dsh-session-id | footer action slot entry id `session-id`;`[data-dsh-plugin="session-id"]`(面板 overlay 根 + 入口触发器) |
128
+ | `miku-pet` | dsh-miku-pet | 宠物浮层根 `[data-dsh-plugin="miku-pet"]`;host 路由前缀 `/miku-pet/*`;设置页 settings.section id `miku-pet-config` |
121
129
 
122
130
  ## 已知脆弱点(上游主题缝 PR 诉求)
123
131
 
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://schemas.linxin666.org/dsh-skin/v2.json",
4
4
  "title": "DSH Skin Manifest v2",
5
- "description": "Declarative manifest for a dsh-web-ui skin asset directory. Skins are pure assets; the skin-center package is the only loader/renderer. Validators must use this local schema copy and never fetch the $id URL.",
5
+ "description": "Declarative manifest for a dsh-web skin asset directory. Skins are pure assets; the skin-center package is the only loader/renderer. Validators must use this local schema copy and never fetch the $id URL.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": [