Guest User

Untitled

a guest
Aug 14th, 2026
492
0
295 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 2.65 KB | None | 0 0
  1. #!/bin/bash
  2. # `~/.claude/hooks/cache-timestamp.sh`
  3. # Stop hook: stamps the cache expiry time so the statusline can render a live countdown.
  4. # Reads the transcript JSONL, finds the last assistant turn that touched the cache
  5. # (read OR creation > 0), and writes (that turn's timestamp + TTL) as epoch seconds to
  6. # /tmp/cache_expiry_<session_id>.
  7. #   - Creation matters because the first turn of a session only *writes* the cache
  8. #     (cache_read is still 0) yet the cache is warm for the full TTL.
  9. #   - Anchoring to the turn's own timestamp (when the cache was actually touched) rather
  10. #     than "now" keeps the countdown honest on long turns, where Stop can fire minutes
  11. #     after the API response that (re)set the TTL.
  12.  
  13. # Change to 300 for the default 5 minute prompt cache TTL.
  14. CACHE_TTL_SECONDS=3600
  15.  
  16. INPUT=$(cat)
  17.  
  18. SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "default"')
  19. TRANSCRIPT=$(printf '%s' "$INPUT" | jq -r '.transcript_path // ""')
  20.  
  21. [ -z "$TRANSCRIPT" ] || [ ! -f "$TRANSCRIPT" ] && exit 0
  22.  
  23. # Epoch (seconds) of the last assistant turn that touched the cache, or empty if none.
  24. LAST_TOUCH=$(python3 -c "
  25. import json, datetime
  26. ts = ''
  27. with open('$TRANSCRIPT') as f:
  28.    for line in f:
  29.        try:
  30.            d = json.loads(line)
  31.            if d.get('type') == 'assistant':
  32.                u = d.get('message', {}).get('usage', {})
  33.                if u.get('cache_read_input_tokens', 0) + u.get('cache_creation_input_tokens', 0) > 0:
  34.                    ts = d.get('timestamp') or ts
  35.        except:
  36.            pass
  37. if ts:
  38.    try:
  39.        print(int(datetime.datetime.fromisoformat(ts.replace('Z', '+00:00')).timestamp()))
  40.    except Exception:
  41.        pass
  42. " 2>/dev/null)
  43.  
  44. if [ -n "$LAST_TOUCH" ] 2>/dev/null; then
  45.   echo $(( LAST_TOUCH + CACHE_TTL_SECONDS )) > "/tmp/cache_expiry_${SESSION_ID}"
  46. fi
  47.  
  48. ##################################################
  49. # and then this goes in your statusline-command.sh
  50. ##################################################
  51.  
  52. # Cache warmth countdown (1h TTL). Expiry is stamped by hooks/cache-timestamp.sh.
  53. # green: first 5min  yellow: middle  red: last 5min  ❄: expired  dim: idle
  54. cache_part=" \033[90mcache idle\033[0m"
  55. exp_file="/tmp/cache_expiry_${session}"
  56. if [ -f "$exp_file" ]; then
  57.   exp=$(cat "$exp_file" 2>/dev/null)
  58.   remain=$((${exp:-0} - $(date +%s)))
  59.   if [ "$remain" -gt 0 ]; then
  60.     ts=$(printf '%d:%02d' "$((remain / 60))" "$((remain % 60))")
  61.     if [ "$remain" -gt 3300 ]; then
  62.       c='\033[32m'
  63.     elif [ "$remain" -gt 300 ]; then
  64.       c='\033[33m'
  65.     else
  66.       c='\033[31m'
  67.     fi
  68.     cache_part=" ${c}cache ${ts}\033[0m"
  69.   else
  70.     cache_part=" ❄"
  71.   fi
  72. fi
Advertisement
Add Comment
Please, Sign In to add comment