dsh-background-web
Self-contained whole-window background plugin for the DeepSeek Harness web
surface. It is a dual-face bundle: the node half registers a same-origin
upload/read/delete route plus the durable settings section, and the browser half
projects the stored image into the window and registers a General-settings
preference row. The image is picked with a browser-native file input — no
Electron dialog, so it works on any dsh web installation.
Install
dsh plugin --profile web add dsh-background-web
dsh web
Then open 设置 → 通用 → 背景 (General settings), choose an image, and adjust enable / visibility / dark overlay / blur.
Distribution (publishing this plugin)
Self-contained:
dependencies/peerDependenciesare empty — the@deepseek-aisurface lives in devDependencies for typechecking only, and the builtlib/artifacts are committed — so the package installs from a plain npm registry or directly from GitHub with no peer resolution:dsh plugin --profile web add github:gubai-future/dsh-background-web # or a registry/tarball specDiscovery: add the
dsh-plugintopic to the GitHub repository so it shows up on https://github.com/topics/dsh-plugin.Target requirements: a standard
dsh webcomposition — the official web-app bundle provides thesettings/webServerhost services and the runtime/ui-settings/locale/ui-slots browser rows this plugin builds on.Runtime data: each user keeps their image in
$DSH_HOME/background-web/(single slot, 20 MB, four raster formats).
Local development
This package is developed locally: the source lives in this workspace and the built artifact is exercised inside the DeepSeek Harness checkout's plugin system (the monorepo composition). The published package is self-contained, so end users install without registry peer resolution — the checkout loop here is for developing the feature itself.
Build here, test there: from the harness checkout (
E:\project\works\dsh\deepseek-harness) run the web surface on a changed port (3090;3080is the primary instance):pnpm run dsh -- web --port 3090 --no-openThe official
@deepseek-ai/dsh-client-ui-backgroundpackage covers the same feature with a different design: it stores the image as a data URL inside its settings namespace and owns a full Settings section; this plugin keeps the image in a host-side single-slot file, serves it through a same-origin route, and registers an inline row under General settings. Namespaces, route paths, and slot ids differ, so both can be composed without hard conflicts — expect two background entries in that case.
How it works
- Node half (
src/index.ts): registers thebackground-websettings section and the/dsh-background-web/backgroundroute (PUTupload,GETserve,DELETEclear). Image bytes live in a single-slot directory under$DSH_HOME/background-web/current.<ext>; the format is probed from magic bytes (png / jpeg / gif / webp). - Browser half (
src/client/index.ts): binds thebackground-websettings scope, drives a self-contained projector (a<style>element + body attributes — no dependency onui-theme's stylesheet), and registers thesettings.general.itemrow. While the background is visible (data-dsh-bg-web-visible), the projector re-themes the stock surfaces: base fills go transparent, and markdown/tool-dropdown code surfaces become frosted glass (backdrop-filter+ translucentcolor-mixfills). The re-theme targets the app's official surface hooks —data-*attributes on cards/blocks, the stablemd-code-blockclass, and thedata-io-cardattribute on the tool row IN/OUT card — never hashed CSS Module classes; switching the background off retracts it all.
Build (author only)
Users install the built artifact; the package must ship lib/index.js,
lib/client.js, and lib/types/**.
Local builds resolve the @deepseek-ai/* peers through node_modules
links (junctions) pointing into the harness checkout
(E:\project\works\dsh\deepseek-harness), and run that checkout's toolchain —
no registry install is needed. The link table (node_modules → checkout):
| link | target in the checkout |
|---|---|
@deepseek-ai/cordis |
vendor/cordis |
@deepseek-ai/schemastery |
vendor/schemastery |
@deepseek-ai/dsh-settings |
packages/settings/settings |
@deepseek-ai/dsh-host-webserver |
packages/host/webserver |
@deepseek-ai/dsh-client-runtime |
packages/client/runtime |
@deepseek-ai/dsh-client-ui-settings |
packages/client/ui-settings |
@deepseek-ai/dsh-client-ui-slots |
packages/client/ui-slots |
@deepseek-ai/dsh-client-locale |
packages/client/locale |
react, @types/react |
packages/client/ui-background/node_modules/... |
@types/node, lightningcss |
root node_modules/... |
& 'E:\project\works\dsh\deepseek-harness\node_modules\.bin\tsc.cmd' -p tsconfig.json
& 'E:\project\works\dsh\deepseek-harness\node_modules\.bin\tsdown.cmd'
The two steps are what pnpm run build (tsc then tsdown) runs under a real
install.
Known limitations
- Remote browsers persist the preference process-locally: the settings RPC is
loopback-only, so a non-loopback browser does not write
settings.yaml. The image bytes are served same-origin and still project for that session. - Uploads are capped at 20 MB and admitted only for the four probed raster formats; no downscaling, compression, or OCR is performed.
- Single-slot storage: a new pick overwrites the previous image.
- The frosted-glass re-theme targets the app's official surface hooks
(
data-*block attributes,md-code-block, and the tool-row IN/OUT card, matched by both itsdata-io-cardhook and a[class*='_ioCard']class-substring fallback so stock app builds keep the glass). If a future app revision renames those hooks, the affected surfaces silently fall back to stock styling — the background image itself keeps working. tsdown.config.tsmirrors the repository'spackages/client/tsdown.client.tspreset; the few deliberate differences for a standalone build are documented in that file's header. Keep it in sync when the preset changes.
No comments yet. Be the first to write one.