dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
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-only, offline-capable. 失败诊断 CLI,零依赖只读离线可用。
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.
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.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:
dsh.client.external+inject),summary.conditional / summary.unclassified in --json tell them apart for CI. Comments/strings and bundle-local relative requires are never misread as missing modules.engines.dsh doesn't cover your dsh.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.--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.--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).ok / never / broken-since / supported-since), plus "you are not alone: N plugins ecosystem-wide miss the same module."--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).✗ [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
Failed to load pluginsThe 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 tabledsh'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 release | module-table change |
|---|---|
0.1.0-rc.8 | removed @deepseek-ai/dsh-client-web-react, @deepseek-ai/dsh-client-ui-attachment, @deepseek-ai/dsh-client-schema-form |
0.1.2-alpha.2 | added @deepseek-ai/dsh-client-store |
0.1.5-alpha.1 | added @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 failedThe 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.
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.
@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.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.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.--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.
dsh-why [--json] [--offline] [--profile <name>] [--dsh-home <path>]
[--lang zh|en] [--no-color] [--version] [--help]
| flag | meaning |
|---|---|
--json | machine-readable report (findings carry structured fields; includes issueTemplate) |
--offline | zero 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) |
--prompt | append a paste-ready fix prompt for an AI coding agent |
--share | opt-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|en | output language (default: from LC_ALL/LANG) |
--no-color | disable 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 diesThe 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:
| verdict | meaning |
|---|---|
completed | fine |
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 |
unclassified | interrupted, 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:
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.
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.engines.dsh in package.json and keep it honest.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/data/compat-observed.json.MIT © ice5kysl