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

checklist-qa

v0.6.1

Published

Conversational QA checklist interview engine, independent of any LLM provider.

Readme

checklist-qa

Transforma uma entrevista de QA (conduzida por qualquer LLM) numa experiência conversacional interativa, e entrega ao final um arquivo checklistQA.md pronto para uso.

O pacote não sabe nada sobre QA — todas as perguntas, regras de negócio e formato do checklist vivem inteiramente no prompt de entrevista (prompts/checklist-interview.md). O pacote apenas orquestra a conversa: envia o histórico ao seu provider de IA, guarda as respostas, detecta o fim da entrevista e disponibiliza o markdown resultante.

  • Independente de modelo de IA: funciona com OpenAI, Anthropic, Gemini, Ollama, Azure OpenAI, DeepSeek ou qualquer outro, através de uma única interface (LLMProvider).
  • TypeScript com tipagem completa, ESM + CommonJS, Node 20+.
  • Zero perguntas hardcoded no código — tudo vem do prompt.

Instalação

npm install checklist-qa

CLI

O pacote inclui um CLI mínimo que roda a entrevista direto no terminal, usando o prompt embutido no pacote — útil para testar sem escrever código:

npx checklist-qa --provider anthropic

| Flag | Descrição | | --- | --- | | --provider <nome> | openai, anthropic ou ollama. Se omitido, é detectado a partir de ANTHROPIC_API_KEY > OPENAI_API_KEY_CHECKLIST > Ollama local. | | --model <nome> | Nome do modelo (padrão depende do provider). | | --prompt <arquivo> | Prompt de entrevista customizado (padrão: prompts/checklist-interview.md do pacote). | | --output-dir <dir> | Diretório onde checklistQA.md será gravado (padrão: diretório atual). | | --context-dir <dir> | Diretório onde procurar a pasta .diffai/ para usar como contexto adicional da entrevista (padrão: diretório atual). | | --no-extension-guess | Desliga a heurística de classificar arquivos como Backend/Frontend pela extensão (.js = Backend, .ts = Frontend) quando não há indicação explícita no contexto. Use em projetos onde essa convenção não vale (ex.: backend em TypeScript). Ativa por padrão quando a flag é omitida. | | -h, --help | Mostra a ajuda. |

Antes de iniciar a entrevista, o CLI consulta o npm para checar se a versão instalada é a mais recente publicada de checklist-qa e bloqueia a execução (com instruções de atualização) se não for. Se a consulta ao registro falhar (ex.: sem internet), o CLI apenas avisa e segue com a versão instalada, em vez de travar.

Contexto adicional (.diffai/)

Se o diretório de contexto (padrão: onde o CLI é executado, ou o valor de --context-dir) contiver uma pasta .diffai/, o CLI lê todos os arquivos dessa pasta recursivamente e anexa o conteúdo ao prompt de entrevista antes de iniciar a conversa. A IA analisa esse contexto antes de perguntar qualquer coisa e gera as perguntas dinamicamente a partir dele. docs/ (ex.: docs/analysis.md) não é lida: é apenas uma renderização em prosa do mesmo conteúdo de .diffai/analysis.json, então incluí-la também só duplicaria informação no prompt sem agregar nada novo.

Cada pergunta é apresentada já com uma resposta sugerida, pré-preenchida a partir do contexto e editável: no CLI, a sugestão abre no seu editor de texto ($VISUAL/$EDITOR, ou Notepad no Windows / nano nos demais), onde o desenvolvedor edita à vontade em várias linhas, salva e fecha para enviar. Quando o contexto não permite sugerir nada com segurança, o editor abre em branco. Se o contexto identificar mais de uma funcionalidade, elas são enumeradas (Funcionalidade 1, 2, ...) e tratadas separadamente na entrevista e no checklist. Ao final, o checklistQA.md combina o contexto (.diffai/) com as respostas confirmadas, destacando as mudanças importantes no sistema e os pontos de atenção.

Em entradas não interativas (stdin via pipe), o CLI faz fallback para uma leitura de linha única, sem abrir editor.

Se a pasta não existir, o comportamento é idêntico ao anterior: a entrevista é conduzida sem contexto extra, e nenhuma resposta é pré-preenchida.

Para usar essa mesma lógica fora do CLI, a classe ContextLoader está disponível publicamente:

import { ContextLoader } from "checklist-qa";

const context = await ContextLoader.loadFromDirectories(["./.diffai"]);

Classificação Backend/Frontend gerada por código

Antes, a IA precisava interpretar sozinha os arquivos .diffai/analysis.*.json para decidir quais testes eram de backend e quais de frontend — e frequentemente errava, misturando os dois lados. Agora o CLI faz essa separação por código, de forma determinística, com a classe DiffaiClassifier: ele lê os arquivos analysis.backend-*.json e analysis.frontend-*.json, usa o lado declarado no nome de cada análise como autoridade (conferindo com o caminho de cada arquivo) e anexa ao prompt um bloco "Classificação Backend/Frontend determinada por código (AUTORITATIVA)" com as listas prontas de testes e arquivos de cada lado. A IA é instruída a copiar essa classificação exatamente como está — em vez de reinferi-la — e a não inventar arquivos que não constem do contexto. Nomes de teste "nus" (sem caminho), como transactionModel.test.js ou new-sale.component.spec.ts, também são classificados corretamente porque o lado vem do nome da análise de origem.

A flag --no-extension-guess também vale aqui: com ela, arquivos que não tenham lado determinável pelo nome da análise nem pelo caminho ficam marcados como indeterminado em vez de serem chutados pela extensão. Para usar a classificação fora do CLI:

import { DiffaiClassifier } from "checklist-qa";

const classification = await DiffaiClassifier.classifyDirectory("./.diffai");
const block = DiffaiClassifier.buildContextBlock(classification);

