Pular para o conteúdo principal
L

dsh-quick-toc

lyaxz/dsh-quick-toc

Plugin de sumário da conversa para o DeepSeek Harness: um painel lateral e uma cortina de largura total como duas visões do mesmo sumário; três escopos de busca (títulos, texto completo e outras sessões); várias formas de saltar (um cabeçalho, o cabeçalho de um turno, o fim de uma seção); um sumário completo ou um modo de leitura somente de perguntas, alternáveis a qualquer momento; posição de leitura memorizada por sessão; e interface em chinês/inglês com um cartão de configuração do plugin.

Instalar

dsh plugin --profile web add github:lyaxz/dsh-quick-toc

README

dsh-quick-toc

English | 中文

DeepSeek Harness(DSH)对话大纲插件:把 AI 回复中的 Markdown 标题(H1–H6)提取成可导航的大纲——侧边面板与全屏幕布两种大纲视图,按对话回合分组、覆盖整段会话(含尚未加载进窗口的回合),支持标题/提问/全文/跨会话四档检索、悬停预览、多种跳转(点标题、点组头、跳到本节末尾),阅读位置自动跟随并可记住。

功能

  • 按回合分组 —— 每条用户消息 + 其后续 AI 回复为一组,组头显示回合时间与首行预览,点击跳到该回合模型回答的开头
  • 覆盖整段会话 —— 未加载进对话窗口的回合也在列表里(带「未加载」标记与预览);点击即加载该回合并跳过去
  • 失败回合的报错 —— 请求超时 / 上游报错这类没有回复的回合显示 请求失败 与报错原文,点击跳到对话中的报错位置
  • 全屏「幕布」 —— 对话顶边标签条里的液滴把手把大纲铺成整幅宽度落下:没有遮罩、不压暗对话,字号与行距都放大,每行三段(层级徽标 / 标题 / 该节正文开头),搜索栏从右侧推进来;点条目、Esc 或 ✕ 收起。它与停靠面板共用同一份列表,滚动位置、搜索、键盘光标全部延续
  • 跳到本节末尾 —— 悬停标题行 / 组头 / 结果行,右端渐显一枚圆钮,点击跳到该节内容结束处;组头这颗跳到整轮对话的末尾
  • 跨会话检索 —— 搜索范围第三档「会话」用宿主的全文索引搜其他会话的消息正文,点结果切过去并继续查找;已归档 / 子会话 / 不在列表里的会话会被略过并计数
  • 只看提问 —— 搜索范围的「提问」档:结果只看你的提问;搜索框留空时大纲折成「每轮只留时间与你的提问首行」
  • 记住阅读位置 —— 重新打开会话回到上次读到的那一轮(半小时内有效;可在设置里关掉)
  • 键盘导航 —— ↑/↓ 移动光标、Enter 跳转、Home / End 到首尾、Esc 收起;光标位置有屏幕阅读器播报
  • 中英双语 —— 界面语言可设为跟随宿主、中文或 English;中文时间戳用 昨天 / 前天,英文昨天用 yesterday、更早用 YY-MM-DD HH:MM 日期
  • 插件配置卡片 —— 设置 → 插件 → 插件配置里的「对话大纲」卡片:语言、默认停靠边缘、显示的标题层级、大纲密度、收起把手的位置、记住阅读位置、模糊搜索、悬停预览与诊断开关;改过的字段标「已自定义」并可单独重置(改回默认值时标记自动消失),卡片与面板实时同步
  • 回合时间带日期 —— 昨天 昨天 15:04、前天 前天 15:04、更早 25-09-11 15:04,跨天的会话里时间不再重影
  • 标题行副标题 —— 每行标题下方显示该节正文的第一句,同名标题一眼可辨
  • 悬停预览 —— 悬停标题行显示该节开头、回合时间与层级路径
  • 搜索 —— 标题 / 提问 / 全文 / 会话 四种范围(范围按钮循环切换),结果列表点击定位并高亮,n/N 回车逐处跳,Esc 关闭
  • 搜索历史 —— 搜索框清空后列出最近搜索过的词,点一下原词重搜,可一键清空
  • 搜索容错 —— 大小写、全角半角、连续空白自动视为同一匹配;「模糊」开关可放宽到关键字中间夹字
  • 对话内高亮 —— 命中的关键字在对话中高亮,当前命中单独标亮
  • 组头吸顶 —— 滚动大纲时,当前回合的组头固定在面板顶部
  • 层级筛选 —— 设置卡片里的「显示的标题层级」任选 H1–H6 组合;顶栏左起第一颗按钮直达该设置页
  • 自动跟随 —— 滚动对话时正在阅读的回合自动点亮(封闭蓝框),大纲自动跟随
  • 跳转 —— 点击标题跳到对话中该标题的位置,滚动动画交给浏览器自己的平滑滚动(按真实时间推进,60Hz 与 240Hz 屏幕上时长一致);飞行中目标被宿主翻页挪动时会重新瞄准、动画被宿主滚动打断时会重新发起,跨页远跳不会半途停下;若某个浏览器把平滑滚动直接执行成瞬移,插件改为自己逐帧绘制。面板与对话双向定位
  • 回到底部 —— 往上翻远之后,列表右下角的浮动按钮一步回到最新一条(不在底部时出现、到底后消失)
  • 回到我离开的位置 —— 关闭面板或幕布时记住列表顶部那一行(两者各记各的、互不覆盖),下次打开时列表右上角出现向上的浮动按钮,一步回到那一行的原位置;用过一次或自己滚回该处就渐隐并忘掉,直到下次关闭再记。同一规则下,打开面板或幕布时正在阅读的那一行会落在列表顶部(读的就在最新几轮时列表已经到底,那一行自然停在底部)
  • 可停靠、可缩放 —— 拖顶部横条移动,◀ / ▶ 切换左右停靠,拖边缘调宽高(尺寸没有上限,最窄可到 120px),收起后成为边缘把手(停在什么高度由设置里的「把手位置」决定);位置与尺寸按浏览器记住(顶边距、宽度、高度只通过拖拽调整)
  • 面板缩放 —— 设置里的滑块把内容(文字、图标、按钮及其间距)在 50%–200% 之间按 5% 一档缩放,面板本身的尺寸不变;拖动滑块时只移动读数,松手才写入设置。面板变窄时顶栏四颗按钮保持一行:先挤掉中间的空白,挤满后整行可横向滚动(在顶栏上滚滚轮即可),此时顶部的灰色拖拽横条渐隐消失
  • 大纲密度 —— 设置里的「大纲密度」两档:「标准」保持原有行距,「紧凑」收紧行距与组间距,一屏看到更多条目
  • 幕布缩放 —— 另一个滑块,把幕布内容在 50%–200% 之间按 5% 一档缩放,幕布本身的尺寸不变;与面板缩放各自独立、互不影响。幕布内容的默认大小比此前小一档(滑块的 100% 即此前的 90%),且只缩放幕布里的大纲,不改变对话本体
  • 分页 —— 默认显示最近的若干组,向上滚动既展开索引也加载更早的对话
  • 边界提示 —— 滚到最早或最新再继续滚动时,面板底部短暂提示
  • Markdown 感知 —— 标题中的行内标记会被剥离;围栏代码块里的 # 行不算标题
  • 主题适配 —— 深色 / 浅色主题自适应;仅对话视图显示,切到其他视图渐隐
  • 对话中没有标题也没有可识别时间时面板自动隐藏

