dsh-loader
Manifest valid★ 3A version-aware adapter registry that decouples third-party Cordis plugins from dsh's internal service names, paths, and RPC internals.

dshloader
A version-aware runtime compatibility shim that keeps third-party plugins working unchanged across dsh (DeepSeek Harness) upgrades.
English
A runtime compatibility shim for dsh (DeepSeek Harness) cordis bundle plugins. dshloader decouples third-party plugins from dsh's internal service names, module paths, package names, and RPC details through a version-aware adapter registry, so that when dsh upgrades and breaks internal APIs, you only upgrade dshloader — plugins keep working unchanged.
Why
dsh is moving fast and its internal surface changes between releases:
httpServerwas renamed towebServer— old plugins that injecthttpServerhang forever.- Deep source imports like
@deepseek-ai/dsh-client-runtime/src/client/sessions/context-provenance.tsbreak when dsh ships nosrc/. - Client UI packages like
@deepseek-ai/dsh-client-ui-primitivescould be renamed in future dsh versions, breaking every plugin that imports them directly. - The official
dsh-host-apiproxyhardcodes a settings namespace whitelist, so third-party settings cards never appear in the Web UI.
dshloader absorbs these (and future) breaks behind a stable API:
ctx.dshLoader on the host, window.__dshLoader__ in the browser, and
@dsh-plugin/dsh-loader/* stable subpaths for package imports.
Quick start
1. Install dshloader into a profile
dsh plugin --profile <name> add /path/to/dshloader
# or
DSH_HOME=~/.dsh npx dshloader setup <name>
2. Plugin package.json — only depend on dshloader
{
"dependencies": {
"@dsh-plugin/dsh-loader": "link:..."
}
}
Plugins must NOT declare any
@deepseek-ai/*dependency. All dsh packages are accessed through dshloader's stable subpaths.
3. Host side — use ctx.dshLoader
export const inject = ['dshLoader'];
export async function apply(ctx) {
// Settings: register a namespace
const scope = ctx.dshLoader.settings.register('my-plugin', schema);
// Web: register routes and WebSocket upgrades
ctx.dshLoader.web.get('/api/my-plugin/status', (req, res) => res.json({ ok: true }));
ctx.dshLoader.web.registerUpgrade({ path: '/ws/my-plugin', handler: fn });
// Services: read cordis services
const sessions = ctx.dshLoader.services.get('sessions');
}
4. Import dsh packages via stable subpaths
// Host packages
const { defineTool } = require('@dsh-plugin/dsh-loader/tools');
// Client UI packages (in client bundle source)
import { IconCloseFill14 } from '@dsh-plugin/dsh-loader/ui-primitives';
Stable subpath → real dsh package mapping (dsh 1.x):
| Stable subpath | Real dsh package |
|---|---|
@dsh-plugin/dsh-loader/tools | @deepseek-ai/dsh-tools |
@dsh-plugin/dsh-loader/llm | @deepseek-ai/dsh-llm |
@dsh-plugin/dsh-loader/agent | @deepseek-ai/dsh-agent |
@dsh-plugin/dsh-loader/settings | @deepseek-ai/dsh-settings |
@dsh-plugin/dsh-loader/ui-primitives | @deepseek-ai/dsh-client-ui-primitives |
@dsh-plugin/dsh-loader/ui-slots | @deepseek-ai/dsh-client-ui-slots |
@dsh-plugin/dsh-loader/ui-settings | @deepseek-ai/dsh-client-ui-settings/client |
@dsh-plugin/dsh-loader/web-react | @deepseek-ai/dsh-client-web-react |
@dsh-plugin/dsh-loader/schema-form | @deepseek-ai/dsh-client-schema-form |
@dsh-plugin/dsh-loader/runtime | @deepseek-ai/dsh-client-runtime/client |
When dsh renames a package, only the dshloader adapter changes — plugin source and bundle stay the same.
5. Client side — use window.__dshLoader__
// Read cordis client services
const conv = window.__dshLoader__.services.get('conversation');
// Register a package alias at runtime (fallback)
window.__dshLoader__.registerPackageAlias('@old/pkg', '@new/pkg');
6. Build config — mark stable subpaths as external
const CLIENT_EXTERNALS = [
'react', 'react/jsx-runtime', 'react-dom', 'react-dom/client', 'cordis',
'@dsh-plugin/dsh-loader/ui-primitives',
'@dsh-plugin/dsh-loader/ui-slots',
'@dsh-plugin/dsh-loader/ui-settings',
'@dsh-plugin/dsh-loader/web-react',
'@dsh-plugin/dsh-loader/schema-form',
'@dsh-plugin/dsh-loader/runtime',
]
How it works
plugin ──▶ ctx.dshLoader.{settings,web,services} ──▶ dshloader adapter
│
▼
real dsh (current version)
plugin bundle ──▶ require('@dsh-plugin/dsh-loader/ui-primitives')
│
▼ (__ModuleLoader__ wrapper maps stable name)
require('@deepseek-ai/dsh-client-ui-primitives')
│
▼
dsh module table
- Version detection reads
node_modules/@deepseek-ai/dsh/package.json(orDSHLOADER_DSH_VERSIONfor tests/override). - AdapterRegistry selects the best adapter for the detected version (exact → range → nearest-low fallback → clear error).
- The selected adapter registers service aliases, installs package-name
mapping hooks (host:
Module._resolveFilename; client:__ModuleLoader__.loadwrapper), and (only when opted in) the settings whitelist bypass bridge. All registrations usectx.reflect.provide/ctx.effect, so cordis auto-recycles them on fiber unload.
Load order does not matter. cordis is reactive dependency injection: plugins declaring
inject: [...]stayPENDINGuntil the alias is provided, regardless of where dshloader sits incordis.patch.yml.
Settings whitelist bypass (exposeAllNamespaces)
By default dshloader does not bypass the official settings namespace whitelist. Opt in explicitly:
- env:
DSHLOADER_EXPOSE_ALL_SETTINGS=1 - profile
package.json:dsh.dshloader.exposeAllNamespaces: true
Security trade-off: enabling this removes the official default-deny boundary for browser settings access. Only enable it in profiles where you trust every installed plugin.
CLI
dshloader setup <profile> Inject dshloader into a profile (dep + patch).
dshloader dump-config <profile> Run `dsh --profile <name> --dump-config`.
dshloader info [profile] Print loader version, detected dsh version,
selected adapter.
Rollback / disable
- Disable per launch:
DSHLOADER_DISABLE=1 dsh web - Remove:
dsh plugin --profile <name> rm @dsh-plugin/dsh-loader
Project layout
src/
index.ts host bundle entry (name / inject / apply)
client.ts client bundle entry (immediately tier)
api.ts DshLoaderHostAPI construction
registry.ts AdapterRegistry + version detection
types.ts shared host/client TypeScript types
version.ts loader version + log prefix
stable/ stable subpath re-exports (ui-primitives, tools, ...)
services/
settings.ts settings stable API
web.ts web stable API
services.ts services stable API (get / alias)
adapters/
dsh-1-x.ts dsh 1.x adapter
index.ts adapter registration
setup.ts profile injection + dump-config + info
bin/dshloader.mjs CLI entry
dist/ compiled host build (tsc output, git-ignored)
lib/ compiled client bundle (tsdown output, git-ignored)
tsconfig.json typecheck config
tsconfig.build.json host build config (emits dist/)
tsdown.client.config.mjs client bundle build config
docs/
api.md full API reference (Chinese)
design.md design document (Chinese)
tests/ L1 (unit) / module (L2) / integration (L3)
examples/
sample-plugin/ minimal example plugin
dsh-aux-state/ example using ctx.dshLoader only
Develop
pnpm install
npm run typecheck # type-check src/**/*.ts
npm run build # compile host (dist/) + client bundle (lib/)
npm test # all tests
npm run test:l1 # unit
npm run test:l2 # module
npm run test:l3 # integration
Node.js >= 18, node --test, no extra test framework.
License
LGPL-3.0-only (GNU Lesser General Public License v3 only). See LICENSE.
Compatibility
Versions
| Latest version | Published | Size |
|---|---|---|
| 1.0.0 | — | — |
| 1.1.0-dev.32278873528 | — | — |
| 1.1.0-dev.32287576957 | — | — |
| 1.2.0-dev.32741629392 | — | — |
| 1.2.0 | — | — |
| 1.3.0-dev.32934417958 | — | — |
| 1.3.0 | — | — |
| 1.3.1-dev.33057703930 | — | — |
| 1.3.1 | — | — |
| 1.3.1-dev.33147177576 | — | — |
| 1.3.2-dev.33147555949 | — | — |
| 1.3.2 | — | — |
| 1.3.3-dev.33217535464 | — | — |
| 1.3.3 | — | — |
| 1.3.3-dev.33218986978 | — | — |
| 1.3.3-dev.33722395196 | — | — |
| 1.3.4-dev.33723587769 | — | — |
| 1.3.4 | — | — |
| 1.3.4-dev.33725063929 | — | — |
| 1.3.4-dev.33728330554 | — | — |
Comments
Loading…
Similar plugins
by Ycet
DSH 设置-插件页新增「我的插件」标签:双列卡片展示用户自己安装的插件(配置状态、Cordis 状态、插件介绍)。Add a "My Plugins" tab to the DSH settings plugins page, listing user-installed plugins in two-column cards with configuration status, Cordis
★ 3
MIT
JavaScript
Oct 22, 2026
dsh plugin --profile web add dsh-my-pluginsby zdjmrq
DSH 用户插件管理器:在 设置→插件 统一管理插件目录散件、运行树插件与 npm 插件包——挂载/卸载/启用/停用(cordis.patch.yml 补丁层 + HMR 热生效)
★ 4
MIT
JavaScript
Oct 4, 2026
dsh plugin --profile web add dsh-pluginmanagerby rvaim
dsh-compat 是 DeepSeek Harness(DSH)的旧插件兼容层。它让原本面向 Claude Code、Codex 的插件尽量保持原目录与语义运行,而不是把每个插件重新迁移成 DSH 原生插件。
★ 0
MIT
TypeScript
Oct 24, 2026
dsh plugin --profile web add @rvaim/dsh-plugin-bridgeby wang-kaopu
Give coding Agents runtime evidence for debugging and verifying DSH / Cordis plugins. 让 Coding Agent 获得用于调试和验证 DSH / Cordis 插件的运行时证据。
★ 0
Apache-2.0
TypeScript
Aug 29, 2026
dsh plugin --profile web add dsh-cordis-devtoolsby rvaim
dsh-compat 是 DeepSeek Harness(DSH)的旧插件兼容层。它让原本面向 Claude Code、Codex 的插件尽量保持原目录与语义运行,而不是把每个插件重新迁移成 DSH 原生插件。
★ 0
↓ 96/wk
MIT
TypeScript
Oct 20, 2026
dsh plugin --profile web add @rvaim/dsh-compatby sky-unicorn
DeepSeek Harness(DSH)一站式增强套件,基于公开插件扩展点构建,无需修改 DSH Core。提供 Windows Launcher、桌面通知与动态桌宠、Plugin Community、MCP Server Manager、模型输入类型配置、最后一条消息编辑与重新生成,以及 Claude Code / Codex Subagents 实时控制。所有功能均可独立安装,支持全量部署、
★ 4
MIT
TypeScript
Oct 28, 2026
dsh plugin --profile web add dsh-enhanced-plugins