Bundle
dsh-file-explorer
Persistent web file explorer: lazy directory tree, search/filter (Ctrl+F), preview + inline editing (Markdown render, syntax highlight, line numbers, virtualized large files), reveal in system file manager, IDE-style context menu (new/rename/copy/paste/delete-to-trash/paths), drag-and-drop move, dock/float panel, workspace follow.
- Source
- Zalpha263
- stars
- 5 stars
- License
- MIT
- Updated
- Updated 3 days ago
Readme
# dsh-file-explorer
> DeepSeek Harness(DSH)Web UI 的文件浏览器:不离开聊天界面就能浏览工作区文件、预览与编辑内容,面板可停靠、可浮动。
## ✨ 功能特性
- **懒加载目录树**:按需展开工作区目录,目录在前、文件带大小;默认隐藏 `node_modules`、`.git` 等(可切换)
- **树内搜索过滤**:`Ctrl+F` 呼出搜索条,即时过滤已加载节点(保留目录层级);命中子串高亮、`↑↓` 导航、`Enter` 打开、匹配计数与空状态;跟随「显示隐藏」开关
- **Markdown 渲染预览**:`.md` 文件默认富文本渲染(GFM 表格 / 任务列表 / 删除线、代码块语法高亮 + 一键复制、可折叠标题目录、限宽居中);`渲染 / 编辑` 切换(`Ctrl+[` / `Ctrl+]`),按文件类型记忆上次模式
- **IDE 式实时高亮编辑**:打开代码/文本文件直接进入编辑视图(无需切编辑模式)——输入即所见语法高亮(客户端内联 highlight.js,34 种语言,与只读视图同版本同调用、高亮一致);行号随输入实时同步、滚动精确对齐;长行横向滚动(不软换行);`Tab` 缩进、`Ctrl+S` 保存、`Esc` 退出;>4MB 分段「继续加载」;深浅主题自动切换配色
- **预览独立卡片**:预览在独立浮动卡片中打开(面板内预览区退役、树区占满);卡片可拖动、四边四角缩放、双击最大化/还原、`Esc` 或 × 关闭;单卡片复用
- **导航与工具**:拖放移动、IDE 式右键菜单(新建/重命名/复制/粘贴/复制路径/删除到回收站)、跨平台回收站、工作区自动跟随、停靠与浮动、ui-beautify 插件面板适配、偏好记忆
- **HIG 风格界面**:Apple HIG 规范统一(系统字体栈、8pt 圆角间距、深浅色材质、SF Symbols 风格图标、150–200ms 动效)
### ⌨️ 快捷键(按 `?` 查看)
| 键 | 动作 |
|---|---|
| `Ctrl+F` / `⌘F` | 搜索 / 过滤文件名 |
| `Esc` | 关闭搜索 · 退出编辑 · 关闭浮层 |
| `↑` / `↓` | 搜索结果中导航 |
| `Enter` | 打开选中文件(目录则展开) |
| `→` / `←` | 展开 / 收起目录 |
| `Ctrl+[` / `Ctrl+]` | 切换渲染 / 编辑视图(仅 Markdown) |
| `Tab`(编辑中) | 插入 2 空格缩进 |
| `Ctrl+S`(编辑中) | 保存 |
| `?` | 快捷键帮助(也可点工具栏「帮助」按钮) |
## 安装
### 前置要求
- DSH `0.1.1-rc.2`(或兼容的 `0.1.x` 系列);Windows / macOS / Linux 均支持(路径处理按平台自适应)
- 官方安装方式需要 [pnpm](https://pnpm.io/zh/)(`npm install -g pnpm`)
### 官方方式(推荐)
```bash
dsh plugin --profile web add github:Zalpha263/dsh-file-explorer
```
- 装完**重启 DSH**,会话标题栏右侧会出现「📁 文件」按钮(安装 ui-beautify 后由「🧩 插件面板」统一管理)
- 升级 / 卸载:`dsh plugin --profile web update/remove dsh-file-explorer`
<details>
<summary>旧版手动安装(仅 v1.2 之前使用,已不推荐)</summary>
DSH 旧版本没有 `dsh plugin` 流程,需要把本包复制到两处并手工注册:
1. 复制包到 profile 目录:`$DSH_HOME/profiles/<profile>/node_modules/dsh-file-explorer`
2. 复制包到 dsh 安装目录:`<npmRoot>/@deepseek-ai/dsh/node_modules/dsh-file-explorer`
3. 在 `$DSH_HOME/profiles/<profile>/cordis.patch.yml` 追加注册行:
```yaml
- insert:
- id: file-explorer
name: dsh-file-explorer
```
4. 重启 DSH。
</details>
## 使用说明
### 打开方式
- 会话标题栏右侧「📁 文件」按钮(ui-beautify 安装时入口为「🧩 插件面板」)
### 面板操作
| 控件 / 操作 | 作用 |
|-------------|------|
| 右侧 / 中间 / 浮动 | 停靠模式切换;「右侧/中间」模式拖边缘调整宽度 |
| 标题栏拖动 | 浮动模式下拖动面板位置 |
| 面板四边 / 四角 | 浮动模式下自由调整大小 |
| ↻ 刷新 | 重新加载当前目录 |
| 👁 隐藏 | 显示 / 隐藏 `node_modules`、`.git` 等条目 |
| 预览区上方分隔条 | 拖动调整预览区高度 |
| 点目录 / 点文件 / ✕ | 展开目录 / 打开文件预览 / 关闭预览 |
### 操作速览
- **打开与编辑**:点文件即打开预览——代码/文本文件直接进入**高亮可编辑**视图(输入即所见);`.md` 默认富文本渲染,可切「编辑」;`Ctrl+S` 保存、`Esc` 退出;保存带版本检测,编辑期间被外部改动会拒绝保存
- **拖放移动**:按住文件 / 文件夹行拖到目标目录行(或树空白区)松开即移动;拖到自身 / 子目录被拒绝
- **右键菜单**:新建文件(内置 `txt` / `md` / `py` / `js` / `json` / `ts` / `html` / `css` 模板)、新建文件夹、重命名、复制、粘贴(同名自动加后缀)、复制绝对 / 相对路径、删除(确认后移入回收站)
- 提示:粘贴到「文件」= 粘贴到其所在目录;删除目录会连同全部内容移入回收站
## 卸载
```bash
dsh plugin --profile web remove dsh-file-explorer
```
重启 DSH 后插件不再加载,面板消失,无残留。
## 常见问题(FAQ)
| 问题 | 原因与解决 |
|------|-----------|
| 点「📁 文件」没有出现面板 | 多为页面缓存或渲染异常:先硬刷新(Ctrl+F5);仍不行则重启 DSH |
| 树里显示红色错误行 | 该路径当前不可读(权限 / 已删除);点「↻ 刷新」重试 |
| 保存文件提示「文件已改变」 | 该文件在编辑期间被其它程序修改;重新载入后再保存 |
| 删除的文件去哪了 | 系统回收站;不可用时落内置回收站 `~/.dsh-file-explorer-trash/`(自动清理:保留 30 天、最多 200 条) |
| 复制到剪贴板失败 | 浏览器在非安全上下文禁用剪贴板 API(本机 localhost 通常可用);可改用右键「复制」内部剪贴板 |
| 面板位置跑出屏幕 | 清除浏览器该站点的 `dsh-file-explorer:*` localStorage 键后重新打开 |
| 与旧版 / 临时版插件冲突 | v1.2.0 起通过官方 bundle 只安装一个实例即可,移除其它副本 |
## 兼容性
- 目标版本:DSH `0.1.0-rc.7`;Windows / macOS / Linux(路径分隔符、大小写敏感、回收站策略均按平台自适应)
- 部分 CSS 选择器(侧边栏宽度探测 `.pI_x6G_frame` 等)针对该版本的客户端产物编写,**DSH 大版本升级后可能需要复核**
- Host 半区依赖 dsh 自带的 `@deepseek-ai/dsh-typert-protocol`(peer 依赖)——**不要**单独安装该包的独立副本,否则 Remote 桥会失效
- **写操作边界(v1.8.1)**:编辑保存 / 新建 / 重命名 / 复制 / 移动 / 删除由 Host 半区直接通过 Node `fs/promises` 执行,并**限制在当前工作区根目录内**——工作区外的写 / 删 / 改名 / 移动会被拒绝(只读的浏览与预览不受限)。这是刻意设计(用户手动操作的文件管理器),但仍**不受 DSH 的 read-only / workspace-write 策略约束**,请勿在不可信环境下使用
- 大目录(如 `node_modules`)整目录复制 / 跨设备移动会较慢,属正常现象
## 开发者
- **Host 半区**(`lib/index.js`):`FileExplorerService` 注册 `fileExplorer` 远程服务(`fsList` / `fsRead` / `fsWrite` / `fsCreate` / `fsRename` / `fsCopy` / `fsDelete` / `fsMove` / `wsRoot` / `wsList`);读操作走 DSH `fs` 服务,写操作 `node:fs/promises` 直连;删除按平台走 PowerShell / osascript / gio trash,失败落内置回收站(30 天 / 200 条自动清理);`fsMove` 处理跨设备(EXDEV)复制 + 删除回退;`agent/status` + `session/event` 维护最近活跃工作区
- **Client 半区**(`lib/client.js`):`__ModuleLoader__.load` 加载;`ctx.remote.$mount` 自挂载 `fileExplorer` 命名空间;零 React hooks(原生 DOM 渲染);路径拼接 / 相对路径 / 大小写比较按 `platform` 自适应;检测到 ui-beautify 的 `dock` 服务时注册为插件面板
- 改代码后:Client 改动刷新页面即可生效,Host 改动需重启 DSH;无需构建
- 已安装用户升级:`dsh plugin --profile web update dsh-file-explorer`
## 版本历史
- **v1.10.0**:适配 DSH 0.1.2-rc.1 + 安全/正确性加固——① **封堵目录穿越**:`assertInsideWorkspace`/`assertNotWorkspaceRoot`/`assertNoSelfNesting` 比较前先 `resolve()` 词法归一化(原前缀字符串检查可被 `D:\ws\..\outside\f` 绕过);② **版本令牌族分裂修复**:`FsInfo.version`(0.1.2-rc.1 `ctx.fs` 的不透明令牌)优先于 mtimeMs|size 回退(旧读法恒 null → 陈旧检查静默失效),`fsWrite` 改走 `ctx.fs`(resolve→stat→writeText→stat)与读操作同族令牌 + 原子写 + 沙箱围栏;③ 工作区字段漂移 `w.workspaceId`→`w.id`;④ 侧栏 AppFrame 定位去掉 `.pI_x6G_frame` 哈希类回退,改按稳定契约(`data-sidebar-collapsed`/`data-dragging` + `grid-template-columns` 内联样式);⑤ 活动工作区探针取「选中会话行之前最后一个展开组」(多工作区不再跟随错误组);⑥ 编辑器关闭时自移除 document 级 selectionchange 监听(防累积);⑦ 空目录显示「(空目录)」空态;⑧ `dsh.client.inject` 幽灵条目清理、peer 升至 `^0.1.2-rc.1`。宿主接口逐项核对(ctx.fs/agents/workspaceRegistry/sandboxPolicy/事件/Remote 手工装饰器技巧)仅上述漂移;reveal-in-explorer 已不存在(回收站仍走独立 child_process,正确)。遗留:fsRename/fsCopy/fsMove/fsDelete/fsCreate 无 `dsh-fs` 等价 API,仍走 node:fs + 词法围栏(沙箱部署下五类操作不经 fs-sandbox 规范化围栏)。
- **v1.9.20**:修复深色主题检测失配——宿主(dsh-client-ui-theme)的权威主题信号是 `<body data-ds-dark-theme>` 属性("深色/浅色/跟随系统"即切换它),此前仅检测 `<html data-theme>`/`class`/`prefers-color-scheme`,手动深色时全部失配 → 深色卡片上整套套用浅色配色(正文 `#24292f`、关键字 `#cf222e`),表现为"深色下字色吃力";现以 `body[data-ds-dark-theme]` 为首选信号(旧信号降级兜底),MutationObserver 同步观察 body 属性变化,深浅切换即时生效;浅色 hljs 配色同步换为 **VS Code Light+**(`#0000ff` 关键字、`#a31515` 字符串、`#008000` 注释、`#795e26` 函数、`#267f99` 类型、`#001080` 变量、`#098658` 数字、`#cd3131` 删除);深色配色维持 v1.9.19 的 Dark+。
- **v1.9.19**:深色模式预览配色与绘制顺序修复——①深色 hljs 调色板由 GitHub Dark 换为 **VS Code Dark+**(`themes/dark_plus.json`):正文字 `#d4d4d4`、关键字/元信息 `#569cd6`、字符串 `#ce9178`、数字 `#b5cea8`、注释 `#6a9955`、函数 `#dcdcaa`、类/类型 `#4ec9b0`、变量/参数/属性 `#9cdcfe`、删除 `#f44747`;②**预览卡片创建时即打 `data-fexp-theme`**(此前仅在面板构建/主题切换时打标,卡片可能长期缺失标记、深色下整套落到浅色配色,正文 `#24292f` 在深色玻璃底上几乎不可读——即"深色下字色吃力"的主因);③修复编辑器横向滚动时正文压行号条:内容列/token 为定位元素(无 z-index)按 DOM 树序画在 sticky 行号条之上,行号条提升 `z-index:2` 后文字从条下穿过。
- **v1.9.18**:编辑器新增撤回/反撤回(VS Code 语义)——自建每文件操作历史(`editUndo`,保存/模式切换/关闭重开均保留,文件被外部修改时丢弃):undo stop 分组(连续输入/删除同一锚点合并为一步,粘贴/剪切/回车/Tab/IME 整词/词删除各自一步,不按时间分段);叠加**双区间记录**(旧区间=重做、新区间=撤销,配选区钳制的前后缀 diff,正确处理"插入与相邻字符相同"等情形);撤销/重做恢复文本+光标/选区;跨保存可撤(保存=检查点);工具栏新增「撤销/重做」按钮(随历史禁用)+ Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y(接管原生栈,含之前不可撤销的 Tab 缩进与 IME 整词提交)。
- **v1.9.17**:修复编辑器光标在中文/全角/emoji 行内的横向错位——编辑器几何由"每字符 = 1 个等宽列"升级为**宽度感知**:ASCII 按实测 `editCharW`(DOM span 测量,替代 canvas,解析更可靠)、中日韩/全角/假名/谚文/emoji(含代理对)按实测 `editCjkW`(≈2 倍宽)累加,Tab 仍按 4 列网格步进;光标、选区底条、点击映射、IME 覆盖条共用同一几何,修复中文文档(如含中文 Markdown)中光标停在可见文字末尾左侧约 1~2 个汉字的错位。
- **v1.9.16**:预览卡片/独立面板缩放重构(对齐 ui-beautify 卡片)——把手从卡片/面板内缘移出,改为**独立 overlay chrome 层**:边条 6px 跨骑边界(3px 内 + 3px 外)、两端让 12px,四角 12×12 外凸 6px,边角互不重叠;此前内贴式把手(边 6px/8px + 角 18×18,z-index 压在内容上)会遮挡代码视图底部的横向滚动条与「继续加载」区域,且左上/右上角块覆盖标题栏 × 关闭按钮(点 × 误触缩放);平时透明仅光标、拖动中品牌色高亮;独立面板(无 ui-beautify 时)同规格:float 8 向 / right 仅 w 边 / middle 仅 e 边,方向随 dock 模式;有 ui-beautify 时面板 chrome 仍由宿主提供。
- **v1.9.15**:编辑器底层重构(按 VS Code / Monaco 架构)——单一滚动容器承载行号/高亮/光标/选区(删除"透明 textarea 叠镜像高亮层"双坐标方案:该方案三代错位 bug:三体滚动累积漂移、行号列宽双倍计入、tab 步长 8/4 不一致);行号列与正文解耦(sticky 固定左侧、随内容纵移、宽度变化不影响正文坐标);光标/选区/鼠标点击/IME 覆盖的像素位置全部由同一套编辑器几何计算(等宽字符宽 canvas 测量 + tab 4 列步进 + 行起点数组二分),渲染与输入共用,从机制上杜绝错位;输入改为隐藏 textarea(2×2px 跟随光标,Monaco TextAreaInput 同思路),保留原生 undo/剪贴板/IME;IME 合成期间自绘覆盖条;hljs 行结果按行文本缓存(输入只重算变化行);只读视图(截断/降级)与编辑器同构。修复编辑器行号与正文整体右偏、光标不在文字末尾/点击与输入错位(含此前修复未同步到安装副本导致的"修了还坏"排查)。
- **v1.9.11**:修复编辑器光标错位——实时高亮编辑器(透明 textarea 叠镜像高亮层)两层横向坐标曾被「行号列宽双倍计入」(镜像容器被左移 `w`,行内又从 `w+12px` 起),可见文字整体比光标/点击坐标偏右一个行号列宽(默认 44px ≈ 6 字符),表现为光标不对齐文字末尾、输入字符出现在光标右侧;同时镜像层统一 `tab-size:4`(textarea 为 4、镜像默认 8,含 Tab 的行进一步漂移)。另修正 `package.json` 版本号滞后(代码注释已到 v1.9.10 未升版本)。
- **v1.9.7**:审计加固——修复「继续加载」第二次起每次偏移多跳一段导致内容静默丢失(`offsetChars` 语义改为"下一段起始偏移");修复工作区拒绝跟随失效(`declinedFollowRoot` 从未被读取,编辑未保存时确认框每 800ms 轰炸);Markdown 渲染修复两处 XSS(标题内联 HTML 未转义、链接 href 属性未转义可突破属性边界);文件总行数统计按 `path@version` 缓存(大文件多次「继续加载」不再反复整文件重读)并修正尾换行文件的 off-by-one;工作区根目录禁止删除/重命名/移动;合并两套重复的工作区根探测逻辑(统一错误隔离);删除死代码(未用图标 `chevronUp`/`eyeOff`/`code`/`text`/`plus`、未用常量、退役预览区 splitter 残骸);**重做编辑器为 IDE 式实时高亮**——v1.9.9 的透明叠加层从不跟随输入重绘导致输入不可见,已重写为:透明 textarea 叠在虚拟化高亮层上,输入即实时语法高亮(客户端内联 highlight.js 11.12 共 34 种语言,与只读视图同版本同调用、高亮一致;`tools/inline-hljs.mjs` 生成内联区,升级 hljs 后重跑即可),行号随输入同步、滚动精确对齐,中文输入法合成期间不闪烁;长行横向滚动(不软换行,软换行留待后续按"逐行测量"增强);**修复编辑器行号/对齐**——行号栏与高亮层不再用 transform 镜像滚动(曾导致行号只显示一部分、滚动脱节),改为原生滚动同步(scrollTop/scrollLeft 直赋、滚动条隐藏),行号栏宽度与文字偏移统一为 `max(44px, 14+位数×8)`(杜绝小文件文字压行号);**修复光标与行号对不齐**——三体滚动同步(textarea/行号栏/高亮层)在行数多、滚动深时易累积错位,重构为单一镜像滚动容器:行号 span 与高亮 span 处于同一行结构、同一 scrollTop(行号列 `position:sticky` 固定左侧),对齐由构造保证;textarea 显式锁定 13px/20px 字体指标,排除字体度量差异;**修复浮层盖住设置弹窗**——设置弹窗被侧边栏层叠上下文困住、有效层级≈0,单纯降 z-index 无效,现检测 `sidebar.settings` 槽内 fixed 层并在设置打开时隐藏预览卡片/面板/菜单/帮助/Toast(关闭后原样恢复,未保存编辑保留),同时插件浮层 z-index 由 2147483xxx 降至 1000 以下(被应用对话框正确覆盖)。
- **v1.9.x**:大版本——Markdown 渲染预览 + IDE 式实时高亮编辑(text-overlay 输入即高亮、`pre-wrap` 自动换行、行号与预览一致)、预览独立浮动卡片(拖动 / 四边四角缩放 / 双击最大化)、树内搜索(Ctrl+F)、快捷键帮助浮层(右上角、可拖动)、HIG 风格界面;服务端引入 `marked` + `highlight.js`(`lib/render.js`)。期间迭代:行视图改 table 布局消除换行重叠、卡片缩放 grip 修复、毛玻璃移除后恢复、移除「在资源管理器中显示」与「源码/纯文本」只读视图、编辑器整合取代独立编辑模式。
- **v1.8.x**:安全加固(破坏性写操作限制在工作区根目录内)+ 颜色值 token 化重构。
- **v1.7.x**:接入 ui-beautify 统一插件面板(卡片 / 经典模式统一管理)、移除悬浮球、健壮性优化(目录缓存上限、blur 竞态、面板重建清理、拖动跟随)。
- **v1.6.x**:适配 ui-beautify 卡片模式(停靠卡标签面板、⧉ 浮动、双向状态同步、经典模式回退)。
- **v1.5.x**:跨平台健壮性 + 拖放移动 + 系统回收站(Win PowerShell / macOS Finder / Linux gio,带内置回收站兜底并自动清理);修复大文件预览、二进制识别、浮动面板打不开、拖放落下/高亮等。
- **v1.4.x**:删除到回收站 + 实时刷新。
- **v1.3.x**:文件内联编辑与 IDE 式右键菜单(新建/重命名/复制/粘贴/复制路径 + 磁盘冲突检测)。
- **v1.2.x**:支持 dsh 官方 bundle 安装(`dsh.bundle.patch` + 自带 `cordis.patch.yml`);typert-protocol 改 peerDependency 保证与 gateway 共享模块实例。
- **v1.1.x**:v2 架构重写(Client `$mount` 自挂载命名空间、Host 用 `TypertRemoteService` 自动注册),修复 v1 加载失败。
- **v1.0.x**:v1 初版,已被 v1.1 取代。
## License
MIT
Install
dsh plugin --profile web add github:Zalpha263/dsh-file-explorer
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-file-explorer from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.