sangam संगम
pull requests

sangam

संगम · “confluence”

Review and merge GitHub pull requests without leaving the terminal.

v2.0.1 latest3 releases3 decisions recordedMIT license

sangam: section tabs on top, the pull requests of the current section on the left, the selected PR's overview on the right

Sangam (संगम) is Sanskrit for a confluence: the place where two rivers meet and flow on as one. Which is what a merge is.

sangam is a terminal UI for the part of the day spent on pull requests: finding the ones waiting for you, reading them, reviewing them and merging them. It runs like lazygit: type sangam in any terminal. It's built on the GitHub CLI (gh), fzf and tmux, so it uses your existing gh sign-in and needs no token, server or config to start.

#Features

See everything that needs you

Read a PR properly

Act on it

Fast and out of your way

#Install

#Requirements

sangam is a Bash script. It runs on Linux (macOS isn't supported yet: it uses GNU tools, see the roadmap).

ToolVersionWhat for
bash4.4+sangam itself
gh (GitHub CLI)2.40+everything GitHub: sign-in, search, PR data, merging
fzf0.66+the list, preview and key handling
tmux3.3+the layout (sangam runs its own private tmux server; you don't need to use tmux yourself)
jq1.6+reading GitHub's JSON
git, lessanythe repo you're in, full-screen views
GNU coreutils, GNU grep, util-linuxanystandard on Linux (md5sum, stat, grep -P, setsid)

Optional, but recommended:

ToolWhat you get
batsyntax-highlighted diffs and Markdown descriptions
A Nerd Font in your terminalthe icons (without one they show as boxes)
notify-send (libnotify)desktop notifications after merges, reviews and comments
wl-copy (Wayland), xclip (X11)y copies a PR's link to the clipboard

Install them with your package manager:

# Arch Linux
sudo pacman -S --needed github-cli fzf tmux jq git bat libnotify wl-clipboard

# Fedora
sudo dnf install gh fzf tmux jq git bat libnotify wl-clipboard

# Debian / Ubuntu (gh from GitHub's apt repo: https://github.com/cli/cli/blob/trunk/docs/install_linux.md)
sudo apt install gh tmux jq git bat libnotify-bin wl-clipboard

fzf version: Debian and Ubuntu ship an fzf older than 0.66. Install a current one from fzf's releases (a single binary: put it in ~/.local/bin) or with git clone --depth 1 https://github.com/junegunn/fzf ~/.fzf && ~/.fzf/install. On Debian/Ubuntu, bat's command is batcat; link it: ln -s /usr/bin/batcat ~/.local/bin/bat.

sangam doctor checks all of this for you.

#Quick install

curl -fsSL https://raw.githubusercontent.com/Theyashsawarkar/sangam/main/install.sh | bash

This clones sangam into ~/.local/share/sangam, links ~/.local/bin/sangam to it, and runs sangam doctor. No root needed. If ~/.local/bin isn't on your PATH, the installer tells you the line to add.

Installer options (pass them after bash -s --):

curl -fsSL https://raw.githubusercontent.com/Theyashsawarkar/sangam/main/install.sh | bash -s -- --ref v2.0.0   # a specific release
curl -fsSL https://raw.githubusercontent.com/Theyashsawarkar/sangam/main/install.sh | bash -s -- --bin-dir ~/bin
OptionDefault
--ref <tag or branch>maininstall a release (e.g. v2.0.0) instead of the latest code
--bin-dir <dir>~/.local/binwhere the sangam link goes
--dir <dir>~/.local/share/sangamwhere sangam is cloned
--uninstallremove the link and the clone

#Other ways to install

Arch Linux (package): a PKGBUILD that builds from the latest commit lives in packaging/arch. It pulls in every dependency and installs to /usr:

git clone https://github.com/Theyashsawarkar/sangam
cd sangam/packaging/arch
makepkg -si

System-wide with make:

git clone https://github.com/Theyashsawarkar/sangam
cd sangam
sudo make install                    # /usr/local/bin/sangam
make install PREFIX=~/.local         # or just for you

make uninstall (with the same PREFIX) removes it again.

By hand: sangam is one script. Clone the repo anywhere and link bin/sangam into your PATH:

git clone https://github.com/Theyashsawarkar/sangam ~/src/sangam
ln -s ~/src/sangam/bin/sangam ~/.local/bin/sangam

As a tmux plugin: see Using it inside tmux.

#Update and uninstall

Installed withUpdateUninstall
the quick installerrun the install command again… install.sh | bash -s -- --uninstall
the Arch PKGBUILDmakepkg -si again in packaging/arch (after git pull)sudo pacman -R sangam-git
make installgit pull && sudo make installsudo make uninstall
TPM (tmux)prefix Uremove the @plugin line, then prefix alt-u

Uninstalling leaves your sections (~/.config/sangam) and cache (~/.cache/sangam); delete them by hand if you want them gone.

#Getting started

  1. Sign in to GitHub with gh (once):

``sh gh auth login ``

To use several accounts (say, work and personal), run gh auth login once per account. sangam uses all of them.

  1. Check the setup:

``sh sangam doctor ``

``` sangam 2.0.0

required ✓ bash 5.3.20(1)-release ✓ tmux 3.8 ✓ gh 2.102.0 ✓ fzf 0.74.5 ✓ jq 1.8.2 ✓ git 2.56.0 ✓ less 710 ✓ GNU tools coreutils, grep -P, setsid

GitHub ✓ signed in work-account, personal-account

optional ✓ bat highlighted diffs and descriptions ✓ notify-send desktop notifications ✓ clipboard wl-copy ! Nerd Font icons need a Nerd Font in your terminal (can't be checked from here)

✓ ready: run sangam ```

  1. Run it, ideally from inside a repo you work on:

``sh cd ~/code/my-project sangam ``

You start in normal mode: j/k move through PRs, h/l switch sections, 1–4 switch what the right side shows, m merges, ? shows every key, q quits.

On first run sangam creates ~/.config/sangam/sections with three sections: Review requested, My PRs and Involved. Make it yours next: see Sections.

#Using sangam

#The screen

╭───────────────────────────────────────────────────────────────────────────────╮
│ Review requested 3   My PRs 5   my-project (here) 2      󰀄 all accounts  ? keys │  ← section tabs
╰───────────────────────────────────────────────────────────────────────────────╯
╭─ Review requested · open · 3 ─────────╮╭─ repo · 1 overview 2 diff 3 checks ──╮
│  #     title              author  age ││                                      │
│ ▌#128  Add rate limiting  alice   2h  ││  the selected PR, in the view        │
│  #127  Fix login redirect bob     1d  ││  you picked                          │
╰───────────────────────────────────────╯╰──────────────────────────────────────╯
  the PRs of the current section          overview · diff · checks · comments

#Sections

A section is a name, an optional account, and a GitHub search. They live in ~/.config/sangam/sections, one per line:

# name           | account    | GitHub search
Review requested |            | review-requested:@me
My PRs           |            | author:@me
Involved         |            | involves:@me -author:@me
Work: backend    | work-login | repo:acme/api repo:acme/worker
Dependabot       |            | author:app/dependabot org:acme

Useful searches:

You wantSearch
Waiting for your reviewreview-requested:@me
Waiting for your team's reviewteam-review-requested:acme/backend
Yoursauthor:@me
You're mentioned, assigned or commentedinvolves:@me
One repo / severalrepo:acme/api · repo:acme/api repo:acme/web
A whole orgorg:acme
A labelorg:acme label:bug
Failing CIauthor:@me status:failure
Approved, ready to goauthor:@me review:approved
Draftsauthor:@me draft:true
Botsorg:acme author:app/dependabot
Busy discussionsinvolves:@me comments:>10

Managing sections from inside sangam: press S for a menu to add a section (name, account picked from your signed-in ones, search), edit or delete the current one, move it left or right, or pin the repo you're in as a permanent section. E opens the file in your editor instead. Either way, sangam reloads right after.

The "here" tab: started inside a clone of a GitHub repo, sangam adds a "repo (here)" section for it (unless a section already searches exactly that repo), run as the folder's account (git config github.user, see below). sangam remembers the section you were on last.

How many PRs: each section shows up to 50 PRs, newest activity first. Narrow it with s or a more specific search to reach older ones.

#Accounts

sangam works with every account gh is signed in to (gh auth status):

``ini # ~/.gitconfig [includeIf "gitdir:~/work/"] path = ~/.config/git/work.gitconfig # contains: [github] user = work-login ``

#Finding PRs

#Reading a PR

sangam showing a PR's diff, highlighted, next to the list

#Reviewing

KeyWhat happens
aApprove, with an optional one-line message (Enter approves, Ctrl+c cancels)
rRequest changes: your $EDITOR opens; write the review above the marker line and save. Leave it empty to cancel.
cComment on the PR, in your editor the same way
xClose the PR without merging (asks first, optional closing comment); on a closed PR, reopen it
dToggle between draft and ready for review
oCheck out the PR's branch (gh pr checkout): only inside a clone of the PR's repo, asks first

After each action the PR is re-read from GitHub, and you get a desktop notification if notify-send is installed.

#Merging

The merge panel: readiness checklist, commits that land, and the merge options the repo allows

m opens the merge panel for the selected PR. It reads the PR and the repo's merge settings fresh, then shows:

  1. Readiness: checks, review, conflicts, whether the branch is up to date with its base (and whether the repo requires that), and draft.
  2. The commits that will land.
  3. What you can do now, and only that:
KeyShown whenDoes
sit's ready and the repo allows squashsquash and merge; you can edit the commit title (prefilled Title (#123))
mit's ready and the repo allows merge commitscreate a merge commit
rit's ready and the repo allows rebaserebase and merge
uthe base moved on and the repo requires up-to-date branchesupdate the branch (merges the base in; checks run again)
ait's blocked (checks or review pending) and the repo allows auto-mergeenable auto-merge: GitHub squash-merges it once everything passes
!it's blocked and you're a repo adminmerge anyway as admin, bypassing branch protection
dit's a draftmark it ready for review
oit has conflicts and you're in its clonecheck out the branch to resolve them (outside its clone, sangam shows the gh command instead)
q / Escalwaysclose the panel

Before merging, sangam asks whether to delete the branch on GitHub afterwards (unless the repo already does that, or the PR comes from a fork), then confirms once: Enter merges, Esc cancels. Your local checkout is never touched. The panel re-reads the PR after each step, so "update branch → enable auto-merge" works in one sitting.

#Keys

sangam opens in normal mode: letters are commands. / switches to typing a filter; Enter or Esc switches back.

Move and find

KeyAction
j / knext / previous PR
g / Gfirst / last PR
h / lprevious / next section
/filter the list
ssearch GitHub within the section
fcycle open / merged / closed / all
Ftoggle open ↔ all
uswitch account
Rreload from GitHub
Sadd / edit / delete / move sections, pin this repo
Eedit the sections file

Read

KeyAction
1 2 3 4overview / diff / checks / comments
Tabnext view
J / Kscroll the preview down / up
Ctrl+d / Ctrl+uscroll half a page
Entercurrent view full screen (failed logs in checks)
bopen in the browser
ycopy the link

Act

KeyAction
mmerge panel
aapprove
rrequest changes
ccomment
xclose / reopen
ocheck out the branch (in its clone)
ddraft ↔ ready for review
?show every key
q / Escquit

The merge panel's own keys are listed under Merging.

#Command line

sangam               open it in this folder (any terminal, in tmux or not)
sangam -C <dir>      open it as if started in <dir>
sangam doctor        check the dependencies and the GitHub sign-in
sangam --version     print the version
sangam --help        show the help

sangam doctor exits non-zero when something required is missing, so it also works in scripts.

#Using it inside tmux

sangam doesn't need tmux to be your terminal setup: it runs its own private tmux server for its layout, with its own socket and none of your tmux config. Run it in a tmux pane like any other program.

If you do use tmux, sangam can also be a popup on a key: prefix G opens it over whatever you're doing, in the current pane's folder, and prefix G again closes it.

With TPM: add this to your tmux config, above TPM's run line, then press prefix I:

set -g @plugin 'Theyashsawarkar/sangam'

TPM keeps its own copy in ~/.tmux/plugins/sangam; you don't need the sangam command installed separately for the popup.

Without TPM: with sangam cloned somewhere, add:

run-shell ~/path/to/sangam/sangam.tmux

Options (set them before TPM's run line):

OptionDefault
@sangam-keyGkey after the prefix that opens the popup (and closes it from inside); none binds nothing
@sangam-width90%popup width
@sangam-height88%popup height
@sangam-title sangam popup title
@sangam-launcheryour own popup command instead of display-popup. It's run with display-popup's arguments appended (-E -d DIR -T TITLE CMD), tmux formats expanded

For example, P instead of G, and a popup helper of your own:

set -g @sangam-key 'P'
set -g @sangam-launcher "~/.tmux/scripts/popup.sh '#{client_name}'"

#Files and environment

PathWhat
~/.config/sangam/sectionsyour sections (format)
~/.cache/sangam/cached lists and PR details (safe to delete), the last section and account
$XDG_RUNTIME_DIR/sangam.XXXXXX/one run's state and its private tmux socket, removed on quit

sangam respects XDG_CONFIG_HOME and XDG_CACHE_HOME. Other variables:

VariableUsed for
VISUAL, EDITORwriting reviews and comments, editing the sections file (default vi)
BAT_THEMEthe colors of diffs and descriptions (any bat --list-themes theme)
GH_CONFIG_DIR, GH_TOKENpassed through to gh as usual (sections with an account use that account's token)

Upgrading from tmux-gh-pr (sangam's earlier name): your ~/.config/gh-pr/sections is copied to ~/.config/sangam/sections the first time sangam runs. In tmux, replace Theyashsawarkar/tmux-gh-pr with Theyashsawarkar/sangam and rename any @gh-pr-* options to @sangam-*.

#How it works

sangam is a single Bash script that calls itself for each part of the screen:

#Troubleshooting

"gh isn't signed in to github.com" Run gh auth login. sangam only talks to github.com (not GitHub Enterprise Server yet).

Icons show as boxes or question marks Your terminal's font isn't a Nerd Font. Install one (e.g. JetBrainsMono Nerd Font) and select it in your terminal's settings.

Colors look washed out or wrong Your terminal needs truecolor (24-bit) support, which every modern terminal has. If it's set up but not advertised, export COLORTERM=truecolor in your shell's rc file.

sangam doctor says fzf is too old Your distribution's fzf predates 0.66 (common on Debian and Ubuntu). See Requirements for getting a current one.

A section always shows 0 Try its search on github.com (pull requests tab) or with gh search prs "<search>". If it finds PRs there, check the section's account: it needs access to those repos (private repos, org SSO). For an org with SAML SSO, authorize gh's token for it in your GitHub settings (Settings → Applications → Authorized OAuth Apps → GitHub CLI → Grant).

o (checkout) says it only works inside a clone Checkout switches the branch of the folder sangam was started in, so start sangam inside a clone of that PR's repo (or use sangam -C <clone>).

The diff or description has no colors Install bat. On Debian/Ubuntu it's called batcat; link it as bat (see Requirements).

The tmux popup opens but prefix G doesn't close it Close it with q. The popup uses your tmux prefix at the time it opened; if you changed your prefix since, reopen it. If you changed the key, set @sangam-key before TPM's run line, then reload tmux.

Something else Run sangam doctor, then open an issue with its output and what you did.

#Contributing

Bug reports, ideas and pull requests are welcome. Before a PR:

make check        # shellcheck + syntax + CLI smoke test (what CI runs)

Test changes by hand too: run bin/sangam from your clone. For the tmux popup, use a throwaway tmux server so your real one isn't touched:

tmux -L test -f /dev/null new -s t
tmux -L test run-shell "$PWD/sangam.tmux"     # then prefix (Ctrl+b) G

Theyashsawarkar/pr-playground is a public repo with one open PR per merge situation (clean, conflicting, behind its base, failing CI, draft, waiting for a review), handy for trying the merge panel. Every change gets an entry in CHANGELOG.md. More notes for contributors (and AI coding agents) are in CLAUDE.md.

#Roadmap

#License

MIT. sangam is part of Vayu, a keyboard-driven Arch Linux desktop, and works anywhere on its own. Built on the shoulders of gh, fzf, tmux, jq and bat.