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.
Files changed (70) hide show
  1. package/AGENTS.md +302 -0
  2. package/BEST-PRACTICES.md +506 -0
  3. package/CHANGELOG.md +82 -0
  4. package/CODE_OF_CONDUCT.md +22 -0
  5. package/CONTEXT.md +26 -0
  6. package/CONTRIBUTING.md +73 -0
  7. package/IMPLEMENTATION_SPEC.md +170 -0
  8. package/INSTALL-ADDITIONAL-HOST.md +333 -0
  9. package/INSTALL-LINUX.md +419 -0
  10. package/INSTALL-WINDOWS.md +305 -0
  11. package/INSTALL.md +364 -0
  12. package/JOB-QUICK-REF.md +222 -0
  13. package/LICENSE +21 -0
  14. package/QUICK-START.md +256 -0
  15. package/README.md +2170 -0
  16. package/SECURITY.md +34 -0
  17. package/UNINSTALL.md +129 -0
  18. package/UPGRADING.md +436 -0
  19. package/agents.js +67 -0
  20. package/approval.js +107 -0
  21. package/backup.js +390 -0
  22. package/bin/openclaw-scheduler.js +138 -0
  23. package/cli.js +1083 -0
  24. package/db.js +122 -0
  25. package/dispatch/529-recovery.mjs +204 -0
  26. package/dispatch/README.md +372 -0
  27. package/dispatch/config.example.json +24 -0
  28. package/dispatch/deliver-watcher.sh +57 -0
  29. package/dispatch/hooks.mjs +171 -0
  30. package/dispatch/index.mjs +1836 -0
  31. package/dispatch/watcher.mjs +1396 -0
  32. package/dispatch-queue.js +112 -0
  33. package/dispatcher-approvals.js +96 -0
  34. package/dispatcher-delivery.js +43 -0
  35. package/dispatcher-maintenance.js +242 -0
  36. package/dispatcher-shell.js +29 -0
  37. package/dispatcher-strategies.js +1280 -0
  38. package/dispatcher-utils.js +81 -0
  39. package/dispatcher.js +855 -0
  40. package/docs/adr-schedule-ownership.md +73 -0
  41. package/docs/gateway-contract.md +904 -0
  42. package/docs/plans/2026-03-09-fix-typescript-types.md +91 -0
  43. package/docs/plans/2026-03-09-test-coverage-gaps.md +83 -0
  44. package/docs/plans/2026-03-10-dispatcher-refactor.md +801 -0
  45. package/docs/trust-architecture.md +266 -0
  46. package/gateway.js +473 -0
  47. package/idempotency.js +119 -0
  48. package/index.d.ts +864 -0
  49. package/index.js +17 -0
  50. package/jobs.js +1224 -0
  51. package/messages.js +357 -0
  52. package/migrate-consolidate.js +694 -0
  53. package/migrate.js +125 -0
  54. package/package.json +130 -0
  55. package/paths.js +79 -0
  56. package/prompt-context.js +94 -0
  57. package/retrieval.js +176 -0
  58. package/runs.js +270 -0
  59. package/scheduler-schema.js +101 -0
  60. package/schema.sql +480 -0
  61. package/scripts/dispatch-cli-utils.mjs +65 -0
  62. package/scripts/inbox-consumer.mjs +288 -0
  63. package/scripts/stuck-detector.sh +18 -0
  64. package/scripts/stuck-run-detector.mjs +333 -0
  65. package/scripts/telegram-webhook-check.mjs +238 -0
  66. package/setup.mjs +724 -0
  67. package/shell-result.js +214 -0
  68. package/task-tracker.js +300 -0
  69. package/team-adapter.js +335 -0
  70. 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.