#!/usr/bin/env bash # claude-profile — Launch Claude Code with a named config profile # Profiles are directories matching ~/.claude-*/ # Usage: # claude-profile # interactive menu # claude-profile # direct launch (e.g. claude-profile work) set -euo pipefail DEFAULT_DIR="$HOME/.claude" PROFILE_PATTERN="$HOME/.claude-*" # Emit a WezTerm user-var escape sequence to trigger profile-based theming. # WezTerm decodes the base64 value and fires a 'user-var-changed' event. # Safe to call in non-WezTerm terminals — the escape sequence is silently ignored. set_wezterm_profile() { local profile_name="$1" printf '\e]1337;SetUserVar=%s=%s\a' CLAUDE_PROFILE "$(printf '%s' "$profile_name" | base64)" } # Reset WezTerm theme when the script exits (e.g., Claude session ends) reset_wezterm_profile() { printf '\e]1337;SetUserVar=%s=%s\a' CLAUDE_PROFILE "$(printf '%s' '_reset' | base64)" } trap reset_wezterm_profile EXIT # Sync all repos before starting a session SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SYNC_SCRIPT="${SCRIPT_DIR}/sync-repos" if [[ -x "$SYNC_SCRIPT" ]]; then echo "Syncing repos..." "$SYNC_SCRIPT" || echo "Warning: some repos failed to sync (continuing anyway)" echo "" fi # Gather profiles profiles=() for dir in $PROFILE_PATTERN; do [[ -d "$dir" ]] || continue name="${dir##*/.claude-}" profiles+=("$name") done # Direct invocation with a profile name if [[ ${1:-} ]]; then target="$HOME/.claude-$1" if [[ -d "$target" ]]; then export CLAUDE_CONFIG_DIR="$target" set_wezterm_profile "$1" echo "Using profile: $1 ($target)" claude "${@:2}" exit $? else echo "Profile '$1' not found. Create it with: mkdir -p $target" >&2 exit 1 fi fi # Build menu echo "Claude Code profiles:" echo "" i=1 echo " $i) default (~/.claude)" options=("default") for name in "${profiles[@]}"; do ((i++)) echo " $i) $name (~/.claude-$name)" options+=("$name") done echo "" read -rp "Choose profile [1]: " choice choice="${choice:-1}" # Validate choice if ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#options[@]} )); then echo "Invalid choice." >&2 exit 1 fi selected="${options[$((choice - 1))]}" if [[ "$selected" == "default" ]]; then echo "Using default profile ($DEFAULT_DIR)" export CLAUDE_CONFIG_DIR="$DEFAULT_DIR" set_wezterm_profile "default" else target="$HOME/.claude-$selected" echo "Using profile: $selected ($target)" export CLAUDE_CONFIG_DIR="$target" set_wezterm_profile "$selected" fi # Load the context CONTEXT_LOADER="${SCRIPT_DIR}/context-load" if [[ ! -x "$CONTEXT_LOADER" ]]; then echo "Error: context-load not found at $CONTEXT_LOADER" >&2 exit 1 fi context="$("$CONTEXT_LOADER")" if [[ -n "$context" ]]; then claude --append-system-prompt "$context" "$@" else claude "$@" fi