Variáveis de ambiente usadas pelos providers embutidos: ANTHROPIC_API_KEY, OPENAI_API_KEY_CHECKLIST e OLLAMA_BASE_URL (opcional, padrão http://localhost:11434). São os mesmos providers mínimos descritos em examples/providers — o CLI é só um ponto de entrada de terminal para o mesmo ChecklistQA. Use VISUAL ou EDITOR para escolher o editor em que as respostas são editadas (padrão: Notepad no Windows, nano nos demais).

O CLI carrega automaticamente um arquivo .env do diretório onde for executado (não do diretório do pacote), sem sobrescrever variáveis já exportadas no shell.

Uso rápido

import { ChecklistQA, PromptLoader } from "checklist-qa";
import { myProvider } from "./my-provider.js";

const prompt = await PromptLoader.loadFromFile("./node_modules/checklist-qa/prompts/checklist-interview.md");

const qa = new ChecklistQA({
  provider: myProvider,
  prompt,
});

let question = await qa.start();

while (!qa.isFinished()) {
  console.log(question);
  // Resposta sugerida a partir do contexto (.diffai): apresente-a já preenchida e editável.
  const answer = await getAnswerFromUser(qa.suggestedAnswer()); // sua UI, CLI, etc.
  question = await qa.answer(answer);
}

console.log(qa.getMarkdown()); // conteúdo final do checklistQA.md
await qa.download(); // grava checklistQA.md em disco (Node) ou dispara o download (browser)

Você também pode copiar prompts/checklist-interview.md para o seu próprio projeto e ajustá-lo, desde que mantenha o marcador <QA_CHECKLIST_READY> (veja Como funciona a entrevista).

Configuração

interface ChecklistQAOptions {
  provider: LLMProvider;       // obrigatório — seu adaptador de IA
  prompt: string;              // obrigatório — texto do prompt de entrevista
  outputFileName?: string;     // padrão: "checklistQA.md"
  autoDownload?: boolean;      // padrão: false — baixa/gera o arquivo automaticamente ao concluir
  marker?: string;             // padrão: "<QA_CHECKLIST_READY>"
  suggestionMarker?: string;   // padrão: "<RESPOSTA_SUGERIDA>" — separa a pergunta da resposta pré-preenchida
  progressMarker?: string;     // padrão: "<PROGRESSO>" — precede a estimativa "pergunta atual/total"
  sessionId?: string;          // padrão: gerado automaticamente (crypto.randomUUID)
}

API

| Método | Descrição | | --- | --- | | qa.start() | Envia o prompt ao provider e retorna a primeira pergunta. | | qa.answer(texto) | Envia a resposta do usuário e retorna a próxima pergunta ("" quando a entrevista termina). | | qa.question() | Última pergunta feita pela IA. | | qa.suggestedAnswer() | Resposta sugerida (pré-preenchida a partir do contexto) para a última pergunta ("" quando não há). | | qa.progress() | { current, total } autorreportado pela IA para a última pergunta (undefined quando não informado). total é uma estimativa que pode mudar entre perguntas. | | qa.isFinished() | true quando o marcador de conclusão foi detectado. | | qa.getMarkdown() | Conteúdo do checklistQA.md (undefined até a entrevista terminar). | | qa.getHistory() | Histórico completo da conversa (nunca perde mensagens). | | qa.download(outputDir?) | Grava o arquivo em disco (Node) ou dispara o download (browser). |

Criando um Provider

A única coisa que o pacote exige de um provider é:

interface LLMProvider {
  chat(messages: Message[]): Promise<Message>;
}

type Role = "system" | "user" | "assistant";
interface Message {
  role: Role;
  content: string;
}

Toda vez que uma pergunta precisa ser feita, o InterviewEngine chama provider.chat(historicoCompleto) e espera de volta uma única mensagem assistant. Você decide como essa chamada conversa com a IA por trás.

Exemplos completos ficam em examples/providers: OpenAI, Anthropic e Ollama. Um provider mínimo para qualquer serviço com API compatível:

import type { LLMProvider, Message } from "checklist-qa";

export class MyProvider implements LLMProvider {
  async chat(messages: Message[]): Promise<Message> {
    const content = await callMyLLM(messages);
    return { role: "assistant", content };
  }
}

Como funciona a entrevista

  1. qa.start() envia o prompt de entrevista (mensagem system) para o LLMProvider e recebe a primeira pergunta.

  2. A cada qa.answer(resposta), a resposta do usuário é adicionada ao histórico e o histórico completo é reenviado ao provider — o pacote nunca trunca ou reescreve mensagens anteriores.

  3. O pacote nunca mostra mais de uma pergunta por vez — isso é responsabilidade do prompt, que já instrui a IA a perguntar um item por mensagem.

  4. Cada pergunta pode vir acompanhada de uma resposta sugerida (derivada do contexto), separada da pergunta pelo marcador <RESPOSTA_SUGERIDA>. O InterviewEngine separa a pergunta (antes do marcador) da sugestão (depois dele) e expõe a sugestão via qa.suggestedAnswer() — apresente-a já preenchida e editável na sua UI. Se a pergunta não tiver marcador, qa.suggestedAnswer() retorna "". 4b. Cada pergunta também pode vir com uma estimativa de progresso, no formato <PROGRESSO>\npergunta_atual/total_estimado. Como a entrevista é dinâmica (sem lista fixa de perguntas), o total é a própria IA quem estima e pode revisar a cada pergunta. O InterviewEngine expõe isso via qa.progress() (undefined quando a pergunta não trouxe a estimativa).

  5. Quando a IA decide que a entrevista terminou, ela responde exatamente com o marcador:

    <QA_CHECKLIST_READY>

    seguido, na mesma mensagem, do conteúdo completo do checklistQA.md em Markdown.

  6. O InterviewEngine detecta o marcador, separa qualquer texto antes dele (última "pergunta", normalmente vazia) do conteúdo após ele (o Markdown), marca a sessão como finalizada e armazena o Markdown.

  7. A partir daí, qa.isFinished() retorna true e qa.getMarkdown() / qa.download() ficam disponíveis.

Use as opções marker, suggestionMarker e progressMarker em ChecklistQAOptions caso seu prompt use marcadores diferentes.

Geração e download do Markdown

  • qa.getMarkdown() retorna a string do Markdown assim que a entrevista termina.
  • qa.download(outputDir?):
    • Node: grava checklistQA.md (ou o outputFileName configurado) em disco via fs/promises, opcionalmente dentro de outputDir, e retorna o caminho gravado.
    • Browser: cria um Blob e dispara o download pelo navegador (sem depender de nenhum framework).
  • Configure autoDownload: true para que o download aconteça automaticamente assim que qa.isFinished() se tornar true, sem precisar chamar qa.download() manualmente.

FAQ

Preciso reescrever as perguntas da entrevista no código? Não. Todas as perguntas, regras e o formato do checklist final vivem em prompts/checklist-interview.md. O pacote só orquestra o fluxo.

Posso usar qualquer LLM? Sim. Implemente LLMProvider (um único método, chat) para o serviço que preferir. O pacote nunca importa um SDK de IA específico.

O que acontece se a IA esquecer o marcador <QA_CHECKLIST_READY>? A entrevista nunca é marcada como concluída e qa.getMarkdown()/qa.download() continuam indisponíveis — ajuste o prompt ou o marker configurado se isso acontecer com frequência.

Funciona em CommonJS? Sim, o pacote publica builds ESM e CommonJS com tipos para ambos.

Como troco de provider no meio do desenvolvimento? Basta passar uma instância diferente em provider ao criar o ChecklistQA — nada mais no pacote precisa mudar.