🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

定时任务调度 cofy-x/dsh-cron

DeepSeek Harnessv0.8.0-alpha.4
cofy-x53 天前有提交已提供中文文档扫描:含敏感能力

按日历计划自动触发智能体会话执行任务

37.2/100
综合分
4
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/19 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:engines.node 要求 >=24.0.0,不满足 Node 22.19.0。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add cofy-x/dsh-cron
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · market
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 53 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/22) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

engines.node 要求 >=24.0.0,不满足 Node 22.19.0

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包@cofy-x/dsh-cron @ 0.8.0-alpha.4
✗Node 引擎要求 >=24.0.0 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/31 07:31:58

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 63 处,展示前 57 条)
  • 删除本地文件递归
    scripts/prepare.mjs:21
    rmSync(join(root, 'lib'), { recursive: true, force: true })
  • 读取本地文件
    scripts/prepare.mjs:24
    if (!existsSync(entry)) {
  • 执行外部命令来自配置/变量
    scripts/prepare.mjs:28
    const result = spawnSync(process.execPath, [entry, ...args], { cwd: root, stdio: 'inherit' })
  • 执行外部命令固定命令
    scripts/extract-patch.mjs:40
    return execFileSync('git', ['-C', harness, ...args], { cwd, encoding: 'utf8' })
  • 读取本地文件
    scripts/extract-patch.mjs:61
    const config = existsSync(args.config)
  • 读取本地文件
    scripts/extract-patch.mjs:62
    ? JSON.parse(await readFile(args.config, 'utf8'))
  • 读取本地文件
    scripts/extract-patch.mjs:71
    if (!existsSync(args.config)) {
  • 读取本地文件
    scripts/extract-patch.mjs:103
    const content = await readFile(path, 'utf8')
  • 写入本地文件
    scripts/extract-patch.mjs:107
    await writeFile(path, content.replace(seam.old, seam.new))
  • 写入本地文件
    scripts/extract-patch.mjs:115
    await writeFile(out, patch)
  • 执行外部命令固定命令
    scripts/extract-patch.mjs:116
    execFileSync('git', ['-C', baselineTree, 'apply', '--check', out], { encoding: 'utf8' })
  • 执行外部命令固定命令
    scripts/extract-patch.mjs:117
    execFileSync('git', ['-C', trimmed, 'apply', '--check', '-R', out], { encoding: 'utf8' })
  • 执行外部命令来自配置/变量
    scripts/git-install-smoke.mjs:22
    const result = spawnSync(executable, args, { cwd, encoding: 'utf8', stdio: 'inherit' })
  • 执行外部命令来自配置/变量
    scripts/git-install-smoke.mjs:28
    const result = spawnSync(command, args, { cwd, encoding: 'utf8' })
  • 读取本地文件
    scripts/git-install-smoke.mjs:39
    const expected = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
  • 写入本地文件
    scripts/git-install-smoke.mjs:62
    writeFileSync(join(workspace, 'package.json'), JSON.stringify({ private: true, type: 'module', packageManager: expected.packageManager }, null, 2))
  • 写入本地文件
    scripts/git-install-smoke.mjs:63
    writeFileSync(join(workspace, 'pnpm-workspace.yaml'), [
  • 读取本地文件
    scripts/git-install-smoke.mjs:81
    const manifest = JSON.parse(readFileSync(join(installedRoot, 'package.json'), 'utf8'))
  • 读取本地文件
    scripts/git-install-smoke.mjs:83
    if (manifest.dsh?.bundle?.patch !== './cordis.patch.yml' || !existsSync(join(installedRoot, 'cordis.patch.yml'))) {
  • 删除本地文件递归
    scripts/git-install-smoke.mjs:93
    rmSync(workspace, { recursive: true, force: true })
  • 读取本地文件
    scripts/publish.mjs:7
    const manifest = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
  • 执行外部命令固定命令
    scripts/publish.mjs:21
    execFileSync('npm', ['publish', '.', '--dry-run', '--access', 'public', '--tag', distTag], { cwd: root, stdio: 'inherit' })
  • 执行外部命令固定命令
    scripts/publish.mjs:34
    execFileSync('npm', ['publish', '.', '--access', 'public', '--tag', distTag, '--provenance'], {
  • 执行外部命令固定命令
    scripts/publish.mjs:55
    const head = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' }).trim()
  • 执行外部命令来自配置/变量
    scripts/publish.mjs:57
    execFileSync(process.execPath, [join(root, 'scripts/verify-release.mjs'), '--ref', `v${manifest.version}`, '--version', manifest.version], {
  • 执行外部命令固定命令
    scripts/publish.mjs:64
    const result = spawnSync('npm', ['view', packageSpec, '--json'], { encoding: 'utf8' })
  • 执行外部命令固定命令
    scripts/verify-release.mjs:15
    const result = spawnSync('git', args, { cwd: root, encoding: 'utf8' })
  • 读取本地文件
    scripts/verify-release.mjs:27
    const manifest = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
  • 执行外部命令固定命令
    scripts/verify-release.mjs:45
    if (spawnSync('git', ['merge-base', '--is-ancestor', head, 'refs/remotes/origin/main'], { cwd: root }).status !== 0) {
  • 读取本地文件
    scripts/verify-self-contained.mjs:18
    for (const entry of readdirSync(directory, { withFileTypes: true })) {
  • 读取本地文件
    scripts/verify-self-contained.mjs:43
    const source = readFileSync(filePath, 'utf8')
  • 读取本地文件
    scripts/verify-self-contained.mjs:60
    } else if (!existsSync(targetPath)) {
  • 读取本地文件
    scripts/verify-self-contained.mjs:89
    if (!existsSync(join(root, requiredPath))) failures.push(`missing repository-layout contract ${requiredPath}`)
  • 读取本地文件
    scripts/verify-self-contained.mjs:92
    const packageJson = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'))
  • 读取本地文件
    scripts/verify-self-contained.mjs:101
    const lockfileSource = readFileSync(join(root, 'pnpm-lock.yaml'), 'utf8')
  • 读取本地文件
    src/filelock.ts:15
    const pid = Number(readFileSync(join(lockDir, 'pid'), 'utf8').trim())
  • 写入本地文件
    src/filelock.ts:32
    mkdirSync(lockDir)
  • 写入本地文件
    src/filelock.ts:33
    writeFileSync(join(lockDir, 'pid'), String(process.pid))
  • 删除本地文件递归
    src/filelock.ts:40
    rmSync(lockDir, { recursive: true, force: true })
  • 删除本地文件递归
    src/filelock.ts:49
    rmSync(lockDir, { recursive: true, force: true })
  • 读取本地文件
    src/lock.ts:20
    const text = readFileSync(join(lockDir, 'pid'), 'utf8').trim()
  • 写入本地文件
    src/lock.ts:49
    mkdirSync(dataDir, { recursive: true })
  • 写入本地文件
    src/lock.ts:52
    mkdirSync(lockDir)
  • 写入本地文件
    src/lock.ts:53
    writeFileSync(join(lockDir, 'pid'), String(process.pid))
  • 删除本地文件递归
    src/lock.ts:60
    rmSync(lockDir, { recursive: true, force: true })
  • 删除本地文件递归
    src/lock.ts:71
    rmSync(lockDir, { recursive: true, force: true })
  • 读取本地文件
    src/store.ts:168
    raw = readFileSync(this.filePath, 'utf8')
  • 写入本地文件
    src/store.ts:189
    renameSync(this.filePath, quarantine)
  • 写入本地文件
    src/store.ts:237
    mkdirSync(dirname(this.filePath), { recursive: true })
  • 读取本地文件
    src/store.ts:317
    stat = statSync(this.filePath)
  • 读取本地文件
    src/store.ts:337
    raw = readFileSync(this.filePath, 'utf8')
  • 写入本地文件
    src/store.ts:358
    mkdirSync(dirname(this.filePath), { recursive: true })
  • 写入本地文件
    src/store.ts:373
    writeFileSync(temporary, content)
  • 写入本地文件
    src/store.ts:374
    renameSync(temporary, this.filePath)
  • 读取本地文件
    src/store.ts:382
    raw = readFileSync(this.filePath, 'utf8')
  • 读取本地文件
    src/store.ts:410
    const value = Number(readFileSync(this.seqFile, 'utf8').trim())
  • 写入本地文件
    src/store.ts:416
    try { writeFileSync(this.seqFile, `${this.seq}\n`) }
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cordis-plugin-include@deepseek-ai/cordis-plugin-loader@deepseek-ai/dsh-api-gateway@deepseek-ai/dsh-api-remotes@deepseek-ai/dsh-api-session-controller@deepseek-ai/dsh-agent@deepseek-ai/dsh-agent-default-model@deepseek-ai/dsh-agent-presets@deepseek-ai/dsh-anonymous-user-id@deepseek-ai/dsh-atomic-write@deepseek-ai/dsh-attachment
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 按日历计划触发任务
  • 模型与人均可调用调度

DeepSeek Harness 的定时任务(cron):模型和人都能调用的调度,向智能体会话触发 followup/inject

README

由 DeepSeek 最新模型翻译生成
dsh-cron DSH Automation 的持久化日历 Trigger 适配器。它把一次性或周期性计划 occurrence 转成幂等 fresh-Session Run,自身不再执行 Agent turn。 责任边界 - dsh-cron 负责计划解析、时区计算、持久化 occurrence 身份、catch-up 策略与任务中心 UI; - dsh-automation 负责 Run 队列、canonical fresh Session、跨 Worker 并发、取消、显式重试、事件历史、retention 与崩溃恢复; - dsh-webhook 是对应的事件驱动 Trigger 适配器,并可选提供终态回调。 安装 需要 Node.js 24 或更新版本、DSH 0.1.5-rc.1 或更新的 0.1.x 版本,以及 dsh-automation 0.2.x。
展开完整文档(README 剩余 1 节)
dsh-cron

DSH Automation 的持久化日历 Trigger 适配器。它把一次性或周期性计划 occurrence 转成幂等 fresh-Session Run,自身不再执行 Agent turn。

责任边界

- dsh-cron 负责计划解析、时区计算、持久化 occurrence 身份、catch-up 策略与任务中心 UI;
- dsh-automation 负责 Run 队列、canonical fresh Session、跨 Worker 并发、取消、显式重试、事件历史、retention 与崩溃恢复;
- dsh-webhook 是对应的事件驱动 Trigger 适配器,并可选提供终态回调。

安装

需要 Node.js 24 或更新版本、DSH 0.1.5-rc.1 或更新的 0.1.x 版本,以及 dsh-automation 0.2.x。

dsh plugin --profile web add dsh-automation@next
dsh plugin --profile web add @cofy-x/dsh-cron

如需测试尚未发布的源码 revision,则从 GitHub 安装:

dsh plugin --profile web add github:cofy-x/dsh-automation
dsh plugin --profile web add github:cofy-x/dsh-cron

插件通过 dsh.client manifest 提供浏览器任务中心,在 headless profile 中也可通过工具、命令与 RPC 使用。

计划语义

支持:

- 五段 cron:分、时、日、月、周;
- 带显式 offset 或 Z 的 RFC 3339 一次性 at;
- 支持夏令时的 IANA 时区。

每个日历 occurrence 都会先持久化 run record 并推进计划,再提交 Automation。稳定身份和幂等键由 job id 与 scheduled instant 确定性生成。如果进程在 Automation 已提交、但本地尚未记录 Run id 时崩溃,重启后会使用同一幂等键取回同一 Run。

错过的周期使用明确的 latest-only catch-up:只执行最新已到期时刻一次,不回放旧积压。一次性 job 执行后作为历史保留。暂停保留计划;恢复周期 job 时会把 next occurrence 推进到当前时间之后。

每个 job 使用并发键 cron:,默认 limit 为 1,由 dsh-automation 在所有 Worker 和进程之间事务性执行。

使用

模型工具:cron_add、cron_update、cron_list、cron_remove。

/cron add 0 9 * * 1-5 总结项目状态 /cron add tz=Asia/Shanghai 30 18 * * 5 准备周报 /cron add-at 2026-09-01T09:00:00+08:00 执行发布检查清单 /cron pause cron-1 /cron resume cron-1 /cron remove cron-1

命令或模型工具创建的 job 会捕获创建 Session 的绝对工作目录,作为 fresh Automation target。浏览器/API job 必须携带 cwd 或继承 defaultCwd。无法得到 fresh target 的旧 job 会安全暂停并记录 migrationIssue,等待重新设置目标。

持久化对账

Occurrence record 从 submitting 推进到关联 Automation state 与终态投影,保留:

- 确定性 occurrenceId、scheduledAt 与 idempotencyKey;
- automationRunId 与当前 Run state;
- 终态时间、outcome、结果摘要或错误。

适配器使用持久化 checkpoint cron.adapter.v1 消费 Automation 事件流。cursor 过期时,它会逐个刷新所有已关联 Run,并从 prune watermark 继续。可选 callback 集成只在首次终态结算时发出。

源 store 只裁剪终态历史,活跃 occurrence 绝不因历史上限被删除。schema v1 在加载时迁移到 v2,旧 lastRun 保留为 legacy occurrence。

配置

| 键 | 默认 | 含义 |
| dataDir | $DSH_HOME/cron | 持久化 job store 与 scheduler lock |
| defaultTimeZone | 主机时区 | cron 未指定时的默认 IANA 时区 |
| maxJobs | 64 | 最大活跃 job 数 |
| minIntervalMinutes | 1 | 周期计划最小间隔 |
| defaultCwd | 无 | 浏览器/API job 的 fresh Session 工作目录 |
| reconcilePollMs | 1000 | Automation 事件流轮询间隔 |
| maxRunHistory | 100 | 每 job 保留的终态 occurrence 数 |

只有持有 scheduler lock 的进程会设置 timer、提交 pending occurrence 并对账事件流。其他共享 Harness home 的进程提供管理服务,并可在主进程退出后接管。

管理写入使用独立的短期跨进程 lock、无冲突 sequence sidecar 和 record-level 三方合并。进程会接纳 peer 新增记录和未在本地修改的编辑,不会复活已删除记录;长时间 lock 竞争必须 fail closed,不得覆盖 peer 状态。

本适配器仅依赖公开的 dsh-automation >=0.2.0-alpha.0 <0.3.0 service contract,不引入私有源码,也不需要修改 deepseek-harness。

开发

pnpm install
pnpm run verify:self-contained
pnpm run typecheck
pnpm test
pnpm run build
pnpm run prepare

许可证

MIT
预览分享卡片长什么样 ↓cofy-x/dsh-cron
分享 · DeepSeek Harness Hub
cofy-x/dsh-cron

按日历计划自动触发智能体会话执行任务

这是你的仓库?认领条目

回到顶部