mcpField
C
cron-scheduler

cron-scheduler

github.com/garrytanAgent 工作流31.3k258 次安装今天更新
代码仓库

关于 cron-scheduler

cron-scheduler 是用于定义和注册定时任务的技能,面向需要自动运行技能或 gbrain 作业的 Agent 操作者。它涵盖错峰调度、静默时段、幂等性、结果报告和通过配置包装器调用 gbrain,并区分托管脑库的同步安排。

主要功能

  1. 01检查任务时段冲突并错峰
  2. 02按时区处理静默时段
  3. 03要求任务可安全重复运行
  4. 04将结果保存为报告
  5. 05通过包装器调用 gbrain

适用场景

  1. 01安排定时运行某项技能
  2. 02配置 gbrain 定期同步
  3. 03避免任务在静默时段通知
  4. 04为多来源脑库设置同步计划

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/garrytan/gbrain --skill cron-scheduler

安装后在 Claude Code 中输入/cron-scheduler确认已加载。

详细介绍

Cron Scheduler

约定: 参见 skills/conventions/test-before-bulk.md——先在 3-5 个项目上测试每个 cron 作业。

Contract

此技能保证:

  • 调度错峰:每个 5 分钟时段最多安排 1 个作业,不发生冲突
  • 静默时段控制:支持时区感知,并可通过用户清醒状态覆盖
  • 简短的作业提示词:作业提示词为“读取 skills/X/SKILL.md 并运行”(不内嵌 3000 字的提示词)
  • 幂等性:作业可运行两次而不会产生重复副作用
  • 结果保存为报告:reports/{job-name}/{YYYY-MM-DD-HHMM}.md
  • 统一入口:每个作业、工作区脚本和钩子都通过同一个包装器调用 gbrain,该包装器会设置 GBRAIN_HOME,并保留标准错误输出和退出代码 (包装器)

Phases

  1. 定义作业。 名称、计划(cron 表达式)、要运行的技能、超时时间。
  2. 验证计划。 检查是否与现有作业冲突(5 分钟偏移规则)。
    • 时段::05、:10、:15、:20、:25、:30、:35、:40、:45、:50
    • 如果检测到冲突,建议下一个可用时段
  3. 检查静默时段。 默认:当地时间晚上 11 点至早上 8 点。
    • 覆盖条件:用户清醒标记(如果用户处于活动状态,则暂停静默时段限制)
    • 静默时段内:将输出保存到待处理队列
    • 早晨联系用户时释放积压内容
  4. 向主机调度器注册。 OpenClaw cron、Railway cron、crontab 或进程管理器。每个已注册条目都应通过 Minions 执行,而不是 agentTurn。 重写模式见 skills/conventions/cron-via-minions.md(PGLite 使用 --follow,Postgres 在周期时段上使用 --idempotency-key,并采用即发即弃方式)。GBrain v0.11.0 迁移会自动重写内置处理器的条目;主机特定的处理器需要按照 docs/guides/plugin-handlers.md 在代码层面注册。
  5. 编写简短提示词。 作业提示词为一行:“读取 skills/{name}/SKILL.md 并运行。”
  6. 通过包装器调用 gbrain。 Cron 运行时的 HOME 和环境变量与 shell 不同,因此直接运行 gbrain(或 bun run src/cli.ts)可能找不到数据库(所有查询都会静默返回空结果),也可能作为第二个主机运行(refresh_not_owner)。注册 gbrain-run <args>,即 cron-schedule.md 中的包装器: 它会设置 GBRAIN_HOME(绝不设置 HOME)、加载大脑的环境文件并运行已安装的二进制文件。将标准错误输出记录到文件中,检查退出代码,避免钩子输出到标准输出,并为每次调用设置至少 10 秒的超时时间。 以下代码行会写入 gbrain-run;doctor 会打印裸命令。 gbrain doctor --only cron_gbrain_home 会警告任何直接运行 src/cli.ts 或在未使用大脑的 GBRAIN_HOME 时调用 gbrain 的 crontab 行或脚本。

Idempotency Requirement

每个 cron 作业都必须具备幂等性:

  • 两次运行同一个作业会产生相同结果(不会创建重复页面或重复的时间线条目)
  • 使用检查点状态文件跟踪进度,并从中断处恢复运行
  • 创建新输出前,检查是否已有现存输出

Output Format

作业配置已保存。报告:“作业‘{name}’已安排在 {cron expression} 执行。下次运行时间:{time}。”

多来源脑:使用 sync --all,而不是为每个来源单独配置

当脑有 2 个或更多活动来源时(即 gbrain sources list 显示的来源具有非空 local_path 且未归档),请使用一条合并的 cron 配置,而不是为每个来源分别配置 N 条。

首选(多来源):

*/5 * * * * gbrain-run sync --all --parallel 4 --workers 4 --skip-failed >> /tmp/gbrain-cron.log 2>&1

这会取代 N 条逐来源配置,并自动纳入未来新增的来源,无需修改 crontab。并发预算:任务运行期间约有 parallel × workers × 2 ≈ 32 个连接(每个逐文件 worker 都会打开一个 2 连接池)。请勿超过 Postgres 的 max_connections 设置。

避免使用(旧方式):分别配置 gbrain sync --source default 和 gbrain sync --source zion-brain,并错开 5 分钟运行。每次新增来源时,都需要手动协调它们;而且较慢的来源可能会与较快的来源争用旧版全局 gbrain-sync 锁(v0.40.3.0+ 使用逐来源的 gbrain-sync:<sourceId> 锁,但逐来源的 cron 配置无法利用 --all --parallel 实际提供的并行能力)。

当 gbrain doctor 检测到 2 个或更多活动来源时,会在 sync_consolidation 检查中显示建议配置行,可直接粘贴使用。

托管脑

托管脑不接受上述配置行:托管同步需要 --no-pull,且不接受 --skip-failed(writer_coordinator_required)。请先检查模式:gbrain sources writer status --json 会报告 "mode": "managed" 或 "mode": "classic",其 bindings 会列出各来源的所属主机。

对于托管脑,请改为在拥有这些来源的主机上安装以下配置行:

*/15 * * * * gbrain-run sources refresh <id> >> /tmp/gbrain-cron.log 2>&1; gbrain-run sync --all --no-pull --hard-deadline 13m >> /tmp/gbrain-cron.log 2>&1
  • gbrain sources refresh <id> 是托管检出获取上游提交的唯一方式(先执行 fetch 和 git merge --ff-only,然后在该检出中对来源执行托管同步)。对于跟踪远程仓库的每个检出,都应添加一条 refresh 配置,并使用实际的来源 ID;对于没有远程仓库的检出,则移除该配置。这里的 ; 是有意为之:即使 refresh 拒绝执行,同步仍会运行。
  • refresh_diverged:该检出包含上游没有的提交,说明有程序在 gbrain 之外提交了更改(通常是某个脚本在检出中写入文件并运行 git commit)。请修复该写入程序,让它使用 gbrain git commit-push -- <paths> 提交,然后按拒绝提示进行协调(征得用户同意后运行 gbrain git commit-push --push-only --keep-checkout);切勿强制操作该检出 (脚本和托管检出)。
  • --hard-deadline 13m 可确保运行时间低于 15 分钟的间隔。托管同步不使用逐来源锁,因此运行时间超过该间隔的任务会与下一次定时运行重叠。在截止时间到达时停止的任务会以 resumable 状态结束,下一次定时运行会继续执行。来源会逐个处理,因此 --parallel 不适用。
  • 某个来源出现 owner_unavailable:请查看其 detail。在 classic Postgres 脑上,unbound_source 属于正常情况,不会阻止 classic 同步;请保留同步配置行。其他任何 detail 都表示该来源由另一台主机负责:请在那台主机上安装逐来源配置行(gbrain sync --source <id> --no-pull --hard-deadline 13m,以及对应的 refresh),而不要在此处认领该来源。
  • 文件失败:修复并提交文件后,使用失败任务的选项重新运行普通的 gbrain sync --source <id> --no-pull …;下一次同步会重试上次记录的失败项。切勿添加 --skip-failed(在托管脑上,--retry-failed 已弃用,等同于普通同步)。

当托管脑有 2 个或更多活动来源时,gbrain doctor 会在 sync_consolidation 中输出这条托管配置行。

失败时的处理

遇到任何 gbrain 错误 code、退出码、[AGENT] 块或通知块时,请遵循Agent 操作员协议。此技能特有的情况:

  • 定时运行的 gbrain sync 遇到 sync_in_progress / lock_busy:说明上一次运行仍未结束。延长间隔或错开任务时间;绝不要再添加一个会重叠运行的定时任务。
  • cron 更改后,Doctor 报告来源过期:再次更改定时任务前,先检查 gbrain sources status <id>,确认是否有暂存项目或错误。
  • 同步日志中出现 checkpoint_validation_timeout:运行错误信息中打印的重试命令;不要取消请求。
  • 定时同步返回 writer_coordinator_required:该 brain 由管理器管理。将该行替换为受管理 brain方案;绝不要使用 --skip-failed 或不带 --no-pull 重试。
  • gbrain sources refresh 返回 sync_in_progress:受管理同步的游标尚未完成,而且刷新不会等待它。运行拒绝信息中打印的 gbrain sync --source <id> --no-pull … 命令;下一个定时任务会继续刷新。
  • 同步时出现 worktree_refreshing:刷新正在清理或合并该工作树。不要干预;下次定时同步会处理它。
  • 某个任务的所有查询结果都为空,或日志显示 no_brain 或 GBRAIN_DB_ACCESS no_url:任务运行时没有加载 brain 的配置。通过包装器调用 gbrain;如果任务的标准错误被重定向到 /dev/null,空结果并不能证明“没有笔记”。
  • cron 返回 refresh_not_owner,但手动运行相同刷新可以成功:任务解析到了另一个 gbrain 主目录,因此它属于另一台主机。拒绝信息会指出读取的身份文件、HOME 和 GBRAIN_HOME;在包装器中设置所有者的 GBRAIN_HOME。绝不要复制或删除 host.json。
  • --json 调用方无法解析 gbrain 的输出:包装器运行的某个钩子向标准输出打印了内容。将该钩子的输出发送到日志文件。
  • 任务中的调用超时,但手动运行可以完成:冷启动需要几秒。将 shell 和生成该进程的运行时中的超时时间都提高到至少 10 s,并使用热 CLI 套接字。
  • 定时写入返回退出码 10:写入已被接受,目前仍在处理中,并非丢失或“未找到”。重试或报告前,先轮询 gbrain write-request <request_id>。

反模式

  • 将多个任务安排在同一分钟运行(所有任务都在 :00)
  • 在 cron 任务中内联 3000 字的提示词(应使用技能文件引用)
  • 未先用 3-5 个项目测试就运行 cron 任务
  • 重跑后产生不同输出的任务(不具备幂等性)
  • 在静默时段发送通知(应改为保存到暂存队列)
  • 在 cron 行、脚本或钩子中直接使用 gbrain 或 bun run src/cli.ts,而不是使用包装器;或包装器设置的是 HOME 而非 GBRAIN_HOME
  • 对 gbrain 调用使用 2>/dev/null,或忽略其退出码
  • 脚本在受管理的工作树中写入文件后运行普通的 git commit,而不是 gbrain git commit-push -- <paths>
  • 调试时将 env 或进程环境变量打印到日志或转录中(其中包含数据库 URL 和密钥)
  • 为每个来源单独设置 gbrain sync --source <id> cron 条目,而 gbrain sync --all --parallel N --workers N 可以用一行命令替代,并自动发现未来添加的来源。

评论

支持 Markdown