我同时用好几个工作区:一个写代码,一个做运维文档,一个整理简历。每个工作区需要的能力不一样,但 DSH 默认会把所有插件和技能都加载进来。于是我想:能不能做一个插件,按工作区决定哪些插件和技能可用?
这就是 dsh-workspace-gate。
它解决什么问题
- 写代码的工作区不需要简历工具,整理简历的工作区不需要服务器管理工具
- 技能太多会污染上下文,模型容易选错
- 我希望「换工作区 = 换一套工具」,而不是所有工具永远在线
实现思路
DSH 的插件由 cordis 加载器管理。dsh-workspace-gate 的做法是:
- arm(布防):切换到某个工作区时,记录当前工作区 ID
- applyGating(应用门控):遍历
loader.entries(),对不该在这个工作区出现的插件调用loader.update(entry.id, {disabled: true}) - release(解除):离开工作区时,把「本插件关掉的」重新打开(配置里本来就关的不会被误开)
- protect(保护名单):
dsh-base、dsh-web-app、workspace-gate本身永远不被关
关键设计:它是运行时控制,不写 cordis.patch.yml。也就是说,门控状态是临时的、可逆的,不会污染你的配置文件。
一个意外的发现
我原本以为「技能开关」也能实时控制。查了源码才发现不是:
- 文件型技能(
~/.dsh/skills/下的):调set-enabled,会写disable-model-invocationfrontmatter,真的关掉了 - 插件自带技能:调
set-provider-enabled,只写~/.dsh/dsh-skill-explorer/provider-toggles.json,只改面板显示,模型仍然可能调用
上游的原话是:「It is a PANEL-LOCAL decision: the host registry still loads the skill」。
这个区别很重要:如果你以为关了技能就不占上下文,对插件自带技能来说是错的。
测试
我在本地写了 5 个测试脚本、36 个断言,覆盖:
- 状态文件读写
- 过滤逻辑(含重复行、空行)
- 客户端面板 smoke test
- 技能浏览器集成
全部通过。但要说实话:这些测试是「逻辑正确性」测试,不是「真实使用场景」测试。真实场景里切换工作区、多个 agent 同时运行、技能冲突,还需要更多验证。
上架
代码已经推到 GitHub:CyberYui/dsh-workspace-gate(MIT)。接下来准备提交到 DSH 市场。
如果你也在管多个工作区,可以试试。也欢迎提 issue —— 这个插件还年轻,边界情况肯定还有。
教训
- 做 DSH 插件,得先读懂 loader 的生命周期,光写业务逻辑不够。
- 「关掉」和「看起来关掉了」是两回事,尤其是技能系统。
- 测试要分清「逻辑正确」和「场景正确」,前者通过不代表后者没问题。
- 开源是最好的文档。把踩过的坑写进 README,能省掉后面一堆 issue。