deepseek-harness
starsstreaming/beautiCode为 DSH Web 与 Desktop 设置本地图片与 MP4 视频背景(也支持 Codex、Cursor、豆包、WorkBuddy):侧栏「背景」面板、可保存命名主题、声音开关、恢复上次背景、只留背景的摸鱼模式,以及 /bg、/bg-theme、/bg-clear 命令。
按模型切换 DSH Web 界面外观:有序规则列表按当前会话的模型名匹配,每条规则自带壁纸、主题色、布局模式、取景与背景透明度、模糊;另有主背景、左侧栏、右侧栏、卡片面板、输入框与控件、设置面板、对话文本框、轨迹页的分区透明度与毛玻璃模糊。
English | 中文
Forked fromTkingxiao/dsh-any-backgroundand renamed todsh-background-by-model.
A DeepSeek Harness appearance plugin built around an ordered list of model rules: each rule carries its own images, opacity, brightness and blur, and each image its own layout mode, framing and theme color. Switch the model and the background switches with it, through the global switch effect you choose on the Config page.
v0.3.0 was a breaking release — video wallpapers, generated backgrounds and the single global theme color were removed. See the v0.3.0 entry in CHANGELOG.md.
A rule is a match string plus one complete set of background settings. On a model switch 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 it (case-insensitive) — with rule 1 as the fallback when nothing matches.
Example list:
# · Match string · Wallpaper 1 · deepseek · Image A 2 · flash · Image B 3 · glm · Image C
Current model · Result · Why DeepSeek-Flash · Rule 1 → Image A · deepseek matches first GLM-Flash · Rule 2 → Image B · flash is earlier in the list than glm Qwen-Flash · Rule 2 → Image B · flash matches GLM-Turbo · Rule 3 → Image C · only glm matches Kimi-K3 · Fallback → Rule 1 → Image A · no rule matches
modelSelection projection the composer's own picker renders), so switching models inside a session takes effect immediately; the page shows what was read, and marks it host default when only the host-wide default was available.The example above has no `kimi` entry, so Kimi falls back to rule 1 = Image A and looks like "nothing happened" — add a rule with the match string kimi.One interface, one config — only the current model differs:
DeepSeek V4.1 Flash · matched the rule containing deepseek: a light wallpaper with a matching theme color
Kimi K2.7 Code · matched the rule containing kimi: a dark wallpaper, and the whole interface reskinned with it
One rule on the Model Background tab · the wallpaper, its opacity, its brightness and its blur belong to the rule; the layout mode, the framing and the theme color belong to the image being edited
Example wallpaper art from ZipZipPipe on bilibili
An ordered list of rules, matched first-hit against the current model's name, with rule 1 as the fallback.
dsh-background-by-model-theme.json with every image inlined; files written by earlier releases still import.~/.dsh/.dsh-background-by-model-data/, and old single-wallpaper configs migrate in place on first read.Per rule, and off by default — cycling spends real bandwidth, memory and battery, so nothing turns it on for you.
What a wallpaper change looks like — one setting on the Config page, shared by every rule, covering a model switch, a rotation step, Next image and a holiday taking over.
transform on the incoming layer, so neither costs a byte of extra transfer.0–3000 ms where 0 is a hard cut rather than "unset". It replaced the per-rule rotate.fadeMs, which had no control anywhere; a hand-tuned value is folded into it on first read.One switch on the Config page and nothing else: on 中秋节 and 国庆节 the wallpaper switches to that holiday's own art and theme color, and back the next morning. It ships off, and the recommended profile turns it on.
holiday-cache// on the first read of the day. The download is gated on the calendar, so an ordinary day fetches nothing at all and every later boot is answered from disk.0–100%, image brightness 0–200% (100% is the picture as saved) and image blur 0–60 px, all three per rule and edited through one slider with a menu beside it that picks the effect. They treat the image (wallpaper) layer only — the Interface tab's opacity treats interface surfaces.One click on the Config tab downloads the author's own configuration — rules, wallpapers and interface settings — from the project's assets repository.
preset/preset.json, preset/theme-config.json, one modelbg- file per wallpaper), so it stays editable on GitHub and publishing it is a cp.Settings → Theme now has three tabs:
Tab · Scope · Contents Interface · Global, shared by every model · Opacity for the main background, left panel, right panel, cards & panels, input & controls, settings panel, conversation text box, trajectory page and every plugin page Model Background · Per rule, per image · The ordered rule list, the live match readout, and each rule's images (filmstrip), per-image layout mode, framing and theme color, plus the rule's opacity, brightness, blur and rotation Config · — · The global switch effect, the whole rule set as a file — recommended profile, import and export (dsh-background-by-model-theme.json) — plus the single holiday background switch
The old Color tab is gone — the theme color is now a property of each rule — and the old Background tab became Model Background.
Data directory: ~/.dsh/.dsh-background-by-model-data/ (Windows: C:\Users\.dsh.dsh-background-by-model-data)
File · Contents theme-config.json · The rule list (each rule with its image list and rotation) plus the global Interface settings, the global switch effect and the holiday overrides modelbg- · One image, stored as raw bytes without a file extension — one file per image, so a rule with three images owns three slots holiday-cache// · Festival art downloaded from the CDN, one file per holiday (mid-autumn.webp, national-day.webp) inside a directory named after the assets release this build pins (v0.1.0). The tag is part of the path so that a build pinning a new tag starts from an empty directory instead of being answered with the previous generation's bytes; the file inside is named after the asset, deliberately outside the slot namespace, which is what keeps a holiday slot read-only. Superseded generations are pruned once the new art is on disk. Delete a file here and it is simply re-downloaded the next time that holiday is in force
dsh plugin --profile web add dsh-background-by-modelThis is the only source — a github: install would clone a tree with no lib/ in it, and nothing there would build one.
Then restart dsh web.
The plugin appears as a "Theme" section in Settings.
npx @deepseek-ai/dsh plugin --profile web add dsh-background-by-model
npx @deepseek-ai/dsh weblib/ is not in the repository — it is built from src/, by the package's prepack hook when the tarball is packed, and by you for a working copy. Clone, install, then build:
git clone https://github.com/HarmlessFunny/dsh-background-by-model.git
cd dsh-background-by-model
pnpm install
pnpm test # builds lib/, typechecks, runs the ten checkspnpm run bundle rebuilds lib/ on its own. Either has to run before the plugin can load: a fresh clone has no lib/.
To mount a working copy into a profile instead, add it to the profile's package.json and register the bundle:
{
"dependencies": {
"dsh-background-by-model": "link:E:/DeepSeek/dsh-background-by-model"
},
"dsh": {
"profile": {
"bundles": ["dsh-background-by-model"]
}
}
}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.
pnpm test builds, typechecks and runs ten checks, none of which needs a dependency, a transformer or a browser. Each can also be run on its own with pnpm check:holiday / pnpm check:rotation / pnpm check:transition / pnpm check:repaint / pnpm check:code-plate / pnpm check:image-mode / pnpm check:rules / pnpm check:preset / pnpm check:ui / pnpm check:node:
pickHoliday applies.nextIndex / isRotating: no walking off the end, shuffle never repeating the image on screen, and nothing called "rotating" with nothing to rotate.resolveFadeMs / transitionPlan: the shipped default still producing byte-for-byte the transition string earlier releases wrote, every route to a hard cut being one, reduced motion vetoing rather than shortening, and every effect ending visible and unscaled.shouldRepaint, including the edit that creates the winner, plus a failure if any write path stops asking, or if a rotation step stops re-emitting the interface palette.:root and body, the light branch emitting the banner, and each surface reading its own plugin variable.src/client/rules-view.ts, plus the page structure the layout rests on.dab-… class styled, no dead entry, and every var(--dsw-…) published by the installed theme.DSH_HOME redirected and fetch stubbed: the holiday block, the festival art's caching and pruning, mirror fallback, the per-image color lift, the global switch effect, and the recommended profile end to end.Every model looks the same — why? Rule 1 probably has an empty match string, which makes it a pure fallback holding the whole list. Give it a match string, or add more specific rules above it.
`GLM-Flash` picked the wrong rule. Matching is first-hit, not best-hit: put the more specific rule higher in the list, or reorder.
Where are my wallpapers? In ~/.dsh/.dsh-background-by-model-data/, one modelbg- file per image plus theme-config.json.
I turned the rotation on and the background never changed. Three things can hold it: the rule needs two or more images, the tab has to be visible, and only the rule the current model resolved to rotates.
Does rotating cost anything? Yes, which is why it is off by default: each image is stored at full fidelity and every switch repaints the whole interface. Two to five images is the sweet spot — boot only reads each rule's first image, so the cost is memory and disk rather than start-up time.
Why did the theme color stop working after I removed a rule's images? That was the old behaviour, and it is fixed: a rule now counts while it has an image, or a theme color of its own, so it still matches and still serves as the fallback while painting the interface alone.
I updated the plugin and the panel says my edits are not being saved. The browser half and the host half update separately, so a refreshed page can run the new client against DSH's process still running the previous node half, which cannot read the new config shape. The client holds its writes until you restart DSH.
I set a color for one image and the other images did not change. That is the design: since 0.7.1 a theme color belongs to the image, so a rotation can move through pictures with different accents. A rule with no image at all is the one case where the controls edit the rule's own color.
Where did the theme color I set before this update go? Nowhere: an image written before per-image colors has no color key at all, which is how the loader tells "never had one" from "cleared on purpose", and it lifts the rule's color onto every such image.
Can I share a setup? Yes — export it from the Config tab; the JSON inlines every rule's image.
Are video or generated backgrounds supported? No. Both were removed in 0.3.0; each rule uses a static image.
After switching a rule back to "System theme", why is the settings dialog a different palette? That was a bug and it is fixed: every surface is now driven by one palette source, so clearing the color reads the host's own tokens back and re-emits them with your alpha.
Why does "Custom color" produce a color the moment I press it? Pressing it means leaving the system-theme state, so it has to hand out a starting color — it runs the extract-from-image pass first and falls back to a default swatch only when the image has nothing vivid.
After switching back to "System theme" the interface stays light until I drag a slider — why? The other half of the same bug, also fixed: the plugin forces body[data-ds-dark-theme] while it owns a color, and the host only rewrites that flag when it projects a theme snapshot. The switch now hands the flag back synchronously, and a one-second watchdog re-reads the host palette.
I picked a new switch effect and the wallpaper still cuts instantly. The effect is Instant, or the duration is 0 — an effect and a duration are two ways of asking for the same hard cut, and the effect wins. Outside the plugin, a system reduced motion setting means nothing animates at all.
Only the two most recent releases are listed here; older ones live in CHANGELOG.md.