Yugitan/dsh-skin ↗★ 1

dsh-skin

Customizable skinning tool for the DeepSeek Harness Web UI — presets, image wallpapers, translucency, and accent colors, all persisted in user settings 适合追求个性化视觉体验,想要自定义Web端背景和配色的用户。

Package
dsh-skin
Compatibility
Unverified
Harness peer range
^0.1.0-rc.6
Cordis peer range
^4.0.1
Version
0.1.0
License
MIT
Last updated
Aug 14, 2026

Other repositories with this package name

Install

This plugin has no verified bundle, or compatibility checks failed. Read the repository notes first. Read the full README ↗

dsh-skin — 自定义换肤工具(支持图片换肤)

📖 中文使用教程:使用教程.md · 📦 源码:github.com/Yugitan/dsh-skin · 🏷 dsh-plugin

A customizable skinning plugin for the DeepSeek Harness Web UI. It adds a 「换肤 / Skin」panel to 设置 → 通用 (Settings → General) that lets you:

  • Toggle the skin on/off with one switch.
  • Pick a built-in gradient preset (深海 Ocean / 极光 Aurora / 落日 Sunset / 薄荷 Mint / 樱花 Cherry).
  • Upload your own wallpaper image (PNG / JPG / WebP / GIF, ≤ 10 MB) — stored under ~/.dsh/skins/ and served from /skins/ (no base64 bloat in settings).
  • Paste any image URL (local /skins/... or external).
  • Tune fit (铺满/适应/拉伸/平铺), position, image opacity, background blur, a dim overlay for readability, and panel translucency (glass effect).
  • Override the brand accent color (swatches + color picker).
  • Reset everything back to the default appearance.

效果预览 / Preview

dsh-skin 效果预览

Everything is persisted in the DSH user-settings document (~/.dsh/settings.yaml → skin: section), survives restarts, and re-applies before the React app mounts (host-injected boot style, no flash).

How it works

  • Host half (lib/index.js, runs in the dsh web process)
    • registers the skin settings namespace + schema,
    • serves POST /skin/upload (magic-byte image sniffing, 10 MiB cap) and GET/HEAD /skins/ (immutable cache, path-traversal guarded),
    • taps the index HTML with a pre-plugin boot script/style that projects the durable skin onto --dsh-skin-* CSS custom properties and the body[data-ds-skin] attribute.
  • Browser half (lib/client.js, loaded by the client module system)
    • SkinRuntime mirrors the settings section into CSS custom properties, toggles data-ds-skin / data-ds-skin-accent on ``, and removes the host boot nodes once active,
    • registers the「换肤 / Skin」row into the settings.general.item slot (order 20, right below the built-in Appearance row).

The wallpaper is painted by a fixed full-viewport body::before layer (z-index: -1), the dim overlay by body::after, and the app surfaces are made translucent through --dsw-alias-bg-* token overrides (!important beats the ui-layout ThemePresenter's inline tokens), so the image shows through panels while text stays readable via the dim overlay.

Install into a running profile

One-command install / uninstall (recommended)

From the dsh-skin/ directory, run the bundled manager script. It does all three steps — module install, cordis.patch.yml entry, host allowlist patch — and is idempotent (safe to re-run):

node manage.mjs install        # one-click install (copy mode, moved-folder safe)
node manage.mjs install --link # dev mode: live symlink, browser HMR picks up client.js edits
node manage.mjs status         # verify (also checks the live server bundle)
node manage.mjs uninstall      # one-click uninstall
node manage.mjs uninstall --clean   # also delete ~/.dsh/skins/ + the skin: settings
node manage.mjs install --profile ~/.dsh/profiles/   # custom profile
node manage.mjs --help

Or via npm scripts in this package: npm run plugin:install / npm run plugin:uninstall / npm run plugin:status.

Restart the server afterwards and refresh the browser: dsh --profile web (or npm exec @deepseek-ai/dsh web).

Install modes. install copies a self-contained plugin into /node_modules/dsh-skin by default, so moving, renaming or deleting this source folder afterwards never breaks the installed skin; re-run install to refresh the copy with your edits. Use --link while developing so the profile links straight to this folder and the client HMR hot-reloads lib/client.js edits in the browser without re-installing. A dangling symlink left behind by a moved folder is repaired automatically on the next install (no --force needed).

Install from GitHub

git clone https://github.com/Yugitan/dsh-skin.git
cd dsh-skin
node manage.mjs install        # one-click install (links + registers + patches)
# restart the server, then refresh the browser:
#   cd ~ && npm exec @deepseek-ai/dsh web

On a new machine, recreate the node_modules symlink inside the clone (ln -s ~/.dsh/profiles/node_modules node_modules) or run npm install there so the harness resolves react / @deepseek-ai/*.

Manual install (advanced)

# from this repository root
PROFILE=~/.dsh/profiles/web
ln -s "$PWD/dsh-skin" "$PROFILE/node_modules/dsh-skin"

Append to $PROFILE/cordis.patch.yml:

- insert:
    - id: skin
      name: 'dsh-skin'

Then apply the one-line platform patch (required — see below), and restart the server: dsh --profile web (or npm exec @deepseek-ai/dsh web).

node patch-host.mjs        # adds the "skin" settings namespace to the API-gateway allowlist
node patch-host.mjs --check

Platform patch (required). DeepSeek Harness's API gateway (dsh-host-apiproxy) only lets configuration clients read/write a hard-coded allowlist of settings namespaces (WEB_SETTINGS_NAMESPACES). A third-party namespace — even one registered through settings.register() — is refused with settings-not-exposed, so the skin row would render but every toggle/preset write silently fails and nothing persists (nothing is written to settings.yaml). patch-host.mjs idempotently adds "skin" to that allowlist (with --check / --revert modes). Re-run it after any harness reinstall/update, then restart the server.

While developing, edit dsh-skin/lib/client.js — the client HMR watcher polls the bundle and hot-reloads it in the browser without a server restart (when installed with --link; in copy mode re-run install first).

Development

  • node manage.mjs install --link — dev install (live symlink → HMR).
  • node patch-host.mjs — reapply the one-line API-gateway allowlist patch (--check to verify, --revert to undo); needed after a harness reinstall.
  • node test-client.mjs / node test-runtime.mjs — execute the browser bundle in Node and render the Skin row with react-dom/server (smoke + runtime projection + row actions).
  • node test-host.mjs — mounts the upload/skins handlers on a throwaway node:http server and exercises upload, serving, traversal guard, and the index tap.
  • The node_modules symlink inside the package points at the profile module fallback so the harnesses resolve react / @deepseek-ai/* without an install.

Optional config

The plugin row accepts a config to relocate the image storage root:

- id: skin
  name: 'dsh-skin'
  config:
    root: /absolute/path/to/skins

Default: ~/.dsh/skins.