Skip to content

Commit f8bffb5

Browse files
committed
chore(FR-2158): add model and token usage info to statusline (#5623)
Resolves #5622 ([FR-2158](https://lablup.atlassian.net/browse/FR-2158)) ## Summary - Read session JSON from stdin once and reuse for both workspace extraction and model/token parsing - Always display model name and context window usage percentage in the statusline - Fall back to model/token-only display on non-Jira branches (e.g. `main`) or when PR/Jira cache is missing ![CleanShot 2026-02-26 at 15.35.43@2x.png](https://app.graphite.com/user-attachments/assets/2f94a58a-30be-4889-aefd-06ad713fd1d0.png) ## Test plan - [ ] Verify statusline shows model + token info on `main` branch - [ ] Verify statusline shows model + token + Jira info on `FR-XXXX` branches with cached data [FR-2158]: https://lablup.atlassian.net/browse/FR-2158?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent c445e6a commit f8bffb5

2 files changed

Lines changed: 54 additions & 9 deletions

File tree

.claude/scripts/statusline.sh

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,58 @@ _refresh_jira() {
5050
) &disown 2>/dev/null
5151
}
5252

53+
# ── Read all stdin once (can only be read once) ───────────
54+
SESSION_JSON=$(cat)
55+
56+
# ── Extract model + token info ───────────────────────────
57+
MODEL_PART=$(echo "$SESSION_JSON" | python3 -c '
58+
import json, sys
59+
try:
60+
data = json.load(sys.stdin)
61+
model = (data.get("model") or {}).get("display_name", "Unknown Model")
62+
cw = data.get("context_window") or {}
63+
used = cw.get("used_percentage")
64+
inp = (cw.get("current_usage") or {}).get("input_tokens")
65+
out = (cw.get("current_usage") or {}).get("output_tokens")
66+
67+
model_str = f"\033[36m{model}\033[0m"
68+
69+
if used is not None:
70+
used_int = round(used)
71+
color = "\033[31m" if used_int >= 80 else "\033[33m" if used_int >= 50 else "\033[32m"
72+
usage_str = f"{color}{used:.1f}% used\033[0m"
73+
token_detail = f" \033[90m(in:{inp} out:{out})\033[0m" if inp is not None and out is not None else ""
74+
print(f"{model_str} | Tokens: {usage_str}{token_detail}", end="")
75+
else:
76+
print(f"{model_str} | Tokens: \033[90mno data yet\033[0m", end="")
77+
except Exception:
78+
pass
79+
' 2>/dev/null) || true
80+
5381
# ── Extract workspace from session JSON ──────────────────
54-
WORKSPACE=$(python3 -c '
82+
WORKSPACE=$(echo "$SESSION_JSON" | python3 -c '
5583
import json, sys
5684
try:
5785
data = json.load(sys.stdin)
5886
print(data.get("workspace", {}).get("current_dir", ""))
5987
except Exception: pass
6088
' 2>/dev/null) || true
6189

62-
[[ -z "$WORKSPACE" ]] && exit 0
90+
# ── If no workspace, show only model/token ───────────────
91+
if [[ -z "$WORKSPACE" ]]; then
92+
printf '%b' "$MODEL_PART"
93+
exit 0
94+
fi
6395

6496
# ── Extract branch and repo info ──────────────────────────
65-
BRANCH=$(git -C "$WORKSPACE" rev-parse --abbrev-ref HEAD 2>/dev/null) || exit 0
97+
BRANCH=$(git -C "$WORKSPACE" rev-parse --abbrev-ref HEAD 2>/dev/null) || { printf '%b' "$MODEL_PART"; exit 0; }
6698
JIRA_KEY=$(echo "$BRANCH" | grep -oiE 'fr-[0-9]+' | head -1 | tr '[:lower:]' '[:upper:]') || true
67-
[[ -z "$JIRA_KEY" ]] && exit 0
99+
100+
# No Jira key on this branch → show only model/token
101+
if [[ -z "$JIRA_KEY" ]]; then
102+
printf '%b' "$MODEL_PART"
103+
exit 0
104+
fi
68105

69106
# Derive GitHub owner/repo from origin remote
70107
GH_REPO=$(git -C "$WORKSPACE" remote get-url origin 2>/dev/null \
@@ -79,12 +116,16 @@ if [[ -f "$PR_CACHE_FILE" ]]; then
79116
PR_CACHE_AGE=$(( $(date +%s) - $(file_mtime "$PR_CACHE_FILE") ))
80117
(( PR_CACHE_AGE >= CACHE_TTL )) && _refresh_pr "$BRANCH" "$PR_CACHE_FILE" "$GH_REPO"
81118
else
82-
# No cache → background pre-warm, show nothing this cycle
119+
# No cache → background pre-warm, show only model/token this cycle
83120
_refresh_pr "$BRANCH" "$PR_CACHE_FILE" "$GH_REPO"
121+
printf '%b' "$MODEL_PART"
84122
exit 0
85123
fi
86124

87-
[[ -z "$PR_URL" ]] && exit 0
125+
if [[ -z "$PR_URL" ]]; then
126+
printf '%b' "$MODEL_PART"
127+
exit 0
128+
fi
88129

89130
# ── Jira fetch (non-blocking, stale-while-revalidate) ────
90131
CACHE_FILE="${CACHE_DIR}/${JIRA_KEY}.json"
@@ -93,8 +134,9 @@ if [[ -f "$CACHE_FILE" ]]; then
93134
JIRA_CACHE_AGE=$(( $(date +%s) - $(file_mtime "$CACHE_FILE") ))
94135
(( JIRA_CACHE_AGE >= CACHE_TTL )) && _refresh_jira "$JIRA_KEY" "$CACHE_FILE"
95136
else
96-
# No Jira cache → background pre-warm, show nothing this cycle
137+
# No Jira cache → background pre-warm, show only model/token this cycle
97138
_refresh_jira "$JIRA_KEY" "$CACHE_FILE"
139+
printf '%b' "$MODEL_PART"
98140
exit 0
99141
fi
100142

@@ -116,8 +158,8 @@ except Exception:
116158

117159
IFS=$'\t' read -r JIRA_SUMMARY JIRA_STATUS TEAMS_URL <<< "$PARSED"
118160

119-
# ── Build single-line output: Teams | Jira ───────────────
120-
LINE=""
161+
# ── Build single-line output: Model | Teams | Jira ───────
162+
LINE="$MODEL_PART "
121163

122164
if [[ -n "$TEAMS_URL" ]]; then
123165
LINE+=$(link "$TEAMS_URL" "Teams")

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)