Skip to content

Instantly share code, notes, and snippets.

@scalp42
Last active March 26, 2026 21:10
Show Gist options
  • Select an option

  • Save scalp42/25879fa00c7c9ffaa4b476220b3967fb to your computer and use it in GitHub Desktop.

Select an option

Save scalp42/25879fa00c7c9ffaa4b476220b3967fb to your computer and use it in GitHub Desktop.
NorthernLabs team statusline for Claude Code - date, git status, k8s context, context bar, rate limits

NorthernLabs statusline for Claude Code

Custom statusline showing date/time, git status, k8s context, context window, and rate limits with ANSI colors.

03/26 14:09 | frontend git:(wip) ?1 ↑1 | 󱃾 nl-use2-prod | █░░░░░░░░░ 7% | 5h: 3% (6m) | 7d: 7% (19h 22m)

what it shows

  • date/time (cyan) - MM/DD HH:MM
  • directory + git - dir in blue, branch in git:(branch) style, file changes (+staged ~modified ?untracked), sync status (↑ahead ↓behind)
  • k8s context - red for prod, green for dev (with 󱃾 nerd font icon)
  • context window - █░ bar with percentage, green <70%, yellow <85%, red >=85%
  • rate limits - 5h and 7d windows with time-to-reset, blue <75%, magenta <90%, red >=90%

requirements

  • jq (JSON parsing)
  • kubectl (k8s context - gracefully skipped if not installed)
  • git (git status - gracefully skipped if not in a repo)
  • nerd font for k8s icon (optional, degrades gracefully)

setup

Ask Claude Code to run this, or do it manually:

# NOTE: download the script
gh gist clone 25879fa00c7c9ffaa4b476220b3967fb /tmp/nl-statusline
cp /tmp/nl-statusline/statusline.sh ~/.claude/statusline.sh
chmod +x ~/.claude/statusline.sh
rm -rf /tmp/nl-statusline

# NOTE: configure Claude Code to use it
# add this to ~/.claude/settings.json (or create the file):
cat <<'EOF'
{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}
EOF

Or if you already have a ~/.claude/settings.json, just add the statusLine block to it.

Works with any model/context window size (Opus, Sonnet, Haiku - 200k or 1M context). Rate limits use the built-in rate_limits field (requires Claude Code v2.18.0+).

#!/bin/bash
# NOTE: lean statusline - date, dir+git, k8s, context bar, rate limits
input=$(cat)
# NOTE: ANSI colors
RST='\033[0m'
DIM='\033[2m'
RED='\033[31m'
GRN='\033[32m'
YEL='\033[33m'
CYN='\033[36m'
BBLUE='\033[94m'
BMAG='\033[95m'
# NOTE: date
DATE=$(date '+%m/%d %H:%M')
# NOTE: current directory basename
CWD=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // empty')
DIR=$(basename "$CWD" 2>/dev/null || echo "")
# NOTE: git status - branch, staged, modified, untracked, ahead/behind
GIT=""
if [ -n "$CWD" ] && git -C "$CWD" rev-parse --git-dir >/dev/null 2>&1; then
BRANCH=$(git -C "$CWD" symbolic-ref --short HEAD 2>/dev/null || git -C "$CWD" rev-parse --short HEAD 2>/dev/null)
if [ -n "$BRANCH" ]; then
STAGED=$(git -C "$CWD" diff --cached --numstat 2>/dev/null | wc -l | tr -d ' ')
MODIFIED=$(git -C "$CWD" diff --numstat 2>/dev/null | wc -l | tr -d ' ')
UNTRACKED=$(git -C "$CWD" ls-files --others --exclude-standard "$CWD" 2>/dev/null | wc -l | tr -d ' ')
AB=$(git -C "$CWD" rev-list --left-right --count HEAD...@{upstream} 2>/dev/null)
AHEAD=$(echo "$AB" | awk '{print $1}')
BEHIND=$(echo "$AB" | awk '{print $2}')
# NOTE: file change flags with spaces between groups
FLAGS=""
[ "$STAGED" -gt 0 ] 2>/dev/null && FLAGS="${FLAGS} ${GRN}+${STAGED}${RST}"
[ "$MODIFIED" -gt 0 ] 2>/dev/null && FLAGS="${FLAGS} ${YEL}~${MODIFIED}${RST}"
[ "$UNTRACKED" -gt 0 ] 2>/dev/null && FLAGS="${FLAGS} ${RED}?${UNTRACKED}${RST}"
# NOTE: sync status separated from file changes
SYNC=""
[ "$AHEAD" -gt 0 ] 2>/dev/null && SYNC="${SYNC}↑${AHEAD}"
[ "$BEHIND" -gt 0 ] 2>/dev/null && SYNC="${SYNC}↓${BEHIND}"
if [ -n "$FLAGS" ] || [ -n "$SYNC" ]; then
GIT=" ${DIM}git:(${RST}${BMAG}${BRANCH}${RST}${DIM})${RST}"
[ -n "$FLAGS" ] && GIT="${GIT}${FLAGS}"
[ -n "$SYNC" ] && GIT="${GIT} ${CYN}${SYNC}${RST}"
else
GIT=" ${DIM}git:(${RST}${GRN}${BRANCH}${RST}${DIM})${RST}"
fi
fi
fi
# NOTE: k8s context - red for prod, green for dev
K8S_RAW=$(kubectl config current-context 2>/dev/null || echo "")
K8S=""
if [ -n "$K8S_RAW" ]; then
if echo "$K8S_RAW" | grep -q prod; then
K8S="${RED}󱃾 ${K8S_RAW}${RST}"
else
K8S="${GRN}󱃾 ${K8S_RAW}${RST}"
fi
fi
# NOTE: context window bar (█ filled, ░ empty)
CTX_PCT=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
CTX=""
if [ -n "$CTX_PCT" ]; then
CTX_INT=$(printf '%.0f' "$CTX_PCT")
BAR_W=10
FILLED=$(( (CTX_INT * BAR_W + 50) / 100 ))
EMPTY=$(( BAR_W - FILLED ))
# NOTE: color by usage - green <70, yellow <85, red >=85
if [ "$CTX_INT" -ge 85 ] 2>/dev/null; then
BAR_CLR="${RED}"
elif [ "$CTX_INT" -ge 70 ] 2>/dev/null; then
BAR_CLR="${YEL}"
else
BAR_CLR="${GRN}"
fi
BAR_FILLED=""
BAR_EMPTY=""
for (( i=0; i<FILLED; i++ )); do BAR_FILLED="${BAR_FILLED}█"; done
for (( i=0; i<EMPTY; i++ )); do BAR_EMPTY="${BAR_EMPTY}░"; done
CTX="${BAR_CLR}${BAR_FILLED}${DIM}${BAR_EMPTY}${RST} ${BAR_CLR}${CTX_INT}%${RST}"
fi
# NOTE: rate limits from built-in field
FIVE_PCT=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
FIVE_RESET=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
SEVEN_PCT=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
SEVEN_RESET=$(echo "$input" | jq -r '.rate_limits.seven_day.resets_at // empty')
NOW=$(date +%s)
format_remaining() {
local reset=$1
local diff=$(( reset - NOW ))
if [ "$diff" -le 0 ]; then
echo "now"
return
fi
local days=$(( diff / 86400 ))
local hours=$(( (diff % 86400) / 3600 ))
local mins=$(( (diff % 3600) / 60 ))
if [ "$days" -gt 0 ]; then
echo "${days}d ${hours}h"
elif [ "$hours" -gt 0 ]; then
echo "${hours}h ${mins}m"
else
echo "${mins}m"
fi
}
# NOTE: color rate limit - green <50, bright magenta <75, red >=90
color_pct() {
local pct=$1
if [ "$pct" -ge 90 ] 2>/dev/null; then
echo "${RED}"
elif [ "$pct" -ge 75 ] 2>/dev/null; then
echo "${BMAG}"
else
echo "${BBLUE}"
fi
}
LIMITS=""
if [ -n "$FIVE_PCT" ]; then
FIVE_INT=$(printf '%.0f' "$FIVE_PCT")
FIVE_REM=""
[ -n "$FIVE_RESET" ] && FIVE_REM=" ${DIM}($(format_remaining "$FIVE_RESET"))${RST}"
FIVE_CLR=$(color_pct "$FIVE_INT")
LIMITS="${FIVE_CLR}5h: ${FIVE_INT}%${RST}${FIVE_REM}"
fi
if [ -n "$SEVEN_PCT" ]; then
SEVEN_INT=$(printf '%.0f' "$SEVEN_PCT")
SEVEN_REM=""
[ -n "$SEVEN_RESET" ] && SEVEN_REM=" ${DIM}($(format_remaining "$SEVEN_RESET"))${RST}"
SEVEN_CLR=$(color_pct "$SEVEN_INT")
[ -n "$LIMITS" ] && LIMITS="${LIMITS} ${DIM}|${RST} "
LIMITS="${LIMITS}${SEVEN_CLR}7d: ${SEVEN_INT}%${RST}${SEVEN_REM}"
fi
# NOTE: build output line
LINE="${CYN}${DATE}${RST}"
[ -n "$DIR" ] && LINE="${LINE} ${DIM}|${RST} ${BBLUE}${DIR}${RST}${GIT}"
[ -n "$K8S" ] && LINE="${LINE} ${DIM}|${RST} ${K8S}"
[ -n "$CTX" ] && LINE="${LINE} ${DIM}|${RST} ${CTX}"
[ -n "$LIMITS" ] && LINE="${LINE} ${DIM}|${RST} ${LIMITS}"
printf '%b\n' "$LINE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment