dsh-plugin-registry
August 24, 2026 · View on GitHub
A machine-readable catalog of DeepSeek Harness plugins, refreshed daily by GitHub Actions.
Clients fetch one static file — no API token, no rate limit:
https://raw.githubusercontent.com/XingLingQAQ/dsh-plugin-registry/main/catalog.json
schema.json defines the format; schemaVersion is bumped on any breaking change.
Why this exists
The dsh-plugin GitHub topic is heavily squatted. A search returns thousands of
repositories, most of which tag themselves for visibility and are not plugins at
all — resume builders, low-code platforms, RAG servers. Sorting by stars makes
this worse, not better.
The only reliable signal is the package manifest. A real DSH plugin declares a
dsh field: dsh.client plus an exports["./client"] subpath for the browser
half, dsh.bundle for the host half. So the search is treated as a candidate
list and every candidate is confirmed by reading its package.json before it
reaches the catalog.
Doing that here rather than in each client matters: the confirmation costs a few hundred requests per refresh, which no end-user application should spend, and the result is identical for everyone.
How a refresh works
- Search
topic:dsh-pluginacross two sort orders (stars, recently pushed) so both established and active plugins are covered, then de-duplicate. - Read each candidate's
package.jsonfromraw.githubusercontent.com, which does not draw on the API rate limit. - Keep the ones declaring a browser half, a host half, or both. Drop the rest —
repositories carrying a
dshfield for presets or skills are not installable as plugins. - Look up each confirmed plugin on npm and record its published tarball.
- Sort by stars, then id, so an unchanged upstream produces no diff. Commit only when the file actually changed.
Install from npm.tarball, not from tarball
This is the part that bites. Most of these plugins declare a client entry that is
a build output — ./lib/client.js, ./dist/client.js — listed in files and
shipped to npm, but gitignored in the repository. A GitHub source archive
therefore lands a package whose declared entry does not exist, and the plugin
silently fails to load.
npm.tarball contains exactly the files set, already built, so installing it
needs no toolchain on the target machine. Use it. tarball is kept for reference
and for the rare plugin that commits its built entry.
installable is false when a plugin was never published to npm. Those entries
are reported but cannot be installed without cloning and building by hand.
Fields worth knowing
clientisnullwhen a plugin has no UI. Only entries with aclientblock contribute anything to a browser surface.hostisnullwhen a plugin has no host half.client.entryis the path the module system fetches, taken verbatim fromexports["./client"].idis the package name, including any scope, and is also the directory name a client should install into.categoryis a content bucket (safety,manager,integration, ...), derived deterministically from the manifest's keywords, topics, and description byscripts/classify.mjs— not a hand label. The full enum and the matching rules live there.
Entries are reported as found. Presence in this catalog confirms that a repository declares itself a DSH plugin; it is not a review, an endorsement, or a security audit. Treat plugin code as you would any third-party dependency.
Running it locally
GITHUB_TOKEN=$(gh auth token) node scripts/build-catalog.mjs
Without a token the searches fall back to the unauthenticated limit (10 requests/minute), which is enough for one run.
Adding your plugin
Nothing to submit. Tag your repository with the dsh-plugin topic and make sure
package.json declares the halves your plugin provides — the next refresh picks
it up.