@sidleo3/dsh-plugins-plus
English | 中文
One DeepSeek Harness (DSH) bundle that ships independently switchable components, each replacing a built-in plugin per agent preset. Configuration lives in DSH Settings.
| Component (Loader row id) | Replaces | What it does |
|---|
dsh-plugins-plus | — | Core row: owns the single configuration schema, the takeover engine, and the read-only status API |
agent-instructions-plus | agent-instructions | AGENTS.md injection: four scan layers (cwd / project / every ancestor / global) with editable file names and budgets |
skill-filesystem-plus | skill-filesystem | Skill discovery: four scan layers plus editable, orderable parent-directory names |
Component naming rule: built-in row id + -plus. Adding a component later means one more export, one more cordis.patch.yml row, one schema section and one UI section — no new package, nothing to install twice.
Install
# from npm (recommended)
dsh plugin --profile <profile> add @sidleo3/dsh-plugins-plus
# from a local checkout (development)
dsh plugin --profile <profile> add link:/path/to/dsh-plugins-plus
Restart DSH afterwards. Installation itself changes nothing: only the core row is enabled by default, both component rows ship disabled: true.
Switch components on
Sidebar Plugins → the DSH Plugins Plus card → flip the row switch of the component you want.
- Turning
skill-filesystem-plus on makes the engine disable the built-in skill-filesystem row inside the selected presets and append this bundle's discovery row.
- Turning it off undoes exactly that; the built-in implementation returns, and DSH deletes the override row entirely once the composition equals the shipped layer again.
Configure (Settings → DSH Plus)
One page, three entry points, the same UI:
| Entry point | Where |
|---|
| Settings → DSH Plus | a first-class settings section (recommended) |
| Sidebar Plugins → this bundle's card | plugins.bundle.config |
| Sidebar Plugins → a component row's Configure | plugins.row.config, keyed <package>#<row id> |
The page offers a global preset selection every component inherits, one card per component (inherit the global selection or pick its own, plus that component's parameters), and the live takeover state of every preset. The page carries no log: a run log opener at its foot shows the engine's record (effective configuration and component state, migration outcome, the last 20 passes with their reasons, writes, failures and notes) in an in-page overlay — never in a new tab, because the Desktop shell denies window.open. The same text answers GET /api/dsh-plugins-plus/log.
Writes go through DSH's own pipeline (ctx.configForms → settings → config editor → the profile's cordis.patch.yml):
- configuration lives in the profile patch under the core row; this bundle keeps no settings file of its own;
- every field keeps inheritance semantics — "restore default" is an
unset, falling back to the schema default;
- saving applies immediately; the core row is not remounted (its fields are volatile).
A session fixes its preset composition when it is created, so takeover changes affect sessions created afterwards.
Differences from the built-ins
| Dimension | Built-in | This bundle |
|---|
| Scope | every preset | only the presets you select (global selection may mean "all") |
| Upward scan | stops at the project root (.git) | scanProject or scanParents (up to /), mutually exclusive |
| cwd / global layer | fixed | independent switches |
| Skill parent directories | fixed | add, edit, remove, reorder |
| Configuration | a JSON file per plugin | DSH Settings (profile patch) |
Migrating from the two standalone plugins
The old packages are @sidleo3/agent-instructions-plus and @sidleo3/skill-filesystem-plus.
dsh plugin --profile <profile> add @sidleo3/dsh-plugins-plus
dsh plugin --profile <profile> remove @sidleo3/agent-instructions-plus
dsh plugin --profile <profile> remove @sidleo3/skill-filesystem-plus
# restart DSH
On the next start the engine performs these steps once, recording the import as a legacyImport timestamp in its own configuration:
- fields from
~/.dsh/dsh-instruction-scan.json and ~/.dsh/dsh-skill-filesystem-plus.json that the profile does not declare yet are imported into components.*;
- presets the old wizards had already taken over are adopted as that component's preset selection (
useGlobalPresets: false plus the list);
- earlier releases' pipeline rows (
*-plus-pipeline and their old module names) are rewritten in place, never duplicated.
The legacy JSON files are left untouched: they live in the shared ~/.dsh, where another profile may still run the old plugins. Delete them yourself once you are sure.
Compatibility
| DSH version | Status |
|---|
0.2.0-rc.1 | ✅ verified: install gate, bundle load, real-link E2E (install → takeover → release → cleanup), client module graph |
0.2.0 (stable, not yet released) | ✅ covered by the declared peer ranges |
0.1.7-alpha.2 – 0.1.7-rc.2 | ✅ covered by the declared peer ranges; not re-verified in the 0.2.0 iteration |
The design target is the plugin API DSH grew in the 0.1.7 line — settings.section, plugins.bundle.config, plugins.row.config, ctx.configForms, ctx.configEditor, agentPresets.compositionInventory.
DSH enforces a hard compatibility gate on peerDependencies whose names start with @deepseek-ai/dsh: a range that does not satisfy the running version makes the installer refuse the plugin, and makes DSH skip the whole bundle at load time (every row, the settings section and the read-only routes disappear — the symptom is "the plugin vanished after a DSH upgrade"). The declared ranges therefore always span every supported release line. Note ^0.2.0 does not match 0.2.0-rc.1, because a prerelease sorts below its release.
Everything version-sensitive is kept in src/core/ (composition.ts, takeover.ts, hmr.ts, rpc.ts) so a future DSH change has one obvious place to look.
Development
pnpm install --ignore-scripts
pnpm resolve-types # resolve @deepseek-ai/* types from the RUNNING DSH install (.dsh-types/, gitignored)
pnpm typecheck # expect 0 errors
pnpm build # tsdown → lib/{index,agent-instructions,skill-filesystem,*-preset,client}.js
pnpm smoke # 28 checks: schema, inheritance, takeover planning, migration, client contract
Release checklist:
pnpm typecheck && pnpm build && pnpm smoke
grep -c 'plugins.bundle.config' lib/client.js # >= 1: the bundle configuration page is registered
head -c 80 lib/client.js | grep -c '__ModuleLoader__' # 1: the client half is a CJS factory
grep -rn 'from "\./.*\.d\.ts"' lib/*.js # 0 lines: no type file is imported at runtime
License
MIT