← Curso

Lição 02

Sem print, não há conclusão.

O estado terminal descreve o que a tela provou — nunca o que a automação esperava encontrar.

Árvore de decisão

A TELA LISTADATA E HORA?NÃOSIMNO_SLOTSou BLOCKEDSLOT_SELECTEDainda não reservadoCONFIRMATION.PNG → RESERVED

Contrato de evidência

Estado
Tela necessária
Artefatos
no_slots
Mensagem explícita de ausência
final-options.png + result.json
blocked_browser_init
Brave ainda em Crashed após a única recuperação permitida
Print da aba e estado do reinício
blocked_*
Erro, WAF, CAPTCHA ou dado ausente
Print do bloqueio + causa exata
slot_selected
Lista e opção escolhida
Todas as opções visíveis + melhor escolha
reserved
Confirmação e localizador
confirmation.png + localizador

Bootstrap confiável do Computer Use

O plugin deve ser carregado pelo wrapper computer-use-client.mjs, chamando setupComputerUseRuntime({globals: globalThis}). Depois, a API correta é globalThis.sky: primeiro sky.list_apps(), depois sky.get_app_state({app: "com.brave.Browser"}). Importar @oai/sky diretamente ou chamar sky.sky contorna o runtime confiável e produz um bloqueio antes da interface.

O prompt da rodada agendada mantém a associação explícita com plugin://computer-use@openai-bundled?app=com.brave.Browser. Uma mensagem delegada não substitui essa associação persistida.

Escudo contra índice obsoleto

Um element_index só vale para a árvore acessível que acabou de ser lida. Depois de seleção, clique, mudança de foco ou navegação, o índice é descartado. Para Continuar, a execução foca o botão com Tab, confirma o foco, aciona Return uma vez, espera dois segundos e faz três leituras sem novos cliques. A mesma disciplina vale para SOLO SEPE e Presencial.

Essa espera é decisiva: uma leitura imediata pode mostrar a árvore antiga enquanto a página já está mudando. Repetir o mesmo número nesse intervalo pode clicar numa aba em vez do botão original.

Integridade do PNG

final-options.png precisa vir da captura real devolvida por get_app_state. Antes de anexar, a rodada valida PNG real, largura mínima de 300 px, altura mínima de 200 px e mais de 10 KB. Um arquivo 1x1, placeholder, imagem sintética ou cópia de outra rodada é evidência inválida. Quando a interface não chegou a ser capturada, o registro correto é screenshots=[] e final_options_available=false.

Janela-alvo antes da escolha

target_window_start recebe o instante real da rodada em Europe/Madrid; target_window_end fica exatamente 48 horas corridas depois. O intervalo é inclusivo: no limite entra; um segundo depois, não.

agora+24h: elegível>48h: rejeitadatarget_window_starttarget_window_end

Primeiro filtra, depois ordena pela data/hora. A primeira linha é só uma candidata, nunca um atalho. A automação escolhe a opção elegível cronologicamente mais próxima; se existir somente uma elegível, escolhe essa. Se todas forem posteriores, não clica: registra no_slots_within_target_window e mantém ACTIVE.

Experimente: classifique a tela

Cenário: a tela diz “não podemos oferecer citas” e mostra apenas “Justificante” e “Volver”.

Escolha um estado.

Fechar a aba também exige prova

Depois do print, do result.json e do read-back do ntfy, um estado terminal fecha somente a aba nova desta execução. Antes de super+w, uma árvore fresca comprova que a aba SEPE está selecionada e que há exatamente uma aba a mais que o baseline. Depois de dois segundos, list_apps deve mostrar que o Brave continua ativo; só então get_app_state comprova que a contagem caiu uma unidade e voltou ao baseline. Nenhum conteúdo da aba anterior é salvo.

needs_booking_confirmation não é terminal: a tela permanece aberta. Já reserved com confirmação explícita e localizador cumpre o objetivo definitivo: o Scheduler muda de ACTIVE para PAUSED, valida o TOML reaberto, fecha a aba de execução e não agenda novas rodadas.

Tentativa encerrada

no_slots ou bloqueio: fecha a aba; o Scheduler continua ACTIVE.

Objetivo cumprido

reserved + localizador: pausa o Scheduler e fecha a aba.

ntfy não reclassifica o SEPE

O resumo e o anexo podem aparecer no feed com pequeno atraso. Por isso a rodada faz até três read-backs frescos. A publicação fica em ntfy_status e um eventual erro em notification_blocker; o status primário — por exemplo no_slots ou blocked_site_error — não é substituído por uma falha de notificação.

Fonte e próximo passo

Os nomes e requisitos vêm do escopo e do prompt persistido. Continue em Confirmações e iPhone →.