problemsdev/rhythm

A skimmable terminal dashboard for your GitHub repos

TypeScript

3

5 commits

updated Oct 13, 2026

See the code

See what people are saying

README

rhythm.sh

A skimmable, full-screen terminal dashboard for your GitHub repos. One glance shows open PRs, dependabot alerts, and the health of main across every project you care about, and every row is a jump-off point to the browser.

Built with Bun and OpenTUI.

 ▐ rhythm.sh  2 repos                      updated 10:17:05 AM · every 120s 

╭ problemsdev/rhythm ──────────────────────────────────────────────────────╮
│ ✓ main ▸2  docs: README and example config · 2h                          │
│ ✓ #3 feat: expand check runs with space ✔ octocat · 1d                   │
│ ✓ no dependabot alerts                                                   │
╰──────────────────────────────────────────────────────────────────────────╯
╭ anomalyco/opentui · ★ 13k ───────────────────────────────────────────────╮
│ ✗ main ▾  Release v0.5.5 · 1h                                            │
│   ✗ CI / test (ubuntu) · 4m02s                                           │
│   ◌ CI / build · 1m18s…                                                  │
│   ✓ CI / lint · 38s                                                      │
│ ✓ #1392 docs: add section-aware documentation search simonklee · 50m     │
│ ✓ #1393 ◇ core: make text selection inclusive of both endpoint cells si… │
│ ✓ #1389 fix(core): use boundary semantics for backward selection ± ofek… │
│ … 113 more open PRs                                                      │
│ ✓ no dependabot alerts                                                   │
│ 1 docs                                                                   │
╰──────────────────────────────────────────────────────────────────────────╯

 tab repo · j/k row · ⏎ open · space checks · 1-9 links · r refresh · q quit

Skim, don't read. Card borders encode health: red means main is failing, orange means alerts need attention, yellow means work in flight, gray means all quiet. You know where to look before you've read a word.

One request per refresh. Every repo is fetched in a single batched GraphQL query, so a long repo list stays fast and rate-limit friendly.

Jump off anywhere. Every row is a real terminal hyperlink, enter opens it in your browser, and keys 1–9 open the logs, dashboards, and analytics you configure per repo.

Install

Requires Bun 1.2 or newer.

bun install -g @problemsdev/rhythm

Check it landed on your PATH with rhythm --version.

Or run it from a checkout:

git clone https://github.com/problemsdev/rhythm
cd rhythm
bun install
bun start

To get a rhythm command from the checkout, symlink the entry point onto your PATH. It is executable and runs under Bun via its shebang:

ln -s "$PWD/src/index.tsx" ~/.bun/bin/rhythm

Authentication

rhythm uses GITHUB_TOKEN if it is set, otherwise the token from gh auth token. If the GitHub CLI works, rhythm works: the default scopes from gh auth login cover public and private repos you have access to.

A few things depend on what the token can see:

  • Dependabot alerts are shown when you can view them on GitHub for that repo. Otherwise the alerts row reads ⚠ alerts unavailable.
  • Stars are shown for public repos only.
  • A repo you can't reach (typo, no access, deleted) shows its error inside the card. The other repos still load normally.

Config

Config is YAML, searched in this order:

  1. $RHYTHM_CONFIG
  2. ./rhythm.yaml
  3. ./rhythm.yml
  4. $XDG_CONFIG_HOME/rhythm/config.yaml (default ~/.config/rhythm/config.yaml)

Or pass one explicitly with rhythm --config <path> (-c for short). There is a starter in rhythm.example.yaml.

refresh: 2m              # how often to poll GitHub
columns: 2               # optional: cap the card grid width

repos:
  - problemsdev/rhythm   # bare form
  - repo: anomalyco/opentui
    links:               # jump-off links, opened with keys 1-9
      docs: https://github.com/anomalyco/opentui#readme
keydefaultnotes
refresh2mA bare number is seconds. Strings take ms, s, m, or h: 90s, 2m, 1.5h.
columnsautoMaximum card columns. Auto fits as many 56-cell-wide cards as the terminal allows.
reposrequiredA non-empty list. Each entry is owner/name or a mapping with repo and optional links.
repos[].linksnoneA mapping of label to URL. The first nine are bound to keys 1–9, in order.

Keys

keyaction
tab / shift+tabnext / previous repo
h l / ← →previous / next repo
j k / ↑ ↓move between rows, flowing across repos
enter / oopen the selected row in your browser
spaceexpand or collapse main's check runs on the selected repo
1–9open the selected repo's configured links
rrefresh now
q / ctrl+cquit

Rows are also real terminal hyperlinks, so in most modern terminals you can click them.

Reading the dashboard

The header shows the repo count and the last refresh time, a spinner while fetching, or the error if a refresh failed. Cards fill a grid, one per repo, and the footer shows a key hint plus the config file in use.

Card borders

colormeaning
bluethe selected card
redmain is failing, or the repo failed to load
orangecritical or high dependabot alerts, or a PR whose CI is failing
yellowwork in flight: open PRs or any alerts
grayall quiet

Rows

Each card lists, top to bottom: the main branch and its latest commit, the ten most recently updated open PRs (plus a … N more open PRs row when there are more), the dependabot alert summary, and any configured links.

glyphmeaning
✓ ✗ ◌ ·CI passed / failed / running / no CI, for main and for each PR's head commit
◇draft PR (the whole row is dimmed)
✔ ±review approved / changes requested
⚠open dependabot alerts, counted by severity: critical, high, medium, low
▸N ▾main has N check runs, collapsed / expanded
⋯ ⊘a queued / cancelled check run
★star count (public repos only)

Press space on a repo to expand main's check runs. Each check row shows the workflow and job name plus its duration. Running checks show elapsed time (3m12s…) and update live. Checks are ordered failures first, then running, then queued, then finished.

Where rows open

rowopens
mainthe branch's commit history
a check runthat run's logs
a PRthe pull request
no open PRs / … N more open PRsthe repo's pull request list
alertsthe repo's dependabot alerts page

Relative times (4m, 2h, 3d) refresh on their own between polls.

Development

bun install
bun run dev          # restarts on file changes
bun run typecheck
pathwhat's there
src/index.tsxCLI entry: flags, config and token resolution, renderer setup
src/config.tsYAML loading, search paths, validation
src/github.tsthe batched GraphQL query and response parsing
src/model.tsshared types and the per-repo health rollup
src/open.tscross-platform "open in browser"
src/ui/OpenTUI React components, row layout, formatting, theme

License

MIT

bun
cli
dashboard
dependabot
github
opentui
pull-requests
terminal
tui

problemsdev/rhythm

A skimmable terminal dashboard for your GitHub repos

TypeScript

3

5 commits

updated Oct 13, 2026

See the code

See what people are saying

README

rhythm.sh

A skimmable, full-screen terminal dashboard for your GitHub repos. One glance shows open PRs, dependabot alerts, and the health of main across every project you care about, and every row is a jump-off point to the browser.

Built with Bun and OpenTUI.

 ▐ rhythm.sh  2 repos                      updated 10:17:05 AM · every 120s 

╭ problemsdev/rhythm ──────────────────────────────────────────────────────╮
│ ✓ main ▸2  docs: README and example config · 2h                          │
│ ✓ #3 feat: expand check runs with space ✔ octocat · 1d                   │
│ ✓ no dependabot alerts                                                   │
╰──────────────────────────────────────────────────────────────────────────╯
╭ anomalyco/opentui · ★ 13k ───────────────────────────────────────────────╮
│ ✗ main ▾  Release v0.5.5 · 1h                                            │
│   ✗ CI / test (ubuntu) · 4m02s                                           │
│   ◌ CI / build · 1m18s…                                                  │
│   ✓ CI / lint · 38s                                                      │
│ ✓ #1392 docs: add section-aware documentation search simonklee · 50m     │
│ ✓ #1393 ◇ core: make text selection inclusive of both endpoint cells si… │
│ ✓ #1389 fix(core): use boundary semantics for backward selection ± ofek… │
│ … 113 more open PRs                                                      │
│ ✓ no dependabot alerts                                                   │
│ 1 docs                                                                   │
╰──────────────────────────────────────────────────────────────────────────╯

 tab repo · j/k row · ⏎ open · space checks · 1-9 links · r refresh · q quit

Skim, don't read. Card borders encode health: red means main is failing, orange means alerts need attention, yellow means work in flight, gray means all quiet. You know where to look before you've read a word.

One request per refresh. Every repo is fetched in a single batched GraphQL query, so a long repo list stays fast and rate-limit friendly.

Jump off anywhere. Every row is a real terminal hyperlink, enter opens it in your browser, and keys 1–9 open the logs, dashboards, and analytics you configure per repo.

Install

Requires Bun 1.2 or newer.

bun install -g @problemsdev/rhythm

Check it landed on your PATH with rhythm --version.

Or run it from a checkout:

git clone https://github.com/problemsdev/rhythm
cd rhythm
bun install
bun start

To get a rhythm command from the checkout, symlink the entry point onto your PATH. It is executable and runs under Bun via its shebang:

ln -s "$PWD/src/index.tsx" ~/.bun/bin/rhythm

Authentication

rhythm uses GITHUB_TOKEN if it is set, otherwise the token from gh auth token. If the GitHub CLI works, rhythm works: the default scopes from gh auth login cover public and private repos you have access to.

A few things depend on what the token can see:

  • Dependabot alerts are shown when you can view them on GitHub for that repo. Otherwise the alerts row reads ⚠ alerts unavailable.
  • Stars are shown for public repos only.
  • A repo you can't reach (typo, no access, deleted) shows its error inside the card. The other repos still load normally.

Config

Config is YAML, searched in this order:

  1. $RHYTHM_CONFIG
  2. ./rhythm.yaml
  3. ./rhythm.yml
  4. $XDG_CONFIG_HOME/rhythm/config.yaml (default ~/.config/rhythm/config.yaml)

Or pass one explicitly with rhythm --config <path> (-c for short). There is a starter in rhythm.example.yaml.

refresh: 2m              # how often to poll GitHub
columns: 2               # optional: cap the card grid width

repos:
  - problemsdev/rhythm   # bare form
  - repo: anomalyco/opentui
    links:               # jump-off links, opened with keys 1-9
      docs: https://github.com/anomalyco/opentui#readme
keydefaultnotes
refresh2mA bare number is seconds. Strings take ms, s, m, or h: 90s, 2m, 1.5h.
columnsautoMaximum card columns. Auto fits as many 56-cell-wide cards as the terminal allows.
reposrequiredA non-empty list. Each entry is owner/name or a mapping with repo and optional links.
repos[].linksnoneA mapping of label to URL. The first nine are bound to keys 1–9, in order.

Keys

keyaction
tab / shift+tabnext / previous repo
h l / ← →previous / next repo
j k / ↑ ↓move between rows, flowing across repos
enter / oopen the selected row in your browser
spaceexpand or collapse main's check runs on the selected repo
1–9open the selected repo's configured links
rrefresh now
q / ctrl+cquit

Rows are also real terminal hyperlinks, so in most modern terminals you can click them.

Reading the dashboard

The header shows the repo count and the last refresh time, a spinner while fetching, or the error if a refresh failed. Cards fill a grid, one per repo, and the footer shows a key hint plus the config file in use.

Card borders

colormeaning
bluethe selected card
redmain is failing, or the repo failed to load
orangecritical or high dependabot alerts, or a PR whose CI is failing
yellowwork in flight: open PRs or any alerts
grayall quiet

Rows

Each card lists, top to bottom: the main branch and its latest commit, the ten most recently updated open PRs (plus a … N more open PRs row when there are more), the dependabot alert summary, and any configured links.

glyphmeaning
✓ ✗ ◌ ·CI passed / failed / running / no CI, for main and for each PR's head commit
◇draft PR (the whole row is dimmed)
✔ ±review approved / changes requested
⚠open dependabot alerts, counted by severity: critical, high, medium, low
▸N ▾main has N check runs, collapsed / expanded
⋯ ⊘a queued / cancelled check run
★star count (public repos only)

Press space on a repo to expand main's check runs. Each check row shows the workflow and job name plus its duration. Running checks show elapsed time (3m12s…) and update live. Checks are ordered failures first, then running, then queued, then finished.

Where rows open

rowopens
mainthe branch's commit history
a check runthat run's logs
a PRthe pull request
no open PRs / … N more open PRsthe repo's pull request list
alertsthe repo's dependabot alerts page

Relative times (4m, 2h, 3d) refresh on their own between polls.

Development

bun install
bun run dev          # restarts on file changes
bun run typecheck
pathwhat's there
src/index.tsxCLI entry: flags, config and token resolution, renderer setup
src/config.tsYAML loading, search paths, validation
src/github.tsthe batched GraphQL query and response parsing
src/model.tsshared types and the per-repo health rollup
src/open.tscross-platform "open in browser"
src/ui/OpenTUI React components, row layout, formatting, theme

License

MIT

bun
cli
dashboard
dependabot
github
opentui
pull-requests
terminal
tui