Skip to content

Instantly share code, notes, and snippets.

@azu
Last active March 7, 2026 11:40
Show Gist options
  • Select an option

  • Save azu/cef84c98aeef832d43dfb640c7e321f5 to your computer and use it in GitHub Desktop.

Select an option

Save azu/cef84c98aeef832d43dfb640c7e321f5 to your computer and use it in GitHub Desktop.
cmux browser open-split difit review
#!/bin/bash
# =============================================================================
# difit-auto-detect.sh
# Automatically detects git state and opens appropriate diff view
# with difit in a cmux browser split pane.
#
# Dependencies:
# - cmux https://cmux.app/
# - difit https://github.com/yoshiko-pg/difit
#
# Setup:
# 1. Install cmux
# Download from https://cmux.app/ and move to /Applications/
# 1.1 Change "Socakge Control Mode" to "Automation Mode"
#
# 2. Install difit
# npm install -g difit
#
# 3. Make this script executable and place it somewhere on your PATH
# chmod +x difit-auto-detect.sh
# mv difit-auto-detect.sh /usr/local/bin/difit-cmux
#
# 4. (Optional) Bind to a global shortcut via your preferred launcher
# e.g. Alfred, Karabiner Elements, Raycast, etc.
#
# Usage:
# Run this script while cmux is focused on a git repository pane.
# The script will:
# - Detect the current branch and default branch
# - Show diff against merge-base (for feature branches)
# - Show diff against HEAD (for default branch or detached HEAD)
# - Open the result in a cmux browser split at http://localhost:4966/
# - Automatically shut down the difit server when the browser pane is closed
# =============================================================================
CMUX="/Applications/cmux.app/Contents/Resources/bin/cmux"
# Get the working directory of the currently focused cmux pane
targetDir=$("$CMUX" sidebar-state | awk -F= '/^focused_cwd=/{print $2}')
if [[ -z "$targetDir" ]]; then
echo "Error: Could not detect focused_cwd from cmux sidebar-state" >&2
exit 1
fi
cd "$targetDir" || exit 1
# Provide immediate feedback so the user knows the script is running
"$CMUX" notify --title "Difit" --body "Loading diff: $targetDir"
echo "πŸ” Detecting git state..."
currentBranch=$(git rev-parse --abbrev-ref HEAD)
# Detect default branch (origin/HEAD β†’ origin/main β†’ origin/master)
defaultBranch=$(git symbolic-ref refs/remotes/origin/HEAD --short 2>/dev/null)
if [[ -z "$defaultBranch" ]]; then
if git rev-parse --verify origin/main >/dev/null 2>&1; then
defaultBranch="origin/main"
elif git rev-parse --verify origin/master >/dev/null 2>&1; then
defaultBranch="origin/master"
fi
fi
# Kill any process using port 4966
kill_difit() {
lsof -ti:4966 | xargs kill 2>/dev/null
}
trap kill_difit EXIT INT TERM
difitArgs=(--mode unified --no-open --clean --include-untracked --port 4966)
echo "πŸš€ Starting difit server..."
if [[ -z "$defaultBranch" ]] || [[ "$currentBranch" == "${defaultBranch#origin/}" ]]; then
# On the default branch or no remote β€” diff working directory against HEAD
difit working "${difitArgs[@]}" &
else
mergeBase=$(git merge-base HEAD "$defaultBranch" 2>/dev/null)
if [[ -z "$mergeBase" ]]; then
# Fallback if merge-base cannot be determined
difit working "${difitArgs[@]}" &
else
echo "πŸ”€ Branch: $currentBranch (base: ${defaultBranch#origin/})"
difit "$mergeBase" . "${difitArgs[@]}" &
fi
fi
# Wait until the difit server is ready
while ! curl -s http://localhost:4966/ > /dev/null 2>&1; do
sleep 0.5
done
# Open in a cmux browser split and get the surface ID
browserSurface=$("$CMUX" --json browser open-split "http://localhost:4966/" | grep -o '"ref" *: *"surface:[^"]*"' | head -1 | grep -o 'surface:[0-9]*')
if [[ -z "$browserSurface" ]]; then
echo "Warning: Could not get browser surface ID, difit server running in background" >&2
wait
exit 0
fi
# Wait until the browser pane is closed, then shut down the server
while "$CMUX" surface-health 2>&1 | grep -q "$browserSurface"; do
sleep 1
done
kill_difit
@0x25a6
Copy link

0x25a6 commented Mar 7, 2026

Oh! So there was such a setting. I completely overlooked it.
Thank you very much for the screenshots too. I truly appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment