🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

多文件夹工作区 Boy-Grid/dsh-multi-folder-workspace

DeepSeek Harness
Boy-Grid14 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek Harness 多文件夹工作区:一个工作区横跨多个文件夹,会话可读写每个成员。核心补丁集 + 插件 + 一条 npx 命令启动。

30.5/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/24 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Boy-Grid/dsh-multi-folder-workspace
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/09/26·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/03·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 14 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 33 处,展示前 33 条)
  • 读取本地文件
    packages/dsh-mfw/lib/bin.js:140
    if (existsSync(readyFile)) {
  • 读取本地文件
    packages/dsh-mfw/lib/bin.js:142
    const marker = JSON.parse(readFileSync(readyFile, 'utf8'));
  • 读取本地文件
    packages/dsh-mfw/lib/bin.js:152
    if (existsSync(manifest)) {
  • 读取本地文件
    packages/dsh-mfw/lib/bin.js:154
    pluginState = JSON.parse(readFileSync(manifest, 'utf8')).version;
  • 读取本地文件
    packages/dsh-mfw/lib/bin.js:169
    ` profile ${profile}${existsSync(profile) ? '' : ' (not created yet)'}\n` +
  • 读取本地文件
    packages/dsh-mfw/lib/bin.js:179
    if (!existsSync(target)) {
  • 删除本地文件递归
    packages/dsh-mfw/lib/bin.js:183
    rmSync(target, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
  • 执行外部命令来自配置/变量
    packages/dsh-mfw/lib/bin.js:203
    const child = spawn(process.execPath, args, {
  • 读取本地文件
    packages/dsh-mfw/lib/manifest.js:18
    export const pkg = JSON.parse(readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
  • 读取本地文件
    packages/dsh-mfw/lib/manifest.js:29
    if (!existsSync(dir)) return [];
  • 读取本地文件
    packages/dsh-mfw/lib/manifest.js:30
    return readdirSync(dir)
  • 读取本地文件
    packages/dsh-mfw/lib/manifest.js:67
    hash.update(readFileSync(entry.file));
  • 执行外部命令来自配置/变量
    packages/dsh-mfw/lib/pnpm.js:43
    return spawnSync(command, args, { shell: false, ...options, env });
  • 执行外部命令来自配置/变量
    packages/dsh-mfw/lib/pnpm.js:46
    return spawnSync(process.env.ComSpec ?? 'cmd.exe', ['/d', '/s', '/c', line], {
  • 读取本地文件
    packages/dsh-mfw/lib/profile.js:46
    name = JSON.parse(readFileSync(path.join(dir, 'package.json'), 'utf8')).name;
  • 读取本地文件
    packages/dsh-mfw/lib/profile.js:69
    if (!existsSync(manifest)) return undefined;
  • 读取本地文件
    packages/dsh-mfw/lib/profile.js:71
    return JSON.parse(readFileSync(manifest, 'utf8')).version;
  • 写入本地文件
    packages/dsh-mfw/lib/profile.js:79
    mkdirSync(dir, { recursive: true });
  • 读取本地文件
    packages/dsh-mfw/lib/profile.js:82
    if (!existsSync(manifestPath)) {
  • 写入本地文件
    packages/dsh-mfw/lib/profile.js:83
    writeFileSync(
  • 读取本地文件
    packages/dsh-mfw/lib/profile.js:102
    const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
  • 读取本地文件
    packages/dsh-mfw/lib/profile.js:132
    if (!existsSync(target)) writeFileSync(target, body);
  • 写入本地文件
    packages/dsh-mfw/lib/profile.js:132
    if (!existsSync(target)) writeFileSync(target, body);
  • 读取本地文件
    packages/dsh-mfw/lib/runtime.js:27
    if (!existsSync(marker) || !existsSync(dshEntry(dir))) return false;
  • 读取本地文件
    packages/dsh-mfw/lib/runtime.js:29
    return JSON.parse(readFileSync(marker, 'utf8')).key === key;
  • 写入本地文件
    packages/dsh-mfw/lib/runtime.js:36
    mkdirSync(path.join(dir, 'patches'), { recursive: true });
  • 写入本地文件
    packages/dsh-mfw/lib/runtime.js:37
    for (const entry of patches) copyFileSync(entry.file, path.join(dir, 'patches', entry.name));
  • 写入本地文件
    packages/dsh-mfw/lib/runtime.js:39
    writeFileSync(
  • 写入本地文件
    packages/dsh-mfw/lib/runtime.js:64
    writeFileSync(path.join(dir, 'pnpm-workspace.yaml'), lines.join('\n') + '\n');
  • 写入本地文件
    packages/dsh-mfw/lib/runtime.js:87
    mkdirSync(dir, { recursive: true });
  • 删除本地文件
    packages/dsh-mfw/lib/runtime.js:88
    rmSync(path.join(dir, READY_FILE), { force: true });
  • 读取本地文件
    packages/dsh-mfw/lib/runtime.js:98
    if (!existsSync(dshEntry(dir))) {
  • 写入本地文件
    packages/dsh-mfw/lib/runtime.js:102
    writeFileSync(
扫描于 2026/11/3(1 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 工作区横跨多文件夹
  • 会话读写全部成员
  • npx命令启动

README

由 DeepSeek 最新模型翻译生成
DSH 多文件夹工作区 English · 启动器 · 插件 · MIT npx @boy_grid/dsh-mfw web 让 DeepSeek Harness(DSH)支持多文件夹工作区:一个工作区由多个分散的文件夹组成,工作区内的会话可以读写全部成员文件夹,在侧边栏与普通单文件夹工作区同列展示,成员还能在之后增删。 状态:已冻结(2026-10-21),仓库已归档。 本 fork 只支持 DSH 0.1.1-rc.2,不再跟随上游。当前 DSH(0.2.1-rc.2)不受支持:上游把 RPC 层迁到了 dsh-api- 包,27 个补丁里只有 4 个还能应用。 要在当前 DSH 上用多根工作区,请用 @dsh-electron/dsh-plugin-multi-root-workspace——out-of-tree、无需改核心、精确支持 0.2.1-rc.2。迁移步骤见 docs/MIGRATION.md。本 README 其余部分记录的是冻结时的设计。 为什么是双轨仓库 上游 DSH 把工作区建模为「恰好一个文件夹」,这个假设散布在多个核心包里——持久记录(path: string)、沙箱策略(workspaceRoot: string)、RPC 载荷、目录选取契约(onPicked(path))。
展开完整文档(README 剩余 1 节)
DSH 多文件夹工作区

English · 启动器 · 插件 · MIT

npx @boy_grid/dsh-mfw web

让 DeepSeek Harness(DSH)支持多文件夹工作区:一个工作区由多个分散的文件夹组成,工作区内的会话可以读写全部成员文件夹,在侧边栏与普通单文件夹工作区同列展示,成员还能在之后增删。

状态:已冻结(2026-10-21),仓库已归档。 本 fork 只支持 DSH 0.1.1-rc.2,不再跟随上游。当前 DSH(0.2.1-rc.2)不受支持:上游把 RPC 层迁到了 dsh-api- 包,27 个补丁里只有 4 个还能应用。

要在当前 DSH 上用多根工作区,请用 @dsh-electron/dsh-plugin-multi-root-workspace——out-of-tree、无需改核心、精确支持 0.2.1-rc.2。迁移步骤见 docs/MIGRATION.md。本 README 其余部分记录的是冻结时的设计。

为什么是双轨仓库

上游 DSH 把工作区建模为「恰好一个文件夹」,这个假设散布在多个核心包里——持久记录(path: string)、沙箱策略(workspaceRoot: string)、RPC 载荷、目录选取契约(onPicked(path))。插件无法改写进程内已存在服务的类型与执行方,所以这个特性做不成纯插件。

上游目前也不接受外部 PR。因此本仓库交付必须成套安装的两样东西:

| 轨道 | 交付物 | 作用 |
| 核心 fork | 补丁集 —— 10 包 / 27 补丁,经 pnpm patchedDependencies 应用 | 多路径领域模型、多根沙箱、扩展 RPC、onPicked(paths[]) 契约、模型可见的成员变更轨迹 |
| 插件 | @boy_grid/multi-folder-workspace | 多选目录流 + 成员管理 UI |

插件依赖的契约只在补丁应用之后才存在,在 stock DSH 上无法工作。选 patchedDependencies 是因为它覆盖依赖树里的全部实例(含 peer 边)——pnpm overrides 不作用于 peerDependencies,所以 scripts/repack.mjs 能产出的 @boy_grid/dsh- 重发布包只作实验,不发布。

手工装齐两轨要好几步,所以还有第三个包替你做完:@boy_grid/dsh-mfw 是一个启动器,它准备好打了补丁的运行时、维护自己的 DSH profile 并装好插件,然后把你的参数原样交给 dsh。见 packages/dsh-mfw。

兼容性

| | 版本 |
| DSH 基线 | 0.1.1-rc.2 —— 精确 pin,见 fork/fork.json |
| 支持的 DSH 范围 | 仅 0.1.1-rc.2(2026-10-21 冻结) |
| 当前上游 latest | 0.2.1-rc.2 —— 不支持,见 docs/MIGRATION.md |
| Node | >= 22 |
| pnpm | 11.7(或 corepack) |

基线冻结在 0.1.1-rc.2。此前的版本通过 rebase 补丁集跟随 npm 的 latest dist-tag;这一做法在 2026-10-21 停止,因为上游重构了补丁目标所在的包(见 docs/MIGRATION.md)。如果你仍在使用冻结的运行时,除了精确 pin @deepseek-ai/dsh,还必须保留 lockfile:上游包之间用 ^<baseVersion> 区间互相引用,否则会漂到新的 prerelease,补丁随之变成 unused。

安全须知

多文件夹工作区扩大了 Agent 的写面。在 workspace-write 模式下,工作区内的会话可以写入全部成员文件夹,而不只是它自己的工作目录。具体来说:

- 补丁集修改了 DSH 的沙箱组件:dsh-sandbox(writableRoots 改为全部成员的并集)、dsh-sandbox-policy(经新增的 ctx.workspaceRoots seam 按会话实时解析成员集)、dsh-sandbox-local(Seatbelt / bwrap / Landlock 多目录授权)、dsh-sandbox-windows-acl(逐成员目录授 Write ACE)。
- 成员集合之外的路径仍然被拒,FS_SANDBOX_DENIED / [sandbox: …] 的升级路径不变。read-only 与 danger-full-access 语义未受影响。
- 成员变更即时生效:新增成员后既有会话立刻可写,移除成员后立刻收回。
- 成员集合与每一次增删都会投影进模型上下文,并作为 workspace/membership 会话事件落盘,轨迹可审计、可重放。

安装前请自行评估这个取舍。如果你一次只在一个文件夹里工作,就不需要它。

快速开始

npx @boy_grid/dsh-mfw web

启动器会在你的缓存目录里准备一棵打好补丁的 DSH 运行时(仅首次,约 10–30 秒)、把插件装进它自己的 DSH profile,然后起 web UI。web 之后的参数原样透传给 dsh,所以 npx @boy_grid/dsh-mfw web --port 8080 按预期工作。

它不干扰你已有的 DSH 安装:你的 web profile 及其 cordis.patch.yml 既不读也不写,原本的 dsh web 行为完全不变;同时两者共享 $DSH_HOME 里的会话与凭据。npx @boy_grid/dsh-mfw doctor 会打印它解析出的每个路径,clean --all 清掉缓存。细节见 packages/dsh-mfw/README.md。

前置要求:Node >= 22、首次运行需联网、pnpm 11+(PATH 上够新就直接用,否则经 corepack 取)。

手工安装(进阶)

想自己掌握安装树——比如 pin 进自己的仓库,或与其他补丁组合?仓库自带一份现成的安装套件,含补丁、清单与冻结 lockfile:

cp -R consumer-template /path/to/my-dsh-deploy
cd /path/to/my-dsh-deploy
pnpm install --frozen-lockfile --config.confirmModulesPurge=false
pnpm add @boy_grid/multi-folder-workspace

然后把插件与 browse 后端写进 profile 的 cordis.patch.yml,并禁用 native picker:

- id: directory-picker
disabled: true
- insert:
- id: directory-picker-browse
name: '@deepseek-ai/dsh-host-directory-picker-browse'
- id: multi-folder-workspace
name: '@boy_grid/multi-folder-workspace'

这个文件要等 profile 建出来才有,而 profile 是 dsh web 第一次运行时创建的——所以先起一次、停掉,再改。改完重启 dsh web。安装成功的判据:node_modules/.pnpm 下有 10 个带 _patch_hash 后缀的目录。完整步骤见 docs/RELEASE.md。

仓库结构

dsh-multi-folder-workspace/
├── plugins/multi-folder-workspace/ 发布的插件(client 半:多选目录流 + 成员管理 UI) ├── packages/dsh-mfw/ 发布的启动器(npx 入口;自带补丁集) ├── fork/ │ ├── fork.json 清单:scope / forkVersion / baseVersion / 包列表 │ └── patches/<pkg>/ 每包的分步补丁(NN-.patch)+ NOTES.md ├── consumer-template/ 即拷即用的消费者套件:清单 + 补丁 + 冻结 lockfile ├── scripts/ │ ├── combine-patches.mjs 重放分步补丁,合成每包一个规范化补丁 │ ├── repack.mjs 实验性 @boy_grid/dsh- 重发布管线 │ ├── build-client.mjs 插件 client 半 → __ModuleLoader__ 格式 │ ├── deploy.sh / run-experiment.sh / serve.sh / wire-plugin.sh / toggle-plugin.sh │ ├── test-setup.sh / integration-smoke.mjs 跨包集成冒烟 │ ├── gen-consumer.sh / make-test-bundle.sh 消费者套件 + 跨平台测试包 │ ├── test-platform.sh / test-platform.ps1 测试包内的 bootstrap 脚本 │ └── lib/pnpm.sh 共享的 pnpm 解析(.tool → PATH → corepack) └── docs/ 设计、状态、验证与发布文档(中文)

开发

pnpm install
pnpm typecheck # 对着 pin 住的基线跑 tsc --noEmit
pnpm build:plugin # host 半 + __ModuleLoader__ 格式的 client 半
pnpm patches # dist/fork/combined/<pkg>.patch(10 个)
pnpm test # 解包 + 打补丁基线、自建上游树,然后跑跨包集成冒烟(11 项)
pnpm consumer:regen # 重建 consumer-template,证明 pnpm 能应用全部 10 个补丁
pnpm experiment # 部署 + 接插件 + 用隔离的 DSH_HOME 启动 dsh web

启动器自带一份 combined 补丁集副本,所以 pnpm patches 之后要同步:

pnpm launcher:assets # 把 dist/fork/combined 拷进 packages/dsh-mfw/assets 并刷新其清单
pnpm launcher:verify # 资产漂移就失败(prepack 与 CI 也会跑)

想用本地插件构建试启动器、又不发布任何东西,就把它指向工作副本,并给它一次性的缓存与 home:

DSH_MFW_PLUGIN=$PWD/plugins/multi-folder-workspace \
DSH_MFW_CACHE=/tmp/mfw-cache DSH_HOME=/tmp/mfw-home \
node packages/dsh-mfw/lib/bin.js web

实验部署树在仓库之外(默认 $HOME/.cache/dsh-mfw-experiment,用 MFW_DEPLOY_DIR 改),因为它含有带凭据的真实 DSH_HOME。MFW_DSH_HOME 单独覆盖 home,PORT 改 web 端口。

一个值得记住的 pnpm 坑:脚本化的 pnpm install 必须带 --config.confirmModulesPurge=false,否则可能停在「modules directories will be removed and reinstalled」的交互确认上一直挂着。仓库脚本已统一带上。

已知限制

- 冻结在 0.1.1-rc.2。 不再计划 rebase;迁移到当前 DSH 见 docs/MIGRATION.md。
- 扩展契约没有类型声明。 补丁只改运行时 lib/.js。workspace.paths、addMember/removeMember、onPicked(paths[])、SandboxExecutionPolicy.workspaceRoots 在运行时存在,但不在 .d.ts 里,TypeScript 消费方调用这些扩展点需自行 declare module 补充。
- 两项 UI 打磨未做:工作区行的成员数徽标;新建会话时选择落在哪个成员目录(当前默认主成员)。
- 上游特性不会自动感知多根,除非它走沙箱 seam。例如 0.1.1 新增的 @ 文件引用按会话自身的工作目录解析,不跨成员目录。
- 嵌套成员被设计性拒绝:成员之间不得互为祖先/后代,同工作区内与跨工作区都一样。
- 卸载是安全的,但不可逆。 打补丁侧写出的记录会保留 path 指向主成员,所以卸载后原版 DSH 仍能启动,并把这些工作区显示为单文件夹工作区。但原版第一次写回记录时会把 paths 字段剥掉,此后成员集合就没了。想保留就先备份 $DSH_HOME/storages/workspace.json。
- Windows 上卸载会留下目录 ACE。 写授权是往成员目录的 DACL 上挂一条 capability SID 的 ACE 实现的,它在文件系统上而不在 DSH_HOME 里,删缓存和 profile 带不走。没有进程持有对应 SID 时它不授予任何权限,但想恢复原样需要手工清一次,命令见 docs/platform-testing.md。

文档

| 文档 | 内容 |
| docs/MIGRATION.md | 冻结状态、替代方案、迁移到当前 DSH 的完整步骤 |
| packages/dsh-mfw/README.md | 启动器:命令、选项、环境变量、它碰与不碰什么(英文) |
| docs/architecture.md | 上游约束、各层设计决策、fork 基线策略、客制化缝 |
| docs/implementation-status.md | 逐补丁的实现状态与验证证据、剩余边界 |
| docs/RELEASE.md | 历史发布/rebase 指南(2026-10-21 冻结)与消费者安装 |
| docs/manual-e2e-checklist.md | 手工 GUI 验收清单 |
| docs/platform-testing.md | 各平台沙箱覆盖情况与跨平台测试包 |

参与

GitHub 仓库已归档(只读),issue 与 PR 均已关闭。仓库作为参考实现保留,不再计划 rebase;docs/ 中的设计记录继续公开可读。

许可

MIT。补丁集派生自 MIT 许可的上游 @deepseek-ai/dsh- npm 产物;上游版权声明保留在 THIRD_PARTY_NOTICES.md。

本项目是独立的社区项目,与 DeepSeek 无隶属关系,也未获其背书。
预览分享卡片长什么样 ↓Boy-Grid/dsh-multi-folder-workspace
分享 · DeepSeek Harness Hub
Boy-Grid/dsh-multi-folder-workspace

DeepSeek Harness 多文件夹工作区:一个工作区横跨多个文件夹,会话可读写每个成员。核心补丁集 + 插件 + 一条 npx 命令启动。

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部