DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
G

dsh-groups

Groups

Add a one-click group switcher to the DSH plugin: organize installed plugins into your own groups, then click once to add a group’s plugins to the profile’s bundle list, taking effect after restart. Enabling is additive and does not disable other plugins you are using; multiple groups can be active

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:zyfsyx666/dsh-groups#48e12e61c5057a479943a1a65cb0cd1ddb7d9fa1
READMECompatibilityVersions

Description

Add a one-click group switcher to the DSH plugin: organize installed plugins into your own groups, then click once to add a group’s plugins to the profile’s bundle list, taking effect after restart. Enabling is additive and does not disable other plugins you are using; multiple groups can be active at the same time. Use “Keep Only This Group” for exclusive use, or “Disable” to turn off a specific group. Capabilities from persistent groups are automatically merged into the presets of other groups. Supports automatic merging from persistent groups, fallback groups that do not receive merges, and applying two groups together. You can also write a group as an agent preset so that an individual conversation enables only that group. Uses local file operations only and does not depend on hot reloading.

Compatibility and provenance

Groups is published as dsh-groups and currently resolves to version 1.5.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
11/5/2026

Versions

1.5.0stable
11/5/2026

Related plugins

Loading related plugins…

Latest
1.5.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 2
Weekly downloads
0
Last push
11/5/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in productivity-workflow.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseExperimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundleOptional bundle that adds Schedule, its task page, and time context to the Web compositionWeb All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / pet / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。Ab Ocrdsh-ab-ocr--- description: "The out-of-tree ocr tool: recognizes a scanned PDF or image page by page, merges the pages in order only after the last one, and saves one Markdown document with the heading levels the model decided." kind: "package-reference" ---

README

dsh-groups

给 DeepSeek Harness 装一个插件分组一键开关。

DSH 的插件是否加载由 profile 的 package.json → dsh.profile.bundles 决定,改完必须重启才生效。 这个插件把这个清单编成几套命名组合,点一下整组切换,不用再手动编辑 JSON。

面板

侧栏「插件分组」(order 60)。打开后:

  • 顶部显示当前生效的分组(可能同时有好几组;一组都没满足时显示「尚未启用任何分组」)。
  • 每张卡片显示点它之后会新增多少 / 已装但清单里没有的包 / 会顺带关掉哪些不属于任何分组的插件。
  • 「启用这组」→ 只做加法,把这一组的插件并入 profile 的 dsh.profile.bundles,你正在用的其它插件不会被关掉。
  • 「仅保留这组」→ 覆盖,关掉其它所有插件只留这一组。
  • 「停用」→ 减法,只把这一组加进来的插件拿出去;别的组(含常驻组)不受影响。确认框里会先告诉你移除几个、是哪些。
  • 三处都会提示重启 DSH。
  • 「新建分组」/「编辑」→ 勾选式界面,从全部已装插件里挑,带搜索;分组里存着但已经不在目录里的包会单独列出,可以一键移除。
  • 「预设」→ 把这一组写成一个 agent 预设,新建会话时可以选它单独生效(见下节)。
  • 「删除」→ 二次确认。

写盘前会备份:package.json.bak-before-groups-<时间戳>、cordis.patch.yml.bak-before-groups-<时间戳>。

多组叠加

两个开关决定一个分组怎么和别的分组共存:

标记含义典型用途
常驻(persist)应用任何别的分组时,这一组会自动一起叠加上去「常驻基础」——字体、通知、顺滑流式这类天天要开的
兜底(solo)不吃任何叠加,应用它就是干干净净只有它自己「全关」——排查问题时关掉一切
  • 点「启用这组」= 加法:当前清单 ∪ 这一组(所有常驻组也会一起叠上来)。
  • 点「仅保留这组」= 覆盖:只剩这一组 + 核心,其它插件全关。
  • 点「停用」= 减法:只减掉这一组自己 enable 里的插件,跳过核心包、官方包、以及任何常驻组也在用的包。
  • 勾两张卡上的多选框 → 出现组合条 → 「同时启用这两组」= 两组一起加进来(A 和 B 一起执行)。最多同时勾两个。
  • 卡片上会提示「应用这一组时会叠加:base + taskA」,点之前就知道会上去什么。

