CLI tempest
Além da CLI de scaffolding create-tempest-app, o pacote
tempest-react-sdk instala um segundo bin — tempest — pra cuidar da
saúde e da higiene do seu projeto no dia a dia: um doctor (no estilo do
flutter doctor) e um fix/lint/format que organiza imports, remove imports
mortos e arruma espaçamento.
Como ele vem dentro do SDK, está disponível assim que você instala a lib — rode
com npx tempest <comando> ou pelos scripts npm run doctor / npm run fix
que o scaffold já cria.
tempest doctor
Faz um diagnóstico do projeto atual e imprime um relatório [✓] / [!] / [✗]
agrupado por seção (estilo flutter doctor) — inclusive problemas
silenciosos que não quebram o build mas explodem em runtime ou drenam horas de
depuração:
npx tempest doctor
tempest doctor (/caminho/do/seu/app)
Environment
[✓] Node 22.13.0
[i] tempest CLI v0.18.0
Project
[✓] package.json found
[✓] tempest-react-sdk in dependencies — ^0.18.0
[✓] tempest-react-sdk installed — v0.18.0
[✓] react + react-dom present — v19.2.0
Dependency health
[!] duplicate instance: react — nested copy under tempest-react-sdk;
rode `npm dedupe`; duas instâncias quebram hooks/context
[✓] @types/react matches react — v19
[!] recharts missing (used by charts) — você importa charts mas recharts não
está instalado — npm i recharts
[✓] tempest-react-sdk up to date — v0.18.0
TypeScript
[✓] tsconfig "@/*" alias
[!] moduleResolution: node — use "bundler" (senão os subpaths
tempest-react-sdk/br, /charts… não resolvem tipos)
[✓] jsx: "react-jsx"
[!] strict mode off — enable "strict": true
Integration
[✓] vite.config.ts uses createViteConfig
[✓] src/main.tsx imports styles.css
Stylesheets
[i] 34 stylesheet(s) · 210 rules · 806 declarations
[✗] src/pages/Dashboard.module.css:12 — a `;` está faltando: o valor de
`padding` engole as declarações abaixo, e o browser derruba todas
[!] src/components/Card.module.css:8 — `bacground-color` não é propriedade
CSS — você quis dizer `background-color`?
[i] src/components/Row.module.css:4 — 7 rules em 6 arquivo(s) declaram as
mesmas 3 propriedades — uma classe global bate 7 cópias locais
[i] 2 finding(s) are auto-fixable — rode `tempest fix`
Design
[i] 42 source file(s) · 1830 lines of code · median 38 — largest:
src/pages/Orders.tsx (204)
[!] src/pages/Orders.tsx:1 — 204 lines of code (limit 150) — extract a
sub-component, a hook or a pure function
[!] src/pages/Orders.tsx:31 — a component must not call the network — move it
to a service and read it with useQuery
[i] 2 limit(s) waived with a written reason — @tempest-limits markers
Tooling
[✓] ESLint config present
[✓] eslint installed
[✓] prettier installed
! 3 warning(s) — usable, but worth fixing.
O que conta como uso, e o que não conta
As checagens que perguntam "esse projeto usa X?" leem o código, não a prosa:
comentários saem antes da busca, então um @example mostrando
import "tempest-react-sdk/styles.css" não vira um segundo import, e um docstring
com <TrajectoryMap tileUrl=…> não passa a exigir o leaflet. Arquivos de teste
também ficam de fora — um teste que renderiza um componente justamente para provar
como ele degrada sem o peer opcional não é o projeto pedindo aquele peer.
Peer marcada como optional em peerDependenciesMeta nunca é reportada como não
satisfeita: é exatamente o que "opcional" quer dizer.
Funciona em projeto que ainda não usa o SDK
Se o tempest-react-sdk não está nas suas dependências, o doctor roda em
modo genérico: audita a saúde de um app React + Vite qualquer e não reprova
você por não ter adotado nada.
As checagens que são convenção do SDK saem do relatório — alias @/*,
createViteConfig, o import do styles.css, o src/main.tsx esperado, os peers
opcionais dos subpaths. O que continua é o que vale pra qualquer app: versão do
Node, instância duplicada de React, dependência declarada e não instalada, peer não
satisfeita, @types/react desalinhado, strict/jsx/moduleResolution, lockfile
(presente, único, não desatualizado), ESLint e Prettier, .env no .gitignore e
variável de cliente sem prefixo VITE_.
$ npx tempest doctor
…
[i] tempest-react-sdk not installed — checking generic React/Vite health only
…
Adopting the SDK (optional)
[i] install — npm i tempest-react-sdk
[i] import the stylesheet once, in your entry — import "tempest-react-sdk/styles.css"
[i] not all-or-nothing — one component at a time works
Antes disso o comando dava duas falhas e exit 1 por um único fato — "você não instalou isto ainda" — e enterrava os achados acionáveis no meio de avisos que eram só a opinião do SDK. Ou seja: era inútil exatamente no projeto onde deveria ajudar mais.
Use no onboarding e na CI
Rode tempest doctor ao clonar um projeto (confirma que tudo está no lugar)
e como passo rápido na CI. Ele sai com código 1 se houver qualquer ✗
(problema bloqueante); avisos ! não falham o comando.
O que ele verifica
Environment — Node ≥ 22.12 (e aviso se for uma linha não-LTS, major ímpar); versão da CLI; versões do TypeScript (≥5) e Vite (≥5); engines.node do package.json satisfeito.
Project — tempest-react-sdk declarado e instalado (com versão); react/react-dom presentes; React major ≥ 18.
Dependency health (os silenciosos):
- Instância duplicada de React ou de libs com estado/contexto (
@tanstack/react-query,zustand,react-hook-form,react-router): uma cópia aninhada dentro dotempest-react-sdksignifica duas instâncias no runtime — hooks inválidos,QueryClient/contexto de RHF que "somem". Sugerenpm dedupe. (Pulado quando o SDK éfile:/link:local.) - Deps declaradas mas não instaladas (drift entre
package.jsonenode_modules) →npm install. peerDependenciesdo próprio app não satisfeitas.@types/react×reactcom majors diferentes → erros de tipo fantasma.- Peers opcionais de subpaths usados: se você importa
tempest-react-sdk/chartssemrecharts,/editorsem@tiptap/react,/visionsemonnxruntime-web, ou passatileUrlnoTrajectoryMapsemleaflet— tudo compila, mas quebra no import lazy em runtime. - SDK desatualizado vs o
latestno npm (best-effort, com timeout curto; pulado offline). lucide-reactem cópia dupla — checagem separada da de cima, porque duas cópias de lucide não quebram hooks como um segundo React: elas duplicam bytes e, o que é pior, deixam as tabelas de slug geradas do/iconsapontando pra exports que a cópia mais antiga não tem. Avisa quando o seupackage.jsondeclara lucide numa faixa diferente da do SDK (é a causa), quando existe cópia aninhada sobtempest-react-sdk(é a prova), e reprova quando a versão instalada é mais antiga do que as tabelas exigem — esse caso quebra o build com… is not exported by lucide-reactapontando pra dentro do SDK. Ver Ícones por slug.
TypeScript — alias @/*; moduleResolution ∈ bundler/node16/nodenext (senão os subpath exports como tempest-react-sdk/br não resolvem tipos — silencioso!); jsx: "react-jsx"; strict: true; skipLibCheck ligado; com testes + vitest, avisa se o types do tsconfig omite vitest/globals.
Integration — vite.config.* usando createViteConfig; @vitejs/plugin-react instalado (JSX/Fast Refresh); import do styles.css no entry (e aviso se importado mais de uma vez).
Stylesheets — análise de sintaxe e semântica de todo .css do projeto (CSS Modules incluídos): CSS que o browser derruba, declaração morta, nome que não existe, e bloco repetido que pede uma classe global. É a seção detalhada na próxima seção deste guia — Análise de CSS. Aqui o doctor mostra no máximo 6 achados por severidade e diz quantos ficaram de fora; a lista completa sai no tempest fix --dry-run.
Design — os limites e anti-padrões de Design de Software medidos no seu código: arquivo/função/hook acima do limite, <X>Props com props demais, any e @ts-ignore, fetch dentro de um .tsx, catch vazio e cor literal em style={{ … }}. Mostra 6 achados por severidade e a mediana de linhas do projeto. Todo achado é warn — limite é heurística com saída de emergência escrita (@tempest-limits <regra> — <motivo>), então a seção nunca derruba o exit code. Pule com --no-design.
Tooling — config + binários de ESLint e Prettier; lockfile presente, único (npm/yarn/pnpm misturados dessincronizam) e não desatualizado (package.json mais novo que o lock → npm install).
Env & secrets — .env no .gitignore (senão segredos vazam no commit); variáveis usadas via import.meta.env.* sem prefixo VITE_ (o Vite não expõe pro browser → undefined em runtime); .env vs .env.example.
Análise de CSS
O ESLint não lê .css e o Prettier só reformata: entre os dois, CSS quebrado
passa batido. O tempest analisa cada folha do projeto — inclusive CSS Modules
— em duas frentes, e o resultado alimenta os dois comandos: o doctor mostra o
resumo, o fix remove a parte que é comprovadamente morta.
npx tempest doctor # resumo, na seção Stylesheets
npx tempest fix --dry-run # lista completa, sem escrever nada
npx tempest fix # remove o que é morto de verdade
npx tempest fix src/components # só um caminho
npx tempest fix --no-css # pula a passada de CSS
Sintaxe — o que o browser derruba
Erros (✗) são coisas que o browser descarta em silêncio. Nenhuma delas
quebra o build do Vite, e é justamente isso que as torna caras:
| Achado | Exemplo |
|---|---|
; faltando entre declarações |
padding: 8px⏎margin: 0; → as duas morrem |
declaração sem : |
color red; |
| valor vazio | color: ; |
bloco nunca fechado / } sobrando |
.a { color: red; |
comentário, string ou ( sem fechar |
/* pra sempre, content: "ops |
| declaração fora de qualquer regra | color: red; no topo do arquivo |
{ sem seletor antes |
{ color: red; } |
O ; que falta é o pior deles
padding: 8px seguido de margin: 0; sem ponto e vírgula no meio é uma
declaração sintaticamente válida com valor 8px margin: 0 — o browser
derruba as duas, sem aviso no console, e o layout fica errado num lugar que
você não escreveu. É o achado que paga a análise inteira.
Semântica — CSS válido que está errado
Avisos (!) são folhas que o browser aceita e que ainda assim não fazem o que o
autor quis:
- Declaração duplicada —
colorduas vezes com o mesmo valor: a primeira é morta. Auto-fixável. - Declaração sobrescrita —
colorduas vezes com valores diferentes na mesma regra: uma das duas é um engano. Não é fixável — escolher qual valor você quis é palpite dentro do design de alguém. - Seletor declarado duas vezes — no mesmo contexto de
@media; diz quais propriedades a segunda regra mata e pede o merge. Quando as duas regras são idênticas declaração por declaração, é auto-fixável. - Propriedade que não existe —
bacground-color,dispaly,paddign. Só reporta quando existe uma propriedade real a até 2 edições de distância, então uma propriedade nova que a tabela não conhece nunca é acusada. @at-ruleinexistente —@medai,@suports: o browser pula o bloco todo.- Token
--tempest-*que não existe — comparado com a tabela lida dostyles.cssinstalado, nunca com uma cópia chumbada na CLI. var(--x)que ninguém define e não tem fallback — resolve pra nada.- Regra vazia — código morto. Em
.module.cssé reportada e nunca removida: pode ser a classe-marcador que o seu JS referencia viastyles.x.
Um var() com fallback nunca é reportado
var(--tempest-card-padding, var(--tempest-space-5)) é o idioma de knob
do SDK: o nome não é um token, é um gancho que o app pode sobrescrever. Como
o fallback garante que renderiza, a checagem fica calada. Sem fallback o
mesmo var() resolve pra nada — aí é defeito e é reportado.
Foi essa regra que derrubou 43 falsos positivos quando a análise rodou no CSS
do próprio SDK — e deixou de pé 4 bugs reais (--tempest-duration-normal,
--tempest-primary-solid, --tempest-primary-on, --tempest-danger-on sem
fallback), corrigidos no mesmo commit que trouxe a análise.
Sugestão (i) — quando o global bate o local repetido
É a checagem que o CSS Modules não pode fazer por você: o escopo garante que
.card de um módulo nunca colide com .card de outro, e o preço é que nada te
conta que os dois são idênticos. A duplicação é invisível por design.
[i] src/br/MapLegend.module.css:32 — 39 rules em 31 arquivo(s) re-implementam
`.tempest-stack` do utilities.css — importe "tempest-react-sdk/utilities.css"
uma vez e use a classe
[i] src/components/Row.module.css:4 — 7 rules em 6 arquivo(s) declaram as mesmas
4 propriedades (display: flex; align-items: center; gap: 8px; …+1) — uma
classe global bate 7 cópias locais
Duas formas do mesmo achado:
global-candidate— bloco com ≥ 3 declarações repetido em ≥ 3 regras e ≥ 2 arquivos (dentro de um único arquivo, exige a 4ª cópia). Agrupa por declaração, não por nome de classe:.row,.linee.barcom o mesmo corpo contam como três cópias.utility-candidate— quando o bloco repetido é um idioma que outilities.cssjá entrega:.tempest-row,.tempest-stack,.tempest-center,.tempest-cluster,.tempest-spread,.tempest-truncate,.tempest-grid-auto,.tempest-card. O casamento ignora o valor dogap, e distingue vizinhos (uma coluna éstack, nãorow).
Além disso, hardcoded-token-value aponta valor literal que é exatamente o
de um token (gap: 8px → var(--tempest-space-2)) — e só quando um único
token tem aquele valor, porque 4px é o valor de vários e mandar você usar
--tempest-space-1 onde você quis uma borda é um palpite dito com confiança.
Sugestão nunca reprova o comando
i é conselho: pode não valer a pena, e transformar cinco blocos iguais em
uma classe global é uma decisão de acoplamento entre telas que a CLI não
tem competência pra tomar. Ela mostra o número e sai da frente.
O que o fix remove — e o que ele nunca toca
A passada de CSS remove três coisas, todas comprovadamente mortas:
- declaração repetida com valor idêntico na mesma regra;
- regra que repete uma anterior declaração por declaração;
- regra vazia em folha comum (não em
.module.css).
$ npx tempest fix
→ css (dedupe declarations · drop dead rules)
src/components/Card.module.css 2
12: removed duplicate `color` — line 14 declares the same value
31: removed `.title` — line 40 repeats it exactly
✓ removed 2 dead declaration(s)/rule(s) in 1 file(s)
Sempre a cópia anterior, nunca a de baixo
CSS é last-wins: remover a declaração de baixo mudaria o resultado sempre que algo entre as duas mexer na mesma propriedade. Remover a de cima não muda nada do que o browser computa — é o que faz a operação segura.
Folha com erro de sintaxe não é escrita
Offset tirado de uma folha pela qual o parser teve que adivinhar caminho não
é offset pra fazer splice. O fix reporta o erro, deixa o arquivo intacto e
sai com código 1: conserte a sintaxe e rode de novo.
O fix também não reescreve valor pra token, não faz merge de seletor
duplicado e não converte bloco repetido em classe global. Tudo isso é edição
de design, não limpeza.
--extract-css: mover o bloco repetido pra classe global
O fix normal reporta bloco repetido e não mexe. Com a flag, ele executa: o
bloco vai pra folha global do projeto, as regras locais somem e os styles.x
no TSX passam a apontar pra classe nova.
npx tempest fix --extract-css --dry-run # revisa o plano, não escreve
npx tempest fix --extract-css # aplica
npx tempest fix --extract-css --css-target src/styles/globals.css
npx tempest fix --extract-css --css-prefix shared-
$ npx tempest fix --extract-css
→ css extract (bloco repetido → classe global)
src/components/Card.module.css 1
removida `.row` (linha 1) → `.u-row` em src/index.css
src/components/Card.tsx 1
`styles.row` → `"u-row"` (linha 5)
src/components/List.module.css 1
removida `.line` (linha 1) → `.u-row` em src/index.css
src/components/List.tsx 1
`styles.line` → `"u-row"` (linha 5)
✓ movidas 2 regra(s) local(is) para 1 classe(s) em src/index.css
O que ele reescreve no TSX:
// antes // depois
<div className={styles.row} /> <div className="u-row" />
<li className={cn(styles.line, on && x)} /> <li className={cn("u-row", on && x)} />
<div className={styles["bar"]} /> <div className="u-row" />
É opt-in porque é decisão de design, não limpeza
As outras passadas removem o que está comprovadamente morto. Esta decide
que N telas passam a compartilhar uma classe — e portanto mudam juntas. É
uma decisão de acoplamento entre telas; a CLI executa, não escolhe. Por isso
nunca roda sem a flag, e por isso o --dry-run existe.
Ela recusa tudo que não consegue provar seguro — e diz o motivo
Nenhuma recusa é silenciosa. Uma ocorrência só é movida quando todas valem:
| Condição | Por que |
|---|---|
seletor é uma classe sozinha (.row), fora de @media |
mover pra fora de um @media mudaria quando a regra vale |
| nenhuma outra regra da folha menciona a classe | um .row:hover ou .row .child ficaria sem sujeito |
| o módulo continua com pelo menos outra regra | senão o import vira código morto, o ESLint remove, e as regras que sobraram param de carregar |
a classe é lida só como styles.row / styles["row"] |
styles[key] ou Object.keys(styles) tornam o módulo opaco: nada nele é extraído |
| a folha global existe e alguém a importa | escrever numa folha que ninguém carrega é no-op silencioso |
| o nome novo não colide na folha global | use --css-prefix |
[!] src/components/Card.module.css:1 não extraído — outra regra na mesma folha
usa `.row` (linha 12) e ficaria sem sujeito
As chamadas são achadas pelo compilador do seu projeto
A varredura usa o typescript instalado no projeto, não regex: styles.row
dentro de comentário, template literal ou string não é uso, e regex não sabe
diferenciar. Sem typescript instalado, a passada avisa e não escreve nada.
O alias do tsconfig é respeitado, então @/components/Card.module.css
resolve igual.
O nome da classe nova
É o nome local que o seu código mais usa (por módulo, e depois por número de
chamadas), com o prefixo u-. Empate é o caso normal — as cópias moram em
módulos diferentes justamente porque ninguém combinou um nome —, e aí a ordem
das ocorrências decide, o que mantém o resultado igual entre execuções. O nome
escolhido aparece antes de qualquer escrita, no --dry-run.
O que a análise deixa de fora, de propósito
Folha minificada (*.min.css ou densidade alta de bytes por linha),
arquivo acima de 512 KB, e as pastas node_modules/, dist/, build/,
coverage/, public/, vendor/. Acima de 600 folhas o doctor avisa
que bateu o teto em vez de truncar em silêncio. A varredura roda em ~0,3 s
nas 200+ folhas do próprio SDK.
tempest fix
Arruma o código de uma vez: converte import relativo pra @/, remove CSS
morto, organiza imports, remove imports não usados, limpa linhas em
branco extras e espaços no fim, e roda o Prettier.
npx tempest fix # o projeto inteiro
npx tempest fix src/app # só um caminho
npx tempest fix --dry-run # mostra o que mudaria, não escreve
npx tempest fix --no-alias # pula a conversão de import
npx tempest fix --no-css # pula a passada de CSS
npx tempest fix --extract-css # opt-in: bloco repetido → uma classe global
São quatro passadas, nessa ordem: a conversão de alias, a
análise de CSS, eslint --fix (com as regras
simple-import-sort, unused-imports/no-unused-imports,
no-multiple-empty-lines, no-trailing-spaces, eol-last) e prettier --write.
A conversão vem primeiro de propósito: trocar ../../services/api por
@/services/api muda o grupo de ordenação do simple-import-sort, então rodar o
ESLint depois deixa tudo ordenado num único fix. O CSS vem antes do Prettier
pelo mesmo motivo: o que a remoção deixa torto, o Prettier arruma na sequência.
--dry-run é a superfície de revisão do CSS
O doctor mostra 6 achados por severidade; o --dry-run lista todos os
erros e avisos (só a cauda de sugestões é limitada a 10) e não escreve nada.
É o que você lê antes de deixar a ferramenta mexer.
A conversão de import
A regra é uma só: nenhum import sobe de diretório.
// antes // depois
import { api } from "../../services/api"; import { api } from "@/services/api";
import { Button } from "../Button"; import { Button } from "@/components/Button";
import { Row } from "./Row"; // inalterado — irmão continua relativo
import cfg from "../../../vite.config"; // inalterado — resolve fora de src/
Um import de irmão (./x) fica como está: ele já diz "isso mora aqui do lado",
que é informação que o @/ joga fora. Um caminho que resolve fora da base do
alias também fica — é isso que protege ../../../vite.config e
../../../scripts/x.
O que a conversão alcança, além de import e export … from:
import type { User } from "../../types/user"; // import type
const m = await import("../../pages/Dashboard"); // import() dinâmico
vi.mock("../../lib/api"); // vi.mock / vi.doMock
E em arquivo .css (o Vite resolve alias em CSS também):
@import "../../styles/tokens.css"; /* → @/styles/tokens.css */
.hero {
background: url(../../assets/bg.png); /* → @/assets/bg.png */
}
Rode com --dry-run primeiro num projeto grande
O --dry-run lista arquivo, linha e o antes/depois de cada import sem
escrever nada — e sem rodar ESLint ou Prettier. É a forma de revisar o
diff antes de deixar a ferramenta mexer.
$ npx tempest fix --dry-run
→ alias imports (../ → @/) [dry-run]
src/pages/admin/Users.tsx 2
1: "../../lib/api" → "@/lib/api"
2: "../../styles/tokens.css" → "@/styles/tokens.css"
✓ would convert 2 import(s) in 1 file(s)
O alias vem do seu tsconfig.json, não é chumbado
A base é lida de compilerOptions.paths — seguindo extends e aceitando
comentário no JSON. Se o seu projeto usa ~/* ou #/* em vez de @/*, é
esse prefixo que sai na conversão; se usa app/ em vez de src/, é essa a
base.
Sem paths no tsconfig, a conversão não roda
Isso é de propósito. O paths é o que o type-checker honra: um alias
achado ali é um alias que o tsc --noEmit aceita depois da conversão.
Adivinhar @ → src só porque existe um src/ produziria import que não
resolve em projeto nenhum que não tenha o alias configurado. Quando não acha,
o comando avisa e segue pro ESLint sem tocar em nada:
! no path alias found — skipping alias pass add "paths": { "@/*": ["./src/*"] } to tsconfig.json
A conversão também precisa do typescript instalado no projeto: ela usa o
compilador do seu projeto pra achar as posições de import, então uma
string parecida com caminho dentro de comentário, template literal ou
variável nunca é reescrita por engano.
Código morto = imports/vars, não funções inteiras
O fix remove imports não usados e avisa sobre variáveis não usadas
(não apaga, pra não arriscar). Ele não faz eliminação de dead code mais
profunda (funções/exports órfãos) — isso exige análise dedicada e é
arriscado automatizar. Para isso, use uma ferramenta como knip à parte.
TypeScript 7 não tem a API que os codemods usam
O 7 é o port nativo: instala com o mesmo nome de pacote, mas publica a API JS
só em typescript/unstable/*, com outra forma — o ts.readConfigFile/
ts.createSourceFile clássicos não existem lá. Como as duas passadas de codemod
(a conversão de alias e o --extract-css) precisam do AST, elas saem do
caminho e dizem por quê:
! alias pass skipped — typescript 7.0.2 não expõe a API clássica do compilador…
Todo o resto continua: a análise de CSS, o dedupe, o ESLint, o Prettier, e as
checagens de tsconfig do doctor (que caem num parser JSONC próprio). Pra usar os
codemods, tenha o TypeScript 6 instalado no projeto.
Antes da 0.29.1 isso não era um aviso: a CLI resolvia o pacote, concluía que tinha
TypeScript e chamava a API — tempest doctor morria com
ts.readConfigFile is not a function.
Precisa de ESLint + Prettier no projeto
Apps gerados pelo create-tempest-app já vêm com tudo configurado. Em um
projeto pelado, instale: npm i -D eslint prettier eslint-plugin-simple-import-sort eslint-plugin-unused-imports.
tempest lint e tempest format
npx tempest lint # eslint . (só reporta, não altera)
npx tempest format # prettier --write . (só formatação)
lint é o relatório read-only; fix é o lint que corrige + formata. Flags que
você passar são repassadas pro binário (npx tempest lint --max-warnings 0), e o
caminho continua sendo posicional.
Ajuda
npx tempest --help
npx tempest --version
Recap
- O
bintempestvem dentro do SDK —npx tempest <comando>. doctordiagnostica o projeto (estiloflutter doctor), sai com código 1 em problemas bloqueantes.fixconverte import relativo pra@/+ remove CSS morto + organiza imports + remove imports mortos + limpa espaçamento + Prettier.--dry-runpra revisar,--no-alias/--no-csspra pular uma passada.- A análise de CSS acha sintaxe que o browser derruba, declaração/regra duplicada, nome que não existe e bloco repetido que pede uma classe global. O
doctorresume, o--dry-runlista tudo, ofixremove só o que é morto. - A análise de design mede limite de arquivo/função/hook, contagem de props,
any,fetchem componente,catchvazio e cor literal inline — sempre como aviso, com@tempest-limits <regra> — <motivo>como saída de emergência escrita. lintreporta;formatsó formata.- Veja também: Scaffold · Arquitetura.