Roda os testes certos, no instante em que você salva o arquivo — e explica por que rodou.
Ferramenta de desenvolvimento instalada como devDependency que observa o projeto,
resolve quais testes uma alteração afeta usando o grafo de dependências, e executa
apenas esse subconjunto — publicando o resultado em três canais ao mesmo tempo:
o terminal (para um agente de IA), um log estruturado (para qualquer ferramenta) e
um painel no VSCode (para você).
$ livetest start
livetest batch-3 (idle) src/login.ts
js -> 4 arquivo(s) de teste
src/footer.test.ts rodou porque src/footer.ts importa src/login.ts (1 nivel)
src/header.test.ts rodou porque src/header.ts importa src/login.ts (1 nivel)
src/layout.test.ts rodou porque src/layout.ts importa src/login.ts via src/header.ts (2 niveis)
src/login.test.ts rodou porque src/login.ts foi alterado
PASSOU js 4 arquivo(s) 5 passou 0 falhou 0 pulou 1.5s
batch-3 PASSOU em 1.6s
LIVETEST batch=batch-3 status=passed files=4 tests=5 passed=5 failed=0 skipped=0 duration=1.6s
Dois problemas recorrentes, agravados quando quem escreve o código é um agente de IA:
- Detecção tardia. O ciclo real é editar → editar → editar → só então testar. Quando o teste enfim roda, várias mudanças já se acumularam e isolar a que quebrou custa caro.
- Escopo subestimado. Ferramentas e agentes tendem a rodar apenas os testes do
arquivo que mudou, ignorando quem depende dele.
login.tsquebra, mas quem acusa são os testes deheader.tsefooter.ts— que ninguém rodou.
| Ferramenta | O que faz | Limitação |
|---|---|---|
jest/vitest --watch |
Roda testes afetados via grafo do bundler | Preso ao ecossistema JS; a saída não foi desenhada para um agente de IA ler |
| Wallaby.js | Execução ao vivo, inline no editor | Focado em UX humana dentro do editor |
pytest-watch |
Reexecuta ao salvar | Sem noção de grafo de dependência; roda escopo fixo |
O Live Test Runner é pensado desde a raiz para dois consumidores simultâneos — o agente, que precisa saber imediatamente se algo quebrou, e a pessoa, que quer ver isso no editor — com controle configurável, por arquivo, de quão fundo no grafo a execução se propaga.
npm install --save-dev @livetest/cli
npx livetest init # cria livetest.config.json comentado
npx livetest doctor # confere ambiente, runners e cobertura
npx livetest start # começa a observarRequer Node.js 18.18+. Para projetos Python, um interpretador 3.8+ no PATH.
┌──────────────────────────────── projeto do usuário ────────────────────────────────┐
│ │
│ arquivo salvo │
│ │ │
│ ▼ │
│ ┌─────────┐ ┌───────────┐ ┌───────────────┐ ┌─────────┐ ┌──────────────┐ │
│ │ Watcher │──▶│ Debounce │──▶│ Grafo de dep. │──▶│ Planner │──▶│ Test runners │ │
│ └─────────┘ └───────────┘ └───────────────┘ └─────────┘ └──────┬───────┘ │
│ agrupa saves quem importa o quê rodar │ │
│ consecutivos este arquivo? e por quê │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Agregador │ │
│ └──┬───┬───┬──┘ │
│ ┌──────────────────────────────────────────────┘ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌──────────────┐ ┌──────────────────┐│
│ │ stdout │ │ run.log │ │ socket TCP ││
│ │ (agente) │ │ status.json │ │ (extensão) ││
│ └────────────┘ └──────────────┘ └──────────────────┘│
└─────────────────────────────────────────────────────────────────────────────────────┘
Cada etapa é um módulo isolado e testado. Grafo de dependência e test runner são adapters plugáveis: adicionar Go ou Rust não exige tocar no core — veja Escrevendo um adapter.
O ponto central da configuração. Para cada arquivo, você decide até onde a execução se propaga no grafo reverso:
| Valor | Significado |
|---|---|
"self" |
apenas os testes do arquivo alterado |
"direct" |
o arquivo + quem o importa diretamente (padrão) |
"transitive" |
o arquivo + toda a cadeia de importadores |
2 |
profundidade numérica exata |
Nota sobre o PRD. A seção 6.2 do PRD descreve
directcomo "roda apenas os testes do arquivo alterado", o que conflita com a seção 4.1, onde o adapter de grafo devolve "importadores diretos ou transitivos". Resolvemos a ambiguidade expondo os três níveis: quem quer o comportamento "só o arquivo" usa"self".
Não tem certeza do que vai rodar? Pergunte:
$ npx livetest why src/login.ts
arquivo: src/login.ts
runner: js
profundidade: transitive — arquivo + cadeia completa de importadores [override: src/login.ts]
arquivos impactados (8):
[0] src/login.ts
[1] src/header.ts
[2] src/layout.ts via src/header.ts
...Suba o daemon uma vez, em background, e leia o resultado sem parser dedicado:
npx livetest start > .livetest/daemon.out 2>&1 &Três formas de consumir, da mais simples à mais completa:
1. A linha resumo. Toda conclusão de lote termina com uma linha chave=valor:
LIVETEST batch=batch-7 status=failed files=3 tests=12 passed=10 failed=2 skipped=0 duration=1.4s
grep '^LIVETEST' .livetest/daemon.out | tail -12. O snapshot. .livetest/status.json sempre reflete o estado atual, com escrita
atômica — nunca se lê um JSON pela metade:
npx livetest status --json | jq '.lastBatch.status'3. O log de eventos. .livetest/run.log é NDJSON append-only, um evento por linha,
com o histórico completo, incluindo o motivo de cada teste ter rodado.
Para uma execução pontual, sem daemon, livetest run devolve exit code 1 quando
algum teste falha — direto em && de shell ou em hook de pre-commit:
npx livetest run src/login.ts && echo "seguro para continuar"Guia detalhado: Agentes de IA.
Painel dedicado com a árvore de arquivos monitorados, status de cada um
(idle/running/passed/failed), o motivo de ter rodado no tooltip, e o log
completo de cada execução.
Conforme o PRD, a extensão não sobe o daemon sozinha: ela procura um em execução
via .livetest/daemon.json e, quando não acha, mostra o botão Iniciar daemon, que
abre um terminal com o comando — a ação continua sendo sua.
| Comando | Para quê |
|---|---|
livetest start |
Observa o projeto e roda os testes afetados a cada save |
livetest run [arquivos...] |
Execução única; exit code 1 se falhar |
livetest why <arquivo> |
Explica o que rodaria e por quê, sem executar |
livetest status [--json] |
Estado do daemon e resultado do último lote |
livetest watch |
Acompanha, em outro terminal, um daemon já em execução |
livetest stop |
Encerra o daemon |
livetest init |
Cria livetest.config.json comentado |
livetest doctor |
Verifica configuração, runners e ambiente |
| Grafo de dependência | Test runners | |
|---|---|---|
| JavaScript / TypeScript | API do compilador TS (paths, baseUrl, index, ESM .js→.ts) |
Vitest, Jest |
| Python | módulo ast nativo, com fallback por regex |
pytest |
| Qualquer outra | adapter próprio (guia) | adapter command (exit code) |
A documentação completa vive no site, em português e inglês, com busca em todo o conteúdo e uma demonstração interativa da propagação no grafo:
| Português | English | |
|---|---|---|
| Primeiros passos | /pt/guide/getting-started | /guide/getting-started |
| Profundidade de propagação | /pt/guide/depth | /guide/depth |
| Agentes de IA | /pt/guide/ai-agents | /guide/ai-agents |
| Escrevendo um adapter | /pt/guide/adapters | /guide/adapters |
| Configuração | /pt/reference/config | /reference/config |
| CLI | /pt/reference/cli | /reference/cli |
| API do core | /pt/reference/api | /reference/api |
| Protocolo de eventos | /pt/reference/protocol | /reference/protocol |
O texto é escrito em packages/landing/content/, que é a fonte única: os arquivos em docs/ apontam para as páginas correspondentes em vez de manter uma segunda cópia.
O site vive em packages/landing/. É estático, construído com Vite e sem nenhuma dependência em runtime: nenhuma página é um arquivo HTML no repositório, e as vinte e oito nascem no build a partir do Markdown e de uma tabela de rotas. A busca é um índice gerado no build e consultado no navegador, sem servidor.
npm run dev --workspace @livetest/landing # servidor local
npm run build --workspace @livetest/landing # gera dist/
npm run preview --workspace @livetest/landing # serve o dist/
npm run build:standalone --workspace @livetest/landing # a home em arquivo úniconpm install
npm run verify # typecheck + cobertura + build, tudo de uma vez
npm test # 1167 testes nos quatro pacotes
npm run test:coverage # 100% de cobertura, com limite obrigatório
npm run typecheck # TypeScript estrito
npm run buildProjetos de exemplo prontos para experimentar em examples/:
demo-js (Vitest) e demo-python (pytest), ambos com a cadeia
login → header/footer → layout que exercita a propagação transitiva.
MIT
{ "dependencyDepth": { "default": "direct", "overrides": { "src/util/**": "self", // utilitário estável: não propaga "src/components/Login.tsx": "transitive" // crítico: propaga até o fim } } }