Installing DeepSeek Harness Plugins from GitHub
How dsh plugin add github:owner/repo works: source vs build output, the allowBuilds prompt pnpm 10+ enforces, commit pinning, and fixing a failed build.
Most DeepSeek Harness plugins right now live as GitHub repositories rather than published npm packages — this is a young, fast-moving ecosystem, and not every author has set up an npm release yet. Installing one is dsh plugin --profile <name> add github:owner/repo, but that command pulls down source code, not build output, which means you'll likely hit a permission prompt the first time you install a TypeScript-based plugin this way. Here's exactly what that prompt means and how to handle it safely.
The command
dsh plugin --profile web add github:owner/repo
You can also target a specific ref instead of the default branch:
dsh plugin --profile web add github:owner/repo#a1b2c3d
This works because dsh plugin add is a thin forwarding layer over pnpm add — anything pnpm's git dependency resolution supports, dsh supports. The #a1b2c3d suffix pins to an exact commit SHA (you can also use a branch or tag name, but a commit SHA is what actually locks the code).
Why GitHub installs are different from npm installs
An npm-published plugin ships prebuilt output — you install it, and it's ready to run. A GitHub-sourced plugin, by contrast, gives pnpm the repository's source code. If the plugin is written in TypeScript and the repo doesn't check in a compiled lib/ directory, that source code needs to be built before dsh can load it.
Plugin authors handle this with a prepare script in package.json — a hook pnpm runs automatically after a git-sourced package is fetched, intended to compile the source into the output dsh actually loads.
The allowBuilds prompt
Here's the part that trips people up: pnpm 10 and later blocks prepare scripts on git dependencies by default. The first time you add a GitHub-sourced plugin that needs a build step, the install fails, and pnpm tells you to explicitly allow it in the profile's pnpm-workspace.yaml:
allowBuilds:
dsh-hello-plugin: true
This isn't a bug or a misconfiguration — it's pnpm's default security posture working as intended, and dsh doesn't override it. The dsh documentation is direct about what you're actually agreeing to when you add that line:
Treat that allowance as what it is: permission to execute the package's code on your machine at install time, outside any sandbox the agent runs under. Only allow packages whose source you trust, and pin a commit.
That's worth reading twice. allowBuilds: true runs arbitrary code from that package during pnpm install, on your machine, before dsh's own runtime sandboxing (read-only, workspace-write, or danger-full-access — covered in our permissions and sandbox guide) has any chance to apply. A malicious prepare script isn't constrained by anything the agent itself is constrained by; it just runs as your user, like any other npm install-time script would.
Two practical rules follow from that:
- Only flip
allowBuilds: truefor a package whose source you've actually looked at, or that comes from an author or organization you already trust. - Always pair it with a commit pin.
allowBuilds: trueon an unpinnedgithub:owner/repomeans that a future push to that branch changes what code runs on your machine the next time you reinstall or update — without you approving anything new.
If you'd rather avoid the prompt entirely
Prefer plugins published to npm with prebuilt output when one is available. No prepare script runs, no allowBuilds decision to make, and installation is generally faster since there's no compile step. This is also the path the dsh docs describe as officially recommended for plugin authors — publish to npm rather than relying on git installs.
If a plugin you want is only distributed via GitHub, check its README for install instructions before you add it; well-maintained plugins usually document whether they need allowBuilds and give you the exact YAML block to paste in.
When the build still fails after allowing it
Granting the build permission doesn't guarantee the build succeeds. A few things to check if add still fails after you've allowed builds:
- Missing
preparescript. If the repo genuinely doesn't ship alib/directory and also has nopreparescript to generate one, the install will succeed but the plugin will fail to load with a "cannot find module" style error the next time you start the profile. This is an authoring gap in the plugin itself, not something you can fix on the install side. - Build tooling mismatch. Some repos assume a build environment (a specific Node version, a monorepo build orchestrator) that doesn't match what runs during a plain
pnpm add. This shows up as the build step itself throwing an error, not a permission block. - Wrong repo path in a monorepo. If the plugin lives in a subdirectory of a larger repo rather than at the repo root,
github:owner/repoalone won't resolve to the rightpackage.json. Check the plugin's own install instructions for the correct specifier format.
For a broader troubleshooting reference covering pnpm-not-found and missing-lib/ scenarios specifically, see DeepSeek Harness plugin install errors and fixes.
A safer default workflow
Putting the pieces together, here's a reasonable sequence for installing any plugin you found via GitHub rather than npm:
# 1. Read the repo first — package.json, cordis.patch.yml, and the plugin's entry point
# (see our plugin security checklist for what specifically to look for)
# 2. Install pinned to a commit you've reviewed
dsh plugin --profile web add github:owner/repo#a1b2c3d
# 3. If prompted, allow the build only for that specific package
# (edit pnpm-workspace.yaml in the profile directory)
# 4. Confirm what actually got activated
dsh --profile web --dump-config
Step 4 matters more than it looks — it's the only way to confirm the plugin's config patch actually applied the way you expected, and it's covered in more depth in our guide to updating and removing plugins.
FAQ
Do all GitHub-sourced plugins trigger the allowBuilds prompt?
No — only plugins that need a build step (typically TypeScript source without a checked-in lib/ directory) and declare a prepare script. A plugin distributed as plain JavaScript with no build step won't trigger it.
Is allowBuilds a dsh-specific mechanism?
No, it's a pnpm 10+ feature. dsh doesn't add or modify this behavior — dsh plugin add is forwarding directly to pnpm, so pnpm's own default protections apply exactly as they would for any other git dependency.
Can I pin to a tag or branch instead of a commit SHA?
Syntactically yes — github:owner/repo#main or github:owner/repo#v1.2.0 both work. But only a commit SHA is immutable. A branch name can move, and even a tag can technically be force-moved by the repo owner, so a commit SHA is the only pin that guarantees you're running the exact code you reviewed.
Where do I edit pnpm-workspace.yaml to add the allowBuilds entry?
It's in the profile's own directory ($DSH_HOME/profiles/<name>/pnpm-workspace.yaml), not a global dsh setting. Each profile manages its own allow-list independently.
What if the plugin I want doesn't have a GitHub install path documented?
Check the plugin's package.json for a dsh field to confirm it's a real dsh plugin at all — see our guide on how to find DeepSeek Harness plugins — then use the standard github:owner/repo specifier against its repository URL.
Next steps
Once the plugin is installed, see how to update and remove DeepSeek Harness plugins for ongoing maintenance. If something goes wrong during install, our install errors and fixes guide and the broader troubleshooting reference cover the most common failure modes. Before installing anything from an author you don't already trust, walk through the plugin security checklist.