schedule:list

php mitosis schedule:list
✓ sessions:prune  15 3 * * *    ran at 2026-08-31 03:15:00 in 41ms
ℹ inbox:poll      */10 * * * *  running since 2026-08-31 03:20:00
✗ reports:build   0 4 * * MON   failed at 2026-08-25 04:00:00 — The process running this job stopped without reporting an outcome, and a later tick reaped it.

Requires Clarity 1.5.0 or newer. One line per registered job, in registration order: its name, its cron expression, and how its last run went. It reads the schedule from app/routes/cli.php the same way every other command does, so this is the answer to "what is this application actually scheduled to do?" without reading code.

--context selects a database connection, as everywhere else.

The four things the last column says

  • never run — registered, but no run record exists yet.
  • ran at 2026-08-31 03:15:00 in 41ms — completed, with how long it took.
  • failed at 2026-08-25 04:00:00 — … — failed, with the reason. A long exception message is collapsed to one line and cut with an ellipsis, so one bad message cannot take the table's alignment with it.
  • running since 2026-08-31 03:20:00 — still in flight, or its process died and no later tick has reaped it yet.

The moment shown is always started_at: a run in flight has no finish time, so that is the one column every row can share.

There is deliberately no "next due" column. Scheduler's expression parser has no next-occurrence search — the runner only ever asks whether the minute it is standing in matches — and a column that would have to guess is worse than one that is absent.

It always prints, and always exits 0

The opposite of schedule:run, and for the same reason that command is silent. schedule:run sits on a crontab where every line becomes a mail; this one is only ever typed by a person who has just asked a question, and an answer of nothing at all is no answer.

A job that failed at 04:00 is a fact this report exists to state clearly, not a failure of the reporting — so the exit code stays 0 in every case. With nothing registered at all:

ℹ No scheduled jobs are registered. Register them in app/routes/cli.php with Scheduler::job().

It still works before schedule:install

Expressions come from the registry and need no database, so a missing scheduled_runs table costs you the third column and nothing else. The schedule is still real, and still worth showing:

ℹ Run history is unavailable: the `scheduled_runs` table does not exist yet, so the last column is blank. The schedule itself is real — run `php mitosis schedule:install` once to start recording what becomes of it.
ℹ sessions:prune  15 3 * * *
ℹ inbox:poll      */10 * * * *

schedule:run is the one that fails loudly on a missing table, because a heartbeat that cannot claim a slot has nothing left to do.

Next steps

  • Scheduler — registering jobs and reading their expressions.
  • schedule:install — the table that fills in the last column.
  • schedule:run — the heartbeat that writes the run records.