Skip to content
dsh.fish
Bundle

dsh-whale-font

把 DeepSeek Harness 对话里的主语人称「我/你/I/me」渲染成 DeepSeek 蓝鲸图标:字体层零 DOM 改动、复制保留原字、深色模式白肚子固定。

Source
kxSenlin
stars
3 stars
License
MIT
Updated
Updated 4 days ago

Readme

# dsh-whale-font

<p align="center"><img src="assets/whale.svg" width="80" height="80" alt="DeepSeek whale"></p>

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

将 DeepSeek Harness(DSH)对话中的主语人称「**我 / 你 / I / me**」显示为 **DeepSeek 官方蓝色鲸鱼图标**。

本插件仅在显示层替换,不修改消息数据、不影响模型读取与记忆,也不作用于输入框。替换后的图标用于标示每句话的主语(说话者)。

## 预览

浅色模式:

![浅色模式](assets/light-mode.png)

深色模式(内部细节固定为白色):

![深色模式](assets/dark-mode.png)

## 功能

| 位置 | 效果 |
|---|---|
| 助手消息中的「我」 | → <img src="assets/whale.svg" width="16" height="16" align="absmiddle"> 鲸鱼 |
| 用户消息中的「你」 | → <img src="assets/whale.svg" width="16" height="16" align="absmiddle"> 鲸鱼 |
| 助手消息中的英文 `I`、`me`(独立单词,默认助手词) | → <img src="assets/whale.svg" width="16" height="16" align="absmiddle"> 鲸鱼 |
| 助手消息替换词(设置中配置) | → <img src="assets/whale.svg" width="16" height="16" align="absmiddle"> 鲸鱼 |
| 用户消息替换词(设置中配置) | → <img src="assets/whale.svg" width="16" height="16" align="absmiddle"> 鲸鱼 |
| 引号内的任何内容(「我/你」、`I`/`me`、自定义词) | 一律保持原样 |
| 代码块 `<code>` / `<pre>` 内的任何内容 | 一律不替换 |
| 输入框(输入中) | 不替换 |

复制消息时,「我 / 你 / I / me」及自定义替换词均还原为原字符(不产生空字符或图片)。鲸鱼图形主体为蓝色,内部细节在深浅色模式下均为白色。

## 效果示例

在对话里发一句自然的话(假设设置里已把 `Deepseek / we / us` 加入助手替换词):引号外人称与替换词变成 DeepSeek 蓝鲸,引号、括号与代码块内保持原样。

![鲸鱼对话效果](assets/example.png)

落到不同位置的规则:

- **引号外**:`I` / `me` / `Deepseek` / `we` / `us` → 鲸鱼图标;`我` → 鲸鱼字形(字体层)
- **引号内**(`“”`、`「」`、`『』`)、**括号内**(`()` `【】` `[]` `{}`)、**代码块**(`` ` `` 行内 / ``` 块):所有内容一律不动
- `你` 只在用户消息里变鲸鱼,助手消息里保持原样

## 实现原理

插件由两层机制组成,两层均可独立开关:

| 层 | 处理对象 | 机制 | 说明 |
|---|---|---|---|
| 字体层(固定字体) | 中文「我」「你」 | 自定义彩色字体(COLR/CFF) | 字符渲染时即显示为鲸鱼,不修改 DOM、无闪烁、实时生效,复制保留原字符;主体蓝色、内部细节白色 |
| DOM 层(动态替换) | 英文 `I`/`me`、自定义替换词、引号内还原 | 监听页面变更并插入 SVG / 包裹基础字体 | 用于字体无法实现的整词判断与上下文判断 |

英文 `I`/`me` 及自定义英文词不使用字体的原因:字体为逐字符映射,会误替换 `It`/`Idea` 中的 `I` 以及 `message`/`time` 中的 `me`。DOM 层通过单词边界精确匹配独立的词;自定义中文词按子串匹配。

### 引号、括号与代码块的硬性边界

