DeepSeek Harness 插件:自定义用户名与头像

前言

DeepSeek Harness(DSH)的左下角账号区域显示的是 DeepSeek 平台账号,只读;未登录时显示通用的“更多”按钮。这个位置无法反映你想要展示的内容。

dsh-user-profile 填补了这个空白:在本地存储一个名字和头像,叠加在同一控制上。账号菜单(设置/反馈/登出)继续正常工作,只有头像和名字发生变化。

插件定位

  • 插件名:dsh-user-profile
  • 维护者:xbbkok
  • 功能:在 DSH 中自定义本地显示的名字与头像,显示在侧边栏账号芯片中
  • 分类:未在 README 中明确标注,仅用于本地显示

核心能力

  • 用户名:最多 32 个字符,支持任意字符集;留空则使用平台默认
  • 头像:支持 PNG/JPG/WebP,居中裁剪并缩放到 192×192,以 base64 形式存储
  • 实时预览:在设置页编辑时可以看到结果,保存后侧边栏立即更新
  • 可逆重置:清除后恢复平台身份
  • 本地化:遵循 DSH 的语言设置(中文/英文)
  • 本地存储:不上传或同步,数据位于 ~/.dsh/plugins-data/dsh-user-profile/profile.json

安装与启用

官方推荐通过 bundle 安装:

dsh plugin --profile web add github:xbbkok/dsh-user-profile

在桌面应用上,使用 desktop 替代 web,然后重启 DSH。

若从本地检出安装,需要在对应配置文件中添加 insert 条目,且路径必须以 file:// 开头:

- insert:
    - id: dsh-user-profile
      name: 'file:///C:/path/to/dsh-user-profile/lib/index.js'

桌面与 Web 的配置路径:

构建类型 路径
Desktop %USERPROFILE%\.dsh\profiles\desktop\cordis.patch.yml
Web %USERPROFILE%\.dsh\profiles\web\cordis.patch.yml

典型用法

  1. 点击侧边栏账号芯片,打开 Settings(快捷键 Ctrl+Alt+,)。
  2. 在设置列表中找到 Profile。
  3. 设置名字,选择图片,点击 Save。
  4. 需要恢复平台身份时,点击 Reset。

存储位置与格式

%USERPROFILE%\.dsh\plugins-data\dsh-user-profile\profile.json

示例内容:

{
  "version": 1,
  "name": "Ada",
  "avatar": "data:image/png;base64,…",
  "updatedAt": "2026-10-20T02:14:44.183Z"
}

同一目录下的 heartbeat.txt 会在每次插件挂载时被重写,可用于检查插件是否加载成功。

头像以 192×192 的 base64 PNG 形式存储(通常 10–40 KB),由浏览器裁剪压缩,原始文件不会写入磁盘。

API

插件在 DSH Web 服务器上注册两个端点(与 GUI 同源):

方法 路径 说明
GET /user-profile 返回 { ok, profile, storagePath }
POST /user-profile Body { name?, avatar? };未填字段保持原值;avatar: null 可清除头像

验证规则:
- 名字限制 32 个码点,并移除控制字符
- 头像仅接受 PNG/JPEG/WebP 的 data: URL,并有字节上限
- 写入请求的 Origin 必须匹配本地主机,否则返回 403,防止跨站篡改

工作原理

插件采用“一包两半”的架构,类似其他 DSH UI 插件:

  • lib/index.js(Host / Node):管理 /user-profile 路由,负责验证、原子写入(临时文件 + 重命名)、心跳。无第三方运行时依赖。
  • lib/client.js(浏览器):通过 ctx.slots.register({ name: 'settings.section', id: 'profile', order: -30 }) 注册设置页,然后覆盖账号触发器 button[data-signed-out] 上的头像与名字。

设计选择:
- 不 fork 其他包的组件。账号按钮属于 dsh-client-ui-settings-account,直接修改容易在更新时失效。插件通过 DOM 装饰实现:记录每个原生子元素的 display,隐藏它们,插入自定义头像与标签;清除时恢复所有内容。使用 MutationObserver 在 React 重新渲染后重新应用,写入操作幂等,防止观察者递归触发。
- 失败在插件内部处理。缺失 Web 服务器、目录不可写或路由注册失败只会产生警告,不会破坏插件树。
- 语言跟随应用。通过 ctx.locale.register('user-profile', { zh, en }) 注册字典,页面读取 ctx.locale.bind(),使用 DSH 自身语言设置。
- 无构建步骤。lib/*.js 为可读的 ESM,直接被客户端模块系统使用,无需打包或 postinstall。

兼容性

  • DSH 0.2.x(@deepseek-ai/dsh >= 0.1.2-rc.1),桌面与 Web 构建
  • 使用 settings.section 插槽与账号触发器的 data-signed-out 属性,自 0.1.x 起稳定
  • 仅修改显示内容,登录、计费与模型调用不受影响

已知限制

  • 修改的是显示的资料,而非 DeepSeek 平台账号本身
  • 资料存储在单机,不跨设备同步
  • 若 DSH 未来重命名 button[data-signed-out],侧边栏覆盖会静默失效(设置页仍然可用)
  • 侧边栏覆盖是对其他包组件的 DOM 装饰,不是官方插槽

开发与测试

npm install   # 仅用于在无 GUI 环境运行浏览器端的 jsdom
npm test

测试覆盖 19 项:Host 验证、原子持久化、HTTP 处理(GET/POST/JSON 格式/过长名字/SVG 伪装/跨站写入/错误方法)、Bundle 加载、带本地化标签的插槽注册、芯片覆盖与完整恢复、折叠侧边栏、观察者稳定。

修改 lib/client.js 可在页面中热交换;修改 lib/index.js 需重启 DSH 以重新导入。

卸载

  1. 从对应配置文件中移除 dsh-user-profile 行(或从 dsh.profile.bundles 中移除)。
  2. 删除 %USERPROFILE%\.dsh\plugins-data\dsh-user-profile\ 目录。
  3. 刷新 DSH。

许可证

MIT 许可证,© 2026 xbbkok

生态背景

DSH 的理念是“一切皆插件”,社区目录独立于 DeepSeek 与幻方,不构成官方应用商店。该插件为社区维护,使用前建议检查源码与许可证。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye