Themes & Appearance

dsh-gif-background

alcohol-101/dsh-gif-background · ★ 1

alcohol-101

Custom background (image / GIF / animated wallpaper) plugin for the DeepSeek Harness (DSH) Web GUI - enable switch plus a local asset library, with separate display mechanisms for the official theme and skin-center skins.

License
Apache-2.0
Added
2026-10-30
Maintenance
active
Install kind
npm
npm
dsh-gif-background
Manifest details
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-10-30T09:38:28.219Z
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add 'dsh-gif-background@0.1.1'

从 npm 安装预构建包

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. Features
  2. Install
  3. From npm (recommended)
  4. From this repository (development)
  5. Usage
  6. How it works
  7. Repository layout
  8. Development
  9. Making your own GIF wallpaper
  10. Troubleshooting
  11. License

CI

English | 中文

A standalone plugin that adds a custom background (image / GIF / animated wallpaper) to the DeepSeek Harness (DSH) Web GUI: one enable switch plus a local asset library, with two display mechanisms that cooperate with the official theme and the dsh-web-ui skin center.

Features

  • Enable / disable switch (persisted in localStorage, enabled by default).
  • Asset library: add (upload gif / jpg / jpeg / png / webp, 100 MB limit), delete, rename, refresh. Deleting the asset currently in use falls back to the built-in background.
  • Official theme (no skin): the background is painted onto the layout frame's own background-image and a translucent token override sheet lets the panels show it through. The built-in art is served through a short API URL, because multi-MB base64 data URLs inside CSS declarations are silently dropped by the browser parser.
  • Skin mode: coexists with the skins from the dsh-web-ui skin center; the backdrop layer sits behind the skin's own surfaces and the skin's palette is left untouched.
  • The asset API is loopback-only and never exposed beyond the local machine.

Install

Prerequisites: DSH 0.1.x. Restart dsh web after installing, then hard-refresh the browser (Ctrl+F5).

dsh plugin --profile web add dsh-gif-background

From this repository (development)

git clone https://github.com/alcohol-101/dsh-gif-background.git
dsh plugin --profile web add "link:<path-to-the-cloned-repo>"

Usage

Settings → Plugins → the Custom Background card:

  • tick the enable switch to show / hide the background;
  • Add uploads a local image or GIF and selects it;
  • click a list row to switch; rename edits inline (Enter confirms, Esc cancels); x deletes;
  • Refresh rescans the asset directory — you can also drop files into gifs/ and hit refresh.

How it works

Two mechanisms, switched automatically by page state:

  1. Official default theme (no skin-center skin active): the current background is painted onto the AppFrame element itself, and an rgba override sheet for the surface tokens (--dsw-alias-bg-base, -bg-layer-1/2/3, -bg-module-platform, --dsw-specific-sidebar-fill; light and dark pairs) is injected so the panels become translucent.
  2. Skin mode: only the fixed full-viewport layer at z-index:-1 plus a scrim layer remain; the skin's own translucent #root surface lets the backdrop through naturally.

Note: the dsh-web-ui skin center keeps a data-dsh-skin-center scope attribute on <body> even when no skin is active. Older versions mistook that for an active skin and never painted the official theme; the current version whitelists it and only treats the skins' own body attributes as skins.

Repository layout

dsh-gif-background/
├── client/
│   ├── client.template.js   # browser-half source (__GIF_BASE64__ placeholder)
│   └── build.mjs            # builds lib/client.js, embedding gifs/builtin.gif
├── lib/
│   ├── index.js             # host half: loopback-only asset API
│   └── client.js            # browser bundle (committed so link installs need no build)
├── gifs/
│   └── builtin.gif          # built-in background (uploads stay local, gitignored)
├── docs/
│   ├── 维护指南.md            # code walkthrough for maintainers (Chinese)
│   └── CHANGELOG.md           # version history
├── .github/workflows/ci.yml # CI: rebuild check + legacy identifier guard
├── cordis.patch.yml         # dsh bundle patch: declares the plugin row
├── CONTRIBUTING.md          # contribution guide
└── package.json             # dsh.client injects + exports

Development

  • Browser half: edit client/client.template.js, then node client/build.mjs to rebuild lib/client.js.
  • Host half: edit lib/index.js.
  • Host changes require restarting dsh web; browser-only changes only need Ctrl+F5.
  • CI runs on every push and fails if the committed lib/client.js is stale or legacy identifiers reappear; failures notify you by email.
  • New to the codebase? Start with docs/维护指南.md (a commented walkthrough in Chinese) and CONTRIBUTING.md.

Pitfalls worth recording:

  • Multi-MB base64 inside a CSS background-image value is silently dropped by the parser → the built-in background goes through a short API URL instead.
  • MutationObserver fires for setAttribute even when the value is unchanged (whatwg/dom#520) → every attribute write is guarded against the same value; an unguarded write retriggers the observer forever and freezes the page.
  • The webserver prefix route matches pathname.startsWith(prefix + '/'), so the prefix must not carry a trailing slash; register one exact route per path and dispatch by HTTP method.
  • See the skin-detection note in "How it works".

Making your own GIF wallpaper

A short ffmpeg recipe (scale + dither palette, infinite loop):

ffmpeg -y -i input.mp4 -t 33 \
  -vf "fps=8,scale=840:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=160:stats_mode=diff[p];[s1][p]paletteuse=dither=floyd_steinberg:diff_mode=rectangle" \
  -loop 0 builtin.gif

For a seamless loop, cut the segment and crossfade it onto itself (xfade) before palettizing.

Troubleshooting

The switch is on but no background shows under the official theme?

Hard-refresh (Ctrl+F5), then check in the DevTools console:

  1. document.body.attributes should contain data-dsh-gif-bg="on" and NOT data-dsh-gif-bg-skin;
  2. document.querySelector('[data-dsh-frame]').style.backgroundImage should contain the asset URL;
  3. getComputedStyle(document.body).getPropertyValue('--dsw-alias-bg-base') should be an rgba value.

If step 1 fails, a skin-center skin is active — in skin mode the background shows behind the skin's panels.

Want a different panel translucency under the official theme?

Edit the rgba values in SKINLESS_CSS in client/client.template.js (both light and dark pairs), rebuild, then Ctrl+F5.

License

Apache-2.0