兼容性

插件版本支持的 DSH 版本
0.9.x(最新,0.9.0)0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1、0.2.0-rc.2
0.8.x(0.8.2)0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1、0.2.0-rc.2
0.7.x(0.7.14)0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1、0.1.7-rc.2、0.2.0-rc.1、0.2.0-rc.2
0.6.x(0.6.3)0.1.5-rc.1、0.1.5-rc.2
0.5.x(0.5.1)0.1.5-rc.1、0.1.5-rc.2
0.4.x(0.4.1)0.1.5-rc.1、0.1.5-rc.2
0.3.x(0.3.3)0.1.5-rc.1
0.2.x(0.2.2)= 0.1.2-rc.1

每个大版本只列该系列最新的一个补丁版本(新功能引入的缺陷都在其后的补丁里修掉了,所以同一个大版本内直接用最新补丁即可;旧补丁仍可继续用,插件不破坏既有接口)。

安装

通过 DSH CLI 安装:

dsh plugin --profile web add dsh-quick-toc

也可以从 GitHub 安装:

dsh plugin --profile web add github:LyaxZ/dsh-quick-toc

或以本地目录安装:

dsh plugin --profile web add <插件目录路径>

安装后重启 DSH 并打开 Web UI。面板默认收起:点对话区边缘的把手展开面板,或点对话顶边标签条里的液滴把手直接把大纲铺成整幅宽度落下。

