GitHub — cross-repo PRs & Issues
- 1. Register the repos you want to see
- 2. Open the view and read it
- 3. Start work on an issue from its row
- Prerequisite: sign in to the GitHub CLI
- If nothing shows up
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
mergebutton 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 yourghlogin, 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).
From the Settings modal (recommended)
- Open Settings → Pull request repos.
- Type an
owner/repo(e.g.receptron/mulmoterminal) and click Add. - Added repos are listed; remove any with its ✕.
The format is
owner/repoonly (no spaces, paths, orhttps://…). The value is passed straight togh --repo, so only a bareowner/reposlug 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:
glablogged in to that host —glab auth login --hostname gitlab.example.com. This app stores no token of its own; it runs yourglab, the same arrangement asgh.- A server restart after editing
config.jsonby hand — the same asprReposwritten 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/repoheading with a count). - Only open items are shown. Order is your registration order (repos) and whatever
ghreturns (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 issuesis 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 noorigin, 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:
- reads the issue (title and body),
- creates a
issue/<number>-<slug>worktree in your clone of that repo, forked from a freshly fetchedorigin/<base>, - 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
ghlogin. - 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/repounder 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 yourghaccess 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/repois right. - Counts are capped → the limits are 100 PRs / 20 Issues per repo; see the rest via the GitHub links.