An open API service indexing awesome lists of open source software.

https://github.com/kannarfr/glab-desktop-ui

A glanceable desktop inbox for GitLab threads that need your reply — answer reviews, mentions and comments without opening GitLab. Built with Tauri + glab.
https://github.com/kannarfr/glab-desktop-ui

desktop-app developer-tools gitlab glab inbox linux merge-requests notifications productivity rust tauri wayland

Last synced: 28 days ago
JSON representation

A glanceable desktop inbox for GitLab threads that need your reply — answer reviews, mentions and comments without opening GitLab. Built with Tauri + glab.

Awesome Lists containing this project

README

          

# GitLab Inbox

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**.

![demo](docs/demo.gif)

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:

![inbox](docs/screenshot.png)
![threads](docs/threads-modal.png)

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:

![notification](docs/notification.png)

> Screenshots use built-in **demo data** (`GITLAB_INBOX_DEMO=1`) — no real
> projects, people, or hosts.

## What it does

- **One inbox, grouped by project**, scoped entirely to *you*:
1. **GitLab Todos** — `review_requested`, `mentioned`, `directly_addressed`,
`assigned`, `approval_required`, `unmergeable`, `build_failed`.
2. **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.
- **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 · blocked` filters.

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.

## How auth works (no credentials in this repo)

Every call shells out to [`glab`](https://gitlab.com/gitlab-org/cli). 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`.

## Install

### Arch Linux (AUR)

| Package | Builds from |
| --- | --- |
| [`gitlab-inbox-bin`](https://aur.archlinux.org/packages/gitlab-inbox-bin) | the prebuilt binary from the latest release — fast, no Rust toolchain |
| [`gitlab-inbox-git`](https://aur.archlinux.org/packages/gitlab-inbox-git) | source at `HEAD` — compiles locally |

```bash
yay -S gitlab-inbox-bin # or: paru -S gitlab-inbox-bin
```

`glab` 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`.

### Build from source

The sections below cover building it yourself.

## Requirements

- Rust (built with 1.95)
- [`glab`](https://gitlab.com/gitlab-org/cli) installed 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-open` to open items in your browser

## Run

```bash
# from the repo root — first build is slow, then it's instant
cargo run --release
```

By 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`:

```bash
GITLAB_INBOX_HOST=gitlab.example.com cargo run --release
```

If `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:

```bash
cargo build --release
cp target/release/gitlab-inbox ~/.local/bin/
```

### Try it without a GitLab account

```bash
GITLAB_INBOX_DEMO=1 cargo run --release
```

Demo mode serves fake data and never calls `glab` — it's what the screenshots
above show.

## The Super+g shortcut

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.

## Using it

- **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`/`⌘`+`Enter` sends.
- **Open** — opens the MR/issue in the browser.
- **Done** — marks the backing GitLab todo(s) done and removes the item.

### Keyboard

| 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 |

## Project layout

```
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.

## Notes & limitations

- 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
`default` action (`swaync`/`mako`/`dunst` all 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.

## License

MIT