Skip to content

Instantly share code, notes, and snippets.

@leonjang88
Created March 2, 2026 21:20
Show Gist options
  • Select an option

  • Save leonjang88/1874086da13a8d99bce8c51e94630500 to your computer and use it in GitHub Desktop.

Select an option

Save leonjang88/1874086da13a8d99bce8c51e94630500 to your computer and use it in GitHub Desktop.
Claude Code (cc) tmux session management commands for .bashrc
#!/bin/bash
# Claude Code (cc) Commands for .bashrc
# Quick tmux-based session management for Claude Code
# Context directories
_CC_HA="$HOME/pezbox/infra/homeAssistant"
_CC_HW="$HOME/pezbox/hiveworth"
_CC_RS="$HOME/pezbox/redfin-scraper"
# Resolve context name to directory
_cc_dir() {
case "$1" in
ha) echo "$_CC_HA" ;;
hw) echo "$_CC_HW" ;;
rs) echo "$_CC_RS" ;;
pb) echo "$HOME/pezbox" ;;
*) echo "$HOME/pezbox" ;;
esac
}
# Resolve context name to session prefix
_cc_prefix() {
case "$1" in
ha) echo "cc-ha" ;;
hw) echo "cc-hw" ;;
rs) echo "cc-rs" ;;
pb) echo "cc-pezbox" ;;
*) echo "cc-pezbox" ;;
esac
}
# Create a new tmux session, send claude into it, attach
_cc_new_session() {
local session_name="$1"
local work_dir="$2"
local cmd="$3"
tmux new-session -d -s "$session_name" -c "$work_dir"
tmux send-keys -t "$session_name" "$cmd" Enter
tmux attach -t "$session_name"
}
# Picker for multiple sessions
_cc_pick_session() {
local sessions="$1"
echo "Active Claude sessions:" >&2
echo "$sessions" | nl >&2
echo -n "Which session? (number): " >&2
read choice </dev/tty
echo "$sessions" | sed -n "${choice}p"
}
# Pick a project and resume into it
_cc_pick_project_and_resume() {
echo "Available projects:" >&2
echo " 1) ha - Home Assistant ($_CC_HA)" >&2
echo " 2) hw - Hiveworth ($_CC_HW)" >&2
echo " 3) rs - Redfin Scraper ($_CC_RS)" >&2
echo " 4) pb - Pezbox ($HOME/pezbox)" >&2
echo " 5) current - Current directory ($PWD)" >&2
echo "" >&2
echo -n "Which project? (number): " >&2
read choice </dev/tty
local ctx work_dir prefix
case "$choice" in
1) ctx="ha"; work_dir="$_CC_HA"; prefix="cc-ha" ;;
2) ctx="hw"; work_dir="$_CC_HW"; prefix="cc-hw" ;;
3) ctx="rs"; work_dir="$_CC_RS"; prefix="cc-rs" ;;
4) ctx="pb"; work_dir="$HOME/pezbox"; prefix="cc-pezbox" ;;
5) ctx="current"; work_dir="$PWD"; prefix="cc-$(basename "$PWD")" ;;
*) echo "Invalid selection"; return 1 ;;
esac
local session_name="${prefix}-$(date +%m%d-%I%M%p | tr '[:upper:]' '[:lower:]')"
local cmd="claude --dangerously-skip-permissions --continue"
echo "Starting new session in $work_dir..."
_cc_new_session "$session_name" "$work_dir" "$cmd"
}
# Switch to a different project within the current tmux session
_cc_switch_project_in_session() {
echo "Switch to project:" >&2
echo " 1) ha - Home Assistant" >&2
echo " 2) hw - Hiveworth" >&2
echo " 3) rs - Redfin Scraper" >&2
echo " 4) pb - Pezbox" >&2
echo " 5) current - Stay in current directory" >&2
echo "" >&2
echo -n "Which project? (number): " >&2
read choice </dev/tty
local work_dir
case "$choice" in
1) work_dir="$_CC_HA" ;;
2) work_dir="$_CC_HW" ;;
3) work_dir="$_CC_RS" ;;
4) work_dir="$HOME/pezbox" ;;
5) work_dir="$PWD" ;;
*) echo "Invalid selection"; return 1 ;;
esac
echo "Switching to $work_dir..."
cd "$work_dir"
claude --dangerously-skip-permissions --continue
}
# cc [context] — new Claude Code session
cc() {
# cc clear [all|context|session-name]
if [ "$1" = "clear" ]; then
local sessions
# No arg: interactive picker
if [ -z "$2" ]; then
sessions=$(tmux ls 2>/dev/null | grep "^cc-" | cut -d: -f1)
if [ -z "$sessions" ]; then
echo "No Claude Code sessions found."
return
fi
echo "Select session(s) to kill:" >&2
echo "$sessions" | nl >&2
echo "" >&2
echo "Enter number(s) separated by spaces (or 'all' for all):" >&2
read choices </dev/tty
if [ "$choices" = "all" ]; then
echo "🔥 Killing ALL Claude Code sessions"
echo "$sessions" | xargs -I {} tmux kill-session -t {}
else
for choice in $choices; do
local selected
selected=$(echo "$sessions" | sed -n "${choice}p")
if [ -n "$selected" ]; then
echo "Killing $selected"
tmux kill-session -t "$selected"
fi
done
fi
echo "Done."
return
fi
# cc clear all - nuclear mode
if [ "$2" = "all" ]; then
sessions=$(tmux ls 2>/dev/null | grep "^cc-" | cut -d: -f1)
if [ -z "$sessions" ]; then
echo "No Claude Code sessions found."
else
echo "🔥 Nuclear clear - killing ALL Claude Code sessions:"
echo "$sessions"
echo "$sessions" | xargs -I {} tmux kill-session -t {}
echo "Done."
fi
return
fi
# Check if it's a full session name
if tmux has-session -t "$2" 2>/dev/null; then
echo "Killing session: $2"
tmux kill-session -t "$2"
echo "Done."
return
fi
# Otherwise treat as context prefix
local prefix
prefix=$(_cc_prefix "$2")
sessions=$(tmux ls 2>/dev/null | grep "^${prefix}" | cut -d: -f1)
if [ -z "$sessions" ]; then
echo "No sessions matching '${prefix}' or '$2' found."
else
echo "Killing ${prefix} sessions:"
echo "$sessions"
echo "$sessions" | xargs -I {} tmux kill-session -t {}
echo "Done."
fi
return
fi
local ctx="$1"
local work_dir
work_dir=$(_cc_dir "$ctx")
local prefix
prefix=$(_cc_prefix "$ctx")
local cmd="claude --dangerously-skip-permissions"
if [ -n "$TMUX" ]; then
cd "$work_dir" && eval "$cmd"
else
local session_name="${prefix}-$(date +%m%d-%I%M%p | tr '[:upper:]' '[:lower:]')"
_cc_new_session "$session_name" "$work_dir" "$cmd"
fi
}
# ccs — quick Claude session switcher (for use within tmux)
ccs() {
if [ -z "$TMUX" ]; then
echo "Not in a tmux session. Use ccr instead." >&2
return 1
fi
# Show resume menu directly
claude --dangerously-skip-permissions --resume
}
# ccr — resume any Claude Code session (shows all projects)
ccr() {
local cmd="claude --dangerously-skip-permissions --continue"
# If already in tmux, handle session switching differently
if [ -n "$TMUX" ]; then
if ! tty -s; then
echo "❌ You're already in a tmux session but have no TTY (probably inside Claude)." >&2
echo " Exit this session first (exit or Ctrl-D), then run ccr from your terminal." >&2
return 1
fi
# Find ALL Claude Code sessions
local sessions
sessions=$(tmux ls 2>/dev/null | grep "^cc-" | cut -d: -f1)
if [ -z "$sessions" ]; then
echo "No other Claude sessions found. Continue in current session." >&2
eval "$cmd"
return
fi
# Show current session and available options
echo "Current session: $(tmux display-message -p '#S')" >&2
echo "" >&2
echo "Available Claude sessions:" >&2
local i=1
while IFS= read -r session; do
echo " $i) $session" >&2
i=$((i+1))
done <<< "$sessions"
echo " c) Continue in current directory" >&2
echo " n) New project" >&2
echo -n "Choice: " >&2
read choice </dev/tty
if [ "$choice" = "c" ]; then
eval "$cmd"
return
elif [ "$choice" = "n" ]; then
_cc_switch_project_in_session
return
elif [[ "$choice" =~ ^[0-9]+$ ]]; then
local selected_session=$(echo "$sessions" | sed -n "${choice}p")
if [ -n "$selected_session" ]; then
echo "Switching to session: $selected_session"
tmux switch-client -t "$selected_session"
else
echo "Invalid selection"
fi
return
else
echo "Invalid selection"
return
fi
fi
# Find ALL Claude Code sessions across all projects
local sessions
sessions=$(tmux ls 2>/dev/null | grep "^cc-" | cut -d: -f1)
if [ -z "$sessions" ]; then
# No sessions exist - start a new one in current dir or pezbox
local work_dir="${PWD}"
if [[ ! "$PWD" =~ pezbox ]]; then
work_dir="$HOME/pezbox"
fi
local session_name="cc-pezbox-$(date +%m%d-%I%M%p | tr '[:upper:]' '[:lower:]')"
echo "No Claude sessions found. Starting new session..."
_cc_new_session "$session_name" "$work_dir" "$cmd"
elif [ "$(echo "$sessions" | wc -l)" -eq 1 ]; then
# Only one session - ask if they want to attach or start new
echo "Found 1 session: $sessions" >&2
echo "" >&2
echo " 1) Attach to existing session" >&2
echo " 2) Resume into another project" >&2
echo -n "Choice: " >&2
read choice </dev/tty
if [ "$choice" = "1" ]; then
tmux attach -t "$sessions"
elif [ "$choice" = "2" ]; then
_cc_pick_project_and_resume
else
echo "Invalid selection"
fi
else
# Multiple sessions - show picker with ALL of them + new project option
echo "All Claude sessions:" >&2
echo "$sessions" | nl >&2
local total=$(echo "$sessions" | wc -l)
local next=$((total + 1))
echo " $next) Resume into another project" >&2
echo "" >&2
echo -n "Which session? (number): " >&2
read choice </dev/tty
if [ "$choice" = "$next" ]; then
_cc_pick_project_and_resume
else
local selected
selected=$(echo "$sessions" | sed -n "${choice}p")
if [ -n "$selected" ]; then
tmux attach -t "$selected"
else
echo "Invalid selection"
fi
fi
fi
}
# ============================================
# BONUS: ccrename skill (use as /ccrename in Claude)
# ============================================
#
# This skill analyzes recent work in the conversation and renames
# the tmux session with a descriptive summary.
#
# Usage in Claude Code: /ccrename
#
# The skill will:
# 1. Analyze the conversation history
# 2. Generate a short descriptive name
# 3. Rename the tmux session to: cc-[project]-[description]
#
# Example renames:
# cc-ha-0302-0345pm → cc-ha-fix-hvac-sensors
# cc-rs-0302-0400pm → cc-rs-add-rental-pipeline
#
# ============================================
# Manual version for bash (if you want to rename from terminal)
ccrename() {
if [ -z "$TMUX" ]; then
echo "Not in a tmux session."
return 1
fi
local current=$(tmux display-message -p '#S')
echo "Current session: $current"
echo -n "New name: "
read new_name </dev/tty
if [ -n "$new_name" ]; then
tmux rename-session "$new_name"
echo "Renamed to: $new_name"
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment