oliverswitzer/lens

Crie e mantenha uma lente de produto — um grafo JSON versionado no git que captura o propósito, loop central, avatares, entrevistados, evidências, alegações, hipóteses de foco, superfícies entregues, ideias, alternativas, concorrentes, insights de mercado, pilares de conteúdo e decisões — tudo em um único index.html autossuficiente e comentável, com visualização de diffs.

O que é lens?

Este skill para agentes de IA (como Claude Code, Cursor, Codex) permite criar e manter uma 'lente de produto' — um grafo JSON completo e versionado no git que centraliza o entendimento de um produto. A lente estrutura informações como propósito, loop central, personas (avatares), entrevistas, evidências (observadas, visão do dono, hipóteses), superfícies entregues e ideias, concorrentes, alternativas, insights de mercado e pilares de conteúdo. Tudo é compilado em um arquivo `index.html` autossuficiente, que qualquer pessoa pode abrir e comentar diretamente no navegador. O skill suporta fluxos como: configurar uma nova lente, adicionar evidências de entrevistas, atualizar uma superfície após uma mudança, adicionar ideias de brainstorms, incluir concorrentes ou insights de mercado, e visualizar diffs de alterações. Ele é útil para product managers, designers e equipes que desejam manter um 'single source of truth' sobre o produto, rastreando decisões, evidências e suposições de forma transparente e rastreável. A validação é feita durante a build, garantindo que o modelo respeite regras de integridade, e o uso de IDs bloqueados (`ids.lock.json`) preserva comentários mesmo após renomeações ou remoções.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/oliverswitzer/product-lens/tree/main/skills/lens

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

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

Documentação

Lente

Uma lente é um grafo JSON, <lente>/model.json, compilado em um <lente>/index.html autossuficiente que qualquer pessoa pode abrir e comentar. <lente> é a pasta onde foi inicializada (padrão docs/lente). <lente>/README.md documenta os tipos de nós, relações, formato das alegações e regras de integridade. A build rejeita um modelo que viole uma regra; portanto, uma build verde é a primeira verificação.

A pasta deste skill contém template/ (o que é copiado para um repositório), scripts/ (auxiliares para concorrentes) e competitors.md. Encontre-a em .claude/skills/lente/ no repositório ou em ~/.claude/skills/lente/ quando instalado globalmente; abaixo, $SKILL significa essa pasta.

Requisitos: Node 20+ e git. Nenhum package.json, nenhuma dependência.

