Building the DeepSeek Harness plugin ecosystem: 42 open-source plugins in a 46-repo family, 45 of them PerryLink-owned — security, workflows, research, messaging bridges, developer experience — plus the DSH Desktop Market catalog, a plugin-certification registry and the dsh-plugin-doctor CI checker. All 42 ship CI and a Gitee mirror, five-language docs held to the same section count, install command and configuration keys by a gate in each repo's own CI, and the dsh.bundle contract; 137,423 npm downloads over the trailing 30 days. I also contribute upstream to Cordis — the plugin-core framework DeepSeek Harness is built on — and to deepseek-ai projects, including a merged FlashMLA fix.
DeepSeek Harness turned "everything is a plugin" into an ecosystem. I build the plugins I wish existed — engineering-discipline guardrails, runtime panels, cross-session memory, and verifiable research engines — and publish them the way production software deserves.
-
The research this family rests on is now a published paper with a DOI — and it is, in large part, a measurement of two things on this profile: laya-mcp — the installable sidecar and MCP server that serves Laya's typed decisions — and jevcore. When a Judgment Layer's Self-Reported Fields Lie: Cost, Latency and the Failure Boundary of Three Judgment Layers on the Same Items — three judgment layers measured on one item set: Laya (local, non-autoregressive), TypeSafe Jev (remote, typed decisions) and DeepSeek-V4.1-Flash. Four claims; three hold and one the data refutes. A complete Chinese translation is archived separately, and the artifact — code and every
results/JSON — is a third record. -
What it found, in one line each. Cost is not the binding constraint: the real axes are latency and the usable state window, and "an order of magnitude cheaper" stops holding once state grows. The judges' self-reported access-layer fields are not trustworthy, and their failures cluster in one place — the concrete ones being a truncation flag that reports
passedwhile silently dropping input, a probability field that inverts an item's conclusion, and two verdict words that are unreachable under real input. The shape behind them: the judge is near-perfect (0.9909, n=220) where the answer is explicitly stated and collapses (0.3091, n=220) where it must notice an absence — while its self-reported confidence stays high in both cases. -
The negative result is reported as one. A dissimilar judge does not supply incremental coverage in any of the three regimes: when the generator errs the judge is less accurate than its own marginal, and the failure correlation is positive in 3/3 draws. The paper also reports four instances of the error class it names — a specification-level defect masquerading as a finding about the model — each caught by a control and not by review, which is where its 23 mandatory protocol clauses come from.
-
Both language versions say they are one work, in their own pages. Zenodo has no
is translation ofrelation, so the fact is carried in each PDF's front matter and in the record descriptions instead. 10.5281/zenodo.22901853 · 10.5281/zenodo.22902025 — cite one, not both; where they differ, the English text governs. -
Fifteen pull requests of mine are now in laya's default branch — fourteen of them merged on 2026-09-23, eight of those within 84 seconds (13:22:52Z–13:24:16Z): #237, #236, #232, #231, #230, #228, #227 and #212. The earlier four are #94, #169, #210 and #211. #222 and #234 were the two still open when this was first written; both landed at 13:43Z the same day once rebased, and #249 followed at 01:44Z on 09-24 — so not one was closed unmerged — every pull request I opened there landed.
-
The batch is a spread, not one theme, which is the part worth keeping: the project's first Windows CI lane (#212 — 15 of the 16 Linux suites now run on
windows-latest, the sixteenth skipped with its reason recorded in the workflow rather than quietly dropped, and the requiredtests (pyX.Y)check names untouched), a suite for the load-time and budget errors no test reached (#237), three assertions that could not fail (#231), an ECE that binned differently from its own siblings (#232), inference moved off the event loop (#230), non-ASCII characters surviving non-string instructions (#228), and a disclaimer heuristic that read the word "confidential" as one (#227). #169 and #210 came out of my own issues #93 and #35, both closed by the maintainer as fixed by merged work; the maintainer's note on #210 is the one worth keeping — "it is better for having been written by someone outside the project." -
And a fifth elsewhere: a process that could not start at all now starts, in a repo governed by the same org as one already on this page. claude-agent-acp #1146 fixes issue #1124 —
src/index.tsawaitedresolveSettingsat module scope with nothing around it, so a transientEINTR/EMFILE/EAGAINwhile reading the managed-policy tier rejected a top-level await in an ESM entry point, aborted module evaluation, and exited the process before it served a single ACP message; the client saw only exit 1 and silence. The two neighbours that make it the only call able to do this are both still true onmain:SettingsManager.loadAllSettingswraps the same SDK call intry/catch, and theunhandledRejectionhandler is registered after the await, so it never covers it. The fix extracts the tier read intosrc/managed-policy.ts— for one reason, that an ESM entry point with top-level side effects cannot be imported by a test — and adds four regression tests, the decisive one asserting the promise resolves with the target env untouched.testswent from17 failed | 1366 passedto17 failed | 1370 passed. The 17 pre-existing failures are recorded as untouched and explicitly not claimed either way.
The six most-starred family plugins (★ measured 2026-09-22); every other family repo is listed in full further down, and the research four-piece set is under Research.
| Plugin | What it gives you | Install |
|---|---|---|
| dsh-auto-review | Second-model auto-review on the approval chain, fail-closed by default (193★) | dsh plugin --profile web add dsh-auto-review |
| dsh-research-report | Verifiable research reports: content-addressed evidence ledger, manifest seal hash, byte-level citation checks, drift detection, disproof ledger (152★) | dsh plugin --profile web add dsh-research-report |
| dsh-industry-research | Industry/company research: chain-map SVG with bottleneck detection, timeline, company cards, adversarial review (150★) | dsh plugin --profile web add dsh-industry-research |
| dsh-permission-rules | Claude Code-style declarative allow/deny/ask rules plus a process-level network policy (114★) | dsh plugin --profile web add dsh-permission-rules |
| dsh-memento | Approval-gated cross-session memory (ctx.memory + SQLite) (108★) |
dsh plugin --profile web add dsh-memento |
| dsh-mcp-panel | MCP management console: /mcp + Settings tab + trial calls (65★) |
dsh plugin --profile web add dsh-mcp-panel |
One-command starter pack: dsh-kit — installs the core family in one command.
Counting note: "42 plugins" is the figure the family's own READMEs and this page's heading both carry, because it counts every repo that declares dsh.bundle.patch. Measured against all 46 repos this page names: 39 of the 41 plugin rows declare the contract, and 3 of the 5 support repos do — dsh-plugin-kit (a review-rule meta package), dsh-cert-mcp (a certification MCP server) and dsh-plugin-doctor (the CI health checker); dsh-catalog and dsh-kit ship none. 39 + 3 = the family's 42. The two plugin rows outside that arithmetic are the sibling project line jevcore (no dsh.bundle; only its jevcore-dsh workspace member is a plugin) and the third-party pan17/dsh-wechat. Both counts therefore describe the same 45 PerryLink-owned repos.
| Plugin | One-liner | npm |
|---|---|---|
| dsh-defend | Injection/jailbreak/secret detection + destructive-delete gate | npm |
| dsh-permission-rules | Declarative allow/deny/ask rules + a local HTTP/CONNECT network policy | npm |
| dsh-mask | PII masking/sanitization | npm |
| dsh-skill-pack-security | Security-audit skill pack + supply-chain gate | npm |
| Plugin | One-liner | npm |
|---|---|---|
| dsh-background-agents | Durable background child agents with a Web UI sidebar, messaging and interrupt | npm |
| dsh-team-rooms | Cross-session team rooms: shared message bus, task board, approval-gated handoffs and a timeline that survive restarts | npm |
| dsh-checkpoint-rewind | Snapshots, forks, one-shot restore | npm |
| dsh-github | GitHub PR/issue integration + Action, writes approval-gated | npm |
| dsh-claude-move | Migrate Claude Code/Codex/OpenCode/Hermes into DSH | npm |
| dsh-click | Desktop control tools (Windows/macOS) | npm |
| dsh-session-sync | Git-backed session synchronization | npm |
| dsh-test-drive | Install→smoke→uninstall test driver for plugins | npm |
| Plugin | One-liner | npm |
|---|---|---|
| dsh-composer-history | Terminal-style input history for the web composer | npm |
| dsh-output-styles | Runtime-switchable model output styles | npm |
| dsh-session-pin | Pin sessions in the Web sidebar | npm |
| dsh-memento | Approval-gated cross-session memory protocol | npm |
| Plugin | One-liner | npm |
|---|---|---|
| dsh-auto-review | Second-model auto-review on the approval chain | npm |
| dsh-doublecheck | Engineering-discipline guard: grill, gates, adversary review | npm |
| dsh-score | Plugin quality scoring across git/gh/npm | npm |
| Plugin | One-liner | npm |
|---|---|---|
| dsh-autotier | Automatic strong/cheap model-tier routing with deterministic risk guards | npm |
| dsh-budget | Token/cost metering, budget caps, carbon estimate, latency benchmarks | npm |
| dsh-observe | OTel/Langfuse telemetry export | npm |
| dsh-fast | Performance diagnostics | npm |
| Plugin | One-liner | npm |
|---|---|---|
| dsh-draw | Image-generation routing | npm |
| dsh-translate | Translation + JSON repair | npm |
| dsh-talk | Speech recognition and voice I/O | npm |
| dsh-library | Local knowledge-base RAG | npm |
| dsh-local-ai | Ollama LLM provider and routing | npm |
| Plugin | One-liner | npm |
|---|---|---|
| dsh-lsp-actions | LSP diagnostics/formatting/completion/actions | npm |
| dsh-mcp-panel | MCP management console | npm |
| dsh-plugin-guide | Plugin-dev knowledge base + CLI toolchain + release-engineering guide | npm |
| dsh-plugin-upgrade | Plugin-author upgrade skill: one package, one corridor index that detects the caller's peer band and routes to the matching closed card (0.1.3-alpha.1 → 0.1.5-rc.1, 0.1.5-rc.2 → 0.1.6-alpha.2), plus a zero-dependency seam scanner (bundle skill + npx CLI) |
npm |
| jevcore | TypeSafe Jev as typed decisions instead of prose (noul/choice/score with calibrated probabilities): offline by default, every transmission named before it happens, disabled gates register nothing (the DSH adapter jevcore-dsh, plus jevcore core and jevcore-mcp for non-DSH MCP hosts) |
npm |
| dsh-laya | Laya typed decisions (noul/choice/score) as a first-class Cordis service (ctx.laya) plus laya_ask/laya_plan tools; a client of a laya-mcp serve sidecar, so it installs and downloads nothing, and reports whether state stays on this machine as a fact rather than a policy |
npm |
Support repos: dsh-plugin-kit (review-rule meta package) · dsh-catalog (DSH Desktop Market catalog source) · dsh-cert-mcp (certification MCP server) · dsh-kit (one-command installer) · dsh-plugin-doctor (plugin health checker). Five repos publish under a @perrylink/ npm name rather than their repo name — the support repos @perrylink/dsh-plugin-kit and @perrylink/dsh-plugin-doctor, and the plugins @perrylink/dsh-github, @perrylink/dsh-ticktick and @perrylink/dsh-skill-pack-security-provider — so the perrylink npm account holds 53 names while the family has 42 plugin repos.
| Plugin | One-liner | npm |
|---|---|---|
| dsh-wechat | WeChat ↔ DSH bridge (Tencent iLink bot): text/image/file/voice, approvals in chat — developed with pan17, who now hosts the repo and publishes the npm package | npm |
| dsh-ticktick | TickTick/Dida365 task bridge: session-header panel + 11 tools | npm |
| dsh-reach | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console | npm |
| Plugin | One-liner | npm |
|---|---|---|
| dsh-data-quality | Data profiling/cleaning/verification | npm |
| dsh-fund-research | Mutual-fund research, sealed traceable snapshots | npm |
| dsh-industry-research | Industry/company research domain pack | npm |
| dsh-research-report | Verifiable research-report engine | npm |
Every repo below is external to PerryLink/*; every number is measured, merged work only, and open proposals are deliberately not listed. The third column names the project's owner — the account alone does not say whether that is a company, a standards body or one person.
★ 1,000+ — named individually, as the rule requires, each carrying the party that owns the project. Fifteen external repos above a thousand stars carry merged work. Five of those rows belong to a major company or a well-known organization — Tencent, DeepSeek, cordiverse, and the ACP project that Zed and JetBrains jointly govern, which now accounts for two of the fifteen; the other ten are catalog repos, small community orgs and one-person projects, and the column says so rather than letting the account name imply a company:
| Repository | ★ | 项目归属方 |
|---|---|---|
| reactive-resume | 43,354 | reactive-resume org — independent open-source project (rxresu.me) |
| awesome-dsh-plugin | 16,705 | awesome-dsh-plugin org — community catalog, no company behind it |
| laya | 18,713 | NandhaKishorM — individual maintainer |
| FlashMLA | 12,952 | DeepSeek — the official deepseek-ai org |
| Cordis | 8,770 | cordiverse org; its maintainer Shigma is now at DeepSeek, and Cordis is the kernel DeepSeek Harness vendors as @deepseek-ai/cordis |
| dsh-web | 7,950 | zhu1090093659 — individual maintainer |
| ouroboros | 6,076 | Q00 — individual maintainer (@zep-us) |
| teamai-cli | 4,939 | 腾讯 Tencent — the official Tencent org, opensource.tencent.com |
| agent-client-protocol | 4,309 | agentclientprotocol org — governed jointly by Zed Industries and JetBrains |
| claude-agent-acp | 2,565 | agentclientprotocol org — the same jointly-governed org as the row above, a separate repository |
| deepseek-harness-desktop | 2,535 | dsh-tauri community org — self-described non-official and non-commercial, not a DeepSeek repo |
| dsh-plugin-radar | 1,466 | AdamPlatin123 — individual maintainer, catalog is a generated artifact |
| Agents-Anywhere | 1,161 | anywhere-labs community org — 3 public repos, created 2026-05, dshdesktop.cn; not a company |
| awesome-deepseek-harness | 1,096 | 0xsline — individual maintainer, community catalog |
| awesome-vibecoded-saas | 1,021 | Anil Chandra Naidu Matcha — individual maintainer, community catalog |
Cordis is the upstream plugin-core framework that powers DeepSeek Harness — vendored into that repo and renamed @deepseek-ai/cordis; FlashMLA #224 is the only merged pull request in the whole deepseek-ai org.
The rest of the contributor set is the community catalog layer rather than upstream projects: 21 further repositories, DSH plugin directories and small community projects (dsh-handbook among them) — the catalogs ingest the family and carry no company owner, so they are named here only in aggregate. 36 external repositories have carried a merged pull request of ours, and 297 merges outside PerryLink/* were counted across them — re-derived 2026-09-23 from every merged pull request of this account, so 297 is exact rather than a floor over a probed subset. Ten of those 36 merged the work under the maintainer's own authorship, so they carry no commit attributed to this account on their default branch; by the rule above they do not size the set, which is 26. SihanTeng's list is the largest of the ten at 32 merges, and is the case that rule was written about.
laya — NandhaKishorM/laya — 15 merged pull requests, every one this account opened there, and the most of any outside contributor — second only to the maintainer, who commits to main directly rather than through pull requests. The next outside contributor has 5. Four areas rather than one:
- Multilingual routing and evaluation — a caller-supplied language hint (#211), a reproducible per-language harness (#210), a re-run of the 51-language sweep in both temperature regimes (#222).
- HTTP serving and containers — inference moved off the event loop (#230), and the Compose
laya-serveservice (#234), later given loopback binding and a healthcheck (#262). - Email disclaimers and language detection — the request kept when a disclaimer footer shares its paragraph (#94), letters counted for the scripts no range claims (#169), and "confidential" no longer read as a disclaimer (#227).
- Correctness and test repairs — three assertions that could not fail (#231), the load-time and budget errors no suite reached (#237), the test suite run on Windows as well as Linux (#212), an ECE that binned differently from its siblings (#232), non-ASCII characters kept in non-string instructions (#228), a README link pointing at a heading that does not exist (#236), and #249, where a
noulcriteria dict that cannot be read raises instead of silently falling back to defaults — the line the project's 0.3.11 release note calls "stricter noul criteria".
Security — published advisory GHSA-j922-p6h6-p255 for dsh-permission-rules (medium, patched in 0.6.16).
Official harness repo — it does not accept external pull requests, so that line runs through issues, Discussions (the Show Your Plugins! post #6104) and the plugin ecosystem instead — while the wider deepseek-ai org is open to fixes (FlashMLA #224 merged).
- GitHub (this profile), Gitee and npm — source, CI and releases here; 104 owned repos mirrored to Gitee by a daily job (default branch + all tags); the
perrylinkaccount holds 55 npm names and 827 versions, 48 of them active and 44 carrying a provenance attestation - npm downloads — 137,423 over the trailing 30 days (npm window 08-22..09-20, the last day its daily series covers); dshfind independently tracks 22k+ across the 8 family plugins it has a download figure for — dshfind reports rounded tiers, so that is a floor rather than a total
- DSH Desktop Market — add the catalog source
https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.jsonunder Market → Sources to browse the family in-app; MCP Registry — three servers, all published from their release workflows over GitHub OIDC:dsh-cert-mcp,jevcore-mcpandlaya-mcp - GitHub Actions — dsh-github and dsh-test-drive also ship composite actions, so they install as
uses: PerryLink/dsh-test-drive@vX
Published to a dozen-plus third-party DSH directories and curated lists — awesome-dsh-plugin, DSH Directory, Awesome DeepSeek Harness, walkinglabs' list, Zhiyuan-Fan's list, the AdamPlatin123 radar, dsh-suite, dshfind.com, deepseek1024.com and Glama among them — and scored on OpenSSF Scorecard; the GitHub dsh-plugin topic is what most of them ingest from.
在 DeepSeek Harness 上构建插件生态:42 个开源插件,来自一个 46 仓的家族(其中 45 个由 PerryLink 自己维护)—— 安全、工作流、研究、消息桥接、开发者体验,外加 DSH Desktop Market 目录、插件认证注册表与 dsh-plugin-doctor 这个 CI 检查器。42 个插件全部带 CI 与 Gitee 镜像,五语文档由每个仓自己的 CI 闸门守着一致(段落数、安装命令、配置键),并声明 dsh.bundle 契约;近 30 天 npm 下载 137,423(窗口 08-22..09-20)。perrylink 这个 npm 账号下共有 55 个名称、827 个版本:其中 48 个在用(42 个非 scoped + 5 个 @perrylink/ scoped + pan17 的 dsh-wechat)、7 个已弃用、44 个当前 latest 版本带 provenance 证明。我也向上游 Cordis(DeepSeek Harness 所基于的插件内核框架)与 deepseek-ai 项目贡献,包括已合并的 FlashMLA 修复(#224,该组织下唯一一条已合并的外部 PR)。方向从检查点回退、声明式权限、跨会话记忆到消息桥接与「研究四件套」。
laya(NandhaKishorM/laya)是这个账号投入最深的外部项目:15 条已合并的 PR —— 我在那里提的 PR 全部进了主干,没有一条被关闭未合并;外部贡献者里最多,仅次于直接向 main 提交(而非走 PR)的维护者。其中 14 条是 2026-09-23 合的,8 条集中在 84 秒之内(13:22:52Z–13:24:16Z),#222 与 #234 随后进主干,#249 在 09-24 跟进。方向不是一个,而是四个:多语言路由与评测(#211、#210、#222)、HTTP 服务与容器(#230、#234,后者随后由 #262 补上 loopback 绑定与 healthcheck)、邮件免责声明与语种判定(#94、#169、#227),以及代码与测试修正(#212、#228、#231、#232、#236、#237、#249)。这批不是一个主题,而是一片:项目的第一条 Windows CI 车道(#212),Linux 的 16 个 suite 里 15 个现在在 windows-latest 上跑;没有任何测试覆盖到的 load-time 与 budget 错误(#237)、三个不可能失败的断言(#231)、把推理移出事件循环(#230)、让非 ASCII 字符在非字符串指令里存活(#228),以及让读不出来的 noul criteria 直接抛错而不是静默回退默认值的 #249(0.3.11 发布说明里的「stricter noul criteria」)。
这一家子所依赖的那项研究,现在是一篇有 DOI 的论文 —— 而且它测的很大一部分,正是这份主页上的两个项目:laya-mcp 与 jevcore。《当判定层的自报字段说谎时》在一套相同条目上实测三类判定层(Laya、TypeSafe Jev、DeepSeek-V4.1-Flash),四条主张三条成立、一条被自己的数据否定;判定器的自报字段不可信,异种判定器没有增量覆盖。四条主张的完整表述见上方 2026-09-23 的英文部分。
第五个在别处:一个根本起不来的进程现在能起来了。 claude-agent-acp #1146 让 src/index.ts 里那处没有保护的顶层 await 不再因一次瞬时错误就中断模块求值、在发出任何一条 ACP 消息之前退出。
待业中。近期考虑给自己安排一次体检。因此最近将减少熬夜,后续的更新迭代节奏会适当放缓。当然,问题和缺陷修复不会停,只是发布频率会降低一些,还请大家谅解。





