Skip to content

Instantly share code, notes, and snippets.

@it3xl
Last active July 15, 2026 20:45
Show Gist options
  • Select an option

  • Save it3xl/3d7b91d6b8fa3c790fdbcfc0e8d0321b to your computer and use it in GitHub Desktop.

Select an option

Save it3xl/3d7b91d6b8fa3c790fdbcfc0e8d0321b to your computer and use it in GitHub Desktop.
Antigravity CLI Custom Status Line Guide

Antigravity Statusline Fixed

import json, sys, datetime, os, subprocess, urllib.parse

# Source: https://gist.github.com/it3xl/3d7b91d6b8fa3c790fdbcfc0e8d0321b
# Force UTF-8 on stdin/stdout for Windows compatibility
for _stream in (sys.stdin, sys.stdout):
    try:
        _stream.reconfigure(encoding='utf-8', errors='replace')
    except Exception:
        pass

def fmt_num(n):
    n = int(n)
    if n >= 1_000_000:
        return f"{n / 1_000_000:.1f}".replace('.0', '') + "M"
    if n >= 1000:
        return f"{int(n / 1000)}k"
    return str(n)

# Colors
R   = '\033[0m'
G   = '\033[32m'   # green   - user
C   = '\033[36m'    # cyan    - model, branch, plan tier
DC  = '\033[38;5;66m' # dim cyan - git status
Y   = '\033[33m'   # yellow  - ctx
M   = '\033[35m'   # magenta - path
TM  = '\033[97m'   # bright white  - time
LD  = '\033[91m'   # bright red    - day limit pct
DLD = '\033[38;5;174m' # muted red    - day reset time
LW  = '\033[38;5;220m' # gold yellow - week limit pct
DLW = '\033[38;5;179m' # dim yellow   - week reset time

try:
    data = json.load(sys.stdin)
except Exception:
    data = {}

# Model
model = (data.get('model') or {}).get('display_name') or data.get('model_name')
if not model:
    try:
        settings_path = os.path.join(os.path.expanduser('~'), '.gemini', 'antigravity-cli', 'settings.json')
        with open(settings_path, 'r', encoding='utf-8') as f:
            model = json.load(f).get('model')
    except Exception:
        pass
if not model:
    model = os.environ.get('AGY_MODEL', '?model')
model_lower = model.lower()

# Directory
ws = data.get('workspace') or {}
cwd = ws.get('project_dir') or data.get('cwd') or ws.get('current_dir') or os.getcwd()
if cwd.startswith('file://'):
    cwd = urllib.parse.unquote(cwd[7:])
    if os.name == 'nt' and cwd.startswith('/'):
        cwd = cwd[1:]

# Context window
ctx_obj = data.get('context_window') or {}
used_pct = ctx_obj.get('used_percentage')
ctx_size = ctx_obj.get('context_window_size')
remaining_pct = ctx_obj.get('remaining_percentage')

if used_pct is not None:
    ctx_str = f'ctx:{round(used_pct)}%'
    if remaining_pct is not None and ctx_size:
        left = int(ctx_size * remaining_pct / 100)
        ctx_str += f' ({fmt_num(left)} of {fmt_num(ctx_size)})'
else:
    ctx_str = 'ctx:?'

# --- QUOTA DIAGNOSTIC LOGIC ---
fh_used = None
fh_reset_str = None
quota_status = 'ok'
pct_text = None

wk_used = None
wk_reset_str = None
wk_status = 'ok'
wk_pct_text = None

quota_obj = data.get('quota')

# --- SYNC ACROSS SESSIONS ---
SHARED_FILE = os.path.expanduser('~/.gemini/shared_quota_v2.json')
shared_quota = {}
try:
    if os.path.exists(SHARED_FILE):
        with open(SHARED_FILE, 'r', encoding='utf-8') as f:
            shared_quota = json.load(f)
except Exception:
    pass

if quota_obj is None:
    quota_obj = shared_quota if shared_quota else None
