Skip to content
dsh.fish
Bundle

dsh-streamfold

流式折叠:一个更好的会话窗口——运行时自动展开最新思考小窗、旧窗自动折叠,跑完把思考与工具调用折起,全程水流般的动效。

Source
rezon-aki
License
MIT
Updated
Updated 5 days ago

Readme

# dsh-streamfold · 流式折叠

[![license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![format](https://img.shields.io/badge/format-DSH%20bundle-blueviolet.svg)](cordis.patch.yml)
[![tests](https://img.shields.io/badge/tests-27%20passed-brightgreen.svg)](test/spark.mjs)

> 一个更好的会话窗口:**运行时自动展开最新的思考小窗**,旧小窗自动折叠,跑完自动将思考过程与工具调用折起,并且可以保留穿插的正文不折叠,全程水流般的动效。

> **为什么有这个项目**:官方「紧凑」在会话还有未加载历史时会折叠失效;本插件的折叠按自己的规则走,不受历史是否加载完影响。

- **顺便「视奸」dsh 现在在想什么。** 运行中自动展开最新的思考小窗——它此刻在想什么你看得见,界面又保持整洁。
- **动效。** 我们要的是一个看着就很舒服的界面:小窗高度、折叠与滚动跟随都按帧推进,水流一样,不跳不顿。右下角那颗「回到底部」外观仍是官方的,但**何时出现由本插件决定**——跟随中的正常落后不会再让它一闪一闪,点它是平滑滑回底部。
- **小窗火花。** 运行中思考小窗底部往上冒火星——像滚筒碾过金属:小窗滚得越快,火星**越亮也越密**(亮度跟着滚动速度走,慢输出暗、快输出烫),停住就不磨了;底边左右两端更密,火星朝窗口内迸。颜色与密度可调,关掉即完全不运行。
- **正文锻打。** 正文流式输出时,每写一段就从写头(最后一行末尾)向四周飘出一扇火星,像溅出来的一小团火。写了才有,停笔就不发,火星烧完自动收手。颜色、密度、速度、寿命都可调。
- **跑完回到提问处。** 一轮结束,视图平滑滑回**你这轮那句话**的位置——不用自己往上翻找回"我当初问的是什么"(你已经自己上滚过就不动你;可关,默认开)。
- **置顶显示提问。** 读到哪一轮,那一轮的提问就钉在会话顶端(一行,超出省略);它自己在屏幕上时自动让位,**点它一下平滑滑回那句发言**(可关,默认开)。

## 它轻在哪

- **不另开视图。** 直接在官方对话流上做 DOM 增强(靠语义属性定位行),不自己实现会话壳、不接管渲染管线、不依赖内部渲染器契约——升级面小。
- **零依赖、零构建。** 手写 `lib/`,没有构建步骤与运行时依赖;宿主半区只做一件事:把设置写进 `~/.dsh/streamfold.json`。
- **不碰官方源码,卸载即净。**

## 安装

```bash
# 两种等价写法
dsh plugin --profile web add github:rezon-aki/dsh-streamfold
dsh plugin --profile web add https://github.com/rezon-aki/dsh-streamfold
```

装完重启 profile,然后**刷新浏览器页面**(客户端代码在页面加载时注入)。

要求 DSH **>= 0.1.5-rc.2**(依赖该版本的对话流 DOM 契约)。

卸载:

```bash
dsh plugin --profile web remove dsh-streamfold
```

重启 profile 即恢复官方行为。

## 用法

设置 → 通用设置 → **对话显示** → 选「**折叠**」(第三项,取代官方那一行):

| 选项 | 行为 |
| --- | --- |
| 标准 | 官方标准(所有过程行可见) |
| 紧凑 | 官方紧凑 |
| 折叠 | 本插件:运行中的一轮只留一个窗,其余过程收成一行 |

专属设置页:设置 → **流式折叠**(下面所有开关都在这里,改动即时生效)。

运行中只会自动展开最新那一个思考窗;**你自己点开的窗不会被自动收起**,被取代的旧窗按「旧窗折叠宽限」(默认 2 秒)折回一行摘要;上滚即停跟,离底时出现回底按钮(箭头图标;小窗与主窗口是同一个按钮)。

## 设置

| 设置项 | 默认 | 说明 |
| --- | --- | --- |
| 折叠历史轮次 | 开 | 关掉后:加载页面不再自动折叠历史轮次(只在跑动时折前面的) |
| 保留穿插正文 | 关 | 折叠时保留带正文的行,并给它套一个限高小窗(正式回答本身不套窗) |
| 窗口高度 | 260 | 单个思考/穿插正文小窗的最大高度(px) |
| 运行中自动展开思考 | 开 | 只自动展开本轮最新的那一个;被取代的旧窗按「旧窗折叠宽限」折回一行摘要 |
| 旧窗折叠宽限 | 2 秒 | 新的思考窗出现后,旧窗再等多久才自动折回(0~60,支持小数) |
| 运行中自动展开工具 | 关 | 开:运行中最新的工具卡自动展开(用官方卡片自己的折叠/内滚,不套限高小窗) |
| 触底自动跟随 | 开 | 内容增长时自动贴底;你上滚即停跟 |
| 平滑系数 | 0.15 | 跟随时每帧吃掉多少差距,越小越柔(0.05~0.9) |
| 平滑最小步长 | 1 | 每 16ms 至少推进多少像素(与屏幕刷新率无关) |
| 离底显示「回到底部」 | 开 | 离开底部时出现回底按钮(跟随中的轻微落后不显示,避免闪烁) |
| 跑完回到提问处 | 开 | 一轮结束后平滑移到本轮你那句话的位置;你已经自己上滚过就不动你(动效关掉时直接到位) |
| 置顶显示提问 | 开 | 把「你正在看的那一轮」的提问钉在会话顶端:往上滚会跟着换成那一轮,超过一行只显示一行;它自己在视口里时自动让位,点它滑回那句话 |
| 动效过渡 | 开 | 关掉则折叠/展开/回底全部瞬时 |
| 小窗火花 | 开 | 运行中思考小窗底部的火星(独立模块:关掉后不建画布、不排帧) |
| 火花颜色 | #4fa8ff | 火星颜色;核心自动提亮成白热 |
| 火花密度 | 1 | 火星数量倍率(0.2~3),越高越密、绘制开销越大(两种火花共用) |
| 正文锻打火花 | 开 | 正文流式写头砸出的火星;写头不动就不砸,跑完自动收手 |

设置同时存在浏览器 localStorage 与宿主文件 `~/.dsh/streamfold.json`(路由 `/streamfold/api/settings`),远程 Web UI 也能写。

## 诊断

浏览器控制台:

```js
__dshStreamfold.stats()          // 窗口 / 折叠 / 折叠条计数(含动效状态)
__dshStreamfold.probe()          // 行状态、还看得见的思考行、小窗动画、回底按钮状态、火星开销(probe().sparks)
__dshStreamfold.state()          // 当前设置 + 官方「对话显示」取值快照
__dshStreamfold.set({ smoothGrow: 0.1, supersedeDelay: 3 })
```

报问题时附上 `probe()` 的输出与 DSH 版本,定位会快很多。

## 安全边界

- 纯客户端展示增强:只读对话 DOM,不发网络请求、不接触凭据、不改官方源码。
- 宿主半区只提供设置持久化:写 `~/.dsh/streamfold.json`,暴露同源路由 `/streamfold/api/settings`(跨站请求返回 403)。
- 卸载即净:设置行、小窗标记与注入的样式全部撤掉。

## 开发

- 手写、无构建:`lib/client.js`(浏览器半区,包在 `window.__ModuleLoader__` 里)、`lib/index.js`(宿主半区)。
- 改完 `lib/*.js` 重载插件并**刷新页面**。
- 行锚点全部用官方语义属性:`[data-chat-flow]`、`[data-chat-flow-kind]`、`[data-chat-turn]`、`[data-disclosure-row][aria-expanded]`、`[data-variant=think]`、`[data-tool]`、`[data-sample=bash]`、`[class*=_thinkBody]`、`[class*=_bodyWrap]`、`[data-context-injection-body]`——不用 CSS module 哈希。
- 已在 DSH 0.1.5-rc.2 验证。

## License

MIT

Install

dsh plugin --profile web add github:rezon-aki/dsh-streamfold#1c9fceba2d46e4c0f40eb1b57645d69f5c1d11f1

Profile: web

Source