Desktop notification that takes you to the tmux pane that notified
After a bit of searching I didn’t find any obvious solution to the problem of: I want a process running in a tmux pane to send a desktop notification, and when I click that notification I’m taken directly to the source pane.
Here are a couple scripts that will achieve it (courtesy of opencode and the new codex-5.3 model).
It’s tailored to my setup:
- macos
- Kitty terminal emulator
- tmux running locally
Example invocation:
./tmux-notify-return.sh <title> <message>

It’s probably a little brittle, but I think it will address a pain point I’ve been facing with a flurry of agents running across different tmux windows and panes.
Here are the scripts:
tmux-return.sh
What it does: click-handler script run by Notification Center; activates Kitty, switches the correct tmux client/window/pane, and retries briefly to avoid focus races.
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 4 || $# -gt 5 ]]; then
echo "Usage: $0 <client\_tty> <socket\_path> <target\_win> <target\_pane> [target\_pane\_id]" >&2
exit 2
fi
client\_tty="$1"
socket\_path="$2"
target\_win="$3"
target\_pane="$4"
target\_pane\_id="${5:-}"
TMUX\_BIN="/opt/homebrew/bin/tmux"
OSA\_BIN="/usr/bin/osascript"
"$OSA\_BIN" -e 'tell application id "net.kovidgoyal.kitty" to activate'
for \_ in 1 2 3 4 5 6 7 8 9 10; do
"$TMUX\_BIN" -S "$socket\_path" switch-client -c "$client\_tty" -t "$target\_win" || true
"$TMUX\_BIN" -S "$socket\_path" select-window -t "$target\_win" || true
if [[ -n "$target\_pane\_id" ]]; then
"$TMUX\_BIN" -S "$socket\_path" select-pane -t "$target\_pane\_id" || true
else
"$TMUX\_BIN" -S "$socket\_path" select-pane -t "$target\_pane" || true
fi
if [[ -n "$target\_pane\_id" ]]; then
current\_pane="$($TMUX\_BIN -S "$socket\_path" display-message -p -c "$client\_tty" '#{pane\_id}' 2>/dev/null || true)"
[[ "$current\_pane" == "$target\_pane\_id" ]] && exit 0
else
current\_pane="$($TMUX\_BIN -S "$socket\_path" display-message -p -c "$client\_tty" '#{session\_name}:#{window\_index}.#{pane\_index}' 2>/dev/null || true)"
[[ "$current\_pane" == "$target\_pane" ]] && exit 0
fi
sleep 0.1
done
exit 1
tmux-notify-return.sh
What it does: captures the tmux pane running this command (TMUX_PANE), then sends a clickable notification whose click runs tmux-return.sh back to that captured pane.
#!/usr/bin/env bash
set -euo pipefail
# Send a clickable macOS notification that returns you to the tmux pane
# where this command was run.
TMUX\_BIN="/opt/homebrew/bin/tmux"
NOTIFIER\_BIN="/opt/homebrew/bin/terminal-notifier"
RETURN\_SCRIPT="/path/to/tmux-return.sh"
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
echo "Usage: $0 [title] [message]"
echo " title Notification title (default: Return to tmux pane)"
echo " message Notification body (default: Click to jump back in Kitty)"
exit 0
fi
title="${1:-Return to tmux pane}"
message="${2:-Click to jump back in Kitty}"
if [[ ! -x "$TMUX\_BIN" ]]; then
echo "tmux not found at $TMUX\_BIN" >&2
exit 1
fi
if [[ ! -x "$NOTIFIER\_BIN" ]]; then
echo "terminal-notifier not found at $NOTIFIER\_BIN" >&2
exit 1
fi
if [[ ! -x "$RETURN\_SCRIPT" ]]; then
echo "return script not executable: $RETURN\_SCRIPT" >&2
exit 1
fi
# Capture the pane that is actually running this process when possible.
# In tmux shells, TMUX\_PANE is stable even if the user navigates away later.
source\_pane="${TMUX\_PANE:-}"
if [[ -n "$source\_pane" ]]; then
target\_win="$($TMUX\_BIN display-message -p -t "$source\_pane" '#S:#I')"
target\_pane="$($TMUX\_BIN display-message -p -t "$source\_pane" '#S:#I.#P')"
target\_pane\_id="$($TMUX\_BIN display-message -p -t "$source\_pane" '#{pane\_id}')"
else
target\_win="$($TMUX\_BIN display-message -p '#S:#I')"
target\_pane="$($TMUX\_BIN display-message -p '#S:#I.#P')"
target\_pane\_id="$($TMUX\_BIN display-message -p '#{pane\_id}')"
fi
client\_tty="$($TMUX\_BIN display-message -p '#{client\_tty}')"
socket\_path="$($TMUX\_BIN display-message -p '#{socket\_path}')"
if [[ -z "$client\_tty" || -z "$socket\_path" || -z "$target\_win" || -z "$target\_pane" || -z "$target\_pane\_id" ]]; then
echo "failed to capture tmux target metadata" >&2
exit 1
fi
printf -v q\_client '%q' "$client\_tty"
printf -v q\_socket '%q' "$socket\_path"
printf -v q\_win '%q' "$target\_win"
printf -v q\_pane '%q' "$target\_pane"
printf -v q\_pane\_id '%q' "$target\_pane\_id"
exec\_cmd="$RETURN\_SCRIPT $q\_client $q\_socket $q\_win $q\_pane $q\_pane\_id"
"$NOTIFIER\_BIN" \
-title "$title" \
-subtitle "$target\_pane" \
-message "$message" \
-execute "$exec\_cmd"