DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-why

i

dsh-why

Discovered

dsh (DeepSeek Harness) failure diagnostics CLI — why a plugin crashes the loader (missed the module table), engines.dsh mismatch, known official breaking points, ecosystem cross-check. Zero-dep, read-

Machine translated

dsh-why

site DSH Insights health npm license: MIT

Why did my dsh (DeepSeek Harness) break? A zero-dependency, read-only CLI that diagnoses plugin load failures: what you have installed, what crashes (or will crash) the loader, why, and how to fix it — cross-checked against the ecosystem-wide observed-compatibility matrix at dsh-insights.com.

npx dsh-why            # diagnose the current environment
npx dsh-why --json     # machine-readable (CI / paste to an LLM)
npx dsh-why --offline  # zero network, bundled rule base only

# holding a red-screen error? paste it straight in:
pbpaste | npx dsh-why                    # piped stdin is auto-detected
npx dsh-why --error "…missed the module table…"
npx dsh-why --prompt   # append a paste-ready fix prompt for your AI agent

Node ≥ 18, no install required (npx), zero npm dependencies, and it never modifies any file on your machine. Output language follows your locale (中文/English), override with --lang zh|en.

There is also a web version at dsh-why.com: paste the red-screen error into a browser and get the same diagnosis with nothing installed — it runs the same rule base client-side and never uploads what you paste.

What it tells you

  • Environment summary — dsh version, shell (module-table) version, DSH_HOME, profile, plugin count, and which row model the verdicts rest on. "No dsh installation found" is a valid answer, not an error.
  • Crash-level findings (R1) — a plugin whose client bundle requires a module the current shell's module table doesn't provide, unguarded (the try/catch-aware check: requires covered by a paired try/catch don't crash — the loader resolves require() at call time). For each missing module: when official dsh removed it, or added it, or never shipped it — derived from the published shell history, not guesswork.
  • Graph-row aware, four-way verdicts — the loader resolves require() via seed words → materialized modules → registered factories: every mounted dsh.client package registers a factory under its package name when its combo batch executes. dsh-why reads those rows from your local install (mounted set = the in-box bundles' cordis.patch.yml roster ∩ every dsh.client package) and classifies each require as:
    • resolvable (seed word / immediate row / a lazy row the plugin declares in dsh.client.external+inject),
    • conditional — warning: an undeclared lazy row; it usually resolves by batch timing, and declaring it makes it deterministic. Never a red card, never in the issue template.
    • missing — error: nothing in this install can answer it (the crash class),
    • unclassified — warning: your install tree was unreadable, so the row branch could not be checked at all. The report says so loudly and tells you how to settle it — a tool must never turn its own blind spot into a crash verdict. Conditional and unclassified both stay out of the exit code; summary.conditional / summary.unclassified in --json tell them apart for CI. Comments/strings and bundle-local relative requires are never misread as missing modules.
  • Version-range warnings (R2) — the plugin's engines.dsh doesn't cover your dsh.
  • Profile integrity (R6) — a plugin declared in the manifest but missing from node_modules crashes dsh at boot (the classic "uninstalled a plugin and now it won't start"); half-uninstalled leftovers on disk get a warning. pnpm symlinks are followed, never misflagged.
  • Pasted-error mode (--error / piped stdin) — parses the loader's actual error text (failed to import loader entry …, require("…") missed the module table, bundle script … failed to load, cannot resolve "…", bare Failed to load plugins → full diagnosis) and diagnoses the referenced plugin/module even when it is NOT installed locally. Unknown patterns get an honest "not recognized" plus the supported list.
  • AI fix prompt (--prompt) — appends a paste-ready prompt for your coding agent: environment + findings + known fixes + the seed-safe constraint (only module-table requires, or try/catch).
  • Upgrade hints (R3) — a newer release exists on npm; upgrading first is often the whole fix.
  • Ecosystem cross-check (R4/R5) — the plugin's measured verdict on dsh-insights.com (ok / never / broken-since / supported-since), plus "you are not alone: N plugins ecosystem-wide miss the same module."
  • Community crash corpus — when a crash-level finding's signature matches the crash-corpus (aggregated opt-in --share reports), the output says how often the exact crash was seen and when last; --share adds yours. Signatures that so far have only cold-start seed rows (machine-measured, never user reports) are labelled as a known crash pattern instead — the corpus never dresses seeds up as user reports. And a crash not in the corpus gets a nudge to --share it, so the next person sees a number instead of nothing (offline / corpus unreachable: no line at all).
  • A copy-ready GitHub issue template for the plugin author, with your environment and the diagnosis pre-filled.
  • A green "all clear" when everything loads fine.

Sample output

✗ [ERROR·R1] fake-crash-plugin crashes the loader on this dsh
  Symptom: "Failed to load plugins" / require("@deepseek-ai/dsh-client-runtime/client")
  missed the module table — the client bundle requires module(s) the shell does not provide:
    - @deepseek-ai/dsh-client-runtime/client: never shipped in ANY published shell's
      module table — the plugin was written against a module that does not exist in dsh
  How to fix (pick one):
    1. remove the plugin to get dsh booting again: dsh plugin remove fake-crash-plugin
    2. report it to the plugin author — a copy-ready issue template is attached below

Hitting one of these errors? This is what they mean

Failed to load plugins

The red screen when dsh web boots. One of your enabled plugins' client bundles threw while the loader was materializing it — almost always a missing module (next section). Run npx dsh-why: it names the plugin, the missing module, when official dsh changed the module table, and your fix options (upgrade the plugin / upgrade or downgrade dsh / remove the plugin).

client-modules: require("...") missed the module table

dsh's web shell doesn't let plugin client bundles require() arbitrary npm packages — it resolves requires against a module table baked into the shell build (react, @deepseek-ai/cordis, @deepseek-ai/dsh-client-store, …) plus the registered client factories of your other installed plugins. Anything else throws this error at call time.

Known official breaking points (dsh-why derives these live from the shell history):

dsh releasemodule-table change
0.1.0-rc.8removed @deepseek-ai/dsh-client-web-react, @deepseek-ai/dsh-client-ui-attachment, @deepseek-ai/dsh-client-schema-form
0.1.2-alpha.2added @deepseek-ai/dsh-client-store
0.1.5-alpha.1added @deepseek-ai/dsh-client-ui-dockkit
(never)@deepseek-ai/dsh-client-runtime/* was never in any published shell's module table

So the same plugin can load on one dsh and crash on another. npx dsh-why tells you which side of the line you're on — and whether the plugin author can fix it (guard the require with try/catch, which the loader's call-time resolution makes safe) or you just need a newer/older dsh.

client-modules: bundle script failed

The plugin's client bundle itself failed to execute or parse in the loader — a build-level problem rather than a module-table miss. dsh-why still helps: it confirms whether the plugin's requires are satisfiable, whether its engines.dsh covers your dsh, whether the ecosystem matrix measured the same failure, and whether a newer plugin release exists.

client-modules: cannot resolve "..."

The async import() twin of "missed the module table" — the specifier isn't a seed word, not materialized, and not in the boot graph. Same diagnosis applies.

Red screen after upgrading dsh

Almost always a 0.1.0-rc.8-style removal: your plugin was written against a module the new shell no longer provides. Options: dsh plugin remove <name> to get booting, downgrade dsh to the last shell that had the module (dsh-why names the exact version), or upgrade the plugin if the author already adapted. When dsh-why reports "only added to the module table in dsh X", it's the opposite direction — your dsh is too old for the plugin; upgrade dsh.


How it works (and why you can trust it)

  1. Collects (read-only): your global dsh install (@deepseek-ai/dsh + the @deepseek-ai/dsh-web-frontend shell build under the global npm root) including its client graph rows (every dsh.client package, intersected with the in-box bundles' cordis.patch.yml roster — immediate vs lazy from each package's own flag), your DSH_HOME (default ~/.dsh) profile manifest — the same seam dsh plugin add operates on — and each enabled plugin's client bundle.
  2. Scans each bundle's literal require("…") set with a guard-aware scanner (brace-matched try{…}catch{…} pairing that skips strings/templates/comments/regex literals) — the exact code that powers the dsh-insights.com observed-compat matrix, so your local diagnosis agrees with the published ecosystem data.
  3. Checks the rule base: R1 module-table misses with per-module history, R2 engines.dsh coverage, R3 npm upgrades, R4/R5 ecosystem cross-check against the live matrix (2,300+ plugins observed), R6 profile integrity — plus known fixes from the fixes.json case base. The case base ships as a bundled snapshot too, so the concrete recipe ("migrate to @deepseek-ai/dsh-client-store", "declare dsh.client.external") survives on a machine with no network; the report labels which side it came from. Recipes and case notes are bilingual (fix/fixEn, note/noteEn) — --lang picks, and a missing translation falls back to the Chinese source rather than printing nothing.
  4. Degrades gracefully: --offline (or an unreachable network) falls back to the bundled shell-history and known-fix snapshots plus the local rule base; an unreadable install tree declassifies its own verdicts to unclassified warnings instead of inventing crashes. The env block always states which row model ran (shell graph rows: 9 immediate + 37 lazy / scan-only / UNREADABLE) — the model is part of the answer. A diagnostic tool must never itself crash, and it must never be more confident than its inputs.

Privacy: online mode makes exactly three kinds of GET requests — dsh-insights.com data files and npm registry latest metadata for your installed plugin names. Nothing about your machine is ever uploaded; nothing is written to disk.

CLI reference

dsh-why [--json] [--offline] [--profile <name>] [--dsh-home <path>]
        [--lang zh|en] [--no-color] [--version] [--help]
flagmeaning
--jsonmachine-readable report (findings carry structured fields; includes issueTemplate)
--offlinezero network — bundled shell-history snapshot + local rules
--profile <name>which profile to diagnose (default: web, or the only one present)
--package <dir>plugin-author self-check: diagnose one plugin directory's client bundle (a pre-publish gate)
--error [text]parse a pasted error text instead of scanning the profile (reads stdin when the value is omitted; piped stdin is auto-detected)
--promptappend a paste-ready fix prompt for an AI coding agent
--shareopt-in: report crash-level findings to the ecosystem case base (api.dsh-why.com). The exact payload is printed before sending — structured fields only (rule id / signature hash / shell & plugin versions), never messages, paths or prompts
--dsh-home <path>override DSH_HOME (env DSH_HOME is honored too)
--lang zh|enoutput language (default: from LC_ALL/LANG)
--no-colordisable ANSI colors (NO_COLOR env respected)

Exit codes: 0 = no crash-level findings · 1 = crash-level findings (usable as a CI gate) · 3 = the check could not be performed · 2 = usage error or an internal bug (please report).

3 is what a pre-publish gate returns when it read nothing: --package pointed at a path with no package.json, or at a checkout whose declared client bundle was never built. A gate that passes when it verified nothing is worse than no gate, so it is deliberately not 0. Any non-zero must block the release:

npx dsh-why --package . && npm publish

Environment overrides for unusual setups: DSH_WHY_NPM_ROOT (where the global npm packages live), DSH_WHY_PROFILE (profile name).

dsh-why run — when dsh boots fine but a run dies

The startup check answers "why won't dsh start". dsh-why run answers the other one: the run is over, you have a symptom, and nothing told you why. It reads your own session logs — read-only, no model, no upload.

dsh-why run                # attribute your latest session's turns
dsh-why run --all          # health view: scan every session
dsh-why run --json         # same object the text renderer consumes

The verdict comes from turn/end.reason, and it is a closed vocabulary — across a real corpus every failure carried one of eight codes, so the whole observed failure space is enumerable rather than open-ended:

verdictmeaning
completedfine
aborted (stopped by you)not a failure — a deliberate stop is never a red card
error (attributed)backed by an error.code and the provider's own words
unclassifiedinterrupted, or the run never finished: said plainly, never guessed

--all adds the part a single run cannot show: your own baseline failure rate, the failure mix, and an incident list for days that differ from that baseline — which is how chronic noise (an API call that fails 1–12×/day for weeks) is told apart from a real event (a model switch that broke the key, at 57% for one day).

Two honesty notes it will always print rather than hide:

  • Session logs are a chain of independent zstd frames, and frames overlap. A naive single-frame read returns the first event and silently drops the rest, so the report states how many frames were decoded and whether events paired up.
  • If a log is truncated or a turn was interrupted, you get UNCLASSIFIED and an explicit "I will not guess" — an unfinished run is not evidence of a broken plugin.

Exit codes: 0 = no failed run in scope (unclassified and self-aborted turns do not gate) · 1 = a failed run in scope (so run --all is usable as a CI gate for "no failed turns in this window") · 2 = usage error.

For plugin authors

  • Guard optional host modules: try { require("@deepseek-ai/dsh-client-store") } catch { /* fallback */ } — the loader resolves require() at call time, so a paired catch turns a crash into a graceful degradation. dsh-why reports guarded misses as notes, never as crashes.
  • Declare engines.dsh in package.json and keep it honest.
  • Pre-publish gate in CI: npx dsh-why --package . — diagnoses the plugin directory's built client bundle against the real shell module table. Exit 1 when a require would crash the loader, exit 3 when the check could not be performed at all (unbuilt checkout, no manifest). --json for a machine-readable report. → Set it up in 30 seconds

Related

License

MIT © ice5kysl

Comments

Loading…

Similar plugins

dsh-harbor

by ZSeven-W

DeepSeek Harness (DSH) plugin: a read-only ledger for the plugins you already have installed — a capability inventory with file:line evidence, declared-vs-detected reconciliation, cross-profile versio

Security & AuditManifest valid

★ 24

↓ 58/wk

MIT

JavaScript

Oct 7, 2026

dsh plugin --profile web add @zseven-w/dsh-harbor

by peterwangze

DSH (DeepSeek Harness) plugin: unified default reasoning level (thinking effort) for all models — per-model defaults with capability probing, live call statistics, one-command install via dsh plugin

Manifest valid

★ 3

JavaScript

Sep 12, 2026

dsh plugin --profile web add dsh-reasoning-level

by d86e

dsh-doctor: self-healing watchdog for the DeepSeek Harness web profile. Recovers from plugin-induced boot failures within 60s, runs an unbounded CLI doctor, captures every tool error, and watches all

Tools & CapabilitiesDevelopment & InfrastructureManifest valid

★ 4

MIT

TypeScript

Sep 8, 2026

dsh plugin --profile web add @d86e/dsh-doctor

by YV3507

DSH (DeepSeek Harness) Host plugin: a configured forbidden plugin - loaded, enabled, or about to be installed - crashes the Host process on the spot, with a crash report. Inspired by the Minecraft For

Manifest valid

★ 0

MIT

JavaScript

Sep 28, 2026

dsh plugin --profile web add dsh-plugin-allcrash

by gezi-wen

DSH plugin that ships a skill for diagnosing and repairing a broken DeepSeek Harness install: boot failures, dead plugins, broken dependency bridges, upgrades.

Development & InfrastructureManifest valid

★ 0

MIT

JavaScript

Sep 13, 2026

dsh plugin --profile web add dsh-repair

Diagnoses and fixes "duplicate loader entry id" boot crashes - finds duplicate loader rows across profile bundles and converts them into id-targeted patches via a zero-dependency CLI (detect / preview

Tools & CapabilitiesManifest valid

★ 0

dsh plugin --profile web add dsh-fix-duplicate-loader-id