blowhorn schedule

blowhorn schedule: bootstrap, delete, get, list, pause, resume, status, tick, trigger-now, upsert, validate, why.

The blowhorn schedule commands. Each one's --help prints the same text.

Command What it does
schedule bootstrap Preview or write a validated schedule starter set.
schedule delete Delete a scheduled action by number.
schedule get Return a single scheduled action with all fields.
schedule list List scheduled actions and whether they are currently due.
schedule pause Pause all scheduled processing: every tick keeps running but claims no rows until 'blowhorn schedule resume', and due times carry forward.
schedule resume Resume scheduled processing after 'blowhorn schedule pause'; rows that fell due meanwhile run once, on the next tick.
schedule status Show whether processing is paused, the last tick's heartbeat, the estimated next tick, today's tick counts from the run ledger, and the scheduler LaunchAgent state.
schedule tick Run one scheduler polling pass against due scheduled actions, executing each through the same command routing the CLI uses and writing a per-job log under <log-dir>/scheduler/.
schedule trigger-now Force a specific scheduled action to run immediately.
schedule upsert Create or update a scheduled action from a JSON payload.
schedule validate Validate the schedule's actions against the supported schema.
schedule why Explain why a scheduled row has or has not run on this machine, in the order the scheduler decides it.

blowhorn schedule bootstrap

Preview or write a validated schedule starter set.

output
blowhorn schedule bootstrap [OPTIONS]
Flag Type Default Description
--replace boolean false Replace the current scheduled actions before writing sample ones
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule bootstrap' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule bootstrap --dry-run
blowhorn schedule bootstrap
blowhorn schedule bootstrap --replace

Output: json with --json, text otherwise.

blowhorn schedule delete

Delete a scheduled action by number.

output
blowhorn schedule delete [OPTIONS] row
Argument Required Description
row yes Row number to delete
Flag Type Default Description
--expected-fingerprint string Reject the delete if the current row fingerprint no longer matches
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule delete' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule delete 7 --json
blowhorn schedule delete 7 --expected-fingerprint 3f2a1c

Output: json with --json, text otherwise.

blowhorn schedule get

Return a single scheduled action with all fields.

output
blowhorn schedule get [OPTIONS] row
Argument Required Description
row yes Row number to inspect
Flag Type Default Description
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule get' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule get 7 --json
blowhorn schedule get 7

Output: json with --json, text otherwise.

blowhorn schedule list

List scheduled actions and whether they are currently due. With several machines sharing the store the Locked By column names the holder and marks this machine's own claims; a paused action reads paused: yes beside its due state, because due keeps meaning its time has passed.

output
blowhorn schedule list [OPTIONS]
Flag Type Default Description
--due-only boolean false Show only rows that are currently due
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule list' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule list --due-only --profile all
blowhorn schedule list --profile all
blowhorn schedule list --json

Output: json with --json, text otherwise.

blowhorn schedule pause

Pause all scheduled processing: every tick keeps running but claims no rows until 'blowhorn schedule resume', and due times carry forward. A job already running finishes first. Pausing has three scopes and a row is claimed only when none of them says paused: without a flag it is this machine only (a local file, never the store), --all is every machine sharing the store, and --row N is one scheduled row on every machine.

output
blowhorn schedule pause [OPTIONS]
Flag Type Default Description
--reason string Short note stored with the pause and shown by 'blowhorn schedule status'
--all boolean false Pause every machine sharing this store, not just this one: no machine claims a row until 'blowhorn schedule resume --all'. Recorded in the store with who paused it and why, so every machine reports the same reason. Without this flag the pause is this machine only
--row integer Pause one scheduled row instead of a whole machine: that job is claimed by nobody until 'blowhorn schedule resume --row N', and every other row keeps running everywhere. Distinct from setting the row's Enabled to no, which is an editorial state with no reason and no intent to resume
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule pause' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule pause
blowhorn schedule pause --all --reason "LinkedIn challenge on kate"
blowhorn schedule pause --row 7
blowhorn schedule pause --reason "LinkedIn challenge on kate" --json

Output: json with --json, text otherwise.

blowhorn schedule resume

Resume scheduled processing after 'blowhorn schedule pause'; rows that fell due meanwhile run once, on the next tick. The same three scopes: without a flag this machine's own pause is lifted, --all lifts the pause every machine sharing the store honours, and --row N lifts one paused action. Lifting one scope leaves the other two as they were.

output
blowhorn schedule resume [OPTIONS]
Flag Type Default Description
--all boolean false Lift the pause every machine sharing this store honours, the one 'blowhorn schedule pause --all' set. This machine's own pause and any paused action stay as they are
--row integer Let one held scheduled row be claimed again, on every machine, the one 'blowhorn schedule pause --row N' held. Every other scope stays as it is
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule resume' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule resume
blowhorn schedule resume --all
blowhorn schedule resume --row 7
blowhorn schedule resume --json

