⚡ GitPulse — Git Repo Dashboard TUI
A developer-focused terminal dashboard that scans a root directory for all local Git repositories and displays live status, recent commits, diffs, and branch management — all from the terminal.
Built with Python, Textual, Rich, and GitPython.
Why GitPulse?
A lot of development happens late at night, and not everyone commits or pushes their changes right away. With "vibe coding" becoming so popular, many people now juggle several projects at once — and that makes it genuinely hard to keep track of every local repository.
GitPulse exists to solve exactly that. It gives you a single dashboard for all your local repos, so at a glance you can see what's committed but not yet pushed, what's changed but not yet committed, the number of modified files, the current branch, the last commit, and everything else about the state of each local Git repository.
Screenshots
Demo — GitPulse in action
Status tab — repo summary cards, staged/unstaged/untracked/stash workspace, and the file tree / recent commits / remote summary side panels
Commits tab — last N commits with color-coded insertions/deletions
Installation
The easiest way to install GitPulse is via PyPI using pip or pipx:
pip install gitpulse-tui
(We recommend using pipx install gitpulse-tui to install it in an isolated environment)
Install via npm
GitPulse is also available as an npm package. The npm package is a thin launcher — it bootstraps an isolated Python environment and runs the same Python application (no logic is duplicated):
npm install -g gitpulse-tui
The CLI command is still gitpulse once installed.
This requires Python 3.10+ on your system; the wrapper handles the rest.
See npm/README.md for details and troubleshooting.
Install from source
If you prefer to install from source or want to contribute to the project:
git clone https://github.com/lebiraja/gitpulse.git
cd gitpulse
./install.sh
The installer:
- Checks your Python version (3.10+ required)
- Creates a virtual environment automatically
- Installs all dependencies
- Adds the
gitpulsecommand to your shell (~/.zshrc/~/.bashrc)
Then reload your shell:
source ~/.zshrc # or source ~/.bashrc
Usage
gitpulse # scan the current directory (or scan.roots from config)
gitpulse --root /path/to/repos # scan a custom directory
gitpulse --commits 20 # show 20 commits per repo (default: 10)
gitpulse --no-watch # disable live watch mode
gitpulse --config path/to.toml # use a custom config file
gitpulse --version # print version
gitpulse --update # upgrade to the latest release
gitpulse --check-update # report if one exists, install nothing
# Activity digest (prints markdown, no TUI):
gitpulse digest --since 7d # last 7 days
gitpulse digest --since 2024-01-01 # since a date
gitpulse digest --author you@example.com # filter by author
For scripts and coding agents
Non-interactive subcommands emit machine-readable fleet state on stdout, so an agent can answer "which of my repos have unpushed work?" in a single call:
gitpulse scan --json # full fleet state as one JSON document
gitpulse scan --json --dirty # only repos with uncommitted changes
gitpulse scan --json --ahead # only repos with unpushed commits
gitpulse scan --ndjson # one JSON object per line
gitpulse context # Markdown context pack for an LLM prompt
The JSON envelope carries a schema_version, ISO-8601 UTC timestamps
alongside raw epochs, and an errors array. Repos that could not be read are
marked "status": "unreadable" with "readable": false — never silently
reported as clean.
GitPulse is also importable as a library. gitpulse.api never imports Textual:
from gitpulse.api import scan_fleet
unpushed = [r for r in scan_fleet("~/Projects") if r.ahead > 0]
Teaching your agent to use it
Claude Code — install the bundled skill, and Claude will reach for GitPulse on its own whenever you ask about "my repos", "what haven't I pushed", or want a standup summary:
git clone https://github.com/lebiraja/gitpulse.git
mkdir -p ~/.claude/skills
cp -r gitpulse/skills/gitpulse ~/.claude/skills/gitpulse
Then just ask: "which of my projects have uncommitted work?"
Any other agent (Cursor, Codex, Aider, …) — AGENTS.md is a
vendor-neutral description of the same CLI contract. Drop it in your project
root, or paste it into your agent's rules/system prompt.
Both documents cover the same ground: the JSON schema, how to narrow with
--dirty / --ahead, and the failure modes worth knowing — chiefly that
"readable": false means unknown, not clean, and that ahead: 0 does not
prove a branch is pushed when it has no upstream.
Staying up to date
gitpulse --update # check PyPI, then upgrade in place
gitpulse --check-update # report only — installs nothing
--update detects how GitPulse was installed and runs the right command for
that channel. It will not upgrade in place when doing so would break the
install — it prints the correct command instead:
| Install method | Behaviour |
|---|---|
| virtualenv | upgrades in place with pip |
| pipx | runs pipx upgrade gitpulse-tui |
| npm | prints npm install -g gitpulse-tui@latest |
| OS-managed Python (PEP 668) | prints a pipx command |
npm installs are deliberately excluded from self-upgrade: the wrapper pins an
exact Python package version and would silently revert a pip upgrade on the
next launch.
GitPulse never checks for updates on its own — no background network calls, no telemetry. The check happens only when you ask for it.
Features
- Multi-repo dashboard — Scans a directory tree and lists every local Git repo, sorted by most recent activity
- Compact fleet sidebar — Each repo as a single row: name, branch, change count, and status (
✓ Clean/● Modified/● Untracked) - Fleet status strip — Cross-repo counters (dirty, behind, ahead, stashes, stale branches); click one to filter the list
- Live watch mode — Polls the filesystem and auto-refreshes repos as they change, without blocking the UI
- Search & filter — Press
/to filter repos by name instantly - Multi-select & bulk actions — Select repos with
Space, then runfetch/pull/push/gc/prune/cleanacross all of them from the command palette (:) - Activity digest — A markdown standup summary of your commits across all repos for a time window (
d, or--digeston the CLI) - Stale-branch cleanup — Find and bulk-delete merged / WIP / old branches across every repo (
b) - Seven content tabs:
- Status — Summary cards (branch, commits, status, stashes, ahead/behind), a staged/unstaged/untracked/stash workspace, and file-tree / recent-commits / remote-summary side panels. Stage, unstage, commit and stash inline.
- Commits — ASCII commit graph + last N commits with color-coded
+green/-reddiff stats - Diff — Per-file picker with syntax-highlighted staged & unstaged changes
- Branches — All local branches; switch, create, or delete
- Remotes — Remote URLs with ahead/behind sync status; fetch / pull / push
- Tags — Recent tags with date and tagger info
- Tree — File hierarchy of all tracked files, with file preview
Keybindings
Press ? inside the app for the full cheat sheet.
| Key | Action |
|---|---|
↑ / ↓ or j / k |
Navigate the repo list |
[ / ] |
Previous / next tab |
/ |
Search / filter repos |
Space / * |
Toggle multi-select / select all |
r |
Refresh — rescan all repos |
w |
Toggle watch mode |
d |
Activity digest |
: |
Bulk action palette |
b |
Stale-branch cleanup |
e |
Error log |
? |
Help |
q |
Quit |
s / u / a |
Stage / unstage / stage-all (Status tab) |
c |
Commit staged changes |
n |
New branch |
z / Z |
Create / pop stash |
Enter |
Switch branch · view commit diff · preview file |
f / p / P |
Fetch / pull / push (Remotes tab) |
Requirements
- Python 3.10+
- Linux / macOS
Documentation
See docs/ for full developer documentation:
Metadata
Release files for gitpulse-tui 1.2.17
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gitpulse_tui-1.2.17.tar.gz | 102.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gitpulse_tui-1.2.17-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 199.7 kB
Release files / gitpulse_tui-1.2.17.tar.gz
| Download URL | gitpulse_tui-1.2.17.tar.gz |
|---|---|
| Size | 102.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
17bd9384776d2d8312be1cb14df86820d61149704736a44a33f3c835b8033330
|
|
BLAKE2b-256 checksum How to use checksums |
15e62e83d3ba98042a230eed33734606a6333f2b1592f58a0d2842429334cf0b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / gitpulse_tui-1.2.17-py3-none-any.whl
| Download URL | gitpulse_tui-1.2.17-py3-none-any.whl |
|---|---|
| Size | 97.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f811bd6798ff599bce0ad12f1227e5293840d8a759fb2c27e7b82d8a50d040f
|
|
BLAKE2b-256 checksum How to use checksums |
054eaddf96a4598ba24fc4dcfcdb3afac5420ca30009c143ea6da8c7095212ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|