DeepSeek Harness 插件

dsh-web-scroll-flow

DSH Web 对话滚动动效插件:自动跟随滚动平滑过渡(内容向上顶/向下拉的流畅滚动),边缘滚动物理回弹(小幅橡皮筋效果),手动滚动保持原生手感(英文原文)

跳到安装方式

来源信息

GitHub 仓库
TYOPXN360/dsh-web-scroll-flow
最近更新
2026年8月21日
分类
工具与能力
GitHub stars
0
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/TYOPXN360/dsh-web-scroll-flow
插件名:dsh-web-scroll-flow
作者:TYOPXN360

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器2 个文件
README.md来源说明 · 只读预览

@deepseek-ai/dsh-client-ui-scroll-flow

DSH Web 对话「流式输出自动滚动过渡动画」客户端插件:模型流式输出时,聊天视图 的贴底自动跟随从「瞬间跳变」变成平滑过渡;同时在 General 设置中提供一个 开关(默认开启),可随时关闭。

纯客户端插件,按 DSH 标准 client-plugin 模式接入(dsh.client manifest + slot 注册 + tsdown client bundle),构建产物 lib/ 随仓库提供,安装后无需 自己构建即可使用。

效果

  • 流式平滑跟随:模型输出过程中,内容持续增长时滚动容器自动跟随最新

内容,滚动从瞬时跳变变为平滑过渡(scroll-behavior: smooth,由浏览器 原生动画驱动)。

  • Think 摘要横向保持原始速度:未展开的思考块在流式时逐行滚动摘要

data-follow-end 行尾跟随)。scroll-behavior 是继承属性,若不处理, 摘要元素会继承滚动容器的 smooth——而浏览器平滑动画有固定最小时长、 跟不上 token 节奏,摘要行会明显落后于文字。规则把 [data-follow-end] 显式钉回 auto:每次行尾写入瞬时落地,横向滚动以与 token 完全相同的 速度跟随(恢复插件接入前的行为),纵向贴底跟随的平滑动画不受影响。

  • 精确触发条件:仅在「模型正在输出(running)」且「用户贴底跟随中」

时生效;流式结束、用户手动滚动离开底部或关闭开关后立即恢复原有行为 (打开会话、加载更早消息等瞬时滚动保持不变)。

  • 不干扰手动滚动:滚轮 / 触摸等读者滚动始终是浏览器原生手感,不经过

scroll-behavior

  • 尊重系统减动效prefers-reduced-motion: reduce 下自动禁用平滑,

保持瞬时行为。

  • 跟随状态稳定(滑行守护):ChatView 的贴底归属账本假设程序化写入是

瞬时落地的——平滑滑行中间产生的「gap > 25px 且向底部前进」的 scroll 事件会被误判为读者滚动,导致大段文本流式或展开 Think 时跟随被错误丢弃、 「回到底部」按钮闪现。行为组件在 window 上挂捕获阶段监听器,仅在 「流式中 && 开关开 && 前向移动 && gap > 25px」时用 stopImmediatePropagation 拦截这些滑行事件(先于滚动容器上的气泡阶段 处理器执行),账本因此永远看不到翻转条件:跟随不丢、按钮不出现,平滑 动画原样保留;读者反向滚动、落地事件与空闲状态全部照常放行,流式结束 时若滑行仍在进行也会守护到落地为止。

  • 状态标签不被待插话顶起:发送待插话时,待处理消息气泡按 DOM 顺序

追加在运行状态标签("Deep diving...")之后,会把标签顶高、消息被采纳 后又回落。流式期间用 flex order 把标签固定为流程列的最后一项,气泡 落在标签上方、标签的滚动位移随之抵消,屏幕上位置全程不变。

  • 状态标签不随行跳动(视觉钉住):平滑滑行永远不会瞬时落地,因此每

次追加一行后、滑行到位的间隙里,视图会滞后于内容底部几个像素——而运行 状态标签恰好是流程列的最后一项,这残余滞后就表现为标签随每一行上下 震动几个像素(未加平滑时是瞬时写入、无滞后,所以标签是固定的)。与其 把滚动位置拍平(那会让逐行小提交——尤其是展开 Think 的垂直跟随——失去 过渡动画),行为组件改为只补偿标签本身:流式期间以 rAF 循环给标签施加 translateY(-min(滞后, 80px)),标签视觉位置恒定、逐行震动消失,而 滚动位置完全不被触碰,展开 Think 等内容的垂直平滑动画原样保留。高刷 屏(600Hz)上 CSS smooth 的动画时长固定(~500ms,与刷新率无关),内容 增长快于动画时会产生 30–60px 的稳态滞后——补偿上限 80px 覆盖该范围; 滞后超过上限时(标签文字抖动、大段落等)触发一次「回底纠正」:把 scrollTop 写回 scrollHeight - clientHeight 让滑行落地(守护器照常 拦截中间事件)。标签文字自身的亚像素级变化(Deep diving 计时器每秒 重渲染)落在死区(≤0.5px)内不做任何补偿,杜绝 1px 抖动。读者向上滚动 会清除「跟随意图」——钉住与回底纠正同时失效,读者不会被拉回底部。

  • 新消息逐行淡入:每次新挂载的行——消息气泡、工具调用行、折叠思考的

摘要行、消息内每一条 Markdown 块行(段落、列表项、代码块、引用、标题、 脚注)——都执行 220ms 淡入(Web Animations API,无需 keyframes),元素 从第一帧起占据布局位,历史消息被自然推上去。MutationObserver 监听流程 列子树的插入,行级判定 = data-chat-flow-key(流程项)或 data-follow-end(折叠思考行尾)或行级块标签(p/li/pre/blockquote/ heading/ul/ol/table/figure/section/hr);同一批次插入的整块消息会 递归淡入其内部各行,行内 inline 元素(span、图标)不触发, prefers-reduced-motion 用户看到普通插入。展开的思考内容没有 DOM 行(ReasoningRow 渲染单个文本块),插件把文本按换行拆成行元素、每行 与普通消息行一样 220ms 淡入、行与行之间错开 30ms 依次显现(仅思考已 定稿时拆行,流式中的展开保持原样以避免与 React 重渲染冲突;同一行 500ms 内不重复淡入,防止批量插入被多次报告时重放动画)。

  • 独立设置菜单项:Settings 导航新增「滚动动画」页面(settings.section

菜单项),页内提供「流式滚动动画」与「调试日志」两个开关,偏好持久化到 浏览器 localStorage(ui-scroll-flow 键;Host 设置传输的写回不可靠, 刷新即丢,故弃用)。

  • 调试记录器(Debug):开启「调试日志」后,插件把关键事件与运行指标

写入环形日志缓冲(约 2 万条上限,写满后丢弃最旧):状态切换(tag 开/关、scrollport 变更)、滑行守护(抑制进入/释放)、标签钉住 (translateY 补偿值)、横向摘要跟随(拦截安装/释放 + 动画采样)、以及 帧率记录器(每秒一条 fps + 帧间隔 >200ms 的 jank 卡顿标记)。可通过 window.__DSH_SCROLL_FLOW_DEBUG__ 实时查看:logs() 取日志、 stats() 按类型统计、clear() 清空、active() 查询开关状态。

标准模式接入说明

位置说明
包 manifestpackage.jsondsh.clientplatform: 'web' + inject 依赖列表(informational)
浏览器入口src/client/index.tsexports["./client"]lib/client.js__ModuleLoader__ 包裹
设置页settings.section slotid scroll-flow(order 100),导航标签「滚动动画」,页内两个开关(动画 + 调试日志,role="switch")
行为组件conversation.composer.dock slot隐藏锚点 + data-scroll-flow 标记切换
平滑规则ScrollFlowBehavior.module.css:global 规则:滚动容器 [data-conversation-scroll][data-scroll-flow]smooth;折叠摘要 … [data-follow-end]auto(覆盖继承,配合 JS 快速跟随)
调试记录src/client/debug-logger.ts2 万条环形缓冲 + 帧率/卡顿记录器 + window.__DSH_SCROLL_FLOW_DEBUG__ 探针
持久化src/client/policy.ts浏览器 localStorage(ui-scroll-flow 键,JSON 双字段)

工作流:模型流式(useSession(s => s.running))且偏好开启时,行为组件给 对话滚动容器([data-conversation-scroll],ConversationRoot 的 scrollBody)打上 data-scroll-flow 标记;ChatView 自身的贴底跟随写入 (el.scrollTop = el.scrollHeight)随即被 CSS 平滑化;同一标记下的折叠 Think 摘要(ReasoningRow 的 data-follow-end 行尾跟随写入)被 JS 拦截 (scroll-behavior: auto 钉回 + 实例级 scrollLeft 遮蔽),写入只记录为 目标、由 rAF 循环以时间基准 easing 插值(时间常数 30ms 小增量 / 10ms 大增量,与刷新率无关:600Hz 屏与 60Hz 屏看到同样的 ~90ms 过渡,逐帧 easing 在高刷屏上会退化成瞬跳)。标记在流式结束、开关关闭或会话卸载时立即移除。

构建

需要 Node.js 22+ 与 pnpm。

pnpm install          # 安装构建 / 测试依赖(registry 上的 @deepseek-ai 0.1.0-rc.8 系列)
pnpm build            # tsc -b && tsdown → lib/(index.js + invariant.js + client.js)

产物说明:

  • lib/index.js — node half(空 apply,供 Host Loader 发现)
  • lib/invariant.js — invariant companion
  • lib/client.js — 浏览器 bundle(window.__ModuleLoader__.load 包裹,

externals 走平台模块表:react / cordis / ui-slots / runtime/client 等)

安装到 DSH Web

# 在本仓库目录下:
pnpm dsh plugin --profile web add "$PWD"

这会向 $DSH_HOME/profiles/web/ 写入指向本仓库的依赖并组合进 web profile。首次安装后重启 pnpm dsh web(之后的构建产物实时生效,刷新页面 即可):

# 停掉当前 dsh web,然后:
pnpm dsh web

打开 http://127.0.0.1:3080window.__DSH_BOOT__ 中出现 @deepseek-ai/dsh-client-ui-scroll-flow 条目、/plugins/@deepseek-ai/dsh-client-ui-scroll-flow/client.js 可访问,即加载成功。随后在设置 → 滚动动画页面确认「流式滚动动画」与 「调试日志」开关。

调试日志查看

设置 → 滚动动画页打开「调试日志」后,在 DevTools Console 里:

window.__DSH_SCROLL_FLOW_DEBUG__.stats()   // 各类型事件计数 + 总量
window.__DSH_SCROLL_FLOW_DEBUG__.logs()    // 最近约 2 万条(旧→新)
window.__DSH_SCROLL_FLOW_DEBUG__.clear()   // 清空缓冲
window.__DSH_SCROLL_FLOW_DEBUG__.active()  // 记录器是否开启

事件类型:state(标记开/关、scrollport 变更)、guard(滑行守护抑制 进入/释放)、pin(状态标签补偿值)、follow(摘要跟随拦截/动画采样)、 fps(每秒帧率)、jank(帧间隔 >200ms 卡顿,含后台标签页冻结)。

热重载(开发时)

每次 pnpm run build 后刷新 http://127.0.0.1:3080 即可(服务器实时读取 lib/client.js),无需重启服务器。

测试

pnpm test             # vitest(jsdom):policy / 设置行 / 行为组件

目录结构

src/
  index.ts                  # node half(空 apply)
  invariant.ts              # invariant companion
  settings.ts               # 偏好类型 + 字段常量 + 默认值(localStorage 契约)
  css-modules.d.ts          # CSS Modules 类型声明
  client/
    index.ts                # 浏览器入口:locale 注册 + 两处 slot 注册
    locales.ts              # zh / en 字典
    policy.ts               # 偏好持久化(localStorage ↔ 快照 store)
    ScrollFlowSection.tsx    # 独立设置页「滚动动画」(两个开关)
    ScrollFlowSection.module.css
    ScrollFlowBehavior.tsx  # dock 行为组件(流式感知标记切换)
    ScrollFlowBehavior.module.css  # 平滑滚动规则(含 reduced-motion)
    debug-logger.ts         # 调试记录器(环形缓冲 + 帧率/卡顿 + 探针)
build/
  tsdown.client.ts          # DSH 标准 client bundle 预设(拷贝自仓库)
  platform.ts               # 平台模块表
tests/                      # vitest 规格
tsdown.config.ts
tsconfig.json
package.json