/ΛΙ‘Ιͺt.bΙl/ (git-bell) noun
- a small desktop companion that rings when something happens in your repos.
GitBell is a lightweight desktop app that lives in your system tray and pops a native notification the moment someone pushes, opens a pull request, reviews, merges or releases in the repositories and organizations you care about.
No server, no webhooks, no browser tab left open. Your machine asks GitHub directly with your own token, once a minute, and the operating system shows the toast. That's it.
![]() |
![]() |
- Native toasts on Linux (freedesktop) and Windows (WinRT). Clicking a toast on Linux opens the commit, PR or issue on GitHub.
- Tray-first. Close the window and GitBell keeps watching from the tray. Left click reopens it, right click for the menu.
- Activity first. The window opens on what happened in your repos, with who you're connected as. Settings live one tab over, and every event category has its toggle and sound on the same row.
- Watch what you want. A single repo (
owner/repo), a whole organization (org:name) or everything you watch and follow (@me). - Pick your events. Pushes, pull requests, reviews, issues, comments, branches and tags, releases, stars and forks. Each one is a toggle.
- Sounds. Two bundled chimes, a different one per event category, volume control, or bring your own audio file.
- A mascot that rings its bell. The tray icon plays a short animation when something new arrives. Because why not.
gitbell notifyfrom any script. Agents, CI, cron: if it can run a command, it can ring your bell. See below.- Knows when an agent did it. Commits and PRs from Claude Code, Copilot, Codex, Cursor, OpenCode, Aider, Devin or Jules land in their own category, the toast names the agent, and the click opens the agent's session when the commit carried a link. Honest limits below.
- Polite polling. Honors GitHub's
X-Poll-Interval, uses ETags so unchanged polls cost zero rate limit, and backs off automatically when throttled. - No spam on first run. Adding a busy organization remembers where it is instead of dumping the last 90 days on you.
- Starts with your session, minimized to the tray, if you want it to.
- English and Spanish. Follows your system language, or pick one in settings.
- Glass. The window is translucent and asks the compositor to blur what's
behind it: KDE Plasma (both the KDE and the new
ext_background_effectprotocols), Windows 11 acrylic, macOS vibrancy. A slider in settings sets the opacity; 100% is opaque. GNOME shows the tint without blur. - Three-step first run. Token, what to watch (your busiest repos suggested), and a real notification from your own repo. Skippable, replayable from settings.
- Tiny. Built with Tauri v2: a few megabytes, not a bundled browser.
ββββββββββββ every 60 s, with ETag ββββββββββββββββββββββ
β GitBell β βββββββββββββββββββββββββΆ β api.github.com β
β (tray) β βββββββββββββββββββββββββ β /repos/:r/events β
ββββββ¬ββββββ 200 new events / 304 β /orgs/:o/events β
β β /users/:u/received β
β diff against last seen id ββββββββββββββββββββββ
βΌ
ββββββββββββ
β OS toast β + sound + tray animation
ββββββββββββ
GitBell reads the public GitHub Events API.
It keeps the id of the newest event it has seen per target and only notifies
for events newer than that. Your token never leaves your machine except to
call api.github.com.
Grab the latest installer from the Releases page:
| Platform | Package |
|---|---|
| Linux | .deb, .rpm, .AppImage |
| Windows | .msi, .exe |
| macOS | coming soon (the CI matrix entry is one uncomment away) |
GitBell needs a GitHub personal access token so it can see private repos and organization activity.
- GitHub β Settings β Developer settings β Personal access tokens β Tokens (classic)
- Scopes:
repo(private repositories) andread:org(organization events) - Paste it into the first-run flow, or later in Settings β Account. GitBell can also open the token page for you with the scopes pre-checked.
The token goes straight into your OS keyring (KWallet / GNOME Keyring on
Linux, Credential Manager on Windows). Settings live in the app data
directory (~/.local/share/dev.ejos.gitbell/ on Linux,
%APPDATA%\dev.ejos.gitbell\ on Windows) and never contain the token.
| Syntax | Watches |
|---|---|
owner/repo |
one repository |
org:name |
every repository in an organization you belong to |
@me |
everything you watch or follow (your received-events feed). Never includes your own activity: to get notified about your own pushes, add the repo itself |
GitHub has no "an agent did this" flag. GitBell reads the fingerprints the
tools leave by default: Co-Authored-By trailers, session-link trailers
(Claude-Session:, Agent-Logs-Url:), bot logins (copilot-swe-agent[bot],
claude[bot]), branch prefixes (claude/, copilot/, cursor/) and PR
body markers. A hit moves the event to the Agents category with its own
toggle and sound, the toast reads "π€ Claude Code (@you) pushed to β¦", and
the link prefers the agent's session. Your own agents count even with
"ignore my own activity" on, because cloud sessions push as you.
| Tool | Detected out of the box |
|---|---|
| Claude Code (CLI, desktop, web, GitHub Action) | yes |
| GitHub Copilot coding agent | yes, always |
| Codex (CLI, app, cloud) | yes |
| Cursor agent, OpenCode, Aider, Devin, Jules | yes |
| Gemini CLI, Cline, Roo Code, Kilo Code | no: they don't sign commits |
The catch: detection only works when the tool signs. If you turn attribution off (every tool lets you), or use a tool that doesn't sign, the commit is indistinguishable from yours, for GitBell and for anyone. For those cases use the hook below: the agent tells GitBell directly, no git forensics involved. Models (DeepSeek, GPT, Claude) are not tools; the mark comes from whatever wraps them.
GitBell doubles as a local notification endpoint. While it's running in the tray, any script can make it ring:
gitbell notify "Build finished" --body "all 212 tests green" --url https://ci.example.com/run/42The second process hands its arguments to the running instance and exits;
you get the toast, the bell animation, the sound and a row in recent
activity. If GitBell isn't running, the command starts it in the tray and
shows the toast anyway. Flags: --body, --url (https only).
This is what makes GitBell useful with coding agents. Claude Code, for
example, can call it from a hook
every time it finishes a turn, so you know when a task is done even if
nothing was pushed yet. In ~/.claude/settings.json:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "gitbell notify \"Claude Code finished\" --body \"$(jq -r .cwd)\""
}
]
}
]
}
}To be told about every commit Claude Code makes, whether or not it signs
them, hook the Bash tool and look for git commit:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "in=$(cat); echo \"$in\" | jq -e '.tool_input.command | test(\"git commit\")' >/dev/null && gitbell notify \"Claude Code committed\" --body \"$(echo \"$in\" | jq -r .cwd)\""
}
]
}
]
}
}Any tool that can run a shell command works the same way: CI scripts, long test runs, deploys, cron jobs.
src/ TypeScript, runs in the webview
βββ core/ pure logic, no Tauri imports
β βββ github.ts Events API client: ETag, X-Poll-Interval, rate limit
β βββ poller.ts the loop, dedupe by last seen event id
β βββ format.ts GitHub event β toast title/body/url
β βββ agents.ts coding-agent fingerprints (trailers, bots, branches)
β βββ i18n.ts typed dictionary, es/en
β βββ types.ts shared shapes and defaults
βββ platform/ thin wrappers over Tauri commands and plugins
β βββ secrets.ts token in the OS keyring
β βββ settings.ts JSON store for settings and state
β βββ notify.ts toasts and tray animation
β βββ sounds.ts audio playback
βββ ui/ activity + settings window, onboarding, no framework
β βββ preview.ts boots the UI in a plain browser with fake data
βββ main.ts wires the three layers together
src-tauri/src/ Rust, the trusted side
βββ lib.rs builder, plugins, window lifecycle
βββ cli.rs `gitbell notify` parsing, forwarded by single-instance
βββ i18n.rs tray menu and toast button strings
βββ tray.rs tray icon, menu, bell animation, unread badge
βββ glass.rs asks the compositor to blur behind the window
βββ notify.rs freedesktop toasts with click-to-open
βββ secrets.rs keyring get/set/delete
βββ sounds.rs validated import of user audio files
Rust stays thin on purpose. Anything that doesn't need OS access lives in
src/core, which has no Tauri imports and is trivially unit-testable.
The webview is treated as untrusted and Rust is the authority. Token in the
OS keyring, least-privilege capabilities, opener scoped to github.com,
asset protocol scoped to the app's own sounds folder, strict CSP, and
cargo audit plus Dependabot in CI. Details in SECURITY.md.
Prerequisites: Rust stable, Node 22, pnpm, and the Tauri system dependencies for your OS.
git clone https://github.com/eJosR-Coding/gitbell.git
cd gitbell
pnpm install
pnpm tauri dev # dev build with hot reload
pnpm tauri build # installers land in src-tauri/target/release/bundle/On Fedora the system libraries are:
sudo dnf install webkit2gtk4.1-devel libappindicator-gtk3-devel librsvg2-devel dbus-develUI preview without Tauri: run pnpm dev and open http://localhost:1420
in a browser. #ob=1, #ob=1c, #ob=2, #ob=3 render each onboarding
step with fake data; #view=settings the settings view; #notoken the
asleep state; no hash the activity view with sample notices.
Tests:
pnpm test # TypeScript core (Vitest)
cargo test --manifest-path src-tauri/Cargo.toml # Rust- Windows installers aren't code-signed yet. SmartScreen shows "Windows protected your PC"; choose More info β Run anyway. Signing is on the roadmap.
- Blur behind the window needs a compositor that offers it. KDE Plasma, Windows 11 and macOS do. GNOME shows the tint only.
- Events arrive with GitHub's own delay (30 s to a few minutes) and GitHub asks not to poll faster than once a minute. Instant delivery via webhooks is on the roadmap.
- Agent detection needs the tool to sign its commits. Tools that don't
(Gemini CLI, Cline and friends) or users who turned attribution off are
invisible; use
gitbell notifyfrom a hook for those.
git tag v0.3.0
git push --tagsThe release workflow builds Linux and Windows installers on GitHub-hosted runners and attaches them to a draft release. You don't need a Windows machine.
- Spanish and English UI
-
gitbell notifyfor scripts and agents - First-run onboarding, activity-first window, glass
- Unread dot on the tray icon
- Agent detection
- Signed auto-updates
- Public repo, AUR and winget packages, then COPR and apt
- Instant mode: webhooks through a tiny relay instead of polling
- macOS builds and notarization
- Do-not-disturb schedule
- Per-branch filters (
mainyes,feature/*no)
Issues and pull requests are welcome. Read CONTRIBUTING.md for the project layout and a few ground rules.
If GitBell saves you from refreshing GitHub one more time, a β on the repo goes a long way. And if it saved you more than that:
GitBell is released under the MIT License.
Developed by Joseph Rodriguez Β· @eJosR-Coding


