Plugin markets
Summary
A plugin market is one JSON index file that lists installable DSH bundles with their titles, icons, authors, and versions. Turn on the experimental Custom plugin markets bundle to browse markets in a Discover tab on the Plugins page and install a listed version after a confirmation. To publish a market, write or generate an index file and serve it, together with its icon files, from any static host.
Table of Contents
- Turn on Discover
- Browse and install
- Publish an index
- Generate an index with the reference generator
- Index format reference
- Further Exploration
Turn on Discover
Open Plugins, select More beside Experimental plugins, find Custom plugin markets, and switch it on. A Discover tab appears next to Installed, and Creator mode gains the read-only plugin_market tool. Switching the bundle off removes both again.
DSH ships no index source. Select Discover, choose Add index source, and enter the URL of an index file. A URL must use http: or https: and must not contain a user name, password, or # fragment. Anyone on the network path can change an http: index, including the install specs it lists, so use https: for a market reached over a network you do not control. Each source belongs to the current profile.
Browse and install
The market menu at the left of the toolbar switches between sources and opens Manage index sources…, where each source shows its last error. Search matches names, authors, keywords, and titles, descriptions, categories, and labels in every language, and tolerates typos; results come in best-match order until you choose another. The Labels menu, category pills, and Sort menu use the categories, labels, and sort keys that the market declares, and Publish date sorts by each plugin's latest version.
Each card shows the plugin's recommended version: the highest version compatible with the running DSH that is not a prerelease, or the highest compatible prerelease when the plugin lists no version without a prerelease tag. Install opens a confirmation with that version's source: the npm package and registry, or the Git repository, commit, and directory. Confirming starts the normal plugin installation, including its compatibility and registry checks; nothing is installed without that confirmation.
Select a card to open its page. The Versions list shows every listed version with its compatibility and offers Install for any version DSH accepts, including older releases and prereleases. A card that shows Installed, Update available, or Provided by DSH opens the installed bundle instead.
Markets are third-party content. A market chooses each plugin's title, description, icon, author, and source; DSH checks the file format but not those claims. Add only sources you trust, and check the source in the confirmation before installing.
Publish an index
An index is a UTF-8 JSON file, at most 128 MiB by default, served with a 2xx status and without redirects. Put it on any static host, for example GitLab Pages, GitHub Pages, or an object store behind https.
Icons can be inline or separate files. An inline icon is a base64 data: URL in the index; it needs no extra request but makes the index larger. A separate icon is a URL. A relative icon resolves against the index URL, the way an image in a web page resolves against the page: for an index at https://market.example/dsh/index.json, "icon": "icons/foo.svg" loads https://market.example/dsh/icons/foo.svg. Publishing the index and an icons/ directory side by side therefore works on any host without editing the file. An absolute icon URL on another origin (scheme, host, and port) must use https:.
This is a minimal index with one npm plugin and one plugin from a Git monorepo:
{
"format": 1,
"title": { "en": "Team plugins", "zh": "团队插件" },
"plugins": [
{
"name": "dsh-plugin-foo",
"title": "Foo",
"description": "Adds the foo tool",
"icon": "icons/foo.svg",
"author": "Jane Doe",
"homepage": "https://github.com/jane/dsh-plugin-foo#readme",
"repository": { "url": "https://github.com/jane/dsh-plugin-foo" },
"versions": [
{ "version": "1.1.0", "publishTimestamp": 1790476800, "source": { "type": "npm" }, "engines": { "dsh": ">=0.2.0-rc.2" } },
{ "version": "1.0.0", "publishTimestamp": 1788000000, "source": { "type": "npm" } }
]
},
{
"name": "@team/dsh-bar",
"versions": [
{
"version": "0.3.0",
"publishTimestamp": 1789000000,
"source": {
"type": "git",
"url": "https://gitlab.example.com/team/dsh-plugins",
"commit": "3f9c2e1d8a4b6c0e7f1a2b3c4d5e6f708192a3b4",
"path": "packages/bar"
}
}
]
}
]
}DSH rejects the whole index when any rule below is violated and shows the reason, with the JSON path of the offending value, under the source in Manage index sources….
Generate an index with the reference generator
The repository includes a reference generator that builds an index from a plain list. Write one npm package name or https Git repository URL per line; blank lines and lines starting with # are ignored:
@team/dsh-foo
https://gitlab.example.com/team/dsh-pluginsRun it from a DSH checkout:
pnpm --filter @deepseek-ai/dsh-plugin-market-generator start --input plugins.txt --output site/index.json --title "Team plugins"For an npm package, the index lists every version that is not deprecated and declares dsh.bundle. For a Git repository, it finds the bundle packages on the default branch and lists their versions at vX.Y.Z, X.Y.Z, and <name>@X.Y.Z tags, plus each package's version on the default branch. Titles, descriptions, icons, authors, and homepages come from each plugin's highest version. Paths are relative to the directory where you run pnpm.
The generator only downloads and reads files; it never installs packages or runs their code. It keeps a cache in .plugin-market-cache next to the list, so a repeated run downloads only new versions and commits. Publish the output directory, index.json together with its icons/ directory, as described above.
Index format reference
Text fields marked LocalizedText are a string or an object of strings keyed by lowercase language ids, such as { "en": "Foo", "zh": "甲" }; an object must contain en. Members DSH does not know are ignored.
| Index field | Required | Meaning |
|---|---|---|
format | yes | 1. |
title, description | title only | Market name and description, LocalizedText. |
metadata.categories, metadata.labels | no | Objects mapping an id to { "title": LocalizedText }. |
metadata.sortKeys | no | Object mapping an id to { "title": LocalizedText, "order": "asc" | "desc" }; order is the initial direction. |
plugins | yes | Plugins in the market's default order. |
| Plugin field | Required | Meaning |
|---|---|---|
name | yes | npm package name, unique in the index. |
title, description | no | LocalizedText; the card shows name without a title. |
icon | no | Inline data: URL (SVG, PNG, JPEG, or WebP, at most 32 KiB) or URL, as described above. |
author | no | Display text. |
homepage | no | Absolute https: or http: URL of a page about the plugin; the plugin page links it. |
repository | no | { "url": string, "directory"?: string }: the source repository's web page, and the package directory inside it. The plugin page links it as Source code. |
metadata.category | no | One declared category id. |
metadata.labels | no | Declared label ids. |
metadata.sortKeys | no | Object mapping declared sort-key ids to numbers, such as downloads or ratings. |
versions | yes | At least one version, in any order. |
| Version field | Required | Meaning |
|---|---|---|
version | yes | Exact SemVer version, unique within the plugin. |
publishTimestamp | yes | Publish time in Unix seconds. |
source | yes | { "type": "npm", "registry"?: url }, or { "type": "git", "url": https-url, "commit": 40-hex-sha, "path"?: directory }. |
engines.dsh | no | SemVer range of DSH versions this version runs on; absent means any. |
DSH installs an npm version as name@version, asking registry first when present, and a Git version as git+<url>.git#<commit> with &path:/<path> for a package in a subdirectory. engines.dsh should match the package's own engines.dsh, which DSH checks again at installation; a package without one is checked against its @deepseek-ai/dsh* peer dependencies instead. The format note defines every rule.
Further Exploration
- Discover tab reference describes the tab's controls and states.
- Plugin market service covers fetch limits, caching, and the
plugin_markettool. - Index validator is the library generators can use to check an index before publishing it.
Dev Note
None.