使用

  • 跳转:点击大纲标题或组头跳到对应位置;带「未加载」标记的条目会先把该回合加载进来再跳;失败回合点报错行跳到对话中的报错位置
  • 搜索:放大镜打开搜索框,输入后点结果定位并高亮,回车逐处跳,Esc 关闭
  • 搜索历史:清空搜索框后点最近搜索过的词即可重搜;右侧「清空」丢掉整份记录
  • 搜索容错:全角/半角、大小写、空格差异会自动匹配;需要更宽松时点搜索框右侧的「模糊」开关
  • 层级筛选:点顶栏左起第一颗按钮(设置图标)直达本插件的设置页,在「显示的标题层级」里选择要显示的层级
  • 移动与停靠:拖顶部横条移动,◀ / ▶ 切换左右停靠
  • 调整大小:拖右边缘、下边缘或右下角(没有上限,最窄到 120px;面板过窄时顶栏可横向滚动)
  • 加载更早:在大纲中向上滚动(既展开索引,也加载更早的对话)
  • 幕布:点对话顶边标签条里的液滴把手(或面板标题栏的「幕布」圆钮)展开全屏大纲;点任意条目、按 Esc 或点右上角的 ✕ 收起
  • 跳到本节末尾:悬停标题行 / 组头 / 结果行,点右端出现的圆钮
  • 跨会话检索:搜索框右侧的范围按钮点两下切到「会话」,用宿主的全文索引搜其他会话;点结果切到那个会话并继续查找
  • 键盘:面板打开后 ↑/↓ 移动光标、Enter 跳转、Home / End 到首尾、Esc 收起;搜索框里 ↑/↓ 在命中之间切换
  • 只看提问:范围按钮(标题 / 提问 / 全文 / 会话)切到「提问」——结果只看你的提问,搜索框留空时大纲折成每轮的时间 + 你的提问首行
  • 回到底部:翻远了之后点列表右下角的浮动按钮回到最新一条
  • 回到我离开的位置:关掉面板或幕布时它记住你当时看的那一行;下次打开时右上角的浮动按钮一步带你回去
  • 阅读位置:滚动对话,正在阅读的回合会以蓝框标出;大纲会自动跟随
  • 设置:在 设置 → 插件 → 插件配置 里展开「对话大纲」卡片,可改语言、默认停靠边缘、大纲密度(标准/紧凑)、面板缩放(50%–200% 滑块,5% 一档)、收起把手的位置(0%–100% 滑块,1% 一档;0% 在最下、100% 在最上,默认 50% 居中)、显示的标题层级、记住阅读位置与模糊/悬停/诊断开关;改过的字段可单独重置(改回默认值时标记自动消失)。卡片与面板实时同步,不需要刷新;偏好保存在 DSH 的设置里,跟随配置走

诊断

面板挂载时默认不打印任何日志。需要排查宿主能力时,在 设置 → 插件 → 插件配置 里展开「对话大纲」卡片、勾选「在控制台打印诊断日志」——打开后当下就会打印一行(无需刷新):

[dsh-quick-toc] panel mounted · turnOutline=… · jumpLoader=… · lang=… · prefs=…

turnOutline 缺失说明宿主没有该投影,jumpLoader 的分阶段措辞(no-sessions-service / no-binding-api / no-binding-for-session / no-loadThrough / binding-threw)可直接定位跳转桥断在哪一环。

