CLI reference: sparkwing crons

CLI reference: sparkwing crons

Every sparkwing crons command, flag, and argument, generated from the CLI's own command registry. All command groups are indexed in cli-reference.md.

sparkwing cronsSection anchor link

Arm, inspect and drive this host's local pipeline schedules

Runs the pipelines that declare an on.schedule cadence in their .sparkwing/sparkwing.yaml, on this machine, from this home's runs store.

Declaring a cadence does not arm it. sparkwing crons install arms a repo's schedules on the host it is run from, and installs one OS timer -- a systemd user timer on Linux, a launchd agent on macOS -- that calls sparkwing crons tick every minute. Sparkwing evaluates every cron expression itself inside that tick, so the machine holds one timer however many schedules are armed.

Each tick resolves every due instant exactly once: it launches the run, skips it when the previous scheduled run is still going and the policy is skip, or records it missed when it fell outside the catch-up window. A scheduled run carries the trigger source "schedule" and executes through the same detached path as sparkwing run --sw-detached.

Arming pins by default: install compiles the pipeline and keeps that binary, so a checkout updated afterwards does not change what runs unattended. Re-run install to move the pin, crons unlock to follow the checkout again, and crons set to override a declared cadence on this host alone.

--profile NAME points every verb but tick, lock and unlock at a controller instead of this host. crons install --profile pushes the repo's where: controller entries to it, pinned at HEAD unless --follow; the controller evaluates them from a loop of its own, one evaluator per store, and each fire becomes a trigger the cluster clones and runs.

SubcommandsSection anchor link

  • install -- Arm a repo's declared schedules on this host and install the OS timer
  • uninstall -- Disarm a repo's schedules, and remove the timer when nothing is left
  • disarm -- Remove one schedule from this host
  • lock -- Pin one schedule to the checkout as it stands
  • unlock -- Let one schedule follow the checkout again
  • set -- Override a declared cadence on this host
  • reset -- Drop this host's override of a schedule
  • status -- Report the OS timer, the last tick, and what is armed here
  • list -- List the schedules armed on this host
  • show -- Show one schedule's full record and its recent fires
  • next -- Show the instants a schedule fires next
  • pause -- Stop a schedule firing, keeping it armed
  • resume -- Let a paused schedule fire again
  • run -- Launch a schedule's pipeline now
  • tick -- Evaluate every armed schedule once (the OS timer's entry point)

ExamplesSection anchor link

# Arm this repo's schedules on this host
sparkwing crons install

# See what is armed and when it next fires
sparkwing crons list

# Check the timer and the last tick
sparkwing crons status

# Push this repo's controller schedules
sparkwing crons install --profile prod

sparkwing crons disarmSection anchor link

Remove one schedule from this host

Deletes one schedule, its fire history and its pinned pipeline binary. Every other schedule of the same pipeline and repo stays armed.

To stop a schedule without losing its history, pause it instead.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Remove one named entry
sparkwing crons disarm sweep/quick

sparkwing crons installSection anchor link

Arm a repo's declared schedules on this host and install the OS timer

Reads .sparkwing/sparkwing.yaml, records every on.schedule entry that declares "where: local" against this home, and ensures the OS timer that runs the tick. An entry declaring "where: controller" is reported and left alone: this host does not fire it.

Each pipeline is compiled first and has to appear in the binary's own description, because a schedule fires unattended: a pipeline that will not build is refused here before unattended execution. That compile is also the pin: the binary is copied under the sparkwing home and recorded with the checkout's HEAD, so every fire runs what was armed however the checkout moves afterwards. --follow arms without a pin, and each fire compiles the checkout. --no-prove skips the compile, and so pins nothing.

--only arms a subset, naming pipelines or pipeline/name entries; a name the repo does not declare is refused before anything is written.

A repo that declares no schedule is reported as nothing to arm and installs no timer. Re-running install is the explicit update: it re-pins at the current checkout, republishes what the repo declares, marks a pipeline that stopped declaring a cadence undeclared, and re-bases this host's overrides onto the new declaration. Pause state, cursor, fire history and the override values survive.

Arming is per host. Another machine runs the same schedule only when the schedule is also armed on that machine.

--profile NAME pushes the repo's "where: controller" entries to that controller instead, and reports the "where: local" ones as this host's. The push needs a git origin, because the cluster clones the source at each fire; it pins every fire to the checkout's HEAD unless --follow, which clones the branch tip. A HEAD no remote branch carries is refused, because every fire would fail at the clone; uncommitted edits are a warning, since the pushed commit is what runs. Re-running the push is the explicit update, and it moves the pin.

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
--repo DIRRepo directory (default: discovered via nearest .sparkwing/)
--fleetArm every registered repo instead of one
--only NAMESArm only these pipelines or pipeline/name entries (comma-separated or repeatable)
--followArm without pinning, so every fire compiles the checkout
--no-proveArm without compiling the pipelines first, which pins nothing
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Arm the current repo
sparkwing crons install

# Arm a different repo
sparkwing crons install --repo /path/to/repo

# Arm two entries only
sparkwing crons install --only nightly,sweep/quick

# Arm without pinning
sparkwing crons install --follow

# Arm every registered repo
sparkwing crons install --fleet

# Push the controller entries to a cluster
sparkwing crons install --profile prod

# Push them following the branch tip
sparkwing crons install --profile prod --follow

sparkwing crons listSection anchor link

List the schedules armed on this host

One row per schedule: its id, its repo/pipeline name, the cron expression and zone it is read in, when it next fires, when it last fired, that fire's outcome, and whether it is armed, paused, or undeclared.

Schedules the repo no longer declares are hidden behind a count; --all shows them. They keep their history and never fire.

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
--allInclude schedules the repo no longer declares
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# What is armed here
sparkwing crons list

# Include withdrawn schedules
sparkwing crons list --all

# What a controller evaluates
sparkwing crons list --profile prod

# Machine-readable (NDJSON)
sparkwing crons list -o json

sparkwing crons lockSection anchor link

Pin one schedule to the checkout as it stands

Compiles the pipeline, keeps that binary under the sparkwing home, and records the checkout's HEAD against the schedule. Every later fire runs that binary, so editing or updating the checkout does not change what an unattended run executes.

The pin covers the pipeline the repo declares. Scripts and binaries the pipeline runs from the checkout or from PATH are outside it.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Pin a schedule at HEAD
sparkwing crons lock nightly

sparkwing crons nextSection anchor link

Show the instants a schedule fires next

Shows upcoming times in each schedule's configured time zone. Supply a schedule name to inspect one expression; omit it to merge upcoming times from every armed schedule.

ArgumentsSection anchor link

  • NAME (optional) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name; omit for every armed schedule

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
--count NHow many instants to show (default: 5)
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# What fires next on this host
sparkwing crons next

# Check one expression
sparkwing crons next fictional-nightly --count 10

sparkwing crons pauseSection anchor link

Stop a schedule firing, keeping it armed

A paused schedule still advances its cursor on every tick, so resuming it fires the next due instant instead of replaying the ones that passed while it was paused.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Pause a schedule
sparkwing crons pause fictional-nightly

sparkwing crons resetSection anchor link

Drop this host's override of a schedule

Returns the schedule to what the repo declares. The pin, the pause state, the cursor and the fire history are untouched.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Run what the repo declares
sparkwing crons reset nightly

sparkwing crons resumeSection anchor link

Let a paused schedule fire again

Resumes at the next due instant. The instants that passed while the schedule was paused are behind its cursor and do not run.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Resume a schedule
sparkwing crons resume fictional-nightly

sparkwing crons runSection anchor link

Launch a schedule's pipeline now

Runs the pipeline immediately, whatever the cadence says and whether or not the schedule is paused, and records the launch in the schedule's history as a manual fire.

The cursor does not move: a manual run is not one of the cadence's due instants, so the next one still fires on time.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Run a schedule's pipeline now
sparkwing crons run fictional-nightly

sparkwing crons setSection anchor link

Override a declared cadence on this host

Lays this host's own value over what the repo declares, for the cron expression, the zone, the overlap policy, the catch-up window and the launch's arguments. Everything left unnamed keeps the declared value, and a field named again replaces the previous override.

--arg replaces the declared argument set whole, so name every argument the schedule should launch with.

The override survives re-arming; sparkwing crons reset drops it. sparkwing crons list marks an overridden expression with *, and sparkwing crons show prints the declared, override and effective value side by side.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
--cron EXPRCron expression to run instead of the declared one
--tz ZONEZone the expression is read in, such as America/Denver or local
--overlap POLICYWhat a due instant does while the previous run is going: skip|queue
--catch-up DURHow late a due instant may still fire, such as 6h
--arg K=VArgument the launch passes (repeatable; replaces the declared set)
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Run it later on this host
sparkwing crons set nightly --cron '0 5 * * *'

# Read the expression locally
sparkwing crons set nightly --tz local

# Launch with arguments
sparkwing crons set sweep/quick --arg depth=shallow --arg dry-run=true

sparkwing crons showSection anchor link

Show one schedule's full record and its recent fires

Prints every stored field with absolute times, then the instants that have resolved, newest first: when each was due, when the tick decided it, what it decided, the run it launched and that run's current status, and the reason for any outcome that is not a launch.

NAME is a schedule id, a repo/pipeline name, or a bare pipeline name that is unique across this host's schedules.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
--fires NHow many recent fires to show (default: 10)
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Inspect one schedule
sparkwing crons show fictional-nightly

# Read further back
sparkwing crons show fictional-nightly --fires 50

sparkwing crons statusSection anchor link

Report the OS timer, the last tick, and what is armed here

Answers whether this host is actually evaluating what it armed: whether the timer is installed and running, whether it runs this sparkwing or one that has since moved, when the tick last landed and what it reported, and how many schedules are armed, paused, and undeclared.

Exits non-zero when schedules are armed and the timer is not running, runs another binary, or has not ticked in the last few minutes, so a check script can read the exit code. A host with nothing armed is healthy.

--profile NAME reads a controller's scheduler instead: its counts, when its loop last ticked, and what that tick reported.

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Read the host's scheduler health
sparkwing crons status

# Machine-readable
sparkwing crons status -o json

# Read a controller's scheduler
sparkwing crons status --profile prod

sparkwing crons tickSection anchor link

Evaluate every armed schedule once (the OS timer's entry point)

What the systemd timer or launchd agent runs every minute. It takes an exclusive lock so two ticks never resolve the same instant, re-reads the declaration of every schedule that follows its checkout -- a pinned schedule keeps the declaration it was armed with -- evaluates every declared unpaused schedule against its cursor, launches what is due, and records each outcome.

Quiet on success: one summary line and the id of each run it launched. It exits non-zero only when the tick itself could not run, so a schedule that fails to launch is recorded against that schedule and the timer stays green.

--dry-run prints what this minute would resolve and writes nothing.

Run it by hand on a host whose platform has no sparkwing timer, from that machine's own scheduler, once a minute.

FlagsSection anchor link

FlagDescription
--dry-runEvaluate and report without launching or recording anything
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Evaluate every armed schedule once
sparkwing crons tick

# See what this minute would do
sparkwing crons tick --dry-run

sparkwing crons uninstallSection anchor link

Disarm a repo's schedules, and remove the timer when nothing is left

Deletes every schedule of one checkout, and its fire history, from this home. When no schedule remains armed anywhere, the OS timer goes too: the timer exists to serve armed schedules and nothing else.

--fleet disarms every schedule this home holds.

--profile NAME deletes the repo's schedules from that controller instead, naming the repo by its git origin.

FlagsSection anchor link

FlagDescription
--profile NAMEProfile name; omit for this host
--repo DIRRepo directory (default: discovered via nearest .sparkwing/)
--fleetDisarm every schedule this home holds
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Disarm the current repo
sparkwing crons uninstall

# Disarm everything on this host
sparkwing crons uninstall --fleet

# Remove this repo from a controller
sparkwing crons uninstall --profile prod

sparkwing crons unlockSection anchor link

Let one schedule follow the checkout again

Drops the pin and the pinned binary, so every later fire compiles the checkout as it stands at that minute, and the tick's refresh reads the repo's declaration again.

ArgumentsSection anchor link

  • NAME (required) -- Schedule id, repo/pipeline[/name], pipeline/name, or a unique pipeline name

FlagsSection anchor link

FlagDescription
-o, --output FMTOutput format: pretty|json|plain

ExamplesSection anchor link

# Follow the checkout again
sparkwing crons unlock nightly