← 返回列表
未验证
跨会话、跨重启、跨睡眠的定时任务 —— DSH host 插件。
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/31 · 已提供中文文档
DeepSeek Harness 的计划任务能够在会话结束、主机重启和机器休眠后继续存在——它调度的是一个结果(完成窗口 + 效果检查 + 追赶),而不是某个时刻。
综合分
28.9
GitHub 分
28.9
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add TT-Wang/dsh-cron该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/18(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-cron
跨会话、跨重启、跨睡眠的定时任务 —— DSH host 插件。
为什么需要它
DSH 自带的 schedule 有意只做会话内提醒。它的交付模式在类型里就写死了:
/** Fixed v1 delivery boundary: the original session must be live. /
type ScheduleDeliveryMode = 'session-local'
配套说明是「原会话必须 live,不存在外部通知通道与冷会话调度器」,包 README 更直白:「本包有意不公开 Schedule service 或可变数据库」。
这不是缺陷,是范围裁定:DSH 里干活的单位是「带 live agent 的会话」,不允许任何东西在会话之外持有状态去驱动工作。而 cron 恰恰要求一个比所有会话都活得久的东西。
本插件就是那个东西:住在 host 进程里,跨会话存活,到点从外面把会话叫起来。
它和 crontab / launchd 的区别只有一条
按结果调度,不按时刻调度。
触发器从来不缺。真实断链的记录是这样的:
| 日期 | 断在哪 | 共同点 |
|---|---|---|
| 8/22–23 | 脚本里 BASE_DIR 拼错一个字母 | 静默 |
| 8/24–25 | 授权过期,会话照开、活没干成 | 静默 |
| 8/26 | 到点没跑,系统日志里查不出原因 | 静默 |
三次三个环节,没有一次断在"开枪"那一步。再加一个更准的触发器,第四次会以第四种方式静默地断。
所以这里的调度单位是完成窗口:
落点(cron 时刻) ──────────── 完成窗口 ──────────→ 窗口关闭
│ │
├─ 问 check:该发生的事发生了吗? │
│ 是 → done(收工) │
│ 否 → 开一枪,过 retryEvery 再问一次 ───────────┤
│ ↓
└──────────────────────────────────────────→ 仍未完成 = MISS(大声记账)
保证是「当天必然送达」,不是「09:00 准点」。后者在一台会睡眠、host 会重启、授权会过期的机器上本来就做不到 —— 承诺它等于承诺一个会静默违约的东西。
白捡的两个性质:host 停机期间错过的窗口,恢复后第一次 tick 就补上(cron 睡眠错过则永不补跑);别人手动把事做了,check 一问即知,我们一枪都不开。
用
cron_add 安排一个任务(带 check 才算真安排)
cron_list 看现有任务与当前窗口状态
cron_status 读只追加的运行台账 —— "今天到底跑没跑" 的答案,是证据不是总结
cron_remove 删除 / 暂停 / 恢复
cron_run_now 立刻走一轮评估(测新任务,不用等窗口)
例子(每天 09:00 出日报,6 小时内必须送达):
{
"id": "daily-digest",
"cron": "0 9 * *",
"tz": "Asia/Shanghai",
"window": "6h",
"retryEvery": "30m",
"check": { "kind": "command",
"run": ["/bin/sh", "-c", "grep -q \"$(date +%F)\" ~/reports/sent.log"] },
"fire": { "kind": "session", "preset": "digest-bot",
"prompt": "生成今天的 digest 并发送", "cwd": "/home/you/reports" }
}
fire 两种:session 开真会话(带无人值守纪律头:没人可问、失败就换招再来、做完为止),command 直接跑(确定性活儿不必过模型)。
check 两种:command(退出码 0 = 已完成)、http(2xx,可选 contains)。
没有 check 会怎样
降级成普通 cron:每个窗口盲发一枪,成没成没人知道。cron_add 的回执、cron_list 的每一行、台账里的每一条都会标出这个状态。真实断链从来不在开枪那一步,所以这个降级模式的存在只是为了"实在没有可观测的完成判据"的场景,不是默认选项。
装
npm install && npm run link:dsh && npm run build
profile 的 package.json 里加一条依赖,cordis.patch.yml 的 insert 里加一项:
- insert:
- id: dsh-cron
name: '@dsh-external/dsh-cron'
配置项(都可省):root(数据目录,缺省 $DSH_HOME/cron)、tickMs(评估间隔,缺省 60s)、wirePort(开会话用的 host 端口,缺省从 host 的 webServer 读)。
数据落在 $DSH_HOME/cron/:tasks.json(任务与窗口状态,原子写)与 runs.jsonl(只追加的台账,永不改写 —— 一个会被覆盖的状态文件回答不了"今天到底发生了什么")。
边界(诚实说)
- 本插件活在 host 进程里。host 不在,它也不在 —— "谁来唤醒唤醒者"的问题只是上移了一层。要它开机自启,还得靠 launchd 把 host 拉起来。
- 完成判据的质量等于这个包的质量:check 写得松(比如只 test -f 一个每天都在的文件),它就会高高兴兴地报告一切正常。
- 台账只追加,不自动轮转;跑久了自己清。
- 单机、单 host。没有跨机协调,也没有分布式锁。同作者(TT-Wang)的其他插件
扫码进群