Dashboard de Análise de Repositórios GitHub que transforma dados em insights poderosos para ensinamentos de Engenharia de Software. Ferramenta educacional desenvolvida pelo ASSERT Lab (UFPE) para apoiar professores e alunos na análise de práticas de desenvolvimento.
- 🔍 Busca Inteligente: Encontre e analise repositórios GitHub usando o formato
owner/repo - 📊 Métricas Completas: Stars, forks, issues, PRs, releases e code churn
- 📈 Gráficos Avançados: Fluxo de trabalho, padrões de commits e stack tecnológica
- ⚡ Health Score: Avaliação rigorosa baseada em 7 critérios comunitários
- 👥 Bus Factor: Análise de risco de dependência de contribuidores com cálculo Pareto 70% e visualização de barra empilhada
- ☢️ Análise de Risco de Equipe (Bus Factor): Card dedicado com número do Bus Factor, avatares dos key developers, classificação de risco (Crítico/Alto/Moderado/Saudável) e barra horizontal empilhada
- 🔄 Dinâmica de Revisão: Lead time e métricas de colaboração
- 🏆 Leaderboard: Ranking dos repositórios mais analisados com histórico de evolução
- 📖 Como interpretar: definição, limitações e referência às métricas CHAOSS de cada indicador
- 🎓 Modo Turma: compare os repositórios das equipes de uma turma no período da disciplina (privados também, com o token de quem usa, sem salvar nada), com exportação CSV
- 🤖 IA no Processo: rastros de IA que o GitHub guarda (configuração de agentes versionada, coautoria declarada em commits, PRs abertos por agentes, revisões de bots de IA), com cruzamento entre as fontes e o selo "Uso responsável de IA"; tudo é limite inferior (sem rastro não quer dizer sem IA)
- 📊 Benchmark Multi-Repo: Compare a evolução de até 10 repositórios lado a lado com gráficos comparativos, filtros temporais (7d, 30d, 60d, 90d, todo histórico) e tabela de métricas detalhada
- 📈 Time Machine (Histórico de Evolução): Visualize a evolução temporal de qualquer repositório através de gráficos interativos com filtros de período (7d, 30d, 60d, 90d, todo histórico). Acompanhe o crescimento de Stars, Forks e Watchers ao longo do tempo com dados baseados em snapshots históricos
- 🔗 Compartilhamento e Histórico: Gere links permanentes (Snapshots) para suas análises. Ideal para avaliações de disciplinas, provas ou code reviews. O link congela o estado do repositório no momento da busca, com data/hora da coleta sempre visível
- 🌍 Suporte Global a Fusos Horários: As buscas por data respeitam automaticamente o fuso horário do navegador do usuário
- 💾 Persistência Automática: O histórico é salvo automaticamente ao carregar a análise, garantindo integridade dos dados
- 🛡️ Sanitização de Dados: Tratamento robusto de payloads JSON para evitar erros com repositórios massivos
- 🌐 Internacionalização Completa: Suporte total PT/EN em todas as interfaces (Ranking, Modais, Navegação)
- 📄 Export PDF/JSON/CSV: Relatórios completos em PDF, dados brutos em JSON e exportação em CSV para análise em planilhas
- ** Monitoramento de Uso**: Rastreamento de acessos e eventos (Buscas, Exports) com Google Analytics 4
- 🛡️ Security-First (RPC Validation): Implementação de RPC segura no Supabase com validação de dados
- 🔒 Apenas Repositórios Públicos: Por design, o Bisolhador não processa nem persiste dados de repositórios privados — mesmo que seu token pessoal tenha acesso a eles — já que os dados analisados podem ser compartilhados publicamente via links permanentes
- 🛡️ Fail-Safe: Tratamento robusto de erros e rate limits
- ♿ Acessibilidade (WCAG AA): Semântica de tabelas, aria-label/aria-hidden em ícones, suporte a leitores de tela
- ⚡ Performance Otimizada: useMemo para gráficos, code splitting e skeleton screens
- ✨ Projetos sem releases são medidos pelas tags (sem pré-versões; datas com token) e "Total de Releases" mostra as tags ao lado
- ✨ Conventional Commits mostra quando a maioria segue outra convenção ("prefixo: resumo", como o kernel Linux)
- 🐛 torvalds/linux e afins voltam a ter histórico: quando a GitHub se recusa a listar os contribuidores (histórico grande demais), o card explica o limite e o snapshot é gravado; nova tentativa também em
5xx - ✨ PRs e issues desativados no GitHub aparecem como "desativados", não como zero ou "Sem PRs mergeados"
- 🐛 Primeira busca de um repositório sem cache da GitHub:
/stats/contributors(202) ganha uma nova tentativa após 3 s antes do fallback parcial que impede salvar o snapshot (valor não medido)
- 🔒
style-src 'self'eimg-srcsemdata:: as exceções vinham dohtml2canvas, já removido; provado pelosmoke:cspem todas as rotas e nos dois PDFs
- 📄 "Baixar Relatório" agora gera um PDF vetorial com a identidade do relatório da turma (resumo, saúde e maturidade, revisão e práticas, pessoas, atividade, IA no Processo, metodologia), no lugar da foto da tela
- 🗑️
html2pdf.jsremovido (ejspdf,html2canvas,dompurify)
- 🤖 PRs e commits do agente do Cursor (
cursor[bot], contacursoragent) passam a contar em "PRs de agentes" e nos commits com rastro de IA
- 📌 "Pontos de atenção" na página de resumo do relatório da turma, escolhidos por regras (sem nota nem ranking)
- 🛟 Erro tratado em vez de tela branca: uma aba aberta antes de um deploy recarrega sozinha uma vez; se não resolver, mostra o erro com botão de recarregar
- 🏅 "3 de 3 (2 não avaliados)" na tabela do Modo Turma, no CSV e no card de IA, em vez de "3 de 3" que parecia nota máxima
- 🧪 Modo Turma: a coluna "CI ok" passa a medir também workflows que rodam só em pull request (antes aparecia como n/d)
- 📝 Relatório PDF: a seção de IA explica por que commits feitos à mão a partir de código de agente não aparecem na contagem
- 🖼️ Logo do Bisolhador no cabeçalho do relatório PDF da turma, no lugar da lupa
- 📄 Relatório PDF da turma: gráficos comparativos por indicador (com a mediana da turma), explicação de cada indicador tirada do guia, leitura por regras, seção de IA no Processo e metodologia, em PDF vetorial com a identidade visual do Compasso
- 🕶️ Anonimização opcional dos repositórios no PDF; nada por estudante vai para o arquivo
- 🔒 CSP:
'wasm-unsafe-eval'edata:para o layout do gerador de PDF (WebAssembly embutido)
- ⚡ Primeiro acesso mais leve (chunk de entrada ~443 KB → ~355 KB, ~141 → ~115 KB gzip): os textos de Como interpretar e do Guia de IA no Processo só são baixados ao abrir essas páginas, e só no idioma ativo
- 🔗 Links em nova aba no Modo Turma: os links dos resultados (Como interpretar, card IA no Processo, visão Por estudante, repositórios) abrem em outra aba, para não perder a análise da turma, que fica só na memória
- 📱 Linha expandida no celular: o detalhe de IA no Processo cabe na tela, sem corte à direita e sem rolagem horizontal da página
- 🧭 Guia de IA no Processo (
/guia/ia): princípios (limite inferior, o que a seção não é, ética dos dados), como declarar a coautoria de IA nos commits (trailer manual e, por ferramenta, o que a documentação oficial confirma), a tabela do que o Bisolhador detecta gerada do próprio registro de ferramentas, orientações para professores no Modo Turma, perguntas frequentes e os limites consolidados. Links a partir de Como interpretar, do card IA no Processo e da visão Por estudante
- 🧪 Testes e CI no selo do Modo Turma: o critério passa a ser medido pelas listagens da raiz e de
.github/workflowse pelas execuções do GitHub Actions no período, sem requisições novas. Testes só aparecem como encontrados ou não verificados, nunca como ausentes - 📊 n no CSV da turma: cada porcentagem vem com o número de commits, PRs ou execuções sobre o qual foi calculada
- 🤖 IA no Processo (Dashboard): ferramentas de IA detectadas, profundidade da configuração versionada, % de commits com coautoria de IA, PRs abertos por agentes e, com token, revisões por bots de IA e salvaguardas (PRs de agentes mergeados sem aprovação, tamanho dos PRs de agentes vs. pessoas). Tudo é limite inferior: sem rastro aparece "Nenhum rastro de IA encontrado", nunca "0% IA"
- 🔀 Fontes em desacordo: quando a configuração versionada fora do template (ou o
.gitignore) mostra IA e nenhum commit nem PR de agente declara uso, o repositório recebe um aviso neutro, sempre com as causas legítimas - 🏅 Selo "Uso responsável de IA": práticas observáveis (configuração versionada, uso declarado, coerência entre fontes, PRs de agentes aprovados por outra pessoa, testes e CI), só por repositório e fora do Ranking
- 🎓 IA no Modo Turma: colunas de IA por repositório e, ao expandir a linha, uma visão por estudante que fica só no navegador (fora do CSV, do Supabase e do GA)
- 📖 Como interpretar: uma entrada para cada indicador de IA
- 🔒 Repositórios privados no Modo Turma: turmas do GitHub Classroom (privadas por padrão) podem ser analisadas com o token de quem usa — nada é salvo, e o Google Analytics fica desligado no Modo Turma. O resto do app continua recusando privados
- 🏫 Importar de uma organização: informe a organização e um prefixo para preencher a lista da turma
- 📱 Cabeçalho no celular: menu compacto, sem a página rolar para o lado
- 🔒 Privacidade no Google Analytics: os envios do app passam a conter só o caminho da página, sem os parâmetros da URL
- 🎓 Modo Turma (
/turma): compare os repositórios públicos das equipes de uma turma no período da disciplina — commits, autores, concentração (sem identificar pessoas), revisão de PRs, CI, Conventional Commits e releases — com exportação CSV; nada é salvo - 📖 Como interpretar (
/guia): para cada indicador, o que mede, como ler, limitações e a métrica CHAOSS correspondente, com as diferenças declaradas
- 🔍 Revisão de código (com token): cobertura de revisão, tempo até a 1ª revisão (a partir de quando o PR fica pronto, não do rascunho) e tamanho dos PRs
- ⚙️ Práticas do Projeto (sem token): saúde do CI (builds de push no branch principal), adesão a Conventional Commits e cadência de releases nos últimos 12 meses
- 📅 Dias da semana: todo o histórico de commits (estatística do GitHub, até 20 mil commits), no horário de quem fez cada commit — antes eram só os 10 mais recentes
- 📈 Commits por semana: título com as semanas exibidas e "calculando" quando o GitHub ainda não tem o dado, em vez de uma linha zerada
- ➕➖ Adições/Remoções (antes "Code Churn"): rótulos descritivos, sem prometer qualidade, com atividade mínima
- ✅ "% fechadas" traduzida e com o que ela inclui explicado
- 📊 Benchmark: compara só o que é comparável — data dos dados em cada repositório (com aviso quando são de datas muito diferentes), N/A em vez de 0, valores de métodos antigos como "não registrado", um ponto por dia, cores válidas
- 📈 Timeline: eixo de tempo real, um ponto por dia, sem zeros falsos, crescimento com sinal e histórico de repositórios renomeados (facebook/react + react/react)
- 🏅 Ranking "Mais Analisados": conta dias distintos com análise, não recarregamentos; sem medalhas nem "Hall of Fame"
- 🐛 Formato local: com o navegador em português do Brasil, datas e números apareciam no formato americano (12/18/2025, 241,721); agora seguem o idioma escolhido (18/12/2025, 241.721)
- ⏱️ Lead time real: mediana (com p90 e tamanho da amostra) dos últimos PRs mergeados, sem bots — antes era a média dos 20 PRs mais recentes criados, quase todos ainda abertos (react e express: N/A)
- 🛡️ Code Review = "mergeado sem aprovação": o badge mede PRs mergeados sem aprovação de outra pessoa, não mais a taxa de self-merge (no react: 54% self-merge, 0% sem aprovação); Divergência sem comentários de bots
- 🧪 Maturidade de Engenharia: testes, CI, Docker e linter detectados em configurações comuns (express, GitLab CI, Dockerfiles em subpastas, monorepos), com ✓ encontrado · ✗ não encontrado · ? não verificado
- ❤️ Health Score: reconhece os formulários de issue (
.github/ISSUE_TEMPLATE/) — react 86% → 100%, igual ao GitHub; forks calculados a partir dos arquivos - 🌿 Branches: total exato e zumbis sobre todas as branches, sem contar a principal, as protegidas e as de release
- 🔗 Permalink por data (
?repo=&date=) voltou a funcionar: mostra o registro mais recente até aquele dia
- 👥 Contribuidores e Bus Factor corrigidos: todos os principais contribuidores (antes só os 30 primeiros), sem bots, nos últimos 12 meses quando há atividade — no express, o "risco crítico" deixou de apontar um mantenedor inativo desde 2014; card e tabela usam a mesma base e os mesmos limites do Benchmark
- 🧭 Termos claros: a tabela mostra a concentração no principal contribuidor (não mais "Bus Factor Baixo" como estado saudável), com a janela de tempo e os bots excluídos explícitos
- ⚡ Primeiro acesso ~2,6× mais leve (~1,56 MB → ~592 KB de JavaScript): o gerador de PDF só é baixado ao exportar
- 🔧 Vite 8
- 🐛 N/A em vez de 0: quando o GitHub não responde (limite de requisições, erro), issues, PRs, merges, branches e Health Score aparecem como N/A, com aviso de dados parciais, em vez de um 0 falso — e esse resultado parcial não é gravado no histórico
- 🐛 Repositórios renomeados:
facebook/react(hojereact/react) mostrava 0 issues; agora usa o nome atual - 🐛 Forks: Health Score aparece como N/A com explicação, em vez de ~14%
- 🌐 https://bisolhador.assertlab.com: o endereço antigo (
assertlab.com/bisolhador/) redireciona automaticamente, inclusive permalinks ⚠️ Reconfigure o token do GitHub no novo endereço (o navegador guarda configurações por domínio)- 🐛 Links diretos: abrir ou recarregar
/ranking,/benchmarke/timeline/...direto no navegador não dá mais 404
- 🐛 Code Churn: deixou de mostrar
Infinity/ "Acúmulo Intenso" para quase todo repositório ativo (a API do GitHub devolve as deleções com sinal negativo) - 🐛 Code Review e Divergência reais: a taxa de self-merge e a média de comentários por PR agora são medidas de verdade (GraphQL, com token do GitHub); sem token aparecem como "n/d" com a explicação, em vez de um 0% falso
- 🧪 Testes Unitários: primeira suíte (Vitest) rodando no CI — foi ela que revelou os três bugs acima
- 🐛 Snapshot vs. Busca ao Vivo: voltar (Back) de uma busca para um permalink de snapshot não mostra mais os dados da busca por baixo do banner de snapshot — a URL decide o que é exibido
- 🐛 Erro em Snapshot Inexistente: link de snapshot inválido ou sem registro agora mostra uma mensagem de erro, em vez de uma página vazia
- 🔧 Dependências: Supabase, React 19.3, TanStack Query, react-router e react-ga4 3 atualizados; ESLint 10
- 🐛 Pixel do GA4 Liberado na CSP:
img-srcpassou a liberar os hosts de coleta do GA4 (*.google-analytics.com,www.googletagmanager.com), evitando a violação de CSP que bloqueava os hits via<img>do gtag.js
- 🔒 Correção de RPCs (Supabase Security Advisor):
get_leaderboardganhou teto de 100 nolimit_count, protegido contraNULLexplícito (COALESCE+LEAST/GREATEST);registrar_buscapassou a validar o tamanho defull_reportpelo tamanho lógico do JSON (octet_length) em vez do tamanho comprimido em disco (pg_column_size, contornável por payloads muito compressíveis), além de validarrepo_name
- 🔔 Notificações Não-Bloqueantes: Todas as chamadas de
alert()bloqueante (compartilhamento, exportação de PDF, validações do Benchmark, rejeição de repositório privado) foram substituídas por um sistema de toast — erros permanecem visíveis até fechamento manual, sucesso/aviso somem sozinhos
- 🐛 Fix de Crash no Timeline: Corrige crash real ao abrir um permalink de Timeline como primeira página da sessão, causado por
chart.jsnão estar garantidamente registrado antes do gráfico montar - ⚡ Prefetch de Chart.js:
chart.jsagora é carregado em paralelo com o início de cada busca e cada adição de repo no Benchmark, reduzindo o lag da primeira renderização de gráfico
- 🔒 Auditoria de Segurança Completa: RLS do Supabase corrigida (bloqueava só na documentação, não na prática), bloqueio de processamento/persistência de repositórios privados e primeira Content-Security-Policy do projeto
- 🔄 react-router-dom Atualizado: Corrige open redirect via backslash, com validação defensiva de rota adicional em
RepoInfoCard - 🐛 Fix de Sincronização de URL:
useSearchParamssubstituiwindow.history.pushStatebruto no Dashboard, corrigindo resíduo de busca anterior ao navegar para Home/Buscar depois de uma pesquisa
- ☢️ Bus Factor Avançado (Pareto 70%): Motor matemático que calcula o número mínimo de devs responsáveis por 70% dos commits, com classificação em 4 níveis de risco
- ☢️ BusFactorCard: Novo componente visual com número central, avatares dos key developers, barra horizontal empilhada em Tailwind e legenda colorida
- 🌐 i18n: Chaves de tradução completas para Bus Factor (PT-BR/EN-US)
- 📊 Exportação Avançada (CSV): Motor nativo de exportação CSV (sem libs externas) com UTF-8 BOM para compatibilidade com Excel
- 📊 CSV no Dashboard: Exporta 13 métricas do repositório (Stars, Forks, Issues, Health Score, Lead Time, Code Churn, Divergência, etc.)
- 📊 CSV no Benchmark: Botão "Exportar CSV" na Tabela Comparativa com colunas idênticas à tabela visual
- 🛡️ Exponential Backoff: Retentativas automáticas com backoff exponencial para envios de analytics ao Supabase, garantindo resiliência a oscilações de rede
- 🛡️ PartialDataAlert: Tratamento de falhas parciais da API do GitHub — o painel renderiza os dados disponíveis e exibe um banner amigável detalhando os dados ausentes
- 🐛 Dynamic Version: Header agora exibe a versão dinamicamente do
package.json(sem strings hardcoded)
- ⚡ Performance:
useMemoem todos os charts (evita re-criação do canvas Chart.js a cada render) - 🏗️ Clean Architecture: Dashboard e Benchmark componentizados, lógica temporal unificada em
useTimeFilter - 🛡️ Segurança: Proteção XSS (
dangerouslySetInnerHTMLsubstituído porTrans), localStorage com wrapper seguro - 🌐 i18n Total: Todas as strings hardcoded migradas para react-i18next
- 🧹 Código Limpo: Constantes extraídas para
src/constants.js, dead code removido
- 📊 Benchmark Multi-Repo: Nova página
/benchmarkpara comparação simultânea de até 10 repositórios com gráficos de evolução temporal e tabela comparativa - ⏱️ Filtros Temporais Unificados: Sistema de filtros (7d, 30d, 60d, 90d, todo histórico) no Benchmark e na Timeline, normalizando visualizações para repositórios com datas de início diferentes
- 📈 Gráficos de Comparação: Evolution charts (Chart.js time-series) e comparison bar charts por categoria (Popularidade, Velocidade, Qualidade)
- 🔒 Security: Atualização crítica de dependências (html2pdf.js, jspdf) para mitigar vulnerabilidades CVE
- ⏱️ Filtros Temporais: Controles de período (7d, 30d, 90d, todo histórico) na Timeline para análise focada
- 📈 Visualização Temporal: Nova página Timeline para visualizar evolução histórica de repositórios através de gráficos interativos
- 📊 Gráficos de Evolução: Line charts mostrando crescimento de Stars, Forks e Watchers ao longo do tempo
- 🔧 Backend RPC: Nova função Supabase
get_repo_historypara buscar snapshots históricos - 🎨 UI/UX: Botão "Ver Evolução" no card do repositório com cards de resumo (primeira análise, última análise, crescimento total)
- 🌐 i18n Completa: Todas as strings traduzidas em PT-BR e EN-US
- 🎨 UI/UX Polished: Correções de navegação global, modal states unificado entre todas as telas
- 🌐 Internacionalização Completa: Suporte total PT/EN em Ranking, Modais (Ajuda/Configurações) e navegação
- 🔧 Header State Management: Botões de configurações e idioma funcionam consistentemente em Dashboard e Ranking
- ♿ Acessibilidade Aprimorada: Labels e aria-atributos completos para leitores de tela
- 🌍 Suporte Global a Fusos Horários: Detecção automática do timezone do navegador para snapshots diários
- 💾 Persistência Inteligente (Save-on-Load): Histórico salvo automaticamente ao carregar análise
- 🛡️ Sanitização de Dados: Tratamento robusto de JSON payloads para repositórios massivos
- 📊 Analytics Aprimorado: RPC segura com validação de dados no Supabase
- Node.js 24 (ver
.nvmrc; mínimo suportado emenginesnopackage.json: 22.12+) - npm ou yarn
# Clone o repositório
git clone https://github.com/assertlab/bisolhador.git
cd bisolhador
# Instale as dependências
npm install
# Execute em modo desenvolvimento
npm run dev
# Ou faça o build para produção
npm run buildNota: Crie um arquivo .env na raiz com as seguintes variáveis para habilitar o Analytics:
VITE_GA_ID=G-SEU-ID
VITE_SUPABASE_URL=https://seu-projeto.supabase.co
VITE_SUPABASE_ANON_KEY=sua-chave-anonimaA aplicação estará disponível em http://localhost:5173
Busca Direta por URL:
https://bisolhador.assertlab.com/?q=facebook/react
Acesso a Snapshot Histórico (Permalink):
https://bisolhador.assertlab.com/?id=123
Busca Semântica Histórica (por Data):
https://bisolhador.assertlab.com/?repo=facebook/react&date=2025-12-18
Mostra o registro mais recente até o fim desse dia (fuso de Recife); o aviso no topo informa quando ele foi registrado.
- Busque um repositório usando o formato
owner/repo(ex:facebook/react) - Analise as métricas de saúde, maturidade e padrões de trabalho
- Compartilhe resultados clicando no botão "Compartilhar" para gerar links permanentes (O Bisolhador salva automaticamente o histórico da sua análise)
- Acesse dados históricos usando URLs semânticas com datas específicas
- Exporte relatórios em PDF, dados brutos em JSON ou métricas em CSV
- Frontend: React 18 + Vite
- Styling: Tailwind CSS
- Charts: Chart.js + react-chartjs-2
- Database: Supabase (@supabase/supabase-js)
- API: GitHub REST API v3
- Analytics: Google Analytics 4 (react-ga4)
- Build: Vite
- Deploy: GitHub Pages
Nota técnica (v3.4.0): A codebase passou por uma refatoração completa em 5 sprints focando em performance otimizada (
useMemoem charts), Clean Architecture (componentização de Dashboard e Benchmark), segurança (proteção XSS, safe localStorage) e eliminação de código duplicado (hooks unificados, constantes extraídas).
Para detalhes técnicos, arquitetura e desenvolvimento:
- AGENTS.md - Contexto técnico do projeto (arquitetura, segurança, decisões)
- Design System - Sistema de design e padrões visuais
- Histórico de Mudanças (Changelog) - Todas as versões e alterações
- Roadmap - Planejamento futuro e histórico de releases
npm run dev- Inicia servidor de desenvolvimentonpm run build- Gera build de produçãonpm run preview- Visualiza build localnpm run lint- Executa ESLint
O Bisolhador foi desenvolvido especificamente para:
- Análise de Projetos Open Source: Avaliar saúde e maturidade de repositórios
- Ensino de Engenharia de Software: Demonstrar boas práticas e identificar problemas
- Pesquisa: Coletar métricas quantitativas sobre desenvolvimento colaborativo
- Mentoria Técnica: Apoiar decisões sobre processos e governança
Contribuições são bem-vindas! Siga estes passos:
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - Push para a branch (
git push origin feature/AmazingFeature) - Abra um Pull Request
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
- ASSERT Lab - Advanced System and Software Engineering Research Technologies Lab do CIN/UFPE
- Comunidade Open Source - Por inspirar e possibilitar esta ferramenta
- Educadores e Desenvolvedores - Por usar e contribuir com feedback
Powered by ASSERT Lab 🦈 | Orgulhosamente feito em Recife