
Security News
GitHub to Block pull_request_target Workflows by Default Starting December 2
GitHub is tightening GitHub Actions security with new restrictions on privileged pull request workflows. Here's what changes and how maintainers are affected.
dsh-explorer-editor
Advanced tools
A VS Code-style file manager plugin for DeepSeek Harness Web — DeepSeek Harness 的 VS Code 风格文件管理器插件(浏览、打开、编辑当前对话工作区的文件).
GitHub · 安装 · 主题导入导出 · FAQ · 反馈 Issues · Releases
English · 简体中文
DeepSeek Harness 的 VS Code 风格文件管理器插件:在 Web 侧边栏浏览当前对话工作区的文件,在中间主区域编辑。
A VS Code-style file manager plugin for DeepSeek Harness Web: browse the current conversation's workspace from the sidebar and edit files in the center column.
侧边栏文件树浏览工作区,点击文件后在中间列「文件」视图中编辑(Monaco 编辑器,语法高亮)。
# 在 clone 下来的 dsh-explorer-editor 目录内执行(不是父目录)
cd /path/to/dsh-explorer-editor
dsh plugin --profile web add .
dsh plugin add 会把包 pnpm-link 进 profile 并追加到 dsh.profile.bundles。重启 dsh web 生效(client 插件元数据按名缓存,重启后重新扫描)。
桌面端是 deepseek-harness-desktop 项目(包名 dsh-plugin-desktop)。它与 dsh web 使用互相独立的 profile(桌面端用 desktop,dsh web 用 web),插件不会自动共享——只装进 web profile 的插件在桌面端不会出现,设置 → 插件列表里也不会显示:
# 同样在 dsh-explorer-editor 目录内执行
cd /path/to/dsh-explorer-editor
dsh plugin --profile desktop add .
安装后完全退出并重启桌面端(退出应用,不是关窗口),dsh-explorer-editor 才会出现在侧边栏"工作区 / 文件"页签和设置 → 插件列表中。
注意:不要往
~/.dsh/profiles/desktop/cordis.yml里添加插件——桌面端每次启动都会把它重写为空列表[]。插件的正确入口是 profilepackage.json的dsh.profile.bundles+dependencies(dsh plugin add做的正是这件事)。
dsh plugin --profile web add dsh-explorer-editor
或从 Releases 页面下载 tarball 后本地安装(桌面端把 --profile web 换成 --profile desktop):
dsh plugin --profile web add ./dsh-explorer-editor-0.9.0.tgz
cordis.patch.yml 中的 root 只是无会话时的兜底根目录(默认 process.cwd())。文件管理器打开时,浏览器会解析当前对话的工作区目录并通过 setRoot 重新固定根目录,因此一般无需改动:
- insert:
- id: dsh-explorer-editor
name: 'dsh-explorer-editor'
config:
root: !!js process.cwd() # 仅作为打开文件管理器前的兜底根目录
allowArbitraryRoot: false # 是否允许 setRoot 越出 root(见下)
安全边界:
allowArbitraryRoot默认false,此时setRoot只能把根固定到root之下的目录,防止通过 RPC 越界读取工作区以外的文件。若你的会话工作区可能位于root之外,请把它设为true(等价于旧行为)。所有文件操作仍受「工作区边界」约束——路径一旦逃逸出当前固定的根即被拒绝(含 symlink 逃逸)。
SessionHeader.cwd),通过 setRoot 重新固定网关根目录——不再是启动 dsh web 的目录conversation.view 视图("文件"标签,与"对话/轨迹"并列)。点击文件后在页面内的会话滚动区(非弹窗)显示并编辑:Monaco Editor(VS Code 同款内核,从 CDN 加载)按扩展名自动语法高亮;CDN 不可达时降级为纯文本 textarea.md 文件默认以源码模式打开(可直接编辑),工具栏"主题"按钮旁有 VS Code 风格的预览/源码切换按钮(仅 Markdown 文件显示),点击可切换到只读渲染预览(marked + GFM:标题/列表/表格/任务列表/代码块);模式选择自动记住(localStorage),下次打开沿用fs.watch 递归监听工作区,文件系统变更通过 SSE 毫秒级推送到浏览器,目录树只刷受影响目录(贴近 VS Code 资源管理器);窗口重新聚焦时全量兜底刷新root,越界路径被 host 拒绝(含 symlink 逃逸防护)dshFile 命名空间,zh / en),随 DSH 语言切换;不再出现中英混杂主题设置面板(编辑器工具栏"主题"按钮)支持把当前主题导出为 JSON 文件,或从 JSON 文件导入恢复——和 VS Code 的主题文件机制一致,方便换机器、换环境时迁移你的配色。
dsh-explorer-editor-theme-YYYY-MM-DD.json 文件。导出的 JSON 同时包含本插件字段与 VS Code workbench colors 字段:
{
"name": "dsh-explorer-editor · One Dark",
"type": "dsh-explorer-editor-theme",
"version": 1,
"background": "#282c34",
"foreground": "#abb2bf",
"fontSize": 13,
"colors": {
"editor.background": "#282c34",
"editor.foreground": "#abb2bf"
}
}
支持的格式:
background / foreground / fontSize);colors["editor.background"] 与 colors["editor.foreground"](tokenColors 暂不参与,语法高亮沿用 Monaco 内置配色)。导入成功后配色立即应用并持久化到 localStorage;文件不是有效 JSON 或缺少有效颜色时,面板会给出错误提示。
插件由两半组成,共用包名 dsh-explorer-editor:
| Host 半(Node 进程) | Client 半(浏览器 React) | |
|---|---|---|
| 源码 | src/index.ts | src/client/ |
| 构建产物 | dist/index.js(tsc,保留标准装饰器) | dist/client.js(esbuild,ModuleLoader bundle) |
| 职责 | 文件系统 RPC | 侧边栏文件树 + 中间列编辑器视图 |
| 关键 API | class FileManagerGateway extends TypertRemoteService + @Remote() | ctx.slots.register()、ctx.remote.$mount() |
浏览器不能直接访问文件系统,所以 host 半把文件操作暴露为 RPC 端点(namespace fileManager:listDir / readText / readDataUrl / writeText / createFile / createDirectory / rename / copy / delete / stat / resolve / getRoot / setRoot)。客户端通过 ctx.remote.$mount(TYPERT_REMOTE) 挂载调用面,再用 ctx.get('remote.fileManager') 解析服务后调用。setRoot 用于把网关根目录重新固定到当前会话的工作区目录。
关键约束(SRC descriptor 契约):Typert gateway 用 Function.prototype.toString 从方法签名提取 wire 参数名——所以 host 方法必须用扁平参数(listDir(path: string),不是 listDir(input: {...})),参数名即客户端发送的字段名。两半的命名必须一致。
侧边栏主区域是 sidebar.workspaces 单席位 slot(被工作区浏览器以 priority 0 占用)。插件在 sidebar.workspaces.tabs 槽注册「工作区 / 文件」视图页签条——渲染在工作区浏览器头部行内、替换原「工作区」文字标签,与搜索/操作图标同一行;点「文件」时插件以 priority: -1 注册自己的 shadow 条目,单席位 slot 渲染 priority 最低的条目,文件管理器成为 winner;切回「工作区」时注销条目,工作区浏览器自动恢复。文件树点击文件后,编辑器在 conversation.view 注册的"文件"视图里渲染——即中间列会话滚动区(与 chat / trajectory 并列),点会话头部的"文件"标签进入,非弹窗。
依赖基础包补丁:sidebar.workspaces.tabs 槽需要工作区浏览器 bundle(@deepseek-ai/dsh-client-ui-workspace/lib/client.js)承载——在 sidebar.workspaces 注册的 children 中声明该子槽、在 browserInjected 注入槽的 subscribe/getSnapshot、并在 WorkspaceBrowser 头部用 useSyncExternalStore 判断 hasTabs 后渲染槽替换 sectionLabel。dsh 升级会覆盖该文件,升级后需重打补丁(本机备份参照 dsh-tools/backup/ 下 dsh-client-ui-workspace.client.js.bak-*)。未打补丁时插件自动回退为底栏「文件」按钮。
@deepseek-ai/* 包不能在插件自己的 node_modules 里安装副本:@Remote 装饰器标记存在模块级 WeakMap 中,若插件与 api-gateway 各持一份 dsh-typert-protocol 实例,标记互不可见(RPC 会 404)。必须让 Node 解析到 dsh 安装目录的同一实例:
# 本地开发(本机 dsh 通过 npx 安装时):
ln -s ~/.dsh/profiles/node_modules/@deepseek-ai node_modules/@deepseek-ai
dsh 启动时会维护 $DSH_HOME/profiles/node_modules 的扁平 symlink 回退(healProfilesModuleFallback),指向 dsh 安装目录的每个包。生产发布时插件将 @deepseek-ai/* 声明为 peerDependencies,由 profile 提供。
桌面端(deepseek-harness-desktop)注意:
~/.dsh/profiles/node_modules/@deepseek-ai 重指向 Desktop.app 打包目录(/Applications/DSH Desktop.app/.../app.asar.unpacked/node_modules),该目录裁剪了 .d.ts——保持上面的 symlink 指向 profiles 即可保证运行时与桌面端 api-gateway 同一实例(RPC 正常)。tsconfig.json 用 paths 把 @deepseek-ai/* 的编译期类型查找映射到全局 dsh 安装(有完整 .d.ts);运行时 Node 解析不受影响(仍走 node_modules symlink → profiles → 桌面端实例)。若全局 dsh 路径不同,按 tsconfig.json 注释调整。npm install:npm 会把 node_modules/@deepseek-ai symlink 解引用成真实目录并破坏 profiles 的 symlink 结构,导致 dsh 启动报 "exists and is not a symlink"。需要装新依赖时,装完重新执行上面的 ln -s。npm install # esbuild + typescript + 类型
node build.mjs # 构建 host (tsc) + client bundle (esbuild)
node build.mjs --watch # watch host (tsc --watch) + client (esbuild)
构建产物:
dist/index.js — host 半(Node ESM,tsc 编译以保留标准 stage-3 装饰器;esbuild 会把 @Remote 降级为 legacy 形式导致运行时崩溃)dist/client.js — client 半(window.__ModuleLoader__.load({id, factory}) 格式,react 等 seed 词 external)dsh --profile web --dump-config | grep -A4 dsh-explorer-editor # 确认插件层已组合
# 测试 RPC(需 dsh web 运行中)
curl -X POST http://127.0.0.1:3080/api/fileManager/getRoot \
-H 'Content-Type: application/json' \
-d '{"type":"client-request","rpcId":"t","method":"fileManager/getRoot","payload":{"args":{}}}'
@deepseek-ai/dsh-typert-protocol 双实例问题——检查插件 node_modules/@deepseek-ai 是否是 symlink(ls -la node_modules/@deepseek-ai),不是则按上文建立链接后重启。dsh-explorer-editor:monaco-mirror 指定私有镜像),全部不可达时降级为纯文本 textarea。setRoot 到当前会话的 cwd;若打开前无会话,则回退到 cordis.patch.yml 的 root。dsh web;client 半 bundle 改动后刷新页面即可(rev 变化触发重新加载)。FAQs
A VS Code-style file manager plugin for DeepSeek Harness Web — DeepSeek Harness 的 VS Code 风格文件管理器插件(浏览、打开、编辑当前对话工作区的文件).
We found that dsh-explorer-editor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
GitHub is tightening GitHub Actions security with new restrictions on privileged pull request workflows. Here's what changes and how maintainers are affected.

Security News
/Application Security
A practical guide to securing GitHub Actions against supply chain attacks, covering malicious pull requests, credential theft, dependency risks, and release pipelines.

Security News
Composer 2.11 adds dependency cooldowns, joining package managers that delay new releases to reduce supply chain risks while allowing urgent security updates.