dsh-night-greeting
这是一个在晚上随机向你问好的插件。
在深夜时分,它可能会突然出现,轻轻地向你道一声「晚上好」。
环境要求
| 项目 | 要求 |
|---|---|
| 运行时 | DeepSeek Harness (DSH) 0.1.x(0.1.0-rc.6 及以上均可) |
| Node.js | ≥ 20(实测 22.x 可用) |
| 平台 | Windows / macOS / Linux |
| 前置插件 | 无 |
插件运行在 DSH 宿主进程内,
cordis、@deepseek-ai/dsh-tools等依赖
由 DSH 宿主提供(plugin 以peerDependencies声明)。其中
@deepseek-ai/dsh-tools同时声明为普通 dependency:这样即使宿主以
link:/本地目录方式装配插件,插件也能在自身node_modules内解析到它,
不会因解析失败导致宿主启动崩溃。
安装
方式 A:git 装配(推荐)
dsh plugin --profile web add github:HokkaidoCOLA/dsh-night-greeting
本包在
package.json中声明了dsh.bundle,因此dsh plugin add安装后
自动并入 profile 的 bundle 层并激活——设置页插件清单、工具与问候功能
全部就绪,无需手动编辑任何cordis.patch.yml(重启 web 后生效)。
--profile web指装配到 web 配置;headless / tui 等其他 profile 同理替换。
方式 B:Release 包(免构建)
从 Releases 下载
dsh-external-dsh-night-greeting-<版本>.tgz,解压后:
dsh plugin --profile web add <解压目录>
方式 C:本地源码(开发调试)
# 先在仓库根目录安装依赖并构建(依赖锁定在 package-lock.json,推荐 npm ci)
npm ci
npm run build
# 再装入目标 profile(bundle 声明同样会自动激活)
dsh plugin --profile web add ./dsh-night-greeting
⚠️
node_modules不在仓库内(见.gitignore)。若把它删除或重新克隆后
未安装依赖就装配插件,DSH 将解析不到@deepseek-ai/dsh-tools而启动失败。
重新克隆后请先执行npm ci(或npm install)再装配。
使用
安装后无需任何操作——它会在晚上(北京时间 00:00–04:00)每小时以 1/100 的概率
随机向你问好。你也可以对 AI 说"帮我触发晚上好问候"
(night_greeting_trigger 工具)。
提供的工具
| 工具名 | 用途 |
|---|---|
night_greeting_trigger |
立即向你问好(演示/强制触发) |
night_greeting_status |
查询插件状态与配置 |
配置项(可选)
安装即用,无需配置。如需调整,在 ~/.dsh/profiles/web/cordis.patch.yml
按 id 覆盖该行配置(name 必须使用真实包名
@dsh-external/dsh-night-greeting):
- id: dsh-night-greeting
config:
probability: 0.01 # 每小时问候概率(0..1)
startHour: 0 # 问候时段起点(北京时间,含)
endHour: 4 # 问候时段终点(北京时间,不含)
text: 晚上好 # 问候文本
color: '#ff2020' # 问候颜色
autoDismissMs: 0 # 自动关闭毫秒;0 = 等待手动关闭
pollIntervalMs: 10000 # 浏览器端轮询间隔(问候时段内)
idlePollIntervalMs: 60000 # 浏览器端轮询间隔(问候时段外)
checkIntervalMs: 60000 # host 端掷骰检查间隔
expireOutsideWindow: true # 自动命中的问候离开时段后作废(只在深夜炸)
pendingMaxAgeMs: 0 # 待显示问候的最长挂起时长;0 = 不按时长作废
配置经 schemastery
Configschema 校验:非法值(如概率 > 1、时段越界)
会在加载时报错而不是静默带病运行;未填写的项自动使用默认值。
轮询节奏
问候只可能出现在 [startHour, endHour) 这段时间里,其余时段的轮询注定为空,
因此浏览器端的节奏由 host 在 /state 响应里用 nextPollMs 指定,分三档:
| 情形 | 间隔 | 说明 |
|---|---|---|
| 正在显示问候 | 5s | 让多个标签页之间的关闭动作及时同步 |
| 在问候时段内 | pollIntervalMs(10s) |
命中后尽快显示 |
| 在问候时段外 | idlePollIntervalMs(60s) |
不可能命中,只需能感知手动触发 |
此外浏览器端标签页不可见时完全挂起轮询(不留定时器、不发请求),回到前台
时立即补一次。默认时段下,一天的请求量从约 8640 次降到约 2640 次,后台标签页
则降到 0。
这条不只是省流量,更是为了让惊吓真正生效:浏览器会拒绝后台标签页的
requestFullscreen(),并把 AudioContext 保持在 suspended。若在后台就把
overlay 搭好,黑屏 → 文字墙的时序会在没人看的时候演完、也没有声音,等用户切回
来只剩一具静止的残骸。改成「切回前台再当场炸」后,全屏、音墙、完整时序都在用户
眼皮底下发生。
过期:只在深夜炸
因为后台不轮询,命中的那一发会一直存在 host 上。若不清理,凌晨 2 点掷中、标签页
挂了一整夜,用户上午 9 点切回来会被补炸一发——深夜氛围荡然无存。
因此自动命中的问候一旦离开问候时段就作废(expireOutsideWindow: true,
宁可白丢一发);也可用 pendingMaxAgeMs 再加一道「最长挂起时长」。
手动触发不受此限。
night_greeting_trigger工具与POST /trigger会把这
一发标记为forced,白天演示照样弹得出来——否则过期逻辑会把演示当场清掉、
让工具看起来像坏了。night_greeting_status会报出forced字段便于分辨。
把 expireOutsideWindow 设为 false 即可回到旧的「惊吓存盘」行为。
开发
本仓库按 DSH 官方插件规范编写:
- Cordis 插件形态:
name/inject/apply函数导出; - 配置声明:schemastery
Config(loader 校验 + 填默认值); - 工具注册:
@deepseek-ai/dsh-tools的defineTool(参数类型化 + 执行前校验); - 生命周期:所有注册挂在
ctx.effect上,热重载/卸载自动清理; - 双面打包:
dsh.client+./client导出(浏览器端零依赖轮询渲染); - 自动激活:
dsh.bundle.patch声明(安装即并入 profile 层)。
npm install # 安装构建依赖(host 类型 + client 打包器)
npm run build # tsc 编译 host → lib/,tsdown 打包 client → lib/client.js
npm run typecheck
说明:官方
adding-a-package规范中@deepseek-ai/cordis同时出现在
peerDependencies 与 devDependencies(本仓库已遵循)。
常见问题
- 装完没生效? 确认已重启 web;检查设置页插件清单中该插件为已启用状态。
- 报 peerDependency 错误? 确认 DSH 版本满足 环境要求。
- 想改默认行为? 按 配置项 在 profile 层覆盖。
License
MIT