dsh-permission-workspace-write-plus
⚠️ 本项目按“现状”提供,不承诺长期持续性维护,使用前请自行评估风险。
项目简介
完全插件化的 Workspace Write Plus 权限预设 + 合并版跨平台睡眠守护。
当前版本 1.4.0。
- 工作区读写 + 工作区外配置类文件写入
.dsh/profiles 插件/配置写入 + .dsh/skills 写入
- 系统睡眠/关机命令宿主执行
- 任务执行期间自动禁止系统睡眠(睡眠守护已并入本插件,不再单独安装 dsh-sleep-guard)
- 跨平台:Windows / Linux / macOS / WSL(WSL 中执行任务时同时让 Windows 主机不睡眠)
- 零核心改动、可热插拔(bundle patch 为纯 insert)
功能一览
| 维度 | 权限 |
|---|
| 工具调用 | 完整(所有 tool) |
| 工作区(会话 workspace 根目录) | 读写 |
| 平台临时区 | 读写 |
| 工作区外配置类文件(且工作区内无同名对应) | 写 |
.dsh/profiles(插件安装与 profile 配置) | 写 |
用户 DSH skills 目录(<DSH_HOME>/skills) | 写 |
用户 DSH 主目录(<DSH_HOME>,兼容旧行为,可独立关闭) | 写 |
| 系统睡眠/关机指令(shutdown / powercfg / systemctl suspend 等) | 允许(宿主执行) |
| 睡眠守护:agent turn 执行期间保持系统不睡眠 | 默认开启 |
| 工作区外其他文件 | 拒绝写 |
| 升级/越界重试 | 需审批(approval: ask) |
架构
- fs 后端(
lib/fs.js):继承 LocalFileSystem,标准 workspace-write fence
完全兼容;plus 会话额外放行配置类文件、.dsh/profiles、.dsh/skills、
.dsh 主目录。每个附加类别有独立 settings 开关。
- shell 后端(
lib/shell.js):Windows 继承 PwshLocalExecutor,
Linux/macOS 继承 LocalBashExecutor;plus 会话中系统命令白名单走宿主执行。
- 睡眠守护(
lib/sleep-guard.js):监听 session/event 的
turn/start / turn/end,引用计数。Windows 通过常驻 PowerShell 调用
SetThreadExecutionState,Linux 用 systemd-inhibit,macOS 用
caffeinate。WSL 中额外通过 interop 启动 Windows PowerShell 常驻进程,
让 Windows 主机在 WSL 的 dsh 执行任务时同样不睡眠。
- Client 端(
lib/client.js):权限图标 + 权限中文名
(“工作区内修改+”)+ 设置中独立的
Workspace Write Plus 设置栏(与通用设置同级),同时适配旧版
(ui-conversation 内联下拉)与新版(权限 UI 合并进
ui-permission-presets、下拉 portal 渲染)客户端。
安装与启用
插件 bundle patch 是纯 insert 的包根行(cordis.patch.yml),可以被
dshmarket 热挂载。fs/shell 两行仍在 profile patch 中。
Windows profile patch
- id: fs-sandbox
disabled: true
- id: pwsh-sandbox
disabled: true
- insert:
- id: fs-workspace-plus-config
name: dsh-permission-workspace-write-plus/fs
- id: shell-workspace-plus-config
name: dsh-permission-workspace-write-plus/shell
Linux / WSL profile patch
- id: fs-sandbox
disabled: true
- id: bash-sandbox
disabled: true
- insert:
- id: fs-workspace-plus-config
name: dsh-permission-workspace-write-plus/fs
- id: shell-workspace-plus-config
name: dsh-permission-workspace-write-plus/shell
权限预设(所有平台都要)
profile patch 的 permission 行必须包含本预设,否则预设不存在、
defaultPreset: workspace-write-plus 会让 permission 行启动即报错
(新版 DSH 会直接抛 unknown preset "workspace-write-plus"):
- id: permission
config:
presets:
read-only:
sandbox: read-only
approval: ask
workspace-write:
sandbox: workspace-write
approval: ask
workspace-write-plus:
sandbox: workspace-write
approval: ask
name: Workspace Write Plus
description: >-
Full tool calls; workspace read/write; config-type files outside the
workspace with no same-named counterpart inside it; .dsh/profiles
plugin writes; .dsh/skills writes; OS sleep/shutdown commands; sleep
guard keeps the host awake during agent turns; everything else outside
the workspace stays write-denied; wider retries require approval.
danger-full-access:
sandbox: danger-full-access
approval: never
defaultPreset: workspace-write-plus
为什么不能自动完成:loader patch 是整体替换 config(不是深合并),
而 profile 的 cordis.patch.yml 在所有 bundle 之后才应用。所以只要
profile 自己配了 permission,bundle 里补的预设就会被覆盖掉,必须以
profile patch 为准。1.3.0 起插件会在启动时自检并打印上面这段提示。
包根行由插件 dsh.bundle.patch 提供:
- insert:
- id: dsh-permission-workspace-write-plus
name: dsh-permission-workspace-write-plus
禁用插件时 disabled 行与 insert 行必须成对处理,否则核心
fs/pwsh 或 fs/bash 服务缺失会导致 DSH 无法启动。
DSH 桌面版(Electron)
桌面版的插件管理器只会做两件事:把包装进
<DSH_HOME>/profiles/<profile>/node_modules,并把包名加进
package.json 的 dsh.profile.bundles。它不会改
profiles/<profile>/cordis.patch.yml,所以装完还要按上面的 Windows
profile patch + 权限预设各补一段,插件才真正生效。
桌面版 profile 默认 patchReload: live,所以改完 cordis.patch.yml 存盘
即可热生效(不需要重启桌面版);只有改动插件 host 侧代码或插件来源时才需要
重启。
自检:启动日志里若出现 the "workspace-write-plus" preset is not in the running permission table,说明 profile patch 还没配好,按日志给出的片段补齐。
从 GitHub 安装
dsh plugin --profile web add github:Wonjader/dsh-permission-workspace-write-plus
设置开关(settings)
插件注册 workspace-write-plus 命名空间;设置页中会渲染独立一栏的开关组
(lib/client.js),也可直接写 settings.yaml:
| 键 | 含义 | 默认 |
|---|
enabled | 总开关:关闭后所有附加放行与睡眠守护失效 | true |
allowConfigFiles | 工作区外配置类文件写入 | true |
allowSkills | <DSH_HOME>/skills 目录写入 | true |
allowProfiles | <DSH_HOME>/profiles 目录写入(插件/profile 配置) | true |
allowDshHome | <DSH_HOME> 整目录写入(兼容旧行为) | true |
allowSystemCommands | 系统睡眠/关机指令宿主执行 | true |
allowOfficeTools | DSH 自带文档渲染链(libreoffice-kit / soffice)宿主执行 | true |
allowSleepGuard | 任务执行期间保持系统不睡眠 | true |
allowOfficeTools 说明:@deepseek-ai/libreoffice-kit 渲染 docx/xlsx/pptx 时必须
自己启动 soffice.exe 子进程,而 Windows 沙箱的「ACL + 受限令牌」运行器起不了这个
子进程——kit 会返回 {"code":"failed","error":"spawn EPERM"}。此前每渲染一次就要审批一次
提升到 danger-full-access;现在 plus 会话把它按「宿主侧直通」执行(与睡眠/关机同一机制,
仅 plus 会话、可关闭)。
settings.yaml 示例:
workspace-write-plus:
enabled: true
allowConfigFiles: true
allowSkills: true
allowProfiles: true
allowDshHome: true
allowSystemCommands: true
allowOfficeTools: true
allowSleepGuard: true
睡眠守护平台说明
| 环境 | 实现 |
|---|
| Windows | 常驻 PowerShell + SetThreadExecutionState(ES_CONTINUOUS|ES_SYSTEM_REQUIRED) |
| Linux | systemd-inhibit --what=sleep |
| macOS | caffeinate -i |
| WSL | Linux 侧尽量使用 systemd-inhibit;同时通过 /mnt/c/.../powershell.exe 持有 Windows 主机唤醒锁 |
turn 开始 hold、turn 结束 release;多会话并发时引用计数,最后一个 turn
结束后释放;插件卸载/停用时自动释放。
特别说明:当Windows的Modern Standby被触发时,WSL会被暂停,sleep guard功能无法避免这一机制。
升级记录(Changelog)
1.4.2
- plus 预设下渲染文档不再反复要求提权:桌面版做 docx 排版任务时,每次把 docx 转图
(
@deepseek-ai/libreoffice-kit → soffice.exe)都被沙箱拦住,返回
{"code":"failed","error":"spawn EPERM"},只能每次审批提升到 danger-full-access。
根因是沙箱限制的是子进程/可执行文件,而 plus 预设此前只放宽了文件路径:Windows 运行器
用「ACL + 受限令牌」起命令,受限令牌起不了 kit 自己 spawn 的 soffice.exe。
- 现在把 DSH 自带的文档渲染链纳入 plus 的「宿主侧直通」(与睡眠/关机命令同一机制):
命中
libreoffice-kit/lib/cli.js、libreoffice-kit/lib/index.js 或 soffice(.exe|.bin)
的命令在 plus 会话里不受沙箱围栏执行,其余命令照旧受限。
- 新增开关
allowOfficeTools(默认开):可在「设置 → 工作区内修改+」或
settings.yaml 的 workspace-write-plus.allowOfficeTools 关掉,关掉后渲染又会回到
「每次审批提权」的老行为。
- 该规则不影响非 plus 会话,也不放宽任何文件路径:它只决定这一条命令是否在围栏外跑。
1.4.1
- 修复最新本地建构版(0.2.x 一代)上「设置里没有本插件的页面」:该版本把
settingsScope 服务整个删掉了(在它的 ui-settings 客户端 bundle 里出现 0 次),
插件设置的唯一传输变成 configForms(按 profile 条目 id 派生表单)。1.4.0 的独立设置栏
只在 settingsScope 存在时注册,因此在那一代宿主上从来没有注册成功过。
- 独立设置页改由
configForms 表单驱动:设置左侧导航重新出现「工作区内修改+」。
- 插件页的四个面全部注册:
plugins.item、plugins.bundle.config、
plugins.row.config(键 <包名>#<行 id>)、settings.plugins.tab。
那一代宿主里插件设置页由侧边栏「插件」页(插件管理器)派发 plugins.item 渲染:
owner 参数 {view:'summary'} 出摘要、{view:'page', form} 出设置页 —— 摘要只画一句描述,
设置内容只在页面视图里画,避免同一个表单出现两次。
- 去掉
whileServed 注册门槛:它的实现是「命名空间已经出现在 host 的 describe 文档里,
回调才跑」,而页面本身就是触碰该命名空间的唯一入口,构成死锁。表单控制器改为懒建,
host 未供出表单时页面显示「不可用」,而不是整页消失。
- 未声明的插槽不会触发(
slots.inject 会等待声明),所以旧宿主行为不变:
0.1.5-rc.2 及更早没有 configForms,仍走 settingsScope / connection 旧路与原有独立设置栏。
1.4.0
- 适配最新版 DSH(0.2.1-alpha.2 一代)的两处破坏性变更:
- 会话事件读取:最新版
Session 移除了公开的 events 数组(只剩
eventAt() / snapshotEvents() / ownEvents())。插件原本靠
session.events 找 permission/preset,于是每个会话都被判成「非 plus」,
所有附加放行静默失效 —— 表现就是「插件装了但没用」。现在按
snapshotEvents() → ownEvents() → 旧版 events 依次回退读取,并以
session.seq 做每会话缓存(写路径每次都会问它)。
- 执行器契约:最新版
ShellExecutor 只声明 resolve() 与 execute(spec)
(run / start 已移除)。插件的 shell 后端原本覆盖 run / start,
在最新版上从未被调用,等于完全没有围栏。现在按最新版
SandboxPwshExecutor 的结构覆盖 execute(spec)(executeArgv +
decorateResult + onProcessDone),并保留旧版 run / start 路径兼容旧宿主。
- 其余能力与 1.3.2 一致。
1.3.2
- 给新版客户端补上真正的设置页:新版的插件设置页不是自动生成的 —— 平台把配置区完全交给插件页的
plugins.row.config 键控插槽(键为 <包名>#<行 id>),注册这个键才会让插件页里那一行出现「配置」入口。
1.3.1 只导出了 Config,所以打开插件页只能看到条目本身、看不到任何开关。
- 现在注册键
dsh-permission-workspace-write-plus#dsh-permission-workspace-write-plus,页面直接复用原有的开关行
(7 个开关 + “额外可写目录”编辑器),数据层换成新版 configForms 表单(load / setField),
改动即时写入(与旧版设置栏一致的交互)。
- 与官方设置页同样的守卫:host 未提供该条目命名空间时不注册(
configForms.whileServed)。
- 旧客户端的独立设置栏、以及 web 版行为完全不变。
1.3.1
-
修复新版 DSH 上「设置里没有本插件」:新版 host 的 dsh-settings 移除了
installSettingsSection / installSection,设置模型改成「profile 条目 id →
该条目的 Config schema,自动生成页面」(describe() 里 ns = entry.options.id)。
1.2.x 的注册分支在新宿主上会直接抛错,整条链断掉,所以设置项从未出现。
-
现在把开关 schema 作为包根的 Config 导出,并用 schemastery 的
.volatile() 标记每个字段 —— 新版 host 的 volatileForm() 只收
meta.volatile 的字段,不标就不会进表单。旧 schemastery 没有 .volatile(),
调用点做了守卫(跳过),因此旧宿主不受影响。
-
包根 apply() 现在会从自身条目配置发布生效开关(新版宿主下设置页的每次修改
都会重跑 apply),fs/shell 后端通过 currentSwitches() 立即取到新值。
-
旧宿主仍走原来的 workspace-write-plus 独立设置栏,web/旧客户端行为不变。
-
设置页在哪:旧版客户端在「设置 → Workspace Write Plus / 工作区内修改+」;
新版客户端在「插件」页里对应条目 dsh-permission-workspace-write-plus 的配置表单。
1.3.0
- 适配 DSH 桌面版与新版权限界面:新版客户端把权限选择器整体并入
ui-permission-presets,并把对话区权限下拉也改成了 portal 渲染。图标规则
因此改为「portal 菜单 + 设置弹窗打开 ⇒ 属于设置行,保持无图标」,对话区下拉
恢复注入 “+” 图标(旧版客户端行为不变)。中文名改写逻辑本身与版本无关,继续生效。
- 新增启动自检:插件挂载后若运行中的权限表里没有
workspace-write-plus
(典型场景:桌面版只装 bundle、profile patch 没配),会在日志里打印完整的
profile patch 片段,而不是静默无效。
- README 补充桌面版安装要点:为什么权限预设无法由 bundle 自动补上
(loader patch 整体替换
config,且 profile 层最后应用)。
- 版本号升至 1.3.0;权限能力与 1.2.2 完全一致。
1.2.2
- 新增中文显示名:中文界面下权限名显示为 “工作区内修改+”(对应官方 Workspace Write 的“工作区内修改”);英文界面与英文文案完全不变,仍为 Workspace Write Plus。
- 适配范围:对话区权限触发按钮(含无障碍名称
aria-label)、对话区权限下拉、通用设置权限下拉、/permission 快捷选择列表,以及设置侧栏的插件分栏标题与总开关文案。
- 切换界面语言后即时刷新;插件被禁用/卸载时恢复核心渲染的英文名。
- 权限预设的
name(profile patch)与图标逻辑均不变:通用设置权限下拉仍保持无图标,其他位置图标不动。
- 实现方式:client 端只在已渲染的文本与
aria-label 上就地改写,不改核心、零核心改动,也不干扰 React 的渲染状态。
1.2.1
- 修复通用设置权限下拉列表中的图标:该菜单是 portal 渲染到
document.body 的,之前只判断了 [role="dialog"] 祖先,导致 Workspace Write Plus 仍被注入图标。现在同时识别 portal 菜单并跳过,保持与系统自带权限项一致。
- 其他位置(对话区权限触发按钮、对话区权限下拉、设置侧栏)的 Workspace Write Plus 图标保持不变。
1.2.0
- 新增
allowWriteDirs 设置:可在 Workspace Write Plus 设置页中添加任意数量的绝对目录,这些目录会加入额外可写白名单,不再局限于预设的配置目录、.dsh/profiles、.dsh/skills、.dsh 主目录。
- 设置页新增“额外可写目录”编辑器:支持添加、编辑、移除目录,保存后立即通过 settings API 生效。
- 目录白名单为空时行为与旧版完全一致;主开关
enabled 关闭时所有自定义目录同样失效。
- README 同步补充该功能与版本记录。
1.1.1
- 修复新版 DSH Client 设置传输兼容:新版浏览器端将设置读写从
connection.api.settings 迁移到 ctx.settingsScope 服务;插件优先使用 ctx.settingsScope.bind({ namespace }),旧版回退到 connection.api.settings,修复新版下设置页缺少 Workspace Write Plus 一栏的问题。
1.1.0
- 兼容新版 DSH Host 设置 API:
@deepseek-ai/dsh-settings 已移除 installSettingsSection / settingsNamespace 命名导出。插件改为运行时特性检测:旧版使用 installSettingsSection(...),新版使用 ctx.settings.installSection(...),避免 ESM 静态链接失败导致 DSH 无法启动。
- Windows profile 的
dshmarket 升级到 1.45.1,以兼容新版 settings 服务 API。
1.0.0
- 首个正式版本:Workspace Write Plus 权限预设、
.dsh/profiles / .dsh/skills 写入、系统睡眠/关机命令宿主执行、跨平台睡眠守护(Windows/Linux/macOS/WSL)。
- 权限图标统一为原生 workspace-write 风格 + 右上角 “+”。
- 设置页独立一栏。
开源收录
本插件目标仓库:
dshmarket 收录后的安装
dsh plugin --profile web add github:Wonjader/dsh-permission-workspace-write-plus
贡献
本项目接受外部贡献,但作者无义务审查或合并。提交即视为按APL授权。
免责声明
本作品包含AI生成内容,按“现状”提供,不附带任何担保。使用或分发所产生的一切后果由接收者自行承担。
许可证
本作品使用 无著公共许可证(Asanga Public License, APL)v1.0 授权。
Copyright © 2026 Wonjader(GitHub、gitee、AtomGit:@wonjader)
详见 LICENSE.md 文件。