Skip to content
dsh-market Browse plugins GitHub 中文

leogottadothebest/dsh-settings-beautify

Normalize the DSH settings UI onto one design language: unified typography, cards, controls, focus and motion across every settings page, including pages contributed by other plugins.

Stars ★ 0 Category UI Enhancements Listed 2026-09-03 npm dsh-settings-beautify

Install

Inside DeepSeek Harness, with dsh-market

dsh plugin --profile web add dshmarket

Or from the command line

dsh plugin --profile web add dsh-settings-beautify

Installing runs third-party code with your own permissions — it can read your files, use your credentials and reach the network. Review the source first, and pin a commit (github:owner/repo#sha) when you can.

README

One design language for the DSH settings surface.

简体中文

What it does

DSH's settings are composed from many plugins, and each page historically speaks a slightly different typography and surface language — page titles in 16/18/22px, explanations in 12/13/14px, cards with 8/10/12px radii, controls with their own heights and focus styles.

dsh-settings-beautify normalizes every settings page onto a single design language:

  • Architecture: every page is built from the same three-part hierarchy — 标题 / Title → 解释 / Explanation → 内容 / Content (通用 General settings keeps its preference-row form, which is the same hierarchy in a compact variant).
  • Typography: one size for every page title, one for every explanation, one for every item title and item description — regardless of which plugin contributed the page.
  • Surfaces: consistent card radius/border/background, consistent rows, controls, focus rings, tabs, chips and scrollbars, all driven by DSH's own --dsw-* tokens, so light / dark / system themes keep working.
  • Motion: subtle, tasteful hover micro-motion that respects prefers-reduced-motion and can be turned off.
  • Extensible: any page — including pages contributed by other plugins, such as archived-conversation lists — opts into the same language with one attribute (data-dshb-scan), and the DOM normalizer handles the rest.
  • Headless: the plugin adds nothing to the settings nav rail — no settings page of its own. Preferences are opt-in and live in localStorage.

It works without touching DSH's source: the plugin observes the settings panel, marks each structural role with a stable data-dshb-* attribute (the built-in class names are build-hashed and can't be relied on), and a scoped stylesheet applies the language on top.

What is covered

Surface Built in
Settings shell (nav rail, header, close, scrollbars) ✅
通用 General — every preference row (language, appearance, font size, Enter behavior, agent presets, permissions, …) ✅
模型 Models ✅
智能体预设 Agent presets ✅
内置插件 Built-in plugins (search, scope groups, catalog) ✅
Agent 预设 Agent presets (group headings, preset cards, tags) ✅
Any third-party page that adds data-dshb-scan to its root (e.g. an archived-conversations page) ✅

Installation

From the plugin market

dsh-settings-beautify follows the DSH community-market package contract (dsh.bundle.patch + dsh.client manifest), so it can be installed from the market or with:

dsh plugin --profile <profile> add dsh-settings-beautify

Manual install (development)

pnpm add dsh-settings-beautify        # into the profile's package set
# and ensure the bundle entry is declared, e.g. via the profile patch:
#   - insert:
#       - id: dsh-settings-beautify
#         name: dsh-settings-beautify

After install, restart DSH Desktop (or reload the web window). The design language is applied automatically — nothing is added to the settings nav rail.

Preferences (headless)

The plugin has no settings page of its own. Preferences are read from the browser's localStorage under dsh-settings-beautify:prefs:

Key Values Effect
enabled true / false Apply the language or restore DSH's original look.
density compact / default / comfortable Row and list spacing.
motion true / false Card hover micro-motion. prefers-reduced-motion always wins.

Defaults: {"enabled": true, "density": "default", "motion": true}. To tune them, open the browser console and run:

window.DSHB.setPrefs({ density: "compact" })   // or { enabled: false }, { motion: false }

No host files or settings namespaces are touched.

The design language

The full specification — tokens, hierarchy, spacing/radius/motion scale, and the data-dshb-* attribute contract — lives in docs/DESIGN.md. A condensed version:

Role Font Color
Page title (页面标题) 18px / 600 / 26px --dsw-alias-label-primary
Page explanation (页面解释) 13px / 400 / 20px --dsw-alias-label-tertiary
Group title (组标题) 14px / 600 / 22px --dsw-alias-label-primary
Item title (条目标题) 14px / 500 / 22px --dsw-alias-label-primary
Item description (条目解释) 13px / 400 / 20px --dsw-alias-label-tertiary
Body (正文) 14px / 400 / 22px --dsw-alias-label-primary
Caption (辅助文字) 12px / 400 / 18px --dsw-alias-label-tertiary

Cards: 12px radius · --dsw-alias-border-l2 · --dsw-alias-bg-layer-3 (elevated over the panel). Controls: 8px radius, 36px min-height, brand focus ring. The title → caption gap is a uniform 4px everywhere the language applies (--dshb-gap-title-desc, matching DSH's row convention). Radii are tokenized (--dshb-*) so a future version can offer alternate palettes.

Contributing pages from other plugins

The DOM normalizer auto-tags the built-in pages. For your plugin's page, either:

  1. Add data-dshb-scan to the page root (a third-party section hosted inside the settings dialog works the same way) — the normalizer then applies the same heading/prose/card/row/control rules generically, including the uniform 4px title → caption gap; or
  2. Use the attributes directly (data-dshb-page-title, data-dshb-item-title, data-dshb-card, …) for full control.

See the extensibility contract.

Design notes

The plugin is intentionally headless: it only restyles the settings surface. If you would rather have a visible control page, that is a small follow-up change — open an issue and it can be added behind a preference.

Development

pnpm install
pnpm check             # syntax checks
pnpm test              # fixture-driven jsdom tests (135 assertions)
pnpm sync-styles       # regenerate lib/styles/settings.css from lib/client.js
pnpm capture-fixtures  # re-record test/fixtures/ from a running DSH Desktop

The tests do not hand-write a stand-in DOM. test/fixtures/<version>.json is captured from a running DSH Desktop — the settings panel's markup and the stylesheets the host injects — and test/cascade.mjs recomputes the cascade in jsdom (specificity, inheritance, var() substitution, the shorthands the tagger reads). Every heuristic is therefore exercised against the computed styles the real build produces, not against inline styles that would silently stop matching it.

After a DSH upgrade: pnpm capture-fixtures, run pnpm test, and fix what the new surface broke. The fixture is committed, so a regression is reproducible offline without a browser.

Compatibility

  • DSH 0.1.7-rc.2 (DSH Desktop, bundled web UI). Currently adapted through 0.1.7-rc.2 against a captured fixture of that build.
  • What 0.1.7-rc.2 changed underneath the plugin: the settings shell kept its contract (nav / content / header / options / [data-slot="settings.section"]), but every page below it was re-laid out — cards moved from 12px to 20px radius, the plugin-market page is gone (replaced by a searchable built-in plugin inventory), the DSH Desktop settings page no longer contributes a settings section, the header gained a second button, and tag/chip labels became a shared _tag_* primitive. 0.3.0 removed the selectors that no longer exist and taught the tagger the new shapes (a preference row is now detected by its divider + padding, cards by their border box, chip labels by their pill radius).
  • If the whole settings surface suddenly reverts to its unstyled form, first check whether another plugin in the same profile still imports host APIs that 2.0.5 removed (e.g. @deepseek-ai/dsh-typert-protocol stopped exporting TypertRemoteFailure in 0.1.2-rc.1) — one failing plugin import can take down the entire profile plugin tree and with it this plugin. The tagger is defensive: anything it cannot recognize is simply left untouched.
  • The stylesheet only runs inside the settings panel scope; nothing outside settings is restyled.

Security

No network requests, no host APIs, no file access, no remote code. Preferences live in localStorage. See SECURITY.md.

License

MIT — see LICENSE.

Content from the project README on GitHub ↗

Comments

Comments live in GitHub Discussions. Sign in with GitHub to post or react.