deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
DSH 的一体化界面增强插件:对话宽度、思考块、界面中文化、会话与工作区管理与入场动效。
DSH(DeepSeek Harness)的多功能增强插件。把对话宽度调节、思考块交互、输出语言、界面中文化、设置面板补丁、会话删除、工作区分页与入场动效收进同一个插件,每项功能独立开关、改动即时生效。
dsh-plugin-width-slider 面向 DSH 的日常使用场景,补齐官方客户端尚未提供、或使用体验不够顺手的能力:
本插件整合了两个上游插件(dsh-think-zh-expand、dsh-client-ui-custom)的成熟能力,安装本插件后无需再单独安装它们,详见兼容性与已知限制。
localStorage 的 dsh.conversation.contentWidth,重启 DSH 后启动即应用,无需打开设置页。dsh.conversation.contentWidthFollow。client.js,升级不会被覆盖。DisclosureRow 与官方思考图标,正文为纯文本(与官方 ReasoningRow 一致),外观与官方保持一致。MarkdownText 渲染,代码块、表格、公式由官方管线处理;围栏(dsh-ui、mermaid 等)完全交给 genui、dsh-mermaid-render 等专门插件,不存在两套 Markdown 渲染互相压制的问题。整合自 dsh-client-ui-custom,设置项收进本插件的功能总控页。
standard(280–350ms)、纯透明度 fast(150–200ms)、新建对话大表面 medium(400–500ms);列表逐项入场步长 70ms,尾部超过 420ms 一起入场;落位类入场(上浮、缩放、面板展开)用带 3% 过冲的 linear() 曲线收尾,关闭类动画单独用 ease-in-expo。| 项目 | 要求 |
|---|---|
| 运行环境 | DSH(DeepSeek Harness),Windows 10/11 |
| DSH 版本 | >= 0.1.5-rc.1 |
| Node.js | ^22.11 或 >= 24 |
| 平台 | 仅 win32 |
本插件由浏览器端注入与 host 端两部分组成:
lib/client.js注入页面,lib/index.mjs在 host 进程提供/api/width-slider端点,两者都随 DSH 重启生效。
下文中的
<profile>指你实际使用的 profile 名。任选一种方式安装后,请重启 DSH:host 端index.mjs、client bundle 以及/api/width-slider端点都需要重启才会生效。
dsh plugin --profile <profile> add dsh-plugin-width-slider
cd C:\Users\<用户名>\.dsh\profiles\<profile>
pnpm link C:\path\to\dsh-plugin-width-slider
修改代码后执行 npm run build 并重启 DSH 即生效,无需复制文件。
将构建产物复制到 profile 的 node_modules 目录:
dsh-plugin-width-slider/
├── package.json
├── cordis.patch.yml
└── lib/
├── index.mjs # Host 端入口
└── client.js # Client 端 bundle(ModuleLoader 握手)
复制到 C:\Users\<用户名>\.dsh\profiles\<profile>\node_modules\dsh-plugin-width-slider\,并在该 profile 的 package.json 中把 "dsh-plugin-width-slider" 加入 dsh.profile.bundles 数组,然后重启 DSH。
lib/ 产物,重启 DSH 生效;功能开关与各项偏好保留。所有配置位于设置面板的 Width Slider 区块,改动即时生效、重启保留。除「跟随窗口宽度」外,各开关默认开启。
| 分组 | 开关 | 说明 | 默认 |
|---|---|---|---|
| 对话宽度 | 启用对话宽度滑块 | 关闭后恢复官方原生宽度拖拽手柄 | 开 |
| 对话宽度 | 跟随窗口宽度 | 内容宽度实时等于对话列宽;开启后手动拖动不可用 | 关 |
| 思考与输出 | 思考块增强渲染 | 思考块展开/收起交互总开关 | 开 |
| 思考与输出 | 思考/回复强制中文 | host 端注入最高优先级语言规则 | 开 |
| 动效 | 对话入场 | 对话内容入场动效 | 开 |
| 动效 | 侧边栏 | 侧边栏树入场动效 | 开 |
| 动效 | 新建对话 | 新建对话欢迎界面入场动效 | 开 |
| 动效 | 设置界面 | 设置面板展开、页面切换与关闭动效 | 开 |
| 动效 | 按角色入场 | 对话行按角色选择入场:用户消息侧向滑入、助手正文用所选样式、工具与系统行轻微淡入 | 开 |
| 界面 | 界面中文化 | 替换官方残留英文标签 | 开 |
| 界面 | 弹窗可拖拽 | 设置面板窗口化(拖拽调宽高、移动、复位) | 开 |
| 界面 | 弹窗按比例跟随 | 弹窗尺寸按窗口比例(62% × 82%)自适应 | 关 |
| 界面 | tab 栏滚动 | 设置左侧导航超高时显示滚动条 | 开 |
| 界面 | 会话删除 | 会话行「⋯」菜单新增删除项 | 开 |
| 界面 | 工作区分页 | 侧栏工作区标题行改为页签栏 | 开 |
| 界面 | 侧边栏工具并入 | 工作区标题行的搜索 / 视图 / 添加工作区三个按钮并入「新建会话」行,页签行独占整行 | 开 |
| 分组 | 选项 | 可选值 | 默认 |
|---|---|---|---|
| 思考与输出 | 显示方式 | 思考完自动收起 / 始终展开 | 自动收起 |
| 动效 | 对话入场样式 | 淡入上浮 / 轻柔淡入 / 上浮放大 / 右侧滑入 / 模糊显影 / 轻盈缩放 | 淡入上浮 |
| 动效 | 侧边栏样式 | 左侧滑入 / 轻柔淡入 / 纵向展开 / 自上而下 | 左侧滑入 |
| 动效 | 新建对话样式 | 轻柔显影 / 轻柔淡入 / 柔和绽放 / 柔和缩放 | 轻柔显影 |
| 动效 | 预设 | 流畅 / 优雅 / 极简(一次写入全部相关开关与样式) | — |
| 通用 | 恢复默认设置 | 重置全部开关与宽度、设置面板尺寸记忆,并刷新页面 | — |
截图与动图来自 DSH 实测,存放于
image/目录。
宽度滑块 · 按下即预览

