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

鱼竿鲸鱼娘光标 xingheyewang-1/dsh-whale-rod-cursor

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

把系统光标换成甩着鲸鱼娘的弹性鱼竿

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

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

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add xingheyewang-1/dsh-whale-rod-cursor
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · ui
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/09/25·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 50 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

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

验证判据与等级说明 →

可信度证据

安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-whale-rod-cursor(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/9/21 23:48:53

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

读写/删除本地文件
查看扫描证据(共 24 处,展示前 17 条)
  • 读取本地文件
    build.cjs:48
    if (!fs.existsSync(SRC)) { console.log('✗ 找不到源码 ' + SRC); process.exit(1); }
  • 读取本地文件
    build.cjs:60
    if (!fs.existsSync(file)) throw new Error('找不到素材 ' + file);
  • 读取本地文件
    build.cjs:117
    if (!measured && fs.existsSync(META_OUT)) {
  • 读取本地文件
    build.cjs:118
    const saved = JSON.parse(fs.readFileSync(META_OUT, 'utf8'));
  • 读取本地文件
    build.cjs:129
    const png = fs.readFileSync(file);
  • 读取本地文件
    build.cjs:142
    let js = fs.readFileSync(SRC, 'utf8');
  • 写入本地文件
    build.cjs:153
    fs.mkdirSync(path.dirname(PREV), { recursive: true });
  • 写入本地文件
    build.cjs:154
    fs.copyFileSync(OUT, PREV);
  • 写入本地文件
    build.cjs:157
    fs.writeFileSync(OUT, js, 'utf8');
  • 写入本地文件
    build.cjs:162
    fs.mkdirSync(PREV_DIR, { recursive: true });
  • 写入本地文件
    build.cjs:178
    fs.writeFileSync(full, Buffer.concat([BOM, buf]));
  • 写入本地文件
    build.cjs:194
    fs.writeFileSync(META_OUT, JSON.stringify(sidecar, null, 2), 'utf8');
  • 读取本地文件
    smoke-test.cjs:20
    const PKG = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
  • 读取本地文件
    smoke-test.cjs:26
    const SIDECAR = JSON.parse(fs.readFileSync(ANCHOR_JSON, 'utf8'));
  • 读取本地文件
    smoke-test.cjs:322
    const code = fs.readFileSync(CLIENT, 'utf8');
  • 读取本地文件
    smoke-test.cjs:323
    console.log('文件: lib/client.js (' + (fs.statSync(CLIENT).size / 1024).toFixed(1) + ' KB)');
  • 读取本地文件
    smoke-test.cjs:365
    const sha = crypto.createHash('sha256').update(fs.readFileSync(ASSET_DIR + m.asset)).digest('hex').slice(0, 16);
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-slots
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 替换系统光标
  • 弹性甩飞回弹
  • 悬停变色与音效
展开完整介绍(127 字)↓

🎣 鱼竿鲸鱼娘光标 —— DSH Web 的鱼竿光标:弹性绳吊着 Q 版鲸鱼娘,随鼠标甩飞/回弹,悬停变色,甩猛了尖叫,停下演「钓鱼佬又空军了」小剧场。A fishing-rod cursor companion for the DSH Web UI.

README

由 DeepSeek 最新模型翻译生成
🎣 dsh-whale-rod-cursor · 鱼竿鲸鱼娘光标 Listed on dsh-plugin.org License: MIT 一句话价值:把你 DSH Web 界面里那个冷冰冰的系统光标,换成一根鱼竿 ——线上吊着只 Q 版鲸鱼娘,你甩鼠标她就跟着飞,悬停输入框会变色,鼠标一停她还自己演"钓鱼佬又空军了"的小剧场。 一个挂在 DeepSeek Harness Web 界面上的小玩具插件: 鼠标位置 = 鱼竿竿尖(默认直接把系统光标换成鱼竿),一条带弹性的绳吊着 Q 版鲸鱼娘(当鱼饵)。鼠标一动,她被猛拽 → 甩飞出去 → 荡几下收回来;甩猛了会冒萌语气泡(字随力度变大,最猛时和鲸鱼娘一样大),安静下来还会补一句求饶/卖萌/生气的台词。 她还会跟着 DSH 的干活状态换姿态:平时 / 在忙 / 干完了。 悬停输入框 / 按钮 / 按下鼠标时,鱼竿会变色,让你用余光就知道"现在点得到什么"。 当前版本:v8(__WHALE_ROD_CURSOR_VER__ = '2026-09-15-v8-swingbubble',包版本 0.1.2) 一、它长什么样 ╲ ← 竿尖钉在鼠标位置(箭头光标同朝向:竿身往右下拖) ╲ │ ← 弹性绳(会随甩动拉长/回缩) │ (🐳) ← Q 版鲸鱼娘 = 鱼饵(猛拽、甩飞、Q 弹形变、荡几下收回) 💬 "杀鲸啦!
展开完整文档(README 剩余 1 节)
🎣 dsh-whale-rod-cursor · 鱼竿鲸鱼娘光标

Listed on dsh-plugin.org
License: MIT

一句话价值:把你 DSH Web 界面里那个冷冰冰的系统光标,换成一根鱼竿 ——线上吊着只 Q 版鲸鱼娘,你甩鼠标她就跟着飞,悬停输入框会变色,鼠标一停她还自己演"钓鱼佬又空军了"的小剧场。

一个挂在 DeepSeek Harness Web 界面上的小玩具插件:

鼠标位置 = 鱼竿竿尖(默认直接把系统光标换成鱼竿),一条带弹性的绳吊着 Q 版鲸鱼娘(当鱼饵)。鼠标一动,她被猛拽 → 甩飞出去 → 荡几下收回来;甩猛了会冒萌语气泡(字随力度变大,最猛时和鲸鱼娘一样大),安静下来还会补一句求饶/卖萌/生气的台词。
她还会跟着 DSH 的干活状态换姿态:平时 / 在忙 / 干完了。
悬停输入框 / 按钮 / 按下鼠标时,鱼竿会变色,让你用余光就知道"现在点得到什么"。

当前版本:v8(__WHALE_ROD_CURSOR_VER__ = '2026-09-15-v8-swingbubble',包版本 0.1.2)

一、它长什么样

╲ ← 竿尖钉在鼠标位置(箭头光标同朝向:竿身往右下拖) ╲ │ ← 弹性绳(会随甩动拉长/回缩) │ (🐳) ← Q 版鲸鱼娘 = 鱼饵(猛拽、甩飞、Q 弹形变、荡几下收回) 💬 "杀鲸啦!"

- 竿子朝向:竿尖在左上、竿身朝右下延伸 —— 和系统箭头光标同一个朝向(v3 修正,v2 是倒着拿的)
- 尺寸:整体 0.72 倍(v3 缩小一档),鱼竿与挂件一起缩;设置页可 0.5–1.2 调
- 鱼饵沿绳方向旋转(最多 ±58°,不会翻跟头)
- Q 弹形变:阻尼余弦振荡 amp = A·e^(-t/τ),压缩/拉伸绕角色中心发生
- 绳末端严格接在她头顶:挂点不是画布中心,而是构建期用 jimp 扫 alpha 量出来的
"画布中线往下第一个实体像素"(当前素材是 (72,10);画布顶端到那儿有 8px 透明留白)。
Q 弹压缩的支点也改成"内容中心"。换素材只需重跑 node build.cjs,不用手改任何常数。

一·五、姿态包:平时 / 在忙 / 干完了(v6 新增)

三张姿态图都已抠好(都是上游 MIT 素材,声明见 NOTICE.md),构建期为每张分别量挂点:

| 姿态 | 素材 | 尺寸 | 挂点 | 什么时候用 |
| idle 平时 | keyed-idle.png | 144×180 | (72,10) | 默认 |
| work 在忙 | keyed-work.png | 159×180 | (80,9) | DSH 正在跑 / 或被甩得手忙脚乱 |
| done 干完了 | keyed-done.png | 160×180 | (80,9) | 跑完了,停留 2.5 秒(可调) |

两种驱动来源(设置页一键切):

- 跟着 DSH 状态(默认):读官方客户端服务 ctx.get('sessions') 的列表快照 { current, byId },取当前会话那一行的 running 布尔值 —— 在跑 → work;跑完 → done 停 2.5s → 回 idle。订阅 + 800ms 轮询兜底,状态一变就跟上。
服务读不到(版本差异)时自动退化成"跟着甩动",而且不会报错。
- 跟着甩动:被甩飞 → work(手忙脚乱);荡稳了 → done(喘口气)→ idle。

性能:三张图都内嵌成三个 ,切换只改 display —— 不重新解码、不闪烁、每帧零开销(只在状态真变了才动一次)。代价是 client.js 从 126.8 KB 涨到 317.9 KB (多约 180 KB base64,一次性解析;鼠标路径完全不受影响)。
将来若嫌包大,可以像桌宠那样改成宿主路由 GET /whale-rod/pose/.png 按需懒加载。

二、手感:猛拽 → 甩飞 → 荡几下收回(v4 换回低阻尼)

递进刚度 + 常数阻尼(阻尼小才有甩飞感):

k_eff = k_soft + k_yank · clamp(|v_rel| / 1600, 0, 1) ← 甩得越猛,绳子越"硬"
F = -k_eff·(绳长差)·方向 - c·v_rel + 重力 ← c 是常数(默认 2.6)
v = e^(-λ·dt) (半隐式欧拉积分)

实测曲线(冒烟测试 [7] 每次都会重新量一遍):

| 阶段 | 数值 |
| 静息悬挂 | 鼠标下方 83px(绳长 62 + 重力沉降 21) |
| 猛拽 600px 的瞬间 | 距离拉到 538px —— 初始拉力极大 |
| 之后 | 416 → 228 → 444 → 333 → 42 → 97 → 85 → 83px —— 荡出去最远 481px(静息的 5.8 倍),这就是"甩飞" |
| 匀速拖拽 1200px/s | 只拖出 82px 尾巴 —— 匀速时仍跟手 |
| 极端甩 1500px | 峰值 1323px,照样收回 83px,不失控飞走 |

想要"乖乖滑回来"就把设置里的「阻尼」调大(8 就基本不荡了);想要更疯就调小。

三、颜色 = 可交互性提示

| 状态 | 颜色 | 含义 |
| 默认 | 深海青蓝 #4FA3D1 | 安静待着 |
| 悬停输入框 / 可编辑区 | 亮青绿 #5FE3B0 | 这里可以打字 |
| 悬停按钮 / 链接 | 淡金 #F2B23E | 这个能点 |
| 按下鼠标 | 橙红 #F2603E(闪 150ms) | 点到了 |
Use closest('textarea, input, [contenteditable]') and closest('button, a, [role=button]') for判定, do not hardcode any DSH class names, so it will not break even if the UI is redesigned.

Because "whether it can be clicked / whether it can be typed in" is all drawn on the fishing rod, hiding the system cursor does not lose information.

IV. Two Cursor Modes

| Mode | Behavior | Description |
| Fishing rod as cursor (default) | html, html { cursor: none }, the fishing rod is pinned to the mouse position | The rod tip follows the hand strictly, with zero delay; the fishing rod itself is the cursor |
| Real cursor + towed attachment | The system cursor is displayed as usual, and the fishing rod hangs beside it | Cursor semantics (I-beam, etc.) are preserved as-is |

Emergency exit: press Alt+Esc to switch between the two modes with one key (in case you cannot find the mouse).
There are also three safety nets: window loses focus / mouse leaves the window / tab is hidden / component unmounts or rendering errors — in any of these cases, immediately restore the system cursor.

V. Bubbles: Triggering Looks at Acceleration + Fling Speed, Font Size Looks at Force (v3 trigger / v4 font size / v8 trigger moved into the physics loop)

Two trigger lines run in parallel, and whichever is larger is used:

① Event line (mousemove): sp = movement speed (px/s), acc = rate of change of speed (px/s²) = instantaneous acceleration
② Physics line (every frame): relSp = |her relative speed to the mouse| ← captures "being yanked away" and "inertial gliding"

- Force = max(acc / acceleration threshold, relSp / fling threshold); if > 1, a bubble appears
- The more violently she is flung → the shorter the cooldown → the more frequently bubbles appear (lower limit 0.7s, to prevent screen flooding)
- Font size grows with force: 13px × force^1.25, capped at ≈ the whale girl's height (about 121px at 0.72 times)
—— so the bubble from the most violent moment can be as big as her; the bubble's padding/border are all in em, so the whole bubble grows together; long sentences (such as "Stop flinging me, stop flinging me, can't I just beg for mercy——") automatically shrink a bit based on character count, to avoid pushing off the screen
- Force ≥ 3 times the threshold → scream pool (13 lines), with three flavors chosen randomly:
- Pure screams: "Ahhhhhhh——" "Wah ahhhhhh——"
- Begging for mercy: "Please stop flinging me, wuwuwu——" "I was wrong, I was wrong! Put me down——" "Spare me, fisherman——" "I confess! I admit I am a fish——"
- Crying: "Wuwuwu I'm going to throw up——" "I'll cry for you to see! Wuwuwuwu——" "Wu—— my ahoge is going to fly off——" "Wuwu... I'll never sneak Tokens again——"
- After calming down, add a line: after being flung and then quieting down (relative speed 150ms, reset the baseline to zero (treat it as starting from rest, so even a whip-crack can still be caught)

v8: Bubble triggering moved into the physics loop (fixing "flung away but no bubble")

Bug scene: she was clearly flung far away, yet did not make a sound; instead, when switching back to the window, a huge scream popped up.

Cause (all three point to the same mistake: the trigger point was placed in the wrong place):

| Phenomenon | Cause |
| Uniform fast drag → no bubble | The old logic only ran in mousemove and only looked at acceleration; uniform dragging has high speed but acceleration ≈ 0, so the threshold could never be reached |
| No bubble at all during the half second after flying out | Once the mouse stops, there are no mousemove events —— and her "being flung away" happens precisely during the inertial gliding phase after the mouse stops, where no check was running at all |
| Screaming instead when switching back to the window | The pointer teleports into the window + baseline reset → a fake "sky-high acceleration" is calculated |

Fix:

- Move triggering into the physics loop (runs every frame), with intensity using "her relative speed to the mouse" relSp
—— this is the physical truth of "how violently she was flung", fully covering both uniform dragging and inertial gliding; the acceleration line (sudden start / sudden stop) is retained, and whichever of the two is larger is used
- Add a new setting item "Fling sensitivity" (default 1400 px/s); the original "Swing sensitivity" is still the acceleration threshold
- When the pointer re-enters the window (focus / mouseenter): while she is still invisible, directly snap to the new anchor,
so she will neither be flung away by a fake violent yank nor emit an inexplicable scream (the position does not jump within a frame, because she was originally invisible)

Regression test ([4.8]): uniform fast drag at 3300px/s → a 28px bubble appears during dragging; after stopping (zero mousemove), another 19px bubble appears during the inertial gliding phase ✔

v8: The rope does not unhook even during Q-elastic deformation

Deformation compresses around the "content center", so the top of the head moves up/down with the deformation (peak up to 32px).
Previously, the rope end was pinned dead at the anchor point → at the instant of being flung, it looked like "the rope had detached from the head".
Now the rope end (and bubble position) calculate the "deformed top of the head" using the same set of transformations, so the two always coincide:

Error at rest 0.000px
Error during Q-elastic deformation 0.01px (measured after pressing the mouse to trigger deformation)

V·V. Idle Mini-Theater (new in v7)

When the mouse stops (default 6 seconds), she starts performing on her own. The line pool has 20 lines, themed around
fishing for whales / fishermen / coming home empty-handed —— half mocking, half cute:

"The fisherman came home empty-handed again today, huh~" "Hello, Commander of the Empty-Handed Air Force, salute!" "You swing the mouse like a fishing float; you'd catch something only if there were ghosts"
"Fish for me? Prepare a ton of dried small fish first" "Want me to take a bite? Just one bite, okay" "This whale is in a good mood today, so I allow you to touch my head once"

- Line interval defaults to 7 seconds, and will not repeat consecutively (remembers the last 5 lines spoken)
- Priority: screams > calm lines > mini-theater —— the three share the "last speech time" gate, always one line at a time, never interrupting each other
- DSH does not interrupt while working (keeps quiet during the work pose, focusing on being a "busy whale")
- As soon as the mouse moves, the performance stops and the timer restarts
- The pool can be freely edited on the settings page (one line per entry); if you do not like it, turn it off with one click

VI. It will not get in the way of what you are doing

- The entire layer has pointer-events: none —— clicking, selecting, dragging, and shortcuts all work as usual
- Each frame only writes transform and SVG coordinate attributes, without touching any layout attributes, so it will not cause reflow
- Pauses rAF when the tab is hidden
- Wrapped in a render error fence: even if an error occurs, it only displays one line of red text, and never throws the exception to the framework (avoiding the entire overlay being unmounted), and conveniently returns the cursor

VII. Installation

From the plugin marketplace / npm (available after release):

Make sure of the profile: this plugin is a web-side plugin, so use web for the profile
dsh plugin --profile web add dsh-whale-rod-cursor

Install from GitHub source:

markdown
dsh plugin --profile web add git+https://github.com/xingheyewang-1/dsh-whale-rod-cursor.git

装完必须重启 dsh web(客户端 bundle 是启动时进内存缓存的,只刷新页面不够),然后硬刷新页面。仓库里已经带了构建好的 lib/client.js,不需要任何构建步骤与授权。

本地开发版安装(本机就是这条): powershell 一条命令搞定(幂等,可反复跑)
node H:\DSH_Workspace\tools\dsh-whale-rod-cursor\install-to-profile.mjs

它会做三件事:
1. 复制插件到 ~/.dsh/plugins/dsh-whale-rod-cursor
2. 复制插件到 ~/.dsh/profiles/web/node_modules/dsh-whale-rod-cursor
3. 备份并在 ~/.dsh/profiles/web/cordis.patch.yml 末尾追加 insert 条目

⚠️ 必须重启 dsh web(客户端 bundle 是启动时进内存缓存的,硬刷新不够)。
重启后硬刷新页面,控制台输入: js __WHALE_ROD_CURSOR_VER__ // 应输出 '2026-09-15-v7-theater'

看到这个版本戳 = 新代码真的生效了。看不到 = 还在跑老 bundle。

安装前的"信任信号"(插件市场收录要求)

| 项 | 说明 |
| 支持 profile | web(dsh.client.platform: 'web')。终端 TUI 不受影响,装不装都不影响命令行 |
| 需要的 DSH 版本 | 客户端插件规范:@deepseek-ai/cordis ^4.0.1、@deepseek-ai/dsh-client-runtime ^0.1.0-rc.6(peer) |
| 权限 | 无网络、无文件访问、无外部服务。只做三件事:往 插一段 CSS、在 shell.overlay 画 SVG 装饰层、读 localStorage 存自己的设置 |
| 唯一"有副作用"的行为 | 默认模式会隐藏系统光标(html * { cursor: none }),并给出四条恢复路径:Alt+Esc、窗口失焦、鼠标离开窗口、卸载/渲染出错 |
| 读取的 DSH 内部状态 | 只读 ctx.get('sessions') 的列表快照里当前会话的 running 布尔值(判断"在忙/干完")。读不到就自动退化,不影响功能 |
| 遥测 | 无。不发送任何数据 |
| 卸载 | dsh plugin --profile web remove dsh-whale-rod-cursor + 重启 dsh web |

预览

示意图

上图是程序绘制的示意图(node tools/make-preview.cjs 生成),不是真机截图 ——真机截图见 assets/preview/screenshot.png(欢迎 PR 补充,Win+Shift+S 即可)。

⚠️ 一个坑(重要):本插件是手工放进 node_modules 的,没有写进 profile 的 package.json dependencies(桌宠 dsh-whale-girl-pet 才是靠 npm 装的)。
所以如果你哪天在 profile 目录里跑 pnpm install / pnpm prune,
pnpm 可能把"不在依赖表里的目录"当垃圾清掉 —— 鱼竿会突然消失。
届时重跑一次 install-to-profile.mjs 即可复原。

八、设置(DSH 设置 → 🎣 鱼竿光标)

| 项 | 默认 | 说明 |
| 启用 | 开 | 想清静时一键关掉(关掉会立刻还回系统光标) |
| 光标模式 | 鱼竿当光标 | 见第四节;也可 Alt+Esc 切 |
| 整体尺寸 | 0.72 | 鱼竿 + 挂件一起缩放 |
| 姿态包 | 开 | 关掉就永远只用 idle |
| 姿态来源 | 跟着 DSH 状态 | 或「跟着甩动」;服务读不到会自动退化 |
| "干完了"停留 | 2.5 s | done 姿态显示多久(0.8–8s) |
| 小剧场 | 开 | 鼠标停下自己开演(吊鲸鱼/钓鱼佬/空军) |
| 停下多久开演 | 6.0 s | 2–60s |
| 台词间隔 | 7.0 s | 2.5–60s,不连着重复 |
| 绳长 | 62 px | 绳的自然长度 |
| 软跟随刚度 | 70 | 静止时只剩它 → 越大气氛越"紧" |
| 瞬间拉力 | 320 | 甩动时额外刚度 → 初始拽力极大 |
| 阻尼 | 2.6 | 小 = 甩得飞、甩完还荡;大 = 乖乖滑回来(8 基本不荡) |
| 指数衰减 | 1.2 | 绝对阻尼 λ |
| 重力 | 1.00 | 沉降量 ≈ g/k |
| 甩动灵敏度 | 45k | 鼠标瞬时加速度阈值(px/s²)—— 抓"猛一顿 / 猛一停" |
| 甩飞灵敏度 | 1400 px/s | 她与鼠标的相对速度阈值 —— 抓"被拽飞 / 惯性滑行"(v8 新增) |
| 气泡冷却上限 | 4.5 s | 实际冷却 = 上限 ÷ 甩动强度(下限 0.7s) |
| 气泡语录 | 10 条 | 一行一条,改完立即生效 |
| 尖叫语录 | 13 条 | 力度超阈值 3 倍时专用(纯尖叫 / 求饶 / 哭唧唧三味),字号能长到和鲸鱼娘一样大 |
| 平静台词停留 | 2.6 s | 求饶/卖萌/生气台词的显示时长(2–3 秒) |
| 平静台词 | 10 条 | 被甩完安静下来时补一句 |
| 小剧场台词 | 20 条 | 吊鲸鱼 / 钓鱼佬 / 空军;鼠标停下时轮播 |

九、开发 powershell
cd H:\DSH_Workspace\tools\dsh-whale-rod-cursor

build 会逐张现量素材挂点(jimp 扫 alpha)→ 注入 __WHALE_POSES__ → 存档 lib/whale-anchor.json
node build.cjs # lib/client.src.js --(注入三张素材 + 各自挂点)--> lib/client.js(并留 lib/client.js.prev 回滚点)
node --check lib\client.js
node smoke-test.cjs # 106 项冒烟测试

改逻辑请改 lib/client.src.js,不要直接改 lib/client.js(每次 build 都会覆盖它)。

smoke-test.cjs 用最小的假 DOM + 假 React 把 bundle 真跑一遍,并手动泵 rAF 帧验证行为:

1. 模块加载协议 / 插件三件套
2. 挂点链条:三张素材各自的 sha256 → whale-anchor.json → 产物里注入的 __WHALE_POSES__ 三者必须一致
3. 两个插槽注册(外壳 overlay + 设置页)
4. 几何:竿尖在 (0,0)、握把朝右下、每张姿态的绳末端都落在她头顶那一像素上(自写 SVG 变换求值器,精确到 0.001px)
5. 姿态包:三张图都挂着且只有一张可见;喂一个假的 DSH sessions 服务({current, byId:{s1:{running}}})验证 在跑→work、跑完→done、2.5s 后→idle;再点设置页的「跟着甩动」按钮验证另一条驱动路径
6. 物理:倾角夹在 ±58°、静止回落、吊线无 NaN
7. 气泡:缓甩小字萌语 → 暴甩尖叫(字号顶到鲸鱼身高)→ 平静后补求饶/卖萌/生气
8. 手感曲线:猛拽峰值 → 甩飞最远距离 → 收敛到静息悬挂 → 极端甩动不失控
9. 保命:Alt+Esc 还光标、卸载后光标仍可见

它抓到的真 bug:factory 忘了 return module.exports(插件会被静默判定为“没有导出”)、页面刚打开头几秒气泡被冷却时间误伤、v3 首版阻尼太大导致“甩不飞”(用户体感反馈)、鲸鱼娘变换里缩放挂错锚点导致头顶被抬高 25px,以及画布顶端到头顶的透明留白让绳末端悬在半空(只能靠量像素发现,肉眼看代码永远看不出来)。
姿态包这轮它自己也踩了一次:work/done 挂点相同,测试一开始只按挂点认人 → 把两张认成同一张,改成“尺寸 + 挂点”一起认才对。

十、已知边界 / 未来可做

- 姿态只有 idle / work / done 三张。上游还有上百个 WebM 动作,想要“生气/开心/惊慌”这类情绪姿态得另找素材 + 走一遍声明流程
- 目前是静态 PNG。想做动画(透明 WebM)得再走一遍素材声明流程,并且要考虑解码开销
- 三张姿态都内嵌在 client.js 里(317.9 KB)。想瘦身就改成宿主路由懒加载
- 只作用于 Web 界面(platform: 'web'),不影响终端 TUI
- 藏系统光标是“整站生效”的:DSH 界面里若有个别控件自带特殊光标,也会被一起藏掉(鱼竿会替它变色)

十一、出处与授权

见 NOTICE.md。简短版:

- Q 版鲸鱼娘形象来自 yanzwzz/dsh-whale-girl-pet(MIT),由星河野望从预览 GIF 首帧抠图 + 缩放加工
- Q 弹振荡 / 阻尼 / 重力的取值基准参考社区插件 dsh-think-bounce-pet(作者 9livewolf,声明 MIT),只借公式与常数,未复制其任何代码或界面

本插件以 MIT 发布。这是社区作品,与 DeepSeek 官方无隶属关系(名字里带 dsh- 只是遵循社区命名习惯)。
预览分享卡片长什么样 ↓xingheyewang-1/dsh-whale-rod-cursor
分享 · DeepSeek Harness Hub
xingheyewang-1/dsh-whale-rod-cursor

把系统光标换成甩着鲸鱼娘的弹性鱼竿

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部