npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fidera/collector

v0.2.0

Published

O coletor forge-native: lê `git` e a forja **na borda do adotante** e empurra os primitivos crus para o Fidera. Zero dependência de runtime — roda via `npx` no CI do adotante.

Downloads

257

Readme

@fidera/collector

O coletor forge-native: lê git e a forja na borda do adotante e empurra os primitivos crus para o Fidera. Zero dependência de runtime — roda via npx no CI do adotante.

Quickstart

O escopo @fidera no npm é da organização fidera (reivindicado em 19/08/2026 pelo governador — antes disso o 404 deixava qualquer terceiro publicá-lo e ser executado no runner do adotante, com o GITHUB_TOKEN dele em mãos; a razão da versão exata abaixo é a mesma).

permissions:
  contents: read # o checkout, e o `git log`/`git diff` locais
  actions: read # `/actions/runs` — o eixo de CI
  pull-requests: read # `/commits/{sha}/pulls` e os comentários do portão

steps:
  - uses: actions/checkout@v4
    with:
      fetch-depth: 200 # 0 apenas para `--mode all`; ver "Modos"
  - run: npx --yes @fidera/[email protected] --mode tail --fidera-url https://api.fidera.app --tenant SEU-SLUG
    env:
      GITHUB_TOKEN: ${{ github.token }}
      FIDERA_INGEST_TOKEN: ${{ secrets.FIDERA_INGEST_TOKEN }}

⚠️ O bloco permissions: não é opcional. Com o default restrito de GITHUB_TOKEN — o padrão de organizações novas — o token recebe contents: read e nada mais, e aí /actions/runs, /commits/{sha}/pulls e /issues/{n}/comments devolvem 403. Esse 403 não traz x-ratelimit-remaining: 0, então não é limite de taxa: é permissão. O coletor passou a dizer isso na mensagem de erro, mas evitar o erro é melhor do que diagnosticá-lo.

⚠️ A versão é exata, e não é preciosismo. Um range (@1, @latest) resolve no runner do adotante, num processo que ninguém está olhando, com o GITHUB_TOKEN do repositório em mãos. Versão exata é o que faz o adotante decidir quando o código que ele executa muda. A guarda fitness/quickstart-versao-exata.test.ts recusa range e exige que este número seja o do package.json.

--yes é da mesma família: sem ele, npx num pacote ainda não baixado abre um prompt, e num runner sem tty isso é um step pendurado até o timeout — com um diagnóstico que não aponta para cá.

Modos

| --mode | o que faz | fetch-depth | |---|---|---| | tail (padrão) | re-observa a cauda de merges. É a corrida diária. | 200 | | all | backfill: todos os merges, mais a varredura de drift na forja. | 0 | | drift | só a observação de drift deste run, lida do workspace. Zero git, zero forja. | 200 |

A cauda é re-observada de propósito: re-run de CI e edição do comentário do portão acontecem depois de o merge assentar, e o servidor faz upsert por (tenant, mergeSha, collectorVersion).

--mode drift devolve merges: [] por desenho — uma corrida de PR não pode reportar como fato o que ainda não foi integrado.

Contrato de entrada

| flag | obrigatória | padrão | |---|---|---| | --fidera-url | sim | — | | --tenant | sim | — | | --mode | não | tail | | --main | não | main | | --tail-k | não | 5 | | --lookback-days | não | 90 | | --repo-root | não | . | | --observacao | não | build/maturity/drift-observacao.json | | --dry-run | não | false |

| variável | para quê | |---|---| | FIDERA_INGEST_TOKEN | obrigatória — autoriza o POST. Tenant-scoped, escopo de ingestão. | | GITHUB_TOKEN | leitura da forja. github.token basta. | | GITHUB_REPOSITORY | obrigatória — o runner já a publica. |

Tudo isso é validado na entrada, antes de qualquer I/O: um --tenant esquecido falha em milissegundos, e não depois de gastar o orçamento de requisições da forja.

Canais

  • stdout — com --dry-run, o envelope collector-v1, um documento JSON parseável. É contrato.
  • stderr — o resumo do run real (lotes e contagem por status, emitido mesmo no sucesso), além de avisos, perdas contadas e recusas do servidor. stderr não-vazio não indica falha; o sinal de falha é o código de saída.

Nenhum canal ecoa o FIDERA_INGEST_TOKEN: o log de um run é público em repositório aberto.

O que "sucesso" significa aqui

O código de saída é 0 só quando o POST foi aceito e o relatório por item não trouxe invalid. Um 200 cujo corpo diz que todas as observações foram recusadas — tenant divergente do token é o caso real — não é sucesso, e sai 1.

Quando nada pôde ser lido, o resumo sai como não verificado, nunca como zero: "não li" não pode ser confundido com "zero inválidos". A completude é medida por item — um relatório com menos itens do que o lote enviado não passa por completo, senão o run afirmaria {"invalid":0} sobre observações de que nada sabe.

Numa carga multi-lote a leitura pode ser parcial: um lote responde relatório legível, outro não. O que foi apurado é piso confirmado, não estimativa — uma recusa contada num lote sai 1 mesmo que o relatório de outro lote nunca tenha chegado, e o resumo sai como ao menos {…} (relatório incompleto). O que falta é o total, nunca o piso. O contrário — absolver o run porque um lote veio ilegível — era o furo da issue #47.

Segue daí uma assimetria que vale conhecer: com uma carga toda inválida, o run sai 1 se a recusa cair num lote lido, e 0 se o único lote lido não a contiver. O piso é honesto sobre o que mediu; ele não adivinha o que não leu.

Não ler o relatório, sozinho, não é motivo de falha: o POST foi aceito, a retomada cobre o resto e o run sai 0. O sinal de falha é a recusa, não a ignorância.

Se o próprio POST falha, o push é interrompido — e o que já assentou não morre com o erro. Os dois modos de morte do transporte estão cobertos: o status de erro (5xx, limite) e a rede caindo (ECONNRESET, DNS, timeout do runner), que é o caso mais comum. O run sai 1 e relata os lotes concluídos, o piso apurado e as recusas que já conhecia — e quando nada foi apurado diz não verificado, nunca ao menos zero, pela mesma razão de sempre: zero é uma afirmação.

(push interrompido) distingue esse caso do (relatório incompleto), que é o push que terminou sem conseguir ler tudo. Re-rodar é seguro: a ingestão é idempotente e o GET :estado retoma do último assentado.

Perdas

Toda perda é contada e sai por stderr — linha de merge não parseada, range sem commits, commit não parseado. Um corpus com buraco não pode ser indistinguível de um corpus completo.