设置面板窗口化


工作区分页




| 机制 | 说明 |
|---|---|
| Slot 注入 | settings.section(功能总控页,id width-slider)、shell.overlay(会话删除确认框)、conversation.chat.node(思考块渲染器)、sidebar.workspaces(工作区分页 wrapper) |
| 宽度应用 | 向每个 [data-phase] 对话根元素写入内联 --dsh-chat-user-width,与官方 onHandleDrag 同路径 |
| 宽度启动恢复 | client 启动即应用持久偏好:跟随模式启用全局 ResizeObserver watcher(观察对话根尺寸、窗口与根增减);固定值在对话根出现后发布一次 |
| 预览模式 | createPortal 挂载到 document.body,position: fixed; inset: 0; z-index: 100000,同时把 [data-shell-overlay] 等设置面板覆盖层设为 opacity: 0 |
| 思考块渲染 | 覆盖 conversation.chat.node 的 assistant-step 渲染器(priority −1),只提供展开/收起;头部沿用官方 DisclosureRow + IconThinkOutline14,正文纯文本 |
| 强制中文 | host 端注册 systemPrompt.section(order −90),开关热注销/注册 |
| 界面中文化 | MutationObserver 精确替换「完全等于」词表的叶子文本节点(排除代码与输入区) |
| 面板补丁 | body 观察器以 [role=dialog][aria-modal] + > nav 语义锚点探测设置面板,不依赖 CSS Module 哈希类名,探测失败安静跳过 |
| 会话删除 | 克隆官方菜单项注入「⋯」菜单,目标会话 id 从会话行 React fiber 直读(避免按标题反查误删);host 端 /width-slider sessionDelete 执行删除链,失败即中止并留痕 |
| 工作区分页 | 常驻 wrapper 包裹官方 sidebar.workspaces,按当前页签过滤会话与工作区(结果按源引用与作用域缓存,保证 getSnapshot 引用稳定);分组数据经 /width-slider wsGroupsRead/Write 存 $DSH_HOME/storages/dsh-plugin-width-slider/workspace-groups.json |
| 动效 | 命令式 Web Animations 实现(replayEntrance),而非 CSS @starting-style:宿主挂载行或面板时已强制过一次样式解析,声明式起始态不会生效;观察 [data-chat-anchor-key] 消息行与 [role="tree"] [role="treeitem"] 侧栏行,整批载入按文档序错峰入场;设置面板动效拦截三条关闭路径,先让真实面板缩小再放行 |
| 动效 | 角色化入场读宿主发布的 data-chat-flow-kind(user/steering → 用户角色,assistant-step → 所选样式,其余 → 过程角色);思考块正文按渲染高度估算行数做 clip-path 逐行擦除;宽度滑块取最近 120ms 的指针采样算释放速度,投影 120ms 后由欠阻尼弹簧(k=260、ζ≈0.67)驱动,落点定稿时才写入存储;设置页错峰由 nth-child 加一个 CSS 变量步长实现,不经过 JS |
| 配置存储 | 功能开关(含动效开关与样式)经 /api/width-slider 端点读写 $DSH_HOME/storages/dsh-plugin-width-slider/settings.json(原子写);client 端 config store 负责热切换 |
| 滑块几何 | 轨道高度等于圆形手柄直径(设置页行内 16px、预览遮罩 28px),填充条右端为与手柄同心同半径的半圆头,无平直切面露出 |
| 性能 | 列宽在 pointerdown 时快照,宽度更新经 rAF 节流,拖动不卡顿 |
本插件整合了以下上游能力,安装本插件后无需再单独安装它们;若同时启用,会出现两套实现争抢同一界面元素的情况,请停用或卸载上游插件。
| 上游插件 | 上游参考版本 | 本插件整合版本 | 整合内容 |
|---|---|---|---|
| dsh-think-zh-expand | v0.4.7 | v0.3.0 | 强制中文、思考块渲染、界面中文化 |
| dsh-client-ui-custom | v0.1.0-rc.12 | v0.8.0 | 四组入场动效与三套预设 |
同时启用时的后果:同一块界面被两个渲染器接管、出现两个按钮与两套设置,或两套动效引擎对同一批 DOM 各自动画一次导致效果叠加。
| 项目 | 说明 |
|---|---|
| 目标内核 | DSH 0.1.5-rc.1(当前官方内核)。插件只适配该内核,不为更早版本保留兼容分支 |
| Host 入口依赖 | inject 声明 systemPrompt、connection、subprocess、webServer。端点注册不用 connection.rpc.handle:该调用把路由注册为 owner.effect(() => owner.webServer.register(route)),owner 取 connection 自身 ctx,而 0.1.5 的 connection 已不在自身 ctx 注入 webServer,第三方插件调用必抛 cannot get property "webServer" without inject —— 所以承担路由注册的 fiber 自己必须声明 webServer 依赖。注册改走 connection.fetch.register 的 /api 精确 Fetch 路由 |
| 端点与围栏 | 客户端 POST /api/width-slider,请求体为 { method, payload },响应体为处理器返回的 JSON;围栏由 connection 的 /api 处理器统一施加(可信 Host/Origin + 浏览器认证) |
| 已核对稳定的契约 | slot(conversation.chat.node、settings.section、shell.overlay)、ui-primitives 组件(MarkdownText、DisclosureRow、IconThinkOutline14、Modal)、__ModuleLoader__ 握手、connection.rpc、locale.register、sessions.list 快照、storageDomain 的 session_projcache 与 workspace 域 |
| 功能 | 状态 |
|---|---|
| 对话宽度滑块、思考块增强、面板补丁 | 已在 DSH 上实测 |
| 会话删除、宽度启动恢复 | 已由作者验收 |
| 工作区分页 | 已由作者验收 |
| 设置页排版重写与动效整合 | 已在 DSH 0.1.5-rc.1 上实测(角色化入场、思考块逐行揭示、滑块惯性回弹、设置页错峰落位逐项核对) |
0.1.5 内核适配(RPC 迁移到 /api 精确 Fetch 路由) |
已在 DSH 0.1.5-rc.1 上实测(/api/width-slider 返回 200,设置读写与各功能开关即时生效) |
win32)上验证与发布;其它平台未做适配。npm install
npm run build # tsdown 构建 → lib/index.mjs + lib/client.js
npm run typecheck # TypeScript 类型检查
npm test # 单元测试(含 jsdom 动效用例)
构建产物:
lib/
├── index.mjs # Host 端(ESM)
├── client.js # Client 端(CJS,含 window.__ModuleLoader__.load 握手)
└── types/ # 类型声明(tsc 产出)
测试位于 test/(8 个用例文件、约 94 项:设置面板动效、思考块渲染、动效角色映射、弹簧手感、文字擦除、侧边栏工具并入、工作区页签对话框);仓库内包含 DSH 源码副本(dsh-src/),已在 vitest.config.ts 中排除,不参与测试收集。
tsdown 0.6.x 与 rolldown 1.2.7 组合会报
The requested module 'rolldown/experimental' does not provide an export named 'transformPlugin'。
请使用 tsdown >= 0.22(本仓库已锁定 ^0.22.14 + rolldown ^1.2.6)。
dsh-plugin-width-slider/
├── src/
│ ├── index.ts # Host 端:systemPrompt 中文注入 + /api/width-slider 端点 + storages 配置
│ ├── host/
│ │ ├── endpointChannel.ts # /api 下 JSON 端点注册(connection.fetch.register)
│ │ └── sessionDeleteService.ts # 会话删除链(停任务、删目录、清投影缓存、工作区记账)
│ ├── shared/
│ │ ├── settings.ts # 功能开关契约(host/client 唯一真源)
│ │ ├── motionSettings.ts # 动效样式 id、默认值与三套预设
│ │ └── dshHome.ts # $DSH_HOME 解析
│ └── client/
│ ├── index.ts # Client 端入口:locale 注册 + 受控功能生命周期
│ ├── config.ts # FeatureSettings 契约 + client 配置 store
│ ├── WidthSliderSettings.tsx # 设置区块:功能总控页
│ ├── WidthSliderControl.tsx # 宽度滑块组件(按下预览、rAF 拖动、释放惯性与持久化)
│ ├── settingsPanelPatch.ts # 面板补丁:弹窗窗口化 + 左侧导航滚动
│ ├── widthPrefs.ts # 宽度偏好读写/发布与启动恢复
│ ├── sessionDelete.ts # 会话删除菜单项与确认框
│ ├── workspaceTabs.tsx # 工作区分页:页签栏、分组 store、树过滤 wrapper
│ ├── endpointChannel.ts # /api 端点调用(POST { method, payload })
│ ├── think/ # 思考块渲染器与界面中文化词表
│ ├── motion/ # 入场动效引擎(对话/侧边栏/新建对话/设置面板)+ 弹簧手感 + 文字擦除
│ ├── lang.ts # 界面语言判定
│ └── locales.ts # zh / en 文案
├── test/ # 单元测试(含 jsdom 动效用例)
├── scripts/fix-dts-imports.mjs # 构建后修正 d.ts 相对导入
├── docs/ # DSH 相关参考文档(非本插件运行时依赖)
├── env.d.ts # 运行时模块类型桩
├── cordis.patch.yml # bundle patch:insert width-slider
├── tsdown.config.ts
├── tsconfig.json
└── package.json
Q:重启后对话宽度没有恢复?
宽度偏好保存在 localStorage,client 启动时会立即应用;若宽度未恢复,请确认「启用对话宽度滑块」处于开启状态,且没有其它插件同时写入 --dsh-chat-user-width。
Q:设置里找不到本插件? 请确认插件已安装到 DSH 的 profile 并已重启。设置项位于 设置 → Width Slider。
Q:和上游插件同时安装会怎样? 会出现两套实现争抢同一界面元素(两个按钮、两套渲染器或两套动效引擎)。请停用或卸载上游插件,见与上游插件的关系。
Q:会话删除能恢复吗? 不能。删除操作会同时清理会话数据、磁盘日志与相关记账,执行前有二次确认。
Q:动效没有生效? 请检查对应的动效开关是否开启;若系统启用了「减少动态效果」,动效会自动降级为仅淡入。
Q:官方升级后某些功能失效? 部分能力依赖官方 DOM 结构,官方大幅重构界面时可能失效。此时相关补丁会安静跳过,不影响其它功能;请在 Issues 反馈并附上 DSH 版本号。
NotFoundError: removeChild。rail-in 关键帧会同时平移「新建会话」按钮与其所在区域,搜索展开时操作区容器自己也带 translateX —— 这些 transform 一旦出现在被测元素的链上,position: fixed 的包含块就会改变、坐标与矩形都不可信,此时跳过测量与发布并保留上一次位置,关键帧结束的 animationend 再触发重测。收起落定时先按 rail 宽度还原宿主布局,不必等动画结束。png/ 改名为 image/。auto: true(标记为「只挪过位置」),resolveDialogRect 据此回落到官方尺寸,旧键里存的宽度被直接丢掉 —— 从旧版本升级的用户永远看不到自己拖定的宽度。clearPanelRect() 只删现行记忆键,而迁移路径仍在读旧键,重置之后弹窗会被重新套回旧宽度。$DSH_HOME 解析、会话删除菜单注入、界面中文化与设置页;每条断言都逐项变异验证过(确认改坏对应实现会被用例抓住)。aria-hidden 元素当遮罩,其它插件带导航的弹窗会被误认,遮罩判断随之命中全页点击并被吞掉。现在只认官方结构(role="presentation" 层 + 紧邻的 aria-hidden 遮罩兄弟),并在每次点击前复核面板仍然存在;结构不匹配时动效安静降级,不再触碰任何点击。0.1.5-rc.1 内核:插件端点从 connection.rpc.handle 迁到 connection.fetch.register 的 /api/width-slider 精确 Fetch 路由,修复桌面端 2.0.8 上 cannot get property "webServer" without inject 导致的插件树加载失败。/api/open-with 与两个开关)整块删除。0.1.0–0.8.1 共 13 个版本,逐版内容见提交历史。
本项目以 MIT 许可发布。
思考增强、会话删除与动效能力分别整合或参考自以下 MIT 开源项目,感谢各位开发者:
| 项目 | 作者 | 关系 |
|---|---|---|
| dsh-think-zh-expand | baosfeng | 能力整合(本插件 v0.3.0 起) |
| dsh-client-ui-custom | Yoli-mi | 动效引擎整合(本插件 v0.8.0 起) |
| dsh-plugin-session-delete | lsz-asd | 会话删除链参考(本插件 v0.5.0 起) |
| dsh-archived-chats | Ultronen | 归档会话删除链参考(本插件 v0.5.0 起) |
许可归属与版权声明明细见 THIRD_PARTY_NOTICES.md。
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。