Skip to main content
All posts
Tutorial

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:

  1. Only flip allowBuilds: true for a package whose source you've actually looked at, or that comes from an author or organization you already trust.
  2. Always pair it with a commit pin. allowBuilds: true on an unpinned github:owner/repo means 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 prepare script. If the repo genuinely doesn't ship a lib/ directory and also has no prepare script 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/repo alone won't resolve to the right package.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.