npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-niulai-pet

v0.4.13

Published

dsh web desktop pet: a Niulai calf that lives in the corner, hops around, and moos "mama" when an agent task completes (client-only plugin)

Readme

dsh-niulai-pet

中文 | English

npm license: MIT Awesome DSH Plugin

牛来桌宠 —— 在 dsh web 界面角落里养一头《牛来》的小牛。平时呼吸、眨眼、踱步、 打盹、气泡唠叨;agent 任务一完成,它就蹦出来喊一声「妈~~妈~~」。

桌宠本体在浏览器端(client 半);host 半(index.js)只负责注册 settings 命名空间——dsh rc.7+ 的设置页「插件配置」区因此有一张牛来桌宠设置卡片, 配置由 dsh host 持久化(~/.dsh/settings.yaml)。rc.6 及更早没有该能力, 插件照常工作,配置留在 localStorage,只是没有设置卡片。 更新后刷新页面即生效,免重启

在线试玩(免安装) —— 同一套代码的 standalone 页面,模拟任务驱动庆祝;想真养在 dsh 里再往下看安装。

九个皮肤

层次合影

演示

皮肤

| 皮肤 | 素材 | 叫声 | 签名动作 | |---|---|---|---| | 牛来 | 抠图 + PIL 精修 | 原声(已降噪) | 连跳 | | 牛来原皮 | AI 生图三视图抠图(无角幼年造型) | 同上 | 连跳 | | 小黄 | 牛来幼年皮(去角+黄亮) | 同上 | 翻滚 | | 熊猫 | 手绘 | 合成吱声 | 翻滚 | | 蓝鲸 | 手绘(DeepSeek 蓝 + 虎鲸眼斑) | 合成鲸鸣 | 跃出水面(弧顶喷水) | | 奶龙 | 三视图抠图(AI 生图)+ 视频切片抠帧 | 原片大笑声(已降噪) | 摇摆(喊叫有捧腹大笑到打滚的帧演出) | | 小奶龙 | 奶龙宝宝造型(AI 生图动作条切帧) | 「我才是奶龙」原声切片 | 摇摆(喊叫有逐帧演出) | | 大狗 | Dagou-Tap-New 立绘(自带 alpha) | 「大狗大狗叫叫叫」链式合成 | 连跳 | | 赛博猫 | AI 生图抠图(一站一趴) | 真猫叫 | 摇摆(趴睡常态:平时趴着,喊叫才站起,声止再站 2.5s) |

行为

| 交互 | 反应 | |---|---| | 待着不动 | 呼吸浮动;随机眨眼 / 小跳 / 踱步 / 扭身子;偶尔气泡吐槽(趴下打盹需在设置面板开启,默认关) | | AI 会话在跑 | 气泡报时「AI 已经跑了 X分X秒…」 | | 点击(戳) | 喊一声 + 绑定动作;循环喊在跑时戳 = 应声停它,不再复读「妈妈」 | | 拖拽 | 拎着走(垂直 1:1 跟随),松手重力坠落 + 水平抛掷惯性,落地压扁回弹;位置记忆(localStorage) | | 变色 | 菜单/设置面板「色相」滑杆 0-360° 任意调色(hue-rotate,按只存;单色角色效果最佳) | | 流光变色 | 设置面板按只开启:色相绕圈缓慢流转(~22s 一圈,纯显示不落盘),史莱姆系绝配 | | 连戳红温 | 连戳会积火:皮肤逐渐变红(红色剪影跟随体型),满格爆发扭头哼唧不理人,随后缓慢退火;前 3 戳不红,可在设置面板整体关闭 | | 多只 | 主宠菜单「再添一只」(上限可配,默认连主 10 只);皮肤/大小/色相/语录按只存,设置面板选「配置对象」按只调 | | 物理碰撞 | 设置面板开启后:走近互挤、撞狠弹飞、拎着越过头顶不推人、砸中别只按落差弹开,落地/重撞有闷响 | | 右键 | 菜单:静音+音量(滑杆)/ 气泡开关 + 大小 / 透明度 / 色相(滑杆)+ 皮肤(下拉,选即换)+ 飞一圈 / 表演一下(喊 + 签名动作)/ 全家福 / 再添一只 / 设置(定位打开设置面板并高亮本宠)/ 关于;低频配置(完成喊几声/打盹/碰撞/动作绑定等)全归设置面板 | | 全家福 | 主宠菜单「👪 全家福」:均匀列队(牛来 C 位、奶龙/小奶龙对称)→ 层次合影(高个靠后矮个往前、叠压出纵深)→ 收起,循环切换;期间主宠钉住置顶,收起原位恢复 | | 任务完成 | 提示音(可连播/可循环到互动停止,可导入自定义提示音替代角色叫声)+ 气泡 + 嘴型开-合-开保持到尾音结束 + 绑定动作(6s 节流,可配延迟——延迟期间你戳它/拎它/发了新任务,就当你已处理过,不再提示)。多只/全家福列队时全员广播 |

动作库:飞行(向上抛物线)/ 摇摆舞 / 转圈 / 连跳 / 翻滚 / 跃出水面 / 摇摆, 任意皮肤可绑任意动作,「签名动作」= 跟随当前皮肤,「随机」= 现场抽。 动作绑定按皮肤记:切换皮肤不清空另一皮肤的绑定,没配过的皮肤用默认 (完成=签名动作,戳一下=连跳)。

任务完成信号来自 client runtime 的 sessions.list 快照订阅: running true→false(当前会话跑完)或 completed 新置位(后台会话完成)。 宿主太旧没有 sessions 服务时降级为仅手动交互。

设置卡片(dsh rc.7+)

rc.7 起,设置 → 插件 → 插件配置里有「牛来桌宠」卡片,分通用 / 当前桌宠 / 自定义 / 高级四个 tab: 声音 / 完成时喊 / 完成连喊(1-3)/ 完成延迟(0-120 秒)/ 循环喊到互动停止 / 妈妈回应「牛来」/ 语音停喊(喊「牛来」停循环,见下文)/ 气泡 / 隐藏全部 / 物理碰撞 / 桌宠数量上限(默认 10,高级 tab 可放开到只保底 1 不设顶)/ 流光变色与红温开关 / 唠叨语录(一行一条,多只时按「配置对象」分只编辑)/ 皮肤下拉 / 桌宠大小滑杆(72-200px,按皮肤带默认值,偏离默认时出现「重置」按钮)/ 离地高度(高级 tab,允许负数沉入地面)/ 禁止走动开关(按只)/ 自定义提示音导入(≤1MB)与自定义角色包导入(自定义 tab)/ 完成时动作与戳我动作下拉(编辑当前皮肤的绑定)。 多只时卡片顶部出现「配置对象」选择器(带皮肤预览图,点预览图对应桌宠会发光 +小跳回应):皮肤/大小/语录按只调。循环喊的停止条件:戳它、拎它、新任务 开跑、静音或关掉开关,60 声兜底自停;互动打断时妈妈会回一句「牛来!」卡片与桌宠右键菜单读写同一份配置, 改一边另一边即时反映; 持久化归 dsh host(~/.dsh/settings.yaml,跨浏览器共享)。旧版 localStorage 配置首次加载自动迁入(不覆盖设置页已改过的值);位置 x 按设备留 localStorage,不进设置。

自定义角色包

想养自己的崽:一个 zip(pack.json + 透明底图 + mp3)就是一个角色, 设置卡片「自定义角色」区导入(IndexedDB 持久化,可删除回落), 或在试玩页直接拖入 .nlpack.zip 即时预览(不落库)。 没做过包?下个最小示例包 先试导入流程;从零做包看 SKIN_AUTHORING.md(含 AI 生图提示词、 逐帧动作条切分、派生覆盖包玩法),格式规范在 docs/skin-pack-schema.md (皮肤级可选字段:size 默认大小、opacity 默认不透明度、walkable 禁止走动、 images.sleep 打盹专睡图、halo 完成金色光环、imageRoll 卷球滚动、 imageDrive 开车图、lampIdle 警灯分场景、splitCount 分裂克隆、 hueCycle 流光变色、doneVoice 完成专属声等;包级 minEngine 最低引擎版本提示)。 同 id 重复导入会提示版本差异,确认后覆盖更新。

语音停喊(双引擎)

引擎演进、架构图与全部实测数据(内存/判别力/交叉验证/降噪,含图表) 见 docs/voice-stop-engine.md

循环喊进行期间,对着麦克风喊一声**「牛来」**,循环立即停止。停下不再播妈妈的 录音回应(你都亲自喊了,不能再让妈妈抢台词;互动打断循环时才回那句)。 识别引擎二选一(设置卡片切换):

  • 模型识别(默认,推荐):sherpa-onnx 中文 KWS 模型(zipformer wenetspeech-3.3M,int8)的 wasm 移植,真语音识别,嗓音差异/背景音/语速 变化都稳。指令词可选:牛来(默认)/ 别喊了 / 安静 / 停下,多选, 喊任一即停(卡片里勾选;各词的音素变体经离线语料交叉验证:零串词、 妈妈喊声零误报)。识别跑在 Web Worker 里(不占主线程;wasm 初始内存 仅 32MB——实测真实工作集不到 32MB——可增长兜底),只听该听的时段:循环一停 worker 空闲 10 秒 即整个终止,内存真正归还浏览器,下次开听再秒级重建。 资产约 17MB 随 npm 包分发,由插件 host 半注册的 /niulai-kws/<file> 路由同源伺服,首次启用加载一次(局域网秒级), 浏览器按 ?v=<插件版本> 缓存后秒开;加载失败(老 dsh 无 webServer、 worker 被拦等)自动回落模板匹配。音频不出浏览器。

  • 模板匹配(零下载):浏览器内 MFCC + 子序列 DTW,模板默认是同一句 「牛来!」的两条电影录音(assets/reply_match.mp3 长切版 + reply_ref.mp3 参考版,取最小分)。别人的嗓音对不上电影 模板是模板匹配的固有上限——卡片里可「录我的『牛来』」:对着麦喊一遍, 自录模板排第一优先匹配(本人嗓音自录几乎必中),测试器和正式监听都走它。

  • 只在该听的时候听:仅在「语音停喊」开关开 + 循环喊进行中才开麦; 循环一停(认出、戳它、静音、新任务)立即关麦停流,不常驻。

  • 环境限制getUserMedia 只在安全上下文可用(https 或 localhost)。 局域网 http://192.168.x.x 访问时麦克风 API 直接不存在,卡片里的开关 会禁用并注明原因。

  • 授权流程:打开开关时会真实试取一次麦克风(浏览器弹原生授权框), 授权成功才生效;被拒则开关弹回关位并提示。卡片上有状态行显示 「未授权 / 已授权 / 不可用」。

  • 音量小识别不到:卡片里把「麦克风增益」调大(浏览器自动增益已开, 这里再叠加 1.0–4.0× 软件增益,软削波防爆音,正式监听热生效不用等重启)。

  • 模板引擎的判别力离线标定见 test/voice-matcher.mts:正样本(本体+变调/变速/窄带) 最高 ≈0.43 < 阈值 0.54 < 负样本(「妈妈」喊声/静音/白噪/他人语音)最低 ≈0.66, 且需连续 3 次过阈才判命中(防抖)。注意宁紧勿松——宠物自己喊的「妈妈」 被误认成「牛来」会让循环自己停掉。真人嗓音的召回率受麦克风与距离影响, 需真机微调。模型引擎的标定结论(28 条语料 21 过、负样本零误报、 「你又来」类近音会误触发)与 wasm 构建/冒烟流程见 wasm-build 的 BUILD-NOTES.md。

demo 试玩页:右上角角标区——🛫 一起飞(彩带式持续起飞,只显示飞行中的)、 👪 全家福(均匀列队/层次合影循环)、📦 自定义包试玩、🎤 语音停喊(落 localStorage)、 👁 隐藏/喊回、🔊 静音;语音停喊搭配 循环喊使用,可在控制台预设 localStorage['dsh-niulai-pet:state-v1']='{"shoutLoop":true}' 后刷新体验。

安装

# 从 npm 装(推荐)
dsh plugin --profile web add dsh-niulai-pet

# 或从 GitHub 装
dsh plugin --profile web add github:whitefirer/dsh-niulai-pet

lib/ 构建产物已入库,安装零脚本;首次安装重启一次 dsh web,之后升级刷新页面即可。

素材说明

素材全部入库,开箱即装即玩。 熊猫/蓝鲸为手绘原创 (SVG 源文件在 tools/drawn/,含已移除奶牛的存档),可自由取用。 大狗立绘来自 Dagou-Tap-New

想换形象/声音:覆盖 assets/ 里的文件后 npm run build,刷新页面即生效。 重建全部素材的管线脚本在 tools/(见 AGENTS.md)。

开发

npm install
npm run build      # 产物 lib/client.js(CJS 闭包 + __ModuleLoader__ 包装)
npm run typecheck

装进 profile 调试:

cd ~/.dsh/profiles/web && pnpm add file:/path/to/dsh-niulai-pet
# 首次安装重启一次 dsh web(市场 shim 在宿主启动时挂载);之后改代码只需
# npm run build + 刷新页面

页面 URL 加 ?petdebug=1 会在 window.__niulai 暴露桌宠句柄 (celebrate/poke/setBusy/destroy),playwright 验证脚本靠它驱动。

实现要点(给后来的维护者)

  • ctx.effect 的回调是立即执行的,清理函数要再包一层返回 (ctx.effect(() => () => cleanup()))——写错会在 apply 时直接把桌宠销毁。
  • dsh 首屏 React 挂载会置换 document.body 的直挂节点:插件用 MutationObserver 守灵,被清就自动重挂。
  • 朝向翻转放在根节点 scaleX,气泡/菜单用 scaleX(var(--face)) 抵消, 否则文字会镜像。
  • 更完整的状态机、素材管线与坑清单见 AGENTS.md