npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@goodandready/dsh-cron

v0.2.50

Published

Background automation runner for DSH: isolated agent runs, script/HTTP/SSH/Docker runtimes, cost guard, notifications, heartbeats.

Readme

📦 @goodandready/dsh-cron


⚡ 概述与问题

自主 AI 智能体经常需要执行周期性任务:生成每日晨报、整理缺陷跟踪、检查 API 健康状态、同步数据库或定期执行 Git 清理。如果 Harness 内没有专用调度器,用户只能依赖外部 crontab 封装、复杂的 webhook 方案或手动干预。

@goodandready/dsh-cron 是 DeepSeek Harness 的原生全栈调度与后台自动化插件。它将标准 cron 表达式、自然语言间隔语法与自主智能体执行连接起来:

  1. 完善的可视化任务管理器 —— 侧边栏按钮带可折叠的活跃任务列表(下次运行时间或实时状态,行数有上限且状态可记忆),以及功能齐全的面板:按类型、模型、渠道筛选,暂停、立即运行、复制、导出/导入与创建任务。
  2. 交互式“由 DSH 创建”流程 —— 与智能体对话,把高层需求转化为规范的定时任务。
  3. 自主工具调用 —— 原生 cron_* 工具让智能体在会话中自行安排后续执行。
  4. 健壮的调度器与原子存储 —— 基于 croner:间隔别名、一次性延时任务、原子写入、运行历史与成本追踪。
  5. 六种执行运行时 —— shell、Node.js、Python、HTTP/webhook、远程 SSH 与 Docker,并支持按任务的环境变量、工作区绑定以及面向代码修改任务的隔离 git worktree。
  6. 多渠道路由与模板 —— 一次运行可投递到 Telegram、dsh-kanban、Discord、Slack、ntfy、Bark、PushPlus、语音(dsh-tts)与 Gitea,支持 {变量} 消息模板与按 DSH 凭据名称引用的密钥。

🏗️ 架构

graph TD
    subgraph Client ["Web 客户端 (DSH UI)"]
        SidebarBtn["侧边栏时钟按钮<br/>(DSH 客户端插槽)"]
        Overlay["任务管理面板<br/>(标签: 全部 / 活跃 / 暂停 / 已完成)"]
        CreateWithDSH["“由 DSH 创建”对话框<br/>(自然语言任务)"]
        ManualForm["手动任务表单<br/>(运行时、cron、超时、重叠策略、渠道)"]
        SettingsCard["设置卡片<br/>(渠道、模板、凭据)"]
    end

    subgraph Server ["服务端 (Cordis 与 DSH 服务)"]
        HttpRoutes["HTTP REST API<br/>(/dsh-cron/*)"]
        AgentTools["工具调用网关<br/>(cron)"]
        Scheduler["TaskScheduler 引擎<br/>(Croner 实例 + one-shot 定时器)"]
        Store["原子 TaskStore<br/>(tasks.json 原子写入)"]
        AgentRunner["智能体会话调度器<br/>(以指定模型执行提示词)"]
        Runtimes["执行运行时<br/>(shell、node、python、http、ssh、docker)"]
        Notify["投递路由<br/>(模板 + 9 个渠道)"]
        Secrets["凭据引用<br/>(DSH credentials / ENV)"]
    end

    SidebarBtn --> Overlay
    Overlay --> CreateWithDSH
    Overlay --> ManualForm
    SettingsCard --> HttpRoutes
    CreateWithDSH -->|POST /chat/start| HttpRoutes
    ManualForm -->|POST /tasks| HttpRoutes
    HttpRoutes --> Scheduler
    AgentTools --> Scheduler
    Scheduler --> Store
    Scheduler -->|按间隔/一次性触发| AgentRunner
    Scheduler --> Notify

✨ 功能与能力

1. 可视化任务管理器

点击 DSH 侧边栏中的时钟图标(位于“新会话”按钮旁)打开管理面板:

  • 状态过滤标签:全部、活跃、已暂停、已完成。
  • 即时操作:立即运行(Run Now)、暂停/恢复调度、带确认的删除。
  • 一键预设模板:每日摘要、每周回顾、待办监控。
  • 运行历史:打开任务卡片查看历史运行 —— 时间、耗时、状态(成功 / 失败 / 超时 / 跳过 / 错过)、输出与错误。
  • 快捷计划预设:在任务编辑弹窗中通过预设按钮一键填入常用频率(15m、1h、Daily 09:00、Weekdays、Weekly Mon),并即时更新自然语言预览。
  • 自动暂停与预算保护徽章:当任务因预算熔断机制(Burn Guard)自动暂停或手动暂停时,任务卡片上显著展示包含具体原因的状态徽章。
  • 汇总统计栏:活跃任务数、总运行次数、总 token 消耗与估算美元成本。

2. “由 DSH 创建”对话框

无需猜测 cron 语法,用自然语言即可创建任务:

  1. 点击 Create ⌄ ➔ Create with DSH。
  2. 描述要自动化的内容(例如:“每个工作日早上 9 点检查未处理的 PR 并起草评论”)。
  3. 插件会创建一个注入了调度器指令的专属智能体会话。智能体会与你确认细节 —— LLM 还是 NO-LLM shell 任务、准确的 cron 表达式、在你的 DSH 安装中可用的经济型模型,以及是否启用“静默规则”(仅在新事件或故障时告警)—— 评估属于对话内定时提醒(schedule_create)还是后台自动化(cron),并在获得您的确认后通过 cron 工具(action: 'create')注册任务。

2. DSH 核心内置 schedule 与 dsh-cron 对比

DeepSeek Harness 内置了轻量级扩展 @deepseek-ai/dsh-schedule,用于会话内的基础定时提醒。下表帮助您根据场景选择合适的工具:

| 功能维度 | DSH 核心 schedule (@deepseek-ai/dsh-schedule) | @goodandready/dsh-cron | |:---|:---|:---| | 主要定位 | 当前会话内的定时提醒与催办消息 | 无人值守的后台自动化执行器与任务编排引擎 | | 执行上下文 | 当前活动会话内 | 独立的隔离智能体会话或外部后台进程 | | 执行运行时 | 仅当前会话提示词(LLM) | 9 种运行时:llm、script (bash/sh)、node、python、http (REST/webhook)、ssh、docker、skill、workflow | | 模型工具 | schedule_create、schedule_list、schedule_delete | 统一 cron 工具(action: create、list、get、update、pause、resume、run、delete) | | 工具模式体积 | 约 1.5k 字符 | 约 1.5k 字符(由 9 个工具合并为 1 个,节省约 12k 字符上下文) | | 推送渠道 | 仅限当前会话 | 多渠道:Telegram、Discord、Slack、Webhook、Kanban、ntfy、Bark、PushPlus、语音 (TTS)、Gitea | | 代码修改隔离 | 无 | 临时或保留的 git worktree 隔离环境(worktree: true) | | 成本与 Token 限制 | 无 | 成本熔断防护:costLimitUsd、dailyCostLimitUsd、tokenLimit 自动暂停 | | 容错与健康检查 | 无 | 指数退避自动重试、失败自动诊断、心跳监测 (Dead Man's Snitch / Better Uptime) | | 静默规则 (Silent Rule) | 无 | 无新事件或变更时完全静默(杜绝通道垃圾消息) | | 任务管理 | 基础列表与删除 | 完整 UI 管理器、运行历史、日志查看器、指标统计、手动触发、导入导出、配置同步 |

3. 智能体工具 (cron)

自主智能体通过单个统一的 cron 工具直接管理定时任务,大幅降低模型模式开销:

| 动作 (action) | 说明 | 核心参数 | |:---|:---|:---| | create | 创建新的后台定时任务或自动化作业 | title、schedule、prompt、type、model、channels、delivery 等 | | list | 列出任务的状态、下次运行时间、token 总量与成本估算 | status ('all'、'active'、'paused'、'completed') | | get | 根据任务 ID 获取单项任务的完整配置 | id | | update | 就地修改现有任务(切换到代码执行运行时需 confirmCodeSwitch: true) | id、修改字段 | | pause | 暂停调度而不删除配置 | id | | resume | 恢复已暂停的调度 | id | | run | 触发一次立即的带外运行 | id | | delete | 永久删除任务及其历史 | id |

[!NOTE] 上下文优化与平滑迁移:此前 9 个单独的工具模式在每次模型轮次中消耗约 13.6k 字符。整合为单一 cron 工具后,模式开销减少约 88%(降至约 1.5k 字符)。旧工具名(cron_create_task、cron_schedule_task、cron_list_tasks 等)被优雅拦截,并返回清晰迁移提示,引导模型使用带对应 action 的 cron 工具。对于简单的会话内提醒,模型将建议使用核心内置的 schedule_create。

会话中模型可进行的调用示例:

cron({
  "action": "create",
  "title": "Morning digest",
  "schedule": "0 8 * * 1-5",
  "prompt": "Prepare a brief morning digest of active tasks and open tickets.",
  "type": "llm",
  "delivery": "isolated"
})

4. 调度表达式语法

基于 croner,支持标准 5 段 cron 表达式与友好的别名:

  • 0 9 * * 1-5 —— 工作日 09:00
  • */15 * * * * —— 每 15 分钟
  • 0 0 * * 0 —— 每周日午夜
  • every 10m / every 2h / every 30s —— 自然语言间隔
  • daily / hourly / weekdays 快捷方式,以及标准 @hourly / @daily / @weekly / @monthly / @yearly 与 @every 30m
  • 任务级时区 —— 可为任务设置 IANA 时区(如 Europe/Berlin);未设置时按服务器本地时间调度
  • 一次性任务:at: 2026-09-05T15:00:00Z(精确 ISO 时间戳)或相对延时 in 20m / in 2h(也接受 через 15 минут 之类的俄语输入)。一次性任务在单次运行后自动转为 completed,显示在 已完成 标签下。

5. 执行可靠性

  • 自动重试 —— 按任务设置 maxRetries 与基础 retryBackoffMs:失败(error/timeout)的运行按指数退避自动重试,成功后计数归零。
  • Misfire 策略 —— 选择守护进程离线期间错过的运行如何处理:skip(默认 —— 记录缺口)、runOnce(迟执行一次)或 catchUpAll(迟执行并记录缺口)。skip 下错过的一次性任务直接转为 completed,不再过期触发。
  • 并发上限 —— 插件设置 maxConcurrent 限制并行运行数;超出的运行记录为 skipped 并附原因。
  • 实时执行指示 —— 任务列表中的脉冲状态图标与运行计时器。

6. 执行运行时

每个任务可选择自己的运行时;非 LLM 运行时不需要模型,也不消耗 token:

  • Shell(script)—— 通过 Harness shell 执行命令或脚本,支持 env 与 cwd。
  • Node.js(node)与 Python(python)—— 指定解释器(nodePath、pythonPath)运行片段;Python 会自动识别项目虚拟环境。
  • HTTP(http)—— 以自定义请求头与请求体访问 URL,状态码与响应写入运行历史。
  • SSH(ssh)—— 通过 dsh-remote-workspace 配置(sshProfileId)或独立 host/key 字段在远程主机执行命令。
  • Docker(docker)—— 在镜像容器(dockerImage)中执行命令。
  • 环境变量 —— 按任务的 env 映射(界面中每行 KEY VALUE)应用于外部运行时;请勿在此存放密钥。
  • 工作区与 worktree —— 将任务绑定到 Harness 工作区(workspaceId);对会修改代码的智能体任务,可在隔离的 git worktree 中运行(worktree、keepWorktree)。

7. 成本控制:回退模型与支出保护(Burn Guard)

  • 回退模型 —— 任务可以默认使用便宜模型,失败时改用更强模型完成:设置 fallbackModel(可选 fallbackProvider),失败(error 或 timeout)的运行会在该模型上重试一次,之后才进入常规重试退避。历史记录会标明最终产出结果的模型以及是否使用了回退,两次尝试的用量与成本都会累计,模板变量 {model} 渲染完成运行的模型。回退仅适用于智能体类型(llm、skill、workflow)。
  • Token 与成本支出保护(Burn Guard) —— 为任务配置严格预算上限:costLimitUsd(总支出美元上限)、dailyCostLimitUsd(24小时滚动支出上限)和 tokenLimit(Token总数上限)。一旦达到任一阈值,任务将自动暂停并记录 pausedReason(cost_limit_exceeded、daily_cost_limit_exceeded 或 token_limit_exceeded),同时向所有配置的通知渠道发送报警通知。
  • 基于会话事件的 Token 与成本统计 —— 直接从 DSH 会话流式事件(assistant/message、assistant/chunk usage、assistant/attempt)中提取实际 Token 消耗,精确计入未命中输入、命中缓存读取、生成输出及重试过程中已计费的失败尝试。
  • 滑动 24 小时成本账本(24h Cost Ledger) —— 日耗保护(dailyCostLimitUsd)在 store.json 中为每个任务维护独立的滑动 24 小时成本记录。即使历史记录超过 100 条触发归档,24 小时内的所有花费依然完整保留并能跨服务重启持续生效。

8. 会话集成与权限

  • 真实智能体输出与终端状态捕获 —— 隔离当前轮次的会话事件,提取最终真实的智能体回复文本(持久会话中自动排除以往历史轮次),并严格校验轮次终止状态(带有错误或中断的 turn/end),确保任务失败能准确反映到执行历史、链路调用及结构化指令中。
  • 按任务的权限预设 —— default、read-only、workspace-write 或 full 在提示词执行前应用于任务会话。
  • 会话自动归档 —— 隔离的 cron 会话在运行后自动归档(尽力而为),不干扰聊天列表。
  • 历史 → 会话 —— 每次 LLM 运行都会记录会话,可直接从历史记录打开对话。

9. 按规则保持安静

有输出的任务可以设置用自然语言描述的静默规则(例如“当没有分区使用率超过 80% 时保持安静”)。运行成功时,由便宜模型对照该规则判断输出,若结论为保持安静则跳过报告,并在运行历史中记录原因。遵循 fail-open:没有规则、没有模型、调用失败或答案无法解析时都会照常投递报告。插件设置 silentRuleModel 指定用于判断的模型。

10. 失败诊断

智能体任务可以请求诊断:设置 inspectOnFailure 后,失败(error 或 timeout)的运行会连同任务提示词与截断输出一起交给模型,运行历史中会保存简短诊断与具体的提示词修改建议。历史记录提供按钮把该建议载入编辑表单 —— 不会自动应用。模型由 inspectorModel 指定,消息模板中可使用 {diagnosis}。模型不可用或调用失败时,失败的运行保持原样。

11. 通知渠道与消息模板

运行完成后,报告会发送到该任务配置的所有渠道 —— Telegram、dsh-kanban、Discord、Slack、ntfy、Bark、PushPlus、语音(dsh-tts)以及 Gitea issue:

  • 任务迁移 —— 将全部配置导出为版本化 JSON,并在别处导入(含预览摘要);导入的任务处于暂停状态。
  • 按任务选择渠道 —— 在任务表单中勾选渠道;显式选择会覆盖旧版 notifyTelegram/kanbanMode 开关,留空则回退到它们。
  • 故障隔离 —— 某个渠道不可用会记录在调度器日志中,其余渠道仍会收到报告;失效的 webhook 不会吞掉整份报告。
  • 消息模板 —— 支持全局模板、按渠道覆盖或按任务模板,变量为 {title} {id} {status} {output} {error} {duration} {schedule} {time} {tokens} {cost}。未知占位符保持原样,失败运行默认使用失败模板。
  • onlyOnFailure —— 全局或按任务生效:成功运行静默,仅发送 error/timeout。
  • 凭据按名称引用 —— webhook token 与 Telegram bot token 填写 DSH 凭据的名称(botTokenRef、ntfyTokenRef、pushplusTokenRef、giteaTokenRef),发送时通过 DSH credentials 服务解析,并可回退到环境变量,且绝不会经过插件设置。webhook URL 与 Bark 设备键本身内嵌密钥,因此保存在插件设置文件中,但返回浏览器时始终为掩码,界面回传的掩码值也不会覆盖已保存的值。
  • 投递超时 —— 每个渠道请求都有上限(deliveryTimeoutMs,默认 15000 毫秒,可在设置面板或 settings.yaml 中调整),且各渠道并发发送:无响应的端点只记录为失败,不会拖慢其他渠道或下一次调度。限制作用于整个渠道处理过程,也覆盖凭据解析——它不支持 abort 信号。
  • Telegram —— 带状态徽标(✅ / ❌)、耗时、调度描述与等宽输出块的 Markdown 报告;动态值会被转义。凭据可直接填写,或从 DSH settings.yaml 的 dsh-messenger-gateway 段继承(尽力而为)。
  • Discord / Slack —— 通过 webhook 投递:Discord 使用按运行状态着色的 embed,Slack 使用纯文本正文。
  • ntfy / Bark / PushPlus —— 移动推送,支持主题/设备键与可选 bearer token;Bark 的标题与正文放在请求路径中,PushPlus 端点可指向自建代理。
  • 语音 —— dsh-tts 通过其 HTTP 路由朗读报告(ttsBaseUrl,默认 http://127.0.0.1:3080)。
  • Gitea —— 创建包含运行报告的 issue(giteaBaseUrl、giteaRepo、token 凭据);失败运行标记为 cron、bug、alert。
  • 测试发送按钮 —— 在安排关键任务前现场验证 Telegram 连通性。

12. Kanban 集成与成本统计

  • 自动创建 Kanban 卡片 —— 当 kanbanMode 为 on_failure 或 always 时,插件在 dsh-kanban 中创建卡片(on_failure → error/timeout 时进入 Backlog;always → 完成后进入 Done/Backlog)。
  • Token 与执行成本计量 —— 按运行与任务统计 token 消耗(输入、输出、缓存读取),基于内置价格表估算美元成本,并提供汇总分析栏。

13. 重叠策略与执行超时

  • 执行超时(timeoutSeconds) —— 达到限制后,shell 子进程通过 abort 信号立即终止,智能体会话被释放以停止消耗 token。默认 1800(30 分钟)。
  • 重叠策略(overlapPolicy) —— 上一次运行尚未结束时再次触发调度时的行为:
    • skip(默认):丢弃重叠的运行,在历史中记录 skipped;
    • queue:将下一次运行排队,当前任务完成后自动开始;
    • replace:通过 AbortController 中止当前运行并启动新的执行。
  • 调度器重叠策略直达 —— Croner 定时触发不再在上游被静默抑制(Croner protect: false),确保定时触发的重叠事件能够完整传递至调度器,严格执行 skip(记录历史)、queue(延迟排队)与 replace(优雅终止)。
  • 队列上下文与链路深度延续 —— 全局并发限制队列与任务重叠队列均完整保留不可变执行参数(chainDepth、prevOutput、prevTaskId、prevStatus、prevCostUsd),防止高负载或排队时任务链路数据丢失。

如果守护进程在计划时刻处于离线状态,启动时该次运行会被记录为 missed,历史空档始终可见。

14. 心跳监控(Dead man's switch)

  • 在插件设置中配置 heartbeatUrl 与 heartbeatIntervalSec,调度器会按间隔 GET 该地址 —— 外部监控可在心跳停止时告警。
  • 内置 GET /dsh-cron/heartbeat 端点返回存活状态、活跃任务数与最近运行时间,便于自建看门狗。
  • onlyOnFailure 模式支持心跳超时告警 — 遗漏心跳(status === 'missed')在各通知渠道过滤判定(channels.js、telegram.js、integrations.js)中被统一视作失败状态,确保外部守护进程中断时 Telegram、Discord、Webhook 与看板即刻告警。

15. 来自配置的声明式任务(#50)

长期运行的任务可以直接声明在配置文件里,而无需在界面中手工重建。配置文件拥有这些任务:每次插件启动时会创建或更新它们,从文件中消失的任务会被删除。

在配置文件(cordis.patch.yml)的插件段加入 jobs 列表:

dsh-cron:
  jobs:
    - id: nightly-backup
      title: Nightly backup
      schedule: "0 3 * * *"
      type: script
      prompt: "bash /path/to/backup.sh"
      channels: ["telegram"]
      timeoutSeconds: 3600
    - id: morning-digest
      title: Morning digest
      schedule: "0 8 * * 1-5"
      type: llm
      prompt: "Prepare a brief morning digest of active tasks."
      provider: my-provider
      model: provider-id/model-id
  • 每条必填:id、title、schedule;以提示词承载有效载荷的类型(script、node、python、ssh、docker、llm、skill、workflow)还需非空 prompt。http 例外:目标由 httpUrl(或 prompt)给出。
  • 其余任务字段按原样透传,校验与 API 一致:channels、model、provider、fallbackModel、silentRule、inspectOnFailure、timezone、timeoutSeconds、template、env、cwd,以及运行时字段(nodePath、pythonPath、httpUrl、httpMethod、httpHeaders、httpBody、sshProfileId、sshTarget、dockerImage、workspaceId、worktree、keepWorktree、skillName、workflowName)。
  • 声明式任务标记为由配置管理;面板中显示来源标签而不是编辑/删除按钮。
  • 对配置任务的编辑、暂停、恢复、切换与删除在面板和 API 上返回 409,携带配置任务现有 id 的创建或更新请求 POST /dsh-cron/tasks 同样被拒绝 —— 配置文件的来源为唯一真值。立即运行仍然可用。
  • 通过 UI、API 或智能体工具创建的、id 相同的任务绝不会被覆盖:该条目会被跳过,冲突写入日志。
  • 会执行代码的类型照常激活,但启动时插件会向日志写警告,使通过配置引入的代码路径可见。
  • 条目逐条校验并带下标(config.jobs[i]: …);一条坏条目会被跳过,不会阻止其余任务或整个配置。

16. 外部 REST API(/dsh-cron/api/*,#54)

外部系统(CI、宿主机 cron、curl)无需打开面板即可驱动调度器。这是唯一由 bearer 令牌保护的接口;面板路由保持本地且防跨站。

令牌是插件设置 apiToken(与所有密钥一样掩码显示)。认证与错误:

  • 未配置令牌 → 整个接口返回 503;
  • 缺少或错误的 Authorization: Bearer <token> → 401,比较为常量时间。

| 方法 | 路径 | 说明 | |:---|:---|:---| | GET | /dsh-cron/api/tasks | 任务列表(status / query 过滤,同面板) | | GET | /dsh-cron/api/tasks/:id | 读取单个任务 | | POST | /dsh-cron/api/tasks | 创建任务;带 id 时更新现有任务 | | DELETE | /dsh-cron/api/tasks/:id | 删除任务 | | POST | /dsh-cron/api/tasks/:id/run | 强制执行一次 |

这些操作复用面板处理器,因此对会执行代码类型的 x-dsh-cron-confirm: script 门禁以及对配置任务的 409 拒绝与 UI 完全一致。

  • Bearer Token 远程访问支持 — 远程客户端凭有效 Authorization: Bearer <token> 凭据可直接创建/修改任务、打卡心跳(/dsh-cron/api/heartbeat/:id)及预览调度(/dsh-cron/api/schedule/preview),解除非本机限制。
BASE="http://127.0.0.1:3080"
TOKEN="<API_TOKEN>"

# 列表
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/dsh-cron/api/tasks"

# 创建;请求体带 id 时为更新
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"id":"cleanup","title":"Cleanup","schedule":"0 4 * * *","prompt":"Remove stale temporary files."}' \
  "$BASE/dsh-cron/api/tasks"

# 强制执行
curl -s -X POST -H "Authorization: Bearer $TOKEN" "$BASE/dsh-cron/api/tasks/cleanup/run"

# 删除
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" "$BASE/dsh-cron/api/tasks/cleanup"

# 会执行代码的任务还需确认头
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "x-dsh-cron-confirm: script" \
  -H "Content-Type: application/json" \
  -d '{"title":"Disk check","schedule":"0 * * * *","type":"script","prompt":"df -h"}' \
  "$BASE/dsh-cron/api/tasks"

17. Prometheus 指标(#53)

GET /dsh-cron/metrics 返回 Prometheus 文本格式,无需新增依赖即可被抓取:

  • dsh_cron_tasks_total{status} —— 按状态统计的任务数(gauge)。
  • dsh_cron_task_last_duration_seconds{task} —— 任务最近一次完成运行的耗时(秒,gauge)。
  • dsh_cron_runs_total{status} —— 自插件进程启动以来完成的运行数(counter);状态为 success、error、timeout、skipped、missed。
  • dsh_cron_run_records —— 当前保存在内存中的运行记录数(gauge)。

导出内容只有计数、状态和耗时;提示词、运行输出与任务配置不会出现在其中。

scrape_configs:
  - job_name: dsh-cron
    static_configs:
      - targets: ["127.0.0.1:3080"]
    metrics_path: /dsh-cron/metrics

18. 严格的渠道校验(#121)

创建或更新任务时若包含未知的投递渠道 id,现在会返回 400 并列出违规项:

{ "ok": false, "error": "Unknown channel ids: email_ping", "unknownChannels": ["email_ping"] }

Changed in v0.2.7:此前未知 id 会被静默丢弃,客户端即使有拼写错误也会得到 ok: true,最终得到一个不投递任何地方的任务。

导入有意保持宽容(文件可能来自旧版本):未知 id 会从导入的任务中丢弃,但会在响应(unknownChannels)中列出并写入调度器日志,而不是无声消失。

19. 安装后校验(#126)

deploy.sh 新增仅校验模式,用于检查已安装的配置而不安装任何东西:

bash deploy.sh verify [exact-version]

它确认配置报告了指定版本(默认取 package.json 的版本),登录 Web UI,然后下载客户端 bundle 并确认其中包含包名。

为什么需要它:Web 配置可能位于认证插件之后并对匿名请求返回 401,而插件客户端 bundle 只能通过认证后索引中打印的精确组合 ?? URL 获取 —— 裸的 /plugins/<name>/client.js 会返回 404。因此校验需要先建立已认证会话。

校验使用的环境变量:DSH_WEB_BASE(默认 http://127.0.0.1:3080)、DSH_WEB_TOKEN(令牌;未设置时脚本从单元日志读取最后一个)、DSH_WEB_UNIT(默认 dsh-web.service)。脚本中不含任何密钥。

20. 内部重构:调度解析与排程(#97)

面向开发者,行为不变。parseScheduleExpression 被拆分为保持相同分支顺序的小函数 —— parseAtExpression、parseRelativeOneShot、parseIntervalExpression、parseAliasExpression、parseCronExpression,scheduleTask 拆分为 clearScheduled、scheduleOneShot、scheduleCron。原有测试全部通过,并新增了针对分支优先级与错误的测试。

21. 性能与进程隔离增强包(v0.2.9,#134)

  • 进程树终止隔离:Shell 和 Script 任务在独立进程组启动(POSIX 下 detached: true);中止或超时向整组发送 -child.pid SIGTERM -> SIGKILL,杜绝孤儿进程与僵尸进程。
  • 并发控制限流:默认安全阈值 maxConcurrent = 2,避免定时重叠引发 CPU 和内存峰值。
  • 瞬态错误重试:针对网络抖动和模型速率限制(429、502、503、504、ECONNRESET)提供指数退避重试(最多3次)。
  • 网络与前端优化:GET /dsh-cron/tasks 支持 ETag 与 304 Not Modified;前端页面根据 visibilityState 自适应轮询(前台 8s,后台 30s)。
  • 历史记录轮换与归档:活动任务仅保留最新 100 次运行,超出部分自动归档至 tasks-history-archive.json。
  • 自主 PR 审查配方 (#33):Template Hub 预置配方与 prReviewerEnabled 设置项。

22. 自动化、任务链与可观测性包(v0.2.10,#137)

  • Telegram 双向交互控制:任务通知附带内嵌操作按钮(🚀 立即运行、⏸️ 暂停/恢复、📋 最新日志)。由 POST /dsh-cron/telegram/webhook 处理,严格鉴权 Chat ID 并调用 answerCallbackQuery 反馈。
  • 任务链上下文与动态变量插值:配置 onSuccess 与 onFailure 下游触发器。父任务的执行结果与元数据自动传递给子任务,在 Shell 任务中提供 $DSH_PREV_OUTPUT、$DSH_PREV_TASK_ID、$DSH_PREV_STATUS 环境变量,在 LLM Prompt 中支持 {{prev.output}}(或 {{prevOutput}})、{{prev.taskId}}、{{prev.status}} 占位符插值。Prompt 额外支持动态运行时时间与元数据变量:{{date}}、{{time}}、{{datetime}}、{{timestamp}}、{{year}}、{{month}}、{{day}}、{{taskId}}、{{taskName}}、{{runCount}}。内置最大 5 级深度递归防护,杜绝死循环。
  • 模型结构化动作指令:自主分析任务可输出 JSON 指令触发级联任务(trigger_task)、定向告警(notify)或创建 Issue。受 llmActionsEnabled: false 严格保护。trigger_task 指令共享全局链路深度上限(chainDepth < 4,最大 5 层调用),彻底阻断自调用死循环与 A → B → A 循环递归,拒绝原因完整记入历史与操作日志中。
  • 历史归档与延迟洞察:REST 接口 GET /dsh-cron/tasks/:id/archive(支持分页)与 GET /dsh-cron/tasks/:id/stats;UI 任务卡片展示耗时彩色徽章(<5s 绿,<30s 黄,≥30s 红)。
  • Prometheus 监控增强:/dsh-cron/metrics 导出当前活动并发量 dsh_cron_concurrent_running、各任务 Token 计数器及成本预估指标。

23. 高级可靠性、自愈、心跳与体验包(v0.2.11,#139)

  • 心跳与寂静监控(Heartbeat / Dead Man's Snitch):针对外部备份与后台作业提供反向监控。外部脚本定期向 /dsh-cron/heartbeat/:id 发送请求;超出 heartbeatIntervalSeconds + 宽限期未打卡时,任务标记为 missed,即刻推送失联告警并触发 onFailure 应急流程。
  • 执行前置检查(Pre-flight Gates):执行前先验证条件(HTTP 状态 2xx、命令退出码 0、最低可用磁盘 MB)。未通过直接置为 skipped,杜绝因外部环境异常产生无意义的模型 Token 消耗与错误干扰。
  • 试运行与调度模拟器(Dry-Run & Simulator):接口 POST /dsh-cron/tasks/:id/dry-run 与 UI 🧪 试运行 按钮支持无副作用执行(不入库历史、不发渠道通知);POST /dsh-cron/schedule/preview 实时计算未来 5 次运行时间。
  • 优先级队列与并发池(Priority Queues):并发满载时,等待队列严格依据任务 priority(1 最高,10 最低)调度。
  • 自愈脚本与 AI 根因诊断(Self-Healing):任务失败后自动执行补偿指令 selfHealingCommand(例如重启服务或清理临时空间);autoDiagnose 自动生成 AI 故障根因摘要。
  • UI 交互式归档与管道全景:支持分页浏览任务历史运行全量输出,直观展示 ➜ 成功触发 与 ↳ 失败触发 关联关系。
  • Shell 与磁盘前置检查强化:前置检查统一支持 command 与 shell 类型,未知类型或异常格式一律安全关闭(fail-closed);磁盘检查支持完整路径与阈值(如 /:10%、/data:500MB)。
  • 可靠性与会话字段完整持久化:HTTP POST 任务创建/修改接口与 cron_create_task 智能体工具完整保留并存储全部 13 个可靠性与会话高级字段(agentPreset、targetSessionId、targetSessionReset、onSuccess、onFailure、heartbeatIntervalSeconds、gracePeriodSeconds、preflightType、preflightTarget、priority、concurrencyGroup、selfHealingCommand、autoDiagnose、fallbackProvider、fallbackModel、silentRule、inspectOnFailure)。

24. 自动挂载智能体预设与工具支持 (#141 / GH-1,v0.2.12 新增)

  • 自动挂载智能体预设:计划执行的自主 llm 任务和交互式启动现在会自动解析并挂载系统智能体预设(默认通过 setup 钩子中的 presets.mount(agentCtx, preset.id) 挂载用户的标准预设)。计划会话现已具备完整的工具调用能力(文件读写、工作区操作、Shell 终端等),彻底解决此前空会话无工具调用的问题。
  • 单任务预设覆盖:可在 Web 管理界面、REST API 或配置文件中为具体任务配置独立的 agentPreset 标识(例如 coding、system、minimal)。未设置时自动继承系统默认预设。
  • 优雅降级保障:当未安装 agentPresets 服务或指定了未知的预设 ID 时,调度器仅记录友好的警告日志,并安全平稳地继续执行基础模型会话,避免定时任务中断。

25. 常驻持久会话与上下文延续 (targetSessionId,v0.2.13 新增,#143)

  • 跨周期会话上下文延续:支持在任务中配置 targetSessionId。设置后,调度器将在每次定时触发时通过 agents.resume() 唤醒已有会话,而不再每次生成孤立的临时会话(cron-exec-${id}-${uuid})。智能体能够完整继承上一轮对话的历史记忆与分析结论。
  • 上下文窗口保护与轮转机制 (targetSessionReset):为防止高频执行导致模型上下文窗口超限与 Token 成本暴增,支持智能轮转策略:
    • never:持续累积单一会话,不重置。
    • daily:每日自动开启全新子会话(后缀 <id>-YYYY-MM-DD)。
    • weekly:每周自动开启全新子会话(后缀 <id>-YYYY-Www)。
    • 日期变量插值:targetSessionId 中支持 {{date}} 占位符,自动注入当前日期 YYYY-MM-DD。
  • 主界面原生可见交互:持久会话不会被标记为 ephemeral/internal,且在执行后跳过自动归档(sessions.archive()),用户可在 DSH 聊天列表中直接查看并继续手动对话。
  • 预设工具链无缝适配:恢复会话时同样完整挂载 agentPresets,保障文件读写、代码编辑与终端工具持续可用。
  • 致谢:功能灵感源自社区开发者 @RaulLazaro。

26. 系统稳定性、硬化与自愈维护包 (v0.2.14, #145)

  • 重试预算自动重置:彻底修复重试耗尽后的计数残留问题。当任务耗尽配置的重试次数(maxRetries)后,attempts 计数器自动清零,确保后续周期的定时调度享有完整的重试预算。常规计划执行或手动触发也均保证以干净的重试预算启动。
  • 清除队列僵尸任务:通过界面/API 暂停或删除任务时,调度器会立即将其从并发等待队列(this.queue)中剔除;并发槽位释放出队时,非激活或已删除的任务也会被自动安全跳过。
  • 历史归档容量上限保护:针对长期运行和高频调度的生产环境,tasks-history-archive.json 针对每个任务安全限制保留最新的 1,000 条运行记录,消除无限制磁盘占用与同步 JSON 序列化卡顿。
  • 灾难恢复与存储自动备份:TaskStore 在每次成功持久化时自动维护原子的 tasks.json.bak 备份副本。若发生进程异常导致数据损坏,存储引擎会自动保存现场切片 tasks.json.corrupted.<timestamp> 供故障分析,并无缝从备份中自愈恢复。
  • 上下文超限自愈与平滑轮转:在常驻持久会话(targetSessionId)中,若智能体因模型上下文窗口溢出(context_length_exceeded)失败,运行器将精准捕获超限错误,归档已满会话,自动轮转至全新子会话并平滑重试,避免任务中断。
  • Windows 进程树彻底终止:在 Windows 系统上,外部进程任务被取消或超时终止时,改为执行 taskkill /pid <pid> /T /F,杜绝孤儿进程和后台残留外壳。

27. 弹窗视口高度自适应与包体积精简 (v0.2.15, #153, #148, #151, #152)

  • 视口高度约束与粘性底部操作栏:所有弹窗(包括任务编辑、新建及推荐模板预设)现已严格受控于视口尺寸 max-height: min(90vh, calc(100vh - 36px)),并内置平滑纵向滚动条。弹窗操作栏(“取消”、“保存”、“创建”)采用 position: sticky 底部悬浮固定,确保无论表单项多长或屏幕分辨率高低,操作按钮始终清晰可见且可随时点击。
  • 遮罩层滚动溢出保护:弹窗遮罩层增加了安全边距与 overflow-y: auto,防止小屏设备在 Flex 居中时发生头部或底部截断。
  • npm 包体积深度精简:从 npm 分发清单中剔除了多余的重复文档副本,使 tarball 体积立减 32 kB 以上,解压后体积减少约 102 kB。
  • Cordis 客户端注入依赖规范化:在 package.json 的 dsh.client.inject 中完整声明了 locale 和 slots 服务依赖。

31. 质量加固与 CI 预检标准包 (v0.2.19, #149, #152, #155, #156, #162)

  • 彻底消除空 catch 块 (#156):引入符合标准规范的 lib/best-effort.js 模块,全面支持同步/异步安全调用、回退返回值和可选日志记录,清除了 runner、scheduler、store 及客户端中的所有 63 处空 catch 块。
  • CI 工作流与本地预检门禁 (#162):新增自动化 CI 工作流(.gitea/workflows/ci.yml 与 .github/workflows/ci.yml),集成本地预检门禁脚本 scripts/ci-preflight.mjs,在出现语法错误、空 catch、颜色硬编码或信息泄露时自动阻断。
  • 主题设计令牌现代化 (#149):将模态对话框与设置卡片中遗留的 rgba(...) 全部重构为原生的 color-mix(in srgb, var(--token) N%, transparent)。
  • 插件清单注入声明规范化 (#152):在 package.json 的 dsh.client.inject 中统一声明完整的 Cordis 包名(@deepseek-ai/dsh-client-locale、@deepseek-ai/dsh-client-ui-slots)。
  • 生产管线导出连接 (#155):将此前仅在测试中调用的导出(findDestructiveRecipe、shouldNotifyTask 和 TEMPLATE_VARIABLES)全面接入配方过滤、通知分发及模板生成核心逻辑。

30. 自更新模块英文与中文多语言支持 (v0.2.18, #160)

  • 设置面板自更新多语言 (#160):在 lib/client-src/10-locales.js 的英文 (en) 与中文 (zh) 字典中补全了全部 10 个自更新键值 (updater.title, updater.btnCheck, updater.checking, updater.btnUpdate, updater.updating, updater.desc, updater.current, updater.available, updater.upToDate, updater.success)。遵循 DSH 插件规范,插件核心内置英文与中文,俄语多语言由 dsh-russian-lang 统一扩展。

29. 客户端模块化解耦与原生主题标准化 (v0.2.17, #149, #150)

  • 客户端模块化架构 (#150): 将庞大的单文件 lib/client.js (约 3950 行) 拆分为 lib/client-src/ 下的 14 个高内聚模块文件 (各模块严格 <= 580 行)。集成零依赖构建脚本 scripts/build-client.mjs 并接入 package.json (build:client, pretest),通过 "files": ["lib/*.js", ...] 避免开发源码冗余打包进 npm 发布包。
  • DSH 语义化主题变量对齐 (#149): 将任务类型标签 (onSuccess, onFailure, heartbeat, targetSession, preflight) 的内联样式全部替换为基于主题变量的 .dsh-cron-tag-* 类;模态框遮罩层接入自适应主题遮罩变量 var(--dsw-alias-bg-mask, rgba(0, 0, 0, 0.75)),移除脉冲动画关键帧中的硬编码 RGBA。
  • 标签治理与工单审计 (#95): 审计并确认全仓库 100% 统一规范使用仓库级标签集。
  • 动态 DOM 清理下的样式自动恢复(#263 / GH-4): 通过 MutationObserver、2 秒兜底定时器与 visibilitychange 事件(startStyleSelfHeal)监听 <head> 与 <html>,当宿主重绘 <head>、切换主题或邻近插件清理样式时,自动重新注入并修复 <style id="dsh-cron-styles"> 标签。

28. 应用内一键自更新与错误容错增强 (v0.2.16, #147, #155, #156)

  • 插件自更新模块 (#147):新增应用内一键自更新机制 (lib/updater.js)、/api/dsh-cron/update 接口与设置面板专属卡片。自动轮询 npmjs 仓库最新版本,精准比对 Semver 版本号(含预发布版本),通过 DSH CLI 就地升级 @goodandready/dsh-cron,无需 SSH 终端操作。POST 请求受跨域与来源保护 (rejectCrossOrigin)。
  • 消除静默异常与错误追踪 (#156):全面消除空 catch 异常压制:任务导入事务回滚失败记录 warn 级别日志、动态核心模块降级原因记录诊断日志、会话自动唤出失败向用户呈现友好提示。
  • 死代码清理与模块导出精简 (#155):清理未引用的旧版实体 (CHANNEL_LABELS, makeInspectAsk),收回 16 个内部工具函数的暴露权限,并将 supportsSilentRule 接入静默规则核心执行流水线。

📦 安装

dsh plugin --profile web add @goodandready/dsh-cron

重启 DeepSeek Harness 实例并刷新浏览器。


⚙️ 配置(settings.yaml)

可以在 settings.yaml 中配置,也可以通过 DSH 中的插件设置卡片交互式管理:

# settings.yaml
dsh-cron:
  botToken: ""                 # Telegram Bot API 令牌(保密字段)
  chatId: ""                   # 接收报告的 Telegram chat ID
  notifyTelegram: false        # 全局投递所有任务的报告
  onlyOnFailure: false         # 仅失败时投递报告
  kanbanBaseUrl: "http://127.0.0.1:3000"  # dsh-kanban HTTP API 基础地址
  defaultTimezone: ""          # 默认 IANA 时区(空 = 服务器本地)
  maxConcurrent: 2             # 最大并行运行数(默认 2,0 = 不限)
  heartbeatUrl: ""             # 心跳上报 URL(dead man's snitch)
  heartbeatIntervalSec: 0      # 心跳间隔秒数(0 = 关闭)
  # --- 投递渠道 ---
  botTokenRef: ""              # Telegram bot token 的凭据名称
  template: ""                 # 全局消息模板,例如 "⏰ {title} — {status}"
  channelTemplates: {}         # 按渠道覆盖模板
  deliveryTimeoutMs: 15000     # 每个渠道的投递超时;慢端点记为失败,不影响其他渠道
  discordWebhookUrl: ""        # Discord webhook
  slackWebhookUrl: ""          # Slack incoming webhook
  ntfyUrl: "https://ntfy.sh"   # ntfy 服务器;ntfyTopic / ntfyTokenRef
  ntfyTopic: ""
  ntfyTokenRef: ""
  barkServerUrl: "https://api.day.app"  # Bark 服务器;barkKey = 设备键
  barkKey: ""
  pushplusUrl: "https://www.pushplus.plus/send"  # pushplusTokenRef
  pushplusTokenRef: ""
  ttsBaseUrl: "http://127.0.0.1:3080"   # dsh-tts 基础地址
  giteaBaseUrl: ""             # giteaRepo = owner/repo,giteaTokenRef = 凭据名称
  giteaRepo: ""
  giteaTokenRef: ""
  # --- 外部 REST API(#54)---
  apiToken: ""                 # 外部 /dsh-cron/api/* 接口的 bearer 令牌(掩码;空 = 503)

配置参数

| 参数 | 类型 | 默认值 | 说明 | |:---|:---|:---|:---| | botToken | string | "" | Telegram Bot API 令牌。留空时插件会尽力继承 DSH 设置中 dsh-messenger-gateway 配置的机器人。保密字段:界面只显示掩码值 | | chatId | string | "" | 接收报告的 Telegram chat ID。留空时回退到 dsh-messenger-gateway 的第一个允许会话 | | notifyTelegram | boolean | false | 全局开关:向 Telegram 投递运行报告 | | onlyOnFailure | boolean | false | 全局开关:仅对 error/timeout 运行投递报告 | | kanbanBaseUrl | string | "http://127.0.0.1:3000" | 用于自动卡片的 dsh-kanban HTTP API 基础地址 | | defaultTimezone | string | "" | 任务调度的默认 IANA 时区;空 = 服务器本地时间 | | maxConcurrent | number | 2 | 并行运行上限;超出的运行记录为 skipped(默认 2,0 = 不限) | | heartbeatUrl | string | "" | 心跳上报 URL,调度器存活期间按 heartbeatIntervalSec 间隔 GET | | heartbeatIntervalSec | number | 0 | 心跳间隔秒数(0 = 关闭) | | botTokenRef | string | "" | 保存 Telegram bot token 的 DSH 凭据名称;发送时解析(回退顺序:botToken → messenger-gateway 设置 → 环境变量 CRON_TELEGRAM_BOT_TOKEN) | | template | string | "" | 带 {title}/{status}/{duration} 等占位符的全局消息模板;留空使用内置文本 | | channelTemplates | object | {} | 按渠道 ID 覆盖模板(telegram、discord 等) | | deliveryTimeoutMs | number | 15000 | 每个渠道的投递超时;超时的端点记为失败,不拖慢其他渠道或下一次调度 | | discordWebhookUrl / slackWebhookUrl | string | "" | Discord 与 Slack 渠道的 webhook 地址 | | ntfyUrl / ntfyTopic / ntfyTokenRef | string | "https://ntfy.sh" / "" / "" | ntfy 服务器、主题与可选的 token 凭据名称(以 Authorization: Bearer … 发送) | | barkServerUrl / barkKey | string | "https://api.day.app" / "" | Bark 服务器与设备键(键、标题和正文位于请求路径中) | | pushplusUrl / pushplusTokenRef | string | "https://www.pushplus.plus/send" / "" | PushPlus 端点(可指向自建代理)与 token 凭据名称 | | ttsBaseUrl | string | "http://127.0.0.1:3080" | 用于语音播报的 dsh-tts 基础地址 | | giteaBaseUrl / giteaRepo / giteaTokenRef | string | "" | Gitea 渠道:基础地址、owner/repo 与 API token 的凭据名称 | | telegramAllowedChatIds | string | "" | 允许执行交互式机器人命令的 Telegram Chat ID 或 User ID(英文逗号分隔) | | apiToken | string | "" | 外部 /dsh-cron/api/* 接口的 Bearer 令牌。保密字段,返回时掩码;为空时接口返回 503,错误值返回 401 |

说明:

  • 运行历史上限为每任务 50 条(固定);每条记录最多保留 4000 字符输出。
  • 任务在服务器本地时区执行;cron 表达式由 croner 按主机时钟计算。
  • 任务持久化在 DSH 数据目录(cron/tasks.json),重启后保留;启动时会检测错过的一次性任务。

🔌 HTTP API 参考

所有端点由 DSH Web 服务器在 /dsh-cron/ 下提供。所有端点均受到强化的 HTTP 来源防护(isTrustedRequest):非回环远程客户端必须携带有效令牌(Authorization: Bearer <token> 或 x-dsh-cron-token),浏览器请求严格校验 Host 与 Origin 一致性并拒绝 Origin: null,同时限制 Sec-Fetch-Site 仅允许 same-origin 或 none。心跳 ping 端点严格要求 POST 方法。任务 GET 响应自动将敏感字段(env、httpHeaders、httpBody)掩码为 '[REDACTED]',并在更新操作提交 '[REDACTED]' 时安全保留已有原密钥。通过 HTTP 创建 script 类型任务还需要 x-dsh-cron-confirm: script 请求头。请求体大小上限为 1 MB。

| 方法 | 路径 | 说明 | |:---|:---|:---| | GET | /dsh-cron/tasks | 任务列表;查询参数 status(all/active/paused/completed)、query(子串搜索)。返回任务、推荐模板与汇总统计 | | POST | /dsh-cron/tasks | 创建或更新任务(携带 id 时为更新)。需要 title、schedule、prompt | | GET | /dsh-cron/tasks/:id/history | 运行历史,?limit=20 | | POST | /dsh-cron/tasks/:id/run | 立即手动运行 | | POST | /dsh-cron/tasks/:id/pause | 暂停调度 | | POST | /dsh-cron/tasks/:id/resume | 恢复调度 | | POST | /dsh-cron/tasks/:id/toggle | 切换活跃/暂停 | | POST | /dsh-cron/tasks/:id/duplicate | 创建暂停状态的副本:复制配置,重置运行历史与计数 | | GET | /dsh-cron/recipes | 内置配方目录:按类别分组的现成监控预设,全部为只读操作 | | GET | /dsh-cron/tasks/export | 仅含任务配置的版本化 JSON —— 不含历史与计数。渠道按名称引用凭据,但手动填写在任务中的 env 与 HTTP 请求头属于配置,会出现在文件里 | | POST | /dsh-cron/tasks/import | 校验文档并以 add、replace 或 skip 策略导入;支持 dryRun 预览。导入的任务始终为暂停状态,恢复不会自动触发 | | PATCH | /dsh-cron/tasks/:id | 部分更新(仅白名单字段:title、schedule、prompt、type、delivery、provider、model、通知/超时/重叠/Kanban 设置、status、oneShot) | | DELETE | /dsh-cron/tasks/:id | 删除任务 | | GET | /dsh-cron/models | 列出 LLM 提供方;?provider=<id> 列出模型 | | POST | /dsh-cron/chat/start | 启动带任务配置指令的“由 DSH 创建”智能体会话 | | GET | /dsh-cron/settings | 客户端安全设置(令牌掩码显示) | | POST | /dsh-cron/settings | 更新集成设置(通过设置服务应用) | | GET | /dsh-cron/heartbeat | 存活探针:活跃任务数与最近运行时间 | | POST | /dsh-cron/telegram/test | 发送 Telegram 测试消息 | | POST | /dsh-cron/kanban/test | 创建 Kanban 连通性测试卡片 | | * | /dsh-cron/action/:id/:action | 任务操作路由的兼容别名(run、toggle、delete、history) | | GET | /dsh-cron/metrics | Prometheus 文本格式的任务与运行计数 —— 不含提示词与输出(#53) | | GET / POST | /api/dsh-cron/update | 插件一键自更新:查询仓库最新版本并就地平滑升级 (#147) | | GET / POST | /dsh-cron/api/tasks | 令牌保护的外部接口:列表 / 创建或更新(#54) | | GET / DELETE | /dsh-cron/api/tasks/:id | 令牌保护的外部接口:读取 / 删除(#54) | | POST | /dsh-cron/api/tasks/:id/run | 令牌保护的外部接口:强制执行(#54) |


🧪 测试与预检门禁 (Preflight)

运行全套自动化测试(调度表达式解析、调度器引擎、原子存储、HTTP 辅助函数、通知与工具契约):

npm test

本地执行质量预检门禁(语法检查、零空 catch 块、主题设计规范、npm 发布归档合规性及防泄漏检查):

node scripts/ci-preflight.mjs

📄 许可证

MIT © GooDAnDReaDY

定时器、间隔与并发分组精度强化 (0.2.39)

  • 32位定时器溢出防护:计划在 24.85 天以后的单次任务(超出 Node.js setTimeout 32位有符号整数上限 2,147,483,647 毫秒)通过分段定时器安全挂起,杜绝立即误触发。
  • 相对单次任务持久截止时间:相对单次任务(如 in 30m、in 2h)在服务重启、存储重载、暂停/恢复以及修改元数据时完整保留初始目标绝对时间戳,仅在显式修改调度表达式时重新计算。
  • 严格的时间间隔校验与转换:对于无法用标准 Cron 分钟步进表示的超限分钟间隔(如 every 90m),在持久化前返回 HTTP 400 拦截;规整整倍数(如 every 120m -> every 2h、every 24h -> every 1d)自动转为合法 Cron 表达式。
  • 统一安全并发默认值:配置规范(Config)与调度器(TaskScheduler)全面对齐默认并发上限 maxConcurrent = 2(0 仅作为显式无限制选项)。
  • 并发分组隔离调度:任务的 concurrencyGroup 属性全面接入调度仲裁与队列排队(同名分组默认限流 1 个并发执行),不同分组可并发运行直至 maxConcurrent,队列任务随所属分组资源释放立即触发。