dsh-theme-customizer 1.0.0 → 1.0.3

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.
@@ -31,8 +31,7 @@ if (all.length === 0) return null;
31
31
  if (all.length === 0 && window.__TCZ_HIDE_OFFICIAL_CORDIS) return null; /* [dsh-theme-customizer] Cordis按钮常驻补丁 */
32
32
  ```
33
33
 
34
- ⚠️ 千万不要加 `!`!历史上写反过一次(`!window.__TCZ_HIDE_OFFICIAL_CORDIS`),
35
- 导致 flag=false(常驻)时反而隐藏。语义:
34
+ ⚠️ 千万不要加 `!`!,会导致 flag=false(常驻)时反而隐藏。语义:
36
35
  - `window.__TCZ_HIDE_OFFICIAL_CORDIS = false` → 常驻(无插件也显示)
37
36
  - `window.__TCZ_HIDE_OFFICIAL_CORDIS = true` → 官方原逻辑(无插件隐藏)
38
37
 
package/README.en.md CHANGED
@@ -1,15 +1,97 @@
1
1
  # dsh-theme-customizer
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/dsh-theme-customizer?style=flat-square)](https://www.npmjs.com/package/dsh-theme-customizer)
4
- [![license](https://img.shields.io/github/license/lxxz1918/dsh-theme-customizer?style=flat-square)](LICENSE)
5
- [![topic: dsh-plugin](https://img.shields.io/badge/topic-dsh--plugin-0969da?style=flat-square)](https://github.com/topics/dsh-plugin)
6
- [![stars](https://img.shields.io/github/stars/lxxz1918/dsh-theme-customizer?style=flat-square)](https://github.com/lxxz1918/dsh-theme-customizer/stargazers)
3
+ [![npm version](https://img.shields.io/npm/v/dsh-theme-customizer?style=flat-square&v=1)](https://www.npmjs.com/package/dsh-theme-customizer)
4
+ [![license](https://img.shields.io/github/license/lxxz1918/dsh-theme-customizer?style=flat-square&v=1)](LICENSE)
5
+ [![topic: dsh-plugin](https://img.shields.io/badge/topic-dsh--plugin-0969da?style=flat-square&v=1)](https://github.com/topics/dsh-plugin)
6
+ [![stars](https://img.shields.io/github/stars/lxxz1918/dsh-theme-customizer?style=flat-square&v=1)](https://github.com/lxxz1918/dsh-theme-customizer/stargazers)
7
7
 
8
8
  **English** | [中文](README.md)
9
9
 
10
10
  > A theme customizer plugin for the DeepSeek Harness (DSH) web UI. Backgrounds, text colors, borders and details — all adjustable visually, persisted across restarts.
11
11
  > Config is stored in localStorage; presets can be exported as `.tczp` files (images included) and shared with any machine.
12
12
 
13
+ ## 🎨 Theme Gallery
14
+
15
+ Four AI-generated wallpaper themes (alternating dark/bright), each with two main-UI "display area" modes: **include sidebar** (one full-screen background) and **exclude sidebar** (main area + independent portrait sidebar background), plus matching `.tczp` presets for one-click import (see "Asset Pack" below).
16
+
17
+ | 🌌 Aurora Nights (dark) | 🌇 Sunset Clouds (bright) |
18
+ |:---:|:---:|
19
+ | ![Aurora](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-front-1.jpg) | ![Sunset](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-front-1.jpg) |
20
+ | **🌃 Cyber Nights (dark)** | **🌸 Sakura Sky (bright)** |
21
+ | ![Cyber](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-front-1.jpg) | ![Sakura](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-front-1.jpg) |
22
+
23
+ ## 📸 Screenshots
24
+
25
+ Each theme has two modes (presets `-0` / `-1`): **display area includes sidebar** (one full-screen background) and **display area excludes sidebar** (main area + independent portrait sidebar background). Each mode has 3 shots: front-1 / front-2 / settings.
26
+
27
+ <details>
28
+ <summary>🌌 Aurora Nights (dark)</summary>
29
+
30
+ **Display area includes sidebar (-0)**
31
+
32
+ | Front 1 | Front 2 | Settings |
33
+ |:---:|:---:|:---:|
34
+ | ![Aurora A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-front-1.jpg) | ![Aurora A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-front-2.jpg) | ![Aurora A-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-settings.jpg) |
35
+
36
+ **Display area excludes sidebar (-1)**
37
+
38
+ | Front 1 | Front 2 | Settings |
39
+ |:---:|:---:|:---:|
40
+ | ![Aurora B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/1-front-1.jpg) | ![Aurora B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/1-front-2.jpg) | ![Aurora B-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/1-settings.jpg) |
41
+
42
+ </details>
43
+
44
+ <details>
45
+ <summary>🌇 Sunset Clouds (bright)</summary>
46
+
47
+ **Display area includes sidebar (-0)**
48
+
49
+ | Front 1 | Front 2 | Settings |
50
+ |:---:|:---:|:---:|
51
+ | ![Sunset A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-front-1.jpg) | ![Sunset A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-front-2.jpg) | ![Sunset A-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-settings.jpg) |
52
+
53
+ **Display area excludes sidebar (-1)**
54
+
55
+ | Front 1 | Front 2 | Settings |
56
+ |:---:|:---:|:---:|
57
+ | ![Sunset B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/1-front-1.jpg) | ![Sunset B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/1-front-2.jpg) | ![Sunset B-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/1-settings.jpg) |
58
+
59
+ </details>
60
+
61
+ <details>
62
+ <summary>🌃 Cyber Nights (dark)</summary>
63
+
64
+ **Display area includes sidebar (-0)**
65
+
66
+ | Front 1 | Front 2 | Settings |
67
+ |:---:|:---:|:---:|
68
+ | ![Cyber A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-front-1.jpg) | ![Cyber A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-front-2.jpg) | ![Cyber A-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-settings.jpg) |
69
+
70
+ **Display area excludes sidebar (-1)**
71
+
72
+ | Front 1 | Front 2 | Settings |
73
+ |:---:|:---:|:---:|
74
+ | ![Cyber B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/1-front-1.jpg) | ![Cyber B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/1-front-2.jpg) | ![Cyber B-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/1-settings.jpg) |
75
+
76
+ </details>
77
+
78
+ <details>
79
+ <summary>🌸 Sakura Sky (bright)</summary>
80
+
81
+ **Display area includes sidebar (-0)**
82
+
83
+ | Front 1 | Front 2 | Settings |
84
+ |:---:|:---:|:---:|
85
+ | ![Sakura A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-front-1.jpg) | ![Sakura A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-front-2.jpg) | ![Sakura A-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-settings.jpg) |
86
+
87
+ **Display area excludes sidebar (-1)**
88
+
89
+ | Front 1 | Front 2 | Settings |
90
+ |:---:|:---:|:---:|
91
+ | ![Sakura B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/1-front-1.jpg) | ![Sakura B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/1-front-2.jpg) | ![Sakura B-settings](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/1-settings.jpg) |
92
+
93
+ </details>
94
+
13
95
  ## Features
14
96
 
15
97
  - **Interface module (7 background areas)**: Main / Sidebar / Conversation / Composer / Settings panel / Floating panel / Cordis panel
@@ -76,7 +158,20 @@ Source layout: `optimized/src/` contains 16 fragments (`00_*`~`15_*` + `host.js`
76
158
 
77
159
  ## Preset files (.tczp)
78
160
 
79
- Presets panel → "📥 Import preset" and pick a `.tczp` file to restore a whole config (images included — no original files needed). Export each preset via "📤 Export" in the same panel.
161
+ Presets panel → "Import preset" and pick a `.tczp` file to restore a whole config (images included — no original files needed). Export each preset via "Export" in the same panel.
162
+
163
+ ## 📦 Asset Pack
164
+
165
+ The **full assets** for all four themes (original wallpapers + 8 `.tczp` presets + all showcase screenshots) are packed in `展示.zip` attached to [GitHub Releases](https://github.com/lxxz1918/dsh-theme-customizer/releases). Download and extract with 7-Zip:
166
+
167
+ ```
168
+ 展示/
169
+ ├── readme展示图/ # README screenshots (4 themes × 2 variants × 3 shots)
170
+ ├── 展示1/ ~ 展示4/ # Each: original wallpapers (landscape + portrait) + 2 .tczp presets + shots
171
+ └── (wallpaper originals: 展示N/N-0, N-1)
172
+ ```
173
+
174
+ > Import: Settings → Theme → Presets → Import → pick `展示N-N.tczp` — images included, full effect restored in one click.
80
175
 
81
176
  ## Uninstall
82
177
 
@@ -84,6 +179,16 @@ Presets panel → "📥 Import preset" and pick a `.tczp` file to restore a whol
84
179
  dsh plugin --profile web remove dsh-theme-customizer
85
180
  ```
86
181
 
182
+ ## Contact & Feedback
183
+
184
+ - Bugs / feature requests → open an [issue](https://github.com/lxxz1918/dsh-theme-customizer/issues)
185
+ - Maintenance: issues are reviewed and replied to **every Sunday**
186
+ - Bilibili: [homepage](https://space.bilibili.com/38175333)
187
+
188
+ ## AI Usage
189
+
190
+ This project is designed and reviewed by [lxxz1918](https://github.com/lxxz1918); the code is written with the assistance of an AI assistant (DeepSeek). All feature requirements, UI copy and final results are confirmed by the author.
191
+
87
192
  ## License
88
193
 
89
194
  [MIT](LICENSE)
package/README.md CHANGED
@@ -1,15 +1,97 @@
1
1
  # dsh-theme-customizer
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/dsh-theme-customizer?style=flat-square)](https://www.npmjs.com/package/dsh-theme-customizer)
4
- [![license](https://img.shields.io/github/license/lxxz1918/dsh-theme-customizer?style=flat-square)](LICENSE)
5
- [![topic: dsh-plugin](https://img.shields.io/badge/topic-dsh--plugin-0969da?style=flat-square)](https://github.com/topics/dsh-plugin)
6
- [![stars](https://img.shields.io/github/stars/lxxz1918/dsh-theme-customizer?style=flat-square)](https://github.com/lxxz1918/dsh-theme-customizer/stargazers)
3
+ [![npm version](https://img.shields.io/npm/v/dsh-theme-customizer?style=flat-square&v=1)](https://www.npmjs.com/package/dsh-theme-customizer)
4
+ [![license](https://img.shields.io/github/license/lxxz1918/dsh-theme-customizer?style=flat-square&v=1)](LICENSE)
5
+ [![topic: dsh-plugin](https://img.shields.io/badge/topic-dsh--plugin-0969da?style=flat-square&v=1)](https://github.com/topics/dsh-plugin)
6
+ [![stars](https://img.shields.io/github/stars/lxxz1918/dsh-theme-customizer?style=flat-square&v=1)](https://github.com/lxxz1918/dsh-theme-customizer/stargazers)
7
7
 
8
8
  **中文** | [English](README.en.md)
9
9
 
10
10
  > DeepSeek Harness(DSH)Web 界面自定义主题插件:背景、文字、框线、细节全部可视化设置,刷新/重启不丢。
11
11
  > 配置存 localStorage,预设可导出 `.tczp` 文件(含图片)分享到任意电脑。
12
12
 
13
+ ## 🎨 主题展示
14
+
15
+ 四套 AI 生成壁纸主题(亮暗交替排列),每套含两种主界面「显示区域」模式:**包含侧边栏**(整屏一体)与**不包含侧边栏**(主体独立 + 侧边栏独立竖版壁纸),配套 `.tczp` 预设一键导入(见下方「素材包」)。
16
+
17
+ | 🌌 星空极光(暗) | 🌇 黄昏云海(亮) |
18
+ |:---:|:---:|
19
+ | ![星空极光](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-front-1.jpg) | ![黄昏云海](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-front-1.jpg) |
20
+ | **🌃 赛博夜景(暗)** | **🌸 樱花晴天(亮)** |
21
+ | ![赛博夜景](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-front-1.jpg) | ![樱花晴天](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-front-1.jpg) |
22
+
23
+ ## 📸 界面截图
24
+
25
+ 每套主题两种模式(对应预设 `-0` / `-1`):**显示区域包含侧边栏**(整屏一体背景)与**显示区域不包含侧边栏**(主体独立 + 侧边栏独立竖版壁纸)。每种模式 3 张:正面-1 / 正面-2 / 设置面。
26
+
27
+ <details>
28
+ <summary>🌌 星空极光(暗)</summary>
29
+
30
+ **显示区域包含侧边栏(-0)**
31
+
32
+ | 正面-1 | 正面-2 | 设置面 |
33
+ |:---:|:---:|:---:|
34
+ | ![星空极光A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-front-1.jpg) | ![星空极光A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-front-2.jpg) | ![星空极光A-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/0-settings.jpg) |
35
+
36
+ **显示区域不包含侧边栏(-1)**
37
+
38
+ | 正面-1 | 正面-2 | 设置面 |
39
+ |:---:|:---:|:---:|
40
+ | ![星空极光B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/1-front-1.jpg) | ![星空极光B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/1-front-2.jpg) | ![星空极光B-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/1-aurora/1-settings.jpg) |
41
+
42
+ </details>
43
+
44
+ <details>
45
+ <summary>🌇 黄昏云海(亮)</summary>
46
+
47
+ **显示区域包含侧边栏(-0)**
48
+
49
+ | 正面-1 | 正面-2 | 设置面 |
50
+ |:---:|:---:|:---:|
51
+ | ![黄昏云海A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-front-1.jpg) | ![黄昏云海A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-front-2.jpg) | ![黄昏云海A-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/0-settings.jpg) |
52
+
53
+ **显示区域不包含侧边栏(-1)**
54
+
55
+ | 正面-1 | 正面-2 | 设置面 |
56
+ |:---:|:---:|:---:|
57
+ | ![黄昏云海B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/1-front-1.jpg) | ![黄昏云海B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/1-front-2.jpg) | ![黄昏云海B-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/2-sunset/1-settings.jpg) |
58
+
59
+ </details>
60
+
61
+ <details>
62
+ <summary>🌃 赛博夜景(暗)</summary>
63
+
64
+ **显示区域包含侧边栏(-0)**
65
+
66
+ | 正面-1 | 正面-2 | 设置面 |
67
+ |:---:|:---:|:---:|
68
+ | ![赛博夜景A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-front-1.jpg) | ![赛博夜景A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-front-2.jpg) | ![赛博夜景A-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/0-settings.jpg) |
69
+
70
+ **显示区域不包含侧边栏(-1)**
71
+
72
+ | 正面-1 | 正面-2 | 设置面 |
73
+ |:---:|:---:|:---:|
74
+ | ![赛博夜景B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/1-front-1.jpg) | ![赛博夜景B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/1-front-2.jpg) | ![赛博夜景B-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/3-cyber/1-settings.jpg) |
75
+
76
+ </details>
77
+
78
+ <details>
79
+ <summary>🌸 樱花晴天(亮)</summary>
80
+
81
+ **显示区域包含侧边栏(-0)**
82
+
83
+ | 正面-1 | 正面-2 | 设置面 |
84
+ |:---:|:---:|:---:|
85
+ | ![樱花晴天A-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-front-1.jpg) | ![樱花晴天A-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-front-2.jpg) | ![樱花晴天A-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/0-settings.jpg) |
86
+
87
+ **显示区域不包含侧边栏(-1)**
88
+
89
+ | 正面-1 | 正面-2 | 设置面 |
90
+ |:---:|:---:|:---:|
91
+ | ![樱花晴天B-1](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/1-front-1.jpg) | ![樱花晴天B-2](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/1-front-2.jpg) | ![樱花晴天B-设置](https://github.com/lxxz1918/dsh-theme-customizer/raw/main/docs/screenshots/4-sakura/1-settings.jpg) |
92
+
93
+ </details>
94
+
13
95
  ## 功能一览
14
96
 
15
97
  - **界面板块(7 区域背景)**:主界面 / 侧边栏 / 对话区 / 输入区 / 设置界面 / 浮窗面板 / Cordis 插件界面
@@ -76,7 +158,20 @@ dsh plugin --profile web add <本仓库路径>
76
158
 
77
159
  ## 预设文件(.tczp)
78
160
 
79
- 预设面板 → 「📥 导入预设」选择 `.tczp` 文件即可恢复整套配置(含图片,无需原图)。导出同样在预设面板逐条「📤 导出」。
161
+ 预设面板 → 「导入预设」选择 `.tczp` 文件即可恢复整套配置(含图片,无需原图)。导出同样在预设面板逐条「导出」。
162
+
163
+ ## 📦 素材包
164
+
165
+ 四套主题的**完整素材**(壁纸原图 + 8 个 `.tczp` 预设 + 全部展示截图)打包在 [GitHub Releases 附件](https://github.com/lxxz1918/dsh-theme-customizer/releases) 的 `展示.zip` 中,下载后 7-Zip 解压即可:
166
+
167
+ ```
168
+ 展示/
169
+ ├── readme展示图/ # README 用展示截图(4 主题 × 2 方案 × 3 张)
170
+ ├── 展示1/ ~ 展示4/ # 每套:壁纸原图(横版 + 竖版)+ 2 个 .tczp 预设 + 截图
171
+ └── (壁纸竖版/横版原图见 展示N/N-0、N-1)
172
+ ```
173
+
174
+ > 预设导入:设置 → 主题 → 预设面板 → 导入预设 → 选 `展示N-N.tczp`,自动带图还原整套效果。
80
175
 
81
176
  ## 卸载
82
177
 
@@ -84,6 +179,16 @@ dsh plugin --profile web add <本仓库路径>
84
179
  dsh plugin --profile web remove dsh-theme-customizer
85
180
  ```
86
181
 
182
+ ## 联系与反馈
183
+
184
+ - 使用问题 / 功能建议 → [Issues](https://github.com/lxxz1918/dsh-theme-customizer/issues) 发议题
185
+ - 维护时间:**每周日**集中查看议题并回复
186
+ - 哔哩哔哩:[个人主页](https://space.bilibili.com/38175333)
187
+
188
+ ## AI 使用说明
189
+
190
+ 本项目由 [lxxz1918](https://github.com/lxxz1918) 主导设计与验收,代码在 AI 助手(DeepSeek)辅助下编写。所有功能需求、界面文案与最终效果均由作者本人确认。
191
+
87
192
  ## License
88
193
 
89
194
  [MIT](LICENSE)
package/lib/client.js CHANGED
@@ -28,7 +28,8 @@ window.__ModuleLoader__.load({
28
28
  ]
29
29
  // 框线区域(v0.9.18):main=主界面(含侧边栏,覆盖布局三列)/ cordis=Cordis 插件界面 / composer=输入区 /
30
30
  // details=设置界面 / float=浮窗面板;label 显示名在 15_borders.js,选择器在 07_css_builder buildBordersCss
31
- const BORDER_KEYS = ['main', 'cordis', 'composer', 'details', 'float']
31
+ // v1.0.2 newSession=新会话按钮(独立框线,主界面行下面设置;官方默认 1px border-l2)
32
+ const BORDER_KEYS = ['main', 'cordis', 'composer', 'details', 'float', 'newSession']
32
33
  // 框线默认色(v0.9.18 用户定):主界面/Cordis/输入区 = 淡灰 #e6e6e6(官方 border-l2 rgba(0,0,0,.1) 白底合成,与色块一致);
33
34
  // 设置界面/浮窗面板 = 黑色。CSS 用(07 buildBordersCss)、色块显示用(15 BordersModule)共用一处定义
34
35
  const BORDER_DEFAULT_LIGHT = '#e6e6e6'
@@ -109,15 +110,17 @@ window.__ModuleLoader__.load({
109
110
  // BrandWordmark path 顺序:第 1-10 个 = DeepSeek,第 11-17 个 = Harness(x 坐标 132-178)
110
111
  // → CSS `svg path:nth-child(n+11) { fill: 色 }` 直接覆盖 currentColor
111
112
  let brandHarness = { color: null, opacity: 0 }
112
- // 框线(v0.9.18):所有 UI 默认边框/分隔线颜色 + 透明度(数值大=透明),5 区域独立。
113
+ // 框线(v0.9.18):所有 UI 默认边框/分隔线颜色 + 透明度,5 区域独立。
113
114
  // color null=官方默认(此时 opacity>0 用 color-mix 淡化官方色,层级保留);
114
115
  // main=主界面(含侧边栏)/ cordis=Cordis 插件界面 / composer=输入区 / details=设置界面 / float=浮窗面板
116
+ // v1.0.2 加 newSession=新会话按钮(独立框线)
115
117
  let borders = {
116
118
  main: { color: null, opacity: 0 },
117
119
  cordis: { color: null, opacity: 0 },
118
120
  composer: { color: null, opacity: 0 },
119
121
  details: { color: null, opacity: 0 },
120
122
  float: { color: null, opacity: 0 },
123
+ newSession: { color: null, opacity: 0 },
121
124
  }
122
125
  // 设置界面面板拖动位置(v0.9.19):null=官方居中(默认);{x,y}=拖动后的固定位置(persist 到 localStorage)
123
126
  // 拖动用内联 style 直更(pointermove),pointerup 写回本状态 → CSS 重建保持位置(刷新不丢)
@@ -167,7 +170,8 @@ window.__ModuleLoader__.load({
167
170
  // sliderColor / sliderOpacity = 主题设置插件滑条(range,data-thmcz-range)已填充部分(左半边)+圆点 颜色/透明度
168
171
  // sliderTrackColor / sliderTrackOpacity = 滑条未填充轨道(右半边)颜色/透明度(v0.9.15;默认浏览器深色 → 必须自定义)
169
172
  // scrollColor / scrollOpacity = 浮窗界面滚动条([data-thmcz-float-scroll])thumb 颜色/透明度
170
- let convBgs = { bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, addBtn: null, cmdMenu: null, addBtnOpacity: 0, cmdMenuOpacity: 0, toBottom: null, sliderColor: null, sliderOpacity: 0, sliderTrackColor: null, sliderTrackOpacity: 0, scrollColor: null, scrollOpacity: 0 }
173
+ // v1.0.3:对话区 8 项各自加透明度键(bubble/inline/code 设色走 token rgba、未设色走元素 color-mix;其余设色 rgba)
174
+ let convBgs = { bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, addBtn: null, cmdMenu: null, addBtnOpacity: 0, cmdMenuOpacity: 0, toBottom: null, sliderColor: null, sliderOpacity: 0, sliderTrackColor: null, sliderTrackOpacity: 0, scrollColor: null, scrollOpacity: 0, bubbleOpacity: 0, inlineOpacity: 0, codeOpacity: 0, scrollbarOpacity: 0, chatScrollOpacity: 0, todoCollapsedOpacity: 0, todoExpandedOpacity: 0, toBottomOpacity: 0 }
171
175
 
172
176
  // ════════ 02_utils.js ════════
173
177
  // ┌─ 片段 02_utils ─────────────────────────────────
@@ -414,15 +418,16 @@ window.__ModuleLoader__.load({
414
418
  // 直更 style 标签(零 React 渲染)——此前每帧 notify 全量重渲染,同一滑条连续拖动越拖越卡。
415
419
  // ⚠️ v0.9.15 优化:bubble/inline/code(token 键)走 'conv'(style+token);其余键(滚动条/滑条/命令/V等)
416
420
  // 只走 'convStyle'(纯 style 标签,不刷 token)——此前拖动滚动条/滑条颜色每帧跑 buildThemeTokens+overrideTokens → 卡顿
417
- const CONV_TOKEN_KEYS = { bubble: true, inline: true, code: true }
421
+ // v1.0.3:bubble 系透明度键(bubbleOpacity/inlineOpacity/codeOpacity)走 token 覆盖(buildThemeTokens 合成 rgba)→ 'conv'
422
+ const CONV_TOKEN_KEYS = { bubble: true, inline: true, code: true, bubbleOpacity: true, inlineOpacity: true, codeOpacity: true }
418
423
  function setConvBg(key, v) {
419
424
  convBgs = { ...convBgs, [key]: v }
420
425
  if (Date.now() < saveSuppressUntil) manualCssRefresh(CONV_TOKEN_KEYS[key] ? 'conv' : 'convStyle')
421
426
  else { notify(); saveNow() }
422
427
  }
423
- // 全部恢复官方默认(对话区 8 项全 null,仿字体颜色 resetAllColors;v0.9.15 含 V 按钮)
428
+ // 全部恢复官方默认(对话区 8 项全 null + 透明度归零,仿字体颜色 resetAllColors;v1.0.3 含透明度)
424
429
  function resetAllConvBgs() {
425
- convBgs = { bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, toBottom: null }
430
+ convBgs = { ...convBgs, bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, toBottom: null, bubbleOpacity: 0, inlineOpacity: 0, codeOpacity: 0, scrollbarOpacity: 0, chatScrollOpacity: 0, todoCollapsedOpacity: 0, todoExpandedOpacity: 0, toBottomOpacity: 0 }
426
431
  notify(); saveNow()
427
432
  }
428
433
  // 命令子板块全部恢复官方默认(仅 addBtn/cmdMenu + 透明度两项,输入区卡片内;v0.9.14 含透明度归零)
@@ -453,9 +458,9 @@ window.__ModuleLoader__.load({
453
458
  newSession = { showText: true, showIcon: true, mode: 'none', color: '#ffffff', opacity: 0, bottomEnabled: true, bottomColor: '#ffffff', bottomOpacity: 0, image: null, iconColor: null, textColor: null }
454
459
  brand = { color: '#3964fe', opacity: 0 }
455
460
  brandHarness = { color: null, opacity: 0 }
456
- borders = { main: { color: null, opacity: 0 }, cordis: { color: null, opacity: 0 }, composer: { color: null, opacity: 0 }, details: { color: null, opacity: 0 }, float: { color: null, opacity: 0 } }
461
+ borders = { main: { color: null, opacity: 0 }, cordis: { color: null, opacity: 0 }, composer: { color: null, opacity: 0 }, details: { color: null, opacity: 0 }, float: { color: null, opacity: 0 }, newSession: { color: null, opacity: 0 } }
457
462
  colors = { main: null, process: null, aux: null, faded: null, accent: null }
458
- convBgs = { bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, addBtn: null, cmdMenu: null, addBtnOpacity: 0, cmdMenuOpacity: 0, toBottom: null, sliderColor: null, sliderOpacity: 0, sliderTrackColor: null, sliderTrackOpacity: 0, scrollColor: null, scrollOpacity: 0 }
463
+ convBgs = { bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, addBtn: null, cmdMenu: null, addBtnOpacity: 0, cmdMenuOpacity: 0, toBottom: null, sliderColor: null, sliderOpacity: 0, sliderTrackColor: null, sliderTrackOpacity: 0, scrollColor: null, scrollOpacity: 0, bubbleOpacity: 0, inlineOpacity: 0, codeOpacity: 0, scrollbarOpacity: 0, chatScrollOpacity: 0, todoCollapsedOpacity: 0, todoExpandedOpacity: 0, toBottomOpacity: 0 }
459
464
  showOpacityHint = true
460
465
  composerStatsExpanded = false
461
466
  detailsPos = null
@@ -463,6 +468,13 @@ window.__ModuleLoader__.load({
463
468
  composerFixedHeight = false
464
469
  composerRows = 4
465
470
  composerStatsItems = { turns: true, steps: true, llm: true, tool: true, ttft: true, tps: true, cache: true, input: true, output: true }
471
+ // ⚠️ v1.0.2 加固:清空 sidebarInfo 缓存并重新检测(2026-08-22 用户反馈——全局重置后第一次切
472
+ // 「不包含侧边栏」用了旧检测宽度 → 背景偏移错误盖进侧边栏右 4/5,刷新后才正常)。
473
+ // 检测走 detectSidebar(同步 DOM 查询,微秒级);结果与旧值相同则 setSidebarInfo 值比较直接跳过,零重渲染。
474
+ // 注意:本函数拼接顺序在 03_detect 之后(函数提升),detectSidebar 可用。
475
+ sidebarInfo = null
476
+ const info = detectSidebar()
477
+ if (info) setSidebarInfo(info)
466
478
  notify(); statsNotify(); floatNotify(); saveNow()
467
479
  }
468
480
  // 输入区卡片实测宽高比(非用户配置,不持久化):AreaCss 布局后测量,供 getCropRatio 使用。
@@ -616,7 +628,8 @@ window.__ModuleLoader__.load({
616
628
  if (c.composerStatsItems && typeof c.composerStatsItems === 'object') composerStatsItems = { ...composerStatsItems, ...c.composerStatsItems }
617
629
  // 对话区背景(2026-08-21 新增):null=官方默认;旧数据无此字段 → 保持默认;旧 terminal/assistant 字段已改版(忽略)
618
630
  // v0.9.14:命令两按钮透明度字段(addBtnOpacity/cmdMenuOpacity)默认 0;v0.9.15:toBottom/sliderColor/sliderTrackColor/scrollColor 及透明度
619
- if (c.convBgs && typeof c.convBgs === 'object') convBgs = { bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, addBtn: null, cmdMenu: null, addBtnOpacity: 0, cmdMenuOpacity: 0, toBottom: null, sliderColor: null, sliderOpacity: 0, sliderTrackColor: null, sliderTrackOpacity: 0, scrollColor: null, scrollOpacity: 0, ...c.convBgs }
631
+ // v1.0.3:对话区 8 项透明度键(bubbleOpacity 等)默认 0
632
+ if (c.convBgs && typeof c.convBgs === 'object') convBgs = { bubble: null, inline: null, code: null, scrollbar: null, chatScroll: null, todoCollapsed: null, todoExpanded: null, addBtn: null, cmdMenu: null, addBtnOpacity: 0, cmdMenuOpacity: 0, toBottom: null, sliderColor: null, sliderOpacity: 0, sliderTrackColor: null, sliderTrackOpacity: 0, scrollColor: null, scrollOpacity: 0, bubbleOpacity: 0, inlineOpacity: 0, codeOpacity: 0, scrollbarOpacity: 0, chatScrollOpacity: 0, todoCollapsedOpacity: 0, todoExpandedOpacity: 0, toBottomOpacity: 0, ...c.convBgs }
620
633
  // 兼容旧数据:缺新字段时立即写回一次(补全 cordisEntry 等);saveNow 不再 notify,这里补一次
621
634
  if (typeof c.cordisEntry !== 'boolean' || c.opacitySem !== 4) { saveNow(); notify() }
622
635
  } catch (e) { /* 忽略 */ }
@@ -822,8 +835,8 @@ window.__ModuleLoader__.load({
822
835
  for (const key of ['bubble', 'inline', 'code', 'scrollbar', 'chatScroll', 'todoCollapsed', 'todoExpanded', 'addBtn', 'cmdMenu', 'toBottom', 'sliderColor', 'sliderTrackColor', 'scrollColor']) {
823
836
  convBgs = { ...convBgs, [key]: (typeof cb[key] === 'string' && cb[key]) ? cb[key] : null }
824
837
  }
825
- // 透明度类键(v0.9.14/15):数值 0-1,缺失/非法回 0(不残留上一预设)
826
- for (const key of ['addBtnOpacity', 'cmdMenuOpacity', 'sliderOpacity', 'sliderTrackOpacity', 'scrollOpacity']) {
838
+ // 透明度类键(v0.9.14/15;v1.0.3 加对话区 8 项):数值 0-1,缺失/非法回 0(不残留上一预设)
839
+ for (const key of ['addBtnOpacity', 'cmdMenuOpacity', 'sliderOpacity', 'sliderTrackOpacity', 'scrollOpacity', 'bubbleOpacity', 'inlineOpacity', 'codeOpacity', 'scrollbarOpacity', 'chatScrollOpacity', 'todoCollapsedOpacity', 'todoExpandedOpacity', 'toBottomOpacity']) {
827
840
  const v = cb[key]
828
841
  convBgs = { ...convBgs, [key]: (typeof v === 'number' && v >= 0 && v <= 1) ? v : 0 }
829
842
  }
@@ -919,8 +932,11 @@ window.__ModuleLoader__.load({
919
932
  } else {
920
933
  cssParts.push('html, body { background-color: ' + bg + ' !important; background-image: ' + grad + ' !important; background-size: cover !important; background-position: center !important; background-repeat: no-repeat !important; }')
921
934
  }
922
- } else if (appBottom) {
923
- cssParts.push('html, body { background-color: ' + appBottom + ' !important; }')
935
+ } else {
936
+ // 「无」模式(v1.0.1 2026-08-22 用户定):不注入任何内容 = 完全官方原样。
937
+ // 曾做 html,body 垫色(v0.9.2),但官方 _frame/三列等容器自带不透明背景盖住垫色看不到,
938
+ // 且侧边栏「无」模式透出下层会透出垫色 → "侧边栏变红"(连锁问题)。
939
+ // 主界面「无」模式已不显示底色选项(09 AreaEditor);旧配置残留 bottomColor 也不再垫色。
924
940
  }
925
941
  return cssParts.join(' ')
926
942
  }
@@ -1060,6 +1076,8 @@ window.__ModuleLoader__.load({
1060
1076
  composer: '[data-composer-seat], [data-composer-card]',
1061
1077
  details: '[class*="VOzbGW_panel"]',
1062
1078
  float: '[data-thmcz-float]',
1079
+ // v1.0.2:新会话按钮独立框线(官方边框 1px solid border-l2 → 随本区域变量)
1080
+ newSession: '[class*="_newSession"]:not([class*="_newSessionLabel"])',
1063
1081
  }
1064
1082
  const cssParts = []
1065
1083
  for (const k of BORDER_KEYS) {
@@ -1088,17 +1106,21 @@ window.__ModuleLoader__.load({
1088
1106
  if (!ns.showText) cssParts.push(nsLabel + ' { display: none !important; }')
1089
1107
  if (!ns.showIcon) cssParts.push(nsBtn + ' svg { display: none !important; }')
1090
1108
  if (ns.mode === 'none') {
1091
- cssParts.push(nsBtn + ' { background-color: ' + bottom + ' !important; border-color: transparent !important; }')
1109
+ // 「无」模式:背景透明透出侧边栏,但保留官方边框(v1.0.2 用户定:默认状态新会话要有边框。
1110
+ // 曾强制 border-color transparent(v0.7.x"无模式完全隐形"),官方默认是 1px solid --dsw-alias-border-l2)
1111
+ cssParts.push(nsBtn + ' { background-color: ' + bottom + ' !important; }')
1092
1112
  cssParts.push(nsBtn + ':hover { background-color: transparent !important; }')
1093
1113
  } else if (ns.mode === 'color') {
1094
1114
  const a = 1 - (ns.opacity == null ? 0 : ns.opacity)
1095
1115
  const [r, g, b] = parseRgb(ns.color)
1096
- cssParts.push(nsBtn + ' { background-color: ' + bottom + ' !important; border-color: transparent !important; position: relative !important; z-index: 0 !important; }')
1116
+ // v1.0.2:纯色模式也保留边框(跟随新会话框线设置);边框绘制在 ::before 之上(背景在 z-index:-1 层)
1117
+ cssParts.push(nsBtn + ' { background-color: ' + bottom + ' !important; position: relative !important; z-index: 0 !important; }')
1097
1118
  cssParts.push(nsBtn + '::before { content: "" !important; position: absolute !important; inset: 0 !important; z-index: -1 !important; pointer-events: none !important; background-image: linear-gradient(rgba(' + r + ',' + g + ',' + b + ',' + a + '), rgba(' + r + ',' + g + ',' + b + ',' + a + ')) !important; background-size: cover !important; background-position: center !important; background-repeat: no-repeat !important; }')
1098
1119
  cssParts.push(nsBtn + ':hover { background-color: transparent !important; }')
1099
1120
  } else if (ns.mode === 'image' && ns.image) {
1100
1121
  const alpha = 1 - (ns.opacity == null ? 0 : ns.opacity)
1101
- cssParts.push(nsBtn + ' { background-color: ' + bottom + ' !important; border-color: transparent !important; position: relative !important; z-index: 0 !important; }')
1122
+ // v1.0.2:图片模式也保留边框(跟随新会话框线设置)
1123
+ cssParts.push(nsBtn + ' { background-color: ' + bottom + ' !important; position: relative !important; z-index: 0 !important; }')
1102
1124
  cssParts.push(nsBtn + '::before { content: "" !important; position: absolute !important; inset: 0 !important; z-index: -1 !important; pointer-events: none !important; background-image: var(--tcz-ns-img) !important; background-size: cover !important; background-position: center !important; background-repeat: no-repeat !important; -webkit-mask-image: linear-gradient(rgba(0,0,0,' + alpha + '), rgba(0,0,0,' + alpha + ')) !important; mask-image: linear-gradient(rgba(0,0,0,' + alpha + '), rgba(0,0,0,' + alpha + ')) !important; }')
1103
1125
  cssParts.push(nsBtn + ':hover { background-color: transparent !important; }')
1104
1126
  }
@@ -1140,30 +1162,55 @@ window.__ModuleLoader__.load({
1140
1162
  // column 内部**所有**滚动条(代码块 terminal/read/search/diff、JsonBlock、IO 卡片 IN/OUT 等,
1141
1163
  // 不管哈希类名)都跟随「代码块滚动条」。对话区滚动容器是 column 的**祖先**(不继承 column 变量)→
1142
1164
  // 不受影响,仍由「对话区滚动条」直接 thumb 控制。此前逐个补 _block_/md-code-block/pre/_body_ 仍有漏网(IO 卡片)
1165
+ // v1.0.3:对话区各键透明度(数值大=透明 → alpha = 1-opacity)——设色时合成 rgba;滚动条/任务栏/一键到底未设色时无官方色可淡,跳过
1166
+ const sbA = Math.max(0, Math.min(1, 1 - (convBgs.scrollbarOpacity == null ? 0 : convBgs.scrollbarOpacity)))
1143
1167
  if (convBgs.scrollbar) {
1144
- cssParts.push('[data-chat-flow] { --dsh-scrollbar-thumb: ' + convBgs.scrollbar + ' !important; --dsh-scrollbar-thumb-hover: ' + convBgs.scrollbar + ' !important; }')
1168
+ const c = sbA >= 1 ? convBgs.scrollbar : 'rgba(' + parseRgb(convBgs.scrollbar).join(',') + ',' + sbA + ')'
1169
+ cssParts.push('[data-chat-flow] { --dsh-scrollbar-thumb: ' + c + ' !important; --dsh-scrollbar-thumb-hover: ' + c + ' !important; }')
1145
1170
  }
1146
1171
  // 对话区滚动条(含 data-chat-flow 的 _scroll 容器):v0.9.19 改**直接作用于自身 thumb**(不设变量)——
1147
1172
  // 变量会被内部滚动条(JsonBlock 裸 pre 等)继承 → 代码块竖滚动条错误跟随对话区颜色(用户反馈"竖的绑错")。
1148
1173
  // ⚠️ v0.9.19 再修:不用 Firefox scrollbar-color——scrollbar-color 是**继承属性**,会继续污染内部代码块滚动条;
1149
1174
  // 只保留 Webkit ::-webkit-scrollbar-thumb 直接样式(只控制对话区最外层滚动条,即最右边的滚动条)
1175
+ const csA = Math.max(0, Math.min(1, 1 - (convBgs.chatScrollOpacity == null ? 0 : convBgs.chatScrollOpacity)))
1150
1176
  if (convBgs.chatScroll) {
1151
- cssParts.push('[class*="_scroll"]:has([data-chat-flow])::-webkit-scrollbar-thumb { background: ' + convBgs.chatScroll + ' !important; }')
1152
- cssParts.push('[class*="_scroll"]:has([data-chat-flow])::-webkit-scrollbar-thumb:hover { background: ' + convBgs.chatScroll + ' !important; }')
1177
+ const c = csA >= 1 ? convBgs.chatScroll : 'rgba(' + parseRgb(convBgs.chatScroll).join(',') + ',' + csA + ')'
1178
+ cssParts.push('[class*="_scroll"]:has([data-chat-flow])::-webkit-scrollbar-thumb { background: ' + c + ' !important; }')
1179
+ cssParts.push('[class*="_scroll"]:has([data-chat-flow])::-webkit-scrollbar-thumb:hover { background: ' + c + ' !important; }')
1153
1180
  }
1154
1181
  // 任务栏:展开滑入动画(官方渲染 list 时播放)+ 背景渐变(0.2s 快速跟手,与状态切换基本同步);
1155
1182
  // 收起 = 官方行为(list 瞬间移除,不做列表动画)
1156
1183
  cssParts.push('@keyframes tcz-todo-expand { from { opacity: 0; transform: scaleY(0.6); } to { opacity: 1; transform: scaleY(1); } }')
1157
1184
  cssParts.push('[data-testid="todo-panel"] [class*="_list"] { animation: tcz-todo-expand 0.4s ease-in-out !important; transform-origin: top !important; }')
1158
- // 收起 = 官方行为(list 瞬间移除,不做列表动画);背景色渐变(设色时)
1185
+ const tdA = Math.max(0, Math.min(1, 1 - (convBgs.todoCollapsedOpacity == null ? 0 : convBgs.todoCollapsedOpacity)))
1186
+ const teA = Math.max(0, Math.min(1, 1 - (convBgs.todoExpandedOpacity == null ? 0 : convBgs.todoExpandedOpacity)))
1159
1187
  if (convBgs.todoCollapsed || convBgs.todoExpanded) {
1160
1188
  cssParts.push('[data-testid="todo-panel"] { transition: background-color 0.2s ease-out !important; }')
1161
1189
  }
1162
1190
  if (convBgs.todoCollapsed) {
1163
- cssParts.push('[data-testid="todo-panel"]:has([aria-expanded="false"]) { background-color: ' + convBgs.todoCollapsed + ' !important; }')
1191
+ const c = tdA >= 1 ? convBgs.todoCollapsed : 'rgba(' + parseRgb(convBgs.todoCollapsed).join(',') + ',' + tdA + ')'
1192
+ cssParts.push('[data-testid="todo-panel"]:has([aria-expanded="false"]) { background-color: ' + c + ' !important; }')
1164
1193
  }
1165
1194
  if (convBgs.todoExpanded) {
1166
- cssParts.push('[data-testid="todo-panel"]:has([aria-expanded="true"]) { background-color: ' + convBgs.todoExpanded + ' !important; }')
1195
+ const c = teA >= 1 ? convBgs.todoExpanded : 'rgba(' + parseRgb(convBgs.todoExpanded).join(',') + ',' + teA + ')'
1196
+ cssParts.push('[data-testid="todo-panel"]:has([aria-expanded="true"]) { background-color: ' + c + ' !important; }')
1197
+ }
1198
+ // ── bubble/inline/code 未设色但透明度>0:元素级 color-mix 淡化官方 token(不覆盖 token——覆盖值里 var 自身会循环失效)──
1199
+ // 选择器:气泡 = 用户消息 _bubble;行内代码 = 非 pre 的 code;代码块 = _block_/md-code-block(banner 单列略过)
1200
+ const bOp = convBgs.bubbleOpacity == null ? 0 : convBgs.bubbleOpacity
1201
+ if (!convBgs.bubble && bOp > 0) {
1202
+ const pct = Math.round(Math.max(0, Math.min(1, 1 - bOp)) * 100) + '%'
1203
+ cssParts.push('[data-chat-flow] [class*="_bubble"] { background-color: color-mix(in srgb, var(--dsw-specific-bubble) ' + pct + ', transparent) !important; }')
1204
+ }
1205
+ const iOp = convBgs.inlineOpacity == null ? 0 : convBgs.inlineOpacity
1206
+ if (!convBgs.inline && iOp > 0) {
1207
+ const pct = Math.round(Math.max(0, Math.min(1, 1 - iOp)) * 100) + '%'
1208
+ cssParts.push('[data-chat-flow] :not(pre) > code { background-color: color-mix(in srgb, var(--dsw-alias-markdown-inline-code) ' + pct + ', transparent) !important; }')
1209
+ }
1210
+ const cOp = convBgs.codeOpacity == null ? 0 : convBgs.codeOpacity
1211
+ if (!convBgs.code && cOp > 0) {
1212
+ const pct = Math.round(Math.max(0, Math.min(1, 1 - cOp)) * 100) + '%'
1213
+ cssParts.push('[data-chat-flow] [class*="_block_"], [data-chat-flow] [class*="md-code-block"] { background-color: color-mix(in srgb, var(--dsw-alias-markdown-code-block) ' + pct + ', transparent) !important; }')
1167
1214
  }
1168
1215
  // 输入框「+」命令按钮背景(官方 --dsw-specific-selector;hover 官方 --dsw-alias-interactive-bg-hover-solid → 一并覆盖防悬停跳回官方色)
1169
1216
  // v0.9.14:支持透明度——自定义颜色用 rgba(1-opacity);官方默认色(addBtn null)时透明度作用于官方 token(color-mix)
@@ -1191,8 +1238,11 @@ window.__ModuleLoader__.load({
1191
1238
  cssParts.push('[class*="_3e4SsG_menu"] { background-color: color-mix(in srgb, var(--dsw-specific-menu) ' + pct + ', transparent) !important; }')
1192
1239
  }
1193
1240
  // 对话区「V」一键到底部按钮背景(v0.9.15):官方 token --dsw-alias-button-floating-fill 被布局手柄共用 → 精确选择器覆盖
1241
+ // v1.0.3:支持透明度(设色时 rgba 合成)
1242
+ const tbA = Math.max(0, Math.min(1, 1 - (convBgs.toBottomOpacity == null ? 0 : convBgs.toBottomOpacity)))
1194
1243
  if (convBgs.toBottom) {
1195
- cssParts.push('[class*="Md3f7G_toBottom"] { background-color: ' + convBgs.toBottom + ' !important; }')
1244
+ const c = tbA >= 1 ? convBgs.toBottom : 'rgba(' + parseRgb(convBgs.toBottom).join(',') + ',' + tbA + ')'
1245
+ cssParts.push('[class*="Md3f7G_toBottom"] { background-color: ' + c + ' !important; }')
1196
1246
  }
1197
1247
  // 主题设置插件滑条(v0.9.15):range 分左右两半——左半边(已填充)+ 右半边(未填充轨道)+ 圆点,各自独立颜色/透明度。
1198
1248
  // 仅作用于 data-thmcz-range(插件自己的 range,不碰官方滑条)。
@@ -1201,13 +1251,19 @@ window.__ModuleLoader__.load({
1201
1251
  // 透明度:数值大=透明 → alpha = 1-opacity(rgba)
1202
1252
  const sliderFill = convBgs.sliderColor
1203
1253
  const sliderTrack = convBgs.sliderTrackColor
1204
- if (sliderFill || sliderTrack) {
1205
- const fillA = Math.max(0, Math.min(1, 1 - (convBgs.sliderOpacity == null ? 0 : convBgs.sliderOpacity)))
1206
- const trackA = Math.max(0, Math.min(1, 1 - (convBgs.sliderTrackOpacity == null ? 0 : convBgs.sliderTrackOpacity)))
1207
- const fillRgb = sliderFill ? parseRgb(sliderFill) : null
1208
- const trackRgb = sliderTrack ? parseRgb(sliderTrack) : null
1209
- const fBg = sliderFill ? (fillA >= 1 ? sliderFill : 'rgba(' + fillRgb[0] + ',' + fillRgb[1] + ',' + fillRgb[2] + ',' + fillA + ')') : 'transparent'
1210
- const tBg = sliderTrack ? (trackA >= 1 ? sliderTrack : 'rgba(' + trackRgb[0] + ',' + trackRgb[1] + ',' + trackRgb[2] + ',' + trackA + ')') : 'rgba(128,128,128,0.3)'
1254
+ // v1.0.3:未设色也可调透明度(用户要滑条/轨道透明度默认显示)——未设色用默认初始色参与淡化
1255
+ // (填充 = Chrome 默认 accent #0060df、轨道 = rgba(128,128,128,0.3) 白底合成 #d9d9d9,与色块默认显示一致)
1256
+ const fillOp = convBgs.sliderOpacity == null ? 0 : convBgs.sliderOpacity
1257
+ const trackOp = convBgs.sliderTrackOpacity == null ? 0 : convBgs.sliderTrackOpacity
1258
+ if (sliderFill || sliderTrack || fillOp > 0 || trackOp > 0) {
1259
+ const fillA = Math.max(0, Math.min(1, 1 - fillOp))
1260
+ const trackA = Math.max(0, Math.min(1, 1 - trackOp))
1261
+ const fillBase = sliderFill || '#0060df'
1262
+ const trackBase = sliderTrack || '#d9d9d9'
1263
+ const fillRgb = parseRgb(fillBase)
1264
+ const trackRgb = parseRgb(trackBase)
1265
+ const fBg = fillA >= 1 ? fillBase : 'rgba(' + fillRgb[0] + ',' + fillRgb[1] + ',' + fillRgb[2] + ',' + fillA + ')'
1266
+ const tBg = trackA >= 1 ? trackBase : 'rgba(' + trackRgb[0] + ',' + trackRgb[1] + ',' + trackRgb[2] + ',' + trackA + ')'
1211
1267
  cssParts.push('[data-thmcz-range] { -webkit-appearance: none !important; appearance: none !important; background: transparent !important; --tcz-range-fill: ' + fBg + '; --tcz-range-track: ' + tBg + '; }')
1212
1268
  cssParts.push('[data-thmcz-range]::-webkit-slider-runnable-track { -webkit-appearance: none !important; appearance: none !important; height: 6px !important; border-radius: 3px !important; background: linear-gradient(to right, var(--tcz-range-fill) var(--tcz-range-val, 0%), var(--tcz-range-track) var(--tcz-range-val, 0%)) !important; }')
1213
1269
  cssParts.push('[data-thmcz-range]::-webkit-slider-thumb { -webkit-appearance: none !important; appearance: none !important; width: 14px !important; height: 14px !important; border-radius: 50% !important; margin-top: -4px !important; background-color: ' + fBg + ' !important; border: none !important; }')
@@ -1219,10 +1275,13 @@ window.__ModuleLoader__.load({
1219
1275
  // 浮窗界面滚动条(v0.9.15 修正):用户要的是浮窗(GlobalFloat)内容区滚动条 [data-thmcz-float-scroll],
1220
1276
  // 不是设置面板的(此前误做成 VOzbGW_options,用户反馈"没作用"——因为看的是浮窗滚动条)。
1221
1277
  // 变量作用于滚动容器(thumb var() 解析基准),滚动条宽度走 body 全局 8px
1222
- if (convBgs.scrollColor) {
1223
- const ca = Math.max(0, Math.min(1, 1 - (convBgs.scrollOpacity == null ? 0 : convBgs.scrollOpacity)))
1224
- const crgb = parseRgb(convBgs.scrollColor)
1225
- const cBg = ca >= 1 ? convBgs.scrollColor : 'rgba(' + crgb[0] + ',' + crgb[1] + ',' + crgb[2] + ',' + ca + ')'
1278
+ // v1.0.3:未设色也可调透明度(默认色 = 官方 scrollbar-bg-l1 → neutral-200 #e5e5e5)
1279
+ const scOp = convBgs.scrollOpacity == null ? 0 : convBgs.scrollOpacity
1280
+ if (convBgs.scrollColor || scOp > 0) {
1281
+ const ca = Math.max(0, Math.min(1, 1 - scOp))
1282
+ const base = convBgs.scrollColor || '#e5e5e5'
1283
+ const crgb = parseRgb(base)
1284
+ const cBg = ca >= 1 ? base : 'rgba(' + crgb[0] + ',' + crgb[1] + ',' + crgb[2] + ',' + ca + ')'
1226
1285
  cssParts.push('[data-thmcz-float-scroll] { --dsh-scrollbar-thumb: ' + cBg + ' !important; --dsh-scrollbar-thumb-hover: ' + cBg + ' !important; }')
1227
1286
  }
1228
1287
  return cssParts.join(' ')
@@ -1246,12 +1305,17 @@ window.__ModuleLoader__.load({
1246
1305
  }
1247
1306
  }
1248
1307
  // 对话区背景(2026-08-21):我的发言气泡 + 行内代码 + 代码块/编辑卡片/脚本终端(官方 token 覆盖,亮暗统一用户色)
1249
- if (convBgs.bubble) tokens['--dsw-specific-bubble'] = { light: convBgs.bubble, dark: convBgs.bubble }
1250
- if (convBgs.inline) tokens['--dsw-alias-markdown-inline-code'] = { light: convBgs.inline, dark: convBgs.inline }
1308
+ // v1.0.3 透明度:设色时 rgba(色, 1-opacity) 合成;未设色时透明度走 buildConvCss 元素级 color-mix(token 自引用会循环,勿在覆盖值里 var 自身)
1309
+ const bubbleA = Math.max(0, Math.min(1, 1 - (convBgs.bubbleOpacity == null ? 0 : convBgs.bubbleOpacity)))
1310
+ if (convBgs.bubble) tokens['--dsw-specific-bubble'] = { light: bubbleA >= 1 ? convBgs.bubble : 'rgba(' + parseRgb(convBgs.bubble).join(',') + ',' + bubbleA + ')', dark: bubbleA >= 1 ? convBgs.bubble : 'rgba(' + parseRgb(convBgs.bubble).join(',') + ',' + bubbleA + ')' }
1311
+ const inlineA = Math.max(0, Math.min(1, 1 - (convBgs.inlineOpacity == null ? 0 : convBgs.inlineOpacity)))
1312
+ if (convBgs.inline) tokens['--dsw-alias-markdown-inline-code'] = { light: inlineA >= 1 ? convBgs.inline : 'rgba(' + parseRgb(convBgs.inline).join(',') + ',' + inlineA + ')', dark: inlineA >= 1 ? convBgs.inline : 'rgba(' + parseRgb(convBgs.inline).join(',') + ',' + inlineA + ')' }
1313
+ const codeA = Math.max(0, Math.min(1, 1 - (convBgs.codeOpacity == null ? 0 : convBgs.codeOpacity)))
1251
1314
  if (convBgs.code) {
1252
- tokens['--dsw-alias-markdown-code-block'] = { light: convBgs.code, dark: convBgs.code }
1315
+ const cv = codeA >= 1 ? convBgs.code : 'rgba(' + parseRgb(convBgs.code).join(',') + ',' + codeA + ')'
1316
+ tokens['--dsw-alias-markdown-code-block'] = { light: cv, dark: cv }
1253
1317
  // banner(read/search 卡片标题栏)同色,补全"背景不完全"
1254
- tokens['--dsw-alias-markdown-code-block-banner'] = { light: convBgs.code, dark: convBgs.code }
1318
+ tokens['--dsw-alias-markdown-code-block-banner'] = { light: cv, dark: cv }
1255
1319
  }
1256
1320
  return tokens
1257
1321
  }
@@ -1273,6 +1337,21 @@ window.__ModuleLoader__.load({
1273
1337
  // · 非 token 键(scrollbar/chatScroll/todo*/addBtn/cmdMenu/toBottom/slider*/scroll*):只刷 conv style 标签('convStyle');
1274
1338
  // · token 键(bubble/inline/code):style + refreshConvTokens('conv')。
1275
1339
  // 此前拖动滚动条/滑条颜色每帧都跑 buildThemeTokens+overrideTokens(无用开销)→ 卡顿
1340
+ // ⚠️ v1.0.3 修复:Chromium 对 ::-webkit-scrollbar-thumb 样式变化**不即时重绘**(style 标签已更新但画面不变,
1341
+ // 松手触发 React 重渲染才刷新——用户反馈"对话区滚动条颜色/透明度调整不会实时变化")。
1342
+ // 强制重绘滚动容器:transform 微调(无布局跳动、不改变视觉);仅 convStyle/conv 分支调用(拖动滚动条/滑条相关)
1343
+ function repaintScrollbars() {
1344
+ try {
1345
+ for (const sel of ['[class*="_scroll"]:has([data-chat-flow])', '[data-chat-flow]']) {
1346
+ const el = document.querySelector(sel)
1347
+ if (!el) continue
1348
+ el.style.transform = 'translateZ(0)'
1349
+ void el.offsetHeight // 强制 reflow,刷新合成层 → 重绘 thumb
1350
+ el.style.transform = ''
1351
+ }
1352
+ } catch (e) { /* 忽略 */ }
1353
+ }
1354
+
1276
1355
  function manualCssRefresh(id) {
1277
1356
  try {
1278
1357
  const setStyle = (key, css) => {
@@ -1292,6 +1371,7 @@ window.__ModuleLoader__.load({
1292
1371
  setStyle('float', buildFloatCss())
1293
1372
  setStyle('conv', buildConvCss())
1294
1373
  refreshConvTokens()
1374
+ repaintScrollbars()
1295
1375
  return
1296
1376
  }
1297
1377
  if (id === 'app') setStyle('app', buildAppCss())
@@ -1303,8 +1383,8 @@ window.__ModuleLoader__.load({
1303
1383
  else if (id === 'ns') setStyle('ns', buildNewSessionCss())
1304
1384
  else if (id === 'cordis') setStyle('cordis', buildCordisCss())
1305
1385
  else if (id === 'float') setStyle('float', buildFloatCss())
1306
- else if (id === 'convStyle') setStyle('conv', buildConvCss())
1307
- else if (id === 'conv') { setStyle('conv', buildConvCss()); refreshConvTokens() }
1386
+ else if (id === 'convStyle') { setStyle('conv', buildConvCss()); repaintScrollbars() }
1387
+ else if (id === 'conv') { setStyle('conv', buildConvCss()); refreshConvTokens(); repaintScrollbars() }
1308
1388
  } catch (e) { /* 忽略 */ }
1309
1389
  }
1310
1390
 
@@ -1500,7 +1580,7 @@ window.__ModuleLoader__.load({
1500
1580
  const liftCss = React.useMemo(() => buildLiftCss(), [areas.sidebar.mode, areas.sidebar.image, sidebarInfo])
1501
1581
  const cordisCss = React.useMemo(() => buildCordisCss(), [areas.cordis, baseBg])
1502
1582
  const floatCss = React.useMemo(() => buildFloatCss(), [floatVisible, areas.float])
1503
- const convCss = React.useMemo(() => buildConvCss(), [convBgs.scrollbar, convBgs.chatScroll, convBgs.todoCollapsed, convBgs.todoExpanded, convBgs.addBtn, convBgs.cmdMenu, convBgs.addBtnOpacity, convBgs.cmdMenuOpacity, convBgs.toBottom, convBgs.sliderColor, convBgs.sliderOpacity, convBgs.sliderTrackColor, convBgs.sliderTrackOpacity, convBgs.scrollColor, convBgs.scrollOpacity])
1583
+ const convCss = React.useMemo(() => buildConvCss(), [convBgs.scrollbar, convBgs.chatScroll, convBgs.todoCollapsed, convBgs.todoExpanded, convBgs.addBtn, convBgs.cmdMenu, convBgs.addBtnOpacity, convBgs.cmdMenuOpacity, convBgs.toBottom, convBgs.sliderColor, convBgs.sliderOpacity, convBgs.sliderTrackColor, convBgs.sliderTrackOpacity, convBgs.scrollColor, convBgs.scrollOpacity, convBgs.scrollbarOpacity, convBgs.chatScrollOpacity, convBgs.todoCollapsedOpacity, convBgs.todoExpandedOpacity, convBgs.toBottomOpacity, convBgs.bubbleOpacity, convBgs.inlineOpacity, convBgs.codeOpacity])
1504
1584
 
1505
1585
  // 各模块独立 <style> 标签:规则相对顺序与原单标签一致(img → app → composer → details → sidebar → ns → lift → cordis → float → conv)
1506
1586
  return React.createElement(React.Fragment, null,
@@ -1999,7 +2079,10 @@ window.__ModuleLoader__.load({
1999
2079
  : null,
2000
2080
  // 底色:主界面(app)/输入区/设置界面/浮窗面板/Cordis 卡片底部"底色";
2001
2081
  // 透明度显示(v0.9.14 用户定):sidebar + details + float + composer + cordis 显示底色透明度;app 仅颜色(用户 v0.9.2 定主界面底色仅颜色)
2002
- area.id === 'app' || area.id === 'sidebar' || area.id === 'composer' || area.id === 'details' || area.id === 'float' || area.id === 'cordis'
2082
+ // ⚠️ v1.0.1(2026-08-22 用户定):主界面「无」模式不显示底色——无模式下官方原样、不做垫色
2083
+ // (此前「无」模式垫色被官方 _frame/三列不透明背景盖住看不到,且透出到侧边栏导致"侧边栏变红"连锁问题);
2084
+ // 纯色/图片模式的底层垫色保留(appBottom 仍参与 color/image 分支)
2085
+ (area.id !== 'app' || value.mode !== 'none') && (area.id === 'app' || area.id === 'sidebar' || area.id === 'composer' || area.id === 'details' || area.id === 'float' || area.id === 'cordis')
2003
2086
  ? React.createElement(BottomRow, { value: value, onChange: (next) => onChange({ ...value, ...next }), style: { marginTop: '4px', marginBottom: '4px' }, title: '底色', hideOpacity: area.id === 'app', noSwitch: area.id !== 'sidebar' })
2004
2087
  : null,
2005
2088
  children,
@@ -2183,9 +2266,12 @@ window.__ModuleLoader__.load({
2183
2266
  const { convBgs } = useStore(['main'])
2184
2267
  return React.createElement('div', { style: { marginTop: '8px', paddingTop: '10px', borderTop: '1px solid var(--dsw-alias-border-l1)' } },
2185
2268
  React.createElement('div', { style: { fontSize: '13px', fontWeight: 600, marginBottom: '6px' } }, '滑条与滚动条'),
2186
- ConvBgRow({ label: '滑条颜色', value: convBgs.sliderColor, onSet: (v) => setConvBg('sliderColor', v), opacity: convBgs.sliderOpacity == null ? 0 : convBgs.sliderOpacity, onOpacity: (v) => setConvBg('sliderOpacity', v), onReset: () => { setConvBg('sliderColor', null); setConvBg('sliderOpacity', 0) }, noDefaultText: true }),
2187
- ConvBgRow({ label: '滑条轨道颜色', value: convBgs.sliderTrackColor, onSet: (v) => setConvBg('sliderTrackColor', v), opacity: convBgs.sliderTrackOpacity == null ? 0 : convBgs.sliderTrackOpacity, onOpacity: (v) => setConvBg('sliderTrackOpacity', v), onReset: () => { setConvBg('sliderTrackColor', null); setConvBg('sliderTrackOpacity', 0) }, noDefaultText: true }),
2188
- ConvBgRow({ label: '滚动条颜色', value: convBgs.scrollColor, onSet: (v) => setConvBg('scrollColor', v), opacity: convBgs.scrollOpacity == null ? 0 : convBgs.scrollOpacity, onOpacity: (v) => setConvBg('scrollOpacity', v), onReset: () => { setConvBg('scrollColor', null); setConvBg('scrollOpacity', 0) }, noDefaultText: true }),
2269
+ // v1.0.3:色块默认显示真实初始色(用户反馈"默认值不是初始值")——
2270
+ // 滑条填充未设置 = 浏览器默认 accent #0060df(Chrome 默认 range 已填充色);
2271
+ // 轨道未设置 = buildConvCss 默认 rgba(128,128,128,0.3) 白底合成 #d9d9d9
2272
+ ConvBgRow({ label: '滑条颜色', value: convBgs.sliderColor, onSet: (v) => setConvBg('sliderColor', v), opacity: convBgs.sliderOpacity == null ? 0 : convBgs.sliderOpacity, onOpacity: (v) => setConvBg('sliderOpacity', v), onReset: () => { setConvBg('sliderColor', null); setConvBg('sliderOpacity', 0) }, noDefaultText: true, defaultSwatch: '#0060df', opacityAlways: true }),
2273
+ ConvBgRow({ label: '滑条轨道颜色', value: convBgs.sliderTrackColor, onSet: (v) => setConvBg('sliderTrackColor', v), opacity: convBgs.sliderTrackOpacity == null ? 0 : convBgs.sliderTrackOpacity, onOpacity: (v) => setConvBg('sliderTrackOpacity', v), onReset: () => { setConvBg('sliderTrackColor', null); setConvBg('sliderTrackOpacity', 0) }, noDefaultText: true, defaultSwatch: '#d9d9d9', opacityAlways: true }),
2274
+ ConvBgRow({ label: '滚动条颜色', value: convBgs.scrollColor, onSet: (v) => setConvBg('scrollColor', v), opacity: convBgs.scrollOpacity == null ? 0 : convBgs.scrollOpacity, onOpacity: (v) => setConvBg('scrollOpacity', v), onReset: () => { setConvBg('scrollColor', null); setConvBg('scrollOpacity', 0) }, noDefaultText: true, defaultSwatch: '#e5e5e5', opacityAlways: true }),
2189
2275
  )
2190
2276
  }
2191
2277
 
@@ -2197,8 +2283,8 @@ window.__ModuleLoader__.load({
2197
2283
  // v0.9.18:恢复按钮条件含透明度(只调透明度未调颜色时也可恢复)——框线/滑条区需要
2198
2284
  // v0.9.18:可选 defaultSwatch——未设置(value null)时色块显示的默认色(默认 #ffffff;框线板块传官方淡灰/设置界面黑色)
2199
2285
  // v0.9.18:可选 defaultText——未设置时的状态文本(默认"官方默认";浮窗面板传"默认"——浮窗是插件自己的面板无官方语义)
2200
- function ConvBgRow({ label, value, onSet, opacity, onOpacity, onReset, noDefaultText, defaultSwatch, defaultText }) {
2201
- // 透明度滑条始终可用(官方默认色 + 用户透明度 → buildConvCss 用 color-mix 作用于官方 token)
2286
+ function ConvBgRow({ label, value, onSet, opacity, onOpacity, onReset, noDefaultText, defaultSwatch, defaultText, opacityAlways }) {
2287
+ // hasOpacity = 是否接透明度滑条;opacityAlways=true(命令按钮)始终显示,false(默认)仅设色后显示
2202
2288
  const hasOpacity = opacity != null && onOpacity != null
2203
2289
  const custom = !!(value || (hasOpacity && opacity > 0))
2204
2290
  return React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'wrap', marginBottom: '6px', fontSize: '12px' } },
@@ -2212,8 +2298,8 @@ window.__ModuleLoader__.load({
2212
2298
  label: '恢复官方默认', confirmLabel: '确认恢复官方默认',
2213
2299
  onConfirm: () => { if (onReset) onReset(); else onSet(null) }, resetKey: (value || '') + '|' + (hasOpacity ? (opacity == null ? 0 : opacity) : ''),
2214
2300
  }) : null,
2215
- // 透明度滑条(仅命令两按钮 + 有自定义颜色时):数值大=透明(语义同全局);拖动走 OpacitySlider 内部抑制(suppress/commit,直更 style)
2216
- hasOpacity ? React.createElement(OpacitySlider, { value: opacity, onChange: (v) => onOpacity(v) }) : null,
2301
+ // 透明度滑条:opacityAlways=true(命令按钮)始终显示(官方默认色也可调);默认 false(对话区)仅设色后显示(未设色无官方色可淡,拖动无效会困惑)
2302
+ hasOpacity && (opacityAlways || custom) ? React.createElement(OpacitySlider, { value: opacity, onChange: (v) => onOpacity(v) }) : null,
2217
2303
  )
2218
2304
  }
2219
2305
 
@@ -2221,18 +2307,19 @@ window.__ModuleLoader__.load({
2221
2307
  // 渲染在「对话区」卡片内部(原待支持区块,现挂接本子版块);底部"全部恢复官方默认"(任一改动过才显示,仿字体颜色)
2222
2308
  function ConversationEditor() {
2223
2309
  const { convBgs } = useStore()
2224
- const hasCustom = !!convBgs.bubble || !!convBgs.inline || !!convBgs.code || !!convBgs.scrollbar || !!convBgs.chatScroll || !!convBgs.todoCollapsed || !!convBgs.todoExpanded || !!convBgs.toBottom
2310
+ const hasCustom = !!convBgs.bubble || !!convBgs.inline || !!convBgs.code || !!convBgs.scrollbar || !!convBgs.chatScroll || !!convBgs.todoCollapsed || !!convBgs.todoExpanded || !!convBgs.toBottom || !!convBgs.bubbleOpacity || !!convBgs.inlineOpacity || !!convBgs.codeOpacity || !!convBgs.scrollbarOpacity || !!convBgs.chatScrollOpacity || !!convBgs.todoCollapsedOpacity || !!convBgs.todoExpandedOpacity || !!convBgs.toBottomOpacity
2225
2311
  return React.createElement('div', null,
2226
- ConvBgRow({ label: '用户发言背景', value: convBgs.bubble, onSet: (v) => setConvBg('bubble', v) }),
2227
- ConvBgRow({ label: '行内代码背景', value: convBgs.inline, onSet: (v) => setConvBg('inline', v) }),
2312
+ // v1.0.3:8 项全部支持透明度(opacity 数值大=透明;onReset 同时清色+清透明度)
2313
+ ConvBgRow({ label: '用户发言背景', value: convBgs.bubble, onSet: (v) => setConvBg('bubble', v), opacity: convBgs.bubbleOpacity == null ? 0 : convBgs.bubbleOpacity, onOpacity: (v) => setConvBg('bubbleOpacity', v), onReset: () => { setConvBg('bubble', null); setConvBg('bubbleOpacity', 0) } }),
2314
+ ConvBgRow({ label: '行内代码背景', value: convBgs.inline, onSet: (v) => setConvBg('inline', v), opacity: convBgs.inlineOpacity == null ? 0 : convBgs.inlineOpacity, onOpacity: (v) => setConvBg('inlineOpacity', v), onReset: () => { setConvBg('inline', null); setConvBg('inlineOpacity', 0) } }),
2228
2315
  // v0.9.19:代码块滚动条 / 对话区滚动条两行位置对调(元素整体移动,键跟随;用户要求交换位置+文本)
2229
2316
  // v0.9.20 小调整:代码块背景 / 代码块滚动条位置交换(背景在前、滚动条在后,更符合逻辑)
2230
- ConvBgRow({ label: '代码块背景', value: convBgs.code, onSet: (v) => setConvBg('code', v) }),
2231
- ConvBgRow({ label: '代码块滚动条', value: convBgs.scrollbar, onSet: (v) => setConvBg('scrollbar', v) }),
2232
- ConvBgRow({ label: '对话区滚动条', value: convBgs.chatScroll, onSet: (v) => setConvBg('chatScroll', v) }),
2233
- ConvBgRow({ label: '任务栏收起', value: convBgs.todoCollapsed, onSet: (v) => setConvBg('todoCollapsed', v) }),
2234
- ConvBgRow({ label: '任务栏展开', value: convBgs.todoExpanded, onSet: (v) => setConvBg('todoExpanded', v) }),
2235
- ConvBgRow({ label: '一键到底', value: convBgs.toBottom, onSet: (v) => setConvBg('toBottom', v) }),
2317
+ ConvBgRow({ label: '代码块背景', value: convBgs.code, onSet: (v) => setConvBg('code', v), opacity: convBgs.codeOpacity == null ? 0 : convBgs.codeOpacity, onOpacity: (v) => setConvBg('codeOpacity', v), onReset: () => { setConvBg('code', null); setConvBg('codeOpacity', 0) } }),
2318
+ ConvBgRow({ label: '代码块滚动条', value: convBgs.scrollbar, onSet: (v) => setConvBg('scrollbar', v), opacity: convBgs.scrollbarOpacity == null ? 0 : convBgs.scrollbarOpacity, onOpacity: (v) => setConvBg('scrollbarOpacity', v), onReset: () => { setConvBg('scrollbar', null); setConvBg('scrollbarOpacity', 0) } }),
2319
+ ConvBgRow({ label: '对话区滚动条', value: convBgs.chatScroll, onSet: (v) => setConvBg('chatScroll', v), opacity: convBgs.chatScrollOpacity == null ? 0 : convBgs.chatScrollOpacity, onOpacity: (v) => setConvBg('chatScrollOpacity', v), onReset: () => { setConvBg('chatScroll', null); setConvBg('chatScrollOpacity', 0) } }),
2320
+ ConvBgRow({ label: '任务栏收起', value: convBgs.todoCollapsed, onSet: (v) => setConvBg('todoCollapsed', v), opacity: convBgs.todoCollapsedOpacity == null ? 0 : convBgs.todoCollapsedOpacity, onOpacity: (v) => setConvBg('todoCollapsedOpacity', v), onReset: () => { setConvBg('todoCollapsed', null); setConvBg('todoCollapsedOpacity', 0) } }),
2321
+ ConvBgRow({ label: '任务栏展开', value: convBgs.todoExpanded, onSet: (v) => setConvBg('todoExpanded', v), opacity: convBgs.todoExpandedOpacity == null ? 0 : convBgs.todoExpandedOpacity, onOpacity: (v) => setConvBg('todoExpandedOpacity', v), onReset: () => { setConvBg('todoExpanded', null); setConvBg('todoExpandedOpacity', 0) } }),
2322
+ ConvBgRow({ label: '一键到底', value: convBgs.toBottom, onSet: (v) => setConvBg('toBottom', v), opacity: convBgs.toBottomOpacity == null ? 0 : convBgs.toBottomOpacity, onOpacity: (v) => setConvBg('toBottomOpacity', v), onReset: () => { setConvBg('toBottom', null); setConvBg('toBottomOpacity', 0) }, noDefaultText: true }),
2236
2323
  hasCustom
2237
2324
  ? React.createElement('div', { style: { marginTop: '4px' } },
2238
2325
  React.createElement(ConfirmButton, {
@@ -3020,8 +3107,8 @@ window.__ModuleLoader__.load({
3020
3107
  // ── 命令(「+」按钮背景 / 命令菜单背景 + 透明度 + 全部恢复官方默认)──
3021
3108
  React.createElement('div', { style: { marginTop: '8px', paddingTop: '10px', borderTop: '1px solid var(--dsw-alias-border-l1)' } },
3022
3109
  React.createElement('div', { style: { fontSize: '13px', fontWeight: 600, marginBottom: '6px' } }, '命令'),
3023
- ConvBgRow({ label: '命令按钮', value: convBgs.addBtn, onSet: (v) => setConvBg('addBtn', v), opacity: convBgs.addBtnOpacity == null ? 0 : convBgs.addBtnOpacity, onOpacity: (v) => setConvBg('addBtnOpacity', v), onReset: () => { setConvBg('addBtn', null); setConvBg('addBtnOpacity', 0) } }),
3024
- ConvBgRow({ label: '命令菜单', value: convBgs.cmdMenu, onSet: (v) => setConvBg('cmdMenu', v), opacity: convBgs.cmdMenuOpacity == null ? 0 : convBgs.cmdMenuOpacity, onOpacity: (v) => setConvBg('cmdMenuOpacity', v), onReset: () => { setConvBg('cmdMenu', null); setConvBg('cmdMenuOpacity', 0) } }),
3110
+ ConvBgRow({ label: '命令按钮', value: convBgs.addBtn, onSet: (v) => setConvBg('addBtn', v), opacity: convBgs.addBtnOpacity == null ? 0 : convBgs.addBtnOpacity, onOpacity: (v) => setConvBg('addBtnOpacity', v), onReset: () => { setConvBg('addBtn', null); setConvBg('addBtnOpacity', 0) }, opacityAlways: true }),
3111
+ ConvBgRow({ label: '命令菜单', value: convBgs.cmdMenu, onSet: (v) => setConvBg('cmdMenu', v), opacity: convBgs.cmdMenuOpacity == null ? 0 : convBgs.cmdMenuOpacity, onOpacity: (v) => setConvBg('cmdMenuOpacity', v), onReset: () => { setConvBg('cmdMenu', null); setConvBg('cmdMenuOpacity', 0) }, opacityAlways: true }),
3025
3112
  cmdCustom
3026
3113
  ? React.createElement('div', { style: { marginTop: '4px' } },
3027
3114
  React.createElement(ConfirmButton, {
@@ -3067,6 +3154,8 @@ window.__ModuleLoader__.load({
3067
3154
  const { borders } = useStore(['main'])
3068
3155
  const defs = [
3069
3156
  { id: 'main', label: '主界面' },
3157
+ // v1.0.2:新会话独立框线,紧跟主界面行(用户定:新会话框线在主界面框线下设置)
3158
+ { id: 'newSession', label: '新会话' },
3070
3159
  { id: 'cordis', label: 'Cordis 插件界面' },
3071
3160
  { id: 'composer', label: '输入区' },
3072
3161
  { id: 'details', label: '设置界面' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-theme-customizer",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "DeepSeek Harness (DSH) Web 界面自定义主题插件:七区域背景(主界面/侧边栏/输入区/设置界面/浮窗/Cordis,纯色/图片/选区裁剪/透明度)、文字颜色 5 类、框线颜色、标志调色、对话区细节定制、输入区统计条接管、浮动主题面板、预设导入导出(.tczp 含图)、localStorage 持久化。",
5
5
  "license": "MIT",
6
6
  "type": "module",