Introduction¶
The philosophy of DSH is “everything is a plugin.” With many plugins, the settings interface also multiplies. Writing a settings interface for a plugin is repetitive labor: you have to write components yourself, tune styles, and handle the entire state logic of load/save/busy/error/saved prompts, revision conflicts, etc. Each plugin writes its own, styles don’t match the official settings page, and the user experience is fragmented when switching between plugins.
dsh-settings-ui solves this problem: it extracts the settings page UI and state logic into a reusable service. Plugins can get ready-made components, declarative forms, and a settings state machine via ctx.settingsUi, without writing UI manually. Below introduces its positioning, functions, and usage.
What is it¶
dsh-settings-ui is a unified settings page UI kit and floating panel kit for DeepSeek Harness plugins, maintained by KaramachiA217, under the MIT license, with a LICENSE file in the repo. Looking at the dsh.client.platform field in package.json, it targets the web platform.
It exposes the ctx.settingsUi service to the outside. Other plugins use this service to construct setting blocks and floating panels. The style aligns with dsh-better-sidebar and --dsw-* semantic tokens—no need to write components or CSS yourself, nor handle the load/save/busy/error/saved/revision conflict state logic yourself.
Core Features¶
Three-Level API¶
ui.pluginCard(): The plugin configuration card for the official Plugins tab in rc7, persisted via the officialctx.settingsScope;ui.section(): Classic settings page cards;ui.overlay()/ui.Panel/createPanelStore: Free-floating panels, supporting drag, minimize, z-order, and position persistence, synced across tabs via storage events.
Atomic Component Family¶
The kit provides a set of atomic components: SectionHeader / Field / TextInput / TextArea / Select / Button / Switch / Checkbox / Radio / Card / StatusDot / Badge / Spinner / Tabs / Banner / EmptyState / List / Dialog / ErrorBoundary / toast.
Declarative Forms¶
Rows renders field descriptions; createSettingsStore + useSettings handles load/save/busy/error/saved-flash/revision conflicts; the backend can run on a fenced route or the official settingsScope.
Backward Compatibility and Self-Healing¶
Backward Compatibility: This plugin only adds services; old usage that directly ctx.slots.inject('settings.section', ...) remains unchanged.
Self-healing capability: section() / overlay() / pluginCard() automatically wrap error boundaries. If a single card rendering crashes, only that card collapses, not the entire settings page.
Alignment with Official Contracts¶
The kit only registers via official slots/services (settings.plugin.item / settings.section / shell.overlay / settingsScope / locale). .sui-* styles are parsed from --dsw-* tokens, without importing the official card chrome (import purity gate), and self-rendering a shell aligned with tokens, maintaining form, state, and accessibility. pluginCard’s chrome defaults to the official card model: collapsed layer-3 → expanded layer-2, disclosure header, field separators, discard/save footer.
Installation and Enabling¶
First, do the installation. Using the official CLI, do it in one step: add the dependency, reconcile, and append to dsh.profile.bundles:
dsh plugin --profile <profile-name> add dsh-settings-ui
For subsequent upgrades, just add the @latest suffix to the same command.
Then add it to profile bundles. When the host provides peers, the consumer doesn’t need to declare it as a peer dependency. Here is an example from the README; fill in version numbers in dependencies as appropriate:
{
"dependencies": { "dsh-settings-ui": "^0.2.22" },
"dsh": { "profile": { "bundles": ["dsh-base", "dsh-web-app", "dsh-settings-ui", "..."] } }
}
A small pitfall during installation: pnpm v11’s minimumReleaseAge supply chain cooldown mechanism will cause a silent fallback to the previous version within 24 hours of a brand new release. You can add minimumReleaseAge: 0 in the profile’s pnpm-workspace.yaml, or wait a day to install.
For local development, first use npm pack to build a tarball, then install from local using the same command, or use a file: dependency:
npm pack
dsh plugin --profile <profile-name> add ./dsh-settings-ui-<ver>.tgz
Note the known difference under rc.6: link: development mounting will fail ESM resolution, you need to switch to using a file: tarball.
Typical Usage: pluginCard()¶
Under rc7, the recommended path for plugin settings by the official team is the configuration card on the Plugins tab (the settings.plugin.item slot keyed by the settings namespace), persisted via the official ctx.settingsScope. pluginCard() provides a card with the kit’s shell on top of this contract, without needing to manually bind scope or handle state logic:
const card = ctx.settingsUi.pluginCard({
key: 'my-plugin', // Required, equals settings namespace, also tab key
header: { title: '我的插件', desc: '一句话说明' },
fields: [
{ key: 'enabled', type: 'switch', label: '启用' },
{ key: 'endpoint', type: 'text', label: '服务地址' },
],
})
// card.store.setField('enabled', true)
After calling, no other action is needed: the store internally calls ctx.settingsScope.bind({ namespace: key }), and every modification is saved immediately via the official revision fence.
Several options:
content: (ctx) => ...: Fully custom body;showIn: 'both'/'settings-page': Let the card appear on both the classic settings page;chrome: 'minimal': Remove the kit’s card shell.
Regarding the family single track: For new settings cards, it is recommended to prioritize pluginCard() (official Plugins tab) to avoid a family split where half is on the settings page and half is on the Plugins tab. section() continues to fully support existing consumers and rc6 / headless environments, no migration needed if already in use.
Compatibility and Environment Requirements¶
- Verified on dsh 0.1.0-rc.5 (official desktop shell, full profile test);
- rc.6 verified (2026-08-17): rc.5 and rc.6 share the same upstream commit
47f9438, only npm version number changed, zero adaptation required; - rc.7 (0.3.0, 2026-08-20) adapted:
pluginCard()targets keyedsettings.plugin.itemslot + officialctx.settingsScope; the classic face (settings.section/settings.general.item/shell.overlay) remains unchanged in rc.7,section()/overlay()continue to be usable.
Regarding dependencies: peerDependencies are @deepseek-ai/cordis >=4.0.0-rc.0, @deepseek-ai/dsh-client-runtime >=0.1.0-rc.0, @deepseek-ai/dsh-client-ui-slots >=0.1.0-rc.0, react ^18.2.0; engines require node >=20; dsh.client.platform is web, will inject three @deepseek-ai client runtime/UI packages.
Known limitations: mounting multiple ToastHost on the same page will show the same toast; only one host should be mounted per page. Scope limits (official contract limits): parallel sidebar slots (sidebar.workspaces / sidebar.settings are singletons) and light mode themes.
Development and Quality Gates¶
If you want to participate in development or verify locally, the repo provides three-step commands:
pnpm install
npm run ci
npm test
npm run ci is a 5-step gate: syntax + unit tests + key scanning + purify + pack whitelist; npm test is based on node:test, totaling 45 unit tests.
Regarding the Roadmap: 1.0.0 plans to provide ui.describeForm, consuming the official settings.describe schemastery schema to automatically render forms, supporting redactSecrets for input and revision conflict handling. Engineering-wise, plans include automatic checks for drift between .d.ts and implementation; maintenance commitment is to re-run the contract-diff methodology when upstream rc drifts, with feedback via GitHub discussions.
Use Cases and Considerations¶
Who is it for: Plugin authors who want to add a settings interface to their DSH plugin but don’t want to write components and state logic manually; scenarios where multiple plugins’ settings styles need to remain consistent and evolve with the official settings page.
Must be clear before installation: Plugins run with the permissions of the current dsh process; installing a plugin is equivalent to running its code in your own environment. dsh-settings-ui is under the MIT license, source code is open on GitHub. You should check the source code and license yourself before installing to ensure trustworthiness.
Summary¶
dsh-settings-ui puts the repetitive parts of the DSH plugin settings interface—components, styles, state machines—into a single ctx.settingsUi service: the three-level API covers needs from official Plugins cards to classic settings pages to free-floating panels, aligns with official contracts, is backward compatible, and won’t drag down the entire settings page even if a single card crashes. If you are writing a DSH plugin with settings, you can start directly from pluginCard().
- Community Plugin Directory: https://www.skillhub.cn/plugins/KaramachiA217/dsh-settings-ui (Independent community site, no official affiliation with DeepSeek / Hypothesis)
- GitHub Repository: https://github.com/KaramachiA217/dsh-settings-ui