Pinpoint

Clique em um elemento do seu aplicativo web em execução ou no iOS Simulator e diga o que deve mudar; seu agente de codificação (Claude Code, Cursor, Codex) recebe seu comentário com o seletor, caminho DOM, estilos, cadeia de componentes, dica de arquivo-fonte e uma captura de tela recortada. Apenas local, MIT.

Documentação

Pinpoint

tests licence: MIT stars npm Glama score

Clique em um elemento do seu site de desenvolvimento local, escreva o que deve mudar, e seu agente de codificação recebe a informação — com o seletor, o caminho no DOM, os estilos computados, a cadeia de componentes React/Vue, a dica de arquivo-fonte e uma captura de tela recortada. Sem arquivos de captura se acumulando na sua pasta Downloads, sem descrever "o terceiro botão à esquerda". Está criando um app nativo? O mesmo funciona no Simulador iOS.

Não é só para estilização. Diga o que a coisa deve fazer — "desative isso até o formulário ser válido", "isso deve salvar o rascunho antes de fechar", "mostre aqui o erro que a API retornou" — e o agente recebe a instrução de tratar o elemento como ponto de partida, seguindo-o até os handlers, o estado, as chamadas de API e o backend por trás dele. Mais abaixo.

Browser (extension) ──POST──▶ pinpoint bridge (127.0.0.1:7331) ──MCP / hooks──▶ Claude Code, Cursor, Codex…
        pins ◀──live events───┘   ~/.pinpoint/annotations.json   └── <repo>/.pinpoint/pending.md (optional)
iOS Simulator ─▶ 127.0.0.1:7331/ios ─┘  (screenshot + accessibility tree instead of the DOM)

Pinpoint on a local dev page: picking an element, writing what should change, and the agent picking it up

Clique em um elemento, diga o que deve mudar, seu agente recebe. (vídeo em velocidade normal)

Não é um agente que controla o navegador

A distinção importa, porque os dois acabam sendo colocados na mesma categoria e são opostos:

  • Playwright MCP, agent-browser, computer-use colocam o agente no comando — ele navega, clica e faz asserções. Bom para testes e para navegar por você.
  • Pinpoint mantém você no comando. Você clica, você diz o que deve mudar, e o agente recebe contexto estruturado para editar código: um seletor, os estilos, a cadeia de componentes, uma dica de arquivo-fonte, um recorte do elemento. Ele nunca toca na página em si.
  • Uma captura de tela colada não carrega nada disso. O agente recebe pixels e precisa adivinhar qual controle você quis dizer, como ele se chama e onde ele está na árvore.

Então ele se integra à automação de navegador em vez de competir com ela: aponte para a coisa, deixe o agente mudá-la, deixe seus testes dirigirem o navegador.

Início rápido

Você precisa de Node 18+ e um navegador Chromium (Chrome, Edge, Brave, Arc, Opera, Vivaldi).

git clone https://github.com/gowtham012/pinpoint
node pinpoint/bridge/cli.js setup

Essa é a instalação. setup instala as próprias dependências primeiro, depois pergunta — toda pergunta tem um padrão, então apertar Enter até o fim já é uma configuração funcional:

  • qual UI do projeto você quer anotar — o repositório cujos arquivos seu agente vai editar
  • se é um app web ou um app iOS nativo (ou ambos) — web recebe a extensão do navegador; iOS recebe o seletor do Simulador, e a configuração verifica Xcode, Maestro e Java e diz como obter o que estiver faltando. Ela não instala nenhum deles por você.
  • quais agentes conectar — ela detecta Claude Code, Cursor e Codex e escreve a entrada MCP para cada um: claude mcp add para Claude Code, <project>/.cursor/mcp.json para Cursor, ~/.codex/config.toml para Codex. Entradas existentes são mescladas, nunca substituídas, e o arquivo TOML é copiado como backup antes de ser tocado.
  • se deseja instalar os hooks do Claude Code, que carregam anotações pendentes junto com sua próxima mensagem
  • qual navegador carregar a extensão, listando os que você realmente tem (somente web)

Depois ela registra o lançador atrás do botão Iniciar bridge do popup e inicia a bridge. Não interativo, para uma máquina com script: node pinpoint/bridge/cli.js setup ~/code/my-app --yes (adicione --for ios ou --for both; o padrão é web).

Está criando apenas um app iOS nativo? Você pode pular o clone: o seletor iOS não precisa de extensão.

npx -y pinpoint-bridge                                      # the bridge, with the picker at /ios
claude mcp add pinpoint -s user -- npx -y pinpoint-bridge mcp   # once, for Claude Code

O Pinpoint também está listado no Registry MCP oficial (io.github.gowtham012/pinpoint), no cursor.directory (Adicionar ao Cursor com um clique) e no Glama. Todos eles instalam apenas o servidor MCP — para páginas web você ainda precisa da extensão e da bridge do clone acima.

O único passo que não pode ser um comando. O Chrome não permite que um terminal carregue uma extensão não empacotada no seu próprio perfil — apenas a Web Store ou uma política empresarial pode. Então a configuração abre a página de extensões do seu navegador e coloca a pasta extension/ na sua área de transferência: Modo do desenvolvedor ativado → Carregar sem compactação → cole. O terminal confirma ✓ O Pinpoint está ativo no Chrome por conta própria, porque a bridge consegue ver a extensão se conectar.

Reinicie o Claude Code uma vez depois — ele lê servidores MCP e hooks quando uma sessão começa.

Depois experimente. Abra seu site de desenvolvimento (ou a página de demonstração), pressione ⌥⇧A / Alt+Shift+A, clique em qualquer elemento, digite o que deve mudar, ⌘↩ / Ctrl+Enter. Digite qualquer coisa no Claude Code e sua anotação chega junto. Se a barra nunca aparecer, veja Solução de problemas.

Fazendo manualmente, e as notas sobre Windows / file://

setup escreve configuração no seu repositório e nos arquivos do seu agente. Se você preferir fazer isso você mesmo, são quatro passos — e a ordem importa: $PWD é embutido na entrada MCP, então o passo 2 precisa rodar a partir de pinpoint/bridge, antes que a bridge assuma o terminal.

# 1. get it
git clone https://github.com/gowtham012/pinpoint
cd pinpoint/bridge && npm install

# 2. wire up Claude Code (once, from this folder)
claude mcp add pinpoint -s user -- node "$PWD/cli.js" mcp
node cli.js install-hooks ~/code/my-app                  # notes arrive without being asked
node cli.js install-native-host --project ~/code/my-app   # optional: the popup's "Start bridge" button

# 3. load extension/ unpacked at chrome://extensions (Developer mode on)
# 4. start the bridge, and leave it running
node cli.js --project ~/code/my-app

Reinicie o Claude Code uma vez após o passo 2. --project é opcional: ele mantém <repo>/.pinpoint/pending.md atualizado para agentes que leem um arquivo em vez de MCP.

Anotando uma página que você abriu como URL file://? O Chrome mantém isso desativado por padrão. No chrome://extensions, abra os Detalhes do Pinpoint e ative "Permitir acesso a URLs de arquivo", depois recarregue a página.

No Windows, $PWD funciona no PowerShell e no Git Bash, mas não no cmd.exe — execute node cli.js --help e copie a linha claude mcp add … pronta que ele imprime, que já carrega o caminho completo. Os atalhos são Alt+Shift+A e Ctrl+Enter, e a interface os rotula dessa forma. install-native-host é apenas para macOS e Linux; no Windows, inicie a bridge em um terminal.

Quais navegadores

Chromium — Chrome, Edge, Brave, Arc, Opera, Vivaldi. Carregue sem compactação, como acima; a suíte de testes executa Chromium headless, então é esse o que é verificado continuamente. Safari — compilado em vez de carregado: bash tools/make-safari.sh (precisa de Xcode). Firefox — ainda não.

O que difere no Safari e o que bloqueia o Firefox

O Safari não aceita extensões não empacotadas, então tools/make-safari.sh a envolve em um pequeno app macOS — ele converte, compila e imprime as quatro configurações do Safari para alternar (a importante é Desenvolver ▸ Permitir extensões não assinadas, que é redefinida toda vez que o Safari fecha). Falta um recurso lá: "world": "MAIN" scripts de conteúdo não são suportados, então inspector.js não consegue ler fibers do React ou instâncias do Vue, o que custa a cadeia de componentes e a dica de arquivo-fonte. Todo o resto — seleção, regiões, comentários, pins, capturas, a bridge, MCP — permanece igual.

O Firefox está mais perto do que antes (todo script prefere browser onde existe), mas dois bloqueadores de manifest permanecem: background: { service_worker } onde o Firefox MV3 quer background: { scripts }, e um browser_specific_settings.gecko.id ausente. Ambos são corrigíveis, mas mantê-los honestos precisa de um job do Firefox no CI em vez de uma afirmação num README. Abra uma issue se quiser.

Apps iOS nativos (Simulador)

Um app nativo não tem DOM, então este caminho lê a árvore de acessibilidade em vez disso. Funciona para apps SwiftUI, UIKit, React Native e Flutter, e não precisa de nada adicionado ao seu app.

Você precisa de Xcode com um Simulador iniciado e Maestro (ele lê a árvore, e precisa de Java — um openjdk do Homebrew é encontrado mesmo quando não está no seu PATH). A bridge mantém um processo maestro mcp rodando para isso, então apenas o primeiro carregamento espera (~10s, enquanto o Maestro inicia seu driver no dispositivo); cada atualização depois disso leva cerca de um segundo. Cada Maestro no seu Mac compartilha esse único driver, então se outro (um servidor MCP Maestro de um agente, uma execução de teste) o reiniciar, a próxima leitura da bridge falha, e a bridge então inicia um Maestro novo e tenta mais uma vez. Se o primeiro carregamento levar minutos, feche as sessões do Claude Code que você não está usando e que têm o servidor MCP Maestro.

A configuração pergunta se seu app é web ou iOS, e para iOS abre esta página para você. Caso contrário, com a bridge rodando — node cli.js a partir do clone, ou npx -y pinpoint-bridge sem clone nenhum — abra http://127.0.0.1:7331/ios. Ele mostra a tela do Simulador: passe o mouse para ver cada elemento, clique em um, digite o que deve mudar, ⌘↩. A anotação chega ao seu agente como qualquer outra, com o accessibilityIdentifier do elemento (seu testID), seu rótulo, seu caminho na árvore, seu frame e um recorte. Pressione R (ou Atualizar) depois que o app mudar; anotações resolvidas desaparecem.

O que ele não pode dar: uma dica de arquivo-fonte ou cadeia de componentes (a árvore não tem nenhum dos dois — dê identificadores aos elementos e o agente faz grep por eles), estilos, ou recheck_annotation, que espera um navegador e expira aqui. Android ainda não está conectado.

Onde roda

O Pinpoint é uma ferramenta para o app que você está construindo, então ele só se carrega em páginas de desenvolvimento local: localhost, 127.0.0.1, .local / .test / .localhost hosts, e páginas file:// uma vez que você concedeu acesso a arquivos. Em qualquer outro site ele simplesmente não está lá — sem barra, sem overlay, nada injetado.

Em qualquer outro lugar — uma URL de staging, ou um endereço LAN como 192.168.1.5:3000 quando você está testando pelo seu celular — o popup da barra de ferramentas o ativa para aquela aba específica.

Como usar

Enquanto a bridge está rodando, uma pequena barra fica no canto superior direito de cada página. Clique nela (ou pressione ⌥⇧A / Alt+Shift+A) para começar a marcar. Clique em um elemento, digite o que deve mudar, pressione ⌘↩ / Ctrl+Enter, e você já está pronto para o próximo. Esc quando terminar, ou clique em Parar na barra. O × esconde a barra para aquele site; o popup a traz de volta, e pode movê-la para qualquer canto.

The bar, idleThe bar resting as a dotThe bar while picking, with a Stop control
Ele informa o atalho e quem está aqui — você e seu agente.Após alguns segundos ele vira um ponto, fora do seu caminho. Passe o mouse para trazê-lo de volta.Selecionando. A barra é transparente a cliques para nunca bloquear o elemento que você está mirando; Parar é a exceção.

The comment popover on a form field, showing the element it picked

O popover nomeia exatamente o que você selecionou, para você distinguir dois botões quase idênticos antes de digitar.

A numbered pin on the annotated field

Um pin numerado gruda no elemento — numerado por página, então cada página conta a partir de 1. Os pins vivem na bridge, não na página, então sobrevivem a recarregamentos, aparecem em toda aba que mostra aquela página, e desaparecem no momento em que seu agente marca a mudança como concluída. Em apps que reconstroem seu DOM, cada pin reencontra seu próprio elemento por identidade, e se esconde em vez de ficar sobre um elemento diferente que por acaso corresponde ao seletor antigo. O contador da barra abre a lista de tudo marcado nesta página; clique em uma linha para ir até ela.

Two notes on a panel that rebuilds itself: one re-finds its element, the other says it is not on this view

As mesmas duas anotações, duas vezes. Alterne de aba e o painel é reconstruído do zero — a anotação 1 reencontra seu próprio elemento entre nós que não existiam há um instante, enquanto a anotação 2 admite que não está nesta visualização. Um agente perguntando naquele momento recebe a mesma informação.

Quando a página se move sob um pin. Um pin que não consegue mais encontrar seu elemento não apenas se esconde — a bridge é informada, então a próxima coisa que seu agente lê diz que o elemento pode estar desatualizado em vez de entregar um seletor que ficou inválido. E recheck_annotation pede ao seu navegador para olhar novamente agora: ele reencontra o elemento, diz se ele sumiu, saiu de baixo do seu seletor, ou apenas mudou, e retorna um recorte novo ao lado do que foi tirado quando você marcou. Se nenhuma aba estiver aberta naquela página, ele diz que não conseguiu olhar — nunca que nada mudou.

Marcando uma área. Algumas mudanças são sobre um grupo — "deixe estes cards em duas colunas no mobile". Arraste em vez de clicar e você obtém uma caixa, ancorada no elemento mais profundo que a contém completamente. Seu agente recebe um contêiner real para mudar, além da lista do que a caixa continha e uma captura de tela recortada para ela. Lendo a resposta. Uma nota concluída não desaparece. Ela permanece no painel com a resposta do seu agente logo abaixo, para que você possa ler o que mudou sem voltar ao terminal.

The notes panel: a pending note, and a finished one with the agent's reply beneath it

Essa resposta é o note que seu agente passa para resolve_annotation, o que é obrigatório — a ferramenta informa que você leu isso no seu navegador, e que "concluído" não é uma resposta. Enquanto funciona, a barra mostra o que está fazendo: a nota que está sendo analisada ganha um anel, e uma nota concluída desaparece diante de você.

Depois, é só conversar normalmente com o Claude Code. Com os hooks instalados, você não precisa mencionar o Pinpoint; sem eles, diga "aplique minhas anotações do pinpoint". Se a ponte não estiver em execução, Enviar copia um prompt pronto para colar para a sua área de transferência, para que nada se perca.

Iniciando e reiniciando a ponte a partir do navegador

Um navegador não pode iniciar um processo, então o install-native-host registra um pequeno lançador com o Chrome (e Brave, Edge, Arc, Chromium, Vivaldi, Opera). Depois disso, o botão Iniciar ponte do popup funciona e, enquanto a ponte está em execução, esse botão e o ↻ na barra da página a reiniciam — o que você quer depois de puxar uma nova compilação, sem sair da página.

O lançador pode fazer exatamente uma coisa: executar o cli.js deste repositório em um número de porta, lido da configuração do popup e nunca da página. A reinicialização é HTTP simples para a própria ponte, então não precisa de lançador e funciona também no Safari. Apenas macOS e Linux por enquanto; no Windows, inicie a ponte em um terminal.

Quando mais de um agente está conectado

