dsh-background-by-model 0.2.4 → 0.3.0
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.md +248 -142
- package/README.zh.md +248 -142
- package/lib/client.js +2277 -3085
- package/lib/client.js.map +1 -1
- package/lib/index.js +203 -361
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,142 +1,248 @@
|
|
|
1
|
-
# dsh-background-by-model
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
<a href="https://github.com/HarmlessFunny/dsh-background-by-model"><img src="https://img.shields.io/github/stars/HarmlessFunny/dsh-background-by-model?style=social" alt="GitHub stars"></a>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
##
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
1
|
+
# dsh-background-by-model
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://github.com/HarmlessFunny/dsh-background-by-model"><img src="https://img.shields.io/github/stars/HarmlessFunny/dsh-background-by-model?style=social" alt="GitHub stars"></a>
|
|
5
|
+
<a href="https://www.npmjs.com/package/dsh-background-by-model"><img src="https://img.shields.io/npm/v/dsh-background-by-model" alt="npm version"></a>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
> Forked from [`Tkingxiao/dsh-any-background`](https://github.com/Tkingxiao/dsh-any-background) and renamed to `dsh-background-by-model`.
|
|
11
|
+
|
|
12
|
+
A **DeepSeek Harness** appearance plugin built around an **ordered list of model rules**. Each rule carries its own wallpaper, theme color, layout mode, framing, opacity and blur — switch the model, and the background switches with it.
|
|
13
|
+
|
|
14
|
+
> **v0.3.0 is a breaking release.** Video wallpapers, generated dynamic backgrounds and the single global theme color were removed. See [Upgrading from 0.2.x](#upgrading-from-02x).
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## How Model Rules Work
|
|
19
|
+
|
|
20
|
+
A rule is a **match string** plus **one complete set of background settings**. When you switch models, the plugin reads the current session's model name, scans the list top-down, and applies the **first** rule whose match string appears anywhere in that model name (case-insensitive). If nothing matches, **rule 1** is used — rule 1 doubles as the fallback.
|
|
21
|
+
|
|
22
|
+
Example list:
|
|
23
|
+
|
|
24
|
+
| # | Match string | Wallpaper |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| 1 | `deepseek` | Image A |
|
|
27
|
+
| 2 | `flash` | Image B |
|
|
28
|
+
| 3 | `glm` | Image C |
|
|
29
|
+
|
|
30
|
+
| Current model | Result | Why |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| `DeepSeek-Flash` | Rule 1 → Image A | `deepseek` matches first |
|
|
33
|
+
| `GLM-Flash` | Rule 2 → Image B | `flash` is earlier in the list than `glm` |
|
|
34
|
+
| `Qwen-Flash` | Rule 2 → Image B | `flash` matches |
|
|
35
|
+
| `GLM-Turbo` | Rule 3 → Image C | only `glm` matches |
|
|
36
|
+
| `Kimi-K3` | Fallback → Rule 1 → Image A | no rule matches |
|
|
37
|
+
|
|
38
|
+
Notes:
|
|
39
|
+
|
|
40
|
+
- **Order matters.** The first match wins, not the best match — drag rules to reorder them.
|
|
41
|
+
- **An empty match string** makes a rule skip matching entirely and act purely as a fallback. A single rule with an empty match string is therefore "one wallpaper everywhere".
|
|
42
|
+
- The match string is compared against the concatenation of **provider, model id and model display name**, so any of the three can be used to select a rule.
|
|
43
|
+
- The current model is read from **this session's durable model selection** (the `modelSelection` projection — the same value the composer's model picker renders), so switching the model inside a session takes effect immediately. The Model Background page shows which model was read, and labels it **host default** when only the host-wide default was available instead of this session's own selection.
|
|
44
|
+
|
|
45
|
+
> Note: the example table above has **no `kimi`** entry, so switching to Kimi falls back to rule 1 = Image A, which looks like "nothing happened". Add a rule with the match string `kimi` to give Kimi its own wallpaper.
|
|
46
|
+
|
|
47
|
+
## Screenshots
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<img src="example_img/image.png" alt="Custom homepage" width="720">
|
|
51
|
+
<br/>
|
|
52
|
+
<em>Custom homepage · wallpaper + theme color of the matched rule applied</em>
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<p align="center">
|
|
56
|
+
<img src="example_img/image-2.png" alt="Per-rule theme color picker" width="720">
|
|
57
|
+
<br/>
|
|
58
|
+
<em>Per-rule theme color · HSL wheel + numeric input + inspiration palette</em>
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
<p align="center">
|
|
62
|
+
<img src="example_img/image-4.png" alt="Per-rule background editor" width="720">
|
|
63
|
+
<br/>
|
|
64
|
+
<em>Per-rule background editor · drag to pan and scroll to zoom (available in Fit mode)</em>
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
<p align="center">
|
|
68
|
+
<img src="example_img/image-6.png" alt="Model background rules list" width="720">
|
|
69
|
+
<br/>
|
|
70
|
+
<em>Model Background tab · ordered rule list with a live match readout</em>
|
|
71
|
+
</p>
|
|
72
|
+
|
|
73
|
+
<p align="center">
|
|
74
|
+
<img src="example_img/image-3.png" alt="Global opacity and blur" width="720">
|
|
75
|
+
<br/>
|
|
76
|
+
<em>Interface tab · global opacity and blur for each interface part</em>
|
|
77
|
+
</p>
|
|
78
|
+
|
|
79
|
+
<p align="center">
|
|
80
|
+
<img src="example_img/image-9.png" alt="Layout modes" width="720">
|
|
81
|
+
<br/>
|
|
82
|
+
<em>Layout modes · Fit / Fill / Stretch / Tile / Center, per rule</em>
|
|
83
|
+
</p>
|
|
84
|
+
|
|
85
|
+
<p align="center">
|
|
86
|
+
<img src="example_img/image-10.png" alt="Config export and import" width="720">
|
|
87
|
+
<br/>
|
|
88
|
+
<em>Export and import configs to share</em>
|
|
89
|
+
</p>
|
|
90
|
+
|
|
91
|
+
## Features
|
|
92
|
+
|
|
93
|
+
### Model rules
|
|
94
|
+
|
|
95
|
+
- **Ordered Rule List** — Add, remove, reorder and name rules. Each rule is matched by its own match string; the first hit wins and rule 1 is the fallback.
|
|
96
|
+
- **Live Match Readout** — The top of the Model Background tab shows the current state, e.g. `Current model deepseek-flash → matched · Rule 1`, so you can verify a rule on the spot. If the current model can't be detected, a hint is shown instead.
|
|
97
|
+
- **Per-rule Appearance** — Every rule owns its wallpaper, theme color, layout mode, framing, opacity and blur. Nothing is shared globally except the Interface tab.
|
|
98
|
+
- **Import / Export** — Export every rule **including its wallpaper** to a `dsh-background-by-model-theme.json` (format version 3, images inlined as base64) and restore it anywhere.
|
|
99
|
+
- **File-based Persistence** — All settings and images are stored on the filesystem under `~/.dsh/.dsh-background-by-model-data/`, not `localStorage`.
|
|
100
|
+
- **Automatic Migration** — Old single-wallpaper configs are upgraded in place on first read. See [Upgrading from 0.2.x](#upgrading-from-02x).
|
|
101
|
+
- **Bilingual** — Full Chinese / English UI with automatic locale detection.
|
|
102
|
+
- **Theme Watchdog** — Re-asserts the custom theme if the host resets it.
|
|
103
|
+
|
|
104
|
+
### Per-rule settings
|
|
105
|
+
|
|
106
|
+
- **Wallpaper** — Upload any image as this rule's wallpaper; each rule keeps its own file.
|
|
107
|
+
- **Theme Color** — HSL wheel plus numeric input and an inspiration palette, with **Extract from this image** and an **eyedropper**. When a rule sets no theme color, the system theme is used. Generates the full CSS design-token set in real time.
|
|
108
|
+
- **Layout Mode** — Fit / Fill / Stretch / Tile / Center.
|
|
109
|
+
- **Framing** — Drag to pan and scroll to zoom inside a viewport-proportional editor; **only editable in Fit mode**, and the committed framing stays consistent across window resizes and cross-monitor moves.
|
|
110
|
+
- **Background Opacity** — `0–100%` for the rule's wallpaper layer.
|
|
111
|
+
- **Background Blur** — `0–60 px`, applied to the wallpaper layer.
|
|
112
|
+
|
|
113
|
+
### Global settings (Interface tab)
|
|
114
|
+
|
|
115
|
+
- **Per-part Interface Opacity** — Independent sliders for the main background, sidebar, cards & panels (including the dropdowns and menus around the dialog), the input & controls (composer box, Cordis panel), plus the settings panel and the conversation text box.
|
|
116
|
+
- **Per-part Interface Blur** — Frosted-glass `backdrop-filter` blur (`0–60 px`) for each interface part, including a real backdrop on the composer and Cordis panel via stable host selectors.
|
|
117
|
+
- **Conversation & Trajectory** — The message list is wrapped in a translucent card automatically, and the trajectory page gets whole-page opacity & blur controls, letting the wallpaper shine through the content.
|
|
118
|
+
|
|
119
|
+
## Settings
|
|
120
|
+
|
|
121
|
+
Settings → **Theme** now has three tabs:
|
|
122
|
+
|
|
123
|
+
| Tab | Scope | Contents |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| **Interface** | Global, shared by every model | Opacity & blur for the main background, sidebar, cards & panels, input & controls, settings panel, conversation text box and trajectory page |
|
|
126
|
+
| **Model Background** | Per rule | The ordered rule list, the live match readout, and each rule's wallpaper, theme color, layout mode, framing, opacity and blur |
|
|
127
|
+
| **Config** | — | Import / export the whole rule set (`dsh-background-by-model-theme.json`) |
|
|
128
|
+
|
|
129
|
+
The old **Color** tab is gone — the theme color is now a property of each rule. The old **Background** tab became **Model Background**.
|
|
130
|
+
|
|
131
|
+
## Storage & Migration
|
|
132
|
+
|
|
133
|
+
Data directory: `~/.dsh/.dsh-background-by-model-data/` (Windows: `C:\Users\<you>\.dsh\.dsh-background-by-model-data\`)
|
|
134
|
+
|
|
135
|
+
| File | Contents |
|
|
136
|
+
| --- | --- |
|
|
137
|
+
| `theme-config.json` | The rule list plus the global Interface settings |
|
|
138
|
+
| `modelbg-<slot>` | The image of each rule, stored as raw bytes without a file extension |
|
|
139
|
+
|
|
140
|
+
### Upgrading from 0.2.x
|
|
141
|
+
|
|
142
|
+
v0.3.0 **removed** three things:
|
|
143
|
+
|
|
144
|
+
- **Video wallpapers** — no longer supported.
|
|
145
|
+
- **Generated dynamic backgrounds** — mesh gradients, Shader and geometric patterns are gone.
|
|
146
|
+
- **The global theme color** — it moved into each rule.
|
|
147
|
+
|
|
148
|
+
Upgrading is otherwise automatic and non-destructive: on first read, a legacy config (one without a `rules` array) is migrated so that the old single `wallpaper.jpg` becomes **rule 1** with an **empty match string** (a pure fallback), inheriting the old theme color, layout mode, opacity, blur and framing. Leftover video files from the old version are cleaned up as well. Existing users keep the appearance they had — you only need to add more rules if you want a different background per model.
|
|
149
|
+
|
|
150
|
+
## Installation
|
|
151
|
+
|
|
152
|
+
### Method 1: npm install (Recommended)
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
dsh plugin --profile web add dsh-background-by-model
|
|
156
|
+
# or install straight from the repository:
|
|
157
|
+
dsh plugin --profile web add github:HarmlessFunny/dsh-background-by-model
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Then restart `dsh web`.
|
|
161
|
+
|
|
162
|
+
The plugin appears as a **"Theme"** section in Settings.
|
|
163
|
+
|
|
164
|
+
### Method 2: npx (No Global Install)
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
npx @deepseek-ai/dsh plugin --profile web add github:HarmlessFunny/dsh-background-by-model
|
|
168
|
+
npx @deepseek-ai/dsh web
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Method 3: Local Build (Development)
|
|
172
|
+
|
|
173
|
+
The `lib/` directory is committed, so installs need no build step. To rebuild after editing `src/`:
|
|
174
|
+
|
|
175
|
+
```sh
|
|
176
|
+
git clone https://github.com/HarmlessFunny/dsh-background-by-model.git
|
|
177
|
+
cd dsh-background-by-model
|
|
178
|
+
pnpm install
|
|
179
|
+
pnpm run bundle # output goes to lib/
|
|
180
|
+
pnpm run typecheck
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
To mount a working copy into a profile instead, add it to the profile's `package.json` and register the bundle:
|
|
184
|
+
|
|
185
|
+
```jsonc
|
|
186
|
+
{
|
|
187
|
+
"dependencies": {
|
|
188
|
+
"dsh-background-by-model": "link:E:/DeepSeek/dsh-background-by-model"
|
|
189
|
+
},
|
|
190
|
+
"dsh": {
|
|
191
|
+
"profile": {
|
|
192
|
+
"bundles": ["dsh-background-by-model"]
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
After changing anything under `src/`, run `pnpm run bundle` again — the mounted profile loads `lib/`, so edits do not take effect until the bundle is rebuilt.
|
|
199
|
+
|
|
200
|
+
## Compatibility
|
|
201
|
+
|
|
202
|
+
- **[`dsh web`](https://github.com/deepseek-ai/deepseek-harness)** — Full support on both the npm release and the new source build. The plugin auto-detects which client-module table the host ships (the new `@deepseek-ai/dsh-client-store` or the legacy `@deepseek-ai/dsh-client-runtime`) and resolves `defineStore` accordingly at runtime.
|
|
203
|
+
- **[deepseek-harness-desktop](https://github.com/anywhere-labs/deepseek-harness-desktop)** — Supported
|
|
204
|
+
|
|
205
|
+
## FAQ
|
|
206
|
+
|
|
207
|
+
**Every model looks the same — why?**
|
|
208
|
+
Your first rule probably has an empty match string, which makes it a pure fallback holding the whole list. Give rule 1 a match string (or add more specific rules *above* the fallback).
|
|
209
|
+
|
|
210
|
+
**`GLM-Flash` picked the wrong rule.**
|
|
211
|
+
Matching is first-hit, not best-hit. Put the more specific rule higher in the list, or reorder so the rule you want comes first.
|
|
212
|
+
|
|
213
|
+
**Where are my wallpapers?**
|
|
214
|
+
In `~/.dsh/.dsh-background-by-model-data/`, one `modelbg-<slot>` file per rule plus `theme-config.json`.
|
|
215
|
+
|
|
216
|
+
**Can I share a setup?**
|
|
217
|
+
Yes — export it from the **Config** tab; the JSON inlines every rule's image.
|
|
218
|
+
|
|
219
|
+
**Are video or generated backgrounds supported?**
|
|
220
|
+
No. Both were removed in 0.3.0; each rule uses a static image.
|
|
221
|
+
|
|
222
|
+
## Recent Optimizations
|
|
223
|
+
|
|
224
|
+
### v0.3.0
|
|
225
|
+
|
|
226
|
+
- **Model rules replaced the single global wallpaper** — The background is now driven by an ordered list of rules, each selected by a match string against the current session's model name (first match wins, rule 1 falls back). The match string is compared against the provider, model id and display name together.
|
|
227
|
+
- **Appearance moved from global to per rule** — Wallpaper, theme color, layout mode, framing, background opacity and background blur are now properties of each rule, so different models can look completely different.
|
|
228
|
+
- **New tab layout** — Settings now has **Interface** (global), **Model Background** (the rule list) and **Config** (import/export). The **Color** tab was removed with the global theme color, and the old **Background** tab became **Model Background**.
|
|
229
|
+
- **Live match readout** — The Model Background tab reports the current model and the rule it resolved to (for example `Current model deepseek-flash → matched · Rule 1`), or a hint when the model can't be detected.
|
|
230
|
+
- **Export format v3** — `dsh-background-by-model-theme.json` now carries the full rule set and every rule's image (base64 inlined).
|
|
231
|
+
- **Breaking removals** — Video wallpapers, generated dynamic backgrounds (mesh gradient / Shader / geometric patterns) and the global theme color are gone.
|
|
232
|
+
- **Automatic legacy migration** — A pre-0.3.0 config becomes rule 1 with an empty match string, inheriting the old appearance, and stale video files are cleaned up.
|
|
233
|
+
- **Smoother switching, with a cross-fade** — Wallpapers are painted from an object URL, so one image is decoded once instead of being re-decoded on every switch, and a rule change now cross-fades (320 ms: the new image fades in over the old one, which stays fully opaque so the backdrop never brightens mid-transition). The drag-time low-resolution wallpaper swap was removed: it re-decoded and re-scaled the whole photo on every change, and its low-res frame was overwritten by the next repaint anyway.
|
|
234
|
+
- **Fixed: switching the model did nothing** — three things stacked up: (1) the old code read `ctx.modelDirectories`, which is not visible from a plugin context (it is registered in ui-model-selection's own scope), so it silently fell back to the host-wide default model; (2) this plugin's client bundle loads **before** `api-session-controller`, so `ctx.get('sessions')` is normally still undefined during `apply()` — and the old code gave up at that point and never retried, which is why nothing happened at all; (3) the readout passed a global default off as this session's model. It now reads **this session's own durable model selection** (`ctx.sessions.binding(id).session.projections.faceOf('modelSelection')` — the same value the model picker renders), waits for the `sessions` service at 400 ms intervals (up to 2 minutes), keeps a 1.5 s safety poll and rebinds on session switches; it labels the value **host default** when only the host-wide default was available, and the readout names the failing hop (not mounted / no current session / no projection / projection empty).
|
|
235
|
+
|
|
236
|
+
### v0.2.4
|
|
237
|
+
|
|
238
|
+
- **dsh 0.1.5 persistence fixed** — The theme/wallpaper RPC channel is now registered directly in the plugin's own `webServer` scope as a prefix route (keeping the same Host/Origin auth fence), instead of through `connection.rpc.handle`, whose effect binds to the connection service's context and never mounted on some 0.1.5 hosts — requests that previously dropped to the SPA fallback with 405 and never reached the disk now persist again. Verified working on both 0.1.2 and 0.1.5.
|
|
239
|
+
- **Host compatibility declared** — Added `engines.dsh: ">=0.1.2-rc.1"` to declare which DeepSeek Harness host versions the plugin supports.
|
|
240
|
+
- **Dark badge tokens fixed (issue #9)** — In the dark preset, the `*-tertiary` badge surfaces (trajectory tool/context badges, connection pill, plan chip) were tinted nearly the same as their background, making light label text unreadable. They now use the native dark 800/900 steps, so bright text sits on a properly dark badge.
|
|
241
|
+
|
|
242
|
+
## Star History
|
|
243
|
+
|
|
244
|
+
[](https://www.star-history.com/?repos=HarmlessFunny%2Fdsh-background-by-model&type=timeline&legend=bottom-right)
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
MIT
|