在对话里按下 Ctrl+F
内容提要
作者开发了纯前端插件 dsh-session-find,用于搜索当前会话的全部对话内容。它不读取 DOM,而是读取会话 store 中的原始文本,因此能搜到折叠步骤、未渲染的工具参数和已被回收的节点。面板支持来源筛选、按轮次分组、合并同文、显示已排除数量,并提供大小写、全词、正则三个开关。文章还记录了转义与引号归一化、跳转定位、高亮等实现细节和踩坑经验。
延伸解读
搜索范围决定结果:从“屏幕”到“全量”
文章指出浏览器 Ctrl+F 只能搜当前 DOM 中渲染的内容,而对话界面中折叠步骤、未展开的工具参数、虚拟列表回收的节点都不在 DOM 里。插件改为读取会话 store 的原始文本,因此能覆盖这些“看不见”的部分。这提醒读者:搜索工具的能力边界首先取决于数据源,而非匹配算法。
默认只搜正文,是权衡而非遗漏
插件默认搜索“你”和“助手”的正文,工具调用内容被排除但会显示排除数量。作者解释一次对话中工具输出可能占八成,全塞进结果会淹没真正有用的人话。面板上的“已排除 N 处”是实际计算出来的,让用户知道结果为何变少,而不是悄悄吞掉。
归一化与跳转:两个容易被低估的工程细节
文章记录了转义字符、弯直引号、全角半角空格导致“明明看见却搜不到”的问题,修复靠两边归一化且必须保持长度不变,否则高亮偏移会错。跳转则要处理折叠回合、虚拟列表回收和 key 对不上等情况,允许失败并如实标注“已跳到所在回合”,不假装精确。
安装后必须完全重启,不是刷新页面
作者强调插件装完要完全退出 DSH 再启动,因为客户端 bundle 是宿主启动时组装的,只刷新页面加载不到新插件。装好之后改 client.js 才只需刷新。此外桌面端 F3 被宿主占用,1.4.0 起改用 Ctrl+G;设置前缀也变了,旧设置会丢失。
Q&A
dsh-session-find 插件是做什么的?
dsh-session-find 是一个纯前端插件,用于搜索当前会话的全部对话内容。它不读取 DOM,而是读取会话 store 中的原始文本,因此能搜到折叠步骤、未渲染的工具参数和已被回收的节点。面板支持来源筛选、按轮次分组、合并同文、显示已排除数量,并提供大小写、全词、正则三个开关。
为什么浏览器自带的 Ctrl+F 搜不到对话里的某些内容?
浏览器搜索的前提是文字必须在 DOM 里。现代会话界面中,折叠的步骤不点开就不渲染,工具调用的参数只有展开的那一截在 DOM 里,虚拟列表滚出屏幕的节点会被回收,思考内容经常默认收起。因此浏览器搜的只是当前屏幕上的一段 HTML,而不是完整的对话数据。
dsh-session-find 的数据是从哪里读取的?
插件从对话 store 的 canonical order 数组入口,逐条通过 nodeStore.get(key) 取出节点。拿到节点后,将其拆分成一段段可搜索的文本,并根据 node kind、block kind 和 raw key 三层推导出角色(如你、助手、思考、工具调用等)。
插件如何避免工具调用内容淹没搜索结果?
插件默认只搜索「你」和「助手」的正文(prose 投影),因为工具输出可能占对话的八成。如果全量搜索,搜“配置”会得到一屏 JSON 片段。面板会显示“已排除 N 处”并提供一个按钮,点击后可展开查看工具调用内容中的命中。
插件在搜索时如何处理转义字符和引号差异?
插件在索引侧和查询侧都加了一层归一化:deescape() 还原转义字符,foldQuotes() 将弯引号折成直引号、全角空格折成半角、破折号折成 -。关键是 foldQuotes() 必须长度不变,否则偏移量会错,导致高亮框到别处。修复前搜不到,修复后能搜到 52 处。
插件的高亮和跳转是如何实现的?
高亮使用 CSS Custom Highlight API,不往 React 管理的 DOM 里插入节点,避免被渲染抹掉或崩溃。跳转分四步:展开目标回合与步骤、二分查找轮次锚点、单向 scrollTop 收敛到节点 key、key 对不上就按文本内容兜底。单向收敛避免与虚拟列表回收冲突。
安装 dsh-session-find 后需要注意什么?
安装后必须完全退出 DSH 再启动,而不是刷新页面,因为客户端 bundle 是宿主启动时组装的。安装命令包括 dsh plugin add dsh-session-find,可指定 profile 或锁版本。装好之后改 client.js 只需要刷新。