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 2, 2026

Thank you. What do "cmux shortcuts" refer to? Is there a way to bind custom commands to shortcuts in cmux?
I've read the cmux documentation, but I couldn't find it.

@azu
Copy link
Author

azu commented Mar 2, 2026

Ah, it was just a typo.
Since it looks at the currently focused tmux window, I think any shortcut key assignment would work.

@0x25a6
Copy link

0x25a6 commented Mar 2, 2026

Thank you for your reply.

I've completed up to step 3 of the setup, but I'm stuck on step 4. For example, when I try to call difit-cmux via Raycast, I get the error "Error: Could not detect focused_cwd from cmux sidebar-state".

The same thing happens when I run difit-cmux in a non-cmux environment, such as Ghostty. It only works as expected when difit-cmux is executed within cmux.

I watched your demo video where you called it from Alfred, and I'm wondering if there's some specific trick to it. Could you please share any insights if you have them?

@azu
Copy link
Author

azu commented Mar 3, 2026

This script is just being read from Alfred, but cmux may need to be configured to accept input from external processes.

You need to change the Access modes.
https://www.cmux.dev/docs/api

image image

@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