cron.*
Scheduled job management RPC methods
cron.* manages jobs that trigger agent prompts on a schedule. Jobs are persisted by CronService (src/tasks/cron/) in SQLite; the state-machine scheduler replaced the historical window-based scheduler.
Methods
| Method | Description |
|---|---|
cron.list | List every job |
cron.get | Fetch one job's full view |
cron.create | Create a job |
cron.update | Mutate job fields |
cron.delete | Delete a job |
cron.status | Service-wide status (running flag + job count) |
cron.run | Trigger a job immediately (bypass schedule) |
cron.runs | Read execution history |
cron.toggle | Enable / disable a job |
Historical aliases
cron.trigger/cron.pause/cron.resumehave been folded intocron.runandcron.toggle; no separate pause / resume RPCs are registered.
Schedule Kinds (schedule_kind)
cron.create and cron.update accept schedule_kind as a tagged enum; the legacy "schedule": "<expr>" field is honoured as a fallback for cron expressions.
| Kind | Fields | Description |
|---|---|---|
{ "kind": "cron", "expr": "...", "tz": "...", "stagger_ms": 0 } | expr (required) | Standard 5-field cron expression |
{ "kind": "every", "every_ms": 900000 } | every_ms | Fixed interval in milliseconds |
{ "kind": "at", "at": 1706468400000 } | at (required, future) | One-shot at the given epoch-ms |
at jobs that point to a past timestamp are rejected at create time with -32602 Invalid params.
cron.list
List every configured job.
Request:
{ "jsonrpc": "2.0", "id": 1, "method": "cron.list", "params": { "limit": 50 } }Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"jobs": [
{
"id": "job-uuid-123",
"name": "Daily Summary",
"schedule_kind": { "kind": "cron", "expr": "0 18 * * *", "tz": "America/New_York" },
"agent_id": "main",
"enabled": true,
"next_run_at_ms": 1706468400000,
"last_run_at_ms": 1706382000000,
"tags": ["productivity"]
}
]
}
}Parameter: limit (number, optional; default 50).
cron.get
Read the full view of one job.
Request:
{ "jsonrpc": "2.0", "id": 2, "method": "cron.get", "params": { "job_id": "job-uuid-123" } }Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"job": {
"id": "job-uuid-123",
"name": "Daily Summary",
"agent_id": "main",
"prompt": "Summarize today's activities",
"enabled": true,
"schedule_kind": { "kind": "cron", "expr": "0 18 * * *" },
"tags": ["productivity"],
"session_target": "ephemeral",
"timeout_ms": 600000,
"next_run_at_ms": 1706468400000,
"last_run_at_ms": 1706382000000
}
}
}cron.create
Create a job. Required: name. Defaults: agent_id="main", prompt="". Provide either schedule_kind or the fallback "schedule" (cron expression only).
Request:
{
"jsonrpc": "2.0",
"id": 3,
"method": "cron.create",
"params": {
"name": "Daily Summary",
"schedule_kind": { "kind": "cron", "expr": "0 18 * * *", "tz": "America/New_York" },
"agent_id": "main",
"prompt": "Summarize today's activities",
"enabled": true,
"tags": ["productivity", "daily"],
"timezone": "America/New_York",
"timeout_ms": 600000,
"session_target": "ephemeral"
}
}Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"job": {
"id": "job-uuid-123",
"name": "Daily Summary",
"enabled": true,
"schedule_kind": { "kind": "cron", "expr": "0 18 * * *", "tz": "America/New_York" }
}
}
}Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Job name |
schedule_kind | object | Yes* | Tagged schedule enum (cron / every / at) |
schedule | string | No | Cron expression, used only when schedule_kind is absent |
agent_id | string | No | Default "main" |
prompt | string | No | Default empty string |
enabled | boolean | No | Default true |
tags | string[] | No | Job tags |
timezone | string | No | IANA timezone (cron schedules only) |
timeout_ms | number | No | Positive integer in ms; null keeps the default |
session_target | object | No | Session target (main / ephemeral / ...) |
cron.update
Mutate job fields. timeout_ms is tri-state: absent = no-op, null = clear, positive integer = set. Negative / zero / non-integer values are rejected to avoid silent no-ops.
Request:
{
"jsonrpc": "2.0",
"id": 4,
"method": "cron.update",
"params": {
"job_id": "job-uuid-123",
"enabled": false,
"prompt": "New prompt text",
"schedule_kind": { "kind": "every", "every_ms": 900000 },
"timeout_ms": 900000
}
}Response:
{ "jsonrpc": "2.0", "id": 4, "result": { "job": { "id": "job-uuid-123", "enabled": false } } }cron.delete
Delete a job.
Request:
{ "jsonrpc": "2.0", "id": 5, "method": "cron.delete", "params": { "job_id": "job-uuid-123" } }Response:
{ "jsonrpc": "2.0", "id": 5, "result": { "deleted": "job-uuid-123" } }cron.status
Service-wide status (not per-job).
Response:
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"running": true,
"job_count": 7,
"enabled_count": 5
}
}cron.run
Trigger a job immediately (bypass the schedule). Delegates to CronService::run_job, which validates (enabled + not already running), propagates a failed persist as an error rather than swallowing it (so a "success" reply always implies the job really ran), and emits a cron.job.changed event.
Request:
{ "jsonrpc": "2.0", "id": 7, "method": "cron.run", "params": { "job_id": "job-uuid-123" } }Response:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"triggered": "job-uuid-123",
"status": "queued",
"next_run_at_ms": 1706400000000
}
}cron.runs
Read the execution history (from the SQLite persistence layer).
Request:
{ "jsonrpc": "2.0", "id": 8, "method": "cron.runs", "params": { "job_id": "job-uuid-123", "limit": 20 } }Response:
{
"jsonrpc": "2.0",
"id": 8,
"result": {
"runs": [
{
"run_id": "run-uuid-001",
"started_at_ms": 1706382000000,
"ended_at_ms": 1706382015000,
"duration_ms": 15000,
"status": "completed",
"trigger_source": "schedule"
}
]
}
}Parameters: job_id (required), limit (optional, default 20).
cron.toggle
Flip the enabled flag.
Request:
{ "jsonrpc": "2.0", "id": 9, "method": "cron.toggle", "params": { "job_id": "job-uuid-123" } }Response:
{ "jsonrpc": "2.0", "id": 9, "result": { "job": { "id": "job-uuid-123", "enabled": true } } }Run Status Values
| Status | Description |
|---|---|
queued | Queued for execution |
running | Currently executing |
completed | Finished successfully |
failed | Execution failed |
retrying | Failed; retrying |
Events
The scheduler emits a cron.job.changed event on the bus whenever a job's state changes; the panel subscribes to keep its view live.
See Also
- agent.* -- Agent execution (triggered by cron)
- events.* -- Subscribe to scheduler events
- Methods Reference -- All method namespaces
- heartbeat.* -- Heartbeat probe tasks