openclaw-scheduler 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +302 -0
- package/BEST-PRACTICES.md +506 -0
- package/CHANGELOG.md +82 -0
- package/CODE_OF_CONDUCT.md +22 -0
- package/CONTEXT.md +26 -0
- package/CONTRIBUTING.md +73 -0
- package/IMPLEMENTATION_SPEC.md +170 -0
- package/INSTALL-ADDITIONAL-HOST.md +333 -0
- package/INSTALL-LINUX.md +419 -0
- package/INSTALL-WINDOWS.md +305 -0
- package/INSTALL.md +364 -0
- package/JOB-QUICK-REF.md +222 -0
- package/LICENSE +21 -0
- package/QUICK-START.md +256 -0
- package/README.md +2170 -0
- package/SECURITY.md +34 -0
- package/UNINSTALL.md +129 -0
- package/UPGRADING.md +436 -0
- package/agents.js +67 -0
- package/approval.js +107 -0
- package/backup.js +390 -0
- package/bin/openclaw-scheduler.js +138 -0
- package/cli.js +1083 -0
- package/db.js +122 -0
- package/dispatch/529-recovery.mjs +204 -0
- package/dispatch/README.md +372 -0
- package/dispatch/config.example.json +24 -0
- package/dispatch/deliver-watcher.sh +57 -0
- package/dispatch/hooks.mjs +171 -0
- package/dispatch/index.mjs +1836 -0
- package/dispatch/watcher.mjs +1396 -0
- package/dispatch-queue.js +112 -0
- package/dispatcher-approvals.js +96 -0
- package/dispatcher-delivery.js +43 -0
- package/dispatcher-maintenance.js +242 -0
- package/dispatcher-shell.js +29 -0
- package/dispatcher-strategies.js +1280 -0
- package/dispatcher-utils.js +81 -0
- package/dispatcher.js +855 -0
- package/docs/adr-schedule-ownership.md +73 -0
- package/docs/gateway-contract.md +904 -0
- package/docs/plans/2026-03-09-fix-typescript-types.md +91 -0
- package/docs/plans/2026-03-09-test-coverage-gaps.md +83 -0
- package/docs/plans/2026-03-10-dispatcher-refactor.md +801 -0
- package/docs/trust-architecture.md +266 -0
- package/gateway.js +473 -0
- package/idempotency.js +119 -0
- package/index.d.ts +864 -0
- package/index.js +17 -0
- package/jobs.js +1224 -0
- package/messages.js +357 -0
- package/migrate-consolidate.js +694 -0
- package/migrate.js +125 -0
- package/package.json +130 -0
- package/paths.js +79 -0
- package/prompt-context.js +94 -0
- package/retrieval.js +176 -0
- package/runs.js +270 -0
- package/scheduler-schema.js +101 -0
- package/schema.sql +480 -0
- package/scripts/dispatch-cli-utils.mjs +65 -0
- package/scripts/inbox-consumer.mjs +288 -0
- package/scripts/stuck-detector.sh +18 -0
- package/scripts/stuck-run-detector.mjs +333 -0
- package/scripts/telegram-webhook-check.mjs +238 -0
- package/setup.mjs +724 -0
- package/shell-result.js +214 -0
- package/task-tracker.js +300 -0
- package/team-adapter.js +335 -0
- package/v02-runtime.js +599 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# AGENTS
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
`openclaw-scheduler` is the durable orchestration runtime for OpenClaw agents
|
|
6
|
+
and shell workflows. It manages scheduling, retries, approvals, delivery, and
|
|
7
|
+
persistent state.
|
|
8
|
+
|
|
9
|
+
Use this tool when the task is about:
|
|
10
|
+
|
|
11
|
+
- creating scheduled or triggered jobs
|
|
12
|
+
- running shell commands on a schedule
|
|
13
|
+
- building multi-step workflow chains
|
|
14
|
+
- delivering results to messaging channels
|
|
15
|
+
- inspecting run history and job status
|
|
16
|
+
|
|
17
|
+
For manifest authoring, validation, and identity/authorization profiles, use
|
|
18
|
+
`agentcli`. The scheduler is the runtime; agentcli is the control plane.
|
|
19
|
+
|
|
20
|
+
## Working Rules
|
|
21
|
+
|
|
22
|
+
- Pass `--json` to any command for machine-readable JSON output.
|
|
23
|
+
- `run_timeout_ms` is required on every job. There is no default -- this
|
|
24
|
+
prevents jobs from running indefinitely.
|
|
25
|
+
- Use `jobs validate` to check a spec before `jobs add`.
|
|
26
|
+
- Prefer `delivery_to` with an alias (`@team_room`) over hardcoded chat IDs.
|
|
27
|
+
- Shell jobs (`session_target: "shell"`) run without the gateway. Agent jobs
|
|
28
|
+
(`session_target: "isolated"` or `"main"`) require a running gateway.
|
|
29
|
+
|
|
30
|
+
## Error Handling
|
|
31
|
+
|
|
32
|
+
CLI errors exit non-zero. In plain-text mode, the message goes to stderr. With
|
|
33
|
+
`--json`, the structured error object goes to stdout:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{ "ok": false, "error": "Human-readable error message" }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Successful operations return:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{ "ok": true, "job": { ... } }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Discovery Flow
|
|
46
|
+
|
|
47
|
+
When first interacting with `openclaw-scheduler`, use this sequence:
|
|
48
|
+
|
|
49
|
+
1. `openclaw-scheduler` -- show usage (plain-text help output)
|
|
50
|
+
2. `openclaw-scheduler jobs list --json` -- enumerate existing jobs
|
|
51
|
+
3. `openclaw-scheduler agents list --json` -- see registered agents
|
|
52
|
+
4. `openclaw-scheduler schema jobs` -- get the job field schema
|
|
53
|
+
5. `openclaw-scheduler capabilities --json` -- check runtime feature support
|
|
54
|
+
|
|
55
|
+
## Creating Jobs
|
|
56
|
+
|
|
57
|
+
### Required fields
|
|
58
|
+
|
|
59
|
+
Every job needs at minimum:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"name": "Job Name",
|
|
64
|
+
"schedule_cron": "0 9 * * *",
|
|
65
|
+
"session_target": "shell",
|
|
66
|
+
"payload_kind": "shellCommand",
|
|
67
|
+
"payload_message": "echo hello",
|
|
68
|
+
"run_timeout_ms": 300000,
|
|
69
|
+
"delivery_to": "YOUR_CHAT_ID",
|
|
70
|
+
"origin": "YOUR_CHAT_ID"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
For agent jobs, use `"session_target": "isolated"` and
|
|
75
|
+
`"payload_kind": "systemEvent"`.
|
|
76
|
+
|
|
77
|
+
### One-shot jobs (run once)
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
openclaw-scheduler jobs add '{ ... }' --at '2026-04-01T09:00:00-04:00'
|
|
81
|
+
openclaw-scheduler jobs add '{ ... }' --in '15m'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Workflow chains (parent triggers child)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Parent runs on cron
|
|
88
|
+
openclaw-scheduler jobs add '{ "name": "Collect", "schedule_cron": "0 6 * * *", "run_timeout_ms": 300000, "origin": "system", ... }'
|
|
89
|
+
# Child triggers on parent success
|
|
90
|
+
openclaw-scheduler jobs add '{ "name": "Process", "parent_id": "<PARENT_ID>", "trigger_on": "success", "run_timeout_ms": 300000, "origin": "system", ... }'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Managing Jobs
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
openclaw-scheduler jobs list --json # list all jobs
|
|
97
|
+
openclaw-scheduler jobs get <id> --json # get job details
|
|
98
|
+
openclaw-scheduler jobs update <id> '{ "enabled": 0 }' # disable
|
|
99
|
+
openclaw-scheduler jobs enable <id> # re-enable
|
|
100
|
+
openclaw-scheduler jobs disable <id> # disable
|
|
101
|
+
openclaw-scheduler jobs run <id> # trigger immediate run
|
|
102
|
+
openclaw-scheduler jobs delete <id> # delete job
|
|
103
|
+
openclaw-scheduler jobs cancel <id> # cancel job + children
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Inspecting Runs
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
openclaw-scheduler runs list <job-id> --json # run history
|
|
110
|
+
openclaw-scheduler runs get <run-id> --json # run details
|
|
111
|
+
openclaw-scheduler runs running --json # active runs
|
|
112
|
+
openclaw-scheduler runs output <run-id> # shell output
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Delivery
|
|
116
|
+
|
|
117
|
+
The scheduler delivers job output through the OpenClaw gateway. All channels
|
|
118
|
+
the gateway supports work with the scheduler: Telegram, Discord, WhatsApp,
|
|
119
|
+
Signal, iMessage, and Slack.
|
|
120
|
+
|
|
121
|
+
Set `delivery_channel` and `delivery_to` on the job, or use delivery aliases:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
openclaw-scheduler alias add ops_team telegram -100200000000
|
|
125
|
+
# Then use @ops_team as delivery_to in any job
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Common Patterns
|
|
129
|
+
|
|
130
|
+
### Cron shell job with delivery
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"name": "Daily Backup",
|
|
135
|
+
"schedule_cron": "0 2 * * *",
|
|
136
|
+
"schedule_tz": "America/New_York",
|
|
137
|
+
"session_target": "shell",
|
|
138
|
+
"payload_kind": "shellCommand",
|
|
139
|
+
"payload_message": "backup.sh",
|
|
140
|
+
"run_timeout_ms": 600000,
|
|
141
|
+
"delivery_mode": "announce",
|
|
142
|
+
"delivery_channel": "telegram",
|
|
143
|
+
"delivery_to": "YOUR_CHAT_ID",
|
|
144
|
+
"origin": "system"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Agent task (isolated session)
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"name": "Morning Briefing",
|
|
153
|
+
"schedule_cron": "0 8 * * 1-5",
|
|
154
|
+
"session_target": "isolated",
|
|
155
|
+
"agent_id": "main",
|
|
156
|
+
"payload_kind": "systemEvent",
|
|
157
|
+
"payload_message": "Prepare the morning briefing. Summarize overnight alerts.",
|
|
158
|
+
"run_timeout_ms": 300000,
|
|
159
|
+
"delivery_mode": "announce-always",
|
|
160
|
+
"delivery_channel": "telegram",
|
|
161
|
+
"delivery_to": "YOUR_CHAT_ID",
|
|
162
|
+
"origin": "YOUR_CHAT_ID"
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Retry on failure
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"max_retries": 3
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Approval gate
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"approval_required": true,
|
|
179
|
+
"approval_timeout_s": 3600
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Multi-Agent
|
|
184
|
+
|
|
185
|
+
The scheduler dispatches to specific agents via the `agent_id` field. A single
|
|
186
|
+
scheduler serves all agents through one shared gateway.
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{ "agent_id": "main" }
|
|
190
|
+
{ "agent_id": "ops" }
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Migrating from Built-in Cron/Heartbeat
|
|
194
|
+
|
|
195
|
+
OpenClaw's built-in `cron/jobs.json` and heartbeat work for simple tasks. The
|
|
196
|
+
scheduler replaces them when jobs need run history, retries, chains, approvals,
|
|
197
|
+
or delivery.
|
|
198
|
+
|
|
199
|
+
### Import existing cron jobs
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
openclaw-scheduler migrate # imports from ~/.openclaw/cron/jobs.json
|
|
203
|
+
openclaw-scheduler jobs list # verify imported jobs
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Disable the old cron system
|
|
207
|
+
|
|
208
|
+
After importing, disable the built-in cron so jobs do not run in both systems:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
openclaw cron edit <job-id> --disable # for each job
|
|
212
|
+
openclaw config set cron.enabled false
|
|
213
|
+
openclaw config set agents.defaults.heartbeat.every "0m"
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Heartbeat replacement
|
|
217
|
+
|
|
218
|
+
Replace `heartbeat.every` with a scheduler job:
|
|
219
|
+
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"name": "Gateway Liveness Check",
|
|
223
|
+
"schedule_cron": "*/5 * * * *",
|
|
224
|
+
"session_target": "shell",
|
|
225
|
+
"payload_kind": "shellCommand",
|
|
226
|
+
"payload_message": "curl -sf http://127.0.0.1:18789/health || exit 1",
|
|
227
|
+
"run_timeout_ms": 30000,
|
|
228
|
+
"delivery_mode": "announce",
|
|
229
|
+
"delivery_channel": "telegram",
|
|
230
|
+
"delivery_to": "YOUR_CHAT_ID",
|
|
231
|
+
"origin": "system"
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
See [QUICK-START.md](QUICK-START.md) for detailed migration examples including
|
|
236
|
+
shell crons, agent prompts, and multi-step chains.
|
|
237
|
+
|
|
238
|
+
## Using with agentcli
|
|
239
|
+
|
|
240
|
+
agentcli is the control-plane companion. It provides declarative manifests,
|
|
241
|
+
stable job IDs, workflow chain compilation, and v0.2 identity/authorization
|
|
242
|
+
support. The scheduler works without it, but agentcli is preferred for
|
|
243
|
+
complex workflows.
|
|
244
|
+
|
|
245
|
+
### Installing alongside the scheduler (same time)
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
npm install -g agentcli
|
|
249
|
+
agentcli validate manifest.json
|
|
250
|
+
agentcli apply manifest.json --db ~/.openclaw/scheduler/scheduler.db --dry-run
|
|
251
|
+
agentcli apply manifest.json --db ~/.openclaw/scheduler/scheduler.db
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Jobs created via `agentcli apply` use stable IDs (SHA256 of workflow:task) and
|
|
255
|
+
can be updated by re-applying the same manifest.
|
|
256
|
+
|
|
257
|
+
### Adding agentcli later (adopting existing jobs)
|
|
258
|
+
|
|
259
|
+
If the scheduler already has jobs created directly via CLI or by the agent,
|
|
260
|
+
agentcli can adopt them:
|
|
261
|
+
|
|
262
|
+
1. Write a manifest with task names matching the existing job names.
|
|
263
|
+
|
|
264
|
+
2. Run a one-time adoption by name:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
agentcli apply manifest.json \
|
|
268
|
+
--db ~/.openclaw/scheduler/scheduler.db \
|
|
269
|
+
--adopt-by name --dry-run # preview first
|
|
270
|
+
|
|
271
|
+
agentcli apply manifest.json \
|
|
272
|
+
--db ~/.openclaw/scheduler/scheduler.db \
|
|
273
|
+
--adopt-by name # execute adoption
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
This replaces each matched job with a stable-ID version. The old job is
|
|
277
|
+
deleted after the new one is created.
|
|
278
|
+
|
|
279
|
+
3. On subsequent applies, use the default (no `--adopt-by` flag):
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
agentcli apply manifest.json --db ~/.openclaw/scheduler/scheduler.db
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Jobs are now matched by stable ID, so the manifest can be renamed or
|
|
286
|
+
reorganized without losing job mapping.
|
|
287
|
+
|
|
288
|
+
### Full migration path: OOB cron -> scheduler -> agentcli
|
|
289
|
+
|
|
290
|
+
1. Import OOB cron jobs: `openclaw-scheduler migrate`
|
|
291
|
+
2. Disable built-in cron (see "Migrating from Built-in Cron" above)
|
|
292
|
+
3. Verify jobs run correctly in the scheduler
|
|
293
|
+
4. Install agentcli: `npm install -g agentcli`
|
|
294
|
+
5. Write a manifest covering the imported jobs
|
|
295
|
+
6. Adopt by name: `agentcli apply manifest.json --adopt-by name`
|
|
296
|
+
7. Future updates: `agentcli apply manifest.json` (stable IDs)
|
|
297
|
+
|
|
298
|
+
See the
|
|
299
|
+
[agentcli AGENTS.md](https://github.com/amittell/agentcli/blob/main/AGENTS.md)
|
|
300
|
+
for agentcli-specific agent instructions and the
|
|
301
|
+
[MANIFEST-QUICK-REF.md](https://github.com/amittell/agentcli/blob/main/MANIFEST-QUICK-REF.md)
|
|
302
|
+
for copy-paste manifest patterns.
|