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:
Bastien Chanot
2026-05-21 05:14:12 +02:00
co-authored by Claude
parent a4558ee805
commit cb1e8cd814
3 changed files with 24 additions and 1 deletions
+10 -1
View File
@@ -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}"