Skip to content

Instantly share code, notes, and snippets.

@mostlyfine
Created April 10, 2026 02:03
Show Gist options
  • Select an option

  • Save mostlyfine/62bd174885da2db51ef24142faf0608f to your computer and use it in GitHub Desktop.

Select an option

Save mostlyfine/62bd174885da2db51ef24142faf0608f to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -euo pipefail
# copilot-ps: Monitor GitHub Copilot CLI sessions running in tmux panes
WATCH_INTERVAL=1
BOLD='\033[1m'
GREEN='\033[32m'
YELLOW='\033[33m'
DIM='\033[2m'
RESET='\033[0m'
usage() {
echo "Usage: copilot-ps [-w|--watch [INTERVAL]]"
echo " -w, --watch [SEC] Watch mode (default: ${WATCH_INTERVAL}s interval)"
exit 0
}
check_deps() {
command -v tmux &>/dev/null || { echo "error: tmux is not installed" >&2; exit 1; }
tmux info &>/dev/null 2>&1 || { echo "error: tmux server is not running" >&2; exit 1; }
tmux list-sessions &>/dev/null 2>&1 || { echo "error: no tmux sessions found" >&2; exit 1; }
}
parse_args() {
watch_mode=false
while [[ $# -gt 0 ]]; do
case "$1" in
-w|--watch)
watch_mode=true
[[ "${2:-}" =~ ^[0-9]+$ ]] && { WATCH_INTERVAL="$2"; shift; }
shift ;;
-h|--help) usage ;;
*) echo "Unknown option: $1" >&2; usage ;;
esac
done
}
is_copilot_pane() {
local cmd="$1" pane_pid="$2"
[[ "$cmd" == "node" ]] || return 1
local pids
pids=$(pgrep -P "$pane_pid" 2>/dev/null | tr '\n' ',' | sed 's/,$//' || true)
[[ -z "$pids" ]] && return 1
ps -o command= -p "$pids" 2>/dev/null | grep -q "copilot"
}
# πŸ€– prefix = running, no prefix = idle
title_status() { [[ "$1" == "πŸ€–"* ]] && echo "running" || echo "idle"; }
title_task() {
local task="${1#πŸ€–}"
task="${task# }"
[[ ${#task} -gt 45 ]] && task="${task:0:42}..."
echo "$task"
}
get_list_copilot_panes() {
while IFS='|' read -r _pane cmd dir pane_pid title; do
is_copilot_pane "$cmd" "$pane_pid" || continue
local status task
status=$(title_status "$title")
task=$(title_task "$title")
echo "${status}|${task}|${dir##*/}"
done < <(tmux list-panes -a -F "#{session_name}:#{window_index}.#{pane_index}|#{pane_current_command}|#{pane_current_path}|#{pane_pid}|#{pane_title}")
}
render() {
printf "${BOLD} %-45s %s${RESET}\n" "TASK" "DIR"
printf '%.0s─' {1..60}; echo
local found=0 icon color
while IFS='|' read -r status task dir; do
found=$((found + 1))
case "$status" in
running) icon="●"; color="$GREEN" ;;
idle) icon="β—‹"; color="$YELLOW" ;;
*) icon="?"; color="$DIM" ;;
esac
printf "${color}%s${RESET} %-45s ${DIM}%s${RESET}\n" "$icon" "$task" "$dir"
done < <(get_list_copilot_panes)
[[ $found -eq 0 ]] && echo "No Copilot sessions found in tmux."
printf "\n${DIM}Updated: $(date '+%H:%M:%S')${RESET}"
}
watch_loop() {
trap 'tput cnorm; tput clear; exit 0' INT TERM
trap 'tput clear' WINCH
tput civis; tput clear
while true; do
local buf
buf=$(render)
tput home
printf "${DIM}copilot-ps (every ${WATCH_INTERVAL}s, Ctrl-C to stop)${RESET}\n\n"
printf '%s' "$buf"
tput ed
sleep "$WATCH_INTERVAL"
done
}
# --- Main ---
check_deps
parse_args "$@"
if $watch_mode; then
watch_loop
else
render
echo
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment