DeepSeek Harness appearance toolkit. Independently tune opacity + frosted-glass blur across 8 surfaces (main background, sidebar, cards & panels, inputs & controls, settings, conversation frame, trajectory view, produced/highlights — 9 with dsh-better-sidebar). Use any image or video as wallpaper with a drag-to-pan, scroll-to-zoom position editor and 5 layout modes (Fit/Fill/Stretch/Tile/Center); videos loop muted, survive refresh, and capture a live frame for preview, color extraction and framing. Rotate a pool of images (shuffle/order, every refresh/daily/weekly). Also: PS-style color wheel, one-click wallpaper color extraction, 6 presets + saved profiles, day/night auto switch, and full theme export/import.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-any-background
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:Tkingxiao/dsh-any-background
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
English | 中文
A DeepSeek Harness appearance plugin: custom theme color, background wallpaper (image / video / algorithmically generated), and per-surface opacity & blur control. Compatible with DSH 0.2.0-rc.1 through 0.2.2-rc.1 — and every host release above it.
Screenshots
Features
Color & theme
- PS-style color wheel — Hue on the ring, saturation and lightness in the inscribed square; generates 30+ CSS design tokens live.
- Precise HSL / RGB input — Numeric entry, bidirectionally synced with the wheel.
- Smart extraction / eyedropper — One click derives a theme color from the wallpaper (sampling the visible area and discarding gray, near-black and near-white), or hover any pixel to pick it. Video wallpapers contribute an auto-captured frame. All client-side.
- Forced light / dark scheme — Light, dark or auto. In auto the surface and font direction follow the accent color's lightness (dark pick → light text), falling back to the wallpaper's brightness when no accent is set.
- Theme export / import — A self-contained
dsh-any-theme.json(config + wallpaper + the whole rotation pool) that restores anywhere. - Presets & profiles — Six one-click presets plus named profiles that can be renamed and duplicated; deleting asks for confirmation twice.
Background & wallpaper
- Image wallpaper — Upload any image as the background.
- Video wallpaper — Muted, looping, survives refreshes (persisted on disk + HTTP Range streaming), with one frame captured for the preview, color extraction and position editing.
- Position editor & layout modes — Drag to pan, scroll or pinch to zoom, one-click reset; Fit / Fill / Stretch / Tile / Center. Image and video placements are stored separately and never overwrite each other.
- Generated backgrounds — Mesh gradient, Shader or geometric patterns, with adjustable spread and intensity and a lockable seed.
- Wallpaper rotation — Build a pool with the thumbnail picker and rotate by shuffle or order, on every refresh / hourly / daily / weekly; the cadence advances while the page stays open, not only on reload.
- Day / night switch — A day profile and a night profile, switched on a fixed schedule or by following the OS dark mode.
Per-surface opacity & blur
- Eleven parts, each with its own slider pair — main background, sidebar, card panels, input & controls, settings panel, conversation frame, trajectory view, right sidebar (or bettersidebar), produced / highlighted content, header popovers, and the header bar.
- The slider IS the frost amount, and 0 means no frost — including over the host's own default menu frost. Every part still defaults to 30px, so a stock install keeps the frosted look.
- Opacity re-scopes the host's own token — it never stacks a second color over the original, so the wallpaper shows through the content.
- Produced / highlighted content shares one slider — code blocks (with their language banner), inline
codechips and produced chips move together. - Right sidebar / bettersidebar: one pair, two identities — without dsh-better-sidebar it drives the official right sidebar; with it installed the same pair takes over that plugin's bottom workbench panel (the official sidebar keeps responding too).
- On the Windows desktop shell it also drives the caption band — the sidebar pair paints the segment directly above the sidebar, and the cut follows the sidebar's width as it is dragged or collapsed (at width 0 the band returns to the header card). The 「标题栏」 card drives the rest of the band and the native window controls, with a four-state 「标题条带文字」 choice (auto / follow theme / always white / always black) for when a light strip fights the theme.
Interface parts
- Sidebar "Theme" page (dual mode) — The same five pages (Color / Interface / Font / Background / Profiles) register into the official right sidebar's guide page or into dsh-better-sidebar's sidebar, sharing one state with the settings panel, so a change anywhere shows everywhere. On a host without that extension point nothing is registered, silently.
- Conversation view cards — The message list is wrapped in a translucent card automatically, and the trajectory page adjusts as a whole page.
- Header popovers and the header bar are separately adjustable — the Agent Team panel, the background-job list, the session-header dropdowns, and the title / view-tab row at the top of a session each have their own opacity + blur pair.
- Custom font — Upload a ttf / otf / woff / woff2 (up to 100 MB) and apply it across the interface; code blocks stay monospace. Can be disabled or removed at any time.
- Per-part text outline — The same surface groups as the interface page, each with its own
-webkit-text-stroke(0–4px, 0 = off) in auto-contrast / gray / black / white / accent / custom. Code blocks, inlinecode, icons and the host's gradient-shimmer text are exempt automatically. - Third-party compatibility — When dsh-better-display is detected, its sticky summary band is pinned at a 20% plate + 30px frost outside the sliders. Any other plugin whose surface reads a token this plugin owns is named in the console, and the whole accommodation can be switched off in Settings.
General
- File-based persistence — Everything is stored under
~/.dsh/.dsh-any-background-data/, not inlocalStorage. - Bilingual UI — Full Chinese / English interface following the host's locale.
- Theme watchdog — Re-asserts the custom theme if the host resets it.
Changelog (latest two releases)
v0.4.3 (follows dsh 0.2.1-rc.5 and the newly opened 0.2.2 line)
- Newly checked host builds:
0.2.1-rc.4,0.2.1-rc.5,0.2.2-alpha.2. rc.4/rc.5change nothing. Every shipped file of the 296@deepseek-ai/dsh-*packages in a0.2.1-rc.3install was hashed throughrc.5: 30 files moved in total, and not one of them is a stylesheet this plugin reads. Three are inlined version-string literals; the rest are the host's settings-tab tooltip becoming conditional and the reasoning-body slot gaining arawText. No token, no[class*="…"]class shape, noz-indexand nodata-slotkey moved, so both builds join thev0-2-1row and their verdict rises fromlinetoexact.0.2.2is a new patch line, sov0-2-2opens its own facts folder. That release is big (1151 files changed, 1709 added), but every fact this plugin claims was re-read and still holds:_handle{z-index:11}/_leadingSeat{z-index:15}/_overlayLayer{z-index:20}are byte-identical (so the sidebar column's ceiling of 1 and the header row's 10 are argued exactly as before), the four menu-frost tokens and the 8--dsw-menu-backdrop-filterconsumers are unchanged, the host still composes--dsw-font-familyonbody(the font rule's!importantstill has to win), the five session-header slot keys stand, and all 75 host selectors this plugin writes still match. The host's peer gate is byte-identical too.- Two host changes on
0.2.2worth recording:--dsw-specific-sidebar-nav-item-hoveris deleted host-side, together with its only consumer — the plugin still writes the token, which now writes something nobody reads, and since the host stopped painting that hover at all there is no regression against the host default; andui-plugin-managergained a new consumer of the token the main-interface slider takes over (apointer-events:noneunderlay behind the page header), which paints nothing at the default value but is a new row on the "who reads this token" list. - The version gate now has its own check:
npm testverifies thatengines.dsh, the six peer ranges anddsh.compatibility.dsheach name every verified build and all keep their uncapped tail, and thatlib/really carries those builds and their channels — so editingsrc/without re-bundling is now caught outright. - After installing or updating, restart the host once — the compatibility gate runs when the profile is composed.
v0.4.4 (real-host check on 0.2.2-rc.1 · issue #34 registry & reporting · issue #33 numeric input & region highlight)
- Checked
0.2.2-rc.1on a real host. An isolated test profile under launcherhomes/0.2.2-rc.1(local plugin via link, plus dshmarket1.73.16/ dsh-better-sidebar0.30.1/ dsh-update-checker1.7.3) bootsdsh web: the gate admits the plugin,readanswershost.version=0.2.2-rc.1 / channel=0.2.2, and the config round-trip lands on disk. A separate headless Chrome boot reports 179style[data-plugin]sheets and all three "unregistered" log lines from issue #34, verbatim. The build now joins all four gate ranges anddshReleases; its verdict rises fromlinetoexact. - Adapter facts re-read: three evidence literals moved, none is a rule input. Across the tag's 98
lib/client.jsartifacts,_handle{z-index:11}/_leadingSeat{z-index:15}/_overlayLayer{z-index:20}, the menu token names, 9--dsw-menu-backdrop-filterconsumers,data-shimmer/data-shell-bottom/data-rightbar-coland the session-header slot keys all still resolve. What moved:--dsw-menu-surface-fill(#f8f9fa94/#43454a73→#fcfdfeb3/#303136a3),--dsw-font-family(now a singlevar(--dsh-font-family-text-default), still abodydeclaration so the font rule's!importantstill wins), and--dsh-dockkit-float-topis no longer emitted (this folder emits no promotion, so it is unaffected). The adapter only asks for token NAMES, so its answer stands; details live inv0-2-2/adapter.ts. Pixel-level A/B for blur / occlusion is still open. - Issue #34: three plugins now have a verdict instead of "unregistered". Two low-risk pins were added — dshmarket's task popover (
--dsw-alias-bg-layer-1) and dsh-update-checker's two buttons (--dsw-alias-bg-layer-2) — re-declaring only the token literal, neverbackground, geometry or frost; all four selector names are 0-hit in that host's artifacts.dsh-better-sidebaris registered as reviewed, deliberately not pinned: its whole panel is exactly what the Main-interface slider is for, so pinning it would take the slider away from the user. Every pin still lives in the one-third-partydynamic sheet, so the switch removes all of it at once. - Reporting no longer needs the console. The settings card lists each plugin, its status and its tokens, with a "Copy report line" button carrying the host release and switch state. Production builds cannot open DevTools, so the button is the whole feedback path; where the clipboard is unavailable a selectable readonly field appears.
- Issue #33, items 1 and 2. ① Slider values are typeable: every slider gained a number field, kept in sync with dragging in both directions, clamping out-of-range values and leaving an empty mid-edit alone. The original zero-lag DOM path is untouched. ② Hover highlights the matching region: hovering a module card outlines the real region it controls. The three frame columns reuse the very nodes
setBlur/applyPartOpacitiespaint; the rest use onlydata-*markers and runtime tags from this plugin's own rules. No host node is written and no third-party z-index is touched — a singlefixed,pointer-events:noneoutline layer is removed on mouse-out and on leaving the settings page. Positions update from capture-phasescroll/resize, never rAF. The hint reuses the plugin's own scheme resolverrScheme()(forced override > theme-color lightness > wallpaper brightness verdict) and paints its inverse: a translucent WHITE plate on a dark interface, a translucent BLACK plate on a light one, with the tag inverted the same way. Strictly neutral black/white — not--dsw-alias-brand-primary(extracted from the wallpaper, so it collides after a theme-color change) and not a fixed accent (which collides with a wallpaper of that same color). The plate breathes slowly and continuously (2.4sease-in-out, fill opacity 22% ↔ 100% — not a one-shot flash); only the fill pseudo-element animates, so the two non-overlapping dashed rings (near-white border + near-black outline) and the tag stay steady.prefers-reduced-motionfalls back to a static plate, and nested targets collapse to the outermost box so alpha never stacks. Measured luminance delta: white-on-dark0.243/ black-on-light0.240, versus0.015/0if the direction is chosen wrongly; on an amber wallpaper the white / black plates still give0.067/0.178. When a region is absent on the current page the card says so rather than drawing a guessed box — the honest answer to "some surfaces only exist once a conversation is open". The other three requests (per-module annotations, a post-turn token-usage module, a model-picker submenu) need per-surface structural probing and are NOT in this release. - After installing or updating, restart the host once — the compatibility gate runs when the profile is composed.
Installation
Method 1: npm install (Recommended)
# published on the npm registry
dsh plugin --profile web add dsh-any-background
# or straight from the GitHub repository
dsh plugin --profile web add github:Tkingxiao/dsh-any-background
Then launch:
dsh web
The plugin appears as a "Theme" section in Settings.
Method 2: npx (No Global Install)
npx @deepseek-ai/dsh plugin --profile web add dsh-any-background
npx @deepseek-ai/dsh web
Method 3: Local Build (Development)
The lib/ directory is committed, so installs need no build step. To rebuild after editing src/:
git clone https://github.com/Tkingxiao/dsh-any-background.git
cd dsh-any-background
pnpm install
pnpm run bundle
pnpm dsh plugin --profile web add "dsh-any-background"
pnpm dsh web
Compatibility
dsh web:0.2.0-rc.1~0.2.2-rc.1, and everything above it. The gate names each build that was checked and then closes with an uncapped>=0.2.0-rc.1. That umbrella is deliberate: the host enforces exactly this peer list — a release it does not name is disabled before a single module is imported — so a range that runs out is a wall in front of a plugin that would have kept working. (More precisely: the host'sapp-bootunmetRequirementsreadsengines.dshalone when that field is present and ignores peerDependencies, so all four places must say the same thing butengines.dshis what actually decides whether the plugin loads.)How an unseen build runs: it gets the closest verified set of facts plus a log line saying how far from
exactthat is. The worst a stale fact can cost is one slider no longer fading a surface the host has since moved; a version check that failed closed would cost the whole plugin.Verified builds (
dsh.compatibility.dshReleases):Host build Facts folder Notes 0.2.0-rc.1v0-2-0-rc-1verified by diffing its tag, package by package 0.2.0-rc.2v0-2-0-rc-2same; this rc renamed the token a sticky menu group heading paints from, so it opened its own facts 0.2.1-alpha.1~0.2.1-rc.5v0-2-1facts unchanged, folded into one folder; every checked build gets its own row with an exactverdict.rc.4andrc.5ship artifacts byte-identical torc.3, file by file0.2.2-alpha.2v0-2-2a new patch line, so its own facts folder; every claim re-read and still true (z-index ladder, menu frost tokens, font token composition, header slot keys, 75 host selectors matching) 0.2.2-rc.1v0-2-2checked on a real host: gate / RPC / boot self-check all pass; every rule input still hits across 98 artifacts, three moved evidence literals recorded in the adapter; exactverdictabove 0.2.2-rc.1reuses the closest row an unverified build takes that line's adapter, stated in the log Facts are isolated per release: the host release is resolved on the Node half and handed down through the
readRPC; styling and logic only ask the adapter questions (who owns this surface, which layer carries the frost, which token fades a menu) and never compare version strings. Supporting a new host means adding one version folder and registering it.A restart is still needed after installing or updating the plugin: the compatibility check runs while the profile is composed, not when the plugin is updated. Features that depend on a specific host structure (the right sidebar's panel blur, the official sidebar's "Theme" card) enable themselves only where that structure exists; everything else behaves identically across the range.
The
0.1.5/0.1.6/0.1.7era is out of the supported range: those fact folders assert things nothing re-checks any more, and a table nobody verifies is worse than no table. An older host is now refused at composition rather than quietly restyled by the wrong adapter.DSHA — the DeepSeek Harness Android launcher (ROOT-free, Termux-free). Its bundled
dshis0.1.5-rc.2, below this plugin's supported floor: the peer gate refuses it at composition, so the plugin never loads there.deepseek-harness-desktop — supported. Windows-only behavior (the caption band, the native window controls) applies on the desktop shell only.
Permissions, side effects & boundaries
- Integration form: an official Profile Bundle —
package.jsondeclaresdsh.bundle.patch: ./cordis.patch.yml(a loader insert layer) and the repository ships ready-to-use prebuilt artifacts (lib/index.js,lib/client.js). No install scripts, no postinstall, no native binaries, no build step at install time. - Filesystem: the server half reads and writes only inside
<dsh home>/.dsh-any-background-data/(config, wallpaper, rotation pool, video, font) and touches nothing outside it; config writes are atomic (temp file + rename). These files live on the real disk, so they are outside generation restore — it neither captures nor rolls them back; deleting the directory is a full plugin reset. - Network: exactly one outbound fetch, and only when the user pastes an http/https image or video URL and presses Apply. No telemetry, no other external calls.
- Shell / native: none. No
child_process, no native modules, no dynamically downloaded binaries. - HTTP surface: only
/dsh-any-background/{video,wallpaper,font}(GET/HEAD streaming) with the matching*/uploadPOST routes (100 MB cap), plus the dedicated RPC channel/dsh-any-background, all under the local dsh web server. No extra listening ports. - Restart required: the first install needs a (re)start of
dsh webto load the client bundle; settings changes afterwards apply live and persist automatically. Changing plugin version requires a restart to pick up the newlib/client.js. - Tests & verification:
pnpm run typecheck(full tsc check),pnpm run bundle(tsdown emitslib/), andnpm test, which starts the real host half and round-trips config writes, reads and profiles plus the upload fence. Visual changes go through two further paths: a local mock page that measures computed values, and realdsh webtesting slider by slider. - Known limitations:
- The styling relies on stable host DOM markers (such as
[data-sidebar-right-panel]) and CSS token names. A host restyle of those layers can leave a slider ineffective for its surface — cosmetic only, nothing breaks. The version-specific half of those selectors lives inside its own version folder, so a host revision normally means editing that one file. -webkit-text-strokemay clip about 1px at the edge of some single-line ellipsis containers.- One rule is a deliberate cross-plugin accommodation: dsh-better-display paints its sticky reading lanes from the token our 「主界面」 opacity owns, so when that plugin is detected its lanes are pinned at a 20% plate + 30px frost outside the sliders. If it ever renames those markers the rule stops matching and its lanes go back to being painted its own way.
- The styling relies on stable host DOM markers (such as
Star History
License
MIT
Links
More in this category
elysia395/dsh-wallpaper-engine★ 6657
Requires DeepSeek Harness 0.1.5-rc.1+ (DSH Desktop >= 2.0.7) and dsh-better-sidebar >= 0.19.0 - update both before installing or updating this plugin. Plays local Wallpaper Engine Video/Web wallpapers behind the chat, renders Scene wallpapers as extracted static frames, and adds content-rating/type filters, custom uploads and an iOS-style liquid-glass settings window.
Small-tailqwq/dsh-deep-whale#maid-atelier★ 3098
Whale-girl skin series for the DSH Web UI (maid-atelier).
Nwflower/dsh-claude-style★ 585
Claude Code Desktop look-and-feel for the DSH Web GUI — ivory/warm-black dual canvas, clay accent, three-font typography, permission segmented control and brand switcher, via CSS overrides and client DOM overrides.
d-dev0101/open-sea-skin★ 391
Realtime WebGPU ocean skin with quick controls for waves, daylight, glass opacity, and an automatic day cycle.
kingOfSoySauce/dsh-liang-skin★ 387
Adaptive reasoning slider skin that maps each model's available reasoning efforts onto a 0–30 visual intensity scale, with synchronized portraits, background, and interface colors.
RevolutionLA/dsh-dream-skin★ 301
One-command skin plugin: 8 original themes, translucent wallpaper with opacity/blur, per-user accent, and shareable theme-pack import/export, favorites and surprise-me — purely native on DSH's token system.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.