DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

duxingxiake3 /

duxingxiake3/dsh-plugin-market

Verified

Plugin Market for DeepSeek Harness: discover, vet and install DSH plugins from inside DSH.

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@ce4dbd00

Plugin Market

Plugin Market adds a Market page to DeepSeek Harness: it discovers DSH plugins from the npm registry and GitHub, shows what each one does, screenshots where the author provides them, and reviews a plugin with a model before anything is installed.

Open it from either entry:

  • the Plugin Market icon in the sidebar (next to the shipped Plugins button)
  • Settings → Built-in plugins → Market tab

Once a plugin is installed, the shipped Plugins page owns it — enabling, configuring and removing all happen there, and the Market links you straight to it.

The Market list

A plugin detail page The pre-install risk review

Install

From DSH itself. Open Plugins → Add plugin, enter the package name, and approve it:

dsh-plugin-market

Or point straight at the repository, which works before any npm release:

github:OWNER/dsh-plugin-market

Manually, by adding two entries to your profile's package.json:

{
  "dsh": { "profile": { "bundles": ["…", "dsh-plugin-market"] } },
  "dependencies": { "dsh-plugin-market": "link:/path/to/dsh-plugin-market" }
}

then reinstall the profile's dependencies and restart DSH.

The host half is loaded at startup, so a restart is required; the browser half reloads on its own while DSH is running.


For plugin authors

You do not have to do anything for your plugin to appear in the Market. It is discovered from the dsh-plugin keyword on npm and from GitHub, and the Market falls back to your README.md for screenshots and to your package.json for the name and description.

Everything below is optional. It is how you make your listing accurate — the correct logo, a description that says what the plugin actually does, and screenshots of the real UI.

Create one folder: dsh-market/

Put everything the Market shows into a single folder at the root of your repository:

your-plugin/
├─ package.json          ← point "icon" at the logo inside the folder
├─ README.md
└─ dsh-market/
   ├─ market.json        ← the description, developer and screenshot list
   ├─ logo.svg           ← your logo
   └─ screenshots/
      ├─ dashboard.png
      └─ settings.png

One folder keeps your repository root clean, and deleting it removes your listing metadata in one step. A root-level dsh-market.json also still works if you prefer a single file; if both exist, dsh-market/market.json wins.

Where each thing goes

Three things describe your plugin, and each is declared in a different place. This table is the whole convention; the sections below give the rules for each one.

What the reader sees You put it in Declared by
The long description, developer line, homepage, licence dsh-market/market.json the description, developer, homepage, license fields
The one-line summary under the title dsh-market/market.json summary
Screenshots of your UI dsh-market/screenshots/ the screenshots[].url list in market.json
Your logo dsh-market/logo.svg icon in package.json (optionally logo in market.json)

A worked example: this plugin's own folder

This repository is listed in the Market by the same convention it documents. Its own dsh-market/ folder is the reference — copy its shape:

dsh-plugin-market/
├─ package.json                  "icon": "./dsh-market/logo.svg"
└─ dsh-market/
   ├─ market.json                displayName, developer, logo, summary, description,
   │                             screenshots[] with per-language captions, license
   ├─ logo.svg                   the logo, referenced by package.json `icon`
   └─ screenshots/
      ├─ market-list.png
      ├─ market-detail.png
      └─ risk-review.png

Nothing outside this folder is needed for the listing, and deleting the folder removes the whole thing without touching the plugin.

Relative paths: two rules, and they differ

This is the one thing that trips people up, so it is worth reading twice. A path in package.json is resolved as a file inside your package; a path in market.json is resolved as a file in your repository. The same logo therefore needs two spellings:

Field Resolved as Write
package.json → icon a file on disk, relative to package.json ./dsh-market/logo.svg
market.json → logo a repository path, appended to raw.githubusercontent.com/<owner>/<repo>/<branch>/ dsh-market/logo.svg
market.json → screenshots[].url the same repository path dsh-market/screenshots/dashboard.png

A descriptor path may also be a full https:// URL on an allowed host (raw.githubusercontent.com, user-images.githubusercontent.com, objects.githubusercontent.com, avatars.githubusercontent.com); any other host is refused, because rendering it would reveal every reader's IP address to that server. Package-relative paths such as ./dsh-market/logo.svg do not work as repository paths — the leading ./ is stripped, so the resulting URL 404s and the logo silently falls back to the letter tile.

1. The logo

The logo is declared through icon, the standard manifest field. The shipped Plugins page reads it too, so one declaration serves both surfaces:

{
  "icon": "./dsh-market/logo.svg"
}
Rule Value
Formats .svg, .png, .jpg, .jpeg, .webp
Maximum size 256 KiB
Location must resolve inside your package directory
Shape square, drawn to a 36×36 canvas — it is rendered at 36px inside a 48px tile

If you would rather keep the manifest untouched, put "logo": "dsh-market/logo.svg" in market.json instead. It overrides icon for the Market only — the shipped Plugins page still reads icon, so with that arrangement the two pages can show different logos.

The shipped icons are solid filled paths with a userSpaceOnUse linear gradient, and the glyph fills roughly 50–58% of the canvas. An outline drawing with a thin stroke looks visibly lighter than everything around it. If you want yours to sit naturally in the list, copy one of the icons out of the DSH installation and match its construction.

2. dsh-market/market.json

Every field is optional, and every text field accepts either a plain string or a per-language object ({"zh": "…", "en": "…"}). Omitted fields fall back to your package.json and README.md.

{
  "schemaVersion": 1,
  "displayName": { "zh": "上下文面板", "en": "Context Panel" },
  "developer": { "name": "Your Name", "url": "https://github.com/you" },
  "summary": {
    "zh": "在会话里查看上下文占用与工具调用细节。",
    "en": "Inspect context usage and tool-call detail inside a session."
  },
  "description": {
    "zh": "较长的一段介绍,显示在详情页的正文位置。",
    "en": "The longer introduction, shown as the detail page body."
  },
  "homepage": "https://example.com",
  "license": "MIT",
  "screenshots": [
    { "url": "dsh-market/screenshots/dashboard.png", "caption": { "zh": "主面板", "en": "Dashboard" } },
    { "url": "dsh-market/screenshots/settings.png", "caption": { "zh": "设置页", "en": "Settings" } }
  ]
}
Field Effect
displayName the title on the card and detail page (default: your package name)
developer.name / developer.url the developer line (default: package.json author, then the repo owner)
summary the one or two lines shown under the title
description the long text on the detail page
homepage, license metadata rows on the detail page
screenshots[].url repository-relative path, or an absolute URL on an allowed host
screenshots[].caption the caption under the image and in the full-screen viewer
logo optional; a repository-relative path or allowed URL — overrides the package.json icon for the Market only

3. Screenshots

Point url at a file in your repository. A path relative to the repository root is easiest, and note the spelling: no leading ./, because the path is appended to the repository's raw URL rather than resolved against your package:

"screenshots": [
  { "url": "dsh-market/screenshots/dashboard.png", "caption": { "zh": "主面板", "en": "Dashboard" } },
  { "url": "dsh-market/screenshots/settings.png",  "caption": { "zh": "设置页", "en": "Settings" } }
]

Listed screenshots win over anything found in your README, and they keep the order you give them. A caption is optional but worth adding: it is shown under the image and in the full-screen viewer, and it is the only text a reader sees next to the picture.

If you ship no descriptor at all, the Market reads the images you already embedded in your README.md, in markdown or HTML form, and uses those. Keeping the best screenshots near the top of the README helps, because earlier images rank higher.

What the Market checks before showing an image:

Rule Why
Host must be raw.githubusercontent.com, user-images.githubusercontent.com, objects.githubusercontent.com or avatars.githubusercontent.com, over https Showing an image hosted elsewhere would reveal every reader's IP address to that server
The file must actually decode as PNG, JPEG, GIF, WebP or SVG A URL that returns 200 is not proof of a picture — error pages and tracking pixels do too
Shortest edge ≥ 240px, longest ≤ 5000px, at most 6 MiB Keeps out icons, banners and dead weight
At most 6 images are shown A listing is a summary, not a gallery
Badges, logos, QR codes, group-chat posters and social-preview cards are filtered out by name They are never a picture of the UI

In the README path an .svg is only considered when its file name or alt text names a UI surface (preview-en.svg yes, logo-en.svg and architecture.svg no), because a vector next to a README is usually a logo or a diagram.

Screenshots open in a full-screen viewer: click one to enlarge, and again to switch between fit-to-window and actual size.

4. Language

Write your summary and description in the language you are comfortable with. When the reader's language differs, the Market translates it once with a model and caches the result, keyed by the text — so editing your description is what triggers a new translation, and nothing else does. The translated line is always labelled as machine-translated, and your original stays available in the tooltip.

You can supply the translation yourself instead, per field, which always wins:

"summary": { "zh": "……", "en": "……" }

Your README.md is shown as written and is never machine-translated.


Configuration

Variable Effect
DSH_MARKET_GITHUB_TOKEN GitHub token used for search. Without it, GitHub search is limited to 10 requests per minute (unauthenticated). GITHUB_TOKEN and GH_TOKEN are also read.
DSH_MARKET_CACHE_DIR Where the translation cache is written. Defaults to <DSH_HOME>/cache/dsh-market.

Privacy and safety

  • Every request is authenticated. The page reaches the plugin through an exact route on the /api channel, which the connection layer wraps in its Host/Origin fence and browser-cookie authentication. An unauthenticated request is answered 401.
  • Images are loaded from the code host only, so viewing a listing does not announce the reader to a third party. Images are rendered with referrerPolicy="no-referrer".
  • Nothing installs without a review. Clicking install runs a deterministic rule scan plus a model review over the plugin's manifest and entry code, shows the findings, and requires an explicit confirmation. The confirmation is a single-use ticket issued by the review, so the check cannot be skipped by calling the route directly.
  • Third-party code is treated as untrusted data. A review never follows instructions found inside a plugin's source, and a plugin claiming to be safe does not lower its own result.
  • Build scripts are never auto-approved. When pnpm blocks postinstall and friends, the names are shown and you approve them explicitly or not at all.
  • Translations are cached locally and never sent anywhere except the configured model.

Licence

MIT.

—/ 5

No ratings yet

Verified DSH bundle

Commit ce4dbd00917b

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout