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 Config schema 校验:非法值(如概率 > 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