Bundle
dsh-settings-beautify
One design language for the DSH settings surface: unified title / explanation / content typography, consistent cards, controls, focus and motion across every settings page — including pages contributed by other plugins.
- Source
- leogottadothebest
- License
- MIT
- Updated
- Updated yesterday
Readme
# dsh-settings-beautify
One design language for the DSH settings surface.
[](LICENSE)
[](https://www.npmjs.com/package/dsh-settings-beautify)
[简体中文](README.zh.md)
## 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, badges 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 | ✅ |
| 插件 Plugins (tabs, cards, config fields) | ✅ |
| 插件市场 Plugin market (inventory tab) | ✅ |
| 桌面 Desktop (profiles, network, notifications) | ✅ |
| 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:
```sh
dsh plugin --profile <profile> add dsh-settings-beautify
```
### Manual install (development)
```sh
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:
```js
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](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](docs/DESIGN.md#the-data-dshb-attribute-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
```sh
pnpm install
pnpm check # syntax checks
pnpm test # jsdom tests for the DOM normalizer (86 assertions)
pnpm sync-styles # regenerate lib/styles/settings.css from lib/client.js
```
The test suite reconstructs the real DSH settings DOM (general items, models
cards, plugins tabs/fields, desktop groups, an opted-in third-party page) in
jsdom and asserts the full `data-dshb-*` tagging contract.
## Compatibility
- DSH Desktop 2.x (bundled web UI), including 2.0.5: the settings DOM and
client-loading contracts were re-audited against 2.0.5 package sources
(the relevant @deepseek-ai client packages ship no code change between
2.0.4 and 2.0.5), so the plugin works without modification.
- 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](SECURITY.md).
## License
MIT — see [LICENSE](LICENSE).
Install
dsh plugin --profile web add github:leogottadothebest/dsh-settings-beautify
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-settings-beautify from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.