package main import "testing" // Real captures from a live agy 1.1.9 session (2026-08-05). const agyApproval = ` python3 -c ' import json with open("analys.ipynb", "r", encoding="utf-8") as f: ⋯ (10 lines hidden) Do you want to proceed? > 1. Yes 2. Yes, and always allow in this conversation for commands that start with 'python3 -c ' import json with open("analys.ipynb", "r", encoding="utf-8") as f:...' 3. Yes, and always allow for commands that start with 'python3 -c ' import json with open("analys.ipynb", "r", encoding="utf-8") as f:...' (Persist to settings.json) 4. No ↑/↓ Navigate · tab Amend · ctrl+g edit/expand command esc to cancel Gemini 3.6 Flash · high` const agyTrust = `Accessing workspace: /tmp/scratch/gemini-arena Do you trust the contents of this project? Antigravity CLI requires permission to read, edit, and execute files here. > Yes, I trust this folder No, exit ↑/↓ Navigate · enter Confirm Gemini 3.6 Flash · high` const agyIdle = ` ▄▀▀▄ Antigravity CLI 1.1.9 ▀▀▀▀▀▀ brasse.bb@gmail.com (Google AI Pro) ──────────────────────────────────────────────────────────── > ──────────────────────────────────────────────────────────── ? for shortcuts Gemini 3.6 Flash · high` // Agent output containing a markdown numbered list must NOT trigger. const agyMarkdownList = ` Here are 5 targeted CLI tools: 1. ntfy: sends push notifications to your phone. 2. tea: manages Gitea repositories from the command line. 3. skopeo: inspects registry images. ──────────────────────────────────────────────────────────── > ──────────────────────────────────────────────────────────── ? for shortcuts Gemini 3.6 Flash · high` const geminiAuthPicker = ` ╭──────────────────────────────────────────────╮ │ ? Get started │ │ │ │ How would you like to authenticate? │ │ │ │ ● 1. Sign in with Google │ │ 2. Use Gemini API Key │ │ 3. Vertex AI │ │ │ │ (Use Enter to select) │ ╰──────────────────────────────────────────────╯` func TestApprovalPrompt(t *testing.T) { q := DetectQuestion(agyApproval) if q == nil { t.Fatal("expected question, got nil") } if !q.Numbered || len(q.Options) != 4 { t.Fatalf("want 4 numbered options, got %+v", q.Options) } if q.Options[0].Label != "Yes" || q.Options[3].Label != "No" { t.Errorf("bad labels: %+v", q.Options) } if q.Selected != 0 { t.Errorf("want selected=0, got %d", q.Selected) } if q.Text != "Do you want to proceed?" { t.Errorf("bad text: %q", q.Text) } } func TestTrustPrompt(t *testing.T) { q := DetectQuestion(agyTrust) if q == nil { t.Fatal("expected question, got nil") } if q.Numbered || len(q.Options) != 2 { t.Fatalf("want 2 unnumbered options, got %+v", q.Options) } if q.Selected != 0 { t.Errorf("want selected=0, got %d", q.Selected) } if q.Options[1].Label != "No, exit" { t.Errorf("bad option: %+v", q.Options[1]) } } func TestIdleScreenNoQuestion(t *testing.T) { if q := DetectQuestion(agyIdle); q != nil { t.Fatalf("idle screen misdetected as question: %+v", q) } } func TestMarkdownListNoQuestion(t *testing.T) { if q := DetectQuestion(agyMarkdownList); q != nil { t.Fatalf("markdown list misdetected as question: %+v", q) } } func TestBoxedNumberedPicker(t *testing.T) { q := DetectQuestion(geminiAuthPicker) if q == nil { t.Fatal("expected question, got nil") } if len(q.Options) != 3 || !q.Numbered { t.Fatalf("want 3 numbered options, got %+v", q.Options) } } func TestSameQuestionSameHash(t *testing.T) { a, b := DetectQuestion(agyApproval), DetectQuestion(agyApproval) if a.Hash != b.Hash { t.Error("hash not stable") } if DetectQuestion(agyTrust).Hash == a.Hash { t.Error("different questions share hash") } }