@tekmidian/pai 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/statusline-command.sh +121 -9
package/package.json
CHANGED
package/statusline-command.sh
CHANGED
|
@@ -310,8 +310,8 @@ fi
|
|
|
310
310
|
|
|
311
311
|
# Output the statusline
|
|
312
312
|
# LINE 1 - Greeting (adaptive: drop CC version when narrow, shorten further if very narrow)
|
|
313
|
-
line1_full="${EMOJI_WAVE} ${DA_DISPLAY_COLOR}
|
|
314
|
-
line1_medium="${EMOJI_WAVE} ${DA_DISPLAY_COLOR}
|
|
313
|
+
line1_full="${EMOJI_WAVE} ${DA_DISPLAY_COLOR}${DA_NAME}${RESET} ${MODEL_PURPLE}CC ${cc_version}${RESET}${LINE1_PRIMARY} ${MODEL_PURPLE}${EMOJI_BRAIN} ${model_name}${RESET}${LINE1_PRIMARY} in ${DIR_COLOR}${EMOJI_FOLDER} ${dir_name}${BRIGHT_CYAN}${session_suffix}${RESET}"
|
|
314
|
+
line1_medium="${EMOJI_WAVE} ${DA_DISPLAY_COLOR}${DA_NAME}${RESET} ${MODEL_PURPLE}${EMOJI_BRAIN} ${model_name}${RESET}${LINE1_PRIMARY} in ${DIR_COLOR}${EMOJI_FOLDER} ${dir_name}${BRIGHT_CYAN}${session_suffix}${RESET}"
|
|
315
315
|
line1_short="${EMOJI_WAVE} ${MODEL_PURPLE}${EMOJI_BRAIN} ${model_name}${RESET}${LINE1_PRIMARY} ${DIR_COLOR}${EMOJI_FOLDER} ${dir_name}${BRIGHT_CYAN}${session_suffix}${RESET}"
|
|
316
316
|
|
|
317
317
|
# Pick line 1 format based on width (plain-text lengths: full~85, medium~45, short~25)
|
|
@@ -330,13 +330,125 @@ if [ -n "$mcp_line2" ]; then
|
|
|
330
330
|
printf "${LINE2_PRIMARY} ${RESET}${mcp_line2}${RESET}\n"
|
|
331
331
|
fi
|
|
332
332
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
333
|
+
|
|
334
|
+
# Fetch OAuth usage (5-hour current + 7-day weekly) with caching
|
|
335
|
+
usage_cache="/tmp/claude/statusline-usage-cache.json"
|
|
336
|
+
usage_cache_ttl=60 # seconds
|
|
337
|
+
usage_suffix=""
|
|
338
|
+
|
|
339
|
+
_fetch_usage() {
|
|
340
|
+
# Try to get OAuth token from macOS Keychain
|
|
341
|
+
local token=""
|
|
342
|
+
token=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null | jq -r '.claudeAiOauth.accessToken // empty' 2>/dev/null)
|
|
343
|
+
[ -z "$token" ] && return
|
|
344
|
+
|
|
345
|
+
mkdir -p /tmp/claude
|
|
346
|
+
local response
|
|
347
|
+
response=$(curl -sf --max-time 3 \
|
|
348
|
+
-H "Authorization: Bearer $token" \
|
|
349
|
+
-H "anthropic-beta: oauth-2025-04-20" \
|
|
350
|
+
"https://api.anthropic.com/api/oauth/usage" 2>/dev/null)
|
|
351
|
+
[ -n "$response" ] && echo "$response" > "$usage_cache"
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
# Use cache if fresh, otherwise fetch in background
|
|
355
|
+
if [ -f "$usage_cache" ]; then
|
|
356
|
+
cache_age=$(( $(date +%s) - $(stat -f %m "$usage_cache" 2>/dev/null || echo 0) ))
|
|
357
|
+
if [ "$cache_age" -gt "$usage_cache_ttl" ]; then
|
|
358
|
+
_fetch_usage &
|
|
359
|
+
fi
|
|
360
|
+
else
|
|
361
|
+
_fetch_usage &
|
|
362
|
+
fi
|
|
363
|
+
|
|
364
|
+
# Read cached usage data
|
|
365
|
+
if [ -f "$usage_cache" ]; then
|
|
366
|
+
five_hour=$(jq -r '.five_hour.utilization // 0' "$usage_cache" 2>/dev/null)
|
|
367
|
+
seven_day=$(jq -r '.seven_day.utilization // 0' "$usage_cache" 2>/dev/null)
|
|
368
|
+
five_reset=$(jq -r '.five_hour.resets_at // empty' "$usage_cache" 2>/dev/null)
|
|
369
|
+
seven_reset=$(jq -r '.seven_day.resets_at // empty' "$usage_cache" 2>/dev/null)
|
|
370
|
+
|
|
371
|
+
# Round to integers
|
|
372
|
+
five_hour_int=$(printf "%.0f" "$five_hour" 2>/dev/null || echo 0)
|
|
373
|
+
seven_day_int=$(printf "%.0f" "$seven_day" 2>/dev/null || echo 0)
|
|
374
|
+
|
|
375
|
+
# Format reset times as HH:MM (local time)
|
|
376
|
+
five_reset_fmt=""
|
|
377
|
+
seven_reset_fmt=""
|
|
378
|
+
seven_reset_epoch=0
|
|
379
|
+
if [ -n "$five_reset" ]; then
|
|
380
|
+
five_reset_fmt=$(date -jf "%Y-%m-%dT%H:%M:%S" "$(echo "$five_reset" | cut -c1-19)" "+%H:%M" 2>/dev/null || date -d "$five_reset" "+%H:%M" 2>/dev/null || echo "")
|
|
381
|
+
fi
|
|
382
|
+
if [ -n "$seven_reset" ]; then
|
|
383
|
+
seven_reset_fmt=$(date -jf "%Y-%m-%dT%H:%M:%S" "$(echo "$seven_reset" | cut -c1-19)" "+%a %H:%M" 2>/dev/null || date -d "$seven_reset" "+%a %H:%M" 2>/dev/null || echo "")
|
|
384
|
+
seven_reset_epoch=$(date -jf "%Y-%m-%dT%H:%M:%S" "$(echo "$seven_reset" | cut -c1-19)" "+%s" 2>/dev/null || date -d "$seven_reset" "+%s" 2>/dev/null || echo 0)
|
|
385
|
+
fi
|
|
386
|
+
|
|
387
|
+
# Color based on utilization: green < 50%, yellow 50-75%, red > 75%
|
|
388
|
+
_usage_color() {
|
|
389
|
+
local pct=$1
|
|
390
|
+
if [ "$pct" -gt 75 ] 2>/dev/null; then echo "$BRIGHT_RED"
|
|
391
|
+
elif [ "$pct" -gt 50 ] 2>/dev/null; then echo "$BRIGHT_YELLOW"
|
|
392
|
+
else echo "$BRIGHT_GREEN"; fi
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
five_color=$(_usage_color "$five_hour_int")
|
|
396
|
+
seven_color=$(_usage_color "$seven_day_int")
|
|
397
|
+
|
|
398
|
+
# Budget pace indicator for 7-day window
|
|
399
|
+
# Compare actual usage vs linear expected usage based on elapsed time
|
|
400
|
+
pace_dot=""
|
|
401
|
+
if [ "$seven_reset_epoch" -gt 0 ] 2>/dev/null; then
|
|
402
|
+
now_epoch=$(date +%s)
|
|
403
|
+
window_secs=$((7 * 86400))
|
|
404
|
+
remaining_secs=$((seven_reset_epoch - now_epoch))
|
|
405
|
+
[ "$remaining_secs" -lt 0 ] && remaining_secs=0
|
|
406
|
+
elapsed_secs=$((window_secs - remaining_secs))
|
|
407
|
+
# Expected usage if spending linearly: elapsed/total * 100
|
|
408
|
+
expected_pct=$(( elapsed_secs * 100 / window_secs ))
|
|
409
|
+
# Daily pace: actual spend per day vs budget (100/7 ≈ 14%/day)
|
|
410
|
+
elapsed_days_x10=$((elapsed_secs * 10 / 86400))
|
|
411
|
+
[ "$elapsed_days_x10" -lt 1 ] && elapsed_days_x10=1
|
|
412
|
+
spend_per_day=$((seven_day_int * 10 / elapsed_days_x10))
|
|
413
|
+
budget_per_day=14 # 100/7 ≈ 14%
|
|
414
|
+
# Color: green = under budget, orange = near budget, red = over budget
|
|
415
|
+
overspend=$((spend_per_day - budget_per_day))
|
|
416
|
+
if [ "$overspend" -le -3 ] 2>/dev/null; then
|
|
417
|
+
pace_color="$BRIGHT_GREEN" # well under budget
|
|
418
|
+
elif [ "$overspend" -le 2 ] 2>/dev/null; then
|
|
419
|
+
pace_color="$BRIGHT_ORANGE" # near budget
|
|
420
|
+
else
|
|
421
|
+
pace_color="$BRIGHT_RED" # over budget
|
|
422
|
+
fi
|
|
423
|
+
pace_dot="${pace_color}${spend_per_day}%% / ${budget_per_day}%%${RESET}"
|
|
424
|
+
fi
|
|
425
|
+
|
|
426
|
+
# Build usage suffix: 5h: 8% → 00:59 │ 1d: ● 29% / 36% │ 7d: 29% → Fr. 08:00
|
|
427
|
+
five_label="5h: ${five_hour_int}%%"
|
|
428
|
+
[ -n "$five_reset_fmt" ] && five_label="${five_label} → ${five_reset_fmt}"
|
|
429
|
+
seven_label="7d: ${seven_day_int}%%"
|
|
430
|
+
[ -n "$seven_reset_fmt" ] && seven_label="${seven_label} → ${seven_reset_fmt}"
|
|
431
|
+
|
|
432
|
+
usage_suffix=" ${SEPARATOR_COLOR}│${RESET} ${five_color}${five_label}${RESET}"
|
|
433
|
+
[ -n "$pace_dot" ] && usage_suffix="${usage_suffix} ${SEPARATOR_COLOR}│${RESET} ${LINE3_PRIMARY}1d:${RESET} ${pace_dot}"
|
|
434
|
+
usage_suffix="${usage_suffix} ${SEPARATOR_COLOR}│${RESET} ${seven_color}${seven_label}${RESET}"
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
# LINE 3 - Context meter + usage limits
|
|
438
|
+
# Auto-compact remaining: how much context left until compaction triggers
|
|
439
|
+
ac_threshold="${CLAUDE_AUTOCOMPACT_PCT_OVERRIDE:-80}"
|
|
440
|
+
ac_remaining=$((ac_threshold - context_pct))
|
|
441
|
+
[ "$ac_remaining" -lt 0 ] && ac_remaining=0
|
|
442
|
+
# Color the remaining %: red ≤5, yellow ≤15, green otherwise
|
|
443
|
+
if [ "$ac_remaining" -le 5 ] 2>/dev/null; then
|
|
444
|
+
ac_color="$BRIGHT_RED"
|
|
445
|
+
elif [ "$ac_remaining" -le 15 ] 2>/dev/null; then
|
|
446
|
+
ac_color="$BRIGHT_YELLOW"
|
|
447
|
+
else
|
|
448
|
+
ac_color="$BRIGHT_GREEN"
|
|
337
449
|
fi
|
|
450
|
+
ac_suffix=" ${ac_color}(${ac_remaining}%%)${RESET}"
|
|
338
451
|
|
|
339
|
-
# LINE 3 - Context meter (from Claude Code's JSON input)
|
|
340
452
|
if [ "$context_pct" -gt 0 ] 2>/dev/null; then
|
|
341
453
|
# Color based on usage: green < 50%, yellow 50-75%, red > 75%
|
|
342
454
|
if [ $context_pct -gt 75 ]; then
|
|
@@ -347,7 +459,7 @@ if [ "$context_pct" -gt 0 ] 2>/dev/null; then
|
|
|
347
459
|
ctx_color="$BRIGHT_GREEN"
|
|
348
460
|
fi
|
|
349
461
|
|
|
350
|
-
printf "${LINE3_PRIMARY}${EMOJI_GEM} Context${RESET}${LINE3_PRIMARY}${SEPARATOR_COLOR}: ${RESET}${ctx_color}${context_used_k}K${RESET}${LINE3_PRIMARY} / ${context_max_k}K${
|
|
462
|
+
printf "${LINE3_PRIMARY}${EMOJI_GEM} Context${RESET}${LINE3_PRIMARY}${SEPARATOR_COLOR}: ${RESET}${ctx_color}${context_used_k}K${RESET}${LINE3_PRIMARY} / ${context_max_k}K${ac_suffix}${usage_suffix}${RESET}\n"
|
|
351
463
|
else
|
|
352
|
-
printf "${LINE3_PRIMARY}${EMOJI_GEM} Context${RESET}${LINE3_PRIMARY}${SEPARATOR_COLOR}: ${RESET}${LINE3_ACCENT}...${
|
|
464
|
+
printf "${LINE3_PRIMARY}${EMOJI_GEM} Context${RESET}${LINE3_PRIMARY}${SEPARATOR_COLOR}: ${RESET}${LINE3_ACCENT}...${ac_suffix}${usage_suffix}${RESET}\n"
|
|
353
465
|
fi
|