Communitygithub.com

undefine-org/ux-from-use

Transforme relatos de uso (bugs, atritos, dúvidas) na experiência que o produto deve estabelecer, encontra a causa estrutural, corrige-a, testa num navegador real com o namespace browser do Beam Lisp e mantém o resultado como um cenário filmado com o modelo gravado.

O que é ux-from-use?

Esta skill capacita o agente a converter relatos de uso (como bugs ou feedbacks de atrito) em uma experiência de produto clara, corrigindo a estrutura subjacente e não apenas os sintomas. Ela é útil para desenvolvedores que trabalham com produtos interativos e desejam testar manualmente, documentar comportamentos com vídeos e garantir que as correções resolvam a causa raiz. A skill suporta o ecossistema Beam Lisp (com o namespace `browser`) e ferramentas como agente de navegador, chromedp e navegador Beam Lisp. O processo segue um loop de 6 passos: coletar o uso real, escrever a experiência em uma frase, encontrar a causa estrutural, testar manualmente no navegador real, transformar o teste em um cenário filmado com o modelo em fita, e relatar a experiência em vez do patch. Inclui também um guia detalhado para testes manuais com o namespace browser, desde a configuração até a criação de filmes, e um conjunto de 'gostos da casa' que refletem preferências de design estabelecidas.

Funciona com~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/undefine-org/enchanted-skills/tree/main/ux-from-use

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Do uso à experiência

Um relato nomeia um sintoma. O trabalho é a experiência por trás dele. « O cliente desaparece quando a conversa vai para o assunto » é um bug. « Uma conversa reúne o que é sobre ela: o cliente fica quando seu assunto é adicionado » é o que construir, verificar e filmar. Escreva essa frase primeiro. Corrija a estrutura que permitiu o sintoma, depois prove a frase usando o produto.

O loop

  1. Colete o uso. Leia o relato, depois os vestígios de uso real: as conversas da pessoa, diários, logs, presença, os arquivos que ela tocou. Eles guardam expectativas que ninguém escreveu (« eles estão onde? » espera os pontos em si, não um resumo).
  2. Escreva a experiência. Uma frase por relato, presente, do lado da pessoa, sem palavras de implementação. Mantenha a lista. Ela se torna a narração do filme e as mensagens das afirmações.
  3. Encontre a causa estrutural. Pergunte por que o produto poderia fazer isso. Uma causa geralmente explica vários relatos (identidade retirada de um nome de exibição; duas contagens que compartilham uma palavra; um renderizador que descarta uma classe ao inserir). Corrija a causa, não a tela que a mostrou.
  4. Use você mesmo. Dirija o aplicativo real como cada pessoa envolvida, em largura de desktop e telefone, através do namespace browser (abaixo). Olhe para capturas de tela. Conte o que a página diz, não o que o código pretende.
  5. Mantenha. Transforme os passos manuais em um cenário: ações viram eventos, verificações viram afirmações, a frase da experiência vira a narração da cena. Coloque as voltas do modelo em fita para que o filme seja reproduzido em segundos, sem custo.
  6. Relate a experiência, não o patch. No resumo, lidere com o que a pessoa encontrará agora, depois a causa, depois o filme e como reproduzi-lo.

Gosto da casa (o que Othman pediu, repetidamente)

  • Menos cópia. O estado é desenhado: tom, peso, posicionamento, um anel, uma marca. Uma frase que explica uma tela significa que a tela está errada.
  • Uma palavra por ideia. Mantenha um glossário e segure-o: um « critère » (julgado contra o procedimento) nunca é um « point » (o que uma pessoa decide). Se duas contagens compartilham uma palavra, alguém as somará.
  • As coisas se acumulam. Tags se somam (tipo, depois cliente, depois assunto). A atual é preenchida e as outras permanecem como contornos. Nunca substitua o contexto que a pessoa já viu.
  • Números desenhados antes do texto. Um histórico abre em gráficos, uma série cada, valores rotulados. O texto fica embaixo, uma linha por evento, e abre sob demanda.
  • Cada referência leva ao seu lugar. Um número de parágrafo rola até o parágrafo e o ilumina. Uma citação encontra sua passagem. A barra de rolagem marca onde as coisas estão, em suas cores.
  • Ao vivo por padrão. Sem recarregamentos completos. Uma alteração feita por uma pessoa aparece em todas as páginas abertas ao mesmo tempo. Toques repetidos em uma página lenta não devem repetir o efeito: gestos são idempotentes.
  • Controles onde a coisa está, e apenas para quem pode usá-los. Pessoas somente leitura veem o estado sem o controle.
  • Saiba quem está lá. Identidade e função alcançam todas as telas e todos os agentes. Não diga a um parceiro que « um parceiro deve confirmar ».
  • Limites honestos. Diga claramente o que o produto ainda não faz. Nunca aponte para uma tela que não pode fazê-lo.
  • Largura de telefone é um leitor de primeira classe: margens de 16px, sem rolagem horizontal (minmax(0,1fr), não 1fr), e a conta sempre acessível.
  • Mockups e narração na linguagem do produto (francês para Knowledger).

