kkkkkklze/dsh-plugin-manager
In-web plugin manager for DeepSeek Harness: categorized list, tags, one-click preset switching, plugin marketplace, import/export, DeepSeek balance. | 在网页里管理 dsh 插件:分类/标签/预设一键切换/插件市场/导入导出/余额。
Listed
2
Market
Bundle verified
What it does
In-web plugin manager for DeepSeek Harness: categorized plugin list, preset bundles with one-click switching, import/export and failure auto-rollback, plugin market with one-click install.
Best for
- DSH Web users who manage many plugins and need categorized search, filtering, tagging, enablement, and installation in one interface.
- Teams that switch between reusable plugin presets and need import, export, and automatic rollback when a switch fails.
Not ideal for
- Users who manage only one or two static plugins and do not need presets, tagging, or a marketplace.
- Workflows requiring mature dependency resolution; dependency tracking is described as future work.
- Offline environments that need marketplace discovery, which depends on GitHub search, raw content, and curated-list data.
README

🎛️ dsh-plugin-manager
在 DeepSeek Harness 网页里直接管理插件:分类列表 · 标签 · 预设一键切换 · 插件市场 · 导入导出 · 余额
Manage your DeepSeek Harness plugins right inside the web UI.
✨ 功能 / Features
- 📂 分类列表 — 内置 128 个插件预分类(23 个标签族)+ 中文简介,搜索 / 筛选 / 启停 / 标签编辑;
- 📦 插件包(预设) — 点选插件组成整合包,一键切换 + 回滚,支持导入 / 导出(名字与介绍随包继承,方便分享);
- 🛒 插件市场 — 浏览 GitHub
dsh-plugin主题仓库,自动识别真插件,一键安装;非插件给出可复制的安装提示词; - 🛡️ 权限与安全 — 变更操作走审批(agent 工具)与确认弹窗(Web);市场安装参数白名单校验(owner/repo 格式,防命令注入);预设名保留键/长度校验、导入256KB 上限;一键停止后可优雅退化为 dsh 原版插件列表;
- 💰 余额与快捷入口 — 侧边栏显示 DeepSeek 余额(点击跳用量页)+ Chat 按钮;实时刷新:可见时每 60s 轮询 + 切回标签页立即刷新,后台暂停、请求防重入、余额没变不重渲染;
- 🕘 工作时间提醒 — 9:00-12:00 / 14:00-18:00(本地时间)聊天对话框自动变红,一眼可辨是否在工作时段;
- 🤖 agent 工具 —
plugin_list / plugin_enable / plugin_disable / plugin_add / plugin_remove / plugin_tag / plugin_preset_list / plugin_preset_switch / plugin_rollback / plugin_stop_self / plugin_market_inspect / plugin_market_install。
🔧 安装 / Install
# 从 GitHub 安装(推荐)
dsh plugin --profile <name> add github:kkkkkklze/dsh-plugin-manager
重启 dsh web 后:设置 → 插件 → 出现「分类 / 插件包 / 市场」三个子标签。
🚀 使用 / Usage
- 「分类」:查看 / 筛选 / 启停全部插件,带标签与简介;
- 「插件包」:点选插件组成整合包,一键切换、导入导出;
- 「市场」:默认「只看插件」扫描模式,点安装即可;
- 对话里:对 agent 说「切到日常预设」「用 plugin_list 看看」等。
🌱 愿景:统一插件依赖标准(Vision)
现在的 dsh 生态里有大量不同格式的风格包 / 美化包,互相冲突、装了 A 就坏 B。 我们想借鉴 Minecraft 模组的「前置依赖(required dependency)」 思路来统一它们。
设想:
- 统一一个前置 / 基础插件作为公共底座,风格包 / 美化包声明对它依赖;
- 依赖同一前置的插件互相兼容 —— 前置统一注册与渲染入口,风格包只负责提供内容;
- 像 MCMod 的前置列表一样,装风格包时自动识别并提示它需要的前置;
- 本插件后续支持依赖追踪:展示依赖关系、安装前校验前置是否齐备;
- 可能需要插件按一定方式声明依赖(例如
package.json的dsh清单增加requires/provides字段)。
如果你也受风格包冲突之苦、认同这个方向,欢迎来 Issue 讨论,一起定标准。
🧠 架构与原理 / Architecture
分层结构
Web 页面(client-bundle.js,浏览器)
│ ctx.remote.$mount(CONTRIBUTION) → ctx.get('remote.pluginManager')
▼ Typert 远程协议(/api,严格编解码,零额外端口)
remote.js(网关,@deepseek-ai/dsh-typert-protocol)
▼
manager.js(核心操作,agent 工具与 Web 共用同一份逻辑)
▼ engine.js(patch DSL 解析/合成)
文件系统:profile/cordis.patch.yml · ~/.dsh/plugin-manager/state.json · ~/.dsh/plugin-presets.yml
插件管理原理
-
patch DSL:dsh 的插件树由
cordis.patch.yml描述(insert新增行 /id目标覆盖行 /disabled停用)。本插件把自己管理的行统一持有:状态存state.json(inserted+overrides),每次变更经sync()重新合成 patch —— 先过滤掉我方行(pm-manager/pm.前缀 / 我方 insert 块),再叠加新状态,写入前自动备份到backups/(可回滚)。 -
id 前缀:loader 条目 id 常带子树前缀(
include:),管理器自动探测自身行的前缀并剥离,读写一律用裸 id。 -
内置「插件」区接管:启动时自动把
ui-settings-plugin-inventory置为停用,并注入「分类 / 插件包 / 市场」三个子标签;自停(stopSelf)时恢复原版界面。 -
标签体系:自动规则(
AUTO_TAG_RULES正则)∪ 出厂库(default-tags.yml)∪ 包声明(package.json的dsh.bundle.tags)∪ 用户标签(tags.yml),按优先级合并。
插件市场原理
-
数据源① Topic 搜索:调用 GitHub Search API
q=topic:dsh-plugin&sort=stars&order=desc&per_page=30(分页)。未认证限 10 次/分,故结果缓存进sessionStorage(10 分钟)。 -
数据源② Awesome 精选:直接抓取
awesome-dsh-plugin/awesome-dsh-plugin的 README,正则解析条目(支持#fragment与/tree/<branch>/<dir>子目录写法,如zoahdev/dsh-subscribe#plugin),分页浏览 —— 覆盖「没有 dsh-plugin topic」和「package.json 在子目录」的漏网插件。 -
插件识别(
identify):抓取仓库package.json,判定isPlugin = 存在 dsh.bundle || dsh.client。候选路径依次为默认分支(+子目录) → HEAD(HEAD 为万能回退,实测对 748 个精选仓库全部有效)。并发限制 6(mapLimit),结果缓存 1 小时 —— 防止突发请求触发 GitHub raw 限流(限流时返回假 404,曾导致列表全空)。 - 只看插件模式:逐页扫描识别后过滤非插件;自动翻页上限 3 页,可手动「加载更多」。
-
安装:走官方 CLI
dsh plugin --profile <p> add github:<owner/repo>(git 安装首次可能需在pnpm-workspace.yaml加allowBuilds)。已识别的插件直接确认安装;未识别的抓 contents API 检查package.json/ README,给出「复制安装提示词」或判定为 Skill/应用类。 - 批量安装:勾选多个插件 → host 串行执行安装 → diff 前后 loader 条目 → 新条目自动生成整合包(检测不到时退回用包名作引用,提示重启后补建)。
整合包(预设)原理
- 预设存于全局
~/.dsh/plugin-presets.yml(所有 profile 共享),支持导入 / 导出(YAML,名字与介绍随包继承)。 -
切换 = 全量启停:启用目标引用、停用其余(管理器自身除外)。引用可写插件 id / 模块名 /
tag:标签。 -
双保险回退:
-
切换失败回退 —— 切换后等待 loader 重载(
waitMs,默认 3s),目标插件missing(未加载)/failed(加载失败)/skipped(引用不存在)→ 自动恢复切换前状态并返回失败原因; -
启动失败回退 —— 切换成功会写
state.lastSwitch待确认标记,正常启动 10s 后自动确认清除;若切换导致下次启动崩溃(如插件冲突),标记残留且attempts ≥ 2时,startupSelfCheck自动恢复切换前状态(默认整合包),防止 boot 起不来。
-
切换失败回退 —— 切换后等待 loader 重载(
-
不可用引用分类(
inspectRef):切换时对不可用引用抓取仓库package.json分类:plugin-missing(是插件未装,附安装命令)/not-plugin(有包无 dsh 清单)/no-pkg(无 package.json,Skill/应用类)/unknown(非仓库引用或网络不可达);Web 端弹出「部分插件不可用」并支持一键复制安装提示词交给 agent。
远程协议(Web 客户端 ↔ host)
- host 侧:网关类继承
TypertRemoteService,方法用Remote(name)装饰器(plain JS 手工展开__esDecorate);方法签名必须保持简单命名参数(SRC 网关按源码反射参数名)。 - client 侧:声明
CONTRIBUTION描述符(带typeSymbol+sourceLocation),ctx.remote.$mount()后经ctx.get('remote.pluginManager')调用;编解码用严格模式 + 恒等 schema(无需 zod)。 -
方法名不能与命名空间服务原型冲突(如
remove被占用 → 改为removeRow)。
其他
-
余额:读
~/.dsh/.credentials.yaml的DEEPSEEK_API_KEY,调api.deepseek.com/user/balance。 -
agent 工具:
index.js用defineTool注册 12 个工具,变更类操作经approval服务审批(policynever时天然拒绝)。
🛠️ 开发者文档 / Developer Guide
目录结构
package.json # 契约:exports(. / ./client / ./package.json)、dsh.bundle.patch、dsh.client.inject
index.js # 插件入口:agent 工具注册、approval、启动接管、startupSelfCheck
manager.js # 核心操作(op* 系列)+ 文件状态机 + inspectRef/startupSelfCheck
engine.js # patch DSL:parsePatch / composePatch / isOwnRow 系列 / FIBER_PHASE
remote.js # Typert 远程网关(REMOTE_METHODS + createGateway)
client-bundle.js # Web 客户端:三个设置子标签 + 侧边栏,全部手写 React.createElement
cordis.patch.yml # bundle 层 patch(不自插 pm-manager,防重复 id)
default-tags.yml # 出厂标签库(覆盖当前插件全集)
default-descriptions.yml # 出厂中文简介
verify.mjs # 92 项断言(契约/引擎/操作/远程/回退/压测)
verify-plugin.ps1 # 一键验收:沙箱副本 + 真实启动 + 安装副本一致性(SHA-256)
如何新增一个远程操作(示例:新增 example 方法)
-
manager.js:在
createManager里新增async function opExample(args) { ... }并加入 return 对象; -
remote.js:把
'example'加进REMOTE_METHODS,并实现async example(param1) { return this.manager.opExample(param1) }(参数保持简单命名); -
client-bundle.js:在
CONTRIBUTION.descriptors加descriptor('example', ['param1']),然后pm.example(param1)即可调用; -
verify.mjs:加断言(方法存在 + 一个行为断言),跑
pwsh -File verify-plugin.ps1; - 安装副本同步:把改动文件复制到
~/.dsh/profiles/node_modules/dsh-plugin-manager/,重启 dsh web。
如何新增一个 UI 功能
- 在
makeXxxSection(pm, t)工厂里用React.createElement写组件(无 JSX);文案一律走t('key')并同时补充LOCALE.zh/LOCALE.en; - 新 tab:在
apply()里ctx.slots.inject('settings.plugins.tab', ...)注册(参考categories/bundles/market); - 浏览器端网络请求注意:并发受限(
mapLimit)+ 结果缓存(sessionStorage),否则会触发 GitHub raw 限流假 404。
注意事项 / Pitfalls
- 远程方法名避开命名空间服务原型(参考
removeRow教训); - descriptor 必须带
typeSymbol+sourceLocation,否则 typert 校验崩溃; -
exports必须包含"."、"./client"、"./package.json"(客户端扫描需要require.resolve(pkg + "/package.json")); - 切换类操作必须先
structuredClone旧状态,任何失败路径都要恢复(见opPresetSwitch的双保险回退); -
state.json是全局共享(所有 profile),测试/改动时注意别把别的 profile 的状态写进来; - 修改后记得同步安装副本再重启,验证用
verify-plugin.ps1(含一致性检查,防漂移)。
✅ 验证 / Verification
仓库自带一键验收(pwsh -File verify-plugin.ps1):92 项断言覆盖契约、引擎、操作、远程、失败回退、批量压测、真实启动与安装副本一致性(SHA-256)。
🙌 反馈 / Feedback
欢迎提 Issue / PR;也欢迎到 dsh-plugin topic 和 awesome 清单互相推荐。
📄 License
MIT © 2026 kkkkkklze
Frequently Asked QuestionsFAQ
Use the verified command dsh plugin --profile default add github:kkkkkklze/dsh-plugin-manager in a DSH-enabled shell. The command resolves the public package metadata and keeps the plugin attached to the catalog identity shown on this page.
Compatibility follows the bundle and profile status shown above. If a profile is not detected, keep the plugin disabled there and check the repository documentation before enabling it in production.
The GitHub link and activity metadata are the source of truth for releases and maintenance. Revisit this page after a new release to confirm the catalog has observed the latest version.