dsh-plugin-reload
English | 中文
A DeepSeek Harness plugin that gives the agent a reload_plugin tool: restart exactly one Cordis Loader entry — matched by entry id, module name, or MCP serverName. Every other entry keeps running.
Two reload strategies are chosen per entry kind:
mcp-cliententries respawn the MCP server child process on restart (picking up new server code on disk) and re-register its tools; sibling MCP connections are not affected.- in-process plugin entries get a hard reload: the Node ESM/CJS module caches for the entry and its local source files are busted, the entry is re-imported from disk, and its fibers are swapped onto the fresh module — the same technique
cordis-plugin-hmr's partial reload uses. Plugin code changes take effect without restarting the host, and a failed re-import or re-apply rolls back to the previous code.
Built on the "everything is a plugin" architecture of DeepSeek Harness. The official repository does not accept external pull requests at the moment — per CONTRIBUTING.md, community plugins are published independently and shared under the
dsh-plugintopic.
Install (auto-mount)
Since v0.1.2 the package declares a dsh.bundle, so a single command installs the plugin and automatically mounts it:
dsh plugin --profile web add dsh-plugin-reload
What happens under the hood:
dsh pluginrunspnpm addinside the profile directory (~/.dsh/profiles/<name>/).- On success it reconciles the profile manifest: because
dsh-plugin-reloaddeclaresdsh.bundlein itspackage.json, it is appended to the profile'sdsh.profile.bundleslayer list. - On the next harness start the bundle layer is composed, and the plugin's own
cordis.patch.ymlinserts theplugin-reloadentry — the tool appears in the model's tool list with no manual patch editing.
To pick up a later version:
dsh plugin --profile web update dsh-plugin-reload
Freshly published versions may be held back briefly by pnpm's
minimumReleaseAgesupply-chain policy; an explicit version (dsh plugin --profile web add dsh-plugin-reload@0.1.x) bypasses it.
Manual mount (alternative)
If you install the package with plain npm (not via dsh plugin), or prefer an explicit patch row, add it to your profile patch (~/.dsh/profiles/<name>/cordis.patch.yml, or a --patch overlay):
- insert:
- id: plugin-reload
name: 'dsh-plugin-reload'
Restart the harness (or let profile-patch HMR pick it up). Keep either the bundle mount or the manual row — not both (a duplicate tool registration fails at load).
Usage
reload_plugin accepts:
| Argument | Required | Meaning |
|---|---|---|
name |
yes | Entry id (preferred), module name, or MCP config.serverName of the entry to reload |
mode |
no | auto (default) — hard reload for in-process plugins, fiber restart for mcp-client; soft — dispose and re-apply only (never picks up in-process code changes); hard — bust ESM/CJS caches and re-import the entry code from disk |
dry_run |
no | true reports the single matched entry and the strategy that would run, without restarting it |
Matching walks the Loader's non-group entries once: exact entry id first, then module name, then mcp-client serverName. Zero matches fail with a bounded list of available entries; multiple matches fail listing the candidate entry ids and change nothing. Group entries never match — restarting a subtree requires one call per leaf entry.
A successful reload returns the entry id, module, optional serverName, previous and current fiber phases, the strategy used, and a semantics note. A hard reload writes nothing back to the loader config: the entry's options stay untouched, only its fiber is swapped onto the re-imported module.
Requirements
- A DeepSeek Harness profile with the web (or headless) bundle, i.e. the standard
dshruntime with@deepseek-ai/dsh-toolsand@deepseek-ai/cordis-plugin-loaderavailable.
Known limitations
- Brief tool outage during reload — the reloaded entry's contributions (e.g. MCP tools) are unregistered between disposal and re-application; in-flight calls to those tools fail.
- No group reload — restarting a whole plugin subtree must be requested per leaf entry.
- Hard reload covers the plugin's own code only — dependencies in
node_modules(e.g.@deepseek-ai/*,ws) are intentionally not re-imported; changing those still requires a host restart. Module-level state of the reloaded plugin is re-evaluated (a freshimport), so plugins must not rely on top-level persistent state surviving a reload. - Agent-facing only — no browser/UI surface; the Settings plugin-inventory tab stays read-only.
Development
npm install # dev deps (types + typescript) from npm
npm run build # tsc → lib/
npm test # vitest
npm pack # inspect the tarball before publishing
License
MIT
No comments yet. Be the first to write one.