Testando manualmente com o namespace browser

O navegador nativo do Beam Lisp (optional/browser-port na árvore beam-lisp) executa Chromium com cabeçalho em um Sway headless privado, com entrada confiável e uma transmissão de tela contínua. É o mesmo objeto que um cenário dirige, então uma sessão manual se transforma em um teste sem ser reescrita. Use agent-browser para uma olhada rápida. Use o namespace browser para qualquer coisa que valha a pena manter.

Uma vez por máquina

cd ~/projects/beam-lisp/optional/browser-port
nix develop --command cargo build --release --locked --features native-browser
nix build .#runtime-wayland --out-link ~/.local/share/bl-browser/runtime-wayland   # chromium, sway, wayvnc
command -v ffmpeg || nix profile add nixpkgs#ffmpeg

Execute qualquer coisa que use com bl run -p ~/projects/beam-lisp/optional/browser-port/bl … (ou bl test -p …).

Uma sonda: um arquivo, uma pessoa, entrada real

templates/probe.bl é o ponto de partida. Seu núcleo:

(ns probe (:require [browser.page :as page]))
(def rt (str (System/get_env "HOME") "/.local/share/bl-browser/runtime-wayland/bin/"))
(def p (page/open! {:executable (str (System/get_env "HOME") "/projects/beam-lisp/optional/browser-port/target/release/bl-browser-port")
                    :width 1440 :height 860
                    :launch {"profile" "/tmp/probe/profile" "runtime" "/tmp/probe/runtime"
                             "chromium" (str rt "chromium") "compositor" (str rt "sway") "vnc" (str rt "wayvnc")
                             "width" 1440 "height" 960}}))
(try
  ;; quem está olhando: a identidade que o proxy adicionaria (aqui cabeçalhos Tailscale); alcança o socket ao vivo também
  (page/cdp! p "Network.enable" {})
  (page/cdp! p "Network.setExtraHTTPHeaders" {"headers" {"tailscale-user-login" "[email protected]" "tailscale-user-name" "timinou"}})
  (page/record! p "/tmp/probe/take.mp4" {:fps 24})          ; opcional: a sessão inteira como um filme
  (page/navigate! p "http://127.0.0.1:24025/a/sahel-…")
  (page/wait! p "document.documentElement.dataset.live==='1'") ; um predicado JS, limite de 30 s por padrão
  (page/click! p ".rv-rail a.para[data-goto]")               ; ponteiro confiável: move, pressiona, solta
  (println (page/evaluate! p "scrollY"))                     ; pergunte à página o que uma pessoa veria
  (page/screenshot! p "/tmp/probe/after.png")                ; então OLHE para ela
  (page/stop-recording! p)
  (finally (page/close! p)))

Os verbos são navigate! wait! click! hover! fill! key! drag! evaluate! screenshot! record! stop-recording! show-cursor! cdp!. cdp! alcança qualquer outra coisa que o Chromium oferece: viewport, rede, cookies, emulação (Emulation.setDeviceMetricsOverride para um telefone).

Hábitos que fazem uma sonda valer a pena ser mantida

  • Pergunte à página, não ao código. Cada verificação é uma expressão JS que retorna true quando uma pessoa veria a coisa: contagens de linhas, o texto de uma tag, scrollY, uma classe no elemento sob o ponteiro. Essas expressões se tornam afirmações sem alteração.
  • Selecione pelo significado. Dê ao aplicativo atributos de dados estáveis onde os testes precisam deles (button.cell[data-person='Karim Saadi'][data-team='Associés']), nunca « o quinto botão ».
  • Seja cada pessoa. Abra uma página por pessoa com sua identidade. Duas páginas lado a lado é como « ao vivo » é provado: uma age, a outra muda sem recarregar.
  • Verifique a primeira pintura e a página corrigida. Aplicativos ao vivo renderizam HTML uma vez, depois corrigem a partir dos dados. Bugs se escondem na diferença (uma classe descartada ao inserir, uma lista começando com texto lido como nome de tag). Alcance cada tela uma vez por URL e uma vez navegando até ela.
  • Aguarde a página ficar ao vivo, não apenas conectada. Um cliente ao vivo pode substituir a página renderizada pelo servidor pela primeira renderização do seu socket. Texto digitado entre eles é perdido, para um teste e para uma pessoa digitando rapidamente após o carregamento. O aplicativo deve manter o que foi digitado durante essa montagem e então dizer que está ao vivo (data-mounted). Testes aguardam essa flag.
  • Olhe para a largura do telefone. Verifique document.documentElement.scrollWidth === innerWidth a 390px, depois olhe para a captura de tela.
  • Nunca toque em dados reais, e prove isso. Aponte o aplicativo para uma cópia reflink de seus dados (cp -a --reflink=auto) e uma porta sobressalente. Depois prove o isolamento antes de confiar: renomeie uma coisa na cópia (um canário: uma equipe « AssociésX »), aja sobre ela e verifique se a cópia mudou e o timestamp do arquivo real não mudou. Faça isso uma vez por tipo de processo que escreve (manipuladores de página, sockets ao vivo, trabalhos em segundo plano). No Beam Lisp, System/put_env de um teste alcança manipuladores de página, mas não sockets ao vivo: um socket que não lê uma pasta de dados configurada cai de volta para o padrão, que são os dados reais. O aplicativo deve fixar sua configuração em toda a VM quando seu servidor inicia (persistent_term) e lê-la de lá. Se você precisar tocar em dados ao vivo, tire um instantâneo do arquivo, aja, faça diff para confirmar apenas sua alteração, restaure.

Da sonda ao filme

Um scenario.demo/defdemo é um teste comum (bl test). Os passos mapeiam um a um:

SondaCenário
(page/navigate! p url)(s/does :othman [:navigate url])
(page/wait! p js)(s/does :othman [:wait js])
(page/click! p sel) / hover! / fill! / key![:click sel] [:hover sel] [:fill sel text] [:key "Enter"]
uma pausa para o olho[:pause ms]
(page/evaluate! p js) que deve ser verdadeiro(s/sees :othman (fn [p _] (= true (page/evaluate! p js))) "a experiência")
uma pessoaum ator em browser.film/owned-worlds, embrulhado para definir sua identidade ao abrir
um parágrafo de narração(demo/scene :id {:title … :say … :capture :video} eventos…)

templates/feature-demo.bl é um arquivo completo: uma cópia isolada dos dados do aplicativo, o aplicativo iniciado na VM de teste em uma porta sobressalente, mundos gravados com identidades, trilhas silenciosas quando nenhuma chave de voz existe, e uma demonstração com três cenas. Exemplo funcional: knowledger-interface-review/apps/practice/test/features-demo.bl (cinco filmes: revisão, histórico, peças, uma equipe alterada ao vivo entre duas pessoas, uma conversa gravada).

Escreva cenas como a experiência, não a correção: « Cada ponto leva ao seu lugar », nunca « corrija o manipulador §-link ». A narração é a documentação.

Voltas do modelo em fita

Qualquer coisa que um agente faça deve passar pela própria porta de ferramentas do aplicativo, para que apenas as escolhas do modelo sejam do modelo. Uma fita mantém, para uma execução do modelo, as chamadas de porta que ele fez em ordem e sua resposta final, indexadas por um hash do modelo, prompt do sistema e prompt (com relógios, números tipo época e ids hex mascarados).

  • record: reproduz o que está na fita, executa o modelo para o que não está, mantém.
  • replay (o padrão): uma execução não na fita é uma volta de erro. Uma reprodução nunca cai de volta para o modelo em silêncio.
  • Reproduzir faz as mesmas chamadas através da mesma porta, ritmado, para que o produto faça o trabalho novamente e a tela mostre, em segundos e de graça.

Fixe tudo que alcança o prompt (o nome da empresa, a data se houver) nos dados de teste, ou a chave se desviará. Comprometa as fitas. Implementação de referência: apps/practice/src/practice/cassette.bl e seus dois ganchos em conversation.bl (a volta e a porta).

Executando e renderizando

bl test -p ~/projects/beam-lisp/optional/browser-port/bl app/test/features-demo.bl             # reproduzir, provar, capturar
DEMO_RECORD=1 bl test -p …                       # colocar voltas de modelo ausentes na fita (precisa de credenciais do modelo)
BL_DEMO_EXPORT=1 bl test -p …                    # também renderizar MP4 + legendas + capítulos por filme

Cada filme limpa sua última captura em seu fixture, porque uma gravação nunca sobrescreve uma. Mantenha cada narração dentro de duas linhas de legenda (cerca de 130 caracteres), ou a renderização recusa. Uma máquina carregada pode matar de fome o codificador de transmissão de tela: verifique frames/recordings.json, onde encodedFrames deveria ser cerca de segundos × fps, e execute novamente quando uma captura estiver curta.

Renderização (scenario.film/export!) precisa de Python 3 e FFmpeg com libass. A narração é falada quando DEEPGRAM_API_KEY está definido. Caso contrário, cada cena recebe uma trilha silenciosa tão longa quanto sua legenda leva para ler. Nunca assuma que uma chave de voz exista. Navegue pelos filmes com (scenario.demo/serve! dir {:port 4163}) em loopback, ou publique com work serve.

Antes de dizer que está pronto

  • Cada item relatado tem sua frase de experiência, sua causa e uma afirmação que prova em um navegador real, como cada pessoa preocupada.
  • Largura de desktop e telefone vistas, em capturas de tela, não apenas afirmadas.
  • Primeira pintura e página corrigida ambas verificadas para cada tela tocada.
  • Comportamento ao vivo provado com duas pessoas, onde importa.
  • Nenhum dado real alterado pelo teste. Qualquer coisa tocada é restaurada, com o diff mostrado.
  • Filmes reproduzidos a partir da fita sem rede. Fitas e cenários são comprometidos, renderizações não.
  • O resumo lidera com o que a pessoa encontrará agora.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas