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

鲸鱼娘看板 Turanbuturan/dsh-agent-whale-girl

DeepSeek Harness
Turanbuturan21 天前有提交已提供中文文档扫描:含敏感能力

侧边栏换成鲸鱼娘,实时播报 token 用量并陪你互动

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Turanbuturan/dsh-agent-whale-girl
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · browser
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 21 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 4 处,展示前 4 条)
  • 读取本地文件
    build.mjs:33
    const readBytes = (name) => readFileSync(join(here, name))
  • 读取本地文件
    build.mjs:42
    const rig = JSON.parse(readFileSync(join(here, 'layers.json'), 'utf8'))
  • 写入本地文件
    build.mjs:1196
    writeFileSync(out, bundle, 'utf8')
  • 写入本地文件
    build.mjs:1201
    writeFileSync(cssOut, CSS, 'utf8')
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

给 DSH Web GUI 配的非官方鲸鱼娘伙伴:侧边栏品牌标志,加一只可拖动、可折叠的悬浮吉祥物,实时显示 token 用量。

README

由 DeepSeek 最新模型翻译生成
dsh-agent-whale-girl 本文是中文开发文档。功能概览与安装见 README.md:本包已声明 dsh.bundle,可直接 dsh plugin --profile desktop add github:Turanbuturan/dsh-agent-whale-girl 安装,不必手工改 profile 补丁。下面「安装 / 卸载」一节写的是手工 drop-in 方式,仍然有效。 社区二创的「鲸鱼娘」(Whale-chan)形象,作为 DSH Web GUI 的品牌标记,外加一个可 拖动、可 收起、会 看你、会 说话(实时用真实数字播报)的看板娘。 两个插槽 | 位置 | 插槽 | 效果 | | 侧边栏品牌行(展开态 + 收起轨道) | sidebar.brand.mark | 官方小鱼 logo 换成鲸鱼娘脸部特写(avatar-face.png)。
展开完整文档(README 剩余 1 节)
dsh-agent-whale-girl

本文是中文开发文档。功能概览与安装见 README.md:本包已声明 dsh.bundle,可直接 dsh plugin --profile desktop add github:Turanbuturan/dsh-agent-whale-girl 安装,不必手工改 profile 补丁。下面「安装 / 卸载」一节写的是手工 drop-in 方式,仍然有效。

社区二创的「鲸鱼娘」(Whale-chan)形象,作为 DSH Web GUI 的品牌标记,外加一个可 拖动、可 收起、会 看你、会 说话(实时用真实数字播报)的看板娘。

两个插槽

| 位置 | 插槽 | 效果 |
| 侧边栏品牌行(展开态 + 收起轨道) | sidebar.brand.mark | 官方小鱼 logo 换成鲸鱼娘脸部特写(avatar-face.png)。单值插槽不允许同优先级重复注册,因此以 priority: -1 遮蔽官方品牌插件(优先级最低者渲染);品牌名文字(DSH 本地构建)不在此插槽内 |
| 整帧浮层 | shell.overlay | 220×298 的看板娘 + 上方 token 卡片 + 台词气泡;见下 |

交互(全部四类 + 心情)

| 操作 | 行为 |
| 鼠标靠近她 | 视线跟随:头朝光标转(±7° 上限)、尾巴反向摆(±4.8°),离开后 0.22s 内回到正中。基准是她脸上实测的眼睛/睫毛质心(art 坐标 220.9, 163.8),所以「正对着她的脸」= 0° |
| 按住 ≥ 350ms | 摸头:一次性「挤压回弹」动画(WAAPI,320ms)+ 专属台词;不会收起她 |
| 快速单击(< 350ms) | 收起 / 展开(4px 阈值内算点击,不会和拖动混淆) |
| 连点 3 / 4 次 | 连击播报:「已经点我 N 次了哦」 |
| 连点 5 次 | 彩蛋:一次性蹦跳 + ✨ + 「喷水给你看!」;同一次连击内只触发一次 |
| 拖动 | 按住拖到帧内任意位置;位置存 localStorage['whale-girl:position'],刷新后保持 |
| 双击 | 回到出厂的右下角,并清除位置记忆 |
| 窗口变小 | 自动夹回可视区,不会被甩出屏幕 |
| 鼠标 / 触屏 / 手写笔 | 统一 Pointer Events + touch-action:none;非起始指针的抬起事件被 id 守卫丢弃 |
| 收起态 | 64px 圆泡(同一张脸部特写),卡片与台词气泡仍在 |

心情刻度:data-mood 由上下文占用率决定 —— <50% = calm、≥50% = tense(偏冷)、≥85% = crit(泛红)。每次跨档会掉一颗 💦 在她右上角,2.6s 后消失。CSS 只对头部图层和尾巴做滤镜,身体不动,避免接缝色差。

关于动效的边界

她只在被交互时动:@keyframes 只有三条一次性动画(wg-pat / wg-egg / wg-emote),全部 1 次、无 infinite、无 alternate、无 will-change。空闲时 getAnimations() 为 0(真实浏览器实测)。骨架振幅仍留在 layers.json(head_amp / tail_amp),注视幅度由它推导(×5 / ×1.4 / ×1.6)。

台词系统(她说什么)

台词表就是组件里的一个对象,改文案 = 改这个对象:

const LINES = {
hello: ['我在这儿呢~', '今天也一起加油吧', '需要我帮忙吗?'],
busy: ['在写了…', '马上就好', '让我想想…'],
done: ['写完啦!', '搞定~', '要不要看看结果?'],
click: ['诶?', '在的!', '怎么啦'],
progress: ['已经写了 {out} 了…', '还在写,已经 {out}', '快了快了,{out} 了'],
warn: ['上下文用到 {pct}% 了', '上下文快到顶了({pct}%)'],
pat: ['呜…好痒', '别摸头啦', '诶嘿…', '头发会乱的'],
combo: ['已经点我 {n} 次了哦', '诶…还要点?({n})'],
combo5: ['好啦好啦,喷水给你看!', '呜哇!别戳啦~', '被你点晕了…(转圈)'],
};

| 触发 | 时机 | 台词 |
| hello | 挂载后 1.5s,说 5s | 打招呼 |
| click | 点她(收起/展开) | 应答 |
| progress | 实时播报:每 1s 检查,Token 在最近 4s 内有增长就算「在干活」,每 3.5s 换一句 | 带真实数字,{out} = 当前输出量 |
| warn | 上下文 ≥ 80% 时提醒一次(每会话一次,且等这轮说完再插话) | {pct} = 当前上下文占用 |
| done | 停止增长 2.5s 后 | 收工 |

- 占位符由 wgFill() 在说话时用真实数字填充:数字来自已经在订阅的会话投影 tokenUsage / contextPressure。台词是模板 + 本地数字拼接,她说话本身不联网、不调模型、不额外请求;真正消耗 token 的是你我在对话里的模型推理,与本插件无关。
- 呈现:.wg-say 气泡在她上方(悬停标签在左侧,互不打架),3–6s 自动消失,带 aria-live="polite"。
- 节奏常量:TICK_MS=1000、WORKING_MS=4000、BUSY_EVERY_MS=3500、WARN_PCT=80、LINE_MS=4000。嫌吵就调大 BUSY_EVERY_MS / WORKING_MS。
- error 类台词没做:当前没有可靠的失败信号,硬凑会变成假报错。

三层皮影骨架

三层(身体 / 头 / 尾)仍然保留:静止时与原立绘逐像素一致(alpha 差 0、颜色均值 ≈2.1/255),所以它们是"隐形"的,只在交互时显形。头与尾各有实测旋转支点(不是猜的):

- 头:transform-origin: 53.5% 46.62% —— 由头部图层的左右镜像轴算出(153/286 px)
- 尾:transform-origin: 17.23% 116.6% —— 藏在裙摆后的鳍根

支点写在 layers.json 的 pivots 里,自检会断言 CSS 用的是这两个值。

注视基准(她看的方向,与转动支点是两件事)写在 layers.json 的 gaze_center:art 坐标 220.9, 163.8,是 avatar-head.png 里眼睛/睫毛像素的质心(由 anim/layers.py 的测量脚本得出)。用包围盒中心会偏 21px/44px —— 那个盒子连头发和肩膀都算进去了。两个值都在美术坐标系(414×560),换算到客户端像素时用的是舞台的缩放比。

token 卡片

只显示当前会话的用量,数字来自 DSH 自己的会话投影,因此与输入框右下角的官方指示器完全一致:

- contextPressure → projectedTokens(回退 pressureTokens)与 contextWindow → 上下文 xx% + 进度条、占用 tokens / 窗口
- tokenUsage → 输出、输入 / 缓存读

没有可用会话时卡片隐藏(不显示假零值);全新会话报 0 时仍显示(窗口大小仍有意义);窗口窄于 900px 时卡片让位。

账户余额功能已删除:remote.account 在部署里没被投放(客户端看不到这个面),而 API Key 钱包那条路(宿主半边查 api.deepseek.com/user/balance)被实测证明该 Key 已被上游拒绝(401 invalid),所以整块拆掉了。

文件

| 文件 | 作用 |
| package.json | dsh.client.platform = "web",让 DSH 把 ./client 作为浏览器 bundle 投放 |
| index.js | 宿主半边:空实现(只负责能被 Loader 载入) |
| lib/client.js | 构建产物:window.__ModuleLoader__.load({...}) 注册 + 两个插槽注册 |
| lib/client.css | 构建产物:样式表原文;自检断言「bundle 真正注入的文本 == 这个文件」 |
| build.mjs | 由四张 PNG + layers.json 生成上面两个产物(内联图片、把骨架几何写进 CSS) |
| layers.json | 皮影骨架:每层裁切框、旋转原点(原始 414×560 坐标系)、动作幅度、pivots(实测支点) |
| verify-bundle.cjs | 结构 + 行为自检(见下) |
| avatar-body.png / avatar-head.png / avatar-tail.png | 皮影三层 56 KB / 31 KB / 3 KB |
| avatar-face.png | 脸部特写 96×96,用于 24px 标记与收起态圆泡 |
| avatar.png | 拆骨前的整身立绘(渲染回归的参照图) |
| assets/ | 原始素材(抠好背景的 720×974 全身图、上一版 Q 版头像等) |

自检覆盖什么

分两层,因为「DOM 替身」无法诚实地回答「浏览器到底画成什么样」。

结构 + 单元(verify-bundle.cjs,纯 Node)

- 注册 id / require 白名单 / inject / 两个插槽 / 样式只插一次
- 四张内联图与源文件字节一致
- 注入的 CSS 与 lib/client.css 逐字节相同,且不是被引号包住的字符串(这条断言曾经救过一次线上事故:整页样式全丢)
- 每层的 CSS 定位、图层顺序、wg-l 定位类与 layers.json 一致;支点用 pivots 的实测值
- 动效边界:@keyframes 恰好三条、名字必须是那三条、不许 infinite / alternate / will-change
- 注视数学:直接调用 bundle 的 wgGaze,断言「指针在她的脸上 → 0°」「向右看 → 正角度」「尾巴反相」「无指针 → 全零」「不会超过幅度上限」「基准不是包围盒中心」;探测点由脸中心的 art 坐标推导,而不是硬编码客户端像素(硬编码会在基准移动时静默变成另一个方向)
- 注视写入:断言数字真的落到头部图层的 --sg / --st
- 行为:token 卡片(有用量 / 全新会话零值 / 无会话)、单击出话、问候定时器、心跳带真实数字、连击阶梯(第 3 次有计数、第 5 次出彩蛋、同一轮不重复)、按住 400ms 出摸头动画且不收起她、心情三档取值
- 时间语义:替身的 setTimeout 是排队 + 手动推进,不是立即执行 —— 否则「900ms 后结束连击」会在同一次点击里触发,连击永远到不了 3(这个坑真出现过)

真实浏览器(cdp-interact-live.mjs,Chrome DevTools Protocol)

在真实页面上用真鼠标事件驱动,并在线标定她头部的实际转动中心(不靠手算),断言:三层在屏、9 点扫描全程单调(-3.74° → +3.23°,0 次反向)、尾巴在每个采样点都反相、扫描零点与 bundle 自报的脸中心重合(实测差 0.1px)、按压产生一条真实的 320ms 一次性动画、空闲时 getAnimations() 为 0、data-mood 合法。当前状态:LIVE PASS。

探针的取点必须落在按钮自己的盒子内:超出范围的坐标根本不会送达,读到的还是上一次的值,看起来就像"功能坏了"。同理,getComputedStyle(el).getPropertyValue('--sg') 对未设置的自定义属性返回继承来的空值,要读内联样式(el.style.getPropertyValue)。两个坑都踩过。

安装 / 卸载

装载条目写在 profile 的用户补丁层 ~/.dsh/profiles/desktop/cordis.patch.yml:

- insert:
- id: whale-girl
name: "./plugins/dsh-agent-whale-girl/index.js"

- 路径相对 profile 目录解析(Loader 的 baseUrl 锚在 profile 目录上)。
- 卸载:删掉这个 insert 条目,保存后刷新页面。
- 客户端改动:刷新页面即可生效;宿主半边改动:必须重启应用 —— Node 的 ESM 缓存会钉住同一个文件路径,profile 热重载不会重新 import 它。

重新构建

$py = "$env:USERPROFILE\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\python\python.exe"
$node = "$env:USERPROFILE\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\node\bin\node.exe"

1) 换图或调骨架参数后,重切三层并导出到本目录(会打印 REST exactness,应为 0) & $py "$env:USERPROFILE\Documents\deepseek-harness\default-workspace\whale-girl\anim\layers.py" --export

2) 生成产物并自检 & $node build.mjs & $node verify-bundle.cjs lib/client.js

3) 真实浏览器验证交互(需先签 cookie;退出码 0 = LIVE PASS) & $node "$env:USERPROFILE\Documents\deepseek-harness\default-workspace\whale-girl\mint-cookie.mjs" & $node "$env:USERPROFILE\Documents\deepseek-harness\default-workspace\whale-girl\cdp-interact-live.mjs" 9341 "$env:TEMP\wg-live" (Get-Content "$env:TEMP\dsh-cookie.txt" -Raw).Trim() 'http://127.0.0.1:19387/' "$env:TEMP\live.png"

layers.py --dump 会逐行打印鲸尾蒙版的 x 范围,方便校形;sim-.png 让穿帮在浏览器之前就暴露。

工作室(工作区 whale-girl/)

| 文件 | 作用 |
| anim/layers.py | 切层 / 抠洞 / 补洞 / 合成模拟;--export 写进插件 |
| anim/shots.py | 探针截图拼成对照表 + 与静止立绘做像素比对 |
| harness.mjs | 用 lib/client.css + 四张图 + 等价 DOM 生成 anim/harness.html(绕开登录态测量/截图) |
| cdp-anim.mjs | 探针:样式表是否真生效、图层定位、静态性、悬停、reduced-motion、静止帧与原图对比 |
| cdp-drag.mjs | 拖动 / 位置记忆 / 单击收起 / 双击复位 |
| cdp-interact-live.mjs | 真实浏览器交互验证:在线标定转动中心、视线跟随单调性、尾巴反相、按压动画、空闲零动画、心情 |
| cdp-eval.mjs | 在真实页面里跑任意表达式(配合 anim/probe-.js) |
| mint-cookie.mjs / probe-auth.mjs | 用凭据库里宿主自己的 client-connection/browser-session 秘钥现签会话 cookie(宿主的 cookie 有效期很短:1 小时有效、6 小时会被拒) |
| anim-hunt/FINDINGS.md | 动画素材调研:三个候选仓库都无动画帧;另有 Live2D 模型(CC BY-NC-SA,非商用)与精灵图(无 LICENSE) |
| PLAN-lines.md | 台词系统的设计稿(已实现,留作后续扩展参考) |

踩过的坑(都留了断言)

1. 注入 CSS 多了一层引号 —— const CSS = '"…"',浏览器解析出 0 条规则,页面变成裸 DOM。现在自检逐字节比对注入文本与 lib/client.css。
2. 会把静态内容居中 —— 头部图层漏了 wg-l 定位类,整个人飘到胸口。现在每层显式 position:absolute 且自检断言 class 列表。
3. 带类型的服务属性必须先 inject —— ctx.remote / ctx.connection 这类属性若未声明,在 apply 阶段拿到的是 undefined(静默失败);宿主半边的余额路由 404 就是这么来的。
4. 占位符替换漏了模板 —— 开关写在 bundle 模板里,而 .replace() 只作用于 componentSource,于是构建永远留着未定义标识符。
5. 不要用 PowerShell 的 Get-Content | Set-Content 改这个仓库的 UTF-8 文件 —— 默认按 ANSI 解码会把整份中文变成不可逆的乱码。用编辑器工具或 Node/Python 写 UTF-8。
6. 自检替身必须遵守真实时序 —— 三处都踩过:setTimeout 不能立即执行(否则连击永远到不了 3)、effect 必须在「提交 DOM 之后」跑(否则挂载时查不到图层节点)、getComputedStyle 读自定义属性要改读内联样式(否则永远读到继承的空值)。每一处修好之前,自检都在报假失败,而假失败和真 bug 一样贵。
7. workdir 不跨命令保留 —— 用相对路径 verify-bundle.cjs lib/client.js 时脚本会去别的目录找 bundle 并直接崩掉;崩溃输出被 PowerShell 包装后曾被我读成"通过了"。现在一律绝对路径,并且构建与自检必须在同一条命令里(构建在别处执行过不代表产物是最新的)。
8. 坐标系搞混了一次,代价是 83px —— 视线基准从"头部包围盒中心"换成"脸上实测点"时,我只改了基准的数值,却忘了基准所在的空间:它在美术坐标系(414×560),换算却仍除以舞台宽度(220),于是 220.9 被当成舞台像素,等于放大 1.9 倍。真实浏览器扫描显示零点在 page x=1220,而她的脸在 1137 —— 差 83px。这类错误只有真实浏览器 + 在线标定能看出来:自检的假 sessions 数据看起来一切正常。
9. 模板字符串里不能出现反引号 —— build.mjs 用 String.raw 包着整段组件源码,JSDoc 里写 why 这样的行内代码会直接终止模板、报 SyntaxError: Unexpected identifier。构建失败时 lib/client.js 仍是上一次的产物,于是自检"通过"、浏览器行为却是旧的 —— 必须每次都检查构建退出码,这也是第 7 条的另一面。
10. 先确认探针字段的语义,再动代码 —— 我把拖动探针的 pressed 当成"指针按下中",它其实是 aria-pressed(= 她是否收起),于是去"修"了一个不存在的问题。误读并非全无收获:它让我看到 onPointerUp 的 id 守卫放在清理之前,两根手指先后按上会丢掉一个拖动会话 —— 现在 onPointerUp 和 release 都是先清理、再判断。
11. 突变测试是唯一能证明断言有效的方法 —— 自检全绿可能只是"断言太松"。把已修好的坐标空间 bug 手工注回 bundle:自检必须 FAIL(实测报出「a pointer on her face must mean no turn」),原件必须 PASS。两步都过,才敢说这条断言真的在守门。

素材来源与署名

形象来自社区二创(非 DeepSeek 官方):

- Neko3000/deepseek-whalechan — 当前使用的形象(skills/whalechan-image-character/assets/reference-images/semi-chibi/0067_angry_you_are_silly_reply_rendered_isolated.webp),抠背景后作看板娘与标记;该仓库未声明 LICENSE,仅供个人使用
- TreapGoGo/deepseek-whale-girl — MIT,上一版 Q 版头像来源
- fornarwhal/deepseek-whale-girl-icon — CC BY-NC-SA 4.0,候选图标来源
- 想要「真动画 / 真眨眼」:社区有 Live2D 模型可用,但素材是 CC BY-NC-SA 4.0 且要求三位署名;见 anim-hunt/FINDINGS.md

商用或再分发前请自行核对各仓库的授权条款。
预览分享卡片长什么样 ↓Turanbuturan/dsh-agent-whale-girl
分享 · DeepSeek Harness Hub
Turanbuturan/dsh-agent-whale-girl

侧边栏换成鲸鱼娘,实时播报 token 用量并陪你互动

这是你的仓库?认领条目

回到顶部