Android UI Inspection (Koder Eye-first)

mandatory

Em sessão com Android conectado via ADB, preferir Koder Eye (HTTP API em 127.0.0.1:9876 após `adb forward tcp:9876 tcp:9876`) a screenshots crus. ~10× menos tokens, bounds/IDs/estado exatos do OS. Cair pra screencap só em casos visuais (ícone, cor, canvas, FLAG_SECURE).

Policy — Inspeção de UI Android (Koder Eye antes de screencap)

Em qualquer sessão com dispositivo Android conectado via ADB, *referir o Koder Eye a screenshots crus*para inspecionar a UI. Aplicável a qualquer agente de IA (Claude Code, Codex, Gemini CLI, etc.) que opere no monorepo Koder.

Por quê

Vision custa ~10× mais tokens que JSON da accessibility tree. Eye dá:

  • Bounds exatos ([x, y, w, h]) — screenshot força adivinhar coordenadas
  • View IDs (dev.koder.eye:id/start_btn) — invisíveis em pixel
  • Estado direto do OS: enabled, clickable, checked, focused
  • Texto exato de TextViewButtonEditText/Switch — sem erros de OCR
  • Diff estrutural entre snapshots — duas screenshots podem parecer idênticas e diferir em estado
  • Long-poll de eventos (/events?wait=10000) — sem polling de screencap

Custo por inspeção:

Ação Tokens
Screenshot enviado ao chat ≈1500 (image)
GET /screen/text 50–500 (text)
GET /screen/buttons 100–400 (text)
GET /screen/diff 50–800 (text, ≈0 quando nada mudou)

10 screenshots ≈ 15 000 tokens vs. 10 queries Eye ≈ 2 000 tokens.

Setup obrigatório por sessão

Fazer *ntes*de declarar Eye indisponível:

adb -s <serial> forward tcp:9876 tcp:9876
curl -s localhost:9876/healthz   # endpoint é /healthz, NÃO /health
# Esperado: {"ok":true,"version":"...","accessibility":true,"media_projection":false}

Se /healthz responder, Eye está pronto.

Se conexão for recusada após forward:

adb -s <serial> shell am start -n dev.koder.eye/.MainActivity
# tap no botão "Start Server" (ou input tap após uiautomator dump)

Se Eye não estiver instalado:

adb -s <serial> install -r ~/dev/koder/dev/eye/app/android/app/build/outputs/apk/release/app-release.apk

*ão interpretar connection refused sem forward como "Eye indisponível".*

Quando usar Eye (matriz de decisão)

Pergunta a responder Use
Botão X está visível agora? GET /screen/buttons
Qual o pacote/atividade em foreground? GET /screen | jq -r .root.pkg
Tela mudou desde a última ação? GET /screen/diff?since=<hash>
Esse texto aparece na tela? GET /screen/text
Esperar até dialog aparecer GET /events?wait=10000
Quantos itens visíveis em uma lista? ✅ Eye conta nodes
Coordenadas exatas pra input tap ✅ Eye dá bounds
Botão está enabled ou só parece? enabled: true|false direto do OS

Quando cair pra screenshot

Eye é cego ou inferior pra:

  1. *onteúdo bitmap*— splash com logo+slogan como PNG, banners, ícones, OG images
  2. *anvas / SurfaceView / WebView*— games, players, mapas, custom-drawn views
  3. *spectos visuais*— cor, contraste, alinhamento, polish de design, validação de tema
  4. *elas com FLAG_SECURE*— banking, password manager, Signal/WhatsApp; ambos (Eye e screencap) bloqueados
  5. *rimeira inspeção de app desconhecido*— vision dá contexto de marca/layout que Eye não dá
  6. *erificação de ícone / avatar carregado*— accessibility tree raramente expõe imagens

Estratégia recomendada

*ye-first, screenshot só no miss:*

  1. curl -s localhost:9876/screen/text e /screen/buttons
  2. Se a resposta resolve → done
  3. Se Eye retorna tree suspeitamente vazio (suspeita de canvas), OU a pergunta é intrinsecamente visual → adb exec-out screencap -p > ~/temp/s.png

Comandos de referência

# Texto na ordem de leitura
curl -s localhost:9876/screen/text | jq .

# Botões + bounds + labels
curl -s localhost:9876/screen/buttons | jq .

# Snapshot + diff
HASH=$(curl -s localhost:9876/screen | jq -r .screen_hash)
# ... ação ...
curl -s "localhost:9876/screen/diff?since=$HASH" | jq '{added: (.added|length), removed: (.removed|length), modified: (.modified|length)}'

# Long-poll de evento (até 10s)
curl -s "localhost:9876/events?wait=10000" | jq .

# Captura PNG no device (sem subir pro chat)
curl -s -X POST -H 'Content-Type: application/json' -d '{}' localhost:9876/capture | jq .

Referências

  • Doc completa: ~/dev/koder/context/tools/koder-eye.md (matriz detalhada, status de features, RFCs)
  • Source: ~/dev/koder/dev/eye/
  • RFC base: products/dev/eye/docs/rfcs/RFC-001-on-device-ui-analysis.md

Source: ../home/koder/dev/koder/meta/docs/stack/policies/android-ui-inspection.kmd