dsh-sfw
为了防止你的好bro/同事看到内测dsh然后:?这是什么
- Stars
- 1
- Language
- TypeScript
- Created
- Aug 5, 2026
- Updated
- Aug 13, 2026
Introduction
dsh-sfw
⚠️ 弃用公告:dsh-sfw 即将弃用,停止维护。后续动态请看 https://github.com/dsh-external/issues/discussions/566
同志们!dsh-sfw!防止你的同学/同事/好bro 发现你在内测dsh
然后 gank 你 让你说出 dsh 的秘密()
目前
- 将左上角的 DeepSeek Harness SVG 换成可配置矢量字标(或选择只移除 HARNESS 铭牌、保留 DeepSeek 和 logo 的 harness-remove 模式)
- 然后把新对话页面的 deepseek logo 和 "预览版" 字样删掉了
- 三个处理面(字标 / 标签页标题 / 欢迎区)可各自独立开关

插件分两半:
- node 半部(宿主侧):通过
webServer.tapIndex改写被服务的index.html—— 把<title>DeepSeek Harness</title>直接换成产品名(JS 加载前标签页就不会露馅),并把配置以window.__DSH_SFW__注入页面(与__DSH_BOOT__同一条注入通道)。 - 浏览器半部(客户端):
document.title拦截 setter(会话标题的xxx — DeepSeek Harness也会被掩蔽);并把侧边栏/欢迎页/引导弹窗里的品牌字标 SVG 就地替换为配置的矢量字标。宿主 SVG 外壳、按钮行为和主题色继承保持不变,不触碰任何普通文本节点或属性。
只要插件包声明了 dsh.client(package.json 的 dsh 字段下),宿主 dsh-client-modules
会自动把它编译好的 lib/client.js 挂进浏览器端的加载图,无需改动 dsh 本体。
安装
在 dsh 的 web profile 下安装(以默认的 web profile 为例):
dsh plugin --profile web add link:D:\githubs\deepseek\dsh-sfw
然后把 @shenjack/dsh-sfw 加进 $DSH_HOME/profiles/web/package.json 的
dsh.profile.bundles 列表(与 @deepseek-ai/dsh-base 等并列)。无需编辑
cordis.patch.yml——插件自带 bundle patch(dsh.bundle.patch → 本仓库的
cordis.patch.yml)会插入自身行,与 session-persistence-rdb 的装载方式一致:
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"@morlay/session-persistence-rdb",
"@shenjack/dsh-sfw"
]
}
}
配置写在 $DSH_HOME/settings.yaml 的 dsh-sfw namespace(见下),或直接在
设置页的「插件配置」里改。改完 settings.yaml 热重载即生效;改完插件代码需
重新 pnpm run build,然后刷新浏览器页面(客户端 bundle 每次请求都会重新读取;
node 半部改动需重启 dsh web)。
部署前提:设置页的配置卡片要能读写,DSH 的 api-proxy 必须把
dsh-sfw放进其 Web settings allowlist(packages/host/apiproxy/src/api-proxy.ts的WEB_SETTINGS_NAMESPACES)。这是 DSH 侧的显式放行,注册 namespace 本身 不会让浏览器拿到读写权;未放行时卡片不渲染(namespace 返回settings-not-exposed)。
配置
配置有两个来源,按优先级叠加(后者覆盖前者):
- DSH 设置页的「插件配置」UI(推荐):浏览器端向设置页的「插件配置」
section 注册一张「品牌隐藏」卡片(
settings.plugin.itemslot)。卡片上的 保存即写入 settings 文档,效果与手改 settings.yaml 等价(字段进入用户层, 热生效)。可编辑:总开关、标签页产品名、左上角字标、字标处理模式,以及 三个处理面(字标 / 标题 / 欢迎区)的独立开关。 $DSH_HOME/settings.yaml的dsh-sfwnamespace(settings 服务存在时; 变更热生效,下次页面加载即用新配置):
dsh-sfw:
enabled: true # 总开关,false 时全部关闭
productName: 'Harness' # 标签页标题的替代产品名
wordmark: 'opencode' # 左上角字标,如 openclaw、harmes、reasonix
overlays: # 各处理面独立开关(可省略,默认全开)
wordmark:
enabled: true
# replace:整体替换为配置字标;harness-remove:只移除 HARNESS 铭牌,
# 保留 DeepSeek 字母和鲸鱼 logo
mode: 'replace'
title:
enabled: true # 浏览器标签页标题替换
hero:
enabled: true # 新对话欢迎区(鱼形图标 + "预览版"徽章)
cordis.patch.yml的 entry config(作为 base;未在 settings.yaml 写出的 字段回落到这里):
- insert:
- id: dsh-sfw
name: '@shenjack/dsh-sfw'
config:
enabled: true # 总开关,false 时全部关闭
productName: 'Harness' # 标签页标题的替代产品名
wordmark: 'opencode' # 左上角字标,如 openclaw、harmes、reasonix
overlays: # 各处理面独立开关(可省略,默认全开)
wordmark:
enabled: true
mode: 'replace' # replace | harness-remove
title:
enabled: true
hero:
enabled: true
settings.yaml 是纯 YAML(settings-local 用
yaml库解析),不支持!!jsJS 表达式;!!js只在cordis.patch.yml(bundle patch 层,loader 求值)有效。 两个来源的字段都可省略,未写出的字段取默认值;settings 服务缺失时(纯 cordis 装配/测试)只用来源 2。
opencode 使用固定上游版本的官方 SVG 路径。其他名称由内置 5×7 像素字库
生成纯 SVG path,支持英文字母、数字、空格、- 和 _;未知字符显示为 ?。
名称最长 32 个字符。整个过程不使用系统字体,也不增加覆盖层。
工作原理
- 字标 SVG 的字母本来就是矢量路径。插件识别
#dsh-wordmark-whale-clip后保留宿主持有的外层 SVG、清空原 children,再注入配置名称对应的路径。opencode使用官方0 0 234 42viewBox 和 16 条官方路径;其他名称由像素字库动态生成并按长度设置 viewBox。 harness-remove模式不动 DeepSeek 字母与鲸鱼 logo,只移除 HARNESS 铭牌:引用#dsh-wordmark-badge-clip的文字组、作为 svg 直接子元素的铭牌底板 rect,以及铭牌 clipPath def。- OpenCode 原组件的 weak/base/strong 三档主题色映射为
currentColor加透明度,在 DSH 的亮色和暗色主题中都沿用宿主文字颜色。按钮整体重挂载或 React 在现有 SVG 内恢复 children 时,观察器会再次处理;幂等标记保证不会重复注入。 - 观察者扫描新增子树内的所有后代 svg(整个 UI 是一次性挂载的一棵大树,字标只是后代节点),并对全文档做一次初始扫描。
- 三个处理面(字标 / 标题 / 欢迎区)由
overlays独立开关:关闭的处理面完全不启动,宿主端在标题关闭时也不再改写<title>(配置载荷仍会注入)。 - 设置页配置卡片通过 cordis 服务协作,不导入任何
@deepseek-ai/*包:ctx.settingsScope绑定dsh-sfwnamespace 读取/写入,ctx.slots把卡片注册进settings.plugin.itemslot。卡片样式直接使用 DSH 主题的--dsw-alias-*token;客户端 bundle 只 externalreact/react/jsx-runtime(Web 外壳的冻结平台模块)。 - 除
document.title、品牌字标 SVG 和欢迎区标题行样式外,不改写其他 DOM 内容。
已知限制
- 只覆盖浏览器界面;终端里
dsh启动横幅、URL 行等文本不在范围内。 - 侧栏折叠态鲸鱼和 favicon 是独立 SVG,目前不在字标替换范围内。
- 标签页标题只替换完整的
DeepSeek Harness拼写,不会误伤其他含DeepSeek的文本。 - 设置页卡片要求 DSH api-proxy 放行
dsh-sfwnamespace(见上文「部署前提」);未放行的部署不渲染卡片,也不报错。 - 卡片在「只读」部署(settings provider 只读)下显示只读提示并禁用控件。
开发
pnpm install
pnpm run build # tsdown 产出 lib/index.js + lib/client.js,tsc 产出 lib/types
pnpm test # vitest:配置解析/index 注入/字标替换与标题掩蔽