#!/bin/bash # Launch tmux session with an LLM in fzf-selected project directories SESSION="ai" # Dependency checks for cmd in fzf tmux claude; do if ! command -v "$cmd" &>/dev/null; then echo "Error: $cmd is not installed" >&2 exit 1 fi done # Claude command — separated for safe editing AI_CMD="claude" AI_INSTRUCTIONS='Read docs/protocols.org and follow all instructions.' # Build candidate directory list build_candidates() { candidates=() [ -d "$HOME/.emacs.d" ] && candidates+=("~/.emacs.d") if [ -d "$HOME/code" ]; then while IFS= read -r d; do candidates+=("~/${d#"$HOME"/}") done < <(find "$HOME/code" -maxdepth 1 -mindepth 1 -type d | sort) fi if [ -d "$HOME/projects" ]; then while IFS= read -r d; do candidates+=("~/${d#"$HOME"/}") done < <(find "$HOME/projects" -maxdepth 1 -mindepth 1 -type d | sort) fi } # If session exists, add new windows to it if tmux has-session -t "$SESSION" 2>/dev/null; then # Get existing window names to filter duplicates existing=$(tmux list-windows -t "$SESSION" -F '#{window_name}') build_candidates # Filter out candidates that already have a window open filtered=() for c in "${candidates[@]}"; do name="$(basename "${c/#\~/$HOME}")" if ! echo "$existing" | grep -qxF "$name"; then filtered+=("$c") fi done if [ ${#filtered[@]} -eq 0 ]; then echo "All projects already have windows open." else selections=$(printf '%s\n' "${filtered[@]}" | fzf --multi --height=70% --reverse) if [ -n "$selections" ]; then selected=() while IFS= read -r line; do selected+=("$line") done <<<"$selections" first_wid="" for entry in "${selected[@]}"; do dir="${entry/#\~/$HOME}" name="$(basename "$dir")" wid=$(tmux new-window -t "$SESSION" -n "$name" -c "$dir" -P -F '#{window_id}') sleep 0.1 tmux send-keys -t "$wid" "$AI_CMD \"$AI_INSTRUCTIONS\"" Enter [ -z "$first_wid" ] && first_wid="$wid" done tmux select-window -t "$first_wid" fi fi # Attach or switch to session if [ -n "$TMUX" ]; then tmux switch-client -t "$SESSION" else tmux attach-session -t "$SESSION" fi exit 0 fi # New session: select projects and create session build_candidates selections=$(printf '%s\n' "${candidates[@]}" | fzf --multi --height=70% --reverse) [ -z "$selections" ] && exit 0 selected=() while IFS= read -r line; do selected+=("$line") done <<<"$selections" # Create session with first selection first="${selected[0]}" dir="${first/#\~/$HOME}" name="$(basename "$dir")" tmux new-session -d -s "$SESSION" -n "$name" -c "$dir" -P -F '#{window_id}' > /dev/null first_wid=$(tmux list-windows -t "$SESSION" -F '#{window_id}' | head -1) tmux send-keys -t "$first_wid" "$AI_CMD \"$AI_INSTRUCTIONS\"" Enter # Create remaining windows for entry in "${selected[@]:1}"; do dir="${entry/#\~/$HOME}" name="$(basename "$dir")" wid=$(tmux new-window -t "$SESSION" -n "$name" -c "$dir" -P -F '#{window_id}') tmux send-keys -t "$wid" "$AI_CMD \"$AI_INSTRUCTIONS\"" Enter done # Select first window and attach or switch tmux select-window -t "$first_wid" if [ -n "$TMUX" ]; then tmux switch-client -t "$SESSION" else tmux attach-session -t "$SESSION" fi