Output: json with --json, text otherwise.

blowhorn schedule status

Show whether processing is paused, the last tick's heartbeat, the estimated next tick, today's tick counts from the run ledger, and the scheduler LaunchAgent state.

output
blowhorn schedule status [OPTIONS]
Flag Type Default Description
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule status' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule status
blowhorn schedule status --json

Output: json with --json, text otherwise.

blowhorn schedule tick

Run one scheduler polling pass against due scheduled actions, executing each through the same command routing the CLI uses and writing a per-job log under <log-dir>/scheduler/. While 'blowhorn schedule pause' is in effect the pass claims nothing unless --ignore-pause is passed; a real pass also records its heartbeat in <log-dir>/scheduler/last-tick.json and appends one tick record to the run ledger, <log-dir>/runs/<YYYY-MM>.jsonl. Browser visibility comes from each job: its own headless=/headed= params, then the environment, then Settings.

output
blowhorn schedule tick [OPTIONS]
Flag Type Default Description
--limit integer 0 Maximum number of due rows to process; 0 means no limit
--ignore-pause boolean false Run even while 'blowhorn schedule pause' is in effect; without it a paused scheduler claims nothing
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Pace handed to every action 'blowhorn schedule tick' runs in-process this pass -- the random delays between that action's browser or API steps: a preset name (fast/normal/slow) or a numeric multiplier (e.g. 0.5, 2.0). Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule tick --profile all --dry-run
blowhorn schedule tick --profile all --limit 5
blowhorn schedule tick --profile all --limit 0
blowhorn schedule tick --profile all --ignore-pause

Output: json with --json, text otherwise.

blowhorn schedule trigger-now

Force a specific scheduled action to run immediately. While 'blowhorn schedule pause' is in effect the row is not run and the command exits 1, unless --ignore-pause is passed. Browser visibility comes from the job: its own headless=/headed= params, then the environment, then Settings.

output
blowhorn schedule trigger-now [OPTIONS] row
Argument Required Description
row yes Row number to execute
Flag Type Default Description
--ignore-pause boolean false Run even while 'blowhorn schedule pause' is in effect; without it a paused scheduler claims nothing
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Pace handed to every action 'blowhorn schedule trigger-now' runs in-process this pass -- the random delays between that action's browser or API steps: a preset name (fast/normal/slow) or a numeric multiplier (e.g. 0.5, 2.0). Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule trigger-now 7 --dry-run
blowhorn schedule trigger-now 7
blowhorn schedule trigger-now 7 --ignore-pause

Output: json with --json, text otherwise.

blowhorn schedule upsert

Create or update a scheduled action from a JSON payload. Giving a completed or failed row a new Next Run At, or a Run At that changes, schedules it again in place with a fresh retry budget (Status scheduled, Retry Count 0; its last run and last error are kept); raising Max Retries alone does not.

output
blowhorn schedule upsert [OPTIONS]
Flag Type Default Description
--payload string JSON object representing scheduled action fields
--row integer Row number to update; omit to create a new row
--expected-fingerprint string Reject the write if the current row fingerprint no longer matches
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule upsert' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule upsert --payload '{"Command":"report","Profile":"all","Run At":"2026-03-12 08:00:00"}' --json
blowhorn schedule upsert --row 7 --payload '{"Run At":"2026-03-13 08:00:00"}' --json
blowhorn schedule upsert --row 4 --payload '{"Next Run At":"2026-10-20 09:00:00"}' --json
blowhorn schedule upsert --row 7 --payload '{"Enabled":"FALSE"}' --expected-fingerprint 3f2a1c --json

Output: json with --json, text otherwise.

blowhorn schedule validate

Validate the schedule's actions against the supported schema.

output
blowhorn schedule validate [OPTIONS]
Flag Type Default Description
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule validate' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule validate --profile all
blowhorn schedule validate --profile all --json

Output: json with --json, text otherwise.

blowhorn schedule why

Explain why a scheduled row has or has not run on this machine, in the order the scheduler decides it: whether the row is enabled and valid, whether anything is pausing it (the row itself, this machine, or every machine), whether it is due, whether another machine holds the claim and when that lease expires, whether this machine can reach the store and when it last ticked, and what the run history says happened the last time it ran. Reads only -- it claims nothing, runs nothing and changes nothing, so it is safe against a row that is mid-flight.

output
blowhorn schedule why [OPTIONS] row
Argument Required Description
row yes The scheduled action's number to explain (the same number 'blowhorn schedule list' prints)
Flag Type Default Description
--json boolean false Emit machine-readable JSON output
--platform string all Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included)
--pace string Accepted by 'blowhorn schedule why' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs

Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.

Examples:

terminal
blowhorn schedule why 7
blowhorn schedule why 7 --json

Output: json with --json, text otherwise.

Last modified October 18, 2026