dsh-plugin-ops
English | 中文
DeepSeek Harness plugin operations: one-command health check, pre-boot gate, failure attribution and recovery, dependency-tree governance — the doctor for the plugin ecosystem, converging into an integrated plugin-management suite.
Status: v0.14.1 — installation adaptation in the panel (exempt-install through the official plugin manager; failures report in-card with the package-manager output) and in the CLI (canary-backed, desktop-aware), with exemption cleanup on removal. Interception, repair, and memory mechanics: docs/architecture.md.
Names
| Layer | Name | Notes |
|---|---|---|
| GitHub repository / npm packages | dsh-plugin-ops (CLI), dsh-plugin-ops-core (engine), dsh-plugin-ops-bundle (embedded bundle) |
one public name across all |
| Command | dsh-ops |
the bin installed by the CLI package |
Why
The DeepSeek Harness (dsh) plugin ecosystem has grown explosively since August 2026, but its loading model is unforgiving: static patches apply through a required bootstrap Include, so one patch row that cannot be imported aborts the whole boot. Since 0.1.6, an already-imported plugin that fails to activate is only skipped with a warning — its features silently disappear instead of failing loud. The same version moved the launcher to runtime resolution: the package table is built in-process from the installation's dependency graph plus the selected bundles, so checks that trust the disk layout alone drift from what the launcher actually resolves.
Existing ecosystem tools cover change-time protection (dry runs during install/update) and runtime observation; none do whole-tree pre-boot checks, follow the launcher's runtime resolution table, and attribute a failed boot through the official diagnostics. dsh-plugin-ops fills that gap.
Quick start
npm i -g dsh-plugin-ops
dsh-ops check # scan every profile (offline, seconds)
dsh-ops scan --profile web # deep scan one profile (--json for machines)
dsh-ops fix --profile web # lockfile realign (--dry-run to preview)
dsh-ops gate -- dsh web # pre-boot gate; attribute failures automatically
dsh-ops adapt <pkg> # adapt a plugin the official gate rejects (canary + exemption)
dsh-ops serve # local web panel at http://127.0.0.1:8912 (zh/en)
dsh-ops selftest # run built-in fault samples through all rules
check prints one summary line per profile plus per-finding fix hints; --json is model-friendly.
Scan rules (8, fully static and deterministic)
| # | Rule | Severity | What it catches |
|---|---|---|---|
| 1 | Bundle declaration integrity | fatal | layer package unresolvable / no dsh.bundle.patch / a declared patch file missing (a bundle may list several patch files in order, 0.1.7+) |
| 2 | Three-way dependency drift | fatal / auto-fix | package.json declaration vs pnpm-lock.yaml vs disk |
| 3 | Registry version comparison | warn | updates via pnpm outdated; advisory, never blocks |
| 4 | Peer gaps / double instances | double instance fatal | peers that cannot resolve; two physical copies of framework core |
| 5 | Patch-row resolution | fatal | packages referenced by patch rows (including subpaths) unresolvable; patch rows apply through the required bootstrap Include, so one bad row aborts the boot (verified against dsh 0.1.6-alpha.2) |
| 6 | Fault memory | info/warn | packages that changed since the last successful boot (attribution baseline) |
| 7 | Structure integrity | fatal/warn | missing default entry / CJS entry (the Loader needs ESM named exports) / missing types or client |
| 8 | Plugin version compatibility | fatal / info (exempted) | @deepseek-ai/dsh* peer ranges that reject the running dsh version — dsh 0.1.7-rc.1+ skips such a bundle, silently dropping its features unless an exact-version exemption is granted |
Resolution follows the launcher's runtime generation (0.1.6+): the profile's own tree wins natively, then the package table rebuilt from the installation manifest and the selected bundles — the frozen disk mirror no longer decides.
Real-ecosystem validation: dangling peer declarations (authors referencing official packages that were never published) were detected on multiple third-party plugins.
Commands
| Surface | Description |
|---|---|
check |
one-shot health check across all profiles (offline by default) |
scan |
single-profile deep scan: rules 1-8 plus optional update check |
fix |
auto-fix set: disk↔lockfile realign (pnpm install --frozen-lockfile --force); plan → confirm → execute → backup |
gate |
block-first graded disposition: fatal findings block (auto-fix then pass; complex ones get loud guidance; --bypass is a logged escape hatch); a boot failure reads the official startup diagnostics ($DSH_HOME/logs/startup-*.log), attributes the changed packages and the launcher-reported failed plugins, and offers interactive disable-and-retry; one-shot headless profiles pass exit codes through without attribution |
serve |
local web panel: health cards / findings / fix execution / plugin-row management (health badges, severity filter, 10-per-page paging, official-row protection, enable/disable) / fault timeline / diagnosis chat with an enhanced-retrieval (RAG) toggle — troubleshooting experience deposits as Markdown and matching entries are retrieved into the chat (BM25 + optional embedding re-rank), zh/en switch |
selftest |
engine self-check over six built-in fault samples |
verify |
publish-time check for plugin authors: accepts a local directory or an npm package spec (dsh-ops verify <name|@scope/name|name@version>, downloaded from the registry); covers bundle patch declaration/parse, patch-row resolution, dependency protocols (file:/workspace:), peer contracts (peer keys must be package names, peer ranges must be semver), ESM entry and exports, client export contract and bundle shape, files completeness (--json, --strict for CI); --runtime additionally boots the package in an isolated DSH home (official install + launch) and reports whether the boot survives, naming the failed loader entries |
adapt |
installation adaptation for a plugin the official gate rejects over incompatible @deepseek-ai/dsh* peer ranges: diagnoses the offending peers and classifies the risk (narrow bound versus cross-major / 0.x-minor), grants the official exact-version exemption in an isolated canary boot first, and writes the real profile only once that boot survives — a failed canary or install rolls the exemption back; for the desktop profile (which the official CLI refuses) it writes the exemption and points at the desktop Plugins page; --remove uninstalls the package and drops its exemptions in one step |
sessions |
session-container repair: scans $DSH_HOME/sessions for the two boot-blocking corruption classes (an artifact whose first frame cannot be decoded; a session directory that does not match its header id); --repair-paths moves a renamed directory back to its header id, --quarantine moves unreadable session directories into $DSH_HOME/cache/dsh-ops/quarantine (never deleted); read-only plan by default, deep event-level diagnostics stay with @argszero/cordis-plugin-session-audit |
dev |
development watcher for one plugin directory: static checks after every change (debounced, numbered, tagged with the package identity), --runtime also boots the package in an isolated DSH home after each clean pass and reports when it skips a dirty pass; a summary of checks/failures/elapsed prints on shutdown; never touches a running dsh |
Embedded bundle (dsh-plugin-ops-bundle) |
adds a "dsh-ops" health section to the dsh Web settings page (scan / rows / installation adaptation — exempt-install through the official pluginManager service, with the exemption list and revoke / uninstall-and-clean actions / timeline / chat with the RAG knowledge base); the host half shares the same engine and route whitelist as serve; chat prefers the official ctx.llm seam and falls back to a direct channel |
Exit codes: 0 ok (or dsh's own code) / 1 fatal findings remain / 2 usage or profile missing / 3 gate blocked by fatal findings / 4-5 gate attribution outcomes.
Configuration ($DSH_HOME/dsh-ops.yml)
rules:
registry-version:
enabled: false # disable a rule
peer-gap:
severity: info # severity can only be demoted
ignorePackages:
- some-noisy-plugin
Architecture and self-reliance
- Core logic lives outside the dsh plugin tree (a standalone wrapper process reading files): a crashing dsh does not affect diagnosis, and a failing diagnosis does not block dsh (fail-open applies only to dsh-ops' own faults).
- Self-contained builds: core and CLI ship as single files with every dependency inlined (zero runtime node_modules) — no dependency tree to drift; the in-tree bundle host half therefore carries no dependency-gap risk into the plugin tree.
- Engine messages are English-only (one fact source for CLI/JSON/panel); the panel UI is dictionary-driven zh/en. The
servepanel includes diagnosis chat (ModelChannel: explicitDSH_OPS_LLM_API_KEY/_BASE_URL/_MODELoverrides, or probing DEEPSEEK/ARK/DASHSCOPE/OPENAI keys from env,.env,.credentials.yaml; the embedded form prefers the officialctx.llmseam and falls back to a direct channel). - Writes are whitelisted, same-origin checked, and backed up; fault-injection tests assert temp-sandbox paths.
Permissions and data access
dsh-ops touches sensitive surfaces by design; here is exactly what, when, and under which guardrails. Nothing runs without an explicit user action.
| Surface | Access | Purpose | Guardrails |
|---|---|---|---|
| Profile files | package.json, pnpm-lock.yaml, node_modules metadata, patch YAML |
the diagnosis itself (check/scan) |
read-only; writes go only through the two whitelisted repair channels below |
| Patch layer | structured write of disabled rows into the profile's user cordis.patch.yml |
disable the plugin row that breaks boot | plan → confirm → backup → validated write; delete the row to revert; official @deepseek-ai/* rows are refused (403) |
| Session containers | read the $DSH_HOME/sessions tree; --repair-paths renames a session directory to its header id, --quarantine moves a session directory into the dsh-ops cache |
the sessions repair command |
explicit flags only; nothing is ever deleted; the read-only plan runs first and reports every move |
| Command execution | pnpm install --frozen-lockfile --force (fixed arguments); the dsh command passed to gate; session-audit when present |
realign drift; launch dsh after a passed gate; session-container pre-check | never arbitrary commands; only on explicit confirmation or the exact command the user typed |
| Local HTTP server | loopback 127.0.0.1:8912 (serve panel); the embedded bundle reuses dsh's own web server |
the web panel | same-origin checks, loopback only, route whitelist |
| LLM credentials | DSH_OPS_LLM_*, or provider keys from env / .env / .credentials.yaml |
the optional diagnosis chat only | read only when chat is used; every static feature works with no key at all |
| Network | pnpm outdated (opt-in via --updates); the configured LLM API |
update advisories; diagnosis chat | check/fix/gate and default scan are fully offline |
dsh-xray rates this project C3 (a capability-surface rating, not intent); the table above is its human-readable counterpart.
Roadmap
- Desktop adaptation (0.12.0). The official desktop app (0.2.0+) ships dsh inside its packaged
app.asarand has no CLI launch point.scan/fix/checkrecognize the desktop profile, read its release version, and trust the official bundles and rows the packaged runtime carries;gate --profile desktoppre-checks without booting and attributes the desktop crash report (crash-*.log). - Installation adaptation (0.13.0/0.14.0).
dsh-ops adaptand the in-panel adapt card complement the official gate's change-time refusal: diagnose why a plugin is rejected, classify the risk, grant the official exact-version exemption (the CLI behind an isolated canary boot; the panel in-app through the official plugin manager, which is also the only UI path on desktop), and clean the exemption up with removal. This is the first step from diagnostics toward a repair loop; small source-level fixes for real incompatibilities, presented with an explanation, remain a later direction. - Multi-surface test sandbox for plugin authors (planned). An isolated
DSH_HOMEplus a separate Electronuser-data-dirand a per-sandbox webserver port let the official desktop app run beside an already-running instance, so a plugin can be exercised on the web, CLI, and desktop surfaces without touching real data. Extendingverify --runtimewith a desktop runtime target and reporting a per-surface adaptation result is the planned follow-up. - Consistency verification for plugin authors.
dsh-ops verifyaccepts a local directory or an npm package spec and ships nine checks (bundle patch declaration/parse, patch-row resolution, dependency protocols, peer contracts, ESM entry and exports, client export contract and bundle shape, files completeness); false positives were triaged against 30 real ecosystem plugins (28 report zero findings).verify --runtimeboots the package in an isolated DSH home through the official install and launch commands and reports whether the boot survives. - Integrated plugin management (v2). Absorb the ecosystem's change-time protections (canary runs, enable/disable, update checks, market) into the startup-lifecycle guard, with the pre-boot gate as the single entry point.
Development
pnpm install && pnpm run build
pnpm run typecheck && pnpm run test # 205 tests (core 156 + bundle 25 + cli 24)
node packages/cli/lib/index.js selftest # engine self-check
node scripts/e2e/scan-fix.e2e.mjs # offline E2E (real pnpm repair)
node scripts/e2e/gate.e2e.mjs # gate scenarios (pass/block/bypass/attribution/headless)
node scripts/e2e/real-plugins.e2e.mjs # real third-party plugin sandbox (network)
Release: core, then cli, then bundle (order enforced by the CI release workflow).
Ecosystem positioning
Not another market or manager, but startup-lifecycle protection: it fills the every-boot gap that change-time protection leaves open. Later versions absorb market/enable-disable/update protection into the same architecture, converging into an integrated plugin-management suite.
Complementary surface: stored session containers are audited by @argszero/cordis-plugin-session-audit — a pre-boot audit for the $DSH_HOME/sessions tree with an exit code a launcher can gate on. gate points at it when a failed boot comes from the workspace registry instead of the plugin tree.
Platform support
Windows, macOS, and Linux (Node ^22.19 || >=24 — the same engines as dsh). CI runs build, typecheck, unit tests, and the offline e2e suite on all three platforms.
Feedback
- In the panels:
serveand the embedded bundle have a Feedback button that opens a pre-filled issue with your environment (version, surface, OS, profile, scan counts) — no manual diagnostic collection. - Plugin compatibility problem (a plugin fails to install or boot, or dsh-ops reports it as broken): open a compatibility issue with the
dsh-ops scan --jsonoutput. - dsh-ops itself misbehaving: open a bug report.
- Questions and general discussion: GitHub Discussions.
- Plugin author? Give your repository the publish gate: plugin-author CI —
dsh-ops verifyplus a boot smoke as a reusable workflow. - Real failure samples are welcome — they become selftest fixtures and knowledge-base entries.
References
- docs/architecture.md — interception, repair, and memory mechanics
- Upstream: https://github.com/deepseek-ai/deepseek-harness
- License: MIT (see LICENSE)