DeepSeek Harness Hub
← 返回列表

定时唤醒闹钟catsenior507/dsh-clock

DeepSeek 客户端兼容 / 相关生态spec-screened在 GitHub 查看 ↗
未验证

按时间与关键词唤醒已关闭的对话并标注迟到偏差

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/16 · 已提供中文文档

DeepSeek Harness 的日历与时钟:闹钟按关键词在选定时刻唤醒选定的对话,并将系统时间和漂移注入唤醒。进程内定时器加上 Windows 任务计划程序镜像。

综合分
29.9
GitHub 分
29.9
用户评分
★ Stars
0
周下载量
兼容 / 相关生态插件(非 dsh 原生,请按其对应运行时安装)
git clone https://github.com/catsenior507/dsh-clock.git
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

⏰ dsh-clock

用户或 agent 指定一个时间点、一个关键词、以及要唤醒的对话;时间一到,关键词就被投递进那个对话——
哪怕对话是关着的。

每次唤醒都带着钟表信息:计划时刻、实际时刻、带符号的偏差,以及迟到时的明确警告。
迟到三小时的唤醒,读起来绝不该和准点的唤醒一样。

架构

为什么要做这个

harness 本身已经能排提醒,但只在提出提醒的那个对话内部投递。
@deepseek-ai/dsh-schedule 的文档写得很直白:
投递是 session 本地的,没有冷会话调度器,关掉的会话会一直把提醒挂着 "已过期",直到有人把它恢复。
所以你没法对一个长任务说"九点回来继续"然后关掉页面。

本插件填的正是这个缺口:闹钟自己写明要唤醒哪个对话,那个对话可以是关着的,唤醒它就会把它恢复起来。

唤醒消息长什么样

⏰ dsh-clock wake — keyword: 继续迁移

scheduled  2026-09-11T09:30:00+08:00  [Asia/Shanghai]
now        2026-09-11T11:43:12+08:00  [Asia/Shanghai]
drift      +2h13m  OVERDUE
now-epoch  1789098192000
trigger    catch-up replay at host start

warning    OVERDUE by +2h13m: the host was not running at the scheduled instant and this is a catch-up
delivery. Re-check anything time-sensitive before continuing.
note       This message was delivered by a timer, not typed by the user. Treat "继续迁移" as the signal
to resume whatever was planned for this instant.
detail     检查构建是否结束

drift 和 warning 两行是关键。没有它们,被唤醒的 agent 分不清"现在是计划中的九点半"和
"现在是十一点四十三,你迟到了三小时",然后会心安理得地按过期前提干活。

安装

npm install
npm run build
dsh plugin --profile web add link:
或者直接从 git 装:
dsh plugin --profile web add

装好后需要重启 dsh web 才会加载(守望者面板的
「重启」按钮最快)。侧边栏底部、设置按钮的上方会出现一个 日历 按钮,点开就是面板。

用法

面板

- 时钟:当前时间、时区,以及到下一次唤醒的实时倒计时;
- 日历:有闹钟的日子带圆点;点一天、填时间与关键词、选对话,按钮上会写清楚它到底要建什么;
- 分支会被发现:分支一个对话复制的是对话,不是闹钟表 —— 分支之前设的闹钟会继续指向原来那条,
于是分支永远不会被唤醒。面板会为每个「尚未覆盖」的分支问一次:把闹钟复制到这个分支,或者拒绝;
两种回答都会被记住,不会再问。
- 闹钟列表:分成「待触发」和「已结束」两栏,各自是一个独立的滚动窗口,所以历史再长也不会把面板撑长;
待触发按时间正序、已结束按时间倒序。每行可以编辑、立即触发、取消、删除;点「编辑」会把这条闹钟装回表单
(时间、关键词、内容、目标对话都能改),按钮变成「保存修改」。只有待触发的能编辑 —— 改一条已经触发过的,
等于承诺一次不会发生的投递。已触发的行会写明是准点还是迟到,投递失败的原因也留在行上,不会被吞掉。

交给 agent

模型会拿到一个 clock 工具:

{ "action": "set", "afterSeconds": 2700, "keyword": "检查构建",
"note": "这时候 release 任务应该跑完了" }

// 唤醒另一个对话:
{ "action": "set", "at": "2026-09-11T09:30:00+08:00", "keyword": "站会",
"sessionId": "session-…", "timeZone": "Asia/Shanghai" }

{ "action": "now" }      // 现在几点
{ "action": "list" }     // 待触发与近期的闹钟
{ "action": "cancel", "id": "a-…" }

插件还带一个名为 clock 的 skill。工具只靠一行描述被广告出去;而从没见过这个插件的对话,
是靠这个 skill 才知道那一行装不下的东西:目标可以是一个已关闭的对话、被唤醒的对话是原地继续而不是
fork、以及迟到投递会在消息里写明迟了多久。它以 bundled 来源注册,所以在这个 profile 的每个对话
的技能目录里都能看到。

