dsh-theme-palette 1.13.1 → 1.13.2

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.
@@ -0,0 +1,153 @@
1
+ # dsh-theme-palette 全量审计与反哺(v1.10.0 → 1.11.0 批次)
2
+
3
+ > **状态:本文件先于修订落盘**(2026-10-27)。各条的「证据」列均为修订前实测;
4
+ > 「落地与复核」一节在修订完成后回填。分数与结论以修订前的 1.10.0 为对象。
5
+
6
+ 审计对象:`client.js`(3749 行,生产引擎)、`index.js`、打包与发版链、`tools/` 全部校验脚本、五语 README 与 docs。
7
+ 方法:通读全部源码 + 本地复跑 `npm run check` 六件套与 `palette-dev.mjs` 两档报表 + 对可疑点写独立脚本实测(caption 的 APCA Lc、npm 包内容、取色开销、组合数口径)。
8
+
9
+ ## 0. 总评
10
+
11
+ **89 / 100。** 复核结论:`npm run check` 全绿,两档报表 0 硬失败、低于 AA 底线 0 处,README 声明的承诺与实测一致。
12
+ 验证体系(1080 组合全扫描、20 组回归断言共 371 条、自愈假宿主测试、宿主 asar 契约测试、发版安全脚本)是本插件最强的资产。
13
+ 本次发现的 12 条问题里,两条 P1 都是半小时级小修;其余为口径一致性与防御性优化。
14
+
15
+ | 维度 | 得分 | 一句话 |
16
+ |---|---|---|
17
+ | 架构与宿主集成 | 9.5 | 只走 overrideTokens 一条正道;自愈带退避与停用;卸载清理完整 |
18
+ | 色彩引擎正确性 | 9.0 | OKLCH 重建 + 色域钳制 + 真实承载面求解;色彩数学有 40 条单测锚定 |
19
+ | 无障碍 | 8.5 | 承诺面全绿 + CVD 守门 + APCA 双口径;caption 深色口径不一致(P2-3) |
20
+ | 测试基础设施 | 9.0 | 断言密度极高;缺 CI 与真实浏览器端到端(P2-5) |
21
+ | 代码质量 | 8.0 | 注释即决策记录;3749 行单文件与若干组织问题(P3-8/9) |
22
+ | 性能 | 8.0 | 双层缓存 + 后台不回读;取色拖动的宿主侧重写无合并(P2-4) |
23
+ | 国际化 | 7.0 | 四语完整;回退语言选错(P1-2) |
24
+ | 安全 | 9.5 | 无 eval、纯文本渲染、短码全字段白名单、发版无 shell 拼接 |
25
+ | 打包与发布 | 8.0 | 发版脚本 9.5 分;npm 包内 README 截图全部 404(P1-1) |
26
+ | 文档 | 9.5 | DESIGN.md 逐组件推演;CHANGELOG 66KB 可追溯 |
27
+
28
+ ## 1. 问题清单(核实证据 → 修订方案)
29
+
30
+ ### P1-1 npm 包内 README 的 4 张截图全部失效
31
+
32
+ **证据**:`package.json` 的 `files` 不含 `assets/`;解包 `dsh-theme-palette-1.10.0.tgz` 确认无 assets 目录(`tar -tzf | grep -c assets` = 0)。
33
+ npmjs.com 渲染 README 时 `assets/screenshot-*.png` 四处相对链接 404,而 README 的卖点正是这些截图。四图合计约 305KB。
34
+ **方案**:`files` 加入 `"assets"`。选「打进包」而不是「改绝对 GitHub URL」:自包含、不依赖仓库地址不变、npm 与镜像双兼容;包体积增量约 305KB(现包 140KB),可接受。
35
+
36
+ ### P1-2 i18n 回退语言不合理:非 zh/ja/en 宿主看到中文界面
37
+
38
+ **证据**:`client.js` `hostLocale()` 只识别 zh/ja/en,其余(fr/de/es/pt/…)返回 null;`pickLocale` 兜底 `|| 'zh-CN'`。
39
+ 德语用户的宿主语言得不到识别时,设置页整页中文。项目维护 es/pt/hi 三份 README,明显有国际受众。
40
+ **方案**:兜底改为 `|| 'en'`;并把 `pickLocale` 加入 dev 钩子导出(P2-6),在 `check-audit` 加断言:宿主语言 fr/ko/de → `en`,zh-TW → zh-TW,ja → ja。
41
+
42
+ ### P2-3 深色注释文字(label-caption)没跟上自家「深色侧下限」哲学
43
+
44
+ **证据(修订前实测,最深面 800)**:
45
+
46
+ | 配色 | 标准 caption WCAG / Lc | 同面三级文字 WCAG / Lc | HC caption Lc | HC 三级 Lc |
47
+ |---|---|---|---|---|
48
+ | 暖砂 | 4.93 / **51.7** | 6.43 / 66.3 | 71.7 | 76.8 |
49
+ | 靛蓝 | 4.89 / **47.9** | 6.44 / 61.9 | **66.6** | 72.0 |
50
+ | 苔绿 | 4.86 / **48.5** | 6.47 / 63.3 | **68.0** | 73.1 |
51
+
52
+ 插件在 `MIN_SECONDARY_DARK` 的注释里论证了「WCAG 比值在暗底高估可读性」,据此给三级定了 6.4、给链接加了 Lc 60 闸——
53
+ 但 caption 深色侧仍按**浅色**下限(4.85)求解,标准档 Lc 只有 48–52,低于自己给文字定的 Lc 60 舒适线;caption 也不在
54
+ `CONTRAST_ROLES` 报表模型里,设置页矩阵看不到它。`check-audit` 第 4 组同样只用浅色 floor 校验。
55
+ **方案**:caption 深色在现有 WCAG 求解后追加 `raiseToLc` 闸——标准档 Lc 60;**HC 档定 70 而不是照抄链接的 75**:
56
+ HC 三级文字 Lc 落在 72.0–76.8,caption 套 75 会反超三级(靛蓝 75 > 72.0),破坏「注释弱于三级」的层级。
57
+ 同步:`check-audit` 第 4 组加 Lc 断言与层级断言(caption 在 800 上 WCAG ≤ 三级),DESIGN.md 口径表补一行。
58
+
59
+ ### P2-4 取色拖动期间每个 input 事件都全量重放覆盖层(降级为防御性优化)
60
+
61
+ **证据(含对初版审计的自我修正)**:初版审计引 `client.js` 内注释「buildTokens 实测 2.4ms/次」推断拖动开销大。
62
+ 本次实测:60 个连续中间色 × 未命中缓存的全量构建共 **3ms(约 0.05ms/次)**——插件侧构建不是瓶颈。
63
+ 真正的每事件开销在宿主侧:`overrideTokens` 重写约 200 个 token 触发全页样式重算,外加 rAF 后 `getComputedStyle` 强制回读。
64
+ **结论**:不是实测到的性能缺陷,是「把宿主侧昂贵操作按帧合并」的防御性优化——拖动中每个 input 事件都打一次全页重排,在低端机/大文档下仍会掉帧。
65
+ **方案**:`setCustomColor` 的 `applyAll + emitCustom` 改为「标脏 + requestAnimationFrame 合并」,同帧多次取色只重放一次;
66
+ 离散动作(重置/派生/导入)保持同步。`check-selfheal` 加第 7 场景:同一帧内 3 次改色 → overrideTokens 恰好 +1。
67
+
68
+ ### P2-5 没有 CI
69
+
70
+ **证据**:`.github/` 不存在;`release.mjs` 预留了 `CI === 'true'` 的 provenance 分支但永远走不到。全部质量门只在本地/发版时跑。
71
+ **方案**:新增 `.github/workflows/ci.yml`:push/PR 触发,Node 22/24 矩阵,跑 `npm run check` + `npm run report`。
72
+ check 脚本只依赖 node 内建模块(semver 仅 release 用),无需 install;宿主契约脚本在无 asar 的 CI 上自动 SKIP,不阻断。
73
+
74
+ ### P2-6 dev 钩子未导出 APCA 与求解函数
75
+
76
+ **证据**:`client.js` dev 导出清单缺 `apcaContrast` / `raiseToLc` / `solveForeground` / `pickLocale` / `floorsDark`——
77
+ 外部工具想复算某个 token 的 Lc(如本审计对 caption 的取证)只能自带一份 APCA 实现,口径可能漂移。
78
+ **方案**:补进导出对象;`check-audit` 的新断言直接用导出的 `apcaContrast`。
79
+
80
+ ### P3-7 `encodeConfig`/`decodeConfig` 用已废弃的 `escape`/`unescape`
81
+
82
+ **证据**:`client.js` `btoa(unescape(encodeURIComponent(...)))` / `decodeURIComponent(escape(atob(...)))`。
83
+ **方案**:换 `TextEncoder`/`TextDecoder`。两条路径产出逐字节相同的 UTF-8(escape 链的语义就是 UTF-8 字节串),
84
+ 新旧版本互解码完全兼容;`check-audit` 第 2 组的旧码解码断言继续守着这一点。
85
+
86
+ ### P3-8 `TEXT_TARGETS` 大常量定义在 `buildTokensRaw` 函数体内
87
+
88
+ **证据**:每次未命中缓存构建都重新分配三套 × 明暗 × 四角色的对象字面量,且与 `SURFACE_TARGETS` 的模块级组织不一致。
89
+ **方案**:上提到模块级(紧随 `SURFACE_TARGETS`)。
90
+
91
+ ### P3-9 `getConfigCode` 闭包引用了下一行才声明的 `langPref`
92
+
93
+ **证据**:`const getConfigCode = () => encodeConfig({ …, lang: langPref })` 在 `let langPref = readLangPref()` 之前。
94
+ 运行时无害(调用发生在初始化后),但阅读时易误判为 TDZ 错误。
95
+ **方案**:把 `langPref` 声明上移。
96
+
97
+ ### P3-10 组合数口径混用:README 说 2160,实际 1080
98
+
99
+ **证据**:`palette-dev.mjs` 全组合扫描实际循环 5 配色 × 3 侧栏 × 3 文字 × 2 Markdown × 3 滚动 × 2 控件 × 2 高对比 = **1080**
100
+ (输出也打印 1080);CHANGELOG 1.9.10 已改口径「从 2160 降到 1080」。但五份 README 仍写「2160 组(5 × 216 × 两档)」——
101
+ 公式还把高对比算了两次(216 已含 hc 档)。`docs/DESIGN.md:326` 同样残留 2160。
102
+ **方案**:五语 README 与 DESIGN.md 统一改为「1080 组(5 套 × 216 组设置,已含标准/高对比两档)」。
103
+
104
+ ### P3-11 升级提示文案与版本号无同步断言
105
+
106
+ **证据**:每版要手改 4 语种的 `notice` 字符串;`check-ui` 只断言「可渲染」,不校验文案含当前版本号——漏改不会红。
107
+ **方案**:`check-ui` 加断言:client.js 源内 `notice: '…'` 恰好 4 处,且每处都包含当前 `PLUGIN_VERSION`。
108
+
109
+ ### P3-12 `label-dimmed`/`document-preview` 的 3.0 下限不在口径表里
110
+
111
+ **证据**:这两个 token 按「装饰性」解到 3.0,不在 `CONTRAST_ROLES` 承诺模型内;DESIGN.md 未说明,未来审计会重复疑问。
112
+ **方案**:DESIGN.md 承诺口径一节补一行说明其定位与底线。
113
+
114
+ ## 2. 修订顺序
115
+
116
+ P1-1 → P1-2 → P2-6(先导出,后续断言要用)→ P2-3 → P2-4 → P2-5 → P3-7 → P3-8 → P3-9 → P3-10 → P3-11 → P3-12。
117
+ 每批修改后跑 `npm run check`;全部完成后跑两档报表 + `npm pack --dry-run` 验包。
118
+ 版本策略:本批不 bump `PLUGIN_VERSION`(截图元数据与版本绑定,重拍需要宿主环境);
119
+ CHANGELOG 落「1.11.0(未发布)」一节,发版时随版本/notice/截图一起走。
120
+
121
+ ## 3. 落地与复核(2026-10-27 修订完成)
122
+
123
+ 12 条全部修订,按第 2 节顺序执行。逐条结果:
124
+
125
+ | # | 修订 | 落点 | 复核证据 |
126
+ |---|---|---|---|
127
+ | P1-1 | `files` 加 `assets` | `package.json` | `npm pack --dry-run`:20 文件 / 435.6KB,4 张截图 + meta 入包 |
128
+ | P1-2 | 回退 `en` + `pickLocale` 进 dev 钩子 | `client.js` `pickLocale` | `check-audit` 第 21 组:fr → **en**;zh → zh-CN;手选原样 |
129
+ | P2-3 | caption 深色 Lc 闸 60/70 | `client.js` `aliasOverrides` | 第 4 组新断言全过:标准 Lc 60.0(WCAG 5.73–6.19,仍 ≤ 三级 6.4x);HC 暖砂原值 71.7 未动、靛蓝 66.6→72.0 ≤ 三级 7.67 |
130
+ | P2-4 | `scheduleCustomApply` 帧合并 | `client.js` `setCustomColor` | `check-selfheal` 场景 6:帧内 2 次取色 overrideTokens **+0**,flush 后 **+1**,末次生效(#1e2f41 → #73889d) |
131
+ | P2-5 | CI 工作流 | `.github/workflows/ci.yml` | push/PR × Node 22/24 跑 check + report;无外部依赖 |
132
+ | P2-6 | dev 钩子补 6 个导出 | `client.js` dev 导出 | `check-audit` 直接用导出的 `apcaContrast`/`pickLocale` |
133
+ | P3-7 | TextEncoder/TextDecoder | `encodeConfig`/`decodeConfig` | 第 2 组旧码(Buffer base64url 构造)仍可解码 |
134
+ | P3-8 | `TEXT_TARGETS` 上提模块级 | `client.js`(紧随 `SURFACE_TARGETS`) | 六件套全绿 |
135
+ | P3-9 | `langPref` 声明上移 | `client.js` `apply()` | 六件套全绿 |
136
+ | P3-10 | 组合数统一 1080 | 五语 README + `docs/DESIGN.md` | 与 `palette-dev.mjs` 输出的「全组合扫描(1080 组配置)」一致 |
137
+ | P3-11 | notice 版本断言 | `tools/check-ui.mjs` | 断言恰好 4 条且都含 `PLUGIN_VERSION`,当前 1.10.0 全过 |
138
+ | P3-12 | 口径表补「注释层」「装饰层」两行 | `docs/DESIGN.md` | 与 P2-3 的闸值(60/70)互相引用 |
139
+
140
+ **修订中额外发现并一并修掉的一处测试基建问题**:`check-selfheal` 的沙箱 localStorage 桩是「恒返 null」,
141
+ 导致 `readCustom` 每次都回落默认三色——场景 6 第一次跑就暴露了它(取色永远不生效)。
142
+ 换成 Map 实现后与真实宿主行为一致。这正是「先写测试再写实现」的价值:坏桩自己先红了。
143
+
144
+ **全量复核结果**:
145
+ - `npm run check` 六件套全绿(含本轮新增的全部断言);
146
+ - `node palette-dev.mjs` 与 `--hc` 均 exit 0:**未达标 0 · 低于 AA 4.5 底线 0 · 硬失败 0**;
147
+ - `check-ui` 的预览页 sha256 校验未受 caption 修改影响(设置页结构不变,截图无需重拍);
148
+ - `npm pack --dry-run` 确认 assets 入包。
149
+
150
+ **版本策略(发版时更正)**:审计阶段曾判断「重拍截图需要宿主 GUI,故本批不 bump 版本」——发版时核实
151
+ `tools/shoot-settings.mjs` 实为无头 Chrome/Edge + CDP 截 `preview-settings.mjs` 生成的 HTML,**不依赖 DSH 宿主**,
152
+ 该判断有误。1.11.0 发版时已按既定流程联动:版本号 bump、四语 notice 换新、`npm run shots` 重拍截图
153
+ (`screenshots.meta.json` 的 `pluginVersion` 对齐)、CHANGELOG 转正。
package/CHANGELOG.md CHANGED
@@ -4,6 +4,67 @@
4
4
 
5
5
  ## 版本一览
6
6
 
7
+ > **「(未发布)」标记**:本文件里带这个后缀的版本节**从未发布到 npm**(只在仓库里演进过)。
8
+ > 1.13.2 起逐节标注 —— 此前 27 个版本节看起来都能装,用户按 CHANGELOG 钉版本会撞 404
9
+ > (2026-10-29 审计 P2-9)。
10
+
11
+ ### 1.13.2
12
+ 对 2026-10-29 全量审计(**34 条**,报告与反哺回执在仓库根目录的 `AUDIT-2026-10-29.md` /
13
+ `AUDIT-2026-10-29-FEEDBACK.md`)的修订。审计的核心判断成立:**引擎正确,缺的是"防回归"的工程能力** ——
14
+ 把 `CONTRAST_FLOOR` 改成 1.0、把 `package.json` 改成 1.99.0,`npm run check` 全绿。这一版补的就是这些洞。
15
+
16
+ - **P0-1 版本漂移在 CI 里不可见**:`tools/check-pack.mjs` 新增四路对账 —— `package.json` / `PLUGIN_VERSION` /
17
+ `screenshots.meta.json` / CHANGELOG 最新版本节必须同为 `1.13.2`。此前只有 `release.mjs` 断言其中一条边,
18
+ 而 `release.mjs` 不在 CI 里。
19
+ - **P0-2 包内 6 条死链**:`files` 补 `tools/README.md`(五语 README 末尾都指向它)与 `AUDIT-2026-10-27.md`
20
+ (1.11.0 版本节引用);`check-pack` 另加**通用死链扫描** —— 包内每份 markdown 的相对链接目标都必须在包里。
21
+ 这比"列出必需文件"更能防下一个死链。
22
+ - **P1-1 承诺下限没有锚点**:dev 钩子导出 `CONTRAST_FLOOR` / `MIN_*` / `FLOORS_HC*` / `RAMP_MIN_GAP`;
23
+ `check-audit` 第 22 组用**字面量**断言它们(4.5 / 12 / 6.2 / 4.85 / 4.95 / 4.62 / 8.0 / 6.4 / HC 15·9·7 /
24
+ 9.6·7.6 / 0.006),第 23 组把 `physicalCeiling` / `limitedByPhysics` 改成**用渲染 token 独立复算**
25
+ (216 格)—— 原先这两个断言拿被测字段互相验证,一起漂移时照样过。
26
+ - **P1-2 / P1-3 发版链的版本闸门**:`publish.yml` 在发布前断言 tag 版本 == `package.json` 版本
27
+ (否则 npm 会发错版本、后续 Release 资产按 tag 版本 404);`release.mjs` 的 `PLUGIN_VERSION` 正则换成与
28
+ `check-ui` / `check-pack` 同一个宽松版,**找不到即 die**(原先是 warn 后继续发版)。
29
+ - **P1-4 宿主契约在 CI 上是 0 条断言**:`check-host-contract.mjs` 支持从 `node_modules` 里的宿主 peer 包取证
30
+ (`@deepseek-ai/dsh-client-ui-theme` / `-ui-layout` / `dsh-web-frontend`,已进 devDependencies 并钉死
31
+ `0.2.1-rc.2`)。CI 加 `npm install` + `npm run contract`(`--strict`:两个来源都没有就红)。16 条契约断言
32
+ 现在在 ubuntu 上也真的跑。
33
+ - **P1-5 脚本清单两处维护**:`release.mjs` 改为直接调用 `tools/check-all.mjs`,清单只有一份;
34
+ SKIP 与否仍单独记账(SKIP 不会被打印成「通过」)。
35
+ - **P1-6 `insert-readme-sections.mjs` 休眠且损坏**:`SAMPLE` 改为运行时调 `tools/sample-code.mjs` 的
36
+ `generateSampleCode()`(不再硬编码 1.9.10 之前那份带 `"r":"sidebar"` 的码),并接入 `npm run check`。
37
+ 此前它 `--check` 在干净检出上直接红,所以没人跑它。
38
+ - **P1-7 色阶 `900` 漏在顺序表外**:`RAMP_ORDER` 补 `'900'`(875 与 950 之间)。补完视觉无变化(钳制量
39
+ 小于一个 8-bit 量化步长),但 `check-audit` 第 25 组新增「凡是构建出来的档位都必须出现在 `RAMP_ORDER` 里」,
40
+ 下一档再漏会红。
41
+ - **P1-8 APCA 的 Lc 被取整到整数**:`apcaContrast` 精度改 0.01 Lc,公开参考值随之回到
42
+ **106.04 / −107.88 / 63.06**(此前发出的是 106 / −108 / 63)。`raiseToLc` 不再"量化后首次过闸就停"。
43
+ ⚠️ 审计报告给的修法 `Math.round(out * 10000) / 100` 是错的(`out` 本身是 Lc/100,除以 100 会返回 Lc,
44
+ 差 100 倍 —— 实装验证过 `worst()` 算出 −4708);正确分母是 **10000**。
45
+ - **P2 十六条**:`mixHex` 注释改回真相(gamma 编码 sRGB 插值,不是线性光);`hexToRgb` 加校验、畸形输入返回
46
+ `null`(`toOklch` / `luminance` / `apcaY` / `flatten` / `mixHex` / `simulateCvd` 全部有定义的回退,
47
+ 不再产出 `#NaNNaNNaN`、也不再对 `null` 抛 TypeError);UI 文案改称「OKLab ΔE」;组件级回退从 `zh-CN`
48
+ 改成 `en`(与 `pickLocale` 同口径);`<section lang>` 改用解析后的 `locale`;es/pt/hi 补「自定义配色 +
49
+ 短码 + 高对比 + 4 语界面」一条并为六语 README 的要点条数加断言;`DESIGN.md` 补 **i18n 章节**、
50
+ 自愈章节补 1.12.0 的四件事、修掉 `paperC` 的自相矛盾与 `+0.022/+0.014`、`0.008` 两处旧值;
51
+ CHANGELOG 逐节标注未发布版本;`locale/*.json` 定性为**市场页元数据**并加键集/覆盖断言;
52
+ 补 `README-ja.md` 与 `locale/es|pt|hi.json`;`release.mjs` 区分「registry 网络失败」与「版本不存在」
53
+ (前者 die)、`dist-tag add` 失败改 die;对比度矩阵的面名跟随语言;5 个工具脚本补 `npm run` 别名、
54
+ `npm run packs` 进 CI;`tools/baseline/*.png` 移出版本控制(`compare.mjs` 不在 CI,基线会烂);
55
+ 清掉 6 个遗留 `.tgz` 并加 `npm run clean`。
56
+ - **P3 八条**:空数组恒真断言加长度守卫;删掉色相检查里的恒真子句;`fail()` 的 printf 风格改模板字符串;
57
+ 「六件套」等硬编码件数改为动态;删 `CONTRAST_ROLES[].step` 死数据;删 `enforceRampOrder` 的死返回值;
58
+ `check-audit` 分组 18/19 调成升序;APCA 锚点注释随 P1-8 自动变正确(106.04 / −107.88)。
59
+ - **复核**:`npm run check` 8 项全绿(新增 `insert-readme-sections --check`);两档报表 exit 0;
60
+ `npm pack` **28 文件 / 455.9 KB**;宿主契约从 peer 包取证 16 条断言全过;CI 新增 install + `npm run contract` + `npm run packs`;
61
+ `node tools/release.mjs --dry` 在临时 git 仓里全流程通过(含版本闸门、8/8 回归、两档 1080 组、registry 探针)。
62
+ - **顺手修掉一个审计没列的洞**:`tools/export-theme-pack.mjs` 拿 `floors(false).main`(浅色 12:1)去卡**深色**包,
63
+ 而深色正文的承诺是 10:1 —— 三套深色包一直被静默丢弃(`npm run packs` 退出 1,但它从不在 CI 里,所以没人发现)。
64
+ 改为按 `CONTRAST_TARGETS.main[mode].normal` 取目标后,8 个包全部导出(深色 10.91 / 11.08 / 11.20 / 12.05)。
65
+ - **未做(留给发版决定)**:本次不发 npm。真正发版仍走 `node tools/release.mjs --ci` 打 tag → Actions 用
66
+ Trusted Publishing 发布。
67
+
7
68
  ### 1.13.1
8
69
  发版链路改造:改用 **Trusted Publishing(OIDC)** 从 GitHub Actions 直接发布,不再依赖长期 token。**插件运行时没有任何变化** —— 这一版主要是让 README 与包内容跟上门禁与流程的真实状态。
9
70
 
@@ -108,7 +169,7 @@
108
169
  - **更正审计报告里的一处错**:报告说「三处 `:focus-visible` 只设 `outline-offset`、轮廓颜色吃浏览器默认」——不成立。设置页 CSS 用一条组选择器统一给了 `outline:2px solid var(--dsw-alias-label-primary)`,那三处只是覆盖 offset;`prefers-contrast: more` 下还有 `ButtonBorder` 兜底。
109
170
  - README 五种语言同步:文字下限改成「浅 / 深」两套口径,并说明深色为什么需要更高的比值。
110
171
 
111
- ### 1.9.8
172
+ ### 1.9.8(未发布)
112
173
  把「承诺什么」「能不能做到」「健不健康」三件事分开说清,并修掉几个会骗自己的判据:
113
174
 
114
175
  - **自愈判据改为「覆盖层标记 + 颜色比对」**:旧判据只看关键 token 的计算值是否非空 —— 覆盖层被宿主撤销后,宿主的基础 token 仍然有值,判据永远说「健康」,配色却早已跳回默认(假健康)。现在用两件事判断:本插件自己写入的标记属性 `--dshtp-layer` 是否还在,以及关键 token 的计算值是否等于本层期望值(明暗两色任一相符即可)。判据不成立才重放,退避与停用逻辑不变。
@@ -134,7 +195,7 @@
134
195
  - README 的 12:1 表述待同步(发版前完成)
135
196
 
136
197
 
137
- ### 1.9.6
198
+ ### 1.9.6(未发布)
138
199
  深色菜单/说明文字压暗(用户反馈「左侧菜单明度太高」):
139
200
 
140
201
  - 深色 `label-secondary` / `label-tertiary` 按导航实际承载面(950/875)压到 L0.78 / L0.70
@@ -142,7 +203,7 @@
142
203
  - 侧栏对比度 8.9:1 / 6.7:1,仍高于下限;四套(含自定义)同步
143
204
 
144
205
 
145
- ### 1.9.5
206
+ ### 1.9.5(未发布)
146
207
  自定义配色对齐新的标签规则(不再只有三套预置享受):
147
208
 
148
209
  - 二级/三级/更弱文字(`label-secondary/tertiary/dimmed`)在自定义下也按主题色相给足色度
@@ -151,7 +212,7 @@
151
212
  - 对比度仍按真实承载面求解
152
213
 
153
214
 
154
- ### 1.9.4
215
+ ### 1.9.4(未发布)
155
216
  侧栏色度显式补足(用户对比参考实现发现侧栏偏中性):
156
217
 
157
218
  - 画布收敛到近中性后,侧栏继承不到暖色;现按方案 `lightC×0.75` 显式补色度(保持明度)
@@ -159,7 +220,7 @@
159
220
  - 只改浅色侧栏底色,悬停/选中随之推导;深色侧不变
160
221
 
161
222
 
162
- ### 1.9.3
223
+ ### 1.9.3(未发布)
163
224
  二级/三级/更弱文字**明暗两套**都提高鲜艳度(用户反馈「只是希望字色鲜艳一点」):
164
225
 
165
226
  - 显式覆盖 `label-secondary` / `label-tertiary`:色度 0.050–0.055(原来是 0.01–0.03 的灰),明暗各一套
@@ -168,7 +229,7 @@
168
229
  - 仍对真实承载面求解对比度(二级 6.2、三级 4.62),不牺牲可读性
169
230
 
170
231
 
171
- ### 1.9.2
232
+ ### 1.9.2(未发布)
172
233
  更弱的注释层也跟随主题(用量统计 / 时间戳这类):
173
234
 
174
235
  - 显式覆盖 `label-dimmed`(200/750)与 `label-document-preview`(300/700),色度提到 0.018–0.023
@@ -176,7 +237,7 @@
176
237
  - 说明:若界面里该处仍发灰,可能是宿主直接用了 Tailwind 字面色而非 token,需要具体元素定位
177
238
 
178
239
 
179
- ### 1.9.1
240
+ ### 1.9.1(未发布)
180
241
  注释/时间戳类文字跟随主题(用户反馈「颜色发灰」):
181
242
 
182
243
  - `midC` 0.010→0.020:label-caption / label-tertiary / 边框等中间层色度提高约一倍
@@ -185,7 +246,7 @@
185
246
  - 深色 caption 求解保持在 800/850 ≥4.6(暖砂 `#bbad9c` 4.66)
186
247
 
187
248
 
188
- ### 1.9.0
249
+ ### 1.9.0(未发布)
189
250
  按参考实现(web.yily.top)的设计 token 做**精确重标定**,不再凭截图猜:
190
251
 
191
252
  - 取得其四套配色的 surface / ink / link / accent 全表;三套预置的表面层逐字对齐:
@@ -196,7 +257,7 @@
196
257
  - 中间层(75/100/200)按 60→150 的 OKLCH 插值,边框与悬浮态不跳变
197
258
 
198
259
 
199
- ### 1.8.4
260
+ ### 1.8.4(未发布)
200
261
  三套预置统一「变轻」(依据参考实现的实际取色,不是凭感觉):
201
262
 
202
263
  - 参考图实测:暖砂 页面 `#fcfbf7` / 卡片 `#f5efe3` / 控件 `#e8dfd0`;
@@ -269,7 +330,7 @@ Markdown 配色丰富化(非加色相,而是加层级 + 修代码块底)
269
330
  需先在 GUI 实测渲染器是吃变量还是内联色,再决定方案——不在未验证的情况下强改
270
331
 
271
332
  ### 1.8.0
272
- 依据 [竞品调研](../../_audit-theme-palette-20261023/竞品调研-2026-10-23.md) 的差距反哺:把工程严谨变成可见、可分享、可验证的东西(不改求解器)。
333
+ 依据竞品调研(`_audit-theme-palette-20261023/竞品调研-2026-10-23.md`,不在本仓库内)的差距反哺:把工程严谨变成可见、可分享、可验证的东西(不改求解器)。
273
334
 
274
335
  - **对比度矩阵**:设置页新增可折叠「对比度」区,4 个前景角色 × 7 个承载面的实测/目标/表面受限三态;
275
336
  `CONTRAST_SURFACES` / `CONTRAST_ROLES` 成为唯一定义,`palette-dev.mjs` 改为消费同一份(消除两套口径)
@@ -460,63 +521,63 @@ Markdown 配色丰富化(非加色相,而是加层级 + 修代码块底)
460
521
  - 样式从内联改为独立注入的 `settings.css`(支持 hover / 窄屏 / `body[data-ds-dark-theme]`)
461
522
  - 新增 `tools/preview-settings.mjs` + `tools/shoot-html.mjs`:不打开 App 也能截设置页
462
523
 
463
- ### 1.2.0
524
+ ### 1.2.0(未发布)
464
525
  - 代码块底色独立成 `--dsh-code-fill`:与画布 ΔE 5.5(浅)/ 11.0(深),原来浅色下同色
465
526
  - 行内代码用更浅的 `--dsh-code-inline`;两者都不需要 `!important`
466
527
 
467
- ### 1.1.0
528
+ ### 1.1.0(未发布)
468
529
  - Markdown 标题 / 加粗用「正文色 + 强调色相」染色(标题 12.3、加粗 14.4,均远高于 AA)
469
530
  - 「更多选项」加一档 Markdown 强调开关;黑白配色不染
470
531
 
471
- ### 1.0.0
532
+ ### 1.0.0(未发布)
472
533
  - `fromOklch` 加色域钳位(二分收色度),修「通道顶满 255 → 色相被压歪」
473
534
  - 浅色侧重标定:近白端 −0.044、`lightC` 上调、暖砂/苔绿色相收敛,套间最弱一对 ΔE 2.15 → 3.07
474
535
  - 黑白配色接入引擎:三级 4.67、链接 4.63、主按钮 4.54(原 3.42 / 3.91 / 4.34)
475
536
  - 主按钮 `button-primary-fill` 从宿主红色改为强调色(并压到按钮文字 ≥4.5)
476
537
  - 设置页改为「配色 / 强度 / 面板表面 / 更多选项」,运行时 token 自检
477
538
 
478
- ### 0.18.0
539
+ ### 0.18.0(未发布)
479
540
  - 主人气泡 `--dsw-specific-bubble` 改由「强调色 11%(深 13%)混画布」派生:暖砂 `#ffede0` → `#f2e5d1`,不再发粉
480
541
  - 气泡与画布 ΔE 4.2–7.9、气泡内文字对比 9.99–13.53
481
542
 
482
- ### 0.17.0
543
+ ### 0.17.0(未发布)
483
544
  - 文字着色第二版标定:跟随 3.0/+0.055(ΔE 2.77 → 5.5)、浓一些 4.6/+0.085(ΔE 8.5)
484
545
  - 会话条目标题与正文共用 token,一并变深变暖
485
546
 
486
- ### 0.16.0
547
+ ### 0.16.0(未发布)
487
548
  - 注释文字跟随文字着色:`mid` 角色乘 `1+(textScale-1)×2.0`,`midC` 0.006 → 0.010(注释 ΔE 1.76 / 3.61)
488
549
  - 深色注释 `label-caption` 改用色阶 500:对比 3.0 → 6.0–6.3
489
550
 
490
- ### 0.15.0
551
+ ### 0.15.0(未发布)
491
552
  - 修:深色模式下选中卡片是白底白字(内联色混错了浅色画布)→ 改由 `--dsh-card-picked` 按模式给值
492
553
  - 设置页细项收进「更多选项」,默认折叠,只留配色卡片
493
554
 
494
- ### 0.14.0
555
+ ### 0.14.0(未发布)
495
556
  - 新增 `darkHue`:暖砂深色层色相 88° → 60°(黄 → 橙棕),修掉暗部「发绿 / 橄榄」
496
557
  - 深端 neutral(深色滚动条)跟同一夜色相;浅色侧与另两套未变
497
558
 
498
- ### 0.13.0
559
+ ### 0.13.0(未发布)
499
560
  - 深色侧栏改用独立 `darkLift`(0.048 / 0 / −0.042):与画布 ΔE 从 1.9–2.3 提到 4.03–5.05
500
561
  - 侧栏内正文对比 12.48–16.40(仍 AAA)
501
562
 
502
- ### 0.12.0
563
+ ### 0.12.0(未发布)
503
564
  - 文字着色重新标定:加 `textLift`(正文抬 0.030 / 0.065),三档 ΔE 从 0.35–1.66 提到 2.77–6.79
504
565
  - 左栏会话条目与正文共用 `label-*`,一并生效
505
566
  - MIN_MAIN 15.5 → 12(给带色正文留空间,仍 ≥ 1.7 倍 AAA)
506
567
 
507
- ### 0.11.0
568
+ ### 0.11.0(未发布)
508
569
  - 开关 / 复选框 / 单选 / 插件页主按钮改跟强调色(覆盖 `--dsw-alias-brand-primary`,13 处引用一个支点)
509
570
  - 设置页现为六行:配色 · 文字着色 · 左侧栏 · 右侧栏 · 滚动条 · 开关勾选
510
571
 
511
- ### 0.10.0
572
+ ### 0.10.0(未发布)
512
573
  - 滚动条三档着色(中性 / 跟随 / 强调),只抬色度不改明度;黑白配色下该行说明会自述无效
513
574
  - 设置页现为五行:配色 · 文字着色 · 左侧栏 · 右侧栏 · 滚动条
514
575
 
515
- ### 0.9.0
576
+ ### 0.9.0(未发布)
516
577
  - 右侧栏可单独上色(默认与左栏同色);注入一条命中 `data-rightbar-col` 的 CSS,颜色走 `--dsh-rightbar-fill`
517
578
  - 全屏右栏退回画布色
518
579
 
519
- ### 0.8.2 (强调色改为设计稿标准值)
580
+ ### 0.8.2(未发布) (强调色改为设计稿标准值)
520
581
  - 强调色新增 `accentL`:色阶中段 `500` 的明度定死成设计值,不再乘 `accentScale`
521
582
  —— 乘性缩放会把选中态软底 `deepseek-50/100/200` 一起压暗 13%
522
583
  - 暖砂 `#a9683e`(h 68→52.4,C 0.105→0.101)、靛蓝 `#3f66a3`(C 0.135→0.107,L 0.589→0.511)、
@@ -526,7 +587,7 @@ Markdown 配色丰富化(非加色相,而是加层级 + 修代码块底)
526
587
  - `tuneRamps` 不再改写 `deepseek-500`(品牌面保持标准值),只兜深色链接 `400`
527
588
  - `palette-dev.mjs`:链接列改读 `--dsw-alias-link`;每套新增「品牌基准色 / 链接」一行
528
589
 
529
- ### 0.8.1 (深色专项审计后)
590
+ ### 0.8.1(未发布) (深色专项审计后)
530
591
  - `ROLE` 深色权重拉平(`800/850` 0.6/0.75 → 1.0,`875` 0.85 → 0.95)—— 卡片/模块不再比画布灰 30–45%,三套在深色层上的区分度从 ΔE 1.02 回到 2.05
531
592
  - `darkC` 按色相归一化:暖砂 0.016→0.014、靛蓝 0.017→0.028、苔绿不动;三套占可用色域 30/19/24%(原 35/11/24%,暖砂发脏、靛蓝发灰)
532
593
  - `darkLift` 三套错开 0.026 / 0.032 / 0.042(原统一 0.034)—— 暖砂↔苔绿 850 层 ΔE 1.15 → 2.05
@@ -536,10 +597,10 @@ Markdown 配色丰富化(非加色相,而是加层级 + 修代码块底)
536
597
  - 苔绿强调 `155°→165°` —— 与底色(h≈152)从 2° 拉开到 13°,链接不再只靠明度识别
537
598
  - 深色对比度:正文 14.40–14.98、三级 4.79 起、链接 4.65 起(0 处低于下限)
538
599
 
539
- ### 0.8.0 (- 新增「文字着色」三档(中性 / 跟随 / 浓一些),默认「跟随」;只放大文字色度,不影响对比度)
600
+ ### 0.8.0(未发布) (- 新增「文字着色」三档(中性 / 跟随 / 浓一些),默认「跟随」;只放大文字色度,不影响对比度)
540
601
  - 配色重建缓存按(配色, 文字档)分键;设置页新增第三行控件
541
602
 
542
- ### 0.7.0 (UI 设计审计后全面修订)
603
+ ### 0.7.0(未发布) (UI 设计审计后全面修订)
543
604
  - 求解靶点从画布改为真实承载面(`60` / `800` / `150`),上限 0.09 → 0.13 —— 修掉 12 处真实的 AA 违规
544
605
  - `accentScale` 三套全部 1.0 —— 强调色浅端恢复四档层次
545
606
  - 阈值 15.5 / 6.2 / 4.62;三级与次级重新拉开明度
@@ -746,7 +807,7 @@ DSH 里“注释类”文字走的是 `--dsw-alias-label-caption`:宿主浅色
746
807
  **② 细项默认折叠。** 配色卡片下面是「▸ 更多选项」;文字着色 / 左侧栏 / 右侧栏 / 滚动条 /
747
808
  开关勾选这五行只在展开后出现。所有档位都保留,默认值就是我推荐的那套,不展开也能正常用。
748
809
 
749
- ### 1.0.0:按设计审计重做的四件事
810
+ ### 1.0.0(未发布):按设计审计重做的四件事
750
811
 
751
812
  **① 色域安全钳位。** `fromOklch` 现在先判断是否超出 sRGB(线性通道必须落在 [0,1]),
752
813
  超了就二分收色度,而不是把通道硬钳到 0/255。此前「暖砂气泡算出 `#ffede0`、R 恒为 255」
package/README-es.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-theme-palette
2
2
 
3
- [English](README.md) · [中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
3
+ [English](README.md) · [中文](README-zh.md) · [日本語](README-ja.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
4
4
 
5
5
  Paleta de tema para DeepSeek Harness (web y escritorio): **4 paletas preajustadas + personalizada × claro/oscuro**, dos ejes independientes.
6
6
 
@@ -30,6 +30,7 @@ El plugin solo apila tokens de color mediante `ctx.theme.overrideTokens`; no reg
30
30
  - la escala se **recalcula** completa: reconstrucción OKLCH → croma por rol → **ajuste al gamut sRGB** → contraste resuelto sobre superficies reales;
31
31
  - se cubren todos los tokens de color del host (122 tokens en paletas con tinte, 17 en mono; 1080 combinaciones de ajuste escaneadas): texto, secundario, terciario, notas, enlaces, barras laterales, tarjetas, burbuja del usuario, botón primario, barras de desplazamiento, interruptores, títulos/negritas de Markdown, bloques de código;
32
32
  - ajustable: intensidad del texto (3), profundidad de la barra lateral (3), énfasis de Markdown, barras de desplazamiento, color de interruptores;
33
+ - **paleta personalizada** (elige superficie / texto / acento — el motor mantiene sus garantías de contraste), **exportación/importación de configuración** con un código `dshs1.`, **modo de alto contraste** y **4 idiomas de interfaz**;
33
34
  - **autorreparable**: si el host descarta la capa de override, la paleta se vuelve a aplicar; tras fallos repetidos la autorreparación se pausa y la página de ajustes ofrece un botón para reactivarla;
34
35
  - **promesas de contraste**: el cuerpo tiene la promesa de 12:1 en claro y 10:1 en oscuro (15:1 en alto contraste), el secundario ≥ 6.2 en claro y 8.0 en oscuro (HC 9 / 9.6), el terciario ≥ 4.85 en claro y 6.4 en oscuro (HC 7 / 7.6), los enlaces ≥ 4.95 en claro y 4.62 en oscuro (HC 7; los mínimos claros llevan un margen para déficits de visión cromática; los enlaces oscuros además pasan una puerta APCA Lc ≥ 60, 75 en HC), medidos sobre las superficies donde el texto realmente cae (el lado oscuro necesita más: un cociente WCAG sobreestima la legibilidad sobre fondo oscuro);
35
36
  - las superficies prometidas son 00/60 en claro y 950/875 en oscuro; las oscuras 800 (superficie de módulo) y 850 (sub-superficie) **no** respaldan el texto del cuerpo: el informe las cuenta aparte como «fuera de política» (ni cuentan como aprobado ni como fallo);
@@ -43,7 +44,7 @@ cd ~/.dsh/profiles/desktop
43
44
  pnpm add dsh-theme-palette
44
45
  ```
45
46
 
46
- Para fijar una versión, usa `pnpm add dsh-theme-palette@<version>` — la versión actual está en [CHANGELOG.md](CHANGELOG.md).
47
+ Para fijar una versión, usa `pnpm add dsh-theme-palette@<version>` — [CHANGELOG.md](CHANGELOG.md) marca las secciones que nunca se publicaron en npm; no fijes una de esas.
47
48
  Desde el tarball de un release de GitHub: elige el asset en la [página de releases](https://github.com/zuoyunlai/dsh-theme-palette/releases) e instálalo con `pnpm add <ruta-del-tgz>`.
48
49
 
49
50
  Después **reinicia la interfaz**: un proceso en marcha conserva el módulo antiguo. Se abre en avatar → Ajustes → **Color theme**.
@@ -79,14 +80,16 @@ Las notas de diseño, el criterio por componente y las tablas de contraste está
79
80
  ## Development
80
81
 
81
82
  ```bash
82
- node palette-dev.mjs # informe de tokens de todas las paletas
83
- node tools/sheet.mjs # tablero de paletas → tools/sheet.html
84
- node tools/shoot-sheet.mjs # captura del tablero (Chrome headless)
85
- node tools/compare.mjs --dir tools/out/<run> # comparar con la línea base
86
- node tools/preview-settings.mjs --lang en # renderizar la página de ajustes
87
- node tools/release.mjs --dry # preflight de publicación
88
- node tools/release.mjs --tag # publicar en npm + tag
89
- node tools/release.mjs --ci # publicación en CI: solo tag; Actions publica con Trusted Publishing
83
+ npm run report # informe de tokens de todas las paletas (-- --hc para alto contraste)
84
+ npm run sheet # tablero de paletas → tools/sheet.html
85
+ npm run shot-sheet # captura del tablero (Chrome/Edge headless)
86
+ npm run compare -- --dir tools/out/<run> # comparar con la línea base local
87
+ npm run preview -- --lang en # renderizar la página de ajustes
88
+ npm run contract # contrato de tokens/DOM del host (strict: SKIP falla)
89
+ npm run release -- --dry # preflight de publicación
90
+ npm run release -- --tag # publicar en npm + tag
91
+ npm run release -- --ci # publicación en CI: solo tag; Actions publica con Trusted Publishing
92
+ npm run clean # borrar tarballs locales / tools/out / dist
90
93
  ```
91
94
 
92
95
  La regresión visual tiene dos capas: el tablero de paletas (sin autenticación) y la ventana real del escritorio vía CDP (`tools/shoot-desktop.mjs`, requiere `--remote-debugging-port`). Ver [tools/README.md](tools/README.md).
package/README-hi.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-theme-palette
2
2
 
3
- [English](README.md) · [中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
3
+ [English](README.md) · [中文](README-zh.md) · [日本語](README-ja.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
4
4
 
5
5
  DeepSeek Harness (वेब और डेस्कटॉप) के लिए थीम पैलेट: **4 प्रीसेट + कस्टम पैलेट × लाइट/डार्क**, दो स्वतंत्र अक्ष।
6
6
 
@@ -30,6 +30,7 @@ DeepSeek Harness (वेब और डेस्कटॉप) के लिए
30
30
  - पूरी रैंप **दोबारा गणना** होती है, बदली नहीं जाती: OKLCH पुनर्निर्माण → भूमिका-आधारित क्रोमा → **sRGB गैमट क्लैंप** → वास्तविक सतहों पर कंट्रास्ट हल;
31
31
  - होस्ट के सभी रंग टोकन शामिल (रंगीन पैलेट में 122 टोकन, मोनो में 17; 1080 सेटिंग संयोजन पूरी तरह स्कैन किए गए): मुख्य टेक्स्ट, द्वितीयक, तृतीयक, कैप्शन, लिंक, साइडबार, कार्ड, उपयोगकर्ता बबल, प्राइमरी बटन, स्क्रॉलबार, स्विच, Markdown शीर्षक/बोल्ड, कोड ब्लॉक;
32
32
  - समायोज्य: टेक्स्ट की तीव्रता (3), साइडबार की गहराई (3), Markdown ज़ोर, स्क्रॉलबार, स्विच का रंग;
33
+ - **कस्टम पैलेट** (सतह / टेक्स्ट / एक्सेंट चुनें — इंजन अपने कंट्रास्ट वादे बनाए रखता है), `dshs1.` कोड से **कॉन्फ़िगरेशन निर्यात/आयात**, **हाई-कॉन्ट्रास्ट** मोड, और **4 UI भाषाएँ**;
33
34
  - **स्व-उपचार**: यदि होस्ट ओवरराइड परत हटा दे, पैलेट फिर से लगा दी जाती है; बार-बार विफलता पर स्व-उपचार रुक जाता है और सेटिंग्स पेज पर इसे दोबारा चालू करने का बटन मिलता है;
34
35
  - **कंट्रास्ट के वादे**: मुख्य टेक्स्ट के लिए लाइट में 12:1 और डार्क में 10:1 (उच्च-कंट्रास्ट में 15:1), द्वितीयक ≥ 6.2 (लाइट) / 8.0 (डार्क) (HC 9 / 9.6), तृतीयक ≥ 4.85 (लाइट) / 6.4 (डार्क) (HC 7 / 7.6), लिंक ≥ 4.95 (लाइट) / 4.62 (डार्क) (HC 7) — लाइट की सीमाओं में रंग-दृष्टि दोष के लिए गुंजाइश रखी गई है; डार्क लिंक अतिरिक्त APCA Lc ≥ 60 (HC 75) — उन्हीं सतहों पर मापे गए जहाँ टेक्स्ट वास्तव में बैठता है (डार्क में ज़्यादा चाहिए: गहरे बैकग्राउंड पर WCAG अनुपात पढ़ने की सुविधा को बढ़ा-चढ़ा कर दिखाता है);
35
36
  - वादे की गई सतहें लाइट में 00/60 और डार्क में 950/875 हैं; डार्क 800 (मॉड्यूल सतह) और 850 (उप-सतह) मुख्य टेक्स्ट को नहीं सहनाते — रिपोर्ट उन्हें अलग «नीति से बाहर» के रूप में गिनती है (न तो पास, न ही फेल);
@@ -43,7 +44,7 @@ cd ~/.dsh/profiles/desktop
43
44
  pnpm add dsh-theme-palette
44
45
  ```
45
46
 
46
- किसी संस्करण को पिन करने के लिए `pnpm add dsh-theme-palette@<version>` — मौजूदा रिलीज़ [CHANGELOG.md](CHANGELOG.md) में है।
47
+ किसी संस्करण को पिन करने के लिए `pnpm add dsh-theme-palette@<version>` — [CHANGELOG.md](CHANGELOG.md) में जिन संस्करणों पर「未发布」लिखा है वे npm पर कभी प्रकाशित नहीं हुए; उन्हें पिन न करें।
47
48
  GitHub रिलीज़ के tarball से: [releases पेज](https://github.com/zuoyunlai/dsh-theme-palette/releases) पर asset चुनें, फिर `pnpm add <tgz का पता>`।
48
49
 
49
50
  इसके बाद **GUI को फिर से शुरू करें** — चल रहा प्रोसेस पुराना मॉड्यूल रखता है। खोलें: अवतार → सेटिंग्स → **Color theme**।
@@ -79,14 +80,16 @@ OKLCH(L, C, ह्यू) ──► गैमट क्लैंप (C पर
79
80
  ## Development
80
81
 
81
82
  ```bash
82
- node palette-dev.mjs # सभी पैलेट का टोकन रिपोर्ट
83
- node tools/sheet.mjs # पैलेट बोर्ड → tools/sheet.html
84
- node tools/shoot-sheet.mjs # बोर्ड का स्क्रीनशॉट (हेडलेस Chrome)
85
- node tools/compare.mjs --dir tools/out/<run> # बेसलाइन से तुलना
86
- node tools/preview-settings.mjs --lang en # सेटिंग्स पेज रेंडर करें
87
- node tools/release.mjs --dry # रिलीज़ प्रीफ़्लाइट
88
- node tools/release.mjs --tag # npm पर प्रकाशित + टैग
89
- node tools/release.mjs --ci # CI में प्रकाशन: केवल tag; Actions Trusted Publishing से प्रकाशित करे
83
+ npm run report # सभी पैलेट का टोकन रिपोर्ट (-- --hc से उच्च-कंट्रास्ट)
84
+ npm run sheet # पैलेट बोर्ड → tools/sheet.html
85
+ npm run shot-sheet # बोर्ड का स्क्रीनशॉट (हेडलेस Chrome/Edge)
86
+ npm run compare -- --dir tools/out/<run> # स्थानीय बेसलाइन से तुलना
87
+ npm run preview -- --lang en # सेटिंग्स पेज रेंडर करें
88
+ npm run contract # होस्ट टोकन/DOM कॉन्ट्रैक्ट (strict: SKIP विफल)
89
+ npm run release -- --dry # रिलीज़ प्रीफ़्लाइट
90
+ npm run release -- --tag # npm पर प्रकाशित + टैग
91
+ npm run release -- --ci # CI में प्रकाशन: केवल tag; Actions Trusted Publishing से प्रकाशित करे
92
+ npm run clean # स्थानीय tarball / tools/out / dist हटाएँ
90
93
  ```
91
94
 
92
95
  स्क्रीनशॉट रिग्रेशन की दो परतें हैं: पैलेट बोर्ड (बिना लॉगिन) और CDP से असली डेस्कटॉप विंडो (`tools/shoot-desktop.mjs`, `--remote-debugging-port` चाहिए)। देखें [tools/README.md](tools/README.md)।