O tool @diagram renderiza diagramas de arquitetura, dependências, fluxo e ER em PNG, SVG ou JPG a partir de Graphviz DOT — com os textos nítidos e exatamente corretos, porque os rótulos vêm do layout engine, não de pixels “chutados” por um modelo de visão.
O Graphviz é embedado: o go-graphviz traz o engine upstream compilado para WebAssembly, executado pelo runtime wazero (Go puro). Portanto funciona sem cgo, sem instalação e sem rede — o mesmo DNA self-contained do TTS/STT embedados e das notas de voz puro-Go. Quando há um Graphviz do sistema (dot) no PATH, o backend passa a usá-lo por padrão (backend=auto): renderizar o mesmo DOT via fontconfig + as fontes do SO + cairo gera saída mais nítida e melhor diagramada. O engine embedado continua sendo o fallback, então o tool nunca exige instalação. Veja Backend de renderização.
Para qualquer diagrama de nós/arestas, prefira @diagram ao @image. O @image gera uma imagem raster e erra letras; o @diagram é determinístico e os nomes saem 100% corretos. SVG é infinitamente escalável; PNG com dpi=300 é qualidade de impressão.
Uso
<tool_call name="@diagram" args='{"cmd":"render","dot":"digraph{rankdir=LR; cli->agent; cli->llm}","output":"/tmp/arch.png"}' />
<tool_call name="@diagram" args='{"file":"./arch.dot","format":"svg","output":"/tmp/arch.svg"}' />
<tool_call name="@diagram" args='{"cmd":"gomod","root":".","format":"svg","output":"/tmp/imports.svg"}' />
O LLM invoca @diagram automaticamente quando você pede um diagrama de arquitetura/dependências como imagem — ele escreve o DOT (os modelos são bons em DOT) e renderiza aqui.
São dois subcomandos: render (DOT → imagem) e gomod (grafo de imports real de um módulo Go → imagem).
Subcomando render
Renderiza DOT — inline (dot) ou de um arquivo .dot (file) — para uma imagem.
Argumentos
| Argumento | Descrição | Default |
|---|
dot | Código Graphviz DOT inline. Exatamente um de dot | file. | (um dos dois) |
file | Caminho para um arquivo .dot a renderizar. Exatamente um de dot | file. | (um dos dois) |
format | png | svg | jpg | png (SVG no embedado sem format) |
engine | Layout: dot | neato | fdp | sfdp | circo | twopi | osage | patchwork | dot |
dpi | Resolução raster para png/jpg (30–600, com clamp) | 150 |
backend | Engine de renderização: auto | system | embedded. auto prefere o dot do sistema se instalado (mais nítido) e cai no WASM embedado. Sobrepõe CHATCLI_DIAGRAM_BACKEND. | auto |
output | Caminho do arquivo de saída. Omitido, grava num arquivo temporário e retorna o caminho. | (temp) |
Subcomando gomod
Constrói o grafo de imports real de um módulo Go (via go list -json ./...) e o renderiza, clusterizado por diretório de topo — um grafo de dependências fiel ao código 1:1, sem enumerar pacote na mão.
Argumentos
| Argumento | Descrição | Default |
|---|
root | Diretório do módulo a analisar | . |
internalOnly | Só arestas entre pacotes deste módulo (descarta dependências de terceiros) | true |
cluster | Agrupa pacotes em clusters por diretório de topo | true |
style | dark | light | plain | dark |
dotOnly | Retorna o código DOT gerado em vez de renderizar a imagem | false |
format / engine / dpi / backend / output | Iguais ao render | — |
Use dotOnly: true para obter o DOT gerado e editá-lo (cores, agrupamentos, rótulos) antes de renderizar com render. Para diagramas focados, aponte root para um subdiretório (ex.: ./cli) — o grafo do módulo inteiro pode ficar muito largo.
Saída
Para render e gomod (sem dotOnly), o tool grava o arquivo e retorna um resumo com caminho, formato, tamanho e — para raster — as dimensões:
Diagrama renderizado → /tmp/arch.png (PNG, 245.1KB)
dimensões: 1200x800
Com dotOnly: true, o gomod retorna o próprio código DOT (texto), pronto para editar ou versionar.
Backend de renderização
O @diagram renderiza o mesmo DOT por um de dois engines. O DOT gerado é idêntico — só muda quem rasteriza:
| Backend | Engine | Quando usar |
|---|
auto (default) | dot do sistema se houver no PATH, senão o embedado | Melhor padrão: bonito quando dá, nunca quebra |
system | Graphviz nativo (ex.: brew install graphviz) | Força a saída mais nítida (fontconfig + cairo); erro se faltar |
embedded | go-graphviz (WebAssembly/wazero) | Força o engine self-contained, sem depender de instalação |
O embedado rasteriza com gg/freetype (sem cairo/pango), então o PNG/JPG sai um pouco mais suave que o do dot nativo. Para minimizar isso, o embedado usa fontes Go embarcadas com hinting completo e escolhe a família certa por nome (proporcional vs monospace, regular vs negrito) — texto nítido e consistente em qualquer máquina. O dot do sistema usa fontconfig + as fontes do SO + cairo, então fica ainda um pouco mais polido. No modo auto, se o render pelo dot do sistema falhar, há fallback transparente para o embedado.
Quer paridade total sem instalar nada? Use format=svg. O SVG é vetorial e idêntico ao do dot nativo (mesmo engine de layout) — por isso, quando o engine embedado renderiza e você não passa format, a saída usa SVG por padrão. Um format explícito ou uma extensão de arquivo reconhecida (.png/.svg/.jpg) sempre prevalecem.
Configuração
Três formas, da mais ampla à mais específica:
- Variável de ambiente
CHATCLI_DIAGRAM_BACKEND=auto|system|embedded (process-wide)
- Argumento
backend por chamada (sobrepõe o env): {"dot":"...","backend":"system"}
/config diagram mostra o backend configurado, o efetivo (após resolver o auto) e se há um dot instalado, com a versão:
Notas
- Não é read-only e não é concurrency-safe: o tool grava um arquivo (e o
gomod invoca go list), então passa pela confirmação de segurança padrão e não entra em lotes paralelos read-only.
- Embedado de verdade: o Graphviz roda como WebAssembly via wazero — nada para instalar, funciona offline já no primeiro uso, em qualquer SO/arquitetura. Com um
dot do sistema instalado, o backend auto o usa automaticamente para saída mais nítida (veja Backend de renderização).
- Engines suportados:
dot (hierárquico, default), neato/fdp/sfdp (força), circo (circular), twopi (radial), osage/patchwork (clusters/treemap).
Combine com o @docs-flatten e o @context: monte uma base de conhecimento do projeto e peça um diagrama de arquitetura — a IA usa o que aprendeu para escrever o DOT e o @diagram para renderizá-lo com fidelidade.