DeepSeek Harness plugin

dsh-toolbelt

Eight DeepSeek Harness plugins: persona, language guard, vision fallback, python workdir guard, windows encoding guard, cross-agent memory, image generation, and skill shell injection.

Jump to install

Source facts

Repository
cking000bigdemon/dsh-toolbelt
Latest update
Aug 13, 2026
Category
Memory
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/cking000bigdemon/dsh-toolbelt
Plugin: dsh-toolbelt
Author: cking000bigdemon

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.en.mdSource · read only
README language

dsh-toolbelt

English | 中文

Eight DeepSeek Harness plugins that fill gaps the harness does not cover on its own: a general-purpose persona, a reply-language guard, a per-request vision fallback, two write/exec guards, a cross-agent memory bridge, image-generation tools, and shell-command substitution inside skills.

Every plugin is an independent Cordis plugin with its own entry point, its own typed Config, and its own tests. Mount only what you want.

> Built against @deepseek-ai/dsh@0.1.0-rc.6. The harness is in developer preview and will make breaking changes.

Install

From a local checkout. Build it firstdsh plugin add <path> links the directory and never runs your build, so an unbuilt checkout fails the whole plugin tree at boot with loader entries failed to apply:

git clone https://github.com/cking000bigdemon/dsh-toolbelt
cd dsh-toolbelt && npm install && npm run build && cd ..
dsh plugin --profile <name> add ./dsh-toolbelt

Directly from GitHub — this takes two attempts, by design. A git install fetches source, not build output, so this package builds itself through its prepare script, and pnpm ≥10 refuses to run that until you authorize it:

dsh plugin --profile <name> add github:cking000bigdemon/dsh-toolbelt
# ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED — copy the exact key pnpm prints into
# $DSH_HOME/profiles/<name>/pnpm-workspace.yaml:
#
#   allowBuilds:
#     dsh-toolbelt@https://codeload.github.com/...: true
#
# then run the same command again.

Authorizing a build means this package's code runs on your machine at install time, outside any agent sandbox. Pin a commit (github:cking000bigdemon/dsh-toolbelt#<sha>) so a later push cannot silently change what runs.

Then confirm the layer composed:

dsh --profile <name> --dump-config    # look for "# == dsh-toolbelt"

Safe by default

Only vision-fallback is enabled on install. It is the one row that cannot surprise you: it does nothing until you send an image to a model that cannot read images.

The other seven change the agent's persona, block tool calls, read files outside the workspace, or execute shell commands. Enable each deliberately in your profile's cordis.patch.yml:

- id: language-guard
  disabled: false
  config:
    targetLanguage: zh

A patch replaces a row's whole config value rather than deep-merging, so restate every key you need.

The plugins

PluginExtension pointWhat it does
vision-fallbackagent/requestA request carrying an image, on a model without image input, is served by an image-capable model for that request only.
general-agent-promptctx.systemPrompt.section()Eight persona/discipline sections replacing the coding-assistant identity. Each is true / false / a replacement string.
language-guardllm/stream + agent/turn-stoppingDetects non-target-language drift while the reply streams; steers a correction at the turn boundary.
python-workdir-guardtools/pre-executeDenies shell calls reaching for a global Python or pip instead of the project venv, with a model-actionable reason.
windows-encoding-guardfs/write-intent, fs/edit-intentBlocks writes of PowerShell/Python files carrying Windows encoding traps; warns on four softer ones.
cross-agent-memoryctx.systemPrompt.context()Injects Claude Code / Codex memory files as explicitly untrusted context.
image-generationctx.tools.register()generate_image_gpt and generate_image_gemini; returns a saved path, never base64.
skill-shell-injectionctx.skills.registerProvider()Runs ` !cmd and `` `! ``` blocks inside a SKILL.md before the content reaches the model.

Each plugin's source file opens with a doc comment covering its design, its config, and its limitations. Read that before enabling.

Notes worth knowing before you enable something

  • vision-fallback holds zero mutable state. Switching the model globally and restoring it afterwards is the obvious implementation and it is wrong: the image stays in durable history, so the next request goes to a blind model anyway. agent/request replaces the frozen call config for one request, which is both simpler and correct.
  • general-agent-prompt's runtime section deliberately ships no built-in text. Only a deployment knows what it bundles, and a wrong claim ("Python is bundled") is worse than no claim, so that section materializes only when you pass a string.
  • windows-encoding-guard guards non-Windows hosts by default. The hazard belongs to the destination interpreter, so a .ps1 authored on Linux is still dangerous. It also surfaces a dsh-specific hazard: dsh-fs-local decodes with a BOM-stripping TextDecoder, so an existing UTF-8 BOM never survives an edit.
  • cross-agent-memory reads files from your home directory and puts third-party content in front of the model. It is framed as untrusted data and XML-escaped so no closing tag is representable, and {{…}} runs are neutralized so memory content cannot interpolate prompt variables. There is no isProjectTrusted() equivalent in dsh — the trustProject flag is yours to wire to a real trust signal.
  • skill-shell-injection executes commands found in files. It only does so under trusted skill roots, memoizes per session so a side-effecting command runs once, and never rescans command output. SkillRegistry exposes no way to intercept an already-registered provider, so this registers its own provider and decorates a provider instance handed to it via config.

Development

npm install
npm test          # 342 tests
npm run typecheck
npm run build

Tests use the harness's own @deepseek-ai/dsh-agent-loop-testkit and stub adapters. They make zero network calls and write only under os.tmpdir().

Status and limitations

  • image-generation has never been exercised against a live provider — no image-generation credential was available during development. Request building and both response shapes are covered by tests against a stubbed fetchImpl; real size/n acceptance and provider error envelopes are unconfirmed.
  • language-guard keeps its correction state in memory, so it resets on resume; it registers no slash commands.
  • python-workdir-guard allows python -c '<program>' and does not resolve variable indirection such as P=pip; $P install x.
  • Several plugins reach optional seams (shell, credentials, subprocess, attachments, workspace) structurally through ctx.get() rather than inject, so they degrade to a no-op when a deployment omits them. Declaring those packages as dependencies would let them use the real types instead.

License

[MIT](LICENSE)