Introduction

The DSH Web UI provides basic theme services. If you want to work in a dark or light environment, manually adjusting CSS variables is tedious and easy to miss details. The dsh-palenight-theme plugin encapsulates this process and provides a complete theme override solution.

Plugin Overview

This is a theme plugin designed for the dsh Harness Web UI, maintained by youyli03. It is delivered in two forms: a persistent Bundle (recommended) and a dynamic Cordis plugin.

Core Features

  • Dual-mode support: Provides dark mode (based on Community Material Theme Palenight) and light mode (warm neutral).
    • Dark mode: Indigo surfaces (#292D3E), pale violet text (#A6ACCD), cyan accent (#80CBC4).
    • Light mode: Parchment background (#F5F4F0), warm gray text (#4F4B45), cyan accent (#00897B).
  • Variable overrides: Overrides approximately 100 theme variables, including surfaces, labels/headers, inputs, menus, text hierarchy, borders, buttons, interactive states, code blocks, and scrollbars.
  • Demo components: Includes demo UI components such as the running card panel and composer status line.
  • Hot update: Supports hot updates via dsh-client-hmr without restarting the host process.
  • Two forms:
    • Persistent Bundle: The recommended form, which is retained across host restarts.
    • Dynamic Cordis plugin: Only effective for the current session and marked as deprecated.

Installation and Enablement

The officially recommended installation method is to use DSH’s package management command.

dsh plugin --profile web add dsh-palenight-theme

After installation, restart dsh to activate the persistent bundle. After restarting, the theme will load automatically and remain active across host restarts.

Usage

After installation and restart, you can apply the theme layer by calling theme.overrideTokens in code. For example:

theme.overrideTokens('deepseek-palenight-theme', {
  '--dsw-alias-bg-base': { light: '#F5F4F0', dark: '#292D3E' },
  '--dsw-alias-brand-primary': { light: '#00897B', dark: '#80CBC4' },
  // ... 约 100 个 token
})

How It Works and Notes

  • Activation mechanism: The client bundle declares inject: ['theme'], which requires the theme service to be available. If the service is not ready, ctx.get('theme') will return undefined, causing styles not to take effect.
  • Persistent vs dynamic: A persistent bundle treats the theme as part of the host configuration and remains after restart; a dynamic Cordis plugin is only active during the session and ceases to apply after restart.
  • Tech stack: The plugin code is pure JavaScript (no TS/JSX/import).

Access and Feedback

The plugin is hosted on GitHub and is also listed in the SkillHub community directory.