Skip to content

Instantly share code, notes, and snippets.

@7shi
Last active October 22, 2026 14:20
Show Gist options
  • Select an option

  • Save 7shi/5a1e1b83fbe6c5c6b8114583d545a8ee to your computer and use it in GitHub Desktop.

Select an option

Save 7shi/5a1e1b83fbe6c5c6b8114583d545a8ee to your computer and use it in GitHub Desktop.
Status line UI for Claude Code and Antigravity CLI
#!/usr/bin/env python3
"""Antigravity CLI Custom Statusline Script.
Displays:
- Default elements: cycle mode, model name, effort level (e.g. accept-edits · Gemini 3.7 Flash · hi)
- Context window size and usage percentage
- 5-hour quota limit and remaining time
- 1-week quota limit and remaining time
"""
import json
import re
import sys
def format_tokens(num):
"""Format token counts into human-readable strings (e.g., 60.4k, 1M)."""
if num is None:
return "--"
try:
num = float(num)
if num >= 1_000_000:
val = num / 1_000_000
return f"{int(val)}M" if val.is_integer() else f"{val:.1f}M"
elif num >= 1_000:
val = num / 1_000
return f"{int(val)}k" if val.is_integer() else f"{val:.1f}k"
else:
return str(int(num))
except Exception:
return str(num)
def format_duration(seconds):
"""Format seconds into readable duration (e.g., 1d0h, 3h14m, 45m)."""
if seconds is None:
return ""
try:
s = int(seconds)
if s <= 0:
return "0m"
days = s // 86400
hours = (s % 86400) // 3600
mins = (s % 3600) // 60
if days > 0:
return f"{days}d{hours}h"
elif hours > 0:
return f"{hours}h{mins}m"
else:
return f"{mins}m"
except Exception:
return ""
def sum_tokens(val):
"""Safely sum token counts whether passed as an int, float, or dict."""
if val is None:
return None
if isinstance(val, (int, float)):
return val
if isinstance(val, dict):
total = 0
found = False
keys_to_check = [
"input_tokens",
"output_tokens",
"cache_creation_input_tokens",
"cache_read_input_tokens",
"prompt_tokens",
"completion_tokens",
"total_tokens",
]
for k in keys_to_check:
if k in val and isinstance(val[k], (int, float)):
total += val[k]
found = True
if found:
return total
num_sum = sum(v for v in val.values() if isinstance(v, (int, float)))
return num_sum if num_sum > 0 else None
try:
return float(val)
except Exception:
return None
def extract_default_info(data):
"""Extract default statusline elements: cycle_mode, model name, effort."""
items = []
# 1. Cycle Mode / Execution Mode
mode = data.get("cycle_mode") or data.get("execution_mode")
if mode:
items.append(str(mode))
# 2. Model & Effort
model_obj = data.get("model") or {}
if isinstance(model_obj, dict):
display_name = model_obj.get("display_name") or model_obj.get("id") or ""
# Clean up '(High)' etc. from model name if effort is displayed separately
clean_name = re.sub(r"\s*\([^)]*\)", "", display_name).strip() if display_name else ""
if clean_name:
items.append(clean_name)
elif display_name:
items.append(display_name)
effort = model_obj.get("effort")
if effort:
effort_map = {"high": "hi", "low": "lo", "medium": "med"}
items.append(effort_map.get(str(effort).lower(), str(effort)))
elif model_obj:
items.append(str(model_obj))
return items
def extract_context_info(data):
"""Extract context usage and window size."""
cw = data.get("context_window") or {}
curr_tokens = sum_tokens(cw.get("current_usage"))
if curr_tokens is None:
in_t = sum_tokens(cw.get("total_input_tokens") or cw.get("input_tokens")) or 0
out_t = sum_tokens(cw.get("total_output_tokens") or cw.get("output_tokens")) or 0
if in_t or out_t:
curr_tokens = in_t + out_t
max_tokens = sum_tokens(cw.get("context_window_size") or cw.get("max_tokens") or cw.get("limit"))
pct = cw.get("used_percentage")
if pct is None and curr_tokens is not None and max_tokens and max_tokens > 0:
pct = (curr_tokens / max_tokens) * 100
if curr_tokens is not None and max_tokens is not None:
pct_str = f"({pct:.1f}%)" if pct is not None else ""
return f"{format_tokens(curr_tokens)}/{format_tokens(max_tokens)}{pct_str}"
elif curr_tokens is not None:
pct_str = f"({pct:.1f}%)" if pct is not None else ""
return f"{format_tokens(curr_tokens)}{pct_str}"
elif pct is not None:
return f"{pct:.1f}%"
return "--"
def get_model_category(model_obj):
"""Detect model category: "argon", "gemini", or "3p"."""
if isinstance(model_obj, dict):
mid = model_obj.get("id") or ""
mdn = model_obj.get("display_name") or ""
name = f"{mid} {mdn}".lower()
elif model_obj:
name = str(model_obj).lower()
else:
name = ""
if "argon" in name:
return "argon"
elif "gemini" in name:
return "gemini"
elif any(k in name for k in ["claude", "sonnet", "opus", "haiku", "gpt", "openai", "3p", "anthropic"]):
return "3p"
return "gemini"
def extract_quota_bucket(quota, patterns, model_category="gemini"):
"""Find a specific bucket from quota payload using pattern keywords and model category."""
if not isinstance(quota, dict):
return None
is_weekly = any(p in ["weekly", "7d", "7_day", "week"] for p in patterns)
is_5h = any(p in ["5h", "5_hour", "five_hour"] for p in patterns)
# Priority candidates by model category
candidate_keys = []
if is_weekly:
if model_category == "argon":
candidate_keys = ["gemini-argon-wtu-weekly", "gemini-argon-weekly", "gemini-weekly"]
elif model_category == "gemini":
candidate_keys = ["gemini-weekly", "gemini-argon-wtu-weekly"]
elif model_category == "3p":
candidate_keys = ["3p-weekly", "gemini-weekly"]
elif is_5h:
if model_category in ("argon", "gemini"):
candidate_keys = ["gemini-5h", "gemini-argon-5h", "3p-5h"]
elif model_category == "3p":
candidate_keys = ["3p-5h", "gemini-5h"]
for k in candidate_keys:
if k in quota:
return quota[k]
# Dynamic fallback matching patterns and category keywords
for pattern in patterns:
for k, v in quota.items():
k_lower = k.lower()
if pattern in k_lower:
if model_category == "argon" and "argon" in k_lower:
return v
elif model_category == "gemini" and "gemini" in k_lower and "argon" not in k_lower:
return v
elif model_category == "3p" and ("3p" in k_lower or "claude" in k_lower or "gpt" in k_lower):
return v
# Generic fallback matching pattern only
for pattern in patterns:
if pattern in quota:
return quota[pattern]
for k, v in quota.items():
if pattern in k.lower():
return v
return None
from datetime import datetime, timedelta
def parse_reset_datetime(bucket_data):
"""Parse reset datetime and convert to local time."""
if not isinstance(bucket_data, dict):
return None
# 1. Try ISO reset_time
reset_time_str = bucket_data.get("reset_time")
if reset_time_str:
try:
iso_str = reset_time_str
if iso_str.endswith("Z"):
iso_str = iso_str[:-1] + "+00:00"
dt_utc = datetime.fromisoformat(iso_str)
return dt_utc.astimezone()
except Exception:
pass
# 2. Try reset_in_seconds
reset_sec = bucket_data.get("reset_in_seconds")
if reset_sec is not None:
try:
return datetime.now().astimezone() + timedelta(seconds=float(reset_sec))
except Exception:
pass
return None
def format_quota_entry(bucket_data, mode="time", fallback_quota=None):
"""Format a single quota bucket entry.
mode="time" -> e.g. 22%(01:50)
mode="datetime" -> e.g. 82%(08/23 01:00)
"""
pct_str = "--"
dt = None
if isinstance(bucket_data, dict):
if bucket_data.get("disabled"):
return "--"
rem = bucket_data.get("remaining_fraction")
if rem is not None:
rem_val = rem * 100 if rem <= 1.0 else rem
pct_str = f"{(100 - rem_val):.0f}%"
else:
used = bucket_data.get("used_percentage")
pct_str = f"{used:.0f}%" if used is not None else "--"
dt = parse_reset_datetime(bucket_data)
elif fallback_quota and isinstance(fallback_quota, dict):
rem = fallback_quota.get("remaining_fraction")
if rem is not None:
rem_val = rem * 100 if rem <= 1.0 else rem
pct_str = f"{(100 - rem_val):.0f}%"
dt = parse_reset_datetime(fallback_quota)
elif bucket_data is not None and not isinstance(bucket_data, (dict, list)):
return str(bucket_data)
if dt:
if mode == "datetime":
time_str = dt.strftime("%m/%d %H:%M")
else:
time_str = dt.strftime("%H:%M")
return f"{pct_str}({time_str})"
elif pct_str != "--":
return pct_str
return "--"
def main():
try:
raw = sys.stdin.read()
if not raw.strip():
print("")
return
# Save raw JSON for debugging
try:
with open("/tmp/antigravity_statusline_debug.json", "w") as f:
f.write(raw)
except Exception:
pass
data = json.loads(raw)
except Exception:
print("")
return
# ANSI Colors
CYAN = "\033[36m"
GREEN = "\033[32m"
MAGENTA = "\033[35m"
DIM = "\033[2m"
RESET = "\033[0m"
parts = []
# 1. Context Size
ctx_info = extract_context_info(data)
parts.append(f"{CYAN}Ctx:{RESET}{ctx_info}")
# 2. Quota / Rate Limits (5h & weekly/7d)
quota = data.get("quota") or data.get("rate_limits") or {}
model_obj = data.get("model") or {}
model_category = get_model_category(model_obj)
q_5h = extract_quota_bucket(quota, ["5h", "5_hour", "five_hour", "short_term"], model_category)
val_5h = format_quota_entry(q_5h, mode="time", fallback_quota=quota if not q_5h else None)
parts.append(f"{GREEN}5h:{RESET}{val_5h}")
q_7d = extract_quota_bucket(quota, ["weekly", "7d", "7_day", "seven_day", "week", "long_term"], model_category)
val_7d = format_quota_entry(q_7d, mode="datetime")
parts.append(f"{MAGENTA}7d:{RESET}{val_7d}")
# 3. Default info (cycle_mode, model, effort) at the end, joined with middle dot
default_items = extract_default_info(data)
if default_items:
dot = f" {DIM}·{RESET} "
print(dot.join([" ".join(parts), *default_items]))
else:
# Join main sections with single space
print(" ".join(parts))
if __name__ == "__main__":
main()
import json, sys
from datetime import datetime, timezone
from pathlib import Path
data = json.load(sys.stdin)
RED = "\033[0;31m"
BLUE = "\033[01;34m"
YELLOW = "\033[0;33m"
CYAN = "\033[0;36m"
RESET = "\033[00m"
cwd = data.get("cwd") or "."
home = str(Path.home())
if cwd == home:
cwd = "~"
elif cwd.startswith(home + "/"):
cwd = "~" + cwd[len(home):]
parts = [f"{BLUE}{cwd}{RESET}"]
model = data.get("model", {}).get("display_name")
if model:
model = model.replace(" context", "")
parts.append(f"{YELLOW}{model}{RESET}")
used = data.get("context_window", {}).get("used_percentage")
if used is not None:
parts.append(f"{CYAN}ctx:{used:.0f}%{RESET}")
rl = data.get("rate_limits", {})
def parse_reset(val):
if isinstance(val, (int, float)):
return datetime.fromtimestamp(val, tz=timezone.utc).astimezone()
return datetime.fromisoformat(str(val)).astimezone()
five = rl.get("five_hour", {})
if five.get("used_percentage") is not None:
t = parse_reset(five["resets_at"])
parts.append(f"{YELLOW}5h:{five['used_percentage']:.0f}%({t:%H:%M}){RESET}")
seven = rl.get("seven_day", {})
if seven.get("used_percentage") is not None:
t = parse_reset(seven["resets_at"])
parts.append(f"{RED}7d:{seven['used_percentage']:.0f}%({t:%m/%d %H:%M}){RESET}")
print(" ".join(parts), end="")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment