dsh-workspace-gate

toolstested: passnpmMIT

Per-workspace gate that hides the tool schemas and system prompt sections of selected plugins from the model in directories that do not need them.

下载量 / Downloads
828
依赖体积 / node_modules
0.13 MB
测试时间 / Tested
2026-11-07
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-workspace-gate

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

<p align="right">

<b>简体中文</b> | <a href="./README.en.md">English</a>

</p>

dsh-workspace-gate · 工作区插件门控

插件照常加载,但按工作区把它不该占的提示词前缀摘掉——工具 schema 与提示词段都不再进模型上下文。

![version](https://github.com/M1r0er/dsh-workspace-gate/tags)

![license](LICENSE)

![dsh-plugin](https://github.com/topics/dsh-plugin)

一个 DeepSeek Harness(dsh)插件。

它让"要不要让模型看见某个插件"从全局下沉到工作区:插件依然全部加载、功能随时可用,

但在你指定的目录下,它的工具 JSON schema 和系统提示词段不再出现在每一次请求里。

省下的是每轮请求的输入 token,而不是插件的加载开销。


目录

  • [它解决什么问题](#它解决什么问题)
  • [它做什么 / 不做什么](#它做什么--不做什么)
  • [主要特性](#主要特性)
  • [界面](#界面)
  • [安装](#安装)
  • [使用](#使用)
  • [归属是怎么判断的](#归属是怎么判断的)
  • [数据存放](#数据存放)
  • [为什么不是"真·停用插件"](#为什么不是真停用插件)
  • [实测数据](#实测数据)
  • [开发](#开发)
  • [已知边界](#已知边界)
  • [许可证](#许可证)

它解决什么问题

DSH 自带的插件管理只有 全局 开关:一个插件要么对所有工作区都开,要么都关。

但插件对 prompt 的成本是每轮都付的——只要它启用了,它的工具 JSON schema 和

系统提示词段就会出现在每一次请求里,哪怕这次对话完全用不到它。

典型场景:

  • 装了「小说写作」插件,但你 90% 的时间在写代码;
  • 装了「网页搜索」全家桶,但某个离线项目根本不该联网;
  • 学生工作区只需要讲解/脑图,教师工作区只需要备课/教案。

本插件把"要不要让模型看见"从全局下沉到工作区,不动全局开关、不重启、不重载插件。

它做什么 / 不做什么

做 · 不做

按目录(含子目录继承)决定哪些工具/段不进 prompt · ❌ 不安装/卸载/升级插件

组级开关 + 展开到单个工具名/段名 · ❌ 不改变插件的全局启用状态

按来源分档:第三方 / 自定义 / 官方 / 官方可选包 · ❌ 不能把全局已停用的插件"变出来"(只减不加)

自动归属推断 + 静态扫包 + 手工归属 · ❌ 不回溯已开会话(前缀已经发出去了)

fail-open:任何异常都当作"没配置" · ❌ 不碰 sandbox / approval 策略

主要特性

  • 工作区级收窄:配置单位是目录,子目录自动继承最近祖先(给 D:\Projects 配一次,

D:\Projects\api 就继承)。

  • 只减不加:用的是 DSH 最弱的收窄原语 ctx.tools.restrict(),它只能移除,不会新增能力。
  • 两类可见面都管:工具 schema + 系统提示词段(后者用"同名空文本段遮蔽"实现)。
  • 按来源分档:靠 bundle 的 availability 判断"随 dsh 安装"还是"用户自装",

第三方档默认展开,官方档默认收起。

  • 归属可手工矫正:每个工具/段右侧有归属下拉,可以把未归属的项并入已有分组或新建分组。
  • 模型可调:workspace_gate 工具支持 status / list / set。
  • 可控的噪声:不写 DOM、不加载宿主客户端包、颜色只用 --dsw-alias-* 主题 token。
  • 可测试:核心逻辑抽在 lib/policy.mjs,24 条单测,不启动 DSH 也能跑。

界面

插件管理页会多出一个 「按工作区」 页签:

插件照常加载;勾掉的插件,它的工具与提示词段不再进入这个目录的请求。
存储: ~/.dsh/data/workspace-gate.json                        [重新扫描]
工作区  (default-workspace)  (my-project ●)  (+ 添加目录)
C:\work\my-project  · 跟随全局 · 已关 1 组 · 共 9 组
插件组                                                    [筛选…]
› 第三方  2                                    ≈ 2.7k
   [网] web-search-free   [9 工具][1 段]        ≈2.7k   ›  ●
› 自定义分组  1
› 官方  7                                      ≈ 17.8k
› 官方可选包  1
› 未归属  27
  • 行尾开关 = 这一组在这个目录下是否可见;
  • › 展开后可以只勾单个工具/段,右侧下拉可以改它的归属;
  • 顶部显示当前目录、是否已单独配置、关了几组、大概省多少 token/轮。

安装

本插件是标准 DSH bundle(package.json 里声明 dsh.bundle.patch)。

三种装法,推荐顺序从上往下;装好后都会在插件管理页出现「工作区插件门控」这一行。

版本要求:engines.dsh = ^0.2.1-rc.2。比这更老的 DSH 会被插件管理器直接拒绝安装,
而不是装上以后在运行期报错。

方式 1 · 让 AI 帮你装(最省事,推荐新手)

新开一个会话,把这句话发给助手:

帮我安装这个 DSH 插件:github:M1r0er/dsh-workspace-gate

助手会调用 plugin_manager 完成「pnpm 安装 → 选中 bundle → 激活」整条链路,最后告诉你

application: applied。然后刷新页面即可。

  • 前提:当前会话的预设启用了 plugin_manager 工具。DSH 默认只在 Creator 模式下启用它,

其它预设默认关闭;如果助手说没有这个工具,切到 Creator 再试,或改用方式 2。

  • 安装 Host 代码属于高权限操作,会请求一次性授权。

方式 2 · Web 插件页安装(不碰命令行)

1. 打开 DSH 的 插件 页;

2. 点安装入口,在 spec 里填 github:M1r0er/dsh-workspace-gate

(也可以填你本地 clone 的绝对路径);

3. 若弹出 “Allow these scripts and retry”,确认后重试一次;

4. 列表里出现 dsh-workspace-gate 即装好,刷新页面;

5. 确认「工作区插件门控」这一行是开启状态。

方式 3 · 命令行(知道自己在做什么的人)

# A. 用 dsh CLI(profile 不是 Desktop 时)
dsh plugin --profile <your-profile> add github:M1r0er/dsh-workspace-gate

# B. 直接进 profile 目录用 pnpm
cd ~/.dsh/profiles/<your-profile>
pnpm add github:M1r0er/dsh-workspace-gate

# C. 本地目录(开发/调试)
git clone https://github.com/M1r0er/dsh-workspace-gate.git
pnpm add link:<克隆下来的绝对路径>
--profile <name> 决定改哪个 profile 目录:--profile web 改的是 ~/.dsh/profiles/web,
而桌面版 GUI 跑的是 desktop profile —— 装进 web,桌面窗口里看不到,两个 profile 的
依赖和 dsh.profile.bundles 互相独立。要装进桌面版,请用它自己的插件页
(npm 版 CLI 会拒绝管理 desktop)。
⚠️ pnpm 只装依赖,不会把包写进 dsh.profile.bundles。
少这一步插件不会加载。装完必须再做一件事:
- 打开 Web 插件页,把 dsh-workspace-gate 这个 bundle 打开;或
- 手工在 ~/.dsh/profiles/<profile>/package.json 的 dsh.profile.bundles
数组末尾加 "dsh-workspace-gate"。
然后重启 DSH(没有 HMR 时)才会加载。

装好后:关掉插件管理页里「工作区插件门控」这一行 = 门控整体不生效,行为回到未安装状态(fail-open)。

常见坑

现象 · 原因 / 处理

装完插件页没有这一行 · bundle 没被选中:按方式 3 的提示把它加进 dsh.profile.bundles

返回 already-installed · 同 spec 已装过;先在插件页 Remove 再装

桌面版提示 CLI 不接管 · Desktop profile 由 Electron 托管,npm CLI 会拒绝管理它;请用 Web 插件页

安装卡在 build scripts · pnpm 11 默认拦截安装脚本;在弹窗里批准后重试

想在插件市场里搜到 · 仓库已打 dsh-plugin topic,但要在市场出现还需被 awesome-dsh-plugin 索引收录(提交 PR)

使用

给人

插件管理 → 「按工作区」→ 选目录 → 关掉不需要的组 → 保存。对新会话生效。

给模型

workspace_gate(action:"status")                          # 最近哪些会话命中了哪个目录、摘掉了什么
workspace_gate(action:"list")                            # 可门控的插件 → 工具名/段名
workspace_gate(action:"set", dir:"D:\\Projects\\api",
                hide:["plugin:r18-novel"])               # 需要显式给 dir
workspace_gate(action:"set", dir:"D:\\Projects",
                show:["tool:read"])                      # 从隐藏清单移除
这个工具没有用 deferLoading:实测打开后子会话里它直接不可见,模型想调也调不到。

两种写法等价(dir 必须是绝对路径,子目录会继承):

  • 隐藏整组:plugin:<分组 id>
  • 隐藏单项:tool:<工具名> / section:<段名>

归属是怎么判断的

DSH 运行时不记录某个工具是哪个插件注册的(tools.register() 只按名字存),

所以"按插件勾选"只能推断。本插件按强度依次尝试:

顺序 · 手段 · 说明 · 可靠度

1 · 段名命名空间 · r18-novel:protocol → r18-novel,与插件 id/包名归一后比较 · 高(约定)

2 · 工具名前缀 · 工具名 token 与插件 id 或包名 token 的前导全等匹配 · 中高

3 · 静态扫包 · 读包入口(第三方递归扫 .js)里的 name: 'x' 定义位,与未归属工具名求交,只在唯一命中时采纳 · 较高

4 · 手工归属 · 界面里自己指定,赢过以上全部 · 最高

静态扫包解决的是这类情况:dsh-free-search 的 profile 行 id 是 web-search-free,

而它注册的 platform_search / video_search / weather 等名字里根本不含包名——

只靠前缀只能认出 1/9,扫包之后 9 个全部归位。

硬边界:官方内置包在 app.asar 里,磁盘上没有目录,扫不到;运行时动态注册的工具

(没有对应文件插件)也没有包可扫。这些会留在「未归属」,用手工归属分类即

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::2,最后更新 2026-10-18

Links

GitHub · Homepage · npm

Same category