dsh-files-pane
In-browser files pane for the DSH Web GUI: a Session View tab that browses the host's files and reads them in place
liooil
@liooil
⬇ 2
★ 0
main
安装
dsh plugin --profile web add github:liooil/dsh-files-pane
需要可复现安装时,可在仓库后追加 #commit 固定提交。
In-browser files pane for the DSH Web GUI: a Session View tab that browses the host's files and reads them in place
该插件未提供要点说明,请参考仓库 README。
deepseek-harnessdshdsh-pluginfile-browser
- 安装并启动 DeepSeek Harness:
npx @deepseek-ai/dsh web - 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
- 用 dsh plugins list 确认已安装,必要时重启 Harness 生效
插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。
| 代码仓库 | github.com/liooil/dsh-files-pane |
| 许可证 | MIT |
| 主要语言 | main |
| 下载量 | 2 |
| GitHub 星标 | 0 |
| 最近推送 | 2026-09-10 |
| 收录日期 | 2026-09-19 |
| 分类 | 会话与消息 |
事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。
以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。
# dsh-files-pane
An in-browser **files pane** for the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web GUI:
a Session View tab (`对话 / 轨迹 / 文件`) that browses the host's files and reads them in place —
instead of handing a path to a native desktop opener, which a headless host cannot honour.
在 DSH 网页面板里内置一个「文件」视图标签:左侧两栏目录导航,右侧阅读文件内容。不改动主窗体,
复用聊天窗自己的 Markdown 与代码渲染,点击会话里的任意文件即在其中打开。
## Why it exists
`dsh web` runs on the machine that holds the files; the browser usually does not. Clicking a file
reference in a conversation calls `remote.session.openWorkspacePath`, which on a headless host
spawns `xdg-open` into nothing. This plugin intercepts that one call and renders the file in the
page instead.
## Features
- **Files as a Session View tab** — a third tab beside Chat and Trajectory, full width, one view at
a time. No floating window, no sidebar takeover.
- **Click-through from the conversation** — tool cards, `@path` mentions and produced-file chips open
here, and the tab is selected for you.
- **The chat window's own renderers** — Markdown goes through the shipped `MarkdownText`, code
through the shipped shiki `CodeBlock`, so both look exactly like the conversation.
- **Relative images in Markdown** — `` is read from the host and rendered beside the
Markdown text (`MarkdownText` itself only renders `http(s)` images).
- **Two-column navigation** — a parent column (siblings, directories only, current one highlighted)
beside the current directory, so hopping sideways never needs a trip up.
- **Editable path** — click the bold name in the header, type a path, press Enter. `~` is expanded;
a file path lands on its content, a directory path on its listing.
- **Reading-oriented chrome** — one merged header row (ancestor path + pinned current name, fish-style
`~` and shortening only when the row would overflow), a collapse toggle that puts the listing away
entirely (remembered across reloads), and loading feedback that never blanks the pane it replaces.
- Text is capped at 400 KB per file, images at 4 MB; binary files are announced rather than dumped.
## Install
The package is plain ESM with a hand-written browser bundle: no build step, no dependencies.
**From a checkout** — clone it, then mount it as one row in your profile's patch layer
(`~/.dsh/profiles//cordis.patch.yml`):
```sh
git clone https://github.com/liooil/dsh-files-pane ~/.dsh/plugins/dsh-files-pane
```
```yaml
- insert:
- id: files-pane
name: '/home//.dsh/plugins/dsh-files-pane/lib/index.js'
```
The loader accepts a path-like entry name, and `dsh-client-modules` walks up from it to this
package's `package.json` for the `dsh.client` declaration and the `./client` bundle. The bundle is
then served at `/plugins/dsh-files-pane/client.js`.
**As a package** — the repo declares a `dsh.bundle` manifest (`cordis.patch.yml`), so a published
copy mounts by name instead:
```sh
dsh plugin add dsh-files-pane
```
⚠️ Use **one** of the two. Mounting the same package from two sources at once fails the client
module scan (`resolves from multiple active Loader sources`), so remove the local-path row before
installing the package (or vice versa).
Changing the plugin set (including this first mount) takes effect on the next `dsh` start:
```sh
systemctl --user restart dsh # or however your host is supervised
```
## Layout
| Path | Half | Owns |
| --- | --- | --- |
| `lib/index.js` | Host (Node) | Two same-origin POST routes, `/dsh-files-pane/list` and `/dsh-files-pane/read`, reading the filesystem through the deployment's own `fs` service. |
| `client/client.js` | Browser | The View tab, the header action, the file-open interception, and all presentation. |
| `package.json` | — | The `dsh.bundle` manifest (installable), the `dsh.client` declaration (`platform: web`), and the `./client` export the module scanner reads. |
| `cordis.patch.yml` | — | The bundle patch that mounts this package by name when it is installed as a package. |
The browser half is a hand-written bundle in the client module-table format
(`window.__ModuleLoader__.load({id, factory})`) — the same shape the shipped client packages ship —
so it can `require("react")` and `require("@deepseek-ai/dsh-client-ui-primitives")` directly.
## Two seams worth knowing
Both are reached through Cordis services and both degrade safely, but both are internal enough to
deserve a note:
- **Opening the tab.** The active View is not owned by a service: the session header and body both
read it from the `conversation.session` slot **store** (`actions.setView`). Selecting this tab
programmatically therefore goes `uiSession.adapter.resolve(sessionId)` →
`slots.resolveStore(entry.store, binding)` → `store.actions.setView('files')`, which is the same
cached per-session instance the header reads. If a future release renames either hop, the failure
is logged and the plugin falls back to manual tab switching.
- **Taking over the file opener.** `remote.session.openWorkspacePath` is replaced on the Remote
namespace service (saved descriptor, restored on unload) and answers with the Remote envelope
`{ok, value}` the caller expects. This is what makes a click in the conversation land here.
The two host routes sit outside `/api` (no gateway involved), so they carry their own guard: POST
only, plus an Origin/Host same-origin check.
## Development
There is no build step: edit `client/client.js` and reload.
- **Browser half only** — ask the host to re-hash the bundle in place, then refresh the page:
```js
ctx.get('clientModules').rebuilt('dsh-files-pane')
```
(A tiny Cordis plugin calling this is enough; a page refresh then fetches the new revision.)
- **Host half or `package.json`** — restart `dsh`.
The client HMR driver only helps while `pnpm run dev:web` is rebuilding bundles from a checkout; this
package is served from its own directory, so the two steps above are the whole loop.
## License
MIT — see [LICENSE](./LICENSE).
数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。