A small, glanceable desktop app that shows — per project — where you need to act on GitLab: review requests, mentions, and especially comment threads waiting on your reply. It's built so you can answer right from the app and stop context-switching into the GitLab web UI all day.
It is not a code-review tool. It doesn't show diffs, suggest changes, or analyze your code. Its only job is to tell you where a human is waiting on you and let you type a reply in two keystrokes.
Filter to what needs you, open an item, and reply inline — the cursor is dropped straight into the box you most likely need to answer:
And when something new lands, you get a desktop notification (with the app icon). Click it — or hit your Super+g shortcut — and the window comes forward with the reply box already focused:
Screenshots use built-in demo data (
GITLAB_INBOX_DEMO=1) — no real projects, people, or hosts.
- One inbox, grouped by project, scoped entirely to you:
- GitLab Todos —
review_requested,mentioned,directly_addressed,assigned,approval_required,unmergeable,build_failed. - Deep thread scan — for every open MR you authored / review / are assigned to, it finds threads where the last reply isn't you and the thread is still unresolved — even when no todo was created.
- GitLab Todos —
- Answer in place — open an item to get its discussion threads in a modal:
reply, resolve/unresolve, or start a new comment. All writes go through
glab. - Notifications that take you to the answer — new/changed items raise a desktop notification; activating it focuses the window and opens that item with the reply box ready.
- Keyboard-driven, urgency-ranked, with
Needs reply/Reviews/CI · blockedfilters.
Everything is personal: the Todos API only returns your todos, and the thread scan only touches MRs where you are the author, a reviewer, or an assignee. No project-wide or unrelated items are ever fetched.
Every call shells out to glab. The app
never reads, stores, or passes a token — glab uses whatever you set up with
glab auth login (its own config/keyring, outside this repo). The only external
commands it runs are glab and xdg-open.
| Package | Builds from |
|---|---|
gitlab-inbox-bin |
the prebuilt binary from the latest release — fast, no Rust toolchain |
gitlab-inbox-git |
source at HEAD — compiles locally |
yay -S gitlab-inbox-bin # or: paru -S gitlab-inbox-binglab and the GTK/WebKit runtime are pulled in automatically. After installing,
run glab auth login (if you haven't), then launch GitLab Inbox from your
app launcher or with gitlab-inbox.
The sections below cover building it yourself.
- Rust (built with 1.95)
glabinstalled and logged in (glab auth status)- Linux desktop with a WebKitGTK runtime (
webkit2gtk-4.1) - A notification daemon (
swaync,mako,dunst, …) for notifications and click-to-open - Optional:
xdg-opento open items in your browser
# from the repo root — first build is slow, then it's instant
cargo run --releaseBy default it auto-detects the host glab is logged into (it tries each
host in your glab config and uses the first one with a valid token), so there's
usually nothing to configure. To pin a specific instance, set GITLAB_INBOX_HOST:
GITLAB_INBOX_HOST=gitlab.example.com cargo run --releaseIf glab isn't installed or you haven't signed in yet, the app still launches
and shows a banner with the exact glab auth login command to run. It re-checks
every couple of seconds, so once you log in it connects on its own — no restart.
Install the binary somewhere on your PATH for daily use:
cargo build --release
cp target/release/gitlab-inbox ~/.local/bin/GITLAB_INBOX_DEMO=1 cargo run --releaseDemo mode serves fake data and never calls glab — it's what the screenshots
above show.
Wayland compositors own global shortcuts, so bind one in your compositor to focus
the app. The app listens for window-focus and, if a notification is pending, opens
that item and focuses its reply box — so Super+g after a ping lands you straight
in the answer field.
sway (~/.config/sway/config):
# raise GitLab Inbox (and jump to the thing that pinged you)
bindsym $mod+g [app_id="gitlab-inbox"] focus
(Other compositors: bind $mod+g to focus the gitlab-inbox window however your
setup does it.) Clicking the notification itself does the same thing.
- Sidebar — pick a project, or All projects.
- Filters —
All,Needs reply,Reviews,CI / blocked(live counts). - Click an item — opens its threads; the right reply box is auto-focused.
- Reply / Resolve / Comment — inside a thread;
Ctrl/⌘+Entersends. - Open — opens the MR/issue in the browser.
- Done — marks the backing GitLab todo(s) done and removes the item.
| Key | Action |
|---|---|
j / k |
move selection down / up |
Enter |
open the selected item's threads |
o |
open the selected item in the browser |
d |
mark the selected item done |
r |
refresh now |
1–4 |
switch filter |
Esc |
close the modal / clear selection |
src-tauri/
src/
main.rs # entry point
lib.rs # Tauri builder, commands, 2-min poll loop, focus handling
gitlab.rs # glab api wrapper (todos, MRs, discussions, reply/comment/resolve)
crawl.rs # crawler: snapshot + thread detail, diffs, notifies, emits, demo data
model.rs # Item / Snapshot / Detail data types + urgency scoring
tauri.conf.json
capabilities/ # Tauri v2 permissions (core only)
icons/ # app icon (logo.svg — duck + GitLab fountain — + rasterized PNGs)
ui/ # vanilla HTML/CSS/JS frontend (no bundler)
index.html
style.css
app.js
The frontend is plain HTML/CSS/JS over the global window.__TAURI__ API — no
npm/node build step. Backend commands: get_snapshot, refresh, mark_done,
open_url, get_detail, post_reply, post_comment, resolve_thread. It emits
a snapshot event per crawl and an open-item event on notification activation.
- It crawls every 2 minutes; refresh on demand with
r. - "Needs reply" thread detection runs on merge requests only (issues use the Todos signal). Bot/system notes are ignored.
- Notifications fire for items new or changed since the previous crawl (not on the
first crawl). Click-to-open needs a daemon that supports the freedesktop
defaultaction (swaync/mako/dunstall do). - The thread scan only looks at MRs that already have comments, to bound API calls.
- Comment bodies render as plain text with light formatting (inline
code, links); full GitLab markdown isn't rendered.
MIT