Os agentes se apresentam no handshake do MCP, então a barra nomeia aquele que está trabalhando (claude-code, cursor-vscode, codex) em vez de dizer "seu agente", e cada resposta no painel é atribuída a quem a escreveu. wait_for_annotation entrega cada nova nota a exatamente um agente em espera, então dois agentes observando ao mesmo tempo compartilham a fila em vez de ambos fazerem a mesma nota — e se um resolver algo que outro já concluiu, ele é informado disso.

Como seu agente descobre

Três mecanismos, do mais forte ao mais fraco. Eles se acumulam — usar todos os três é aceitável.

  • Hooks (automático). node cli.js install-hooks <repo> adiciona um hook SessionStart e um UserPromptSubmit ao <repo>/.claude/settings.json, ambos executando cli.js print --hook. Não imprime nada quando não há nada pendente, então uma sessão normal não é afetada. Marque algo no navegador, digite qualquer coisa no Claude Code, e ele vem junto. Suas próprias configurações nesse arquivo são preservadas, e reexecutar atualiza em vez de duplicar. Reinicie o Claude Code uma vez depois.
  • MCP (sob solicitação). As instruções do servidor pinpoint dizem ao agente para verificar anotações sempre que você falar sobre uma mudança de UI ou recurso, então "deixe esse botão maior" geralmente aciona uma busca por conta própria.
  • Um loop de observação (sem intervenção). Diga "observe o pinpoint e aplique cada mudança conforme ela chegar". O agente fica parado em wait_for_annotation, que retorna no instante em que você pressionar Enviar — com captura de tela incluída.

Aparência ou comportamento

O comentário é a instrução, nas suas palavras, e pode ser sobre qualquer coisa da qual o elemento faça parte. Ambas são boas notas:

  • "Deixe isso em largura total no mobile e remova a sombra" — uma mudança de estilo, feita onde o elemento está.
  • "Clicar nisso deve salvar o rascunho primeiro e mostrar um toast se o salvamento falhar" — uma mudança de comportamento. O botão é apenas o caminho: o agente é instruído a segui-lo do componente até o handler, o estado, a chamada de API e, se for onde a correção pertence, a rota do backend.

Cada canal — MCP, os hooks, pending.md, os botões de copiar para a área de transferência — informa ao agente que uma nota pode ser sobre qualquer um dos dois, então uma solicitação de comportamento não é reestilizada e chamada de concluída. Quanto mais você disser sobre o resultado desejado ("deve", "em vez de", "quando … então …"), menos o agente terá que adivinhar.

Conectando outros agentes

A entrada mais simples executa o pacote publicado, então não há caminho para acertar: npx -y pinpoint-bridge mcp. Ele fala com qualquer ponte em execução, clonada ou não. Para fixar o agente ao seu clone, use o caminho absoluto para cli.js (de pinpoint/bridge, execute pwd e adicione /cli.js, ou copie a linha que node cli.js --help imprime). Reinicie o editor depois; os servidores MCP são lidos na inicialização.

Cursor — um clique em cursor.directory, ou .cursor/mcp.json (ou ~/.cursor/mcp.json para cada projeto):

{ "mcpServers": { "pinpoint": { "command": "npx", "args": ["-y", "pinpoint-bridge", "mcp"] } } }

Codex CLI — ~/.codex/config.toml:

[mcp_servers.pinpoint]
command = "npx"
args = ["-y", "pinpoint-bridge", "mcp"]

Qualquer cliente MCP via HTTP — http://127.0.0.1:7331/mcp (Streamable HTTP, sem estado). Windsurf, Cline, Continue, Zed e Gemini CLI todos aceitam uma URL.

Sem MCP algum — execute a ponte com --project <repo> e ela mantém <repo>/.pinpoint/pending.md atualizado (com seu próprio .gitignore). Diga a qualquer agente "leia .pinpoint/pending.md e aplique"; ele termina cada um com node cli.js resolve <id>. Ou use Copiar prompt no popover para colar em qualquer chat.

Comandos

Execute estes a partir de pinpoint/bridge.

node cli.js [start]            start the bridge (default command)
node cli.js mcp                run as a stdio MCP server
node cli.js status             is it running? how many pending?
node cli.js print              pending annotations as markdown  (--consume also resolves them)
node cli.js resolve <id...> --note "what you changed"
                               mark done — the pin disappears and your note is shown as the reply
node cli.js install-hooks [dir]  wire up Claude Code
node cli.js install-native-host   let the popup's "Start bridge" button start the bridge
                               (--uninstall removes it; --id <id> allows a second checkout)
node cli.js clear              delete everything
node cli.js --help

http://127.0.0.1:7331/ios      the iOS Simulator picker, served by the running bridge

--port <n>       default 7331, or $PINPOINT_PORT (set the same number in the popup)
--project <dir>  mirror pending annotations into <dir>/.pinpoint/
--print          echo each new annotation to stdout as it arrives
$PINPOINT_HOME   where annotations are stored (default ~/.pinpoint)

Ferramentas MCP

ferramentapropósito
get_pending_annotationstudo pendente como uma lista de tarefas em markdown, cada uma com sua captura de tela
list_annotationsuma linha por anotação
get_annotationdetalhe completo + captura de tela para um id ou número de pin
recheck_annotationreencontra o elemento na página ao vivo e relata o que mudou, com um recorte novo ao lado do original
resolve_annotationmarcar como concluído → o pin desaparece no navegador em menos de um segundo
wait_for_annotationbloqueia até o desenvolvedor enviar a próxima
clear_annotationsapagar tudo

Recurso: pinpoint://pending (markdown).

O que uma anotação contém

comment          "make this full-width on mobile"          ← the only instruction
page             url, title, viewport, scroll
element          tag, id, classes, a CSS selector built from stable attributes where they exist
                 (`button[data-action="next"]` rather than `:nth-of-type(2)`; shadow DOM via
                 "host >>> inner"), DOM path, rendered text, trimmed outerHTML, role/aria/data-*
                 attributes, bounding box, ~25 computed style properties, and a fingerprint
                 (tag + text + key attributes) used to verify a pin is still on the right element
source           framework (react/vue/svelte/angular/astro), component chain,
                 file:line where the dev build exposes it
screenshot       PNG of just the element (+8px), long edge ≤1200px

Do Simulador iOS, element carrega o identificador de acessibilidade, rótulo, texto e valor em vez disso, o caminho pela árvore de acessibilidade e o quadro em pontos; source é ios-native sem arquivo, e page.url é ios-simulator://<device name>.

Para file:line exato no React 19 ou Next, adicione um plugin de inspetor somente para desenvolvimento (vite-plugin-react-inspector, @react-dev-inspector) — o Pinpoint lê os atributos data-source que eles emitem, bem como os próprios _debugSource/_debugStack do React e o __file do Vue.

Solução de problemas

Nenhuma barra aparece na página

A barra só aparece enquanto a ponte está em execução — é assim que ela informa que está ativa. Verifique node cli.js status a partir de pinpoint/bridge. Se a ponte estiver ativa mas a barra ainda não estiver lá, a página provavelmente não é uma em que o Pinpoint injeta automaticamente (veja Onde é executado) — abra o popup da barra de ferramentas e ative para essa aba.

Nada em uma página file://

O Chrome mantém o acesso a arquivos desativado por extensão. Em chrome://extensions → Pinpoint → Detalhes → "Permitir acesso a URLs de arquivo", depois recarregue.

O ponto da barra de ferramentas nunca fica verde

Ou a ponte não está em execução, ou está em uma porta diferente da extensão: o campo Porta do popup e o --port da ponte devem corresponder. Se node cli.js status disser "a porta responde, mas NÃO é a ponte do pinpoint", outra coisa é dona dessa porta — inicie a ponte com --port 7332 e defina 7332 também no popup.

a porta 7331 já está em uso

Geralmente a ponte já está em execução em outro terminal, caso em que você está pronto. Caso contrário, escolha uma porta livre como acima. Não execute duas pontes ao mesmo tempo: elas compartilham um único arquivo de armazenamento e o último escritor vence.

Uma anotação não tem captura de tela

A imagem é tirada logo após seu comentário ser armazenado, então o comentário nunca é perdido. Se a página navegou ou a aba foi fechada naquele momento, a anotação registra o motivo em vez de anexar uma imagem da página errada. O comentário, seletor e estilos ainda estão todos lá.

Claude Code não menciona minhas notas

Os hooks são lidos quando uma sessão inicia — reinicie uma vez depois de install-hooks. Verifique se <your repo>/.claude/settings.json tem duas entradas contendo print --hook, e se o caminho nelas ainda existe (mover seu clone do Pinpoint quebra isso — execute novamente install-hooks). Você sempre pode simplesmente dizer "aplique minhas anotações do pinpoint".

"Iniciar ponte" diz que uma configuração única é necessária, ou não encontra o Node

Execute node cli.js install-native-host uma vez, depois pressione novamente. Se você já executou, execute novamente — mover o repositório, ou recarregar uma compilação sem o manifesto key, muda o id da extensão, e o Chrome relata um id rejeitado da mesma forma que um lançador ausente. Saia e reabra o navegador depois. O lançador também incorpora um caminho absoluto para o node, porque um processo iniciado pelo navegador não recebe o PATH do seu shell; se o node mudou (uma nova versão do nvm, uma atualização do Homebrew), execute novamente.

Você quer um estado limpo

node cli.js clear esvazia o armazenamento; ~/.pinpoint/annotations.json é o único estado fora do seu repositório.

Uma página para experimentar

demo/index.html é um site de demonstração autônomo — sem compilação, sem rede — com as formas que tornam o Pinpoint útil: uma grade de cartões e níveis de preço para arrastos de região, botões irmãos quase idênticos, um painel de abas que se reconstrói, uma tabela densa e um formulário.

cd demo && python3 -m http.server 8080     # then open http://localhost:8080

Testes

cd test && npm install && npx playwright install chromium && npm test

102 testes. bridge.test.mjs cobre o daemon, CLI, hooks, o caminho de árvore para anotação do seletor iOS e cada ferramenta MCP via stdio e Streamable HTTP; e2e.test.mjs carrega a extensão descompactada no Chromium headless e dirige páginas reais — React, Vue, shadow DOM, um iframe, uma página com CSP estrito, uma página de estresse com 3.600 nós, DPR 2, sincronização entre abas, e um formulário que reconstrói todo o seu DOM. Veja CONTRIBUTING.md para saber para que serve cada suíte.

Segurança e armazenamento

A ponte se liga a 127.0.0.1, recusa qualquer solicitação que carregue um Origin de página da web (a única exceção é a sua própria, para a página /ios que serve, que também se recusa a ser enquadrada), e se identifica com um marcador service; tudo extraído da página é rotulado como não confiável onde alcança seu agente, e apenas seu comentário digitado é apresentado como uma instrução. As capturas de tela vivem codificadas em base64 dentro de ~/.pinpoint/annotations.json em vez de arquivos soltos. SECURITY.md tem as notas completas de limite de confiança, incluindo por que a permissão <all_urls> é necessária, e PRIVACY.md diz exatamente o que é coletado, onde é armazenado e o único lugar onde sai — o agente de codificação ao qual você o conecta.

Roadmap

  • Emulador Android: maestro hierarchy já lê a árvore lá; precisa de adb para a captura de tela.
  • Dicas de fonte nativa: _debugSource do React Native e locais de criação de widgets do Flutter, via um pacote opcional somente para desenvolvimento no aplicativo.
  • Mapeamento de fonte CSS via chrome.debugger (qual conjunto de regras definiu esta cor e onde).
  • Anotações em nível de página — uma nota sobre a página inteira em vez de um elemento ou área.
  • Firefox: o manifesto precisa de um scripts em segundo plano e um gecko.id.
  • Respostas do agente no próprio pin, não apenas no painel de notas.

Contribuindo

Issues e pull requests são bem-vindos — veja CONTRIBUTING.md. Não há etapa de compilação: clone, npm install em bridge/, carregue extension/ descompactado, e você está desenvolvendo. Toda mudança de comportamento deve vir com um teste.

Licença

MIT — consulte LICENSE. As notas de versão estão em CHANGELOG.md.