dsh-workspace-studio
编辑精选维护状态: 活跃yishengjun8/dsh-workspace-studio
允许显示工作区的文件树、浏览文件内容、并且允许对话中嵌入引用的文件内容、自由切换思维分支视图,目标是和VSCode相类似的开发体验
$ dsh plugin add dsh-workspace-studio2
星标
0
Fork
JavaScript
语言
MIT
许可证
2026-08-17
创建于
2026-09-19
最近推送
README
🗂️ DeepSeek Harness 工作区 Studio 插件(左中右三栏布局)
English | 中文
此 bundle 将 DeepSeek Harness Web 的根布局替换为左中右三栏:左侧栏(Session/工作区选择器 + 文件树视图切换)· 中部高亮文件预览与受控编辑器 · 右侧聊天。文件预览栏默认在对话左侧,可在「工作区设置 → 内容浏览设置」中切到右侧。文件树不再独占一栏,而是融合进左侧栏,与「会话列表」通过顶部按钮互切。插件保留现有侧栏、会话、详情与全局浮层的 Slot 合约,内置的新建会话、会话列表、设置、聊天、工具详情、审批等仍由原插件提供;工具详情以右侧抽屉覆盖在三栏布局上,不额外占用常驻栏位。会话头部提供「导图」按钮,可随时进入导图模式:左侧区域变成会话分支树画布,右侧聊天保持可见、可继续对话。
📸 界面预览
![]() |
![]() |
|---|
✨ 核心亮点
| 能力 | 说明 |
|---|---|
| 📁 工作区文件树 | 融合在左侧栏「文件浏览」视图,目录优先、逐级展开,刷新后展开状态与滚动位置按会话恢复 |
| ⌨️ CodeMirror 6 编辑器 | 20+ 语言语法高亮、行号、代码折叠、编辑器内搜索、自动换行,支持 14 种文本编码 |
| 🗂️ 预览标签页 | 按会话持久化、跨刷新恢复、拖拽重排、固定标签、草稿不丢失、冲突保护、外部变更自动同步 |
| 🖼️ 渲染视图 | 查看方式菜单:Markdown / HTML 渲染预览、图片直接预览、只读文件分页浏览完整内容 |
| 🎯 编辑器上下文 | 打开文件 / 选区以 <opened_file> / <selection> 前缀注入对话,历史只记录一行摘要;标题守卫自动净化泄漏进会话标题的封套前缀 |
| 🧹 文件操作 | 右键新建 / 重命名 / 复制 / 剪切 / 粘贴 / 删除 / 复制路径,支持快捷键 |
| 🧭 导图模式 | 会话分支树:会话头部「导图」进入导图模式,反向解析完整会话记录切成轮次卡片并持久化,在任意卡片处分叉新分支,可重命名 / 删除卡片、归档整图 |
| 📱 手机模式 | 一键切换手机竖屏布局,文件浏览可铺满手机列 |
| 🔒 安全边界 | 工作区受限读写、路径包含校验、修订版本冲突保护、拒绝符号链接 |
🧩 功能
文件树
- 文件树融合在左侧栏中:侧栏顶部有「会话列表 / 文件浏览」两个视图按钮,「文件浏览」视图下,会话属于某 Workspace 时自动显示其文件树(会话
cwd与 Workspace 路径一致时同样识别);目录优先于文件,支持逐级展开、折叠与手动刷新。 - 文件树展开的文件夹按当前会话持久化,刷新后重新展开并加载内容;标签选中时在树中定位并恢复垂直滚动位置。
- 会话标题右键可重命名当前会话。存在多个同标题会话时,右键菜单会显示匹配到的会话 id 后缀,归档操作需二次确认(防止归档错误会话及其分支)。
- 左侧两栏宽度均可拖拽调宽:侧栏边界与预览栏边界各有一条分隔条(左侧两栏合计最多占视口 80%),布局参数以
localStorage全局持久化。
编辑器
- CodeMirror 6 按文件名或后缀显示行号与语法高亮,未知类型按纯文本显示;内置折叠槽与编辑器内搜索(
Ctrl/Cmd+F、F3)。 Ctrl+K+J展开所有已折叠区域;Ctrl+K+1..9按层级折叠代码(如Ctrl+K+2折叠所有第二层级的折叠区域)。Ctrl/Cmd+S保存快捷键在任意焦点状态可用(含聊天输入框)。- 可编辑文件打开即进入编辑状态(无需「编辑」按钮);面板头提供「取消」「保存」「自动换行」与「从磁盘重新读取」(刷新)。只读文件(外部拖入、超大、截断、混合换行、符号链接或未启用编辑)显示只读原因横幅。
- 每类文件类型组可在工作区设置页选择编辑器高亮预设(默认、经典、暖色、冷色、单色、XML (VS Code) 等 10+ 款),按类型记忆于
localStorage。
编码
- 文件预览自动检测编码(UTF-8 / UTF-8 BOM / UTF-16 LE / BE / GBK / GB18030 / Big5 / Shift_JIS / EUC-JP / EUC-KR / ISO-8859-1 / Windows-1252 / Windows-1251 / ASCII)。
- 右键预览头可「以编码打开…」重新解码,或「另存为编码…」写回磁盘;面板头显示当前编码徽标。
- 编码列表以服务端
/workspace-studio/api/encodings为准,请求失败时回退内置清单,操作不会中断。
预览标签页
- 打开的文件进入按 Session 保存的预览标签页:可
X关闭、拖拽重排,标签页跨重载恢复。 - 右键标签「在新窗口内打开」:Markdown 文件(md / markdown / mdx)在新标签页中直接显示渲染后的文档(GFM:表格、任务列表、删除线等;原始 HTML 按字面文本显示,链接与图片仅放行 http / https / mailto,与面板内预览的渲染策略一致,页面无脚本);HTML 文件原样运行页面脚本,其余文件显示原始文本。
- 固定标签:右键标签可「固定 / 取消固定」,固定标签带图钉图标、自动排前,「关闭其他标签页」只关闭未固定标签。
- 未保存修改时,标签页名称与预览面板标题的文件名末尾显示
·,保存后消失。 - 未保存草稿以暂存盘文件保留(见「编辑与保存」),localStorage 只记脏标记、不存内容;切换文件不会静默丢弃未保存内容。
- 标签条支持滚轮横向滚动,打开新标签自动滚动到可见。
渲染视图
- 预览面板的查看方式由渲染器注册表驱动(与新版 Harness 右侧栏文档预览同源):Markdown 文件可在「源码编辑 / 渲染预览」间切换(GFM 渲染,与「新窗口打开」同策略),打开时默认进入渲染预览;HTML 文件可在「源码编辑 / 页面预览」间切换,打开时默认进入页面预览(点切换按钮即回源码编辑),预览页面的相对脚本与样式表经标准工作区文件接口读取后打包进沙箱 iframe(编辑内容实时生效,打包防抖 400ms)。
- 图片文件(png / jpg / jpeg / gif / webp / bmp / ico / svg)直接以图片预览打开:完整字节经标准工作区文件接口读取,刷新或外部变更后自动重取。
- 只读文本文件(超大截断、过大、只读等)可在「源码 / 只读浏览」间切换:只读浏览分页读取完整文件(编辑器受
maxPreviewBytes截断),滚动到底自动加载下一页,Markdown 渲染为文档、其余代码高亮显示。 - 查看方式按文件切换时重置为该文件的默认视图(Markdown 为渲染预览、HTML 为页面预览、其余为源码编辑)、不持久化;PDF 渲染暂未提供。
编辑与保存
- 可编辑文件打开即进入编辑模式(Markdown、HTML 文件默认进入预览:Markdown 为渲染预览、HTML 为页面预览,点切换按钮即回源码编辑),提供“保存”“取消”与
Ctrl/Cmd+S。 - 暂存盘(草稿文件):编辑时提取一次快照(源文件内容),所有临时修改防抖写入暂存盘文件(
~/.dsh-plugin/dsh-workspace-studio/drafts/<workspaceId>/,长期留档),源文件不被触碰;刷新页面后从暂存盘文件恢复(草稿 + 快照 + 编码)。自动存盘不视为“保存”,·仍保留直到显式保存。localStorage 只保留脏标记,不存编辑内容/快照。 - 保存(合并回源文件):保存时重新读取源文件,与快照比较——
- 源文件未被其他工具改动(= 快照):把暂存内容静默写回源文件,成功后删除暂存盘文件。
- 源文件被改动、且与你的修改不在同一位置:自动三方合并,双方修改都保留后写回。
- 源文件被改动、且与你的修改在同一位置:弹窗逐处展示冲突区域——上方两栏为行内增删对比(我的修改 / 磁盘版本),下方两栏为修改后的实际代码,可分别选择「保留我的版本 / 保留磁盘版本」,取消则放弃保存。
- 取消:放弃临时修改,删除暂存盘文件,编辑器恢复到源文件内容(源文件本身不改动)。
- 外部变更自动同步:默认开启「监听文件更改并自动同步」,对每个打开的标签约每 2 秒检查一次磁盘变更。干净且激活的标签被其他工具改动时自动从磁盘重新加载并保留滚动位置(自动模式显示「已从磁盘重新读取」;「仅提示,不自动刷新」模式显示「文件已在磁盘上更改」提示);未保存的脏标签绝不覆盖,只显示提示由你决定(保存时三方合并或逐处选择);文件被删除时激活标签提示「文件已被删除」。
- 拒绝二进制、非 UTF-8 与工作区外符号链接;截断的大文件、混合换行文件与经符号链接的路径只读。
文件操作
- 可在选中层级新建文件 / 文件夹,
F2重命名。 - 右键菜单:复制名称、复制路径、复制相对路径、「在资源管理器中打开」。
- 右键复制 / 剪切 / 粘贴 / 删除,支持快捷键
Ctrl/Cmd+C、Ctrl/Cmd+X、Ctrl/Cmd+V、Del。 - 剪切 + 粘贴 = 移动;粘贴目标同名自动去重(
a.txt → a-1.txt);删除弹确认对话框,涉及未保存标签时附加警示。 - 剪贴板为内存态、按工作区隔离(跨工作区粘贴置灰),刷新页面即失效;外部文件(拖入的只读预览)不可重命名 / 删除。
搜索
- 搜索内容时结果按文件分组:点击文件头折叠 / 展开该文件的匹配条目,点击匹配条目打开文件并跳到对应行。
- 支持区分大小写切换;大文件仅搜索开头部分时标注「部分」。
- 可在工作区设置页选择搜索结果的默认展开 / 折叠方式。
编辑器上下文
- 编辑器上下文经现有输入 dock 显示为输入框外的不可编辑前缀:启用发送时冻结上下文,文件模式渲染
<opened_file>...</opened_file>、选中文本模式渲染<selection>...</selection>(无选区时不携带文件字节),灰色发送不附加上下文。 - Host 校验并把它拼接到直接用户提示前;对话页折叠成气泡上方显示文件名与行列范围的一行摘要,历史只渲染已记录的用户消息。
聊天体验
- 会话头部标题区是会话切换器:点击弹出下拉面板,列出全部会话(最近更新在前、当前会话高亮、行尾附所属工作区名、子代理会话带「子代理」徽标),点击即切换到该会话;导图家族的分支会话不在其中(根会话保留,便于直达)。
- 界面语言跟随 Harness「设置 → 通用设置 → 语言」(中文 / English)即时切换,无需重启或刷新。
- 聊天中的思考内容(Think 条)以常驻卡片显示:正文视口只展示最新 N 行(可在工作区设置页拖动「思考显示行数」滑块在 5–30 行间调整,默认 10 行),输出中自动跟随最新内容,更早的内容可通过卡片右侧的滚动条回看,点击标题行可收起为单行摘要;用户手动收起的条目不会被强制重新展开。对话中的编辑/写入条目(merged diff 卡片)采用同一卡片模式并始终默认展开:改动内容视口按「编辑显示行数」限制高度(设置页独立滑块,5–30 行,默认 10 行),右侧滚动条可查看完整改动,不再需要「展开剩余」按钮。
/init命令(类似 Claude Code):在当前会话所属工作区的根目录生成或更新AGENTS.md,已有文件时弹层让你选择「更新」或「取消」,由当前 Agent 分析工作区后生成。- 可将外部文件拖入预览面板直接以只读标签预览(会话内有效,不写入工作区)。仅文本类文件可预览:图片、文件夹等非文本内容会提示「无法作为文本预览」(图片属聊天输入区,此为有意行为)。
导图(会话分支)模式
- 会话头部「导图」按钮进入导图模式:导图作为预览区标签页打开(
dsh-ws-preview内,可与其他文件标签页自由切换),右侧聊天保持可见可继续对话;关闭 = 标签页 × 按钮。首次进入时,插件从会话的完整事件日志反向解析全部轮次,把整个会话切成一根提问卡片链,并持久化到~/.dsh-plugin/dsh-workspace-studio/mindmap/—— 该持久化文档是导图的唯一信息源。 - 首次进入前会弹确认框:将普通会话转换为导图会话后,它从侧栏会话列表隐藏,改为对应工作区分组下会话列表末尾的一个自绘条目(点击条目会打开会话并把导图打开为预览标签页);凡由该导图派生出来的 fork 会话都会从列表隐藏,只在导图里管理。该条目支持拖拽排序(顺序按工作区分组持久化)、右键重命名导图标题(与根会话标题相互独立)或「在资源管理器中打开」;家族任一会话流式输出时条目图标持续旋转。
- 导图顶部是虚拟根节点:点击它新建一个空白顶级会话(无继承轮次,同工作区 cwd,自动打开可立即提问);右键根节点可选择「新建会话归属工作区」或「归档整个导图」。
- 点击卡片 = 切换优先、新建兜底:停在某卡片的分支(链尾卡片)点击即切换到该分支(右侧聊天跟随切换,导图内高亮跟随,可自由切换);没有分支停靠的中间轮次卡片(如分支 6-7 里的 6)点击则在该处 fork 新分支并进入对话,新轮次与兄弟轮并列(6 → 8、9 与 7 并列)。所有 fork 都归同一个主导图,绝不新增导图;新分支会话也不出现在侧栏会话列表。分支的新轮次由 Host 在同步时从分支会话的完整日志折叠回文档。
- 右键分支可重命名;工具栏可「归档整个导图」(连同全部分支会话,归档后标签页自动关闭)。右键任意卡片(含根会话卡)可删除卡片(真截断):从上一张卡 fork 出截断后的新会话并归档原会话——该卡片及其后的轮次、由此衍生的所有分支一并移除(原会话归档后当前无恢复入口),聊天与导图从此从截断点重新开始、编号一致。导图支持抓手平移、滚轮缩放与「还原视图」。
- 分支正在输出时(输入问题、agent 生成中),导图会为家族中每个生成中的会话实时显示一张「生成中…」卡片(显示本轮问题文本);每张流式卡与其父卡片带同色炫彩渐变流动光环,两者之间的连线显示同色流动虚线;输出完成后流式卡自动转为正常卡片,光环与流动边消失。流式卡可点击 = 切换到正在生成的会话(右侧聊天跟过去实时看输出、高亮跟随;未收尾轮没有 turn/end seq,不能作为分叉点,右键菜单也禁用);生成中会话的最后一张已完成卡此时按中间卡处理,点击即在它处分叉新分支。
- AI 卡片摘要(可选,默认关闭):在「工作区设置 → 导图浏览设置 → AI 卡片摘要」中启用后,导图会用所选模型自动总结每轮提问(每轮一次小调用,产生少量 token 消耗;摘要为建议性总结,完整原文可悬浮卡片查看)。卡片右键「重新生成摘要」、工具栏「重新生成全部摘要」可随时重算;工具栏「重新生成所有会话总结」只重算全部会话头卡片的总结(不重算已有卡片摘要,缺少卡片摘要的会话会先补齐缺失部分);会话头右键「总结当前会话」为整个会话生成一段总结。摘要模型可选「跟随会话模型」或指定模型,摘要长度与会话总结长度可分别调整(20–200 字 / 20–500 字)。
外观与设置
- 使用 Harness 主题语义变量,支持亮色、暗色与系统主题。
- 设置页顶部提供插件更新组:从 GitHub(yishengjun8/dsh-workspace-studio)的 main 分支检查新版本,一键下载并替换插件的安装文件,完成后提示重启 dsh 并刷新页面生效(本地
file:开发安装只替换 profile 副本,本地仓库不受影响)。 - 插件更新组后紧跟 Token 统计组:弹出面板按标准周 / 自然月(本周、上周、本月、上月、全部)或自定义起止日期统计所有会话日志中的 token 用量,可查看总计或按模型明细(输入、缓存读取、缓存写入、输出),按模型视图可用左侧复选框决定哪些模型计入底部汇总行;默认包含已归档会话(归档不删除日志),可取消勾选排除。数据来自会话日志中的
usage记录,被压缩 / 截断的早期记录不计入;Host 以增量索引缓存每个会话的汇总结果(~/.dsh-plugin/dsh-workspace-studio/token-stats/),每次 dsh 启动后自动在后台预热,未变化的会话直接复用上次缓存(以持久化索引的 stat 修订号为变更信号,首次扫描全量日志、之后只重扫变化的会话),首次打开面板即可秒出;若后台扫描尚未完成,面板先显示部分结果并每 1.5 秒自动刷新(页脚显示「已完成 N / M 个会话」),格式不受支持而读不出的会话只尝试一次并在页脚提示,长扫描每 100 个会话落一次检查点,重启不必从零重算。 - 工作区设置页按组提供:会话浏览设置(侧栏导图条目流式输出时旋转图标的速度,倍速 0–3×,越大越快,默认 1.2×)、导图浏览设置(悬浮高亮与选中高亮颜色、会话头卡片与末端卡片提示色、导图挂载连线弯曲幅度(0–6× 默认 5×,0 为直线)、AI 卡片摘要(启用开关、摘要模型、摘要长度 20–200 字默认 48、会话总结长度 20–500 字默认 64))、文件浏览设置(文件树行高、搜索结果显示方式、文件图标徽标配色)、内容浏览设置(每类文件高亮预设、冲突弹窗对比字号、文件浏览页面显示在对话左侧或右侧(默认左侧)、监听文件更改并自动同步(默认开启,可改为仅提示不自动刷新))、对话页面设置(思考显示行数与编辑显示行数)。
- 侧边栏底部提供「手机模式」开关:开启后整栏布局切换为居中的手机竖屏列,侧栏变为由左上角鲸鱼开合的悬浮抽屉(会话列表与文件树仍在其中);会话头部鲸鱼右侧出现「文件内容浏览」按钮,点击后文件浏览铺满手机列、会话头部保持可操作。手机模式为瞬态状态,刷新后回到桌面布局。
🎨 语法高亮
内置 20+ 语言:JavaScript/JSX、TypeScript/TSX、JSON、HTML、CSS/SCSS/Less、Markdown/MDX、Python、SQL、XML/SVG、YAML、C/C++、C#、Java、Rust、PHP、Go、Shell、PowerShell、Ruby、TOML、INI 与 Dockerfile。
Makefile、.gitignore、LICENSE 与未知扩展名以纯文本显示,仍可浏览与编辑。
🧩 双面实现
一个包内封装三个端面:
- Host 端(
lib/index.js)注册/workspace-studio/api:按 Workspace ID 列目录、读取有上限的 UTF-8 文件,按 membership 或规范化 cwd 授权当前 Session;显式启用编辑时,通过修订版本校验、单段名称校验和原子替换保存已有普通文件、新建文件与文件夹、重命名已有条目,拒绝过期修订版本而不是静默覆盖。另提供/mindmap-doc(读 / 写 / 删)与/mindmap-doc/sync、/mindmap-doc/index、/mindmap-doc/rename、/mindmap-doc/models、/mindmap-doc/regenerate-summary、/mindmap-doc/regenerate-all、/mindmap-doc/regenerate-session-summaries、/mindmap-doc/summarize-session接口:按会话持久化导图文档,反向解析完整事件日志折叠所有会话的轮次,重命名只更新导图标题而不整份往返,AI 摘要的生成 / 重算 / 会话总结由 Host 串行调度。再有/update/check(比较已安装版本与 GitHub main 分支版本)与/update/download(校验并原子替换自身安装目录),供设置页「插件更新」组使用;替换后需重启 dsh 生效。另有/token-stats(按客户端给定的[from, to)毫秒窗口汇总所有会话日志的assistant/messageusage 记录,archived=0排除已归档会话),供设置页「Token 统计」组使用;Host 端以~/.dsh-plugin/dsh-workspace-studio/token-stats/usage-index.json增量缓存按日按模型的汇总结果(以持久化索引的 stat 修订号为变更信号;读不出的会话缓存「不可读」结论,长扫描每 100 个会话落一次检查点,索引已就绪时请求立即返回部分结果并给出warming/progress)。 - Browser 端(
lib/client.js)提供兼容的ctx.layout服务与usePanelInfo标准 Hook(panelInfo根贡献),占用根 Slot,声明sidebar、main(keyed,承载新版 Harness 的会话面板)、details与shell.overlay,并加入文件树、CodeMirror 6 浏览器/编辑器、编辑器上下文行、工作区设置页、/init命令与会话分支导图(预览标签页)。 - 共享不变量(
lib/invariant.js)为每次 Host 请求提供路径包含与写入资格校验。
激活模型
layout 提供方有意不硬注入 conversation:conversation 插件本身消费 layout。因此 bundle 在激活后通过子注入 patch 现有 sendSession seam,并向 conversation.input.dock 注册编辑器上下文行,避免形成激活依赖环。
已知限制与待办
编辑器上下文发送桥适配 Harness 0.1.x 具体的 sendSession、输入提交与队列 steer 实现,因为跨包公开 face 不承载任意 Composer 上下文。这些 seam 都封装在本包内并在卸载时恢复,未来 Harness 版本可能只需更新本 bundle。
布局状态、展开目录、编辑器选区与工作区暂存盘草稿状态均属页面内存状态;预览标签页及其各自的垂直滚动位置在重载后、以及返回原 Session 或 Workspace 时恢复(未保存内容本身存于暂存盘文件,见「编辑与保存」)。
模型体验
当前缀启用且 CodeMirror 主选区非空时,每次发送都会捕获该选区的精确文本、规范化工作区路径与范围,并渲染为 <selection>...</selection> 封装。选区为空时,每次发送只捕获打开的文件路径,并渲染固定的 <opened_file>...</opened_file> 封装;绝不提交完整文件。
Browser 发送桥把渲染后的文本拼接到直接用户提示前,因此普通 user/message 记录包含实际模型可见的上下文。对话页会把该封装折叠成气泡上方的一行摘要,只显示文件名与行列范围;鼠标悬浮该行会显示完整的注入 XML。灰色前缀不贡献上下文;后续每个启用回合都会再次记录相同上下文。
Token 与 KV 缓存影响
选区上下文会增加 <selection>...</selection> 封装以及选中文本的输入 Token。资源管理器先按默认 65,536 UTF-8 字节限制预检选中文本;Host 独立将完整渲染默认限制为 69,632 字节,并最多读取 10 MiB 用于 clean 修订版本校验。截断预览以浏览器权威的选区文本为准。仅路径上下文只增加 <opened_file>...</opened_file> 封装、不携带文件正文。每个启用回合都有自己的日志提示文本,因此 compaction 前重复选区可能增加提示 Token。
📦 安装
在 Git Bash、Linux 或 WSL 中执行。先进入本插件所在目录(用你自己的路径替换):
cd <插件目录>
bash ./install.sh # 默认安装到 web profile
bash ./install.sh web # 也可显式指定 profile
示例路径
C:/GreenSoftware/deepseek-harness/deepseek-harness-plugin/dsh-workspace-studio中的deepseek-harness-plugin是作者自定义的插件目录名,不是固定要求。install.sh以插件 目录为基准向上两级解析 Harness 根目录(供 PATH 无dsh时的pnpm --dir回退使用),因此 推荐把插件放在 Harness 根目录下两层的插件目录中(与示例一致);若 PATH 中已有dsh, 插件放在任何位置都可安装。
脚本优先使用 PATH 中的 dsh;当前目录属于 Harness checkout 且 PATH 无 dsh 时自动使用
pnpm --dir <harness-root> dsh,也可用 DSH_BIN 指定可执行文件。安装完成后停止并重启原有
Web 进程(先停止再启动,让插件随 Web 进程重新加载生效),然后刷新 http://127.0.0.1:3080;
脚本不会启动第二个服务器。
从 Git 直接安装
不依赖本地副本,直接从插件仓库安装(首次安装会用 tsdown 把 src/client/ 与 src/host/ 现场构建出 lib/client.js 与 lib/index.js):
bash ./install.sh --git # 默认安装到 web profile
bash ./install.sh --git web # 也可显式指定 profile
脚本把 git 依赖 spec 解析为当前插件的 GitHub 仓库(可用 GIT_SPEC 环境变量覆盖),并锁定到
当前 HEAD 提交(github:<owner>/<repo>#<commit>),因此后续推送不会悄悄改变已安装的代码。
pnpm ≥ 10 默认拒绝执行 git 依赖的 prepare 构建脚本,首次 add 会失败;脚本会解析 pnpm 打印的
allowBuilds 键、写入该 profile 的 pnpm-workspace.yaml,然后重试,无需手动干预。
⚠️ 允许构建意味着允许该包的
prepare脚本在安装时于你的机器上执行(不在 agent 沙箱内)。 从本插件的官方仓库安装时这是预期行为。手动安装的等价命令是dsh plugin --profile web add github:yishengjun8/dsh-workspace-studio:失败后按 pnpm 提示把 allowBuilds 键复制进该 profile 的pnpm-workspace.yaml,再重跑add。
🗑️ 卸载
bash ./uninstall.sh
卸载后同样需要重启 Web 进程;移除 bundle layer 后内置 ui-layout 自动恢复。
⚙️ 配置
cordis.patch.yml 中插件 row 接受:
| 字段 | 默认值 | 说明 |
|---|---|---|
enableEditing |
false |
是否启用 Host 写入接口;本 bundle 显式设为 true。 |
maxContextBytes |
65536 |
选中文本 UTF-8 预检上限(1024–1048576);仅路径上下文不提交文件字节。 |
maxPromptContextBytes |
69632 |
Host 对完整渲染上下文(含封装与选中文本)的上限(4096–2097152)。 |
maxContextSourceBytes |
10485760 |
clean 修订校验最多读取的原始文件字节(1024–104857600)。 |
maxEditableBytes |
1048576 |
单文件可保存的最大 UTF-8 字节(1024–10485760)。 |
maxEntryNameBytes |
255 |
新建/重命名条目名称最大 UTF-8 字节(1–1024)。 |
maxMutationBodyBytes |
4096 |
create/rename 请求最大 JSON 字节(128–65536)。 |
maxPreviewBytes |
1048576 |
单文件读取并返回的最大字节(1024–10485760)。 |
enableUpdateCheck |
true |
是否启用「插件更新」的检查与下载(设为 false 时检查返回禁用态、下载接口拒绝,设置页该组在首次检查后隐藏)。 |
💡 改配置直接编辑 bundle 的
cordis.patch.yml;为避免 pnpm 复用已安装的本地file:副本,先运行uninstall.sh,再运行install.sh,最后重启 Web 进程。
🔒 安全边界
路径包含校验:Host 接口只接受已登记的 Workspace ID 与相对路径,每次读写都解析真实路径并确认目标仍位于 Workspace 规范根目录内,..、绝对路径与跳出 Workspace 的符号链接均不可访问;Windows 上还拒绝含 : 的路径(驱动器相对形式 C:/a:b 的解析语义意外,且冒号在 Windows 文件名中非法)。接口同时执行与内置 /api 同目的的 Host、Origin 与 Fetch-Metadata 来源检查。
写入保护:写入接口仅在 enableEditing 开启时接受 PUT,正文必须是有上限的 UTF-8 文本,且必须携带读取时的 If-Match 修订版本,版本不一致返回冲突而不覆盖;写入目标必须是已存在且不经过任何符号链接的普通文件。create/rename 沿用相同的路径包含校验,要求单段名称、拒绝已存在目标,并拒绝 Windows 保留设备名(CON/PRN/AUX/NUL/COM1-9/LPT1-9)与以点或空格结尾的名称。Host 通过同目录临时文件、文件同步与原子重命名提交,并尽量保留原权限模式。
上下文安全:编辑器上下文只接受拥有当前 Session 的 Workspace 内相对路径(拥有关系来自 membership projection 或会话规范化 cwd);仅路径上下文不携带文件字节。Host 拒绝符号链接,按磁盘修订校验 clean 选区,maxPreviewBytes 截断预览时以浏览器提交文本为权威,并把渲染文本拼接在直接提示前,因此普通 Session 日志记录实际模型可见上下文;对话页把它折叠成气泡上方显示文件名与行列范围的一行摘要,历史只渲染已记录的用户消息,不重新读取当前编辑器或磁盘。
自更新保护:/update/check 与 /update/download 仅向受信任来源开放(与其余接口相同的 Host / Origin / Fetch-Metadata 门禁);检查下载 main 分支源码包并缓存,安装的正是检查阶段缓存的那份(再次校验包名、版本与 lib/、cordis.patch.yml 等关键文件后提交),经同目录暂存、备份与原子改名完成,失败自动回滚;替换的是插件自身的安装目录(本地 file: 安装只影响 profile 副本)。检查与安装全程只走 codeload.github.com——github.com / api.github.com / raw.githubusercontent.com 常被 hosts 级 GitHub 加速代理指向本地并签发自签证书,Node 的 CA 库会拒绝,而 codeload 不受影响。更新只在用户在设置页明确点击后触发,不自动检查、不自动重启。
⚠️ 这些限制只约束资源管理器自己的文件接口与 Composer 上下文,不改变 agent 的权限策略、沙箱或工具能力;接口为受信任本地 UI 操作提供应用级路径包含校验,不替代 Harness 的内核级沙箱。
📁 项目结构
.
├── package.json # 单包 manifest:bundle patch + client inject + exports
├── cordis.patch.yml # 禁用内置根布局并挂载本插件(自引用单包名)
├── install.sh / uninstall.sh
├── src/client/ # 浏览器源码(多模块:index.js 入口 + constants/locale/api/stores/…)
├── src/host/ # Host 源码(多模块,构建为 lib/index.js)
├── lib/index.js # Host:有界的 Workspace 读、保存、新建、重命名 API
├── lib/invariant.js # Host 共用不变量断言
└── lib/client.js # 预构建三栏布局、文件树与编辑器
CodeMirror 与语言模块已内联到预构建的普通 JavaScript Client bundle;本地 file: 安装无需构建,
从 git 安装时 prepare 会用 tsdown 现场重新构建。维护源码时,在仓库根目录执行
pnpm install --config.auto-install-peers=false,再运行 npm run bundle 重新生成
lib/client.js 与 lib/index.js。
🔄 兼容性说明
针对提供 conversation.input.dock Slot、Session 输入 resolver 与发送服务的 Harness 0.1.x checkout 编写。编辑器上下文功能完全由本 bundle 实现,不要求修改 Harness 源码;发送桥适配 0.1.x 的具体 send/输入提交/队列 steer seam,未来版本可能只需更新 bundle 内桥接代码。其他高优先级 profile/home patch 若重新启用 ui-layout,会与本插件同时占用根 Slot;请保留本 bundle 对 ui-layout 的禁用设置。
更多「界面与体验」插件
dsh-better-sidebar
作者 omdsh-dev
开放的侧边栏底座,支持三方拓展注册新侧边栏页面。内置文件渲染编辑/终端/侧边对话/Git/子代理页面 | Open sidebar foundation, supports third-party extensions to register new sidebar pages. Built-in file rendering/editing, terminal, side chat, Git, and sub-agent pages.
dsh-tui
作者 ccch1mneyyy
DSH 官方公众号收录的 TUI 补位插件:Claude Code 风,鲸鱼顶栏/实时状态/流式思考/双击 Esc 回滚/上下文进度+TPS。npm 一键装。 DSH official WeChat featured TUI plugin — Claude Code style: whale bar, live status, streaming thoughts, double-Esc rollback, context bar + TPS. npm one-click.
dsh-tianshu-tui
作者 huiliyi37
官方 DeepSeek Harness 的交互式终端 UI 插件:自研 ANSI 极简交互渲染、流式 Markdown/工具卡、16+ 主题、slash 命令与选择器、输入历史与本地偏好持久化、LSP 诊断、memory记忆,很丝滑的开发体验。
dsh-popout-sidebar
作者 e2mcc
将侧边栏弹出为独立浏览器标签页,可拖到另一块屏幕使用