开发

  • lib/client.js —— 全部 UI 逻辑(浏览器端)
  • lib/index.js —— 宿主半:注册 dsh-quick-toc 设置命名空间(schemastery schema,含取值范围校验),让偏好进入 DSH 的设置文档并提供插件配置卡片的入口
  • cordis.patch.yml —— loader patch(符合官方 bundle 规范)
  • 面板注册进会话级 conversation.input.overlay 槽以取得会话级 hook(useChat、useSession、sessionId 等),面板本体通过 createPortal 渲染到 document.body 成为固定浮层;对话数据来自 props.useChat(ChatSnapshot.order 与 nodes,节点形状:kind: user/assistant-step、location.turn、data.blocks)
  • 「未加载回合」能力依赖宿主的两样东西:turnOutline 投影(整段会话的回合索引,每条含 turn/start 的 seq)与会话跳转加载器(客户端 sessions 服务的 binding(sessionId).session.loadThrough(seq),通过客户端 ctx 的 ctx.get("sessions") 免声明查找取得)。两者各自独立降级:没有投影时只列已加载回合,没有加载器时未加载条目只展示、不跳转,面板其余功能不受影响。
  • 失败回合的报错行读的是宿主的 turn-error 会话节点(宿主在 turn/end 的原因为 error 时发布,含 message 与可选的 code);宿主不提供该节点时只是不显示这一行,其余功能不受影响。
  • 界面文字来自 lib/client.js 顶部的一张字符串表(DICTS,中英各一份),语言设置决定用哪一份:跟随宿主 时优先问宿主的翻译函数(ctx.locale.bind("dsh-quick-toc"),注册的表就来自 DICTS),拿不到才回退到内置表。中英两份表的键必须对齐(仅 time.beforeYesterday(前天)是中文独有——英文对更早的时间直接用日期;time.yesterday 两语言都有,英文作 yesterday)。
  • 偏好存储分两层,由一个模块级 store 统一读出:宿主设置文档(语言/停靠边/层级/缩放/把手位置/记住阅读位置/模糊/悬停/诊断九项,回环页面上是权威层)与 localStorage(镜像 + 顶边距/宽度/高度三项的正式存储——它们描述"这一块屏幕",按浏览器保存)。宿主那一层按运行中的宿主二选一:0.1.5-rc.3 上是 ctx.settingsScope.bind({ namespace: "dsh-quick-toc" })(按命名空间寻址),0.1.7 两条线(alpha 与 rc)上改成 ctx.configForms.get(<profile entry id>)(按 profile 条目 id 寻址,客户端按宿主实际服务的 schema 认出自己那一条);两者暴露的方法与快照字段相同,所以 store 只有一套。写入按字段路由:宿主字段走 scope.mutate(本地同步折叠、宿主应答后对账),其余写 localStorage;写入的值若正好是该字段的默认值,则改为把用户层里的这一项删掉(等同于"未自定义")。非回环页面 DSH 将设置标记为只读,此时这九项偏好退回本地镜像,行为与 0.5.x 一致;0.5.x 留下的本地值会在宿主层首次应答时导入一次(仅当用户层为空)。宿主应答之后宿主层就是权威层,因此 localStorage['dsh-quick-toc.debug'] 这类本地键在回环页面上不再生效——诊断开关请用卡片里那一条。
  • 幕布与停靠面板共用同一份列表 DOM:幕布只是把面板本体搬进一个从标签条下沿落下的整宽容器(面板在幕布态换一套几何:相对定位、宽高 100%、不套用面板缩放),容器本身常驻挂载、收起时是一个 0×0 的直通盒,所以开关幕布不会重建列表、也不会丢掉滚动位置。跨会话检索走客户端 ctx.get("sessions") 的 search(query, signal)(走宿主的会话全文索引,一次最多 20 条);每个会话的阅读位置存在浏览器本地(dsh-quick-toc.readPos.v1,半小时内有效)。
  • 插件配置卡片按宿主实际提供的槽位注册,三处一起挂、装上哪一处由宿主决定:0.1.5-rc.3 上是 settings.plugin.item(key 为插件命名空间,该槽按宿主实际服务的命名空间派发,宿主半未加载时卡片自然不出现,面板不受影响);0.1.7 两条线(alpha 与 rc)上是侧边栏「插件」页的两处——「官方」分组里插件自己的条目(plugins.item,id 为 quick-toc,label 取「对话大纲」,order 50)与该 bundle 页面上的配置区(plugins.bundle.config,key 为 npm 包名)。0.1.7 的插件页渲染这两处时都会带上 view,卡片因此默认展开(点进条目或 bundle 页本身就是展开动作);rc 线的配置单元不带任何 props,卡片保持收拢的列表形态。所有注册都只在设置作用域绑定成功后才做,卡片与面板共享上面那个 store,因此两边实时互通。
  • 修改 lib/client.js 后刷新页面即可看到变化(客户端模块按内容哈希发版,DSH 的客户端 HMR 也会推送重载);改 lib/index.js(宿主半)需重启 DSH
  • 发布说明的措辞修订只落在仓库与 GitHub Release 页面上:npm 上已发布版本包内的 CHANGELOG.md 是发布当时的版本,npm 的版本内容不可变,改不了(例如 0.7.5/0.7.6 包内仍是 2026-09-19 改写前的长版、0.7.9 包内仍有一句后来被修正的说法)。每次发版会用 relnotes.mjs 核对"仓库中英 == npm 包内中英 == Release 正文中英"四处一致。

License

MIT © 2026 LyaxZ

Plugins relacionados