Created
March 6, 2026 14:13
-
-
Save chrisbolin/9b11cfadfdd1b5e95e829ac438b1b7ab to your computer and use it in GitHub Desktop.
start: tmux + claude code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # start — tmux dev session manager | |
| # Creates a split-pane dev layout: claude | shell / git-status watch | |
| # Pure Bash version (no dependencies beyond tmux + fzf) | |
| set -euo pipefail | |
| # ── Helpers ────────────────────────────────────────────────────────────────── | |
| sanitize_session_name() { | |
| echo "${1//[.:]/_}" | |
| } | |
| list_sessions() { | |
| local prefix="$1" | |
| tmux list-sessions -F '#{session_name} #{session_windows}' 2>/dev/null \ | |
| | awk -F'\t' -v p="$prefix" '$1 ~ "^"p { print $1 "\t" $2 }' | |
| } | |
| next_session_name() { | |
| local base="$1" | |
| if ! tmux has-session -t "$base" 2>/dev/null; then | |
| echo "$base" | |
| return | |
| fi | |
| local i=2 | |
| while tmux has-session -t "${base}-${i}" 2>/dev/null; do | |
| ((i++)) | |
| done | |
| echo "${base}-${i}" | |
| } | |
| create_session() { | |
| local name="$1" | |
| tmux new-session -d -s "$name" -n main | |
| tmux send-keys -t "$name" "claude" C-m | |
| tmux split-window -h -t "$name" | |
| tmux split-window -v -t "$name" | |
| tmux send-keys -t "$name" "watch -n 1 git status" C-m | |
| tmux select-pane -t "$name:0.0" | |
| } | |
| attach_session() { | |
| exec tmux attach -t "$1" | |
| } | |
| # ── Main ───────────────────────────────────────────────────────────────────── | |
| if ! command -v tmux &>/dev/null; then | |
| echo "error: tmux not found" >&2 | |
| exit 1 | |
| fi | |
| base="dev-$(sanitize_session_name "$(basename "$PWD")")" | |
| # --new / -n: skip picker, create new session directly | |
| if [[ "${1:-}" == "--new" || "${1:-}" == "-n" ]]; then | |
| name=$(next_session_name "$base") | |
| create_session "$name" | |
| attach_session "$name" | |
| fi | |
| # Read existing sessions into arrays | |
| names=() | |
| descs=() | |
| while IFS=$'\t' read -r sname windows; do | |
| names+=("$sname") | |
| if [[ "$windows" == 1 ]]; then | |
| descs+=("$sname — 1 window") | |
| else | |
| descs+=("$sname — $windows windows") | |
| fi | |
| done < <(list_sessions "$base") | |
| # No existing sessions: create one directly | |
| if [[ ${#names[@]} -eq 0 ]]; then | |
| create_session "$base" | |
| attach_session "$base" | |
| fi | |
| # Build fzf picker | |
| descs+=("+ New session — Create a new dev session") | |
| descs+=("+ New session (kill others) — Create new session and kill all others") | |
| if ! command -v fzf &>/dev/null; then | |
| # Fallback: simple select menu if fzf isn't available | |
| echo "start — pick a session:" >&2 | |
| for i in "${!descs[@]}"; do | |
| printf " %d) %s\n" "$((i + 1))" "${descs[$i]}" >&2 | |
| done | |
| printf "Choose [1-%d]: " "${#descs[@]}" >&2 | |
| read -r choice | |
| if [[ -z "$choice" ]] || ! [[ "$choice" =~ ^[0-9]+$ ]] \ | |
| || ((choice < 1 || choice > ${#descs[@]})); then | |
| exit 0 | |
| fi | |
| idx=$((choice - 1)) | |
| else | |
| selection=$(printf '%s\n' "${descs[@]}" | fzf --height=~20 --reverse \ | |
| --header="start" --prompt="session> " \ | |
| --color="header:magenta,pointer:magenta,prompt:magenta") || exit 0 | |
| # Find index of selected item | |
| idx=-1 | |
| for i in "${!descs[@]}"; do | |
| if [[ "${descs[$i]}" == "$selection" ]]; then | |
| idx=$i | |
| break | |
| fi | |
| done | |
| [[ $idx -eq -1 ]] && exit 0 | |
| fi | |
| total=${#descs[@]} | |
| new_idx=$((total - 2)) | |
| kill_idx=$((total - 1)) | |
| if [[ $idx -eq $kill_idx ]]; then | |
| # Kill all existing sessions and start fresh | |
| for sname in "${names[@]}"; do | |
| tmux kill-session -t "$sname" 2>/dev/null || true | |
| done | |
| create_session "$base" | |
| attach_session "$base" | |
| elif [[ $idx -eq $new_idx ]]; then | |
| name=$(next_session_name "$base") | |
| create_session "$name" | |
| attach_session "$name" | |
| else | |
| attach_session "${names[$idx]}" | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment