TypeClawTypeClaw
Reference

cron.json

Scheduled job schema

Lives at the agent folder root. Reloads live via typeclaw reload.

{
  "$schema": "./node_modules/typeclaw/cron.schema.json",
  "jobs": [
    {
      "id": "morning-status",
      "schedule": "0 9 * * *",
      "kind": "prompt",
      "prompt": "Summarize yesterday's commits and post to #standup",
      "scheduledByRole": "owner"
    },
    {
      "id": "backup-db",
      "schedule": "0 3 * * *",
      "kind": "exec",
      "command": ["/agent/scripts/backup.sh"],
      "scheduledByRole": "owner"
    }
  ]
}

Common fields

FieldTypeRequiredNotes
idstringyes[a-zA-Z0-9_-]+, unique within the file
schedulestringyesstandard 5-field cron expression (no seconds)
kind"prompt" | "exec"yesdispatcher selector
scheduledByRolerole name (string)yesrole the firing session resolves as; required — rejected with an error if missing
enabledbooleannodefaults to true; set false to keep the entry but skip firing
timezoneIANA tz name (string)nodefaults to container TZ env (UTC if unset)

kind: "prompt"

FieldTypeNotes
promptstringrequired; the prompt text fed into the new session
subagentstring (name)optional; if set, spawns the named subagent instead of a top-level session, with payload { prompt } (or however the subagent's payloadSchema accepts it)

kind: "exec"

FieldTypeNotes
commandstring[]argv array; not a shell string. Use ["sh", "-c", "…"] if you need shell features

Per-job coalescing

If a job is still running when its next tick fires, the next tick is dropped for that specific job (and logged), not queued. Other jobs are unaffected.

The scheduler is a pure clock — it just emits "this job's time has come" events. The consumer owns the per-id in-flight set.

Limits

  • kind is limited to "prompt" and "exec". Adding a third requires extending the consumer.
  • Scheduling expressions use cron-parser syntax (standard 5-field cron). Sub-minute precision is not supported.

Missing scheduledByRole

A job missing scheduledByRole is a hard error — parseCronFile rejects the file on load. Add "scheduledByRole": "owner" (or the appropriate role) to every job before running typeclaw reload.

On this page