Everything waiting on your review, in the order you were asked.
Mrow is a small desktop app for the pull and merge requests where you’re the reviewer. It reads GitLab through glab and GitHub through gh, shows every diff natively, and keeps quiet until someone asks for you.
Lena Fischer wants to merge lena/sticky-filter into main
src/issues/IssueList.tsx+1−1
2222exportfunctionIssueList({ tab }: Props) {
23−const [query, setQuery] = useState('')
23+const [query, setQuery] = useSearchParam('q')
L
Lena Fischer10:02
Same hook the settings page uses.
Y
You10:20
Nice, does it debounce the URL writes?
2424const issues = useIssues(tab, query)
2525return <List items={issues} />
Try it: switch accounts, lists and rows, or move with j and k. Every person and repository in it is made up.
Sorted by when you were asked
Most review lists sort by when a request was opened or last touched. Mrow sorts by the moment you were asked to look. When someone asks again after pushing fixes, the request comes back to the top of Today.
The queue falls into Today, Yesterday, This week, This month and Older. Anything that has waited on you for more than two days shows its age in clay, so the old ones don’t hide under the new.
Tuesday, 4:10 pm
Today
Retry webhook delivery with backoffnorthwind/billing!305Asked 4:02
This week
Move preview environments to the shared runner poolnorthwind/infra!97Asked Monday
Thursday, 9:40 am, after Sam pushes fixes
Today
Retry webhook delivery with backoffnorthwind/billing!305Re-requested 9:40
This week
Move preview environments to the shared runner poolnorthwind/infra!973d
To review
You haven’t reviewed it yet, you’ve started, or new commits reset your review.
Reviewed
You approved, commented or asked for changes, and it’s still open.
Done
Merged or closed in the last 14 days. The window is yours to change.
The whole review, without the browser
The description renders the way its author wrote it. Every file’s diff has line numbers and syntax highlighting, and comment threads sit on the lines they’re about.
Comment on a line or on the whole request, tick files off as viewed while you go, and approve when you’re satisfied. Keep a few open in tabs and move between them.
Keep the filter when switching tabsApprove
src/issues/IssueList.tsx+1−1
2222exportfunctionIssueList({ tab }: Props) {
23−const [query, setQuery] = useState('')
23+const [query, setQuery] = useSearchParam('q')
L
Lena Fischer10:02
Same hook the settings page uses.
Y
You10:20
Nice, does it debounce the URL writes?
Reply⌘↩
2424const issues = useIssues(tab, query)
2525return <List items={issues} />
GitLab and GitHub, one picker
Mrow reads GitLab through the glab command-line tool and GitHub through gh. Signed in to both? The picker at the top of the sidebar flips between them, the way you’d switch teams in a chat app.
Each account keeps its own queue, its own unread dots and its own three lists.
GLMerge requests, through glab
GHPull requests, through gh
Ask Cursor about the change
Press ⌘L and a chat opens beside the review, run by Cursor’s agent acp. Your first question carries the description, the diff and the threads, and the agent can read your local clone as it’s checked out. Ask where else a function is called, or what a change might break.
It’s read-only three ways. Chats run in Cursor’s ask mode, Mrow offers the agent no file or terminal access, and it declines every permission request, showing each one in the chat. You get one chat per request, kept across relaunches.
Ask CursorRead-only
Given the description, the diff of src/issues/IssueList.tsx and its threads.
Is anything else calling this the old way?
Two callers still expect the old behaviour. Both are in tests, so nothing in production changes, but they'll need updating before this merges.
// fixtures/IssueList.tsx, line 12
Ask about this pull request
Talks to nothing but glab and gh
Mrow has no server, no sign-up and no analytics. Every request goes through the glab and gh tools you already use, and their tokens stay in your keychain, where those tools put them. Mrow never sees a token. All it keeps is a few preferences.
The only exception is the one you choose. Open Ask Cursor, and your question goes to Cursor through its agent, along with the review it’s about.
Mrow
glabGitLab
ghGitHub
agent acpCursor, when you ask
Every action has a key
You can work through a whole morning’s reviews without touching the trackpad.
Keyboard shortcuts
Keys
Action
⌘1⌘2⌘3
To review, Reviewed, Done
⌥⌘1⌥⌘2⌥⌘3
Overview, Changes, Discussion
↑↓jk
Move through the list
⌥⌘]⌥⌘[
Next or previous request
⌘K⌘F
Filter the list
⌘R
Refresh
⌘O↩
Open in the browser
⇧⌘A
Approve
⇧⌘C
Copy link
⌘↩
Post the comment
⌃⌘S
Show or hide the sidebar
⌘L
Ask Cursor: open the chat, move into it, or close it
⇧⌘L⌥⌘L
New chat, choose the model
←→
Change the model’s effort, in the model picker
esc
Stop the answer, in the chat
Install it
One command downloads the latest release, checks it against the release’s checksum and installs it.
macOS 15 or later on Apple silicon, or Linux (x86_64 or arm64) with a Vulkan driver
glab signed in for GitLab, gh for GitHub, or both
Terminal
curl -fsSL https://mrow.wania.app/install | bash
On a Mac it puts Mrow in ~/Applications and opens it. On Linux it installs mrow and its desktop entry into ~/.local. Then sign in with glab auth login, gh auth login, or both.
The latest release. Older ones, and what changed in each, are on the releases page.
Or build it yourself
Terminal
git clone https://github.com/ZainW/mrow.git
cd mrow/apps/desktop
scripts/install.sh
Needs a Rust toolchain (rustup); on Linux, also libxkbcommon-dev and libwayland-dev, and run scripts/package-linux.sh --install instead. Builds from source don’t update themselves.
Lena Fischer 10:02
Same hook the settings page uses.