dsh-theme-synthwave
September 1, 2026 Β· View on GitHub
π δΈζζζ‘£οΌREADME.md
A Synthwave theme plugin for the DSH (DeepSeek Harness) Web UI.
One package ships both the host half (config reading, media file serving) and the client half (theme tokens, neon glow, background media, font scaling), ready to use after installation. The background supports local image slideshows or video, semi-transparent panels that let the media show through, plus configurable neon glow, blur, and global font scaling.

β¨ Features
- Neon glow on hover/focus: adds layered
text-shadowglow to links, buttons,role="button"and other clickable controls, switching colors on hover/focus. - Semi-transparent panels revealing the background: adjust the app/sidebar background opacity with
background.baseAlphato let the image or video behind show through. - Background image slideshow: cycle multiple images sequentially or randomly, with configurable opacity and interval.
- Background video: supports local video files or
http(s)URLs, with configurable loop, mute, andobject-fit. - Background media / default bubble blur:
blur0β40px, applied only at the render layer without touching the source files. - Root font scaling
fontScale: scales text via the root font size, avoiding CSSzoomhit-target and popup-positioning issues in Firefox. - Light/dark adaptive tokens: dark mode keeps the synthwave neon look; light mode automatically switches to a light background with dark text to stay readable.
- Config card shortcut: in the Plugins configuration page, the card offers "Open config file" and "Copy path" buttons to quickly open or copy the current profile's
config.dsh-theme-synthwave.jsonc. - Removable media: the config card can remove a configured video, and remove any single image from the image list; changes are written back to the local config immediately.
- Editing safety: the config file editor supports a "Cancel" action to discard unsaved changes; if the config fails to parse, the plugin falls back to defaults (without touching the file) and shows a notice in the UI.
π Quick start
-
Install the plugin
# Local directory dsh plugin --profile web add link:<repo root> # Git repository (after publishing to GitHub) dsh plugin --profile web add "git+https://github.com/<your-username>/dsh-theme-synthwave.git" # npm (after publishing) dsh plugin --profile web add @1mlightyears/dsh-theme-synthwaveGit install note: a
git+install fetches the source (not built artifacts); DSH/pnpm runs this package'spreparescript after install to buildlib/fromsrc/. pnpm β₯10 refuses to run a git dependency'sprepareuntil you allow it: the firstaddfails anddshprints the exact package key to copy into that profile'spnpm-workspace.yaml, e.g.:allowBuilds: '@1mlightyears/dsh-theme-synthwave': trueThen re-run
add. Lock the commit (git+https://β¦#<sha>) so later pushes cannot silently change what runs.If your repository is a monorepo and the plugin lives in a subdirectory:
dsh plugin --profile web add "git+https://github.com/<your-username>/<repo>.git#subdirectory=path/to/dsh-theme-synthwave" -
Create/edit the config
On first page load, the plugin automatically generates
config.dsh-theme-synthwave.jsoncin the current profile directory (using built-in defaults). You can also create it manually by followingconfig.dsh-theme-synthwave.example.jsonc. The config file lives in the current profile directory, not the session workspace. -
Prepare background assets
Put images or videos in the same directory as
config.dsh-theme-synthwave.jsonc(absolute paths andhttp(s)URLs also work).Current directory: the base directory that
.(or any relative path) inbackground.video.path/background.images.pathsresolves against is the directory containingconfig.dsh-theme-synthwave.jsoncβ i.e. the current profile directory (usually$DSH_HOME/profiles/<profile>/). It is not the session workspace and not the plugin package directory. -
Restart and refresh
Restart DSH after the first install, then hard-refresh the page in the browser to see the effect. Afterwards, changing
config.dsh-theme-synthwave.jsonconly requires a hard refresh.
βοΈ Configuration
You can also open or copy the current profile's config file path from the "DeepSeek Harness: εζζ³’ι£ζ ΌδΈ»ι’" card in DSH Settings β Plugins β Plugin configuration.

The plugin looks for config.dsh-theme-synthwave.jsonc in the current profile directory (usually $DSH_HOME/profiles/<profile>/); if it does not exist, the plugin creates one with built-in defaults. config.dsh-theme-synthwave.example.jsonc is a commented reference template you can follow.
In the "DeepSeek Harness: εζζ³’ι£ζ ΌδΈ»ι’" card you can perform the common operations directly: choose/upload an image or a dynamic background, remove a dynamic background or a single image from the "Current background media" list, apply a media source via URL or bare filename, configure the dynamic background's autoplay policy and cache duration, clear all cached dynamic backgrounds, and edit the config file text ("Save" writes it, "Cancel" discards unsaved changes). If the config file fails to parse, the plugin temporarily applies defaults without modifying the file, and shows a notice suggesting you delete it (the plugin will recreate a default) or fix it against the example file.
Mobile autoplay note: a dynamic background can be large. To save data, mobile never autoplays by default (
background.video.autoplaydefaults tonever). Whenever the dynamic background is already cached locally (Cache Storage hit) it will autoplay with no extra data; otherwise the page shows a "Load dynamic background" button (annotated with the file size when known; remote-URL sizes are unknown), which downloads and plays only after a tap.
A minimal example without comments:
{
"textGlow": {
"enabled": true,
"alpha": 0.6,
"hoverAlpha": 0.85,
"blurEm": 0.30,
"colors": ["#ff2a6d"],
"hoverColors": ["#05d9e8"],
"suppressHoverFill": true
},
"fontScale": 1.15,
"background": {
"baseAlpha": 0.5,
"blur": 2,
"defaultEffect": 1,
"video": {
"path": "background.mp4",
"loop": true,
"muted": true,
"objectFit": "cover",
"autoplay": "never",
"cacheDays": 30
},
"images": {
"paths": ["background.jpg"],
"alpha": 0.85,
"intervalMs": 60000,
"order": "sequential"
}
}
}
After changing `config.dsh-theme-synthwave.jsonc`, hard-refresh the page to reload the config; only installing/uninstalling the plugin itself requires a DSH restart.
π Service endpoints
| Path | Description |
|---|---|
GET /synthwave-theme-config | Returns the resolved JSON config (includingconfigPath) for the browser half. |
POST /synthwave-theme-config/open | Opens the current profile's config file with the OS default handler. |
POST /synthwave-theme-config/remove | Removes the dynamic background record, or removes a given image from the image list, and writes the config back. |
POST /synthwave-theme-config/video-options | Sets the dynamic background's autoplay policy and cache duration (cacheDays). |
GET /synthwave-theme-media/<filename> | Reads and returns background image/dynamic background bytes (512MB cap, with Cache-Control by cache duration). |
β FAQ
- Background media doesn't show: make sure
config.dsh-theme-synthwave.jsoncis in the current profile directory, the media path resolves, and you have hard-refreshed the page. Seeconfig.dsh-theme-synthwave.example.jsoncfor parameter details. - Video has no sound: background video is muted by default, which is expected under browser autoplay policy; see the
video.mutedcomment inconfig.dsh-theme-synthwave.example.jsonc. - Dynamic background doesn't autoplay on mobile: this is intentional to save data (see the "Mobile autoplay note" above). Tap "Load dynamic background" to play it; it will autoplay automatically once cached locally.
- How to clear cached dynamic backgrounds: click "Clear all cached dynamic backgrounds" under "Dynamic background options" in the config card; it deletes the local browser cache and reports the count and total size released.
π Project structure
.
βββ src/
β βββ host/
β β βββ index.ts # host half: reads config, serves media and config endpoints
β βββ client/
β βββ index.ts # client half: tokens / glow / background / blur / font scaling
β βββ OpenConfigCard.ts # plugin config card: open/copy the config file
βββ lib/ # build output (do not edit by hand)
β βββ index.js
β βββ client.js
βββ build/ # vendored DSH client-bundle build preset
βββ cordis.patch.yml # bundle patch
βββ tsdown.config.ts # tsdown build entry
βββ config.dsh-theme-synthwave.example.jsonc # config template
βββ package.json
π οΈ Development
pnpm install # also runs `prepare` to build lib/
pnpm build # tsdown β lib/index.js + lib/client.js
Build output goes to lib/; do not edit lib/ by hand before publishing. Note: the host half loads when the DSH process starts, so changing it requires restarting dsh --profile web; a browser refresh only reloads the client half.