diff --git a/.gitignore b/.gitignore index 0992648..a0e1425 100644 --- a/.gitignore +++ b/.gitignore @@ -112,3 +112,6 @@ desktop.ini *~ .idea/ .vscode/ + +# Profile cache — written by lib/profile.sh, read by hooks/statusline.sh +.active-profile diff --git a/hooks/statusline.sh b/hooks/statusline.sh index f806a27..793e543 100755 --- a/hooks/statusline.sh +++ b/hooks/statusline.sh @@ -29,6 +29,15 @@ else fi PLAN_UPPER=$(echo "$PLAN" | tr '[:lower:]' '[:upper:]' | head -c1)$(echo "$PLAN" | tail -c+2) +# Active profile (written by lib/profile.sh set|apply|reset to /.active-profile). +# Read directly — `profile.sh current` is 12s+ and unusable in a statusline. +REPO="$(cd -P "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +PROFILE="?" +if [ -f "$REPO/.active-profile" ]; then + PROFILE=$(head -n1 "$REPO/.active-profile" | tr -d '[:space:]') + [ -z "$PROFILE" ] && PROFILE="?" +fi + # Session duration (from total_duration_ms) DURATION_MS=$(echo "$INPUT" | jq -r \ '.cost.total_duration_ms // 0' | cut -d. -f1) @@ -68,4 +77,4 @@ fi RESET="\033[0m" # Output: single line -echo -e "$MODEL | $FOLDER${BRANCH_STR} | $PLAN_UPPER | ${COLOR}${BAR}${RESET} ${PCT}% | ${DURATION}" +echo -e "$MODEL | $FOLDER${BRANCH_STR} | $PLAN_UPPER | ${PROFILE} | ${COLOR}${BAR}${RESET} ${PCT}% | ${DURATION}" diff --git a/lib/profile.sh b/lib/profile.sh index 0163758..3cd4ff3 100755 --- a/lib/profile.sh +++ b/lib/profile.sh @@ -45,6 +45,7 @@ SKILLS_DIR="$REPO/skills" DISABLED_DIR="$REPO/skills-disabled" PROFILES_DIR="$REPO/lib/profiles" TOGGLE_EXTERNAL="$REPO/lib/toggle-external.sh" +ACTIVE_CACHE="$REPO/.active-profile" # statusline reads this — keep fast (single-line file, profile name only) # Plugins that are toggle-managed by `set`. Anything NOT in this list is # never auto-disabled — protects always-on plugins (caveman, security-guidance, @@ -71,6 +72,14 @@ warn() { echo -e "${YELLOW}⚠${NC} $1"; } err() { echo -e "${RED}✗${NC} $1" >&2; } info() { echo -e "${BLUE}ℹ${NC} $1"; } +# Persist active-profile name for fast statusline lookup (cmd_current is slow +# — iterates every profile + every entry). Write profile name only; statusline +# reads the file directly without re-invoking this script. +write_active() { + local name="$1" + printf '%s\n' "$name" > "$ACTIVE_CACHE" 2>/dev/null || true +} + # ── Profile parsing ──────────────────────────────────────── # Read a profile file. Output one line per entry: "\t" @@ -351,6 +360,7 @@ cmd_apply() { while IFS=$'\t' read -r skill type; do enable_skill "$skill" "$type" done < <(read_profile "$prof") + write_active "$prof" } cmd_set() { @@ -406,6 +416,7 @@ cmd_reset() { fi info "Plugin state NOT touched. To re-enable a managed plugin disabled by 'set'," info "run: claude plugin enable @ (or: profile apply )" + write_active "none" } cmd_current() {