计时是怎么做的

三层触发,一条投递路径:

| 层 | 覆盖的情况 |
|---|---|
| 进程内定时器 | 常规情况。只为最早的那个待触发闹钟挂一个 setTimeout,任何变更都重新推导。没有轮询循环,空闲时零 CPU。 |
| Windows 计划任务 | 机器休眠、宿主被挂起、计划被错过——StartWhenAvailable 让 Windows 在机器真正可用的第一时间补跑。它也是唯一能被要求唤醒机器的一层(wakeComputer)。 |
| 宿主启动时补发 | 闹钟到点时宿主根本没在跑。这条才是真正把错过的闹钟送出去的那一层,也正是唤醒文本必须报告偏差的原因。 |

三层调用同一条 先认领、再投递 的路径,而且闹钟在任何投递开始之前就被翻成 fired。
谁先到谁赢,其余层发现无事可认领,所以三层叠在一起也不会把一个唤醒送三遍。
提示词还带着由闹钟 id 推导出的 request id,session controller 会去重,这是第二道保险。

系统计划任务是镜像,不是所有者:它只 ping 插件自己的端点。任务缺失、失败或过期,都只会退化成另外两层,
而不会丢掉这次唤醒。注册走 PowerShell 的 ScheduledTasks 模块(不是 schtasks.exe,后者表达不了
StartWhenAvailable),插件卸载时会被移除。

配置

- id: ui-clock
name: '@dsh-external/dsh-client-plugin-clock'
config:
port: 4801                  # profile 没有 web server 时的私有端口
dataDir: …                  # 默认 $DSH_HOME/clock
defaultTimeZone: Asia/Shanghai
useSystemScheduler: true    # 把最早的闹钟镜像进 Windows 计划任务
wakeComputer: false         # 允许那个任务把机器从睡眠中唤醒
wakeMode: queue             # queue | steer:唤醒如何进入一个正忙的对话
driftToleranceSeconds: 60   # 偏差小于这个值仍算 ON-TIME
retainFiredDays: 7          # 已结算的闹钟在面板里保留多久
exposeTool: true            # 把 clock 工具暴露给 agent

说清楚的边界

- 唤醒需要宿主在跑。 只有宿主能恢复会话,所以如果到点时 dsh web 没运行,这次闹钟会在它恢复运行的第一时间
补发(靠计划任务的补跑,或启动时的补发),并在消息里写明迟了多久。它不是推送通知:机器关着的时候
没有任何东西能送到你手上,也没有邮件和短信。
- 只支持一次性闹钟。 还没有"每个工作日九点"这类重复规则;日历是用来选日期的,不是用来表达重复的。
- 一个计划任务、固定的名字。 任务名是 dsh-clock-wake,所以同一台机器上跑两个宿主会互相抢它。
进程内定时器不受影响。
- 触发按钮是真正的 slot 注册(sidebar.footer.action),但它打开的面板是浮在 body 上的独立表面,
所以面板本身不跟随皮肤主题。

HTTP 接口

搭在 harness 的 web server 上(/api/clock);profile 没有 web server 时走私有本地端口。

| 端点 | 用途 |
|---|---|
| GET /api/clock/state | 时钟、日历数据、闹钟、目标对话、调度器状态 |
| GET /api/clock/now | 宿主时区的当前时刻 |
| POST /api/clock/alarms | 新建——{ at \| afterSeconds, keyword, sessionId, … } |
| POST /api/clock/alarms/update | 改时刻、关键词、备注或目标 |
| POST /api/clock/alarms/cancel · /forget | 取消一个待触发闹钟 · 删除一行 |
| POST /api/clock/alarms/fire | 不管到没到点,立刻触发 |
| POST /api/clock/tick | 计划任务的 ping:认领并投递所有到期的 |

所有响应都是 { ok: true, value } 或 { ok: false, error }。

开发

npm run build     # tsdown:宿主半边 -> lib/index.js,浏览器半边 -> lib/client.js
npm test          # 26 个单元测试,node --test + 类型剥离

测试挑的是"错了代价最大"的地方:让三层触发不会把一个唤醒送三遍的幂等性、唤醒文本报告的偏差、
闹钟重载后的持久性、启动时的过期补发、以及日历算术。
测试从不注册 Windows 任务——每个 service 都关掉了系统镜像。

另见

- dsh-context-assembler —— 会话表面上的上下文树,
每个节点可以选组装方式。
- dsh-web-watchdog —— dsh web GUI 的崩溃记录、
指数退避自动重启与状态面板。

许可

MIT — 见 LICENSE。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

同作者(catsenior507)的其他插件

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群