else:
    merged = {}
    all_keys = set(quota_obj.keys()).union(shared_quota.keys())
    for k in all_keys:
        q1 = quota_obj.get(k)
        q2 = shared_quota.get(k)
        if not q1: 
            merged[k] = q2
        elif not q2: 
            merged[k] = q1
        else:
            rt1 = q1.get('reset_time', '')
            rt2 = q2.get('reset_time', '')
            if rt1 != rt2:
                merged[k] = q1 if rt1 > rt2 else q2
            else:
                try:
                    rf1 = float(q1.get('remaining_fraction', 1.0))
                except Exception:
                    rf1 = 1.0
                try:
                    rf2 = float(q2.get('remaining_fraction', 1.0))
                except Exception:
                    rf2 = 1.0
                merged[k] = q1 if rf1 <= rf2 else q2
                
    if merged != shared_quota:
        try:
            tmp_file = SHARED_FILE + f".tmp.{os.getpid()}"
            with open(tmp_file, 'w', encoding='utf-8') as f:
                json.dump(merged, f)
            os.replace(tmp_file, SHARED_FILE)
        except Exception:
            pass
    quota_obj = merged

if quota_obj is None:
    quota_status = 'missing_obj' # d-noquota
    wk_status = 'missing_obj' # w-noquota
else:
    is_gemini = 'gemini' in model_lower
    key_5h = 'gemini-5h' if is_gemini else '3p-5h'
    key_wk = 'gemini-weekly' if is_gemini else '3p-weekly'
    q = quota_obj.get(key_5h)
    qw = quota_obj.get(key_wk)
    
    if not q:
        quota_status = 'missing_model' # d-?model
    else:
        if 'remaining_fraction' in q:
            rem_frac = q['remaining_fraction']
            try:
                fh_used = (1.0 - float(rem_frac)) * 100.0
                pct_text = f'd-{round(fh_used)}%'
            except (ValueError, TypeError):
                quota_status = 'math_err' # d-err
                pct_text = 'd-err'
        else:
            quota_status = 'missing_fraction' # d-??%
            pct_text = 'd-??%'
        
        fh_reset_str = q.get('reset_time')
        if not fh_reset_str:
            if quota_status == 'ok':
                quota_status = 'missing_time'

    if not qw:
        wk_status = 'missing_model' # w-?model
    else:
        if 'remaining_fraction' in qw:
            wk_rem_frac = qw['remaining_fraction']
            try:
                wk_used = (1.0 - float(wk_rem_frac)) * 100.0
                wk_pct_text = f'w-{round(wk_used)}%'
            except (ValueError, TypeError):
                wk_status = 'math_err' # w-err
                wk_pct_text = 'w-err'
        else:
            wk_status = 'missing_fraction' # w-??%
            wk_pct_text = 'w-??%'
        
        wk_reset_str = qw.get('reset_time')
        if not wk_reset_str:
            if wk_status == 'ok':
                wk_status = 'missing_time'

