@dongasai/dsh-editor
A file editor in the DSH web GUI right sidebar: open any text file, edit it, and save in place, with a version gate on every save — if the file changed on disk during the edit it stops and asks instead of overwriting. The document preview gains an edit button and a two-step delete button, and a sepa
Install
dsh plugin --profile web add @dongasai/dsh-editor
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
@dongasai/dsh-editor
在 DSH Web GUI 的右侧栏里直接把工作区文件改掉:官方文档预览注册的 Markdown / 代码 /
图片 / PDF / Office 渲染器全部只读,读文件的 Remote 命名空间
@deepseek-ai/dsh-api-workspace-files 也明确写着 "The service exposes no mutation operation.",
这个插件补上写与删的那一半 —— 可编辑的正文、保存按钮、未保存状态与冲突处理,预览头部
的「🗑 删除」按钮(两次点击确认),外加一个自带文件树的右侧栏工具 「文件编辑」:新建、
改名 / 移动、复制 / 剪切 / 粘贴、删除、拖拽整理,都在 GUI 里做完 —— 包括把系统剪贴板里复制好的
文件直接粘进工作区。它们全部打到本插件自己的 Host 路由。
与「用终端 / 让 Agent 改」的差别不是快慢,而是谁在改:人在 GUI 里改完点保存,
版本闸记得住「你读到的是哪一版」,磁盘中途被模型改过就停下来问,不静默覆盖;
删除同样带版本闸 —— 你确认期间文件被改过就停下来,要删得再点一次「仍然删除」。
- 怎么用插件 → 本文件(安装、怎么进编辑器、线上协议、排错、已知边界)。
- 为什么这么实现 → [IMPLEMENTATION.md](IMPLEMENTATION.md)(设计决策、两半怎么拼起来、
四条实现约束的来龙去脉)。
快速开始
两步:装插件 → 在右侧栏打开一个文件。
1. 装插件
四种装法,按场景选。都走同一条 pnpm 路径(@deepseek-ai/dsh-plugin-manager/operations,
共用一把 profile 写锁),装完都会出现在侧栏「插件」页的已安装列表里。
都不需要手写注册行:本包在 package.json 里声明了 dsh.bundle.patch,只要这个 bundle
被选中,生效的那一行就来自本包自带的 [cordis.patch.yml](cordis.patch.yml)。命令行(方式二、
三、四)安装会顺带把它选进 dsh.profile.bundles;Web 上(方式一)是装完点 立即启用才选中 ——
不点就只是「装着但没启用」。
本包已发布到 npm(@dongasai/dsh-editor),所以 spec 有三种写法:包名(走 registry,最省事)、
git 地址、本地路径。包名这条最稳:npm 上的 tarball 就是同名 tag 的内容,版本号与 tag 逐字对应。
方式一:Web 界面(推荐)
DSH Web → 左侧栏插件 → 添加插件 → 填入本仓库绝对路径 /data/ai/dsh/dsh_editor
(或下面的 git 地址)→ 安装 → 装完点立即启用。
- 「添加插件」接受:包名(可带版本)、Git 地址、压缩包、本地绝对路径。
- 装完不点立即启用,就只是「装着但没启用」。
- 侧栏这个「插件」页才能装和开关;设置 → 内置插件里的清单是只读的。
- 填 git 地址时若 GitHub 连不上,界面会提示无法访问 GitHub 并给出改用国内镜像的选项
(镜像只提供注册表里的包与依赖,不代替 GitHub 仓库下载)。
方式二:命令行 · npm registry(分发,推荐)
dsh plugin --profile web add @dongasai/dsh-editor # 钉版本 dsh plugin --profile web add @dongasai/dsh-editor@1.2.0
- 走的是该 profile 里 pnpm 的 registry 配置。本机默认的
registry.npmmirror.com是镜像,
与 npmjs 有同步延迟:刚发的版本可能要先等一会儿才装得到,急用就临时指定
npm_config_registry=https://registry.npmjs.org/ dsh plugin --profile web add @dongasai/dsh-editor。
- tarball 里只有运行所需的文件(
index.js/client.js/cordis.patch.yml/locale/*.json/
icon.svg,外加 README 与 IMPLEMENTATION.md),没有任何构建步骤,装完即用。
- 钉版本时写的是包版本(
@1.2.0),不是 tag 名;两者逐字对应(v1.2.0↔1.2.0)。
方式三:命令行 · git 源(分发)
dsh plugin --profile web add github:dongasai/dsh_editor # 或 dsh plugin --profile web add git+https://github.com/dongasai/dsh_editor.git
dsh plugin --profile <name> <pnpm args> 把参数转发给该 profile 目录里的 pnpm。装进来的是
副本:之后改本仓库代码不影响已装的副本(想边改边用就走方式四)。
--profile必填(不写直接报required option '--profile <name> not specified');
web 换成你要装进的 profile。
- 钉版本:URL 后加
#,例如
git+https://github.com/dongasai/dsh_editor.git#v1.2.0(tag / 分支 / commit 都行)。
本仓库当前 tag 是 v1.2.0,对应 package.json 的 1.2.0 —— 不带 # 就跟 main 走,
每次装到的都可能是新代码(本机开发用方式四的 link:,不受影响)。
- 私有仓库:
git+ssh://git@github.com/dongasai/dsh_editor.git(需已配好 SSH key),
或先把 HTTPS 凭据配好。
- 必须带
git+或github:前缀。git@github.com:owner/repo.git这种 scp 写法不会被认成
git spec,pnpm 会把它当路径,装出一条指向不存在目录的 link: 死链(本机 profile 里就留着一条
这样的残留:依赖名 git → link:github.com:yangshen830-eng/dsh-editor.git,node_modules/git
是断链)。CLI 识别 git spec 的判定也是这个:/^git\+|^github:|\.git(?:#|$)/。
- pnpm 默认会拦
prepare等依赖构建脚本;本包没有任何构建步骤(client.js是手写的浏览器
bundle,由 Host 直接读盘发出),不会遇到。
- git / tarball 这类 spec 要先 fetch 才知道 peer 范围,所以 DSH 版本兼容判定发生在安装之后;
判定不兼容会回滚 package.json 与 pnpm-lock.yaml 并打印 allow-version 命令。本包没有声明
任何 DSH peer 依赖,不会触发。
方式四:命令行 · 本地目录(link,开发)
dsh plugin --profile web add link:/data/ai/dsh/dsh_editor
装成 link: 依赖,代码改动立刻是「已装的那份」—— 适合边改插件边用。
- 改 Host 半边(
index.js):要重启 Harness 才生效(见「已知边界」)。 - 改 浏览器半边(
client.js):刷新页面即可(bundle 每次请求都从磁盘现读,
按内容 revision 换 URL),不需要重启。
装完确认
Config.listConfigs(name: "@dongasai/dsh-editor")里能看到行、且 enabled 为真,即已生效。
再新开一个会话(或重启 Harness)让插件加载,然后按第 2 步在右侧栏验证。
2. 在右侧栏用起来
1. 打开右侧栏的「文件」页,点开任意一个文本文件。
2. 默认就以编辑器打开的文件:`.txt .text .log .json .jsonc .json5 .jsonl .ndjson
.yaml .yml .toml .ini .cfg .conf .config .env .properties .lock`
—— 官方对这些文件本来也只有只读纯文本 / 代码预览,没有不可替代的能力,所以直接给编辑器
当默认视图,点开就能改。
3. 其它文本 / 代码文件(.md .ts .py .sh .html .css .sql .csv …):默认仍是官方的排版 /
高亮预览。要编辑,点预览工具栏上的「✎ 编辑」按钮 —— 它用编辑器页签顶掉这张预览
页签(同一个面板、同一个位置);该文件的编辑器页签已经开着时只聚焦它。也可以走
「打开方式」下拉选「编辑器」,那是就地换渲染器,选择按标签页记住。
4. 改完点「保存」,或按 Ctrl/Cmd+S。
5. 要删掉这个文件:点预览工具栏上的「🗑 删除」(在「✎ 编辑」右边)。第一下只是把它
变成「确认删除」,第二下才真的删 —— 中间那几秒里如果你不点,它会自己变回「删除」。
删掉的文件不进回收站,页签会随之关掉,文件树里那一行也会消失(树自己盯着变更)。
6. 把文件与行号发到对话输入框:在编辑器正文里右键,选「发送到 DSH 输入框」 ——
它把「当前文件 + 选区所在行」拼成 @路径#L行号(选中多行是 @路径#L起-止,没有选区就是
光标所在行)插进当前会话的对话输入框,插在输入框光标上次所在的位置。工作区内的文件按
相对路径写,工作区外用绝对路径;路径带空格时按官方 grammar 加引号。插进去的是普通文本
(不是文件芯片),模型侧按 @…#L 引用语法解析。
3. 用「文件编辑」面板
右侧栏的加号 / 引导页里有一张「文件编辑」卡片(快捷键 Ctrl/Cmd+Alt+E,可在快捷键设置里改)。
它开一个自带文件树的页签:
想做什么 · 怎么做
看目录 · 点目录行展开 / 收起;条目默认「目录在前、再按名字」(工具条上的排序按钮可切成「按类型」,或关掉「目录优先」);一路只有一个子目录的链会折成一行(a/b/c,点它展开链尾);名字以点开头的条目淡显;目录变了会自己刷新(订阅了官方变更流)
找操作 · 每行行尾有常显的「⋯」(不用悬停),行上也有悬停出现的图标;右键任意一行是一份完整菜单
打开文件 · 单击文件行 → 在同一栏里开本插件的页签(面板自己不消失):文本进编辑器页签,图片进图片预览页签(见下)
新建 · 工具条上的「新建文件 / 新建文件夹」落在当前选中的目录(选中文件时是它所在的目录);也可以点某个目录行上的 +
改名 / 移动 · 四个入口:行上铅笔(悬停出现)、行尾常显的「⋯」菜单、右键菜单、工具条上的铅笔(作用于选中行)。输入框里回车提交,名字里带 / 就是搬到子目录(a/b.md);键盘党按 F2
创建副本 · 文件行上的复制按钮:同目录生成「xxx 副本」,重名自动往后编号;目录不支持复制
复制 / 剪切到剪贴板 · 「⋯」或右键菜单里的「复制到剪贴板」(只收文件)与「剪切」(文件与目录都行);键盘党在树上按 Ctrl/Cmd+C / Ctrl/Cmd+X。剪贴板贴着面板底部显示,带一个「清空」
粘贴 · Ctrl/Cmd+V 贴系统剪贴板里的文件(在系统文件管理器里复制一个文件,回面板按一下就行);菜单 / 工具条上的「粘贴」也贴同一份。有内部剪贴板时优先贴内部那一份:复制过来的是「再复制一份」(重名自动编号、剪贴板留着可以连贴),剪切过来的是移动(贴完剪贴板清空)
复制路径 · 「⋯」或右键菜单里的「复制路径」(这个条目的绝对路径)与「复制相对路径」(相对工作区根,如 sub/keep.txt)。成功时面板上方亮一条一次性提示(几秒后自己消失);写剪贴板失败时亮同一行提示但不会自动消失(带「取消」点掉)
在终端打开 · 「⋯」或右键菜单里的「在终端打开」:在右侧栏开一个终端页签,等它的 shell 一变得可写就替你敲一条 cd '<该目录>'(目录行 = 它自己,文件行 = 它所在的目录),终端里能看到这一行。见下面「为什么是敲一条 cd」
删除 · 行上的垃圾桶按钮 → 确认条再点一次。空目录一次确认;非空目录确认条会报条目数,按钮是「递归删除」
拖拽 · 把行拖到目录行上松手 = 搬进它;拖到文件行上
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::2,最后更新 2026-10-25