codex-message-schdeuler
v0.2.1
Published
Unofficial local scheduler for Codex CLI sessions using tmux and one-shot launchd scheduling.
Maintainers
Readme
codex-message-schdeuler
Unofficial local scheduler for Codex CLI. Not affiliated with, endorsed by, or maintained by OpenAI.
codex-message-schdeuler lets you schedule messages for local Codex sessions, or keep a session warm with recurring looped hi messages. Users choose Codex sessions, not tmux sessions. tmux is only local execution infrastructure used when a scheduled job actually runs.
What it does
- Lists locally discoverable Codex sessions
- Lets you choose a session, create a new one, or enter one manually
- Supports one-time scheduling and recurring loops
- Supports custom local times and Codex 5-hour reset based starts
- Stores jobs and loops locally
- Uses one-shot automatic scheduling on macOS and Windows
- Resumes Codex in tmux only when a job is actually due
Disclaimer
- This package is unofficial.
- It uses the term “Codex CLI” descriptively to refer to the local CLI tool.
- It does not use OpenAI branding, logos, or claim official support.
Requirements
- Node.js
>=18.17.0 - Codex CLI installed and already authenticated locally
tmuxinstalled locally- macOS for automatic one-shot
launchdscheduling - Windows for automatic one-shot Task Scheduler scheduling
- Linux currently requires manual
run-dueor an external scheduler
Installation
npm install -g codex-message-schdeuler
codex-message-schdeulerCompatibility note:
codex-message-schdeuleris the primary binary.codex-tmux-schedulerandcodex-schedulerare still shipped as compatibility aliases for existing users.
Quick start
codex-message-schdeuler
codex-message-schdeuler schedule
codex-message-schdeuler loop
codex-message-schdeuler loops
codex-message-schdeuler jobs
codex-message-schdeuler cancel <jobId>
codex-message-schdeuler cancel-loop <loopId>
codex-message-schdeuler doctorMain flow
When you run:
codex-message-schdeulerthe CLI flow is:
- Choose whether you mainly use Codex CLI or Codex app sessions.
- Select a discovered session, create a new session, or enter one manually.
- Choose:
One time scheduleRe run this schedule in a loop (keep session alive)
One-time schedule flow
- Choose:
Send at custom timeSend when my 5-hour limit resetsSend when my weekly limit resets
- If you choose custom time, enter a local future time such as
05:01 pm. - If you choose a reset mode, the tool resumes the selected session in hidden tmux, runs
/status, parses the reset time, and asks you to confirm it. - Enter the message.
- Confirm the job.
Loop flow
- Choose loop cadence:
Every 5 hoursDailyWeekly
- Choose the first loop run timing:
Send at custom timeSend when my 5-hour limit resets
- Loop messages are always
hi. - The loop keeps exactly two future pending loop jobs queued automatically.
Important loop rule:
- If you start a loop from the 5-hour reset option, the tool uses only the reset time-of-day, not the full reset date.
- That keeps the loop anchored to a recurring time instead of inheriting a one-off date from
/status.
Reset-based scheduling
Reset-based scheduling uses Codex CLI /status.
- It does not call undocumented web APIs.
- It does not scrape chatgpt.com.
- It does not store auth tokens.
- If Codex says limits may be stale, the CLI warns you and lets you continue or fall back to custom time.
Example /status-based use:
codex-message-schdeuler
Choose:
One time schedule
Then:
Send when my 5-hour limit resetsHow it works
End-to-end:
- Session discovery
- Local job or loop storage
- Optional Codex CLI
/statuscapture for reset-based timing - Loop expansion into future
hijobs when loops are active - One-shot OS scheduler arms for the next pending job
run-dueexecutes due jobs- tmux-hosted
codex resume - Message injection and submission verification
- Logs and status updates
Runtime path:
- The interactive CLI discovers sessions from local Codex metadata.
- If reset timing is chosen, the tool resumes the selected session in hidden tmux, sends
/status, captures the pane output, and parses reset times locally. - A one-time job or loop definition is stored locally in JSON.
- Active loops keep exactly two future pending loop jobs queued, each sending
hi. - The scheduler backend finds the earliest pending job.
- On macOS it writes a one-shot
launchdplist. On Windows it creates a one-shot Task Scheduler entry. - The OS scheduler invokes
codex-message-schdeuler run-dueonly when that next job is due. run-dueexecutes all pending jobs whosescheduledAt <= now.- After due jobs run, active loops are replenished back to two future jobs.
- Each due job creates a detached tmux session, runs
codex resume, injects the message, and verifies that the prompt actually advanced.
Automatic scheduling
codex-message-schdeuler does not keep an always-running background worker on supported operating systems.
Instead:
- No worker polls every minute by default.
- The OS scheduler is armed only for the next pending job.
- When there are no pending jobs, the scheduled entry is removed.
Automatic scheduler backends:
- macOS: one-shot
launchd - Windows: one-shot Task Scheduler
- Linux: currently manual
run-dueor external scheduler only
Manual fallback always remains available:
codex-message-schdeuler run-dueCommands
codex-message-schdeuler
codex-message-schdeuler schedule
codex-message-schdeuler loop
codex-message-schdeuler loops
codex-message-schdeuler jobs
codex-message-schdeuler cancel <jobId>
codex-message-schdeuler cancel-loop <loopId>
codex-message-schdeuler run-due
codex-message-schdeuler doctor
codex-message-schdeuler doctor --status-check
codex-message-schdeuler install-daemonCommand notes:
schedule: open the interactive scheduling flowloop: directly create a recurringhilooploops: list configured loopsjobs: list stored jobscancel <jobId>: cancel a pending jobcancel-loop <loopId>: cancel a loop and its pending generated jobsrun-due: run all due jobs now and refresh automatic schedulingdoctor: inspect dependencies, storage, next pending job, and scheduler backend statusdoctor --status-check: explicitly run Codex/statusagainst a real sessioninstall-daemon: refresh one-shot automatic scheduling for the next pending job
Storage locations
Default storage:
~/.codex-message-scheduler/Compatibility behavior:
- New installs default to
~/.codex-message-scheduler/ - If an existing
~/.codex-scheduler/directory exists and the new directory does not yet exist, the CLI continues using the legacy directory automatically
Environment overrides:
CODEX_MESSAGE_SCHEDULER_HOMECODEX_TMUX_SCHEDULER_HOMECODEX_SCHEDULER_HOME
Stored files:
~/.codex-message-scheduler/jobs.json~/.codex-message-scheduler/loops.json~/.codex-message-scheduler/config.json~/.codex-message-scheduler/logs/<jobId>.log~/.codex-message-scheduler/runtime.log~/.codex-message-scheduler/launchd.stdout.log~/.codex-message-scheduler/launchd.stderr.log
Security and privacy
- No Codex auth tokens are stored by this tool.
- No prompts or scheduled messages are uploaded anywhere by this tool.
- Reset-based scheduling uses local Codex CLI
/statusoutput only. - No undocumented web APIs are called.
- No chatgpt.com scraping is performed.
- No telemetry, analytics, crash reporting, or hidden network calls are implemented.
- Scheduled messages and loop metadata stay local on disk.
- tmux execution is local only.
- Session discovery is local only and uses best-effort local Codex metadata.
- Do not schedule secrets unless you are comfortable storing them locally.
Limitations
- Session discovery is best-effort and depends on local Codex metadata layout.
- Reset-based scheduling depends on Codex CLI
/statusremaining parseable. - tmux is required for execution and
/statuscapture. - Native Windows still depends on having a tmux-capable environment.
- Linux automatic one-shot scheduling is not implemented yet.
- Codex UI readiness detection and prompt submission are still heuristic because they depend on upstream terminal behavior.
Troubleshooting
Missing dependencies on first run
- The CLI now blocks normal interactive use if required runtime dependencies are missing.
- Run:
codex-message-schdeuler doctortmux not found
- Install
tmux - On Windows, this usually means using WSL or another Unix-like environment
codex not found
- Ensure the Codex CLI is installed and available on
PATH
reset time could not be parsed
- Retry after running
/statusmanually in Codex once - Use:
codex-message-schdeuler doctor --status-check- Fall back to custom time if Codex changes its
/statusformat
launchd or Task Scheduler is not armed
- Run:
codex-message-schdeuler install-daemon
codex-message-schdeuler doctorinspect logs
cat ~/.codex-message-scheduler/runtime.log
cat ~/.codex-message-scheduler/logs/<jobId>.logDevelopment
npm install
npm run build
npm run typecheck
npm testLicense
MIT