Configurar uma nova lente

  1. Escolha a pasta. Pergunte ao usuário onde a lente deve ficar; padrão docs/lente. Recuse sobrescrever um model.json existente.

  2. Copie o template (tudo, exceto um index.html já compilado):

    mkdir -p docs/lente && cp -R "$SKILL/template/." docs/lente/ && rm -f docs/lente/index.html
    echo '[]' > docs/lente/ids.lock.json      # os IDs iniciais não são seus; comece o lock vazio
    
  3. Entreviste o usuário e substitua o modelo inicial. O model.json vem com um exemplo fictício "Acme Notes" que mostra todos os tipos comuns. Mantenha sua estrutura, substitua seu conteúdo. Pergunte, um tópico por vez, e dê um rascunho concreto para corrigir, em vez de uma pergunta em branco:

    • o nome do produto (title) e o nome do dono (nó pessoa owner, id p-owner a menos que ele prefira outro; seu title é exibido como "Visão de " em cada alegação de visão);
    • o propósito em uma frase (purpose, uma alegação do tipo view citando a fonte do dono);
    • o loop central, 2 a 5 loop-steps ordenados;
    • para quem é (avatars, com um mapa de personas) e quais as dores (problems);
    • entrevistas ou outras evidências que já possuem (source + nós person; nunca invente citações ou timestamps — se não houver transcrição, registre como relato do dono);
    • o que já foi entregue (surface com shipped: true, com screenshot real) e o que é apenas ideia (shipped: false);
    • o que as pessoas usam no lugar (alternatives);
    • até três apostas para provar agora (hypothesis com focus: 1|2|3). Tudo que o usuário disser sem evidência é uma view (dele) ou uma hypothesis; nada é observed sem uma fonte e um at. Use nomes placeholder ("Entrevistado A") a menos que o usuário queira nomes reais em um arquivo que pode ser público.
  4. Limpe o exemplo. Delete assets/example.png quando nenhum nó o referenciar, e aponte screenshots para assets/surfaces/<surface-id>/<slug>.png. Caminhos de code e adrs de superfícies são relativos à raiz do repositório e devem existir (aponte adrs para onde o repositório mantém registros de decisão, ex.: docs/adr/).

  5. Compile e teste:

    node docs/lente/build.mjs && node --test docs/lente/tests/*.test.mjs
    
  6. Visualize. Os comentários são armazenados no navegador por origem, então sirva o arquivo em vez de abri-lo diretamente:

    python3 -m http.server 8767 --bind 127.0.0.1    # a partir da raiz do repositório
    open "http://127.0.0.1:8767/docs/lente/index.html"
    
  7. Sugira uma linha de .gitignore para docs/lente/assets/ads/**/*.mp4 se forem rastrear anúncios de concorrentes. Faça commit de model.json, ids.lock.json, index.html, assets/ e o resto da pasta, seguindo as regras de commit do próprio repositório.

Fundamentar o trabalho

Leia os nós relevantes, suas alegações e fontes antes de perguntar algo ao dono. Dê a ele uma síntese concreta para corrigir. Para uma superfície, verifique o código que ela nomeia (code, adrs) quando seu comportamento for relevante; um registro de decisão diz o que foi decidido, não o que o código faz hoje.

Adicionar evidências

Cada afirmação é uma alegação com kind, evidence e um next opcional:

  • observed (Ouvi / vi): o que alguém disse ou fez. Cite a fonte com at (timestamp de transcrição, ou seção de um documento). Parafraseie ou cite de perto; nunca melhore uma hesitação ("poderia ser útil").
  • view (Visão do dono): a interpretação do dono. Deve citar uma fonte cujo people inclua o owner do modelo.
  • hypothesis (Não testado): qualquer coisa não testada, incluindo sugestões do agente e ideias de implementação.
  • Uma hipótese também é um tipo de nó: registre cada evidência com stance (supports ou contradicts) e at. Nunca defina uma confiança; o indicador nas hipóteses focus é calculado a partir dessas evidências na próxima build (entrevistados distintos apoiando; um nível abaixo se alguém contradiz; a visão do dono nunca a aumenta). Registre evidências contraditórias tão prontamente quanto as de apoio.
  • Dê a cada alegação fraca um next: uma pergunta específica o suficiente para ser feita em uma ligação. Ela aparece em Próxima conversa.
  • Mantenha claro quem disse o quê: uma ideia que o dono levantou e alguém concordou não é uma necessidade dessa pessoa.
  • Uma nova entrevista é uma source com date, people, locator e takeaways curtos, citada pelas alegações que apoia. Deixe de fora detalhes pessoais não relacionados ao produto. Arquive transcrições em <lente>/sources/ apenas se o repositório for privado e o entrevistado concordou.

Atualizar uma superfície (após alterá-la)

Quando uma mudança altera a aparência ou o comportamento de uma superfície, no mesmo branch:

  1. Capture os estados alterados do produto em execução em <lente>/assets/surfaces/<surface-id>/<slug>.png (substitua os obsoletos, mantenha 1 a 4).
  2. Atualize as entradas screenshots da superfície: caption, capturedAt (hoje), origin: "app", version. A página sinaliza qualquer screenshot mais antigo que o último commit no code da superfície.
  3. Atualize unique / situations se o comportamento mudou, e code / adrs se arquivos foram movidos.

Uma superfície recém-entregue é um novo nó surface com shipped: true, pelo menos um screenshot, arestas serves para os problemas que resolve e arestas implements para etapas do loop.

Adicionar uma ideia (de um brainstorm)

Uma superfície que foi discutida mas não construída é uma surface com shipped: false; aparece em Ideias, visualmente distinta. Dê a ela unique (como alegações hypothesis), situations, heard (o que as pessoas disseram, com evidência) e mockups como screenshots com origin: "design". Quando for entregue, alterne shipped e substitua mockups por capturas reais.

Adicionar um pilar de conteúdo ou ideia

Um tema de marketing é um pillar; um post, vídeo ou evento concreto é uma content-idea under ele, com um format. Relacione pilares ou ideias a avatares com speaks-to, ideias features as superfícies que mostram e like concorrentes que já executam um ângulo semelhante. Ideias e pilares são Não testados até que o conteúdo tenha alcançado pessoas; registre o que aconteceu como evidência em uma hipótese about a ideia.

Adicionar um insight de mercado

Uma tendência de pesquisa externa é um insight na aba Market insights. Registre o artigo como uma fonte Market research (opcionalmente um snapshot em sources/), declare seus fatos como findings do tipo observed, e mantenha o que significa para um avatar como uma view ou hipótese, incluindo uma finding sobre os limites da fonte. Relacione-o com bears-on a tudo que ele afeta.

Adicionar ou atualizar um concorrente

Siga $SKILL/competitors.md: pesquise (verificações de anúncios em navegador real, nunca contornando um bloqueio), scripts/add-product.py, captura de anúncios em staging, scripts/apply-staged-ads.py (verifica tudo, depois aplica em um passo), scripts/smoke-ads.mjs, depois faça commit sem .mp4s. Compare com o produto a partir do propósito e das hipóteses de foco da lente, nunca de sua página de marketing, e rotule essa comparação como Não testado.

Achados de usabilidade não são conteúdo da lente

Problemas de interação (um botão que ninguém encontra, um estado de foco ausente) pertencem ao rastreador de issues da equipe. Registre-os lá e documente apenas seu significado para o produto, se houver, na lente.

Renomear ou remover

ids.lock.json registra cada id comentável da última build. Um id que desaparece deve ser mapeado em renamed no model.json ("old-id": "new-id", ou null quando removido intencionalmente), ou a build falha. É isso que mantém comentários existentes vinculados.

Alterar a própria lente

Qualquer alteração em components/ (o que uma view mostra, roteamento, validação, diff) começa com um teste falhando em <lente>/tests/ (node:test; fixture compartilhada em tests/fixture.mjs, apenas nomes fictícios). Mantenha a lógica em módulos puros; apenas components/app.js toca no DOM. Depois execute os testes, então verifique o mesmo cenário em um navegador.

Visualizar o diff

Quando o dono pedir para ver, revisar ou visualizar o que mudou:

node docs/lente/diff.mjs [rev]          # padrão HEAD; imprime a lista de alterações
python3 -m http.server 8767 --bind 127.0.0.1
open "http://127.0.0.1:8767/docs/lente/index.html"

Contornos verdes são itens adicionados e amarelos são alterados; itens removidos são listados em vermelho no banner. Cada linha adicionada ou alterada vincula ao seu item. As alterações são correspondidas por id, então uma única alegação acende sem que todo o cartão seja destacado. Antes de commitar, sempre limpe e verifique:

node docs/lente/build.mjs
grep -c LENS-V2-DIFF docs/lente/index.html   # deve imprimir 0

Recompilar e verificar

node docs/lente/build.mjs && node --test docs/lente/tests/*.test.mjs

Depois veja as views afetadas no navegador. Os comentários são locais ao navegador por origem; exporte-os antes de trocar. Termine com o link da lente, o que mudou, as evidências e quaisquer limites.

Habilidades Relacionadas