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.

showcase

✨ Features

  • Neon glow on hover/focus: adds layered text-shadow glow 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.baseAlpha to 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, and object-fit.
  • Background media / default bubble blur: blur 0–40px, applied only at the render layer without touching the source files.
  • Root font scaling fontScale: scales text via the root font size, avoiding CSS zoom hit-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

  1. 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-synthwave
    

    Git install note: a git+ install fetches the source (not built artifacts); DSH/pnpm runs this package's prepare script after install to build lib/ from src/. pnpm β‰₯10 refuses to run a git dependency's prepare until you allow it: the first add fails and dsh prints the exact package key to copy into that profile's pnpm-workspace.yaml, e.g.:

    allowBuilds:
      '@1mlightyears/dsh-theme-synthwave': true
    

    Then 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"
    
  2. Create/edit the config

    On first page load, the plugin automatically generates config.dsh-theme-synthwave.jsonc in the current profile directory (using built-in defaults). You can also create it manually by following config.dsh-theme-synthwave.example.jsonc. The config file lives in the current profile directory, not the session workspace.

  3. Prepare background assets

    Put images or videos in the same directory as config.dsh-theme-synthwave.jsonc (absolute paths and http(s) URLs also work).

    Current directory: the base directory that . (or any relative path) in background.video.path / background.images.paths resolves against is the directory containing config.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.

  4. 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.jsonc only 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.

settings

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.autoplay defaults to never). 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

PathDescription
GET /synthwave-theme-configReturns the resolved JSON config (includingconfigPath) for the browser half.
POST /synthwave-theme-config/openOpens the current profile's config file with the OS default handler.
POST /synthwave-theme-config/removeRemoves the dynamic background record, or removes a given image from the image list, and writes the config back.
POST /synthwave-theme-config/video-optionsSets 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.jsonc is in the current profile directory, the media path resolves, and you have hard-refreshed the page. See config.dsh-theme-synthwave.example.jsonc for parameter details.
  • Video has no sound: background video is muted by default, which is expected under browser autoplay policy; see the video.muted comment in config.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.

πŸ“„ License

Apache-2.0