用途:loop.mjs 是一个无依赖的 Node ESM 运行器,用于注册并按固定间隔触发 codex exec 任务,适合“/loop”“每 N 分钟/小时运行”“每 5 分钟轮询 X”“重复此 Codex 提示词”等间隔重复场景。它只支持间隔重复(loop)这一种任务类型;cron 计划或指定时间的一次性运行需使用单独的 schedule 技能。
主要能力:提供 8 个子命令——parse-loop、add、list、cancel、status、run-due、daemon、doctor。任务状态保存在 .codex/loop/ 下。每次运行记录在 .codex/loop/runs/<taskId>/,含带时间戳的 .jsonl(完整 codex stdout)、.last.txt(最后一条 Codex 消息),可选 .stderr.txt。每次运行后,下次运行时间按 finishedAt + intervalMs 重算,间隔从运行完成时计起,不会漂移。
使用方式:所有改变状态的命令都需要 --state-root <dir>,惯用路径为 --state-root .codex/loop。添加任务示例:node scripts/loop.mjs add --state-root .codex/loop --interval 1m --prompt "check CI status" --cwd "$PWD"。add 仅限 loop,--kind 可选且若给出必须为 loop。省略间隔时默认 10m,单位有 s(向上取整到分钟,最小 1m)、m、h、d。可选 --next-run-at <ISO> 覆盖首次运行时间。管理命令:list(加 --json 输出机器可读)、cancel <id>、cancel --all、status(加 --json)。启动运行器:node scripts/loop.mjs daemon --state-root .codex/loop [--poll-ms 5000] [--once] [--max-runs N] [--codex-bin /path/to/codex]。run-due 做一次按需到期检查,不持续占用守护锁,适合 CI 触发或手动测试。doctor 检查状态根可写性、任务数、锁状态和 codex 二进制可达性,只读且不创建状态根。
限制:官方推荐优先使用 Codex app Automations 作为持久常驻方案,它跨重启和终端退出保持;本地 CLI 仅为终端回退,守护进程不运行则不会触发,它不是 OS 服务,不随终端退出存活,需放在持久终端或 tmux 会话中。守护进程持有单运行器锁,同一状态根下第二个守护进程在第一个存活时会失败,仅回收可证明过期的锁(PID 已死)。--codex-arg 透传采用默认拒绝白名单,目前仅允许 --model/-m(含其值),其余标志被拒绝并抛出 ValidationError,明确拒绝沙箱/审批/配置覆盖类标志。脚本不会向 codex exec 发出绕过审批或沙箱的标志,也不安装 OS cron、launchd 或任何系统服务。完整状态/锁模式、间隔语法和逐命令契约见 references/loop-contract.md。