Scheduler
Heartbeat, cron jobs, and event-driven automation.
Overview
Every Claw42 agent has a built-in scheduler that runs background tasks without any dashboard interaction. There are three types of scheduled work: heartbeat monitoring, cron jobs, and event handlers. All of them are file-driven - you edit a file in the workspace and the agent picks up the changes live, no restart required.
Heartbeat
The heartbeat is a periodic check-in where the agent runs a monitoring checklist. By default it fires every 30 minutes.
On each tick, the agent reads HEARTBEAT.md from the workspace root and executes the instructions inside it as a full agent turn. A default template is written at startup, but you can edit it to check whatever you want.
For example, your heartbeat checklist might include:
- Check if a web app is still responding.
- Verify disk usage is below a threshold.
- Confirm a long-running process is still alive.
- Scrape a page and report if specific content changed.
If the agent responds with HEARTBEAT_OK, the response is suppressed (nothing appears in chat). Any other response is posted to the dashboard so you can see what the agent found.
Self-healing
Before each heartbeat tick, the agent runs built-in self-healing checks: it verifies Chrome is reachable via CDP (and restarts it if not) and checks workspace disk health. These checks run automatically and don't require any configuration.
Cron jobs
For tasks that need to run on a specific schedule, create a CRON.toml file in the workspace root. The agent parses it on every scheduler cycle, so edits take effect immediately.
[[jobs]] name = "check-prices" schedule = "0 */6 * * *" # every 6 hours command = "Check current BTC price and log it to prices.csv" [[jobs]] name = "daily-summary" schedule = "0 9 * * *" # 9 AM daily command = "Summarize yesterday's activity and post to Slack" [[jobs]] name = "cleanup" schedule = "0 0 * * 0" # midnight Sunday command = "Delete temp files older than 7 days"
Each job has three fields:
- name - identifier for the job, shown in logs and chat.
- schedule - standard 5-field cron expression (minute, hour, day-of-month, month, day-of-week).
- command - natural language instruction sent to the agent. The agent interprets it the same way it handles a chat message - it can use any of its tools (shell, browser, file read/write, etc.) to carry out the task.
Last-run timestamps are persisted to state/cron-state.json, so jobs won't re-fire after a restart if they already ran within their window.
Event handlers
Event handlers let the agent react to things that happen in real time. They're defined in ON_EVENT.md in the workspace root using markdown headings to name each event type.
## on_title_change When the browser title changes, check if the page loaded correctly. If you see an error page or CAPTCHA, try to resolve it. ## on_title_change If the title contains "Login" or "Sign in", fill in the credentials from MEMORY.md and submit the form.
Currently supported events:
- on_title_change - fires when the browser page title changes. The agent receives the new title and URL as context. A 3-second debounce prevents rapid-fire triggers during page loads. The event is also suppressed if the title change was caused by the agent's own actions (so it doesn't react to its own navigation).
You can have multiple handlers for the same event - they're all concatenated and sent to the agent as a single prompt. A default template is written at startup, but you can customize it freely.
Concurrency
Only one agent turn runs at a time. All scheduler tasks use a non-blocking lock: if an agent turn is already in progress (from chat, webhook, or another scheduler task), the tick is skipped rather than queued. This means your chat messages always take priority - a heartbeat or cron job will never block you from talking to the agent.
Output
All scheduler output flows through the same message store as regular chat. When a heartbeat, cron job, or event handler produces a response, it appears in the dashboard chat feed. There's no separate log viewer - everything the agent does is visible in one place.
Workspace files
| File | Purpose | Created at startup |
|---|---|---|
| HEARTBEAT.md | Monitoring checklist | Yes (default template) |
| CRON.toml | Cron job definitions | No (user-created) |
| ON_EVENT.md | Event handler rules | Yes (default template) |
| state/cron-state.json | Last-run timestamps | Auto-created |
All workspace files are synced to the control plane database periodically. If the container is rebuilt, they're restored automatically.
Disabling the scheduler
The scheduler is enabled by default in container mode. To disable individual features, update the agent config: set heartbeat, cron, or events to disabled. In CLI/local mode, all scheduler features are off by default since there's no background daemon.