- **引号内一律不替换**:引号内的「我/你」不会被字体层变成鲸鱼,`I`/`me` 与自定义替换词也不插入图标,内容保持原样。引号配对在**整条消息行范围**内按文档顺序计算——markdown 把一句话拆成多个文本节点时,跨节点的引号(如 `他说“我` + `是”我`)也能正确配对。
- **括号内同样不替换**(设置项「括号内同样不替换」,默认开):`()` `()` `【】` `[]` `{}` 内的内容与引号相同处理,括号支持嵌套;括号内常是标识符/参数/引用,不应被替换。关闭后括号内恢复替换。
- **代码块内一律不替换**:`<code>` / `<pre>` 内不插入图标,字体层回退到等宽字体,「我/你」按普通文字显示。

### 目标容器(DSH web,兼容新旧两版)

插件同时识别新旧两版 DSH web 的消息行结构,哪个页面命中就用哪个:

| 消息 | 新版(数据属性) | 旧版(哈希类名) | 字体 |
|---|---|---|---|
| 助手回答行 | `[data-chat-flow-kind="assistant-step"]` | `.Sxvs8a_root` | `WhaleWo`(替换「我」) |
| 用户消息行 | `[data-chat-flow-kind="user"]` | `.gdEzaW_bubble` / `uV2eYG_` | `WhaleNi`(替换「你」) |

扫描范围默认 `[data-chat-flow], .Sxvs8a_root, .gdEzaW_bubble`。DSH 改版导致消息行结构变化时,可在设置页「文字替换」标签页调整范围选择器,无需改代码。

## 设置

安装后,打开 **设置 → 文字替换** 标签页:

![设置页截图](assets/settings.png)

- **启用鲸鱼图标**:总开关,停用后立即清除已插入的图标;
- **中文「我/你」鲸鱼字体**(字体层):关闭后「我」「你」按普通文字显示;
- **括号内同样不替换**(默认开):()()【】[]{} 内的内容与引号一样一律不替换;
- **助手消息替换词**(DOM 层):这些词在助手回答里显示为鲸鱼图标;引号、括号与代码块中保持原样。**默认自带 `I` 和 `me` 两个独立单词**(与其它词完全同一机制),可随意增删。填写示例:

  ```
  Deepseek
  We
  us
  ```

- **用户消息替换词**(DOM 层):与助手词条同一机制,但只在用户消息里生效,默认空。
- **对话区域 CSS 选择器**:DSH 改版后手动指定消息容器;
- 状态行:当前页面检测到的消息流容器数、助手/用户消息行数、助手/用户词条数量,用于确认插件是否生效。

设置保存在浏览器本地(`localStorage`),刷新页面后仍生效。

## 安装

### 前置要求

- 已安装 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(`dsh` 命令可用)。

### 方式一:官方命令(推荐)

执行以下命令:

```bash
dsh plugin --profile web add github:kxSenlin/dsh-whale-font
```

安装完成后,重启 DSH 服务,并在浏览器中强制刷新(`Ctrl + Shift + R`)。

可通过 `dsh plugin --profile web list` 确认插件已安装。升级时重复执行同一条 `add` 命令。

### 方式二:本地路径安装(离线)

将仓库下载到本地(`git clone https://github.com/kxSenlin/dsh-whale-font.git`,或下载 zip 后解压),然后在仓库目录下执行:

```bash
dsh plugin --profile web add ./dsh-whale-font
```

安装完成后同样需重启 DSH 服务并强制刷新。两种安装方式会将插件安装至相同位置,后续调参与卸载使用相同命令。

## 调整大小 / 位置(可选)

以下为默认参数,可按需调整。

> 仅在使用调参脚本时需要 fonttools;日常安装与使用插件(查看鲸鱼效果)无需安装。

1. `pip install fonttools`
2. 编辑 `tune/whale-config.json`:

   | 参数 | 含义 |
   |---|---|
   | `scaleX` | 鲸鱼图形的视觉宽度(值越大越宽) |
   | `scaleY` | 鲸鱼图形的视觉高度(值越大越高) |
   | `yOffset` | 垂直偏移(值越大越向下) |
   | `advanceWidth` | 字符占位宽度(普通汉字 = 1000) |
   | `leftBearing` | 图形左侧空白(值越大越靠右) |

3. 运行 `python tune/adjust_whale.py`(脚本读取同目录的 `favicon.svg` 与 `whale-config.json`,重新生成字体并写回已安装插件)。
4. 在浏览器中强制刷新,无需重启 DSH。

### 宽度参数的关系

鲸鱼图形的实际宽度 = `scaleX × 48.84`(`scaleX=28` 时约 **1367**)。三个宽度参数满足:

```
advanceWidth = leftBearing + 图形宽 + 右侧留白
```

- 调整图形宽度 → 修改 `scaleX`;
- 调整图形在占位内的水平位置 → 修改 `leftBearing`;
- 调整字符总占位宽度(与相邻字符的间距)→ 修改 `advanceWidth`。

> 需保证 `advanceWidth ≥ leftBearing + 图形宽`,否则图形会超出占位并与相邻字符重叠。
> 例如 `scaleX=28`(图形宽 1367)、`leftBearing=200` 时,`advanceWidth` 应不小于 `200 + 1367 = 1567`(默认值 1700,右侧留白 133)。

## 卸载

```bash
dsh plugin --profile web remove dsh-whale-font
```

## 常见问题

**Q:复制消息时英文 `I`/`me` 是否会丢失?**

A:不会。`I`/`me` 显示为鲸鱼图标,但复制结果为原字符;图标内包含一个默认不可见、选中时可见的原始字符,用于保留复制内容。中文「我/你」走字体,复制结果同样为原字符。

**Q:鲸鱼颜色异常(显示为黑色等)?**

A:鲸鱼主体为 DeepSeek 蓝 `#4d6bfe`,内部细节固定为白色,深色模式下不变黑。若显示异常,请确认浏览器支持 COLR 彩色字体(Chrome 71+ / Firefox / Safari 16.4+)。

**Q:升级 DSH 后鲸鱼不再显示?**

A:v1.1.0 起插件同时兼容新旧两版 DSH web:新版用数据属性(`data-chat-flow-kind`),旧版用 `.Sxvs8a_root` / `.gdEzaW_bubble` 哈希类名。若 DSH 再次调整 DOM 结构导致失效,先打开 **设置 → 文字替换** 标签页查看「消息流容器」数量是否为 0,再按需调整「对话区域 CSS 选择器」。

**Q:自定义替换词可以替换成任意文字吗?**

A:目前自定义替换词统一替换为鲸鱼图标(与 I/me 同一机制),复制消息时仍还原为原词。如需任意文字替换(如关键词高亮、改名),属于另一类功能,可在仓库提出需求。

**Q:引号内的内容会变吗?**

A:不会。引号内的任何内容一律不替换:「我/你」不会被字体层变成鲸鱼,`I`/`me` 与自定义替换词不插入图标。引号配对在整条消息行范围内计算,跨文本节点(markdown 拆行)也能正确配对。代码块内同理,一律不替换。

## License

[MIT](LICENSE)

## 目录结构

```
dsh-whale-font/
├── package.json        声明 dsh.bundle.patch + dsh.client
├── cordis.patch.yml    配置层(将插件挂载至 profile)
├── lib/
│   ├── index.js        节点端(空实现)
│   └── client.js       浏览器端(字体 + DOM 逻辑,含内嵌 base64 字体)
├── test/
│   └── smoke.mjs       jsdom 冒烟测试(npm run test:smoke)
├── tune/               调参工具(可选)
│   ├── adjust_whale.py
│   ├── whale-config.json
│   └── favicon.svg
├── assets/             README 配图
│   ├── whale.svg       蓝色鲸鱼图标
│   ├── light-mode.png  浅色模式截图
│   ├── dark-mode.png   深色模式截图
│   ├── example.png     对话效果示例截图
│   └── settings.png    设置页截图
├── LICENSE
└── README.md
```

Install

dsh plugin --profile web add github:kxSenlin/dsh-whale-font

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source