dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Composer polish for DSH: full-access permission turns red, reasoning effort becomes a draped slider with a heat ramp.
推理等级变成滑块,完全权限变红。 两件事,一个插件,不动任何官方组件。
Reasoning effort becomes a slider; full access turns red. Two things, one plugin, no shipped component replaced.
DSH 的 composer 底部有两处可以更好用:
这个插件把第一处变红,把第二处变成滑块。
DSH's composer has two spots that could read better:
This plugin repaints the first and turns the second into a slider.
#ec1313,暗色 #f25a5a#ec1313 light, #f25a5a dark打开模型菜单 → 点「推理等级」,那一行下面直接出现一条滑块:
┌──────────────────────────┐
│ 模型 Deepseek-V4.1… ›│
│ 推理等级 High ›│
└──────────────────────────┘
↓ 点进
┌──────────────────────────┐
│ [=========|==========] │ ← 滑块,停在当前档
│ Low **High** Max │ ← 档名当刻度,当前档加粗
└──────────────────────────┘menuitemradio,不写死menuitemradio rows, never hard-codedshipped list stays
data source and the write entry point
dsh plugin add dsh-ember也可以从源码装:
dsh plugin add F:/path/to/dsh-ember装完重启 DSH。这是纯前端插件,没有服务端逻辑。
Install, then restart DSH. It is browser-only; there is no host-side logic.
项 · 要求 DSH · 0.2.1-rc.3(在 rc.3 上开发与验证) 菜单 · [role="menu"][aria-label="模型与推理等级"] 依赖服务 · locale 平台 · Web(桌面端与局域网访问一致)
为什么注入 DOM,而不是用槽位
输入行里的模型选择器是 conversation.input.model,一个 single 槽位:
already has a registration),想接管就得整体重写那份 79KB 的 ModelSelect(菜单、搜索、键盘导航、浮层定位、失败重试、toast)single 槽位也不能容纳第二个 child —— child 必须在父 entry 的 children 表里声明,而那张表属于官方包菜单内部没有留给第三方的缝隙,所以走唯一不碰官方的路:观察菜单,插入一个它自己没写过的元素。
Why DOM injection rather than a slot
The composer model seat is a single slot: re-registering at the same priority throws, so taking it over means reimplementing the whole 79KB ModelSelect. A single slot also cannot host a second child — child slots are declared by the parent entry's children table, which belongs to the shipped package. There is no seam inside its popup, so the only route that leaves the host untouched is to observe the menu and insert one element it did not author.
官方触发器渲染时用的是:
.trigger { color: var(--dsw-alias-label-secondary) } /* 灰 */
.triggerIcon { display: inline-flex } /* 无 color,继承 */triggerIcon 不写 color,盾牌 ` 用 currentColor` 描边 —— 所以给按钮上色,盾牌跟着变。
插件用 MutationObserver 监听,当触发器同时满足「aria-label 含访问模式」和「含完全权限文案」时打上 data-dsh-full-access,再配一条规则:
[data-dsh-full-access]{ color: var(--dsw-alias-state-error-primary) !important }
[data-dsh-full-access] svg{ color: inherit !important }--dsw-alias-state-error-primary 在主题里本来就分开放(亮色 → red-600,暗色 → red-400), 所以不用自己挑色就自动跟随明暗。预设切走时属性被移除,颜色自己回来。
判据故意从严:既要 aria-label 像触发器、又要含完全权限文案,两个条件都满足才动手 —— 官方哪天改了文案,结果是「不变红」而不是「染错按钮」。
第一步是找到菜单。用它的无障碍名匹配,不用哈希类名:
document.querySelectorAll('[role="menu"]')
→ aria-label 匹配 模型与推理等级 / Model and reasoning effort哈希类名(如 _9r0rkG_*)每次构建都变,而 aria-label 是产品文案。
档位不是猜的,是读官方自己的行:
menu.querySelectorAll('[role="menuitemradio"]')
→ [{ label: 'Low', checked: false, node: <button> },
{ label: 'High', checked: true, node: <button> },
{ label: 'Max', checked: false, node: <button> }]aria-checked="true" 那一项就是当前档;数组顺序就是上游声明的顺序。
提交时点击官方 radio:
radio.click();这样写入走的是用户手点完全相同的路径 —— 同一个 Remote 调用、同一个 pending 状态、同一套失败处理。插件不新开写入通道。
节点可能因官方重渲染而失效,所以点击前先确认它还在文档里,不在就按档名重新解析一次。
为什么折叠而不是删除 radio:它们是档位名的来源、当前档的判据、以及写入的入口。 删掉之后滑块既读不到数据也写不进去。
折叠用 CSS 类(.dsh-ember__folded)而非内联 display:none, 这样插件卸载时类被清掉、规则随样式表消失,不会把用户的菜单永久弄空。 卸载路径实测 9/9 全部还原。
为什么松手才提交:拖动过程中只重画刻度与 aria-valuetext,不写数据。 一旦在 input 事件里提交,一次拖动会打出十几次切换。
只注入、不接管:官方那两行(模型 / 推理等级)原样保留,只是在推理等级下方 多了一个本插件写的块。官方菜单自己怎么渲染、怎么定位、怎么处理键盘,完全没动。
修正位置:lib/client.js 的 FULL_ACCESS_LABELS。
title 与 aria-valuetext 兜底)。available === false),与官方选择器一致。/model。git clone https://github.com/REALOIYO/dsh-ember
cd dsh-ember目录:
lib/index.js loader 入口(空实现,dsh.client 声明才让宿主加载 client.js)
lib/client.js 全部前端逻辑:CSS 注入、权限染色、滑块组件
cordis.patch.yml profile patch 层,插入一个 loader entry
docs/ 探测报告与验证记录离线验证台在 _tmp/(不在包内):用真实 DOM 复现 composer 行, 不连 DSH 即可检查红色与滑块。11 项断言 + 5 种档位长度。
MIT