KQ-1650 · HEARTBEAT/LEDGER
Heartbeat Ledger
A monitor for scheduled jobs that check in: each row is a job, its owner, a strip of recent check-ins drawn as slim bars whose height is the run's length (on time, late, failed, and a hatched slot wherever a run never arrived) and its next deadline. A new check-in drops into the head of its strip on springs.recoil while the strip rolls one slot left on springs.glide; past its deadline a job wears a ring that runs down its grace on a linear tween between readings of the now prop, and if the grace runs out the row tips into a warning tint that sweeps in on glide while its dot turns into a warning glyph on springs.snap. It is a role="grid" with one roving cell: arrows move, P pauses, M mutes, Enter opens the last run, and Enter on a strip steps into it to pick an older run.
Fernworks nightly
6 jobs · 1 due
P pauses a job, M mutes it, Enter opens its last run. Enter on the history steps into it.
01:52 utc · 6 jobs · 1 due · 0 missed
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/heartbeat-ledger
Props
- stripLength
- number
- default 24
- How many beats each history strip shows at wide widths; narrow widths always show the last ten.
- density
- "compact" | "cozy" | "roomy"
- default "cozy"
- Row height and bar size.
- accent
- string
- default "var(--accent-bright)"
- On-time ticks, grace rings and the clock, any CSS colour.
- jobs
- HeartbeatJob[]
- default defaultHeartbeatJobs
- The jobs: { id, name, schedule, every, grace, lastCheckIn?, owner, beats, typical? } with beats { id, at, status, duration } oldest first.
- now
- number
- default defaultHeartbeatNow
- The time every deadline is judged against, in ms; the host advances it and the clock is never read.
- paused / defaultPaused
- string[]
- default — / []
- Paused job ids, controlled or initial.
- onPause
- (job: HeartbeatJob, paused: boolean) => void
- default —
- Fires from the button or the P key, with whether the job is now paused.
- muted / defaultMuted
- string[]
- default — / []
- Muted job ids, controlled or initial.
- onMute
- (job: HeartbeatJob, muted: boolean) => void
- default —
- Fires from the button or the M key, with whether the job's alerts are now muted.
- onOpenRun
- (job: HeartbeatJob, beat: HeartbeatBeat | null) => void
- default —
- A run was opened: Enter or a press on the job, or a beat picked in its strip; null when the job has never run.
- status
- "ready" | "loading" | "error"
- default "ready"
- Loading draws skeleton rows with ghost strips; error shows its own state with Retry; an empty jobs list has its own state too.
- onRetry
- () => void
- default —
- Retry was pressed after the check-ins failed to load.
- title
- string
- default "Fernworks nightly"
- The heading and the grid's accessible name.
- formatTime
- (ms: number) => string
- default HH:MM in UTC
- Formats the clock, deadlines and beat times.
- height
- number
- default 520
- Height of the surface in px; rows scroll under the pinned header.
- disabled
- boolean
- default false
- Nothing can be paused, muted or opened; the surface dims.
- className
- string
- default —
- Classes for the outer surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| stripLength | number | 24 | How many beats each history strip shows at wide widths; narrow widths always show the last ten. |
| density | "compact" | "cozy" | "roomy" | "cozy" | Row height and bar size. |
| accent | string | "var(--accent-bright)" | On-time ticks, grace rings and the clock, any CSS colour. |
| jobs | HeartbeatJob[] | defaultHeartbeatJobs | The jobs: { id, name, schedule, every, grace, lastCheckIn?, owner, beats, typical? } with beats { id, at, status, duration } oldest first. |
| now | number | defaultHeartbeatNow | The time every deadline is judged against, in ms; the host advances it and the clock is never read. |
| paused / defaultPaused | string[] | — / [] | Paused job ids, controlled or initial. |
| onPause | (job: HeartbeatJob, paused: boolean) => void | — | Fires from the button or the P key, with whether the job is now paused. |
| muted / defaultMuted | string[] | — / [] | Muted job ids, controlled or initial. |
| onMute | (job: HeartbeatJob, muted: boolean) => void | — | Fires from the button or the M key, with whether the job's alerts are now muted. |
| onOpenRun | (job: HeartbeatJob, beat: HeartbeatBeat | null) => void | — | A run was opened: Enter or a press on the job, or a beat picked in its strip; null when the job has never run. |
| status | "ready" | "loading" | "error" | "ready" | Loading draws skeleton rows with ghost strips; error shows its own state with Retry; an empty jobs list has its own state too. |
| onRetry | () => void | — | Retry was pressed after the check-ins failed to load. |
| title | string | "Fernworks nightly" | The heading and the grid's accessible name. |
| formatTime | (ms: number) => string | HH:MM in UTC | Formats the clock, deadlines and beat times. |
| height | number | 520 | Height of the surface in px; rows scroll under the pinned header. |
| disabled | boolean | false | Nothing can be paused, muted or opened; the surface dims. |
| className | string | — | Classes for the outer surface. |