omdp
August 28, 2026 · View on GitHub
English
A single GitHub repo that collects all of my DeepSeek Harness (DSH) plugins as a monorepo. Each plugin lives in its own subdirectory and is an independently installable DSH bundle, published to npm on every v* tag.
Layout
omdp/
├── README.md # this file
├── package.json # root manifest — keeps bare-git installs functional (see below)
├── dsh-connector/ # unified MCP + Skills manager (Web UI settings tab)
│ ├── index.js # host half
│ ├── client.js # client half (Web UI)
│ ├── cordis.patch.yml # bundle activation row
│ ├── package.json
│ └── README.md
├── dsh-key-fallback/ # multi-key API key pool with automatic rotation
│ ├── lib/index.js # host half (ESM)
│ ├── lib/client.js # client half (Web UI settings tab)
│ ├── cordis.patch.yml # bundle activation row
│ ├── package.json
│ └── README.md
├── dsh-vision-bridge/ # vision bridge: let text-only models "see" via a configured multimodal endpoint
│ ├── index.js # host half
│ ├── client.js # client half (paste/drop → temp path)
│ ├── cordis.patch.yml # bundle activation row
│ ├── package.json
│ └── README.md
├── archive/ # archived plugins retained for historical reference
│ ├── dsh-gitbash-win/
│ └── resume-stream/
├── notes/ # development lessons & notes (三层:notes/<date>/<category>/)
├── docs/ # research notes, compatibility matrix, publish guide
└── <future plugins>/ # each its own subdirectory + package.json
Plugins
@omdp/dsh-connector — MCP + Skills manager (v0.2.5)
One settings tab (Connector) that manages three things from the DSH Web UI:
- MCP servers — edits the MCP block in
cordis.patch.yml(stdio / streamable-http), with full validation so bad config never reaches the next boot. Legacy SSE servers (e.g. Zhihu) are kept asmcp-remote --transport sse-onlystdio bridges; the plugin only manages that config text. - User skills — read / write / delete skills under
~/.dsh/skills/<name>/SKILL.md(frontmatter preserved). - Market explorer (v0.2.0+) — read-only browsing of ModelScope Skills hub and MCP plaza via anonymous OpenAPI; one-click copy of install commands /
mcpServersconfig snippets, skill "check update" viasource/sourceUpdatedfrontmatter. Market data lives only in process memory (30-min TTL), never on disk.
"dependencies": { "@omdp/dsh-connector": "^0.2.5" }
@omdp/dsh-key-fallback — multi-key API key pool with rotation (v3.1.1)
Sits between the LLM adapter and the credential store. Before each request the plugin picks a key from the per-provider pool and pre-writes it into the provider's credential reference; on a configured trigger error it marks the failed key cooling and advances to the next key — re-sending is left entirely to DSH's own dsh-llm-retry. Ships an always-visible settings page (Settings → API Key 回退) with a redesigned UI:
- Configurable rotation triggers (
rotateOn) — clickable chips covering the full DSHLlmErrorstandard code set (QUOTA/AUTH/RATE_LIMIT/TIMEOUT/TRANSPORT/SERVER/EMPTY_RESPONSE/INVALID_CREDENTIAL) plus custom codes (matched exactly againstfailure.code). - Shows the actually-used key (derived from the last value written to the env), not a truncated hash.
- Short refs (
key_fallback_<provider>_key1, …) with one-time idempotent migration of legacy long refs. - Plaintext reveal via an eye toggle (
GET /keys/plain, pool-owned keys / env key only) and editable env keys (file-backed ones; read-only when supplied by the launching environment). - Per-key
nextRef, pool lock ("设为当前"), cooldown reset, and delete.
"dependencies": { "@omdp/dsh-key-fallback": "^3.1.1" }
@omdp/dsh-vision-bridge — vision for text-only models (v0.1.7)
A zero-dependency plugin that gives text-only models vision: it auto-detects whether the routed model supports images (llm.resolveModelInfo().inputModalities), and for text-only models forwards pasted / attached images to a configurable OpenAI-compatible multimodal endpoint (default Agnes agnes-2.5-flash) and feeds the returned text back as evidence. Ships a vision_bridge_read_image tool, a paste/drop → temp-path browser handler, a wrapped (vision bridge) provider entry, and an agent/pre-step auto-read hook.
"dependencies": { "@omdp/dsh-vision-bridge": "^0.1.7" }
Installing from npm (recommended)
All three plugins are published to npm automatically by GitHub Actions on every v* tag. This is the preferred install path — it avoids the git-#path: normalization, cross-resolution, and allowBuilds friction that GitHub installs cause (see the history in docs/npm-publish.md).
// ~/.dsh/profiles/<name>/package.json — you can use one or mix-and-match
"dependencies": {
"@omdp/dsh-connector": "^0.2.5",
"@omdp/dsh-vision-bridge": "^0.1.7",
"@omdp/dsh-key-fallback": "^3.1.1"
}
cd ~/.dsh/profiles/<name>
pnpm install
Updating is a standard pnpm update:
cd ~/.dsh/profiles/<name>
pnpm update @omdp/dsh-connector @omdp/dsh-vision-bridge @omdp/dsh-key-fallback
Remote installs from GitHub (alternative)
Each active plugin is a standalone npm package in its own subdirectory, so it can also be installed straight from GitHub without a local checkout:
dsh plugin --profile web add github:XJungit/omdp#path:dsh-connector
dsh plugin --profile web add github:XJungit/omdp#path:dsh-vision-bridge
dsh plugin --profile web add github:XJungit/omdp#path:dsh-key-fallback
Command availability — the
dsh plugin addcommands above assumedshis on yourPATH. If you run DSH vianpxper the official docs (no globaldshcommand), those lines fail withcommand not found: dsh— prefix each line withnpx @deepseek-ai/dshinstead (nodshon PATH required).
The #path:<subdir> selector tells pnpm which workspace subdirectory to install (it resolves to that subpackage's package.json, not the repo root).
pnpm ≥10 build-script gate. A git install fetches sources, and pnpm refuses to run a git dependency's prepare/build scripts until explicitly allowed — the first add fails until you whitelist it in the profile's pnpm-workspace.yaml:
allowBuilds:
'@omdp/dsh-connector': true
'@omdp/dsh-vision-bridge': true
'@omdp/dsh-key-fallback': true
Then re-run the add. (These plugins are plain JavaScript with no build step, so the whitelist is the only hurdle — no prepare script is needed. See the official publish.md for the full "build-script catch".) Treat the allowance as permission to run the package's code at install time; for untrusted sources, pin a commit (github:XJungit/omdp#<sha>&path:<subdir>).
The same monorepo layout is used by other DSH plugin collections, e.g. zhu1090093659/dsh-web-ui.
Releasing a new version (GitHub Actions)
- Bump
versionin the subdirectory'spackage.json(only the one(s) you touched). - Commit, then tag and push:
git tag v3.1.1 git push origin master && git push origin v3.1.1 .github/workflows/publish.ymlpublishes the touched packages to npm with provenance (re-publishing an already-published version is a no-op — skip message is printed).- Update your profile:
pnpm update @omdp/<plugin>.
See docs/npm-publish.md for the full setup (npm token, GitHub Secret, troubleshooting) and docs/plugin-compatibility.md for the crash-resistance matrix.
Historical: GitHub and local-link installs
GitHub installs (dsh plugin add github:XJungit/omdp#path:<plugin>) worked but hit network/TLS friction (e.g. UNABLE_TO_VERIFY_LEAF_SIGNATURE) and pnpm's git-#path: normalization on update (which dropped the #path: spec and could cross-resolve both packages to the repo root). A one-shot repair script (~/.dsh/profiles/web/update-omdp.ps1) handled those, but npm installs make all of that unnecessary.
Local link: installs ("@omdp/<plugin>": "link:<abs-path>/omdp/<plugin>") still work: pnpm install creates a junction so the running plugin is the repo source, and updating = edit/pull + restart. They remain a good choice during active development.
Conventions
- Every plugin subdirectory is a standalone npm package with a
dsh.bundle(and optionallydsh.client) manifest. - Package names are scoped under
@omdp/to avoid colliding with upstreamdsh-*packages on npm. - Plugins in this repo are plain JavaScript (no build step), so both local-link and GitHub installs work without a compile stage.
- Installing locally is preferred during development: add
"@omdp/<plugin>": "link:<abs-path>/omdp/<plugin>"to the profile'sdependenciesand runpnpm install— the plugin loads straight from the repo and updates with a restart. - New plugins should be modelled on the existing three (connector / vision-bridge / key-fallback) rather than on a skeleton — the real plugins are the living templates.
- Doc discipline — any plugin update (source / config / version) must keep the root README, the plugin's own README, and the
docs/files in sync; lessons learned during development go intonotes/<date>/<category>/(see AGENTS.md 规范 2).
Docs index
| Doc | What it covers |
|---|---|
docs/npm-publish.md | npm publishing pipeline, why npm over GitHub installs, release flow |
docs/plugin-compatibility.md | crash-resistance matrix per plugin against DSH updates |
docs/AI-DSH-plugin-quality.md | community research: why AI-written DSH plugins break, and defensive practices |
docs/DSH-plugin-quality-zh-discussion.md | Chinese write-up of the same research + omdp practice |
docs/dsh-drag-and-drop-troubleshooting.md | troubleshooting record for the dsh-drag-and-drop plugin (Windows/Chinese) |
notes/README.md | development lessons & notes index (notes/<date>/<category>/) — see AGENTS.md 规范 2 |
中文版
一个把作者全部 DeepSeek Harness(DSH)插件收进单一 GitHub 仓库的 monorepo。每个插件各自独立子目录,是可直接安装的 DSH bundle,并在每次打 v* tag 时自动发布到 npm。
目录结构
omdp/
├── README.md # 本文件
├── package.json # 根清单——保证 bare-git 安装可用(见下文)
├── dsh-connector/ # 统一 MCP + Skills 管理器(Web UI 设置页)
│ ├── index.js # host 半区
│ ├── client.js # client 半区(Web UI)
│ ├── cordis.patch.yml # bundle 激活行
│ ├── package.json
│ └── README.md
├── dsh-key-fallback/ # 多 key API 池 + 自动轮换
│ ├── lib/index.js # host 半区(ESM)
│ ├── lib/client.js # client 半区(Web UI 设置页)
│ ├── cordis.patch.yml # bundle 激活行
│ ├── package.json
│ └── README.md
├── dsh-vision-bridge/ # 视觉桥:让纯文本模型通过配置的多模态端点「看见」
│ ├── index.js # host 半区
│ ├── client.js # client 半区(粘贴/拖拽 → 临时路径)
│ ├── cordis.patch.yml # bundle 激活行
│ ├── package.json
│ └── README.md
├── archive/ # 已归档插件,留作历史参考
│ ├── dsh-gitbash-win/
│ └── resume-stream/
├── notes/ # 开发教训与笔记(三层:notes/<date>/<category>/)
├── docs/ # 研究笔记、兼容性矩阵、发布指南
└── <未来插件>/ # 每个插件一个子目录 + package.json
插件
@omdp/dsh-connector — MCP + Skills 管理器(v0.2.5)
一个设置页(Connector),从 DSH Web UI 管理三件事:
- MCP 服务器 —— 编辑
cordis.patch.yml中的 MCP 块(stdio / streamable-http),带完整校验,坏配置绝不可能带到下次启动。旧版 SSE 服务器(如知乎)保留为mcp-remote --transport sse-only的 stdio 桥;插件只管这段配置文本。 - 用户 Skills —— 读写/删除
~/.dsh/skills/<name>/SKILL.md下的技能(保留 frontmatter)。 - 市场浏览器(v0.2.0+) —— 匿名 OpenAPI 只读浏览 ModelScope Skills 集市 与 MCP 广场;一键复制安装命令 /
mcpServers配置片段;通过source/sourceUpdatedfrontmatter 检查技能更新。市场数据只存进程内存(30 分钟 TTL),绝不落盘。
"dependencies": { "@omdp/dsh-connector": "^0.2.5" }
@omdp/dsh-key-fallback — 多 key API 池 + 轮换(v3.1.1)
位于 LLM 适配器与凭据存储之间。每次请求前,插件从对应 provider 的 key 池里选一把,预写入 provider 的凭据引用;遇配置的触发错误时,把失败 key 标记为冷却并切到下一把——重发完全交给 DSH 自带的 dsh-llm-retry。带一个常驻可见的设置页(设置 → API Key 回退)与全新 UI:
- 可配置的轮换触发码(
rotateOn)——点选 chips 覆盖 DSHLlmError标准码全集(QUOTA/AUTH/RATE_LIMIT/TIMEOUT/TRANSPORT/SERVER/EMPTY_RESPONSE/INVALID_CREDENTIAL),也支持自定义码(与failure.code精确匹配)。 - 显示当前实际使用的 key(从最后一次写入 env 的值推导),不是截断的哈希。
- 短 ref(
key_fallback_<provider>_key1、…),旧长 ref 一次性幂等迁移。 - 眼睛开关明文揭示(
GET /keys/plain,仅限池内 key / env key)与可编辑 env key(文件托管的可编辑;由启动环境注入的只读)。 - 每把 key 的
nextRef、池锁定("设为当前")、冷却重置与删除。
"dependencies": { "@omdp/dsh-key-fallback": "^3.1.1" }
@omdp/dsh-vision-bridge — 给纯文本模型的视觉(v0.1.7)
零依赖插件,给纯文本模型装上视觉:自动探测被路由模型是否支持图片(llm.resolveModelInfo().inputModalities);对纯文本模型,把粘贴/附加的图片转发到可配置的 OpenAI 兼容多模态端点(默认 Agnes agnes-2.5-flash),并把返回文本喂回作为证据。附带 vision_bridge_read_image 工具、粘贴/拖拽 → 临时路径的浏览器处理器、一个包装后的 (vision bridge) provider 条目,以及 agent/pre-step 自动读取钩子。
"dependencies": { "@omdp/dsh-vision-bridge": "^0.1.7" }
从 npm 安装(推荐)
三个插件都会由 GitHub Actions 在每次打 v* tag 时自动发布到 npm。这是首选安装路径——绕开 GitHub 安装带来的 git-#path: 规范化、交叉解析与 allowBuilds 摩擦(历史详见 docs/npm-publish.md)。
// ~/.dsh/profiles/<name>/package.json —— 可用其一或自由组合
"dependencies": {
"@omdp/dsh-connector": "^0.2.5",
"@omdp/dsh-vision-bridge": "^0.1.7",
"@omdp/dsh-key-fallback": "^3.1.1"
}
cd ~/.dsh/profiles/<name>
pnpm install
升级就是标准的 pnpm update:
cd ~/.dsh/profiles/<name>
pnpm update @omdp/dsh-connector @omdp/dsh-vision-bridge @omdp/dsh-key-fallback
从 GitHub 远程安装(备选)
每个活跃插件都是独立子目录里的独立 npm 包,因此也能不经过本地 checkout、直接从 GitHub 安装:
dsh plugin --profile web add github:XJungit/omdp#path:dsh-connector
dsh plugin --profile web add github:XJungit/omdp#path:dsh-vision-bridge
dsh plugin --profile web add github:XJungit/omdp#path:dsh-key-fallback
安装命令前提:上面的
dsh plugin add假设dsh已在 PATH。若你是按官方文档用npx运行 dsh(没有全局dsh命令),这几行会报command not found: dsh—— 每行前面加npx @deepseek-ai/dsh即可(不要求dsh在 PATH)。
#path:<子目录> 选择器告诉 pnpm 安装哪个 workspace 子目录(解析到该子包的 package.json,而不是仓库根)。
pnpm ≥10 构建脚本门禁。 git 安装拉取的是源码,pnpm 默认拒绝运行 git 依赖的 prepare/构建脚本,直到显式放行——首次 add 会失败,需要先在 profile 的 pnpm-workspace.yaml 里白名单:
allowBuilds:
'@omdp/dsh-connector': true
'@omdp/dsh-vision-bridge': true
'@omdp/dsh-key-fallback': true
然后重新执行 add。(这些插件是纯 JavaScript、无构建步骤,所以白名单是唯一障碍——不需要 prepare 脚本。官方 publish.md 有完整的"构建脚本坑"说明。)放行等于允许在安装时运行该包的代码;对不可信来源,请固定到具体 commit(github:XJungit/omdp#<sha>&path:<子目录>)。
其他 DSH 插件集合也采用同样的 monorepo 布局,例如 zhu1090093659/dsh-web-ui。
发布新版本(GitHub Actions)
- 在子目录的
package.json里 bumpversion(只 bump 你动过的)。 - 提交,然后打 tag 并推送:
git tag v3.1.1 git push origin master && git push origin v3.1.1 .github/workflows/publish.yml把动过的包发布到 npm(带 provenance;已发布的版本重复发布是 no-op,会打印 skip 信息)。- 更新你的 profile:
pnpm update @omdp/<plugin>。
完整配置(npm token、GitHub Secret、排障)见 docs/npm-publish.md;抗崩溃矩阵见 docs/plugin-compatibility.md。
历史:GitHub 与本地 link 安装
GitHub 安装(dsh plugin add github:XJungit/omdp#path:<插件>)能用,但会撞上网络/TLS 摩擦(如 UNABLE_TO_VERIFY_LEAF_SIGNATURE),以及 pnpm 在 update 时的 git-#path: 规范化问题(会丢 #path: 片段,甚至可能把两个包都交叉解析到仓库根)。当时用一次性修复脚本(~/.dsh/profiles/web/update-omdp.ps1)兜底,但 npm 安装让这一切都不再必要。
本地 link: 安装("@omdp/<插件>": "link:<绝对路径>/omdp/<插件>")依然可用:pnpm install 会创建 junction,让运行中的插件就是仓库源码,更新 = 改代码/拉取 + 重启。开发活跃期仍是好选择。
约定
- 每个插件子目录都是独立 npm 包,带
dsh.bundle(可选dsh.client)清单。 - 包名统一挂在
@omdp/作用域下,避免与上游dsh-*包在 npm 上撞名。 - 仓库里的插件都是纯 JavaScript(无构建步骤),所以本地 link 与 GitHub 安装都不需要编译环节。
- 开发期优先本地安装:把
"@omdp/<插件>": "link:<绝对路径>/omdp/<插件>"加进 profile 的dependencies,跑pnpm install—— 插件直接从仓库加载,改完重启即生效。 - 新插件应以现有三个插件(connector / vision-bridge / key-fallback)为蓝本,而不是复制模板——真实插件就是活的模板。
- 文档纪律:插件有任何更新(源码/配置/版本)时,必须同步更新根 README、对应插件 README、docs/ 相关文档;开发中产生的教训/经验主动写入
notes/<date>/<category>/(详见 AGENTS.md 规范 2)。
文档索引
| 文档 | 内容 |
|---|---|
docs/npm-publish.md | npm 发布管线、为什么选 npm 而非 GitHub 安装、发布流程 |
docs/plugin-compatibility.md | 各插件对 DSH 更新的抗崩溃矩阵 |
docs/AI-DSH-plugin-quality.md | 社区研究:为什么 AI 写的 DSH 插件会坏,以及防御性实践 |
docs/DSH-plugin-quality-zh-discussion.md | 同一研究的中文版 + omdp 实践 |
docs/dsh-drag-and-drop-troubleshooting.md | dsh-drag-and-drop 插件排障记录(Windows/中文) |
notes/README.md | 开发教训与笔记索引(notes/<date>/<category>/)——见 AGENTS.md 规范 2 |