叠加只影响选哪些插件;最终清单仍是扁平的一层 dsh.profile.bundles,顺序保持用户原有顺序、新项追加在尾部。

两个标记都在编辑器里勾(「设为常驻组」/「设为兜底组」),也可以直接写 plugin-groups.json 的 persist / solo 字段。都不勾就是普通任务组。

保存时没带的标记沿用旧值,所以用脚本 PUT /group 只改 enable 不会把兜底标记抹掉;要显式清除就传 solo: false。

单个对话只开一组(预设)

点卡片上的「预设」按钮,就能把这一组写成一个 agent 预设:

  • 勾「生成预设」+ 选能力 → 保存 → 重启 DSH → 新建会话的预设列表里出现 group-<分组id>。
  • 选它开的新对话,只带这一组勾选的官方 agent 能力(基础工具 / 计划模式 / 上下文压缩 / 子代理 / 联网 / 定时任务)。
  • 取消勾选「生成预设」就把它从补丁层里移除(受管块整体重写,不会留残渣)。

常驻组的能力会自动并进来:如果你有标了「常驻」的分组(persist: true),它勾的能力会 自动加进其它每一组的预设——常驻组的语义就是「任何场景都要有」。所以给「任务 A」开预设时, 常驻组勾的「定时任务」也会一起写进去,不用重复勾。预设编辑器里会明说「常驻组也会带上它们勾的 能力:常驻基础(定时)」。兜底组(solo: true)不吃这套,它的预设有且只有自己勾的能力。

id 撞车会自动区分:分组 id 会折成预设 id(a: b → group-a-b)。如果两个分组折出同一个, 后一个会带上稳定后缀,例如 group-a-b--ec916c(原始 id 的 sha1 前 6 位)——不是随机数, 所以同样的分组永远得到同样的 id,重复同步不会反复重写。

产物写在 <profile>/cordis.patch.yml 里的一段受管块,形如:

# >>> dsh-groups presets (managed) >>>
- insert:
    - id: preset-group-task-a
      name: '@deepseek-ai/dsh-agent-preset'
      config:
        id: group-task-a
        order: 100
        name: 任务 A
        plugins: [ ... ]
# <<< dsh-groups presets (managed) <<<

块外的手写补丁不动;内容没变时不会写盘;写之前留 .bak-before-preset-<时间戳>。

两个安全阀:

  • 受管块必须有完整的首尾标记,而且只能有一份。缺结束标记、或者出现第二份,同步会直接拒绝(HTTP 409 BLOCK_CORRUPT)并保持文件逐字节不动——宁可不动,也不吞掉块外你手写的补丁。
  • 卸载插件之后的残留项:分组里引用了已卸载的包时,卡片会提示「未安装(会被跳过)」,点「编辑」可以在清单顶部看到逐条列出的残留项,每条带一个 × 按钮单独删掉(也有「全部移除」一次清空)。
    • 标签分两种:「(未安装)」是真的装不上,保存时会被丢掉;「(不可选)」是内置官方包(@deepseek-ai/* 由宿主自带、不进 profile 的 dependencies),保存时照常保留。判据来自后端 GET /state 的 missing 字段(走 isInstalled()),前端不自己猜。
    • 如果当前 DSH 进程是旧版、/state 里还没有 missing,标签会显示「(未知)」并提示重启,而不是把官方包误标成「未安装」。
  • 分组 id 只允许字母、数字、点、下划线、连字符(1–64 位)。像 a: b 这种会折成 a-b 生成预设 id,避免把整份 cordis.patch.yml 写成解析不了的形态。
  • 历史遗留的脏 id 能救回来:旧版本写进 plugin-groups.json 的不合规 id(如 a: b)会被标成 legacyKey,卡片上给出警告,点「编辑」可以把 id 改成合规形态并保存(按钮文案变成「改名并保存」);这类分组也能正常删除。改名时目标必须是合规 id、不能撞上已有分组。

没开任何预设时:如果块里本来就空,同步直接返回「无变化」,不写盘,也不会凭空创建 cordis.patch.yml。

删了分组不忘清理:删除分组时会顺手重同步一次,它生成的预设会一起消失。如果补丁层里还留着没有任何分组对应的预设,面板顶部会提示,并给一个「清理孤儿预设」按钮。

老进程上不白屏:如果当前 DSH 进程还没加载到带预设能力的这一版(GET /presets 返回 404),面板会明说「重启 DSH 后按钮才可用」,分组的启用 / 停用仍然照常工作。

两条硬限制:

  1. 预设只管 agent 平面。第三方插件是宿主平面(挂 webServer/llm/systemPrompt/skills), 工具在全局注册,塞进预设会触发 Preset services require isolate realms 检查失败。 所以「这个对话装载哪些第三方插件」仍然只能靠顶部的分组开关(要重启)。
  2. 预设只在会话空白时能换。官方判据是「还没发过任何消息」,第一句话发出去后就锁定(agent-preset/locked)。

永远保留的核心

@deepseek-ai/dsh-base、@deepseek-ai/dsh-web-app 以及官方 17 个受保护模块,加上 dsh-groups 自己、dsh-m、dshmarket 不会被任何分组关掉。

官方包不进勾选清单:@deepseek-ai/* 全部不列在插件选择里,分组也不会开关它们。 应用分组时,当前已启用的官方 bundle(dsh-experimental-agent-team-profile、 dsh-experimental-auto-review、dsh-experimental-voice-input-bundle 等)会被原样保留。 要开关这些,请用 DSH 自带的插件管理器。

为什么需要重启

DSH 的 HMR 只监视显式配置,node_modules 与 profile manifest 不在监视范围内(hmr 行 config.root = [])。 所以本插件不做热重载,只负责把清单改对,重启由用户自己决定何时做。

数据文件

  • 分组定义:<profile>/plugin-groups.json(不内置任何预设分组,首次打开是空的,由你自己建)
  • 日志:~/.dsh/dsh-groups/plugin-groups.log(超 1 MB 轮转为 .1)
  • 锁:<profile>/package.json.lock、<profile>/cordis.patch.yml.lock(写到锁里带 pid + 实例 id,可接管死进程留下的锁)

安全

所有 HTTP 路由只接受回环地址,且要求 Host 回环、Origin 同源、Sec-Fetch-Site 不是 cross-site。

测试

npm test        # check + check:hooks + 扫描器自检,三段串跑
npm run check   # 语法 + package.json 合法性
npm run check:hooks   # 只跑 hook 位置扫描

check:hooks 挡的是 node --check 结构上抓不到的一类问题:hook 写在了组件的 return 之后。1.4.4 就是这样白屏的——第一次渲染走 early return 只跑了 15 个 hook,state 到货后跑到第 16 个,React 抛 #310 把整个面板判崩溃,而语法完全合法。

判定标准是「hook 必须位于该组件所有 return 之前」。回调里的 return 不算,因为它不属于组件本身:

const save = async () => {
  if (!confirmDialog('覆盖?')) return   // 这是回调的 return,不算组件的早退
}
if (state === null) return h('div', null, '加载中…')   // 这才是

识别范围:组件认 function Name(…)、function* Name(…)、const Name = (…) =>、const Name = function (…)(含 async);hook 认 react.useXxx( 与解构引入后的裸调用 useXxx(;文件里自己声明的 useXxx 不算 hook。

--selftest 用内置样本自检扫描器本身(真违规必须报、回调 return 必须不报、箭头组件必须被识别……共 6 项),防止它哪天退化成只认字符串位置——那种检查比没有还危险。