def fmt_day_limit(status, pct_txt, reset_str):
    if status == 'missing_obj':
        return f'{LD}d-noquota{R}'
    if status == 'missing_model':
        return f'{LD}d-?model{R}'
    if status == 'math_err':
        return f'{LD}d-err{R}'
        
    if status == 'missing_time':
        return f'{LD}{pct_txt} ??:??{R}'
        
    if not reset_str:
        return f'{LD}{pct_txt}{R}'

    try:
        reset_str_fixed = reset_str.replace('Z', '+00:00')
        reset_dt = datetime.datetime.fromisoformat(reset_str_fixed).astimezone()
        now = datetime.datetime.now(datetime.timezone.utc)
        diff = reset_dt - now
        
        if diff.total_seconds() > 0:
            h, m = divmod(int(diff.total_seconds() // 60), 60)
            dur = f'{h}h {m}m' if h else f'{m}m'
            return f'{LD}{pct_txt}{R} {DLD}{reset_dt.strftime("%H:%M")}{R} {LD}{dur}{R}'
        else:
            return f'{LD}{pct_txt}{R}' # Keep showing the last known usage
            
    except Exception:
        return f'{LD}{pct_txt} ?format{R}'

def fmt_week_limit(status, pct_txt, reset_str):
    if status == 'missing_obj':
        return f'{LW}w-noquota{R}'
    if status == 'missing_model':
        return f'{LW}w-?model{R}'
    if status == 'math_err':
        return f'{LW}w-err{R}'
        
    if status == 'missing_time':
        return f'{LW}{pct_txt} ??:??{R}'
        
    if not reset_str:
        return f'{LW}{pct_txt}{R}'

    try:
        reset_str_fixed = reset_str.replace('Z', '+00:00')
        reset_dt = datetime.datetime.fromisoformat(reset_str_fixed).astimezone()
        now = datetime.datetime.now(datetime.timezone.utc)
        diff = reset_dt - now
        
        if diff.total_seconds() > 0:
            d = diff.days
            h, m = divmod(int(diff.seconds // 60), 60)
            if d > 0:
                dur = f'{d}d {h}h'
            else:
                dur = f'{h}h {m}m' if h else f'{m}m'
            return f'{LW}{pct_txt}{R} {DLW}{reset_dt.strftime("%a %H:%M")}{R} {LW}{dur}{R}'
        else:
            return f'{LW}{pct_txt}{R}'
            
    except Exception:
        return f'{LW}{pct_txt} ?format{R}'

day_str = f"  {fmt_day_limit(quota_status, pct_text, fh_reset_str)}"
week_str = f"  {fmt_week_limit(wk_status, wk_pct_text, wk_reset_str)}"

# Git info (timeout clamped to 1s to prevent hanging prompts)
try:
    branch = subprocess.check_output(
        ['git', '-C', cwd, 'branch', '--show-current'],
        stderr=subprocess.DEVNULL, timeout=1
    ).decode('utf-8', 'replace').strip() or '?'
    status_out = subprocess.check_output(
        ['git', '-C', cwd, 'status', '--porcelain'],
        stderr=subprocess.DEVNULL, timeout=1
    ).decode('utf-8', 'replace').strip()
    if status_out:
        lines = status_out.splitlines()
        def conflict(l): return 'U' in l[:2] or l[:2] in ('AA', 'DD')
        conflicted = sum(1 for l in lines if conflict(l))
        staged     = sum(1 for l in lines if not conflict(l) and l[0] in 'MADRCT')
        modified   = sum(1 for l in lines if not conflict(l) and l[1] in 'MDT')
        untracked  = sum(1 for l in lines if l.startswith('??'))
        parts = []
        if conflicted: parts.append(f'!{conflicted}')
        if staged:     parts.append(f'+{staged}')
        if modified:   parts.append(f'~{modified}')
        if untracked:  parts.append(f'?{untracked}')
        git_status = ' '.join(parts) if parts else 'clean'
    else:
        git_status = 'clean'
except Exception:
    branch = ''
    git_status = ''

now_str = datetime.datetime.now().strftime('%H:%M')

account = data.get('email', '')
plan_tier = data.get('plan_tier', '')

home = os.path.expanduser('~')
if os.name == 'nt':
    home = home.replace('\\', '/')
    cwd = cwd.replace('\\', '/')

# Check directory boundary to avoid matching sibling folders (e.g. ~/ann vs ~/annette)
low_cwd, low_home = cwd.lower(), home.lower().rstrip('/')
if low_cwd == low_home:
    display_cwd = '~'
elif low_cwd.startswith(low_home + '/'):
    display_cwd = '~' + cwd[len(low_home):]
else:
    display_cwd = cwd

conv_id = data.get('conversation_id')
conv_name = ""
if conv_id:
    history_path = os.path.join(os.path.expanduser('~'), '.gemini', 'antigravity-cli', 'history.jsonl')
    try:
        if os.path.exists(history_path):
            with open(history_path, 'r', encoding='utf-8') as f:
                for line in f:
                    if conv_id in line and '/rename ' in line:
                        try:
                            item = json.loads(line)
                            if item.get('conversationId') == conv_id:
                                display = item.get('display', '')
                                if display.startswith('/rename '):
                                    conv_name = display[8:].strip()
                        except Exception:
                            pass
    except Exception:
        pass

name_str = f'  {M}{conv_name}{R}' if conv_name else ''
path_part = f'{M}{display_cwd}{R}'
branch_str = f'  {C}{branch}{R}' if branch else ''
gs_str = (f' {DC}{git_status}{R}' if git_status and git_status != 'clean' else f' {DC}clean{R}') if branch else ''
account_str = f'  {G}{account}{R}' if account else ''
plan_str = f'  {C}{plan_tier}{R}' if plan_tier else ''

print(f'{TM}{now_str}{R}{name_str}  {C}{model}{R}  {Y}{ctx_str}{R}{day_str}{week_str}  {path_part}{branch_str}{gs_str}{account_str}{plan_str}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment