🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

侧栏划选提问 ChenRuoT/dsh-sidebar-qa

DeepSeek Harnessv1.2.2
ChenRuoT5 天前有提交已提供中文文档扫描:未发现敏感能力

一个基于DSH-better-sidebar的侧边栏提问tab,实现类codex的侧边提问或claude…

53.9/100
综合分
62
GitHub 星标
812
npm 周下载
—/5
用户评分

数据截至 2026/10/30 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-sidebar-qa
npm 源 · dsh-sidebar-qa 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · market
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功(非静态推断);本次验证针对插件 v1.2.1,当前版本为 v1.2.2
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-sidebar-qa @ 1.2.2
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/29 22:39:02

安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

发起外部网络请求
查看扫描证据(共 1 处,展示前 1 条)
  • 发起网络请求
    src/client/api.ts:38
    response = await fetch(`/sidebarqa/api/${method}`, {
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-ui-primitives@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

界面预览

1 张 · 点击查看大图

功能亮点

  • 侧边栏提问标签页
  • 划选内容提问
v1.2.22026-10-29
· [1.2.2] - 2026-10-29 · Fixed · issue #23:配置接缝优先识别条目表单能力(host 半,需重启 dsh web / 桌面应用):configure + describe/update 存在时按本插件 profile 行 id 读写,即使宿主仍保留 legacy register;不再让命名空间分支覆盖 volatile 配置读源。缺少条目 id 时明确拒绝,不回退写入另一份存储。旧命名空间宿主继续沿用原路径。 · Flash 模型目录兼容(host 半):回答配置、摘要与标题调用在使用时查 provider 目录;仅当所配名称缺失、另一名称确实存在时,兼容 deepseek-v4-flash / deepseek-flash。保留已有条目、自定义模型及保存值;目录查询失败或无匹配时保留原值。 · 补充混合 settings API、配置读取/保存/冲突与新旧模型目录回归;31 文件 / 455 用例通过。真实 settings 产物验证与桌面验收边界见 issue #23 验证记录。 Full Changelog:
v1.2.12026-10-19
· [1.2.1] - 2026-10-19 修 DSH 0.2.1 平台上的两个 P0:/sidebarqa/api 信任围栏退化(LAN / --trusted-host 恒 403),以及追问面板不再流式、轮次失败没有任何提示。同时把类型桩升到 0.2.1-rc.2、装载闸测试改成「0.2.0 peer / 0.2.1+ engines」两代语义。 · Fixed · 信任围栏迁移到 webStartup(host 半改动,需重启 dsh web / 桌面应用):DSH 0.2.1-alpha.1 删除了 webRuntime 服务;src/index.ts 仍只读它,回退读到 loader row 里未求值的 !!js 表达式,Array.isArray 判否后围栏静默退化为 loopback-only——dsh web --host 10.0.0.7 或 --trusted-host app.example 的浏览器访问 /sidebarqa/api 全部 403(config / context / title / catalog 一起失效),且没有任何报错。 - trustedHostsOf 现在按 webStartup.trustedHosts(0.2.1+)→ webRuntime.trustedHosts(旧宿主)→ loader 的 id: connection 行字面量顺序读;服务存在即以其值为准(空列表表示 loopback-only,不再回退到别的来源)。 - 新增 bindHostOf / bindProtocolOf(读 webServer.host / .protocol),围栏按上游 packages/client/connection/src/api-request-trust.ts 接受监听 bind IP、按 http(s) 规范化默认端口、拒绝 cross-site 与不匹配的 Origin。 - webServer 镜像补 host / protocol,webStartup 镜像补上出处;webRuntime 保留为旧宿主回退。 - 回归:新增 tests/trust-fence.spec.ts(17 例)与 tests/host-route.spec.ts(9 例,用 fake host 驱动真实 apply 路由:webStartup 优先、bind IP、旧 face 回退、malformed 值不抛、403/200、Origin 与 cross-site)。 · 追问恢复流式;失败轮次不再永久停在「生成中…」(client 半改动,浏览器硬刷新即可):DSH 0.2.x 的 agent loop 不再写持久化的 assistant/chunk——成功提交 assistant/message,失败/中断提交 assistant/attempt(含 compact stream),实时增量改为 opt-in 的 follow({ assistantStream: true })。插件原实现两者都没接,回答只在结束时整段出现,模型报错时面板没有任何提示。 - followSession 显式传 assistantStream: true,转发 start / chunk / end 帧与重连 snapshot 的 assistantStream.activeAttempt。 - answer.ts 新增 foldAssistantStreamRecords / assistantAttemptOf / liveStreamOf / applyAssistantStreamFrame,把文本增量、失败原因(finish.reason.failure)与旧格式 assistant/chunk 统一折叠;assistant/attempt 成为带 failure 的 transcript 行(保留已生成的部分文本)。 - AskPanel 维护 live 行:首 token 起逐段渲染,durable 事件落地后替换;失败轮次显示「本轮回答失败:」。MarkdownText 的 labels 仍按 locale memo。 - 新增文案键 askTurnFailed(zh/en);回归:tests/answer.spec.ts(新增 9 例)、tests/session-wire.spec.ts(新增 follow 帧转发用例)。 · Changed · 装载闸叙事与测试对齐 0.2.1 的新语义:DSH 0.2.1-alpha.3+ 的 evaluatePluginCompatibility 只要 manifest 有 engines.dsh 就只按它判、
v1.2.02026-10-15
· [1.2.0] - 2026-10-15 修 issue #21「设置保存失败」:配置改为声明在插件自己的 Config schema 上、并按 profile 条目 id 寻址——DSH ≥ 0.1.7(含 0.2.x)上「追问」设置页从「只读默认值」变成可保存。 · Fixed · 设置面板在 DSH ≥ 0.1.7 上可以保存了(host 半改动,需重启 dsh web):dsh-settings@0.1.7-alpha.1 起没有 register,可编辑字段改为从插件自报的 Config schema 派生(volatileForm 只认标了 volatile() 的字段),describe / update 接受的是 profile 条目 id(cordis.patch.yml 里那一行的 id,本插件是 sidebar-qa),而不是插件声明的命名空间。1.1.0 的接缝只会注册命名空间,于是在这类宿主上 configFace 恒为 undefined——每一次保存都回 503「this host exposes no sidebarqa settings namespace」(正是 #21 截图里那行红字),面板只能显示默认值。 - host 半现在导出 export const Config = SidebarqaPrefsSchema,12 个字段全部 volatile();apply(ctx, config) 拿到的是每字段一个活引用,新增的 src/live-config.ts 负责把它读成普通配置(字段缺失或读抛错只回落该字段的默认值,绝不让一次读失败打掉整个路由)。 - src/settings-face.ts 的接缝现在有两形、互斥:宿主有 register(≤ 0.1.6,低于本包声明下限)走原来的命名空间;没有就按条目 id(取 ctx.fiber.entry.options.id)打开同一个 revision 守卫的 describe / update 面。id 取不到、或服务连 describe/update 都没有时给出带原因的拒绝(no-entry / no-form),503 文案由 settingsRefusalMessage 按原因生成,不再是一句「可能缺服务、也可能缺注册」的含糊话。 - 保存的值经 loader 的 volatile 提交(updateVolatile / loader/volatile-update)直接写进运行中的引用,插件不重挂;摘要与标题路由下一次调用读到的就是新值。 - 新增 claimOwnSettingsCard:在同代宿主上用 settings.configure({ auto: false }, ctx.fiber) 抑制宿主按 schema 自动生成的表单——本插件自己已有一整页设置卡(settings.section),同一份配置不该出现两个入口(结构探测;宿主没有该方法时静默跳过,且 disposer 挂在 effect 上随插件卸载)。 · 配置的落点变了(≥ 0.1.7):写在插件自己的 profile 行(cordis.patch.yml 里 id: sidebar-qa 的 config:),不再写 settings.yaml 的 sidebarqa 段(那一代宿主本来也没有该命名空间)。老宿主行为与 1.1.0 一字不变。 · 回归:新增 tests/live-config.spec.ts(12 例:活引用识别全有全无、读永远给出完整普通配置、坏引用只降级单个字段);tests/config.spec.ts 增加「每个字段必须 volatile()、根不可 volatile」(漏一个字段 = 宿主表单少一项且写入被 Config field "…" is not volatile 拒绝)与「解析结果就是运行期能就地更新的活引用」;tests/settings-face.spec.ts 重写(21 例)——两形接缝、条目 id 寻址、描述符值解引用(活引用直接上线会 JSON.stringify 成 {},面板全空)、畸形宿主不抛、拒绝文案逐原因唯一,以及接线守卫(profileEntryIdOf(ctx);src/index.ts 不得再出现 no-register)。 · 实测(本机 checkout DSH 0.2.1-alpha.3,只读):用真实的 SettingsForms + volatileForm / isVolatilePath + loader 的 volatile 提交原语,驱动本插件构建产物的 apply 与 /sidebarqa/api 路由处理器(config editor 换成内
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-sidebar-qa 划选即问,侧边栏内嵌问答划选提问 添加到对话 上下文摘要 嵌套追问 追问记录 零打断 中英双语 DeepSeek Harness(DSH)Web 插件:在对话里划选任意文本 → 点击「提问」→ 右侧面板问答——自动创建同工作区的独立 DSH 会话,主对话零打断。实现类 codex 侧边提问 / Claude Code /btw 功能。 🌏 中文 · English ✨ 功能一览 - 📝 划选提问:对话中划选任意文本 → 浮层「提问」→ 右侧面板内嵌问答,全程不跳转大窗口;侧边栏面板收起时也会自动展开,「提问」永远有可见反馈 - 💬 添加到对话:同一个浮层的另一个按钮,把划选文本以 > 引用块追加进当前会话的主输入框并聚焦(光标落在引用块下方),不新建会话、不打开侧边栏——想就地接着说的时候用它(issue #11) - 🧠 智能摘要:快速无思考模型把主对话上下文压缩成小摘要,与划选引文一起注入首条消息 - 🔀 三种上下文策略:每次提问可在「全量继承(fork+缓存命中)/ 压缩 / 机械裁切」间切换,面板内选择器 + 配置默认值双入口 - 🔗 独立会话:自动创建同工作区独立 DSH 会话(❓<主题>),可继续、可归档,主对话零打断 - 🪆 嵌套追问:在追问对话里再划选提问,生成子追问,层层嵌套
展开完整文档(README 剩余 1 节)
dsh-sidebar-qa

划选即问,侧边栏内嵌问答划选提问 添加到对话 上下文摘要 嵌套追问 追问记录 零打断 中英双语 DeepSeek Harness(DSH)Web 插件:在对话里划选任意文本 → 点击「提问」→ 右侧面板问答——自动创建同工作区的独立 DSH 会话,主对话零打断。实现类 codex 侧边提问 / Claude Code /btw 功能。

🌏 中文 · English

✨ 功能一览

- 📝 划选提问:对话中划选任意文本 → 浮层「提问」→ 右侧面板内嵌问答,全程不跳转大窗口;侧边栏面板收起时也会自动展开,「提问」永远有可见反馈
- 💬 添加到对话:同一个浮层的另一个按钮,把划选文本以 > 引用块追加进当前会话的主输入框并聚焦(光标落在引用块下方),不新建会话、不打开侧边栏——想就地接着说的时候用它(issue #11)
- 🧠 智能摘要:快速无思考模型把主对话上下文压缩成小摘要,与划选引文一起注入首条消息
- 🔀 三种上下文策略:每次提问可在「全量继承(fork+缓存命中)/ 压缩 / 机械裁切」间切换,面板内选择器 + 配置默认值双入口
- 🔗 独立会话:自动创建同工作区独立 DSH 会话(❓<主题>),可继续、可归档,主对话零打断
- 🪆 嵌套追问:在追问对话里再划选提问,生成子追问,层层嵌套
- 🗂️ 追问记录:按根(主)会话分层树展示;限定当前工作区;节点可折叠、显示最近访问时间;点击跳转后追问记录 tab 保持开启;已归档/已删除的追问置灰标记状态,可一键从记录中移除(连同整棵子树清理映射,不影响 DSH 侧会话)
- 🏷️ 两段式命名:划选首行占位命名 → 首次回答完成后基于「问题 + 回答」自动提炼 ≤15 字最终标题
- ⚙️ 可配置:摘要/回答模型渠道、思考模式、上下文窗口与预算全部可调——入口是 DSH 设置页 → 左侧导航「追问」(面板注册为 settings.section);同一份配置也可以直接写进插件自己的 profile 行(cordis.patch.yml 里 id: sidebar-qa 的 config:),条目表单宿主上两条路写的是同一份配置(legacy 宿主仍读写 sidebarqa 命名空间)
- 🌏 中英双语:界面文案与模型侧提示词跟随 DSH 语言设置实时切换(无需刷新,包括已打开 tab 的标题);回答语言跟随你提问/划选的内容,不被界面语言绑架

🔌 只注册进 DSH 自带右侧栏:DSH 0.1.5-alpha.1 及以上自带右侧栏(@deepseek-ai/dsh-client-ui-sidebar-right),本插件直接注册进它(ctx.sidebarRightTabs / ctx.sidebarRight 服务 + sidebar.right.pane.tab 与 sidebar.right.pane.tab.title 席位),无任何额外依赖。dsh-better-sidebar 兼容已在 1.0.0 彻底移除。更早的 DSH 上插件仍然激活:划选浮层与「添加到对话」照常可用,只是不注册侧边栏 tab(并记一条 console.warn)。

📦 更新记录

1.2.1 - 2026-10-19

修 DSH 0.2.1 上的两个 P0:局域网 / --trusted-host 访问 /sidebarqa/api 恒 403;追问面板不再流式、失败轮次没有任何提示。

- 信任围栏迁移到 webStartup(host 半,需重启宿主):DSH 0.2.1-alpha.1 删除了 webRuntime 服务,插件回退读到未求值的 !!js 表达式,围栏静默退化为 loopback-only。现按 webStartup.trustedHosts → 旧 webRuntime → loader 字面量读取,并像 DSH 自己的 /api 围栏一样接受监听 bind IP、按 http(s) 规范化默认端口。回归:tests/trust-fence.spec.ts + tests/host-route.spec.ts。
- 恢复流式 + 轮次失败可见(client 半,硬刷新):0.2.x 不再写持久化 assistant/chunk,实时增量需要 follow({ assistantStream: true });插件此前没接,回答只在结束时整段出现、报错时永久停在「生成中…」。现在逐段渲染 live 文本,失败/中断轮次显示「本轮回答失败:<原因>」(assistant/attempt 的 compact stream 也会折叠)。回归:tests/answer.spec.ts + tests/session-wire.spec.ts。
- 类型桩升到 0.2.1-rc.2,装载闸测试改为两代语义(0.2.0 读 peer、0.2.1-alpha.3+ 只读 engines.dsh),新增 package.json ↔ dsh.plugin.json 的 version / engines 同步守卫。升级需重新 pnpm install。

1.2.0 - 2026-10-15

修 issue #21「设置保存失败」:配置改为声明在插件自己的 Config schema 上,并按 profile 条目 id 寻址,DSH ≥ 0.1.7(含 0.2.x)上「追问」设置页从「只读默认值」变成可保存。

- dsh-settings@0.1.7-alpha.1 起不再有命名空间注册:可编辑字段从插件自报的 Config schema 派生(只认标了 volatile() 的字段),describe / update 按 profile 条目 id(cordis.patch.yml 里那一行的 id)寻址。1.1.0 的接缝只会注册命名空间,于是这类宿主上每次保存都回 503;现在 host 半导出 Config(12 字段全部 volatile())、按条目 id 打开同一个 revision 守卫的面,插件读运行期就地更新的活引用(不重挂)。老宿主(≤ 0.1.6)走原来的 sidebarqa 命名空间,行为不变。
- 顺手用 settings.configure({ auto: false }) 抑制宿主按 schema 自动生成的表单(本插件自己有一整页设置卡);拒绝原因细分为 no-entry / no-form 并各自有具体 503 文案。
- 依赖换成 @deepseek-ai/schemastery@3.18.4(devDependency 精确钉,volatile() 只存在于 DSH 这个分叉),构建期打包进 lib/index.js,运行期不依赖宿主那一份。升级需重新 pnpm install;host 半改动,需重启 dsh web。

1.1.0 - 2026-09-29

修 DSH 0.2.0 上插件整个不加载:DSH 0.2.0 新增了一道启动期 peer 兼容闸——每个 profile bundle 装载前,它 manifest 里每一个 @deepseek-ai/dsh peer 区间都要满足 semver.satisfies(运行时版本, 区间, { includePrerelease: true }),有一个不满足,这个 bundle 的整个 patch 层被跳过(stderr 一行 dsh: skipping profile bundle …,插件像没装)。本插件 peer 写的 ^0.1.0-rc.8 在 semver 里是「下限 + 天花板」(>=0.1.0-rc.8 <0.2.0-0),而运行时 0.2.0-rc.1 已越过那个天花板,于是每个 0.2.x 宿主上都整层被跳过。现改为纯下限(>=0.1.0-rc.8 / >=0.1.7-alpha.1):新版本上线时插件不会再因版本号变化而整体消失。类型桩同步精确钉到 0.2.0-rc.1 并重新全量校验(client 半源码零改动)。新回归 tests/dsh-compat.spec.ts 在 node 里复刻这道闸门(含「旧区间必须判不兼容」的反向检测器)。host 半改动,升级后需重启 dsh web。

1.0.2 - 2026-09-24

修「打开侧面板报 面板渲染出错:Minified React error #130 … but got: undefined」:DSH 0.1.7-alpha.1 把整套宿主图标从「尺寸后缀」改成「字重后缀」(IconQuestionOutline14 → IconQuestionOutlineRegular / …Medium)且不留别名,插件按名 import 的 glyph 在运行期是 undefined,面板输入区一渲染就抛 React error #130(随后由本插件的错误边界就地隔离成那条可重试的说明条)。现在图标按名解析(Regular → Medium → 旧尺寸名),宿主没有的 glyph 渲染为空而不是崩溃;MarkdownText / Tooltip / Menu 这类有类型的 API 面仍按名 import。仅 client 半改动,浏览器硬刷新即可生效。

1.0.0 - 2026-09-20

首个 1.x:只注册进 DSH 自带右侧栏,零额外依赖。 破坏性变更在于移除了 dsh-better-sidebar 后端(见下),因此按 semver 走 major:只装 dsh-sidebar-qa 即可,不再需要任何 peer 侧边栏基座。

- 移除 dsh-better-sidebar 兼容(破坏性):插件不再有第二个后端,也不再需要任何额外依赖;peer 依赖 dsh-better-sidebar 与其 peerDependenciesMeta 条目已删除(pnpm install 后 lock 里的 node-pty / protobufjs 一并消失)。
- DSH ≥ 0.1.5-alpha.1:注册进 DSH 自带右侧栏。栏位展开/拆分/浮动/全屏由 DSH 自己管,插件不再需要手动展开面板。
- 更早的 DSH:插件仍然激活,划选浮层与「添加到对话」照常可用,只是不注册侧边栏 tab(并记一条 console.warn)。
- 已打开 tab 的标题现在会跟随语言切换:插件在 sidebar.right.pane.tab.title 席位注册了一个活的标题组件(以前该标题会冻结在打开时的语言)。
- 新增能力:src/client/ask-mode.ts(面板视图模式)、src/client/show-session.ts(用 ctx.uiWorkspace.openSession 把目标会话切到屏幕上)。
- 补回两个 tab 的图标:+ 页胶囊与 tab 条上的 chip 现在分别显示 ❓(追问)与队列(追问记录)的宿主图标——原生改造时 icon 字段整个丢了,胶囊一直在画宿主的方块占位。
- 已归档 / 已删除的追问不再把面板带塌:切换条里这类行置灰不可点并标注状态,默认选中改为「最新一条可读的追问」;选中项在阅读中被归档时给出说明 + 「移除」,输入区停用。此前点它们会把面板切到一段读不出内容的会话上(永远「生成中…」)。
- 面板不会再整块变白且无法恢复:两个已知触发点都已修掉(宿主 MarkdownText 的文案 prop 改名后,含代码块的消息会渲染崩溃;面板内任何渲染错误以前会让 tab body 在整页所有会话上被永久摘除),并新增本插件自己的错误边界:崩溃就地显示为一条可重试的说明条,标签页本身不受影响。
- 修掉一批「类型镜像臆造上游成员」导致的静默故障:「添加到对话」一直找不到目标会话、「追问记录」跳转抛 TypeError、局域网访问 /sidebarqa/api 恒 403、assistant-stream 帧读取崩溃等。详见 CHANGELOG。
- 配置面板已迁入 DSH 官方设置页:ConfigPanel 现在注册成一个 settings.section(src/client/settings-slot.ts 注册 + src/client/settings-section.tsx 页面),设置页左侧导航因此新增一整页「追问」(排在 DSH 自带各页之后),不再有齿轮弹窗。之所以不是 plugins.item:那个席位的契约留给 ui-settings-plugins 的 host-plane 配置页,且在没有受管 profile 的部署上整页不可用,会把配置入口一起带走。
- host 与 client 两半都有改动(host 侧修了 /sidebarqa/api 的信任围栏),且依赖层有变化(移除 dsh-better-sidebar peer;@deepseek-ai/dsh-client-ui-primitives 的类型桩精确钉到 0.1.6-alpha.2):升级后请重新 pnpm install,并重启 dsh web。

0.5.0 - 2026-08-29

- 划选浮层双按钮(issue #11):新增「添加到对话」——把划选文本以 > 引用块追加进当前会话的主输入框并聚焦(光标落在引用块下方),不新建会话、不打开侧边栏;「提问」文案与行为不变。仅 client 半改动,浏览器硬刷新即可生效。

前置条件

| 宿主 DSH | 侧边栏 tab | 划选浮层 / 添加到对话 |
| ≥ 0.2.0 | ✅ 注册进 DSH 自带右侧栏 | ✅ |
| ≥ 0.1.5-alpha.1(推荐) | ✅ 注册进 DSH 自带右侧栏 | ✅ |
| 0.1.2-alpha.1 ~ 0.1.4.x | ❌ 不注册(记一条 console.warn) | ✅ |

- 侧边栏 tab 需要 DSH ≥ 0.1.5-alpha.1:原生右侧栏(@deepseek-ai/dsh-client-ui-sidebar-right)从该版本起提供。
- 探测是运行期结构探测(服务在不在),不是版本号比对:sidebarRightTabs / sidebarRight / slots 三件套齐备才注册。
- engines.dsh 声明 >=0.1.7-alpha.1(如实反映设置接缝与图标改名两个世代)。
- 装载闸有两代,写法不同:DSH 0.2.0 校验的是 peerDependencies 里的每个 @deepseek-ai/dsh 区间;DSH 0.2.1-alpha.3+ 改为只看 engines.dsh——只要有这个字段,peer 就完全不读。两代都用 semver.satisfies(运行时, 区间, { includePrerelease: true }),任一不满足就跳过整个 bundle patch 层(插件不加载,只在 stderr 留一行)。本插件因此把两种区间都写成纯下限(无 < 天花板):^0.1.0-rc.8 这种带预发布的 caret 展开成 >=0.1.0-rc.8 <0.2.0-0,在 0.2.x 上会把插件整层挡掉(1.1.0 修的正是它)。回归:tests/dsh-compat.spec.ts(两代闸门都复刻,并校验 package.json / dsh.plugin.json 的 engines.dsh 同步)。
- 设置项在 ≥ 0.1.7-alpha.1 的宿主上按「插件自有 Config + profile 条目 id」持久化:可编辑字段来自本插件导出的 Config schema(12 个字段全部 volatile()),写入经 DSH 的 settings 服务落到插件自己的 profile 行(cordis.patch.yml 里 id: sidebar-qa 的 config:),插件读的是运行期就地更新的活引用(不重挂);1.2.0 起设置页可直接保存。老宿主(dsh-settings ≤ 0.1.6,仍提供命名空间注册)走原来的 sidebarqa 命名空间,行为不变;两种形态由接缝结构探测互斥选择,都不会写错地方(issue #21 / issue #19)。

安装

通过 npm(推荐)
dsh plugin --profile web add dsh-sidebar-qa

或本地路径
dsh plugin --profile web add <本仓库路径>

重启 dsh web(host 半改动需要重启;client 改动浏览器硬刷新即可)。

DSH 0.2.1-alpha.2+ 的 profile 不允许覆盖安装:升级时先 dsh plugin --profile web remove dsh-sidebar-qa,再 add 新版本。桌面版请在完全退出应用后执行 CLI,或直接用应用内 Plugins 页;桌面 profile 是 --profile desktop。

使用

1. 在任意对话(主对话或追问对话)中划选一段文本,浮层会给出两个按钮:「添加到对话」把引文追加进当前会话的主输入框(不开侧边栏),「提问」则走下面的侧边追问流程。点击浮层「提问」。即使右侧面板处于收起状态也会自动展开(对应 issue #6),「追问」tab 直接可见——包括「先手动收起面板、再点提问」的重复场景。
2. 右侧「追问」面板变成一条内嵌对话:引文/问题在侧边栏内流式回答,输入框固定在下方面板底部,不会跳转到子对话大窗口。
3. 回答过程中可在输入框继续追问(Enter 发送、Shift+Enter 换行),所有问答都在侧边栏内完成。面板底部的输入框复用 DSH 主对话的输入栏外观(同一套设计 token 的圆角胶囊卡片):发起新追问时左侧是上下文策略 chip,右侧的模型选择(与主对话同一份 session.models/selectModel 数据,切换互通)与 context 占用环(复用 contextPressure 投影)始终可见——新追问时它们绑定被追问的父会话(context 环即父会话占用,可据此判断用全量还是裁切)。模型座不会写主对话:新追问 + 压缩/裁切时它是本地草稿,默认显示配置里的回答模型(子会话真正会用的那个),你的选择只在追问会话建好后应用;新追问 + 全量继承时只读置灰(fork 子会话沿用主对话模型,正是前缀缓存命中的前提,如需换模型请改用压缩/裁切);继续已有追问时绑定该追问会话并直接生效。最右侧为上箭头发送键。
4. 每个追问仍是同工作区的独立会话(❓<主题>),主对话零打断;追问可以嵌套(在追问对话里再划选提问会生成新的子追问)。发起新追问时,输入框左侧的上下文策略 chip 可选择策略(默认取配置 historyStrategy):
- 全量继承:sessions.fork 从主会话最近的已完成 turn 分叉子会话,完整历史随种子继承,首条请求复用主会话消息前缀 → DeepSeek 自动前缀缓存命中、零压缩损失;子会话沿用主会话模型。主对话正在回答(无已完成 turn)时 fork 自动降级为「压缩」并提示。追问 tab 中,继承的父对话历史显示在分割条上方,默认视图锚定在本追问自己的「引用 + 提问」处,向上滚动分页加载父对话历史(与主对话「加载更早」体验一致)。
- 压缩:快速模型压缩较早窗口 + 近期原文保留(默认,省 token)。
- 机械裁切:最后 trimWindowMessages 条消息原文直取,零 LLM 成本、确定性输出。
5. 侧边栏「追问记录」tab 按根(主)会话分组,以分层树列出当前工作区内的所有(嵌套)追问(归属判定:当前会话所在工作区,见 src/client/history-scope.ts),点击跳转。有子追问的节点右侧有折叠按钮(箭头随折叠状态旋转)收纳子树,其左侧显示该对话组最近访问时间(相对标签,复用 DSH 左侧面板的样式与数据源 sessions.list.updatedAt)。跳转后目标会话的追问记录 tab 保持开启(本插件先把目标会话切到屏幕上——ctx.uiWorkspace.openSession——再把「追问记录」tab 开进它的右侧栏)。被归档或删除的追问(用户自行管理会话时)会置灰并标注「已归档 / 已删除」,不可再点击跳转,行尾的「移除」按钮将其从记录中清除(连同整棵子树清理 localStorage 映射,DSH 侧会话本身不受影响)。

配置

配置走 DSH 设置服务:插件导出自己的 Config schema,DSH 据此在插件自己的 profile 行(cordis.patch.yml 的 id: sidebar-qa)里持久化,设置页或手写该行都等效。

ℹ️ 配置面板就在 DSH 设置页里:「功能配置」面板(src/client/ConfigPanel.tsx)注册成一个 settings.section,导航路径是 设置 → 左侧导航「追问」(排位在 DSH 自带各页之后)。它经本插件自己的 /sidebarqa/api/config.update 读写(带 revision 乐观锁),而 host 半把这个请求转给当前宿主实际提供的那一种设置面:
- DSH ≥ 0.1.7-alpha.1:按 profile 条目 id 寻址(settings.describe / settings.update),值落在插件自己的 profile 行——也就是下面这张表可以直接写进 cordis.patch.yml:
- id: sidebar-qa
name: dsh-sidebar-qa
config:
answerModel: deepseek-v4
historyStrategy: trim

- 更早的 DSH(dsh-settings ≤ 0.1.6):仍走 settings.yaml 的 sidebarqa 命名空间,行为与 1.1.0 一致。

两种形态由 src/settings-face.ts 结构探测(优先 configure + describe/update 的条目表单能力,再回退 legacy register)互斥选择;宿主两个都没有时写入会返回 503,并按原因给出具体文案(no-entry:宿主按条目 id 编辑配置、但本插件认不出自己的行;no-form:两形都没有)——追问功能不受影响。
Flash 模型名按运行期目录兼容:仅当所配名称不存在且另一名称已公布时,在 deepseek-v4-flash / deepseek-flash 之间切换,适用于回答、摘要和标题。不改写保存值,保留已有目录项与自定义模型。

下表是可逐项编辑的 8 个常用键(Config schema 共 12 个字段,压缩/标题的 4 个内部参数见下方说明)。面板里逐项编辑这些字段——文本行 blur/Enter 提交,数字行按区间钳制,写入经 /sidebarqa/api/config.update 带 revision 乐观锁(多窗口冲突时提示重试),回答/摘要的模型渠道与模型为下拉框(选项来自运行时已配置的渠道);直接手写 YAML / 该 profile 行也完全等效。

| 键 | 默认 | 说明 |
| historyStrategy | compressed | 默认上下文策略:inherit 全量继承(fork+缓存命中)/ compressed 压缩 / trim 机械裁切(面板内可逐次切换) |
| trimWindowMessages | 10 | 机械裁切模式保留的最近消息条数(1–256) |
| summarizeProvider | '' | 摘要快速模型渠道;空 = 继承被追问会话的 provider |
| summarizeModel | deepseek-v4-flash | 摘要快速无思考模型 |
| summarizeReasoningEffort | off | 摘要思考模式(off/high/max 三档下拉) |
| answerProvider | deepseek-official | 子对话回答模型渠道 |
| answerModel | deepseek-v4-flash | 子对话回答模型 |
| answerReasoningEffort | off | 子对话思考模式(off/high/max 三档下拉) |

配置面板(config-fields.ts)只声明上述 8 项常用设置;压缩/标题的内部调参键(summarizeBudgetTokens、recentWindowMessages、backgroundWindowMessages、titleBudgetTokens)不在面板暴露,只能手写配置(profile 行,或老宿主的 sidebarqa 命名空间)。

压缩模式的上下文注入刻意保持轻量:旧背景压成最多 3 句话(目标 / 当前进度 / 未决事项),近期只保留最近 2 条且每段强截断(≤400 字符);模型侧从新到旧提交,让当前进度落在注意力最强位置。摘要失败/无渠道时自动降级为「仅近期对话 + 引文 + 问题」,问答不中断;全量继承失败(主对话正在回答)时自动降级为压缩模式。

架构

dsh-sidebar-qa (bundle: dsh.bundle + package.json#dsh.client)
├── src/index.ts host:/sidebarqa/api 摘要 + 标题服务 + 设置接缝装配(导出插件 Config) ├── src/summarize.ts 表面文本抽取 + 流组装(纯函数,可测) ├── src/title.ts 标题提示词 + 规范化 + Q+A 输入框定(纯函数,可测) ├── src/config.ts 插件 Config schema(12 字段全部 volatile)+ 默认值 ├── src/live-config.ts 读运行期活引用(纯函数,可测) ├── src/settings-face.ts 设置接缝结构探测:命名空间(≤0.1.6)/ profile 条目 id(≥0.1.7) ├── src/prompt-locale.ts 模型侧 zh/en 提示词词表 + 问题标记注册表(两半共享,纯函数,可测) ├── src/context-types.ts 结构化 cordis 服务面 + Context 增补 └── src/client/ 浏览器:选区捕获、浮层、问答面板、会话编排、追问记录 ├── index.tsx apply:tab 规格(id/kind 分开声明)+ 浮层 + locale 词典 + 侧边栏装配 ├── sidebar-native.ts 唯一的侧边栏模块:服务探测 + 三阶段注册(类型 / body / 活的标题)+ 按 kind 打开(含导航后跨帧确认) ├── slots.ts 插槽注册表探测(ctx.get('slots');侧边栏 tab 与设置页共用) ├── show-session.ts 把目标会话切到屏幕上(ctx.uiWorkspace.openSession,可测) ├── current-session.ts 当前会话判定:retainedBy.mainView > 0(纯函数,可测) ├── selection.ts 选区捕获与校验(单消息/非流式/≤2000 字符) ├── SelectionPopover.tsx 划选浮层「添加到对话」/「提问」两个按钮 ├── quote-draft.ts 引用块格式化 + 草稿合并(纯) ├── draft-insert.ts 把引文写进主输入框(conversation 服务接线) ├── AskPanel.tsx 追问 tab(内嵌对话:流式 transcript + DSH 风格输入卡片 + 追问切换) ├── HistoryPanel.tsx 追问记录 tab(分层树:折叠按钮 + 最近访问时间 + 工作区限定 + 归档/删除置灰与移除) ├── history-scope.ts 工作区归属解析 + 树过滤 + 子树最近访问时间 + 会话状态判定(live/archived/gone)与子树移除(纯函数,可测) ├── history-time.ts 相对时间分桶 + 本地化标签(纯函数,可测,复用左侧面板样式) ├── StrategySelect.tsx 上下文策略 chip(PermissionSelect 同款触发器 + Menu) ├── ModelSelect.tsx 模型选择(双层菜单三态:提交 / 草稿 / 只读) ├── model-menu.ts 模型目录扁平化/选中解析 + 有效强度与去重判定(纯函数,可测) ├── model-seat.ts 模型座绑定(读哪个会话、提交还是草稿、显示什么,纯函数,可测) ├── ContextMeter.tsx context 占用环(contextPressure 投影 + breakdown 面板) ├── context-meter.ts 占用百分比/紧凑 token 格式化(纯函数,可测) ├── ask-mode.ts 面板视图模式判定 resolveAskMode(纯函数,可测) ├── locales.ts 界面 zh/en 词表 + 模块级 t()(零依赖,可测) ├── use-locale.ts useLocaleRevision():语言切换时重渲染各面板根 ├── orchestrate.ts create → 占位 rename → selectModel(默认 flash/关思考)→ prompt + 继续追问 + 回答后重命名 ├── settings-slot.ts 把配置面板注册成 DSH 设置页的一个 section(探测 + 重试,纯模块,可测) ├── settings-section.tsx 设置页「追问」页面:标题 + 说明 + ConfigPanel ├── ConfigPanel.tsx 功能配置面板(逐项编辑 8 个常用键;Config schema 共 12 字段;由设置页的 settings.section 渲染) ├── config-fields.ts 配置面板行声明 + 数字钳制 + catalog 选项解析(纯函数,可测) ├── store.ts 父→子 映射(localStorage 持久化,支持嵌套)+ 待提问引文 + 已命名标记 ├── injection.ts XML 转义/消毒 + 注入格式 + 占位主题生成 ├── answer.ts 历史流 → 回答文本折叠 └── api.ts /sidebarqa/api fetch 封装 + 当前模型读取

跨插件 seam(预填引文)

外部插件可以打开追问 tab 并预填引文(不经本插件的划选浮层)。载荷走原生侧边栏的 per-open 通道 —— ctx.sidebarRight.openTab(kind, { params }),kind 是 ask 或 history:

// 在目标会话的右侧栏打开「追问」tab,并预填一段引文
ctx.sidebarRight.openTab('ask', {
params: { quote: '选中的内容', role: 'user' },
})

// 只打开「追问记录」tab
ctx.sidebarRight.openTab('history')

⚠️ kind 是 ask / history 这样的派发短名,不是 dsh-sidebar-qa:ask / dsh-sidebar-qa:history——后者是 tab 的实现 id(席位注册用的键)。openTab 按 kind 查注册表,传 id 会抛 no tab type is registered as "…"。

本插件自己的划选浮层走的是同一条通道:sidebar-native.ts 暴露一个 opener(openAsk / openHistory),浮层拿到引文后调 opener.openAsk({ sessionId }, { quote, role })。没有给外部插件用的端口导出——client bundle 的纯度门本来就禁止跨特性插件 value-import。

面板优先显示这条来路引文(形状校验:params.quote 为非空字符串;可选透传 role / messageId),回退到本插件浮层的 pending 引文;引文由适配器保证每次导航只交付一次,所以刷新/再次聚焦不会复现旧引文,而第二次外部打开仍会递送它的新引文(一次导航 = 一个新的出现实例)。<quoted_context> 的 source 标签沿用 agent-history。

已打开 tab 的标题会跟随语言切换:插件往 sidebar.right.pane.tab.title 席位注册了一个组件(它订阅语言 revision 并就地重渲染)。宿主不声明该席位时回退为打开时捕获的标题字符串(该语言下陈旧但无害)。

关键数据流

划选文本 ─┬▶ 浮层[添加到对话] ─▶ 当前会话主输入框(> 引用块 + 聚焦,光标在下方) └▶ 浮层[提问] ─▶ 右侧面板(引文 + 底部输入框) 回车 ─▶ ① host 摘要:sessionQuery.readSurface(被追问会话) → llm 快速无思考模型压缩 ② client 创建会话 sessions.create(workspaceId) ③ rename → "❓<划选文本首行占位>" ④ selectModel(默认 deepseek-v4-flash, 思考关闭) ⑤ prompt(摘要块 + <quoted_context> + 问题) ─▶ 面板 follow session 日志流式渲染 transcript(不跳转大窗口) ─▶ 首次 turn/end 后 ⑥ host 标题:Q+A 截断 → llm 快速无思考模型提炼 ≤15 字主题 → rename 覆盖为 "❓<最终主题>"(仅一次,失败保留占位) ─▶ 底部输入框继续追问;主对话零影响;追问可嵌套

上下文注入格式(首条消息)

<统领性指令:这是「侧边栏追问」,只围绕划选文本主题直接回答……>

【主对话上下文】【背景】<模型压缩的旧历史,最多 3 句话> 【近期对话】<最近 2 条近原文,每条 ≤400 字符>

<quoted_context source="agent-history" label="Agent 回复"
message_id="<id>" role="assistant" turn="<n>">
<引文原文> </quoted_context>

问题:<用户输入>

统领性指令置于输入最前,利用注意力机制让模型先定调「聚焦划选文本」再读上下文;用户问题虽然在输入末尾,但划选文本(quoted_context)与指令共同锚定了回答范围。追问会话内的后续消息默认不带主对话上下文(只有首条携带)。

构建与测试

pnpm install
pnpm build # tsc 声明 + tsdown(lib/index.js + lib/client.js + lib/client-registry.js)
pnpm test # vitest 单测(30 个 spec / 443 用例;纯模块 + sidebar-native / settings-slot / panel-boundary / primitives / panel-icons / dsh-compat / markdown-labels / trust-fence / host-route)
pnpm typecheck

多语言

界面文案与模型侧提示词都跟随 DSH 的语言设置(设置 → 通用 → 语言,即 $DSH_HOME/settings.yaml 的 locale.preference);缺少 locale 服务时回退浏览器语言,再回退 en。切换语言即时生效,无需刷新或重启。

- 界面:两个 tab 标题(含已打开的 tab——由 sidebar.right.pane.tab.title 席位的活标题组件保证)、划选浮层、空态与状态提示、模型选择、context 占用环、功能配置面板——词表在 src/client/locales.ts,zh 为键集基准,en 由类型标注锁定。
- 模型侧:追问引导语、上下文压缩系统提示、标题系统提示,以及提示词指名引用的结构标记——词表在 src/prompt-locale.ts。client 调用 /sidebarqa/api/context 与 /sidebarqa/api/title 时带 locale 字段;缺省等价于 zh,旧版 client 打到新 host 与 i18n 之前逐字节一致。
- 回答语言不跟界面走:提示词要求模型「用与用户提问相同的语言作答,问题语言不明确时跟随划选文本」——中文界面下划选英文论文提问,仍得到英文回答(与 DSH 官方会话命名同款策略)。
- 追问会话标题为 ❓<主题>:只用 emoji 标记,不含需要翻译的词,切换语言不会让会话列表出现混合语言前缀。

License

MIT
预览分享卡片长什么样 ↓ChenRuoT/dsh-sidebar-qa
分享 · DeepSeek Harness Hub
ChenRuoT/dsh-sidebar-qa

一个基于DSH-better-sidebar的侧边栏提问tab,实现类codex的侧边提问或claude…

回到顶部