leinaldo/dsh-routines:給 DSH 補一套 Claude 風格的定時任務

前言

DSH 自帶 @deepseek-ai/dsh-schedule 這套「自動化任務」,但它是排期提醒:到點把一條消息投回任務綁定的會話,用那個會話的歷史繼續幹活。回執只表示「消息進了收件箱」,不表示模型執行完成,也沒有暫停和手動運行。

下面介紹的 dsh-routines(維護者 leinaldo,分類「工作流」)把語義換成任務運行器:到點新開一個對話跑一輪,跑完有狀態、耗時、步數和 token 回執,可以回看那輪會話。目標是照 Claude 桌面 App 本地定時任務(Routines / CCD scheduled tasks)的行爲,給 DSH 補一套定時任務。

這是什麼

一句話定位:一個 DSH 插件,用一份 JSON 索引管理定時任務,每次觸發都新建會話、獨立上下文跑一輪。

解決的實際問題是——內置提醒到點只投遞消息,你不知道模型到底跑沒跑完、跑得怎麼樣;而 dsh-routines 把這一輪當成一次真正的運行來記賬,失敗、超時都能查到。

與內置自動化任務的區別

維度 @deepseek-ai/dsh-schedule(內置) dsh-routines(本插件)
運行位置 投回綁定會話,複用其歷史 新建會話,每輪獨立上下文
執行回執 只表示消息進入收件箱 turn/end 後記錄狀態/耗時/步數/token
手動運行 無 「立即運行」,不改排期
停用/啓用 無 支持
一次性任務 無 支持,跑完自動停用

因爲每輪不共享上下文,任務裏那條指令(prompt)必須自包含——寫清楚要做什麼,不要指望它會讀到上一次的對話。

調度與運行語義

調度能力:

  • cron:五字段,本地時區;支持 *、a、a-b、a-b/n、列表、月份和星期英文縮寫。
  • 一次性:ISO 時間點,只允許未來時間;跑完自動停用;超過 7 天未跑的到點任務直接停用。
  • 僅手動:cron 與一次性都不填,只保留在列表裏,點「立即運行」。
  • 心跳:啓動立即掃一次,之後每 60 秒掃一次。
  • 補跑:錯過時在 max(創建時間, 7 天前, 啓用時刻) 之後找最近一個槽補跑一次;遲到超過 2 分鐘標記爲 missed。
  • 抖動:cron 任務派發延遲 = sha256(taskId) % (min(10, 相鄰間隔-1) * 60) 秒,同一任務恆定,避免整點同時觸發。
  • 重試:建會話或投遞失敗按 5/15/30 分鐘重試,最多三次;模型回合失敗不重試。
  • 併發:同一任務同時只跑一次。

運行一輪的過程:

  1. ctx.sessionController.create({ cwd }) 新建會話,工作目錄取任務配置的,否則取最近會話的。
  2. resolveAgent 後把標題改成「任務名 · 月-日 時:分」;會話 id 記進隱藏名單,從左側列表過濾掉。
  3. 訂閱 session/event,投遞指令,等 turn/end:reason.kind === "completed" 記成功,其餘(error、blocked、aborted、timeout 等)記失敗並保留原因;45 分鐘沒結束按超時失敗處理。
  4. 運行記錄寫進索引,每個任務保留最近 50 條。
  5. 任務由對話裏的工具創建且開着通知時,跑完向創建它的那個會話發一條完成/失敗消息;面板建的任務沒有創建會話,不發。

狀態只存在一個文件裏:

~/.dsh/routines/
  scheduled-tasks.json          # 任務索引:名稱、描述、指令、調度、運行記錄

舊版本寫在 <taskId>/SKILL.md 正文的任務,讀取索引時會自動搬進 prompt 並刪掉目錄。

安裝與啓用

從插件市場安裝,索引源是作者自己用 GitHub Pages 提供的:

https://leinaldo.github.io/dsh-routines/market/index.json
  1. 打開 插件 → 發現 → 添加索引源,填上面的 URL。
  2. 在列表裏找到 定時任務,點 安裝。
  3. 重啓 DSH,左側欄出現「定時任務」。

本地開發方式:

~/.dsh/plugins/dsh-routines
  1. 把倉庫目錄放到 ~/.dsh/plugins/dsh-routines。
  2. 在 ~/.dsh/profiles/desktop/package.json 的 dependencies 加 "dsh-routines": "file:/Users/leinaldo/.dsh/plugins/dsh-routines"(路徑按本機調整)。
  3. 在同一個文件的 dsh.profile.bundles 末尾加 "dsh-routines"。
  4. 在 profile 目錄執行 pnpm install,然後重啓 DSH。

宿主代碼在啓動時加載,改完必須重啓才生效;客戶端面板隨頁面刷新重載。

典型用法

在側邊欄面板裏操作:「新建」填名稱、描述、指令、調度方式、工作目錄;卡片上「立即運行」不改排期,只推 lastRunAt;「停用」只停自動派發,停用後手動運行也會被拒絕。「運行記錄」展開後每條都有狀態、時間、耗時、token、摘要與「查看會話」,點進去就是那次運行的會話——運行會話不出現在左側列表,只從這裏進入。

讓模型直接建任務,不必先開面板:

工具 作用
routine_create 建任務:name、prompt 必填,cron_expression / fire_at / cwd / notify_on_completion 可選
routine_list 列出所有任務、下次運行時間與指令
routine_update 只改傳入的字段;enabled:false 停用
routine_delete 刪任務連同運行記錄
routine_run 立即跑一次,不改排期

在對話裏說「每天 12 點幫我總結 AI 資訊」時,模型會按工具描述在內置 schedule_* 與本插件之間選。想穩定走本插件,點名「用定時任務建」,或直接說「每次新開對話跑」。

HTTP 接口(面板底層就是這些):

方法 路徑 說明
GET /dsh-routines/tasks 任務列表視圖(含下次運行、最近一次狀態、運行中標記)
GET /dsh-routines/task?id= 單個任務(含 prompt)與全部運行記錄
GET /dsh-routines/defaults 默認工作目錄
POST /dsh-routines/tasks/create {name, description?, prompt, cronExpression?\|fireAt?, cwd?, notifyOnCompletion?}
POST /dsh-routines/tasks/update 同上字段 + id,另支持 enabled、disableJitter
POST /dsh-routines/tasks/delete {id},任務文件與運行記錄一起刪
POST /dsh-routines/tasks/run {id},立即運行(不改排期)

適用場景與注意

適合這些情況:已經有一個想在固定時間跑的獨立任務,希望每輪都是乾淨上下文、跑完能查回執;或者想用一次性任務做「跑到點就不動」的提醒。

幾個需要留意的點:

  • 插件以當前 dsh 進程權限運行,裝之前應先讀一遍源碼和許可證(MIT,見倉庫 LICENSE)。
  • 需要審批的任務會停在審批卡上,直到超時記失敗——沒有無人值守審批策略。
  • 沒有系統通知,只有發給創建會話的完成消息和麪板狀態;也沒有費用字段,DSH 宿主只暴露 token,不暴露價格。
  • 運行會話的隱藏只做在網頁端,代價是名單更新依賴這套客戶端代碼,宿主改列表實現時要跟着改。
  • 存儲根目錄只取 DSH_HOME 或 ~/.dsh,不讀 ctx.baseDir——GUI 啓動時後者常是 /,會導致面板永遠讀到空索引。

小結

dsh-routines 把 DSH 的定時動作從「提醒投遞」升級爲「運行記賬」,調度語義、補跑和抖動都按 Claude Routines 對齊,代價是指令必須自包含、每輪新開會話。

  • 目錄頁:https://www.skillhub.cn/plugins/leinaldo/dsh-routines
  • GitHub:https://github.com/leinaldo/dsh-routines
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