GitHub — cross-repo PRs & Issues

See open Pull Requests and Issues across several repositories on one screen. Which repo has something waiting for review, whether CI is red — all at a glance, without hopping between sessions. You choose which repos show up by registering them (just a list of owner/repo).

  • Two places, one list: the pane beside an enlarged cell (the merge button in the cell’s header), and a full-screen view from the toolbar’s Pull requests button (call_merge).
  • Shows both open PRs and Issues, grouped per repository. In the pane, that cell’s repository comes first.
  • Data comes through the GitHub CLI (gh) — it uses your gh login, so no token is stored in the app.

1. Register the repos you want to see

Only the repos you register appear (nothing is auto-added from worktrees or sessions). Two ways, both effective immediately (no restart).

  1. Open Settings → Pull request repos.
  2. Type an owner/repo (e.g. receptron/mulmoterminal) and click Add.
  3. Added repos are listed; remove any with its .

The format is owner/repo only (no spaces, paths, or https://…). The value is passed straight to gh --repo, so only a bare owner/repo slug is valid.

By editing the config file

Add to prRepos (an array of "owner/repo" strings) in ~/.mulmoterminal/config.json:

{
  "prRepos": ["acme/web", "acme/api"]
}

An entry may also name its host — "gitlab.com/group/project". GitLab projects are read too, with glab in the same role gh plays for GitHub: the list, starting work from an issue, work comments, and opening a merge request all work. GitLab groups nest, so gitlab.com/group/sub/project is fine. A bare owner/repo still means github.com, so nothing you already have changes.

An entry on any OTHER host shows a row naming that host, rather than silently contributing nothing.

One difference worth knowing: a GitLab row’s CI dot is usually blank, because GitLab’s merge-request list carries no pipeline status and reading it costs one call per merge request. A cell watching a single branch does read it, so the phase pill in the cockpit is accurate.

A GitLab of your own (self-hosted)

gitlab.example.com cannot be recognised from its address — nothing in the name says whether that host runs GitLab, Gitea or a wiki. So you say so once, in the same file:

{
  "gitlabHosts": ["gitlab.example.com"],
  "prRepos": ["gitlab.example.com/group/project"]
}

A declared host then behaves exactly like gitlab.com: the list, starting work from an issue, work comments, and opening a merge request. Two things it needs:

  1. glab logged in to that hostglab auth login --hostname gitlab.example.com. This app stores no token of its own; it runs your glab, the same arrangement as gh.
  2. A server restart after editing config.json by hand — the same as prRepos written by hand, since the file is read at start-up.

Until the host is declared, its row says so and names the key to add. Not covered yet: a port in the host name (gitlab.example.com:8443), an http-only instance, and GitHub Enterprise.

→ See Configuration for the full key list.

2. Open the view and read it

Beside a cell. Enlarge a cell and press the merge button in its header (Show GitHub PRs and issues). The list opens in that cell’s right pane, replacing whatever pane it had — Canvas, Tools, Files and Collections are one-at-a-time per cell, and GitHub is one of them.

Full screen. Click Pull requests (call_merge) in the toolbar (it sits between Accounting and Wiki).

  • A Pull requests section on top, an Issues section below. Both are grouped per repository (an owner/repo heading with a count).
  • Only open items are shown. Order is your registration order (repos) and whatever gh returns (items).
  • In the pane, the cell’s own repository is lifted into a block of its own at the top — its PRs and its issues together — including when it has nothing open, where No open PRs / No open issues is still the answer. Two conditions: the cell’s directory is inside a working directory you registered (the clone or anywhere under it; a directory that is not a git repo, has no origin, or sits on a forge this app cannot read names no repository), and that repository is in the list above. Otherwise the pane opens in the configured order.
  • Clicking a row opens it on GitHub in a new tab (nothing opens in-app).
  • ↻ (Reload) at the top re-fetches. There is no auto-refresh — it loads once when you open the view, then only on Reload.

What a PR row shows

Element Meaning
● CI dot green = checks passing / red = failing / amber = running / dim = no checks
#number · title the PR number and title
draft shown for draft PRs
approved / changes requested / review required review state
author · relative time e.g. alice · 2h ago (last updated)

An Issue row shows #number · title · author · relative time, plus a ▶ start button on the right — see below.

Up to 100 PRs / 20 Issues per repo. Beyond that, a “there are more” note appears with a link to GitHub.

3. Start work on an issue from its row

The button at the end of an issue row does the whole setup in one click:

  1. reads the issue (title and body),
  2. creates a issue/<number>-<slug> worktree in your clone of that repo, forked from a freshly fetched origin/<base>,
  3. starts Claude in that worktree as a grid cell, with the issue already typed into the input box — and not sent. You read it, edit it if you like, and press Enter yourself.

Because the branch carries the issue number, everything downstream follows without being told again: the ⧉ Open PR button writes Fixes #<number> into the PR body, and the header’s work-item chip, the issue work comment and the merge-time auto-close all read the same number.

If you keep several clones of one repo, the button asks which one the first time and remembers your answer (repoDirs in the config); after that it is one click. If you have no clone of that repo, the button is disabled and says so — register the directory in Settings → directory presets to enable it.

Pressing it again for the same issue does not make a second worktree. One issue has one worktree: the existing one opens, along with the session left in it if there is one. If that session is still open in another terminal, nothing happens and the button says so — the same one-session-per-worktree rule as everywhere else.

The issue body is text written by whoever opened the issue, which is often not you. That is why it is left in the input box rather than sent: the Enter is yours. A resumed session gets nothing typed into it — it already has a conversation of its own.

Prerequisite: sign in to the GitHub CLI

The view runs the gh command behind the scenes. On the machine running the server:

gh auth login
  • The app stores/reads no token — it works with your gh login.
  • Repos always come from server-side config (never from the request).
  • Each repo is fetched in parallel; only a failing repo shows its error (the others still load).

If nothing shows up

  • “No repositories configured…” → nothing registered yet. Add owner/repo under Settings → Pull request repos.
  • “gh not found…” → install the GitHub CLI and run gh auth login.
  • One repo errors → check the spelling (owner/repo) and your gh access to it (private repos need permission).
  • A PR you just opened is missing → there’s no auto-refresh, so hit ↻ Reload. Still missing? Confirm it’s open and the owner/repo is right.
  • Counts are capped → the limits are 100 PRs / 20 Issues per repo; see the rest via the GitHub links.

Feature reference / Configuration / English guide index


This site uses Just the Docs, a documentation theme for Jekyll.