为每个会话划定独立产出目录,防止互相覆盖文件
29.6/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add TOP1Wu/dsh-session-isolation该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 会话独立产出目录
- 防止跨会话文件覆盖
为 DeepSeek Harness 提供工作区级会话隔离:同一工作区里多个会话各自写自己的产出目录,拒绝覆盖其他会话的文件。
README
由 DeepSeek 最新模型翻译生成dsh-session-isolation
DeepSeek Harness 插件:让同一个工作区里的多个会话互不覆盖对方的产出。
这个插件是干什么用的
一句话:给同一个工作区里的每个会话划一条写入边界。
它要解决的问题
DeepSeek Harness 的会话,在“对话”这一层本来就是隔离的——每个会话有自己独立的事件日志、独立的 agent、独立的上下文窗口。唯一被共享的东西是工作目录。
于是在同一个工作区里开多个会话时,会出这种事(下面是一个真实案例):
1. 在同一个工作区里开了两个会话,分别做两个不相干的项目(下面叫 A 项目和 B 项目);
2. 会话 A 建了一份“目录级”文档 README-文件索引.md,用来索引它自己那批产出;
3. 会话 B 看到这个工作区,按“这个目录是我的项目”的假设去改这份索引,把它自己项目的内容也塞了进去;
4. 结果一份文档里混着两个项目的内容。甚至出现了这样的标题:
五之三、B 项目(独立于 A 项目)
—— 一边声明“独立于 A 项目”,一边被写进同一个索引。
并行跑的时候更直接:两个会话写同一个路径,后写的把先写的整文件覆盖。
这不是“会话隔离坏了”,而是多个写入方共享了同一批文件。
展开完整文档(README 剩余 1 节)
dsh-session-isolation
DeepSeek Harness 插件:让同一个工作区里的多个会话互不覆盖对方的产出。
这个插件是干什么用的
一句话:给同一个工作区里的每个会话划一条写入边界。
它要解决的问题
DeepSeek Harness 的会话,在“对话”这一层本来就是隔离的——每个会话有自己独立的事件日志、独立的 agent、独立的上下文窗口。唯一被共享的东西是工作目录。
于是在同一个工作区里开多个会话时,会出这种事(下面是一个真实案例):
1. 在同一个工作区里开了两个会话,分别做两个不相干的项目(下面叫 A 项目和 B 项目);
2. 会话 A 建了一份“目录级”文档 README-文件索引.md,用来索引它自己那批产出;
3. 会话 B 看到这个工作区,按“这个目录是我的项目”的假设去改这份索引,把它自己项目的内容也塞了进去;
4. 结果一份文档里混着两个项目的内容。甚至出现了这样的标题:
五之三、B 项目(独立于 A 项目)
—— 一边声明“独立于 A 项目”,一边被写进同一个索引。
并行跑的时候更直接:两个会话写同一个路径,后写的把先写的整文件覆盖。
这不是“会话隔离坏了”,而是多个写入方共享了同一批文件。
装上之后是什么样
- 每个会话(以及它派生的子代理)自动获得自己的产出目录: /.sessions//
- 会话的第一步会收到一条说明,告诉它产出目录在哪、哪些东西不能碰;
- 当一个会话想覆盖另一个仍然存活的会话的文件时,写入被拒绝,并被告知改写到自己的产出目录;
- 归属会话结束、或应用重启之后自动放行,不会永久锁死文件。
它不做什么
- 它不改变会话的 cwd。会话的工作目录仍然由 DSH 创建时决定,所以这是“约定 + 拒绝”式的隔离,不是物理隔离;
- 它不拦 bash。bash 里的 >、tee、python -c "open(...,'w')" 写文件不会被守卫拦住(详见“已知边界”);
- 要做到物理隔离,仍然是“一个话题一个工作区”或 git worktree。
怎么工作
两条机制,都挂在 DSH 自己的扩展接缝上,没有一行 hack:
机制 1 · 产出目录约定(挂 agent/pre-step)
每个会话在第一步收到一条注入说明,内容是:
- 本工作区目录;
- 本会话的产出目录绝对路径;
- 四条写入边界(新文件写自己的目录 / 不动别人的文件 / 目录级索引文件默认不碰 / 拿不准就问用户)。
每个会话只注入一次。
机制 2 · 跨会话写入守卫(挂 ctx.tools.guard)
write / edit / str_replace_editor / apply_patch 在落地之前检查目标路径:
- 如果这个文件已被同一工作区里另一个仍然存活的会话占用 → 直接拒绝,并给出替代路径;
- 归属在 tools/result 里按“文件确实落到磁盘上”记账,失败或被拒绝的调用不会产生归属。
归属按血缘计算(关键设计)
- 子代理(header.origin === 'subagent')沿 parentSession 上溯到顶层会话,所以整棵委派树算同一个归属:父会话和它的子代理可以自由互相修改产出;
- 两个无关的顶层会话之间才互相隔离;
- 用户手动 fork 出来的会话不是子代理,因此是独立归属。
归属只在该顶层会话存活期间生效。会话结束或应用重启后自动放行——避免“文件被永久锁死”这种反向麻烦。
安装
命令行 profile
dsh plugin --profile web add /绝对路径/dsh-session-isolation
本插件零第三方依赖,只用 node: 内置模块,所以不需要构建步骤、也不需要联网。
DSH Desktop
⚠️ 桌面版真正的 DSH_HOME 是
~/Library/Application Support/dsh-desktop/harness
不是 ~/.dsh。 直接在终端跑 dsh plugin 会装进 ~/.dsh,对桌面版不生效。
要么用桌面版内置的插件市场安装,要么显式指定 home:
DSH_HOME="$HOME/Library/Application Support/dsh-desktop/harness" \
dsh plugin --profile web add /绝对路径/dsh-session-isolation
装完重启 DSH(CLI 安装不会热加载)。
验证装上了
dsh --profile web --dump-config | grep -A2 session-isolation
应能看到:
== dsh-session-isolation
- id: session-isolation
name: dsh-session-isolation
验证真的生效
重启后,在任意工作区开一个会话并让它做事,然后:
ls "/.sessions"
应该出现以会话短 id 命名的目录(短 id 就是 $DSH_SESSION_ID 去掉 session- 前缀后的第一段)。
配置
全部通过环境变量:
| 变量 | 默认 | 作用 |
| DSH_SESSION_ISOLATION | guard | guard = 约定 + 守卫;advise = 只注入约定、不拒绝;off = 完全关闭 |
| DSH_SESSION_ISOLATION_DIR | .sessions | 产出目录名 |
| DSH_SESSION_ISOLATION_MKDIR | 1 | 设 0 则不主动创建产出目录,只告知路径 |
用 advise 或 off 可以随时把插件软化/静默掉,不用卸载。
已知边界(重要)
1. 只拦文件工具,不拦 bash。
bash 里的 > / tee / python -c "open(...,'w')" 这类写文件不会被守卫拦下——可靠地解析 shell 命令很困难,硬拦会误伤正常命令。这条路径只由机制 1 的约定覆盖,没有强制。
2. 归属记录是进程内内存,DSH 重启后清空。
重启后已存在的文件重新变成“无主”,第一个写入它的会话会取得归属。
3. 不做物理隔离。 见上文“它不做什么”。
4. 只对顶层会话之间生效。 子代理按血缘并入其父会话,不独立成归属。
测试
node test/logic.test.mjs
21 项离线测试,用一个最小 fake ctx 复现 ctx.agents.get / ctx.tools.guard / ctx.on 三个接缝,覆盖:
- 两个会话争同一文件的拦截
- 归属会话自身放行
- 血缘归属(父会话的子代理放行 / 别的会话的子代理照样拦)
- 其他工作区不受影响
- 归属会话离线后放行
- 只读工具与非文件工具放行
- edit / str_replace_editor 同样受守卫
- pre-step 只注入一次,reject 决策不被污染
卸载
dsh plugin --profile web remove dsh-session-isolation
实现要点(给维护者)
| 依赖的 DSH 接缝 | 参考位置 |
| ctx.on('agent/pre-step', handler, { prepend: true }) | packages/context/time-context/src/index.ts |
| ctx.tools.guard(fn),返回字符串即拒绝 | packages/core/tools/src/index.ts |
| ctx.on('tools/result', (exec) => …) | packages/context/agent-instructions/src/index.ts |
| agent.session.header 的 cwd / id / origin / parentSession | packages/core/session/src/types.ts |
| 子代理写 parentSession | packages/subagent/subagent/src/child-agent.ts |
| 消息来源 { kind: 'plugin', form: 'snapshot', sections: [...] } | packages/llm/llm/src/message.ts |
本插件刻意不 import 任何 @deepseek-ai/* 包:以本地路径安装时 peer 依赖不一定解析得到,而运行期的消息 id 只是普通字符串(brand 只存在于类型层),所以手工构造消息与工厂函数等价。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
TOP1Wu/dsh-session-isolation
为每个会话划定独立产出目录,防止互相覆盖文件
相关插件 · 其他
模型破甲清洗HunYiSage/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,993已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,270已汉化DSH
70.8
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。