- Início
- Plugins
- Desenvolvimento e ferramentas de plugins
- dsh-plugin-debugging
dsh-plugin-debugging
dsh-plugin-lab/dsh-plugin-debugging
Diagnóstico em tempo de execução dos plugins DSH: executar ao vivo, reiniciar ou recarregar a quente.
Instalar
dsh plugin --profile web add github:dsh-plugin-lab/dsh-plugin-debuggingREADME
dsh-plugin-debugging
Let your DSH agent inspect and fix its own runtime
让 DSH agent 自检自修它身处的运行时
Per-version changes → Releases
You changed something and it didn't take effect? In DSH, that usually means one of three things:
- Config: re-read on every change, so edits apply immediately. This presumes
hmris mounted inprofile; withouthmr, every change degrades to restart-required. - Host code: a process loads code once at startup, so edits need a restart.
- Front-end assets: the browser swaps assets by fingerprint, so edits need a hot reload or refresh.
This plugin lets the agent decide which case you're in, and what to do next.
What it does
After installation, the agent gains a set of tools and a skill document. The skill loads on demand; you invoke it with a slash command.
Tools
Read-only — they change nothing on the host.
| Tool | Arguments | What it does | Web | Desktop |
|---|---|---|---|---|
dsh_list_instances | port | List the DSH hosts running on this machine. A port counts as DSH only when an unauthenticated GET / returns the exact DSH body. "Could not probe" and "not DSH" are reported separately. | ✓ | ✓ |
dsh_check_auth | host, port | Tell "not running" apart from "not authenticated". | ✓ | ✓ |
dsh_diagnose_plugin_load | package, port, dshHome | Check whether a plugin actually loaded: bundle membership, mount form, loader tree, with observed evidence kept separate from inferred evidence. | ✓ | ✓ |
dsh_check_effect_mode | change: config / bundle-added / host-code / client-code, alreadyInDependencies, dshHome | Tell whether a change takes effect live, needs a restart, or needs a hot reload. It probes the running profile instead of guessing. | ✓ | ✗ |
dsh_dump_config | profile, dshHome | Show what a profile resolved to: the composed tree, plus the diagnostics that explain it. | ✓ | ✗ |
dsh_sign_cookie | host, port, maxAgeDays, dshHome | Sign a browser-session cookie so a script or CLI client can reach your own DSH instance. | ✓ | ✓ |
Changes state — the first two swap code or end the host you are debugging.
| Tool | Arguments | What it does | Web | Desktop |
|---|---|---|---|---|
dsh_hot_reload | exactly one of entryId / module / serverName, plus dryRun | Swap a mounted entry to the latest code on disk without restarting. Rolled back on failure. | ✓ | ✓ |
dsh_restart | reason, delayMs, dryRun, force | Restart this host when a change truly requires it. Off by default. | ✓ | ✗ |
Rows follow the order you would use them, so the two tables split on a single line: whether they change anything. The last column is availability by carrier; reasons live under Platform support.
Three common traps:
- A
401fromdsh_check_authdoes not mean the session expired. A request carrying nocookiealways gets401, so anauth probe's401only proves the service is running and wants authentication. To tell "the session is still valid" apart from "theauthorityis wrong", you must open thathost:portin a browser. An oldcookiekeeps working after a restart on the same port; only a changed port produces401. dsh_hot_reloadmay leak. Resources the framework does not track — atimerorsocket, for example — leak silently after a swap.dsh_restarthas its own section below.
The skill document behind it
The skill document lives at skills/dsh-plugin-debugging/SKILL.md and carries the full reasoning behind install forms, credential acquisition, process identification, and isolated instances.
The tools are accelerators; if a tool's output conflicts with the skill document, the skill document wins.
Install
Install from the Plugins page:
Open the Plugins page, click Add plugin in the upper-right corner, enter dsh-plugin-debugging, and install.
Install from npm:
dsh plugin --profile web add dsh-plugin-debugging
Install from source:
git clone https://github.com/dsh-plugin-lab/dsh-plugin-debugging.git
cd dsh-plugin-debugging
pnpm install && pnpm run build
dsh plugin --profile web add "$PWD"
Notes:
- Do not skip
pnpm install: with alink:install, dependencies come from the repository itself; skipping it makes the plugin show up as not running and reportERR_MODULE_NOT_FOUND. - Restart to take effect: restart
dsh --profile webafter installing. link:anddsh.bundleare two separate things:link:only decides whether editing source needs a reinstall; whether thepatchlayer applies depends on whether the package declaresdsh.bundle.
Requirements:
Node >= 20, and a DSH version that satisfies the range in package.json.
Maintenance rules:
The profile's dependency and bundle list are managed by dsh plugin add; do not edit them by hand. Do not create packages under $DSH_HOME, and do not run a package manager inside a profile directory.
Safety and boundaries
Except for dsh_restart, these tools never restart a process, never rewrite a profile, and never write to host data. Tests enforce this rule: as soon as any write targets a host-data path (profiles / sessions / storages / logs / cache / attachments / backups / integrations / mcp / settings.yaml / .credentials.yaml …), or uses DSH_HOME itself as the target, pnpm run test fails.
The only write exception is this plugin's own namespace, $DSH_HOME/<package name>/: only the first directory directly under $DSH_HOME must exactly match the package name; anything below that is unrestricted.
What each one touches:
- Read-only, no requests:
dsh_check_effect_mode,dsh_diagnose_plugin_load,dsh_dump_config. They only read files the instance already has, and they produce no credentials. - Read-only, sends HTTP:
dsh_check_authconnects to thehost:portyou name;dsh_list_instancesprobes loopback ports only. Neither sends credentials. - Touches the running module tree only:
dsh_hot_reload, and kills no process. - Reads the local signing key:
dsh_sign_cookie, to sign acookiefor your own instance. It sends no request, and thecookievalue is deliberately not returned. - Ends the host:
dsh_restart, the only irreversible action here.
dsh_restart
dsh_restart is the only irreversible action: it ends the host you are debugging. It is off by default, and running it means passing three gates:
- Four checks: whether it is in a restart loop, whether other sessions or jobs are busy, whether the
bundletable is readable, and whether the launch command can be determined.forceoverrides only the "sessions busy" gate; the other three cannot be bypassed. - A separate approval check: the approval policy is read first, and you are asked only when the policy is
ask.nevermeans prompts are disabled, so asking underneverwould be refused; the policy must be read before deciding whether to ask. - A separate check before writing
marker: this plugin's own namespace is outside the default file sandbox, so the write explicitly usesdanger-full-access.
All three results are written into the tool output. dryRun runs every gate but writes nothing.
[!IMPORTANT] Only on Windows, and only when the host was started as a Web process. In the Desktop app it refuses before writing anything: quit from the tray and start again.
What happens after a restart:
- The new host reads the
marker, wakes every session listed in it, and leaves one note in each. - That note is a recap, not a "please continue": when the restart was requested, how long the host was down, what became of the
marker. - The
reasonyou typed appears only in the session you started the restart from; other sessions get the same recap without it.
Platform support
Port-based process identification is designed to be cross-platform; only Windows has been measured on real hardware. Specifically:
- When no usable command is found: it reports "could not check", not "no listener". Those are opposite conclusions.
- Weaker fallbacks: they may find "someone is listening" without identifying the process; that is reported as unidentified, not as "no listener".
Everything else is platform-neutral. dsh_restart needs Windows and a host started as a Web process: in the Desktop app the host is a child of the Electron shell, and no plugin-facing channel can relaunch that shell. If you can try a real relaunch on Linux or macOS, tell us in #44 — that gap is exactly what the issue is for.
Configuration
Fields
These fields configure this plugin in the profile composition. enableRestart also has a switch on this plugin's card on the Plugins page.
| Field | Default | Meaning |
|---|---|---|
enableRestart | false | Whether dsh_restart is allowed to run. Takes effect immediately, with no host restart. |
dshHome | $DSH_HOME, otherwise <home>/.dsh | Where the instance keeps profiles, logs, and credentials. |
profile | $DSH_PROFILE, otherwise the default profile | Which profile the tools inspect. |
port | 0 | Host port to probe; 0 means find the listening port automatically. |
timeoutMs | 60000 | Timeout budget for quick work: reading a file, running one command, or one HTTP probe. |
schemaDumpTimeoutMs | 240000 | Timeout budget for running --dump-config-schema (measured 10.2–15.7 s; 32 s under load). |
How those two budgets are derived, and why the transport layer has to expire before the host's tool deadline → docs/ARCHITECTURE.md §5.1.
Debugging another instance
When you need it: you are debugging one instance, but the evidence is on another — a second profile, or another DSH_HOME.
Which tools take dshHome: dsh_dump_config, dsh_check_effect_mode, dsh_diagnose_plugin_load, dsh_sign_cookie. Both path resolution and the spawned dsh subprocess use the home you pass in, and the output says which one was actually read (dshHomeSource: tool-argument). A value passed as an argument is never silently reported as the configured default.
Which do not, and why:
dsh_check_auth: it answers about ahost:port's authentication state, and already hashost/port.dsh_list_instances: it only does discovery, and all it can give is ahost:port.dsh_hot_reload: it swaps modules in the current process's memory, which cannot cross to another instance.dsh_restart: it kills the host it runs in, so there is no "other instance" it could be aimed at.
One trap: discovery tools can only give a host:port, and nothing maps that to a corresponding DSH_HOME; so you must supply dshHome yourself. Accordingly, dsh_diagnose_plugin_load splits its answer in two: disk evidence comes from the home you passed in, and the loader tree half reflects the current process only.
License
MIT.
Contributing
Bugs and requests go to the repository Issues.
Maintainer's document map → AGENTS.md.
Plugins relacionados
deepseek-harness
deepseek-ai/deepseek-harness
dsh-web (dsh-plugin-manager)
zhu1090093659/dsh-web
dsh-market
dsh-market/dsh-market
dsh-web
zhu1090093659/dsh-web