Back to home@huyang218

dsh-plugins

No description

Stars
1
Language
JavaScript
Created
Aug 18, 2026
Updated
Aug 18, 2026
GitHub repo

Introduction

dsh-plugins

Plugins for DeepSeek Harness — the "everything is a plugin" agent runtime built on Cordis.

License: MIT Build-free ESM Tests: node:test

English · 中文


Every package here is an installable dsh bundle: pure ESM, no build step, so it runs from npm, from git, or straight from a checkout while you edit it.

Plugins

Three kinds, told apart by dsh.category in each package — what a plugin extends decides where it can be seen from:

GroupVisible toWhat it extendsGuide
tools/…the modelcapabilities it can call, described in the system promptauthoring tools
runtime/…nobodywaterfall wrappers and shared services around the harness itselfauthoring runtime
ui/…the personweb client extensions — result cards, keyboard-driven surfacesauthoring ui

The second half of the category is the domain: tools/finance and ui/finance cover A-share market data, information feeds and portfolio state; tools/vision reaches a multimodal model on behalf of a text-only one; runtime/provider, runtime/observability, runtime/reliability and runtime/llm cover shared credentials, measurement, retries and gateway compatibility; runtime/im drives sessions from a chat app; ui/productivity covers the web client's own ergonomics.

Pick what you need

tools/ — capabilities the model can call

PluginWhat it doesPackage
astockA-share quotes, K-lines, indicators, whole-market screening, financials, money flow, convertible bonds — free, a few tools need a Tushare tokendsh-plugin-astock
visionLets a text-only agent call a multimodal model mid-task — Qwen, Kimi, OpenAI, Claude or Gemini — and get back structured evidence rather than prosedsh-plugin-vision
ainfoA-share news, broker research, earnings pre-announcements, dividends, insider trades, shareholders — needs a Tushare tokendsh-plugin-ainfo
aportfolioHoldings and watchlist that survive the session, priced live, with profit, weights and target hitsdsh-plugin-aportfolio

runtime/ — behaviour around the harness, invisible to the model

PluginWhat it doesPackage
imCommand the agent from a chat app on your phone — Lark, WeCom, DingTalk or QQ drive a real turn and the reply comes back; allowlist denies by defaultdsh-plugin-im
tushareShared Tushare Pro access: one token, one quota gate, one calendar, failures an agent can act ondsh-plugin-tushare
tool-healthRemembers which tools keep failing and warns the next session before it startsdsh-plugin-tool-health
tool-usageCounts calls, duration percentiles and failures per tool, with an optional budget warningdsh-plugin-tool-usage
tool-retryRetries transient failures — socket resets, rate limits, timeouts — for tools an operator declares repeatabledsh-plugin-tool-retry
gateway-compatKeeps a finished reply from failing when a gateway ends its SSE stream without [DONE]dsh-plugin-gateway-compat

ui/ — web client extensions

PluginWhat it doesPackage
astock-chartDraws astock_data as a candlestick chart with volume, in the reply — needs native or both presentationdsh-plugin-astock-chart
shortcutsKeyboard shortcuts for the web client: 34 features, every binding recordabledsh-plugin-shortcuts

Each plugin's own README, in English and 中文, is the accurate account of what it does and what it costs to run. Install any of them by package name:

dsh plugin --profile web add dsh-plugin-astock

Looking for something this repo does not ship? CATALOG.md lists plugins maintained elsewhere, by category.

[!NOTE] Finance plugins share one credential through the tushare provider rather than each asking for the same token. Every tool that needs it says so in its own description, so the model can choose a free tool when one will do — and tell you exactly what is missing when one will not.

Install

Into a dsh profile, from npm:

dsh plugin --profile web add dsh-plugin-astock

Or from a checkout — also how you develop against a running profile, since the install is a symlink and edits take effect on the next service restart:

dsh plugin --profile web add ./packages/astock

Verify it landed in the composed tree before starting anything:

dsh --profile web --dump-config      # look for the plugin's row

Configure

A plugin that exposes a Schemastery Config is configurable without touching a command line: a desktop shell renders the form at install time. The values end up as an id-targeted override in the profile's cordis.patch.yml, which you can also write by hand:

- id: astock
  config:
    tushareToken: 'your-token'

[!IMPORTANT] Later layers win per row, and a patch replaces a row's whole config rather than merging keys — so restate every key you need when overriding someone else's row.

Tool presentation — whether a session dispatches tools natively, through Code Mode, or both — is chosen once per agent preset and applies to every tool in the session, not per plugin. Some plugins here require a particular mode, and the choice affects every other plugin you install: tool presentation modes.

Develop

npm install                                        # root; resolves peer deps for every package
npm test                                           # every package
npm test -w dsh-plugin-astock                      # one package
node --test packages/astock/test/*.test.js   # one file

Tests use Node's built-in runner (node:test) — no test dependencies, no build, matching the way the plugins themselves load. They exercise the real published entry (lib/index.js) and the real defineTool, so a schema violation fails in unit tests instead of at dsh startup.

[!TIP] Green tests are not the whole bar — they never touch the Loader or a real composition.

CLAUDE.md carries the full working spec — plugin lifecycle, config, tool authoring, waterfall extension points, bundle layering, the test convention, and the verification checklist to run after changing a plugin. It is addressed to AI coding agents, but the rules are the same ones a human contributor needs.

Contributing

  1. Read the guide for what you are building: tools (capabilities the model calls), runtime (waterfall wrappers and shared services) or ui (web client extensions).
  2. Create packages/<name>/ with package.json (including dsh.category), cordis.patch.yml, lib/index.js, README.md and LICENSE.
  3. Export name / inject / apply as named exports. A default export makes the loader drop inject, and the plugin then fails in a way that looks like something else entirely.
  4. Add test/plugin.test.js covering the export shape and every registration.
  5. Run npm test and the checklist in CLAUDE.md.

Four names travel together and are easy to confuse:

WhereValuePurpose
package.json namedsh-plugin-astocknpm package
lib/index.js exported nameastockloader diagnostics — short, no prefix
cordis.patch.yml idastockrow id in the composed tree; config overrides target it
cordis.patch.yml namedsh-plugin-astockreferenced by package name, never a path

License

MIT — see LICENSE.