feat(profile,statusline): show active profile in statusline via .active-profile cache
`bash lib/profile.sh current` is 12s+ — far too slow to call from the statusline hook (runs on every keystroke). Add a one-line cache file at `<repo>/.active-profile`, written by `cmd_apply` and `cmd_reset`. The statusline reads the file directly with a single `head -n1`, no sub-shell into `profile.sh`. Behavior: - `bash lib/profile.sh set <name>` (which ends in `cmd_apply`) and `bash lib/profile.sh apply <name>` both write `<name>` to `<repo>/.active-profile`. - `bash lib/profile.sh reset` writes the literal `none`. - Statusline inserts the cached profile name between the plan segment and the context-bar segment, e.g. `Opus 4.7 | claude (master) | Max | full | ████░░░░░░ 42% | 3m`. - Missing or empty cache → statusline shows `?`. Cache file is gitignored — it tracks runtime state, not source. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a4558ee805
commit
cb1e8cd814
3
.gitignore
vendored
3
.gitignore
vendored
@ -112,3 +112,6 @@ desktop.ini
|
||||
*~
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Profile cache — written by lib/profile.sh, read by hooks/statusline.sh
|
||||
.active-profile
|
||||
|
||||
@ -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 <repo>/.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}"
|
||||
|
||||
@ -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: "<skill>\t<type>"
|
||||
@ -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 <name>@<marketplace> (or: profile apply <profile>)"
|
||||
write_active "none"
|
||||
}
|
||||
|
||||
cmd_current() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user