Skip to content
MagicFrog
Menu

Triggers

Scheduled runs and event watchers — both tied to an explicit target and visible in one overview.

Triggers make MagicFrog act without a human turn: a cron trigger fires a scheduled action, and a watcher loops a small script that decides whether something interesting happened. Both kinds share one overview, and both refuse to guess where they run.

Scheduled triggers (cron)

A scheduled trigger carries its identity, a schedule, and an action:

Field Meaning
triggerId Stable identity of the trigger
kind cron
schedule Non-empty schedule expression
intervalMinutes Integer; the minimum is 30 minutes, anything below is rejected
targetComputerId The computer the action runs on — required for cron
ownerTaskId Optional: the task the trigger belongs to
action What to run (type plus optional parameters)

Two contracts make schedules trustworthy:

  • Fail-closed targeting. A cron trigger without targetComputerId is rejected at registration and re-checked at every execution. It never runs against the local machine and is never silently re-targeted.
  • No catch-up replay. If a fire is missed while the service is down or a run overruns, the trigger fires normally at the next cycle — the missed fire is skipped, never replayed.

Every execution outcome is recorded: ok, error, or rejected.

Watchers

A watcher is a bun script authored by you or by an agent, run on a loop against one target.

Field Meaning
watcherId Stable identity of the watcher
scriptPath Path to the bun script
targetKind task or agent
targetId The task or agent being watched
interval Loop cadence in seconds (the 30-minute floor is a cron contract, not a watch-loop contract)
ownerAgentId Optional: the agent that owns the watch
status stopped, running, or failed

The script contract

Each iteration receives its target context on stdin as JSON:

{
  "watcherId": "wat_...",
  "targetKind": "agent",
  "targetId": "...",
  "now": 1792000000000,
  "artifactsDir": ".../watchers/wat_.../",
  "events": [],
  "eventCursor": 0
}

The script answers with a single JSON finding line on stdout:

{ "matched": true, "summary": "Build failed twice in a row", "data": { "runId": "run_..." } }

What counts as "matched" is entirely the script's decision. A script exiting non-zero counts as a failed run and the watcher keeps running; failed status means the script itself could not start, for example an unreadable file.

Every watcher gets its own artifact directory, used as the child's working directory and exposed as MAGICFROG_WATCHER_ARTIFACT_DIR, so script-produced files can never collide across watchers or leak into the workspace.

Targets

  • agent — the loop reads the cloud agent's events: run.started, tool.called, tool.result, form.pending, form.answered, and takeover.requested. After a disconnect it resumes from where it left off instead of starting over.
  • task — the loop reads a snapshot of task status. If task status cannot be read, starting the watcher fails explicitly — a fabricated status is never presented.

Watchers run on your machine. A watcher can watch a remote cloud agent's events without the watcher itself moving anywhere.

One overview

GET /v1/triggers/overview is one account-scoped read listing every task's cron triggers and watchers, each with its status and next due time. The console and the local command show the same state.