ArchFlow: diagramas em texto, animados e editáveis por IA
A engenharia do ArchFlow: DSL de diagramas, CLI sem janela, WebP animado, servidor MCP, importação de Mermaid, timeline com blocos e gitgraph.
avançadoPublicada em · 36 min de leitura
O ArchFlow é um ecossistema de desenho arquitetural projetado para resolver um impasse moderno: humanos pensam visualmente, modelos de inteligência artificial pensam em texto, e diagramas estáticos comuns quase sempre morrem desatualizados no primeiro commit. Ele combina um aplicativo web interativo, uma linguagem declarativa própria (DSL), uma interface de linha de comando (CLI) autônoma e um servidor (Model Context Protocol) que permite a assistentes de código desenharem e corrigirem fluxos animados sem intervenção humana.
Esta aula disseca a engenharia do ArchFlow do primeiro ao último byte, incluindo o que entrou depois da primeira versão: leitura e escrita de Mermaid, blocos na timeline de sequência, de grupos nas conexões e o , que anima o histórico de um repositório. Veremos como o aplicativo foi concebido sobre React Flow e Zustand, como a CLI conseguiu gerar SVGs e WebPs animados no terminal sem depender de downloads pesados de navegadores, e como o servidor MCP foi desenhado com sessão preguiçosa e isolamento estrito de canais para transformar agentes de IA em projetistas visuais. O código de referência vive no repositório archflow (espelhado em svg-creator), com ferramentas em tools/archflow/.
Mapa da aula
| Parte | Seções | Pergunta central que responde |
|---|---|---|
| 1. Fundamentos e origem | 1 a 3 | Qual problema de comunicação entre humanos e IAs motivou a criação do ArchFlow? |
| 2. A engenharia do aplicativo | 4 a 7 | Como o editor web foi estruturado, da digitação do texto à árvore DOM? |
| 3. O pipeline de exportação e estado | 8 a 10 | Como o SVG captura estilos, pacotes animados e preserva o estado do diagrama? |
| 4. A criação da CLI | 11 a 15 | Como gerar gráficos de navegador no terminal com alta performance e sem janelas? |
| 5. O motor de WebP animado | 16 a 18 | Como congelar e fatiar o tempo virtual para criar animações determinísticas? |
| 6. A criação do servidor MCP | 19 a 23 | Como expor o motor visual para agentes de IA via JSON-RPC seguro? |
| 7. Edição cirúrgica e reidratação | 24 a 26 | Como ler, alterar e validar diagramas existentes sem alucinar? |
| 8. Depois da primeira versão | 27 a 32 | O que entrou depois do lançamento: Mermaid, blocos na timeline, desvio de grupos, gitgraph e as novas ferramentas MCP? |
| 9. Casos de borda e boas práticas | 33 a 35 | Quais armadilhas de concorrência, contraste e tokens você deve contornar? |
| 10. Prática e consolidação | 36 a 38 | Exercícios aplicados e glossário dos mecanismos internos. |
Parte 1: Fundamentos e origem
1. O dilema visual do desenvolvimento moderno
Imagine tentar explicar a arquitetura de uma casa pelo interfone usando apenas códigos postais. Você até consegue transmitir onde ficam as paredes, mas quem ouve não tem ideia de onde o sol bate nem por onde a fumaça sai. Na engenharia de software, o equivalente a esse interfone são os arquivos Markdown cheios de listas em tópicos ou diagramas Mermaid rudimentares.
Antes do ArchFlow, existiam dois caminhos predominantes para documentar sistemas:
- Editores visuais livres (Figma, Miro, Excalidraw): produzem artes expressivas, mas o arquivo é um binário opaco ou um JSON gigantesco. Uma IA não consegue ler com facilidade, um diff no Git vira pesadelo e, em três semanas de sprints corridas, o desenho fica obsoleto porque ninguém teve paciência de entrar na ferramenta para mover cinco caixas de lugar.
- Ferramentas baseadas em texto tradicionais (Mermaid, PlantUML, Graphviz): fáceis de versionar no Git, mas visivelmente pobres. São estáticas, com caixas cinzas sem hierarquia visual expressiva, cartões que parecem saídos da década de 1990 e nenhuma capacidade de ilustrar tráfego dinâmico ou saturação de filas.
O ArchFlow nasceu para unir os dois mundos: uma linguagem declarativa legível por humanos e barata em tokens para IAs, capaz de compilar instantaneamente em cartões modernos com tipografia refinada, ícones de tecnologias reais e pacotes animados fluindo pelas arestas.
O diagrama acima ilustra esse contraste. À esquerda, as abordagens antigas isolavam a documentação visual da automação. No centro, o pipeline unificado do ArchFlow recebe a DSL declarativa e ramifica o resultado em dois artefatos: o SVG animado autônomo e o WebP para plataformas que barram vetores. À direita, esses artefatos alimentam o Obsidian, o GitHub e blogs técnicos, mantendo aberta a seta pontilhada de reidratação, que permite converter o SVG final de volta em texto para futuras edições.
2. O que é e para que serve o formato de texto (.diagram)
A alma do ArchFlow é a sua DSL (Domain Specific Language). Em vez de forçar o autor ou a IA a calcular coordenadas espaciais (x, y), a sintaxe foca exclusivamente na topologia e nas intenções de negócio.
Observe este exemplo conciso:
diagrama "Processamento de pedidos"
direção LR
espaçamento 60 140
cliente = ator "Comprador" kind=browser
api = rest "API de Checkout" base=/v1
fila = kafka "pedidos.v1" partitions=3
banco = cilindro "PostgreSQL" "Armazenamento primário" icon=logos:postgresql tema=supabase
cliente -> api "POST /checkout" anim=pacotes
api -> fila "Publica evento" anim=pacotes cor-pacote=#f59e0b
api -> banco "Grava rascunho" anim=pacotes ida-volta
Quatro princípios orientaram o design dessa DSL:
- Uma instrução por linha: facilita a leitura por regex e evita erros de fechamento de blocos aninhados.
- Nomes de ícones padronizados: integração direta com bibliotecas reais (Logos, Simple Icons, Lucide), evitando ilustrações genéricas.
- Semântica de fluxo nas conexões: parâmetros como
anim=pacotes,cor-pacote,ida-voltaevel=rápidatransformam uma linha inerte em uma demonstração visual de latência e direção de mensagens. - Layout totalmente automático: o autor declara as relações de dependência e os agrupamentos; os motores de grafos cuidam do espaçamento e evitam colisões.
3. Exemplos reais de uso
Para perceber a flexibilidade desse arranjo, considere dois contextos onde o formato de texto e sua automação trazem ganhos imediatos:
Contexto A: Documentação contínua em pull requests. Em vez de anexar prints desatualizados, um fluxo no GitHub Actions roda a CLI do ArchFlow (pnpm archflow render docs/ --if-newer) sempre que um arquivo .diagram é alterado. A documentação no repositório ganha um SVG animado atualizado no mesmo commit do código backend.
Contexto B: Pareamento com agentes em tempo real. Você pede ao Claude Code ou Gemini: “acrescente um cache Redis com TTL de 60 segundos entre a API e o banco de dados”. O assistente não tenta adivinhar nós em telas; ele chama ferramentas MCP dedicadas, altera três linhas na DSL, valida a sintaxe e entrega a imagem pré-visualizada diretamente no chat.
Parte 2: A engenharia do aplicativo
4. O trio de sustentação: React 18, Vite e
O aplicativo do ArchFlow (src/) foi projetado como uma aplicação web de página única (SPA), usando Vite para compilação rápida e React 18 com TypeScript estrito. A camada de exibição visual é construída sobre o XYFlow (@xyflow/react, a evolução moderna do clássico React Flow).
O XYFlow provê os alicerces de interação de baixo nível: manipulação de zoom e pan, suporte a nós arrastáveis, seleção retangular, renderização de arestas baseadas em curvas de Bézier e cálculo de caixas delimitadoras (bounding boxes). Contudo, o ArchFlow não utiliza os nós padrão da biblioteca; ele implementa componentes inteiramente customizados (BaseNode, ContainerNode, ChartNode) para permitir visualizações ricas como anéis de progresso, pílulas de status e tabelas de esquemas de banco de dados.
5. Gerenciamento de estado reativo com Zustand
Para gerenciar o grafo em tempo de execução sem provocar renderizações em cascata por toda a aplicação, o projeto adotou o Zustand (src/store/index.ts).
O estado central reúne:
- A coleção de nós (
Node[]), com dados customizados que variam de tipos visuais a atributos de acessibilidade. - A coleção de conexões (
Edge[]), com parâmetros de roteamento, cores de pulso e marcadores de ponta. - O histórico de alterações para suporte a desfazer e refazer (undo/redo).
- A viewport ativa (posição x, y e nível de zoom).
Quando o usuário edita uma linha no painel de texto, o aplicativo não reconstrói o grafo do zero de forma ingênua. Ele despacha a ação applyTextDiagram, que reconcilia o estado anterior com a nova estrutura, preservando seleções e evitando saltos visuais na tela.
6. O pipeline do compilador de DSL (Parser e )
O compilador que transforma a DSL em elementos de tela é TypeScript puro e não depende de nenhuma API de navegador. Isso permitiu que a mesma lógica fosse compartilhada entre a interface web, a CLI e o servidor MCP.
O fluxo opera em quatro etapas sequenciais:
- Scanner e Tokenizer (
src/utils/diagramText/scan.ts): consome o arquivo caractere por caractere, ignorando comentários (#) e separando identificadores, strings entre aspas, números e palavras-chave. - Parser Sintático (
src/utils/diagramText/parse.ts): aplica as regras da gramática formal. Ele valida comandos comodiagrama,direção, atribuições de nós (id = tipo "Rótulo"), containers (grupo) e conexões (a -> b). Produz uma Árvore Sintática Abstrata (AST) tipada, registrando diagnósticos com número de linha para erros e avisos. - Resolução de Ícones (
src/utils/diagramText/iconResolve.ts): verifica se o identificador emicon=existe na biblioteca estática. Se o usuário digitaricon=posgres, o compilador emite um aviso sugerindoicon=logos:postgresql. - Construtor de Elementos (
src/utils/diagramText/build.ts): mapeia a AST para a estrutura nativa de nós e arestas compreendida pelo XYFlow, atribuindo tamanhos padrão, estilos de preenchimento e classes CSS correspondentes aos temas (supabase, claude, stripe, entre outros).
7. O layout automático e a prevenção de colisões
Desenhar caixas automaticamente é simples; garantir que conexões não cruzem cartões e que textos longos não fiquem sobrepostos é onde a maioria das ferramentas falha.
O motor do ArchFlow implementa um algoritmo de layout hierárquico (src/utils/autoLayout.ts) combinado com um estágio pós-layout de repulsão (src/utils/overlap.ts). Esse estágio executa testes geométricos nas caixas delimitadoras absolutas de todos os elementos. Quando detecta que um rótulo de aresta cruza o corpo de um cartão, ele afasta o elemento de destino ou espalha os rótulos verticalmente. O resultado é um posicionamento equilibrado sem necessidade de microajustes manuais.
A figura acima mapeia a organização interna do aplicativo. O pipeline do formato de texto (em marrom e roxo) transforma os caracteres brutos em nós com posições geométricas. Em seguida, a camada de runtime (em azul e laranja) sincroniza o Zustand com o canvas do XYFlow. Por fim, o motor de exportação (em verde e petróleo) clona o elemento renderizado para produzir o arquivo SVG final.
Parte 3: O pipeline de exportação e estado
8. Como funciona a clonagem do DOM via
Um dos maiores desafios de arquitetura de software gráfico é como transformar um canvas interativo React em um arquivo SVG puro que qualquer visualizador consiga abrir. Muitos projetos tentam gerar o XML do SVG manualmente do zero, mas isso quase sempre resulta em discrepâncias visuais: o texto quebra diferente, os gradientes ficam opacos e a renderização no arquivo nunca bate com o que estava na tela.
O ArchFlow resolve isso por clonagem do DOM real (src/utils/diagramFile.ts). Quando você clica em Exportar ou aciona a renderização headless, a biblioteca html-to-image atua sobre o elemento .react-flow__viewport. Ela lê o nó da árvore DOM, calcula todos os estilos computados (computed styles) através das APIs do navegador, converte imagens e fontes externas para base64 e gera uma árvore <svg> contendo nós <foreignObject>.
9. Inlining de CSS, keyframes e assets
Para que o SVG exportado continue funcionando quando você o move para outra máquina ou abre no Obsidian sem acesso à internet, ele não pode depender de folhas de estilo externas (<link rel="stylesheet">).
O motor de exportação do ArchFlow realiza três procedimentos essenciais de isolamento:
- Injeção de CSS de transição e animação: concatena os arquivos
nodeFx.cssechart.css, embutindo regras de@keyframespara o pulso dos nós, brilhos neon e animações de gráficos cartesianos. - Sanitização de cores e URLs: remove qualquer chamada de script potencialmente maliciosa e limpa referências inseguras.
- Conversão de ícones em data-URIs: cada ícone do Lucide ou do catálogo de marcas é embutido diretamente no corpo do XML como um vetor limpo, garantindo autonomia completa do arquivo.
10. O truque do estado embutido: a tag metadata
Se você exportar um diagrama para SVG e perder o arquivo de texto original, como editá-lo no futuro? Ter de refazer o desenho do zero seria inaceitável.
A solução da equipe do ArchFlow foi genial pela simplicidade: antes de fechar a string do arquivo SVG, o exportador serializa a AST do diagrama (ou o texto DSL canônico) em base64 e o insere dentro de uma tag padronizada:
<metadata id="svg-creator-state">
eyJuYW1lIjoiUHJvY2Vzc2FtZW50byIsIm5vZGVzIjpb...
</metadata>
Esse bloco é completamente ignorado pelos navegadores ao renderizar a imagem, não afeta a exibição no Obsidian nem no GitHub, mas funciona como um registro fóssil intacto. Sempre que o ArchFlow ou o MCP lê um arquivo .svg, ele extrai essa tag e restaura imediatamente o diagrama para edição.
Parte 4: A criação da CLI
11. O dilema: exportar SVG requer DOM, mas o terminal roda Node puro
Quando surgiu o requisito de criar uma CLI (tools/archflow/cli.ts), a equipe deparou-se com um grande obstáculo técnico: o parser e o layout funcionam perfeitamente em Node puro, mas a exportação fiel do SVG depende de calcular o layout do XYFlow, fontes do sistema e clonar o DOM do navegador.
Criar um motor de renderização alternativo em Node (usando node-canvas ou jsdom) exigiria reescrever milhares de linhas de código, reimplementar o layout flexível do CSS e manter dois motores gráficos diferentes em sincronia perpétua. A decisão estratégica foi outra: o terminal abriria o próprio aplicativo compilado dentro de uma janela invisível do Chromium e extrairia o SVG do DOM real.
12. Localização de Chromium nativo sem downloads inflados
A maioria das ferramentas baseadas em automação de navegadores (como Puppeteer padrão) força o download de centenas de megabytes de binários do Chromium na pasta node_modules. Para um utilitário de terminal ou ambiente de desenvolvimento local, isso desperdiça disco e tempo de instalação.
O ArchFlow contornou isso usando playwright-core combinado com um módulo de varredura nativa (tools/archflow/chrome.ts). O código inspeciona os caminhos padrão do sistema operacional em busca de navegadores baseados em Chromium já instalados no computador do usuário:
- No macOS: Google Chrome, Chromium, Brave Browser ou Microsoft Edge na pasta
/Applications. - No Linux:
/usr/bin/google-chrome,/usr/bin/chromium, entre outros. - No Windows: os caminhos clássicos em
Program Files.
Se o ambiente for customizado, a variável ARCHFLOW_CHROME permite apontar o executável diretamente. O resultado é instalação leve e inicialização imediata.
13. O servidor HTTP efêmero e a ponte window.__archflow
Para que o navegador headless renderize o app, ele precisa carregar a pasta dist/. Carregar arquivos via protocolo file:// quebra políticas de segurança do navegador (CORS) ao buscar ícones e fontes.
A CLI então orquestra os seguintes passos:
- O módulo
tools/archflow/server.tssobe um servidor HTTP mínimo nativo do Node em uma porta aleatória e livre de127.0.0.1. Ele possui proteção rigorosa de path traversal, impedindo que requisições escapem da pastadist. - O Playwright abre uma aba apontando para
http://127.0.0.1:<porta>/?archflow=1. - O parâmetro
?archflow=1é o gatilho para o aplicativo carregar o arquivosrc/archflowBridge.ts. Esse arquivo expõe na janela global a funçãowindow.__archflow.render(request).
A CLI comunica-se com o app usando page.evaluate: envia o texto do diagrama pela ponte, o app aplica o texto no Zustand, espera a montagem do canvas e as transições CSS concluírem, chama o motor de exportação e devolve a string completa do SVG para o terminal.
14. Otimizações de desempenho: check em Node e flag —if-newer
Abrir um navegador sem janela leva cerca de 1,5 a 2 segundos. Se você estiver trabalhando em um repositório com 50 diagramas, rodar o navegador para todos eles a cada build tornaria o processo insuportável.
A CLI introduziu duas otimizações que reduzem esse tempo a quase zero:
O comando archflow check: executa apenas o parser sintático, o cálculo de layout e a checagem de nomes de ícones em Node puro. Ele valida o diagrama em 0,6 segundos, informando se há erros de digitação ou linhas sobrepostas antes mesmo de encostar no navegador.
A flag --if-newer: compara o carimbo de data e hora de modificação (mtime) do arquivo .diagram de origem contra o arquivo .svg de destino. Se o SVG já existir e for mais recente que o texto fonte, a CLI pula o arquivo silenciosamente. O comando roda em apenas 0,4 segundos quando nada foi alterado.
15. Proteção contra concorrência e o trinco de build
Se duas instâncias da CLI (ou duas chamadas de agentes simultâneos) tentarem rodar em paralelo enquanto o código do aplicativo precisa ser compilado, uma instância poderia sobrescrever a pasta dist/ da outra durante o pnpm build, corrompendo os arquivos.
Para evitar isso, o arquivo tools/archflow/build.ts implementa uma trava atômica baseada no sistema de arquivos (node_modules/.archflow-build.lock). Como a chamada mkdirSync no sistema operacional é uma operação atômica no nível do kernel, se o diretório de trava já existir, o segundo processo aguarda educadamente em um laço de espera com timeout de segurança.
O diagrama acima detalha a máquina de estados da CLI. Note a ramificação logo após a análise dos argumentos: comandos leves como check e icons são resolvidos instantaneamente no runtime do Node. Apenas o comando render desce para o estágio pesado, passando pelo trinco de build e pela verificação de alteração de arquivo (--if-newer) antes de ligar o servidor estático e acionar o Playwright.
Parte 5: O motor de WebP animado
16. Por que o WebP animado é necessário
Embora o formato SVG seja o padrão ouro para documentação moderna em ambientes como o Obsidian e o GitHub, ele enfrenta restrições severas na web aberta. Plataformas como o Dev.to, sistemas de gerenciamento de conteúdo corporativos (CMS), Medium e clientes de e-mail barram a inclusão de arquivos SVG por medo de ataques de cross-site scripting (XSS), já que um SVG pode conter scripts executáveis.
A alternativa clássica sempre foi o GIF, mas o formato GIF é limitado a uma paleta de 256 cores, gera arquivos gigantescos e não possui suporte a gradientes suaves nem transparência translúcida. O WebP animado oferece cores verdadeiras de 24 bits, canal alfa de 8 bits e alta taxa de compressão.
17. O congelamento do relógio: e CSS frame a frame
Gravar a tela de um navegador em tempo real enquanto a animação roda gera resultados instáveis: se o computador sofrer uma oscilação de CPU, a taxa de quadros cai e a gravação fica engasgada.
O ArchFlow resolveu isso construindo um motor de animação determinístico e independente do relógio da máquina (tools/archflow/animate.ts). Ele não grava a tela em tempo real; ele congela o tempo e manipula o relógio virtualmente quadro a quadro:
- Carrega o SVG exportado em uma página limpa do Chromium.
- Animações SMIL (os pacotes que viajam nas arestas): o motor executa
svg.pauseAnimations()e controla a posição do tempo através de chamadas síncronas asvg.setCurrentTime(tempoSegundos). - Animações CSS (os pulsos e gradientes dos cartões): o motor pausa as propriedades CSS via
animation-play-state: pausede avança o progresso através de atrasos negativos (animation-delay: -tempo).
A cada avanço infinitesimal do tempo (t = quadro / fps), o Playwright tira um screenshot estático em memória (page.screenshot). Não há perda de frames nem interferência da carga do sistema.
18. O cálculo do loop perfeito e codificação com sharp
Para que o WebP animado se repita infinitamente sem dar um tranco visual perceptível ao recomeçar, o ponto final da animação precisa casar exatamente com o ponto inicial.
O módulo tools/archflow/animateTiming.ts analisa os tempos de todas as animações declaradas no diagrama. Ele calcula o Mínimo Múltiplo Comum (MMC) dos períodos das animações infinitas para determinar a menor duração de loop na qual todos os pacotes e pulsos retornam à posição de partida original.
Após capturar a sequência de buffers PNG, o motor executa uma passagem de deduplicação (descartando quadros consecutivos estáticos) e alimenta a biblioteca sharp. O sharp codifica a sequência diretamente em WebP binário, configurando o cabeçalho de repetição contínua (loop: 0).
A figura acima exibe as três fases da geração do WebP. À esquerda, o SVG é injetado e analisado para calcular o ciclo de repetição. No centro, o tempo virtual é congelado e fatiado quadro a quadro em um laço determinístico de capturas fotográficas. À direita, os buffers resultantes passam pelo filtro de deduplicação e são empacotados pelo sharp no arquivo final.
Parte 6: A criação do servidor MCP
19. A arquitetura do Model Context Protocol (MCP)
O Model Context Protocol é uma especificação aberta introduzida para padronizar como assistentes inteligentes de IA interagem com ferramentas e dados locais. Em vez de implementar conectores ad-hoc para cada modelo, o assistente conecta-se a um servidor MCP padronizado.
O servidor do ArchFlow (tools/archflow/mcp.ts) é construído sobre o SDK oficial da Anthropic (@modelcontextprotocol/sdk) e utiliza esquemas Zod para validação rigorosa de entradas. Ele é registrado localmente tanto no Claude Code (via .mcp.json) quanto no Gemini CLI (via .gemini/settings.json), subindo automaticamente como processo filho quando o ambiente é aberto.
20. A regra de ouro do stdio e a higiene de logs
No transporte padrão por entrada e saída do console (StdioServerTransport), o canal stdout é reservado exclusivamente para o tráfego de mensagens do protocolo JSON-RPC.
Se você colocar um inocente console.log("Servidor iniciado!") ou se uma dependência imprimir um aviso de versão no stdout, a saída será interceptada pelo cliente MCP como uma mensagem do protocolo malformada. O cliente falha imediatamente e derruba a conexão.
No ArchFlow, a comunicação foi blindada com uma função central de log direcionada exclusivamente ao stderr:
const log = (message: string) => process.stderr.write(`[archflow-mcp] ${message}\n`);
Tudo o que é mensagem operacional, aviso de compilação ou progresso de quadros viaja por stderr, mantendo o stdout imaculado para o fluxo JSON-RPC.
21. A sessão preguiçosa () do navegador
Iniciar o Chromium headless quando o Claude Code ou o Gemini abre o terminal consumiria memória desnecessária e atrasaria a inicialização do ambiente, mesmo se o usuário nunca fosse gerar um diagrama na sessão.
O ArchFlow implementa um padrão de inicialização sob demanda chamado Lazy Session (tools/archflow/session.ts). O servidor MCP inicia instantaneamente sem tocar em navegadores. Quando a IA chama a ferramenta render_diagram pela primeira vez, o servidor verifica se já existe uma sessão aberta. Se não houver, ele compila o app caso o código tenha sido alterado, sobe o servidor HTTP estático e abre o Chromium.
Nas chamadas seguintes de renderização durante a mesma conversa, a instância do navegador permanece aquecida na memória, respondendo às novas renderizações em fração de segundo.
22. O catálogo de ferramentas: divisão entre leves e pesadas
Uma decisão de engenharia notável no servidor MCP do ArchFlow foi a categorização de suas ferramentas de acordo com o custo computacional. A maioria das operações não precisa renderizar pixels:
Ferramentas leves (executadas em Node puro em menos de 50 milissegundos):
syntax_help: devolve regras gramaticais e exemplos de sintaxe.describe_format: detalha programaticamente todas as propriedades válidas geradas do próprio código TypeScript.search_iconsesuggest_icons: pesquisam no índice local de ícones sem precisar abrir telas.check_diagram: valida o texto do diagrama, avisando erros sintáticos, rótulos sobrepostos ou elementos que ultrapassam a largura confortável de leitura.chart_math: calcula cruzamento de curvas, tabelas assintóticas de Big O e percentis matemáticos sem gerar imagens.
Ferramenta pesada (envolve o canvas do navegador):
render_diagram: compila a DSL no DOM, renderiza o SVG, salva o arquivo no disco rígido e, quando solicitada a opçãopreview: true, devolve ao assistente uma imagem reduzida em base64 (escala 0,6) para que o modelo confira visualmente a qualidade do layout gerado.
23. Exposição de documentos como Resources MCP
Além de funções acionáveis (tools), o protocolo MCP permite disponibilizar recursos de leitura passiva (resources). O ArchFlow expõe sua documentação completa e especificações técnicas sob a URI customizada archflow://:
archflow://docs/diagram-text: manual completo de referência da linguagem.archflow://docs/cheatsheet: colinha compacta de consulta rápida.archflow://specs/charts: especificação do motor matemático de gráficos.
Isso permite que assistentes com contexto estendido leiam os manuais do sistema sob demanda, sem gastar tokens da janela de contexto no prompt inicial.
A figura acima exibe a bifurcação de tráfego no servidor MCP. O host envia comandos JSON-RPC pelo canal stdout devidamente isolado de stderr. O núcleo do servidor avalia o comando: requisições de consulta textual são atendidas imediatamente em Node puro, enquanto requisições gráficas ativam a sessão preguiçosa do Chromium apenas no momento necessário.
Parte 7: Edição cirúrgica e reidratação
24. A leitura reversa: read_diagram
Imagine que um assistente de IA precise alterar um diagrama que já foi exportado anteriormente para assets/arquitetura.svg, mas o usuário não forneceu o arquivo .diagram fonte.
Graças à tag de metadados embutida na Parte 3, o servidor MCP oferece a ferramenta read_diagram. A função inspeciona o XML do arquivo SVG, localiza a tag <metadata id="svg-creator-state">, decodifica o base64 e reconstrói o texto original da DSL com precisão absoluta. O assistente obtém o código fonte sem nenhuma perda de informação.
25. Alteração estruturada via patch_diagram
O método tradicional de edição por IA consiste em pedir ao modelo que reescreva o arquivo inteiro. Essa abordagem é perigosa: ao reescrever 60 linhas de código para alterar uma cor, o modelo pode esquecer uma conexão, alterar a ordem dos elementos ou cometer erros de digitação.
O ArchFlow introduziu a ferramenta patch_diagram (tools/archflow/patchTools.ts). Ela permite que a IA realize operações atômicas direcionadas através de um array de operações:
set: altera ou adiciona uma propriedade a um elemento existente (ex: mudar o tema parasupabase).rename: renomeia o identificador de um nó, propagando a renomeação automaticamente por todas as conexões dependentes.add: insere um novo elemento ou conexão em ponto seguro do texto.remove: remove um elemento e desconecta suas ligações.
Se qualquer operação criar uma inconsistência sintática ou romper a integridade do grafo, o patch inteiro é rejeitado e nenhuma modificação é gravada.
26. O ciclo de inspeção e diff semântico
Para garantir que as modificações foram compreendidas, o ecossistema inclui:
find_elements: permite ao assistente localizar nós pelo rótulo sem precisar ler o arquivo todo, identificando o id correto antes de aplicar o patch.diff_diagrams: compara o texto antes e depois da modificação, emitindo um relatório semântico legível:+nó adicionado-nó removido~propriedade alterada
O diagrama acima fecha o círculo completo da arquitetura. O assistente parte do arquivo SVG existente no disco, extrai o texto com read_diagram, descobre os nós alvo com find_elements, aplica alterações controladas com patch_diagram, confere as alterações com diff_diagrams e regrava o novo SVG pelo render_diagram. A seta pontilhada sinaliza a retrocompatibilidade permanente do formato.
Parte 8: Depois da primeira versão
27. Por que o ArchFlow continuou crescendo
A versão 0.1.0 saiu em 24 de outubro de 2026 e já fazia o essencial: texto vira diagrama animado, a CLI gera o arquivo sem abrir janela e o servidor MCP deixa uma IA editar o desenho. Em quatro dias, o repositório recebeu mais de noventa commits, quase todos de 28 de outubro, e eles mexem em quatro frentes: leitura e escrita de Mermaid, blocos na timeline de sequência, roteamento de conexões em volta de grupos e um elemento novo, o gitgraph. No momento em que esta aula foi atualizada, essas mudanças estavam na seção “Não lançado” do changelog.
Todas elas respondem a uma mesma pergunta: o que impede alguém de adotar o ArchFlow amanhã? A resposta mais honesta é que as pessoas já têm diagramas em Mermaid espalhados por READMEs e wikis, e que alguns assuntos, como o histórico de um repositório Git, ou um fluxo com alt e loop, pedem um elemento próprio em vez de caixas e setas. Quando você ler as próximas seções, repare que nenhuma delas troca a arquitetura das partes anteriores. Todas reaproveitam o mesmo parser em TypeScript puro, o mesmo pipeline de exportação e o mesmo servidor MCP.
28. Mermaid: importar e exportar sem perder o controle do que se perdeu
O Mermaid é a linguagem de diagramas em texto que o GitHub e o Obsidian já desenham sozinhos. O ArchFlow passou a ler o texto dele e a escrever de volta. O conversor mora em src/utils/mermaid/ e, como o parser da DSL, é TypeScript sem nenhuma API de navegador. Por isso o mesmo código atende o diálogo do aplicativo, a CLI e o servidor MCP.
O fluxo começa por uma detecção. O módulo detect.ts lê o cabeçalho do texto (flowchart, sequenceDiagram, stateDiagram, erDiagram, classDiagram, mindmap ou gitGraph) e entrega o texto ao leitor correspondente. Tipos que o conversor não conhece, como gantt e journey, são recusados com uma mensagem que nomeia o tipo, em vez de gerar um desenho enganoso.
O ponto de design mais importante está na seta “Perdas”. Converter entre duas linguagens nunca é perfeito: o Mermaid tem dezenas de formas de nó que o ArchFlow não desenha igual, e o ArchFlow tem coisas, como pacotes animados, que o Mermaid não expressa. Em vez de esconder isso, a ferramenta mermaid_compat devolve uma tabela linha a linha com o que ficou aproximado, o que foi ignorado e os avisos. Na exportação acontece o mesmo: o que o Mermaid não consegue representar sai listado num comentário %% no fim do arquivo, para quem for ler depois saber o que ficou de fora.
Como saber que o conversor é bom e continua bom? A spec de compatibilidade usa os exemplos da documentação oficial do Mermaid (versão 12, licença MIT) como corpus. Na primeira medição eram 263 blocos de código. Deles, 258 convertiam e 5 eram recusados, mas 101 geravam avisos, e alguns avisos escondiam perda de estrutura: um bloco alt achatado em texto, por exemplo, contava como “converte”. O objetivo definido foi zero recusas entre os tipos suportados e nenhuma perda silenciosa. O corpus virou um teste do repositório, com uma linha de base por arquivo (baseline.json) que guarda quantos elementos e conexões cada exemplo produz e quantos avisos gera. Se uma mudança piora um exemplo específico, o teste falha dizendo qual arquivo piorou. É a mesma ideia de um teste de regressão visual, só que para um conversor de texto.
29. Timeline com blocos: o fluxo de verdade tem condição e repetição
A timeline do ArchFlow é o diagrama de sequência: participantes em colunas e mensagens em linhas. Na versão 0.1.0 ela só desenhava mensagens em fila. Um fluxo real tem desvios (“se as credenciais forem válidas…”) e repetições (“a cada 5 minutos…”), então ela ganhou blocos.
login = timeline "Login"
participante u "Usuário" tipo=ator
participante app "App" tipo=fronteira
participante api "API" tipo=controle
numerar
u -> app: abre a tela
app ->+ api: POST /login
alt "credenciais válidas"
api --> app: 200 token
else "credenciais inválidas"
api --> app: 401
end
loop "a cada 5 min"
app -> api: renovar sessão
end
nota sobre u, app: o token nunca vai ao navegador
Os blocos disponíveis são loop, alt (com else), opt, par, critical, break e rect. Também entraram notas, criar e destruir para participantes que nascem e morrem no meio do fluxo, tipos de participante com tipo= (ator, fronteira, controle, banco), numerar para numerar as mensagens e ativações com ->+. A animação respeita a estrutura: ao rodar, o ArchFlow acende a moldura do bloco e o ramo ativo no trecho em que ele acontece, e a animação respeita a preferência de movimento reduzido do sistema.
Tecnicamente, a mudança segue um padrão que vai se repetir no gitgraph: o dado do elemento é uma lista de itens que preserva a ordem do texto, e o layout é uma função pura que calcula a altura de cada linha a partir do texto e posiciona molduras e pontos de divisão. Como o layout não depende de pixels do navegador, ele pode ser testado em Node.
30. Roteamento com desvio: a linha que contorna o grupo
Quando um diagrama tem grupos, uma conexão reta entre dois elementos de grupos diferentes pode atravessar um terceiro grupo que não tem nada a ver com ela. Visualmente isso sugere que a conexão passa por dentro do grupo. A solução está em src/utils/detour.ts.
A regra é simples de enunciar. Se o segmento entre as duas pontas cruza a caixa de um grupo que não contém nenhuma delas, a conexão vira um cotovelo de 90 graus que contorna o grupo com uma folga de 24 pixels (DETOUR_GAP). Para decidir se o segmento cruza a caixa, o código usa o recorte de Liang-Barsky, um algoritmo clássico de geometria que testa a interseção de um segmento com um retângulo sem precisar resolver equações de reta. Conexões que já não cruzam nada ficam exatamente como estavam.
Três decisões deixam o comportamento previsível para quem edita. O desvio acompanha o grupo quando você o arrasta, porque ele é recalculado a partir da posição atual. Uma edição manual da conexão encerra o desvio automático, já que a sua intenção passa a valer mais que a regra. E há uma opção no texto, desviar elementos, que estende o mesmo cálculo a elementos comuns, não só a grupos. Essa opção fica desligada por padrão porque desviar de tudo pode deixar o desenho cheio de cotovelos.
31. Gitgraph: o histórico de um repositório como animação
O elemento novo mais ambicioso é o gitgraph. O Mermaid já desenha um gitGraph, mas só mostra o resultado final de commits, branches e merges. O ArchFlow quis ensinar o fluxo: o HEAD andando, o commit nascendo, o merge convergindo, o conflito parando a operação até alguém resolver. A spec cobre commits, branches, merge (com avanço rápido, sem avanço e com squash), rebase (simples e interativo), cherry-pick, reset, revert, amend, tags, stash, remotos com push, fetch e pull, pull requests e bisect.
Veja como é uma descrição de um fluxo com pull request:
hist = gitgraph "Fluxo com pull request" direção=LR legenda=sim
remoto origin
commit "Início" id=a1
empurrar
ramo feature
commit "Nova tela" id=f1
empurrar feature
pr 42 de=feature para=main "Nova tela"
trocar main
mesclarpr 42 modo=esmagar
etiquetar v2.0 "Release da nova tela"
A decisão central é a mesma da timeline: o elemento guarda uma lista de itens em ordem e o estado do repositório é calculado, nunca guardado. A função stateAt(itens, n) devolve o estado depois de n itens, com a branch atual, as pontas de cada branch, os commits vivos e os abandonados. Isso é o que torna o player simples: avançar um passo é pedir o estado de n + 1, e voltar um passo é pedir n - 1. Commits abandonados por um rebase ou reset continuam no desenho, esmaecidos, do mesmo jeito que o git reflog ainda guarda commits que nenhuma branch alcança.
Há um detalhe de engenharia que vale entender. No canvas do aplicativo, o gitgraph se anima com JavaScript, quadro a quadro. Mas o SVG exportado precisa funcionar fora do aplicativo, em um README ou no Obsidian, onde não existe JavaScript. Por isso existe o (src/utils/exportMode.ts), com três valores: none para o uso normal, still para o desenho completo e parado (o PNG) e animated para um desenho em que a animação inteira foi reescrita em CSS. Quem exporta escolhe o modo, e o elemento se desenha de acordo.
Duas escolhas de escopo deixam a ferramenta honesta. A simulação descreve um histórico, não executa git: ler um repositório de verdade com git log ficou como trabalho futuro. E o gitGraph do Mermaid é importado e exportado, mas o que o Mermaid não tem (rebase, conflito, stash) sai aproximado, com aviso, na exportação.
32. O que mudou no servidor MCP
Como a lógica nova vive em TypeScript puro, o servidor MCP herdou quase tudo sem esforço. As ferramentas que entraram ou mudaram são estas:
import_mermaid: converte um texto Mermaid e devolve o texto ArchFlow com avisos por linha.mermaid_compat: mostra a tabela de compatibilidade antes de importar, para a IA decidir se vale a pena.export_mermaid: escreve o diagrama como Mermaid. O parâmetroasforçaflowchart,sequenceougitgraph; sem ele, a escolha depende do que há no diagrama.explain_gitgraph: descreve em palavras o estado do repositório depois de n passos, o que permite a uma IA conferir o que a animação mostra.render_diagram: passou a aceitar um texto Mermaid direto, convertendo antes de renderizar.
Essa lista também mostra o princípio que as partes 6 e 7 já tinham explicado: operações que só mexem em texto continuam leves, e só render_diagram abre o navegador.
A CLI ganhou o equivalente em dois comandos, archflow mermaid import e archflow mermaid export, e o render e o check também aceitam um arquivo .mmd.
Parte 9: Casos de borda e boas práticas
33. Fundo transparente versus fundo sólido
Por padrão, o ArchFlow exporta SVGs com fundo transparente. Para garantir legibilidade tanto no tema claro quanto no escuro do GitHub e do Obsidian, os cartões utilizam bases com preenchimento opaco escuro, e os títulos de nós recebem pequenas pílulas de contraste.
Entretanto, há dois cuidados indispensáveis:
- A opção
preenchimento=ghost: remove o fundo dos cartões, deixando apenas os contornos. Em fundos escuros ela funciona bem, mas em páginas de fundo claro o texto claro some. Eviteghostem documentação pública compartilhada. - Tamanho de WebP transparente: o codec WebP comprime muito melhor fundos sólidos do que transparências complexas com sombras suaves. Um diagrama que ocupa 480 KB com
--bg darkpode chegar a 3,2 MB com fundo transparente. Se o seu destino for um blog ou site de documentação com tema definido, prefira sempre declarar--bg darkou--bg light.
34. Otimização de tokens de imagem em pré-visualizações
Quando o servidor MCP executa render_diagram com a opção preview: true, ele precisa devolver uma imagem para o modelo de linguagem avaliar o resultado.
Se o servidor devolvesse um PNG em alta definição (escala 2 ou 3), a imagem consumiria de 3.000 a 6.000 tokens da janela de contexto da IA a cada chamada. O ArchFlow calibrou a constante interna PREVIEW_SCALE para exatamente 0.6. Nessa escala, o consumo cai para cerca de um terço dos pixels, o texto continua perfeitamente legível para a visão computacional do modelo, e a conversa não estoura o orçamento de contexto.
35. Largura máxima e a densidade recomendada
Uma das falhas mais comuns em diagramas de arquitetura é o crescimento horizontal descontrolado. Quando um diagrama atinge mais de 2.000 pixels de largura e é inserido em uma nota do Obsidian (cujo painel padrão costuma ter entre 700 e 900 pixels de largura), o visualizador encolhe a imagem inteira. O texto de 12 pixels passa a ter 4 pixels e fica completamente ilegível.
A ferramenta check_diagram emite um aviso sempre que a largura total ultrapassa 1.800 pixels. A boa prática recomendada é adotar direção TB (Top to Bottom) para árvores e hierarquias, limitar diagramas principais a no máximo 25 elementos e dividir fluxos extensos em uma visão panorâmica e subdiagramas com zoom em componentes específicos.
Parte 10: Prática e consolidação
36. Exercícios práticos
-
Validação local sem navegador: Abra o terminal na raiz do repositório do ArchFlow e crie um arquivo temporário de teste:
echo 'diagrama "Teste"\na -> b "Chamada gRPC"' > teste.diagram pnpm archflow check teste.diagramObserve o tempo de resposta inferior a um segundo e o relatório de nós e arestas emitido diretamente pelo Node.
-
Renderização com geração combinada: Gere simultaneamente o SVG animado, o PNG estático e o WebP animado com fundo escuro:
pnpm archflow render teste.diagram -o assets/teste.svg --png --webp --bg darkAbra os três arquivos e compare o comportamento: o SVG tem animação infinita nativa, o PNG é um instantâneo estático para impressão, e o WebP roda em loop contínuo.
-
Inspeção do estado embutido: Inspecione as últimas linhas do arquivo SVG recém-gerado com o comando:
tail -n 10 assets/teste.svgIdentifique a tag
<metadata id="svg-creator-state">e verifique como ela encapsula o estado serializado. -
Mermaid ida e volta: Importe um exemplo de Mermaid e exporte de volta, olhando o que o relatório de compatibilidade diz:
pnpm archflow mermaid import examples/mermaid/fluxo-ci.mmd -o fluxo-ci.diagram pnpm archflow mermaid export fluxo-ci.diagram -o volta.mmdCompare
volta.mmdcom o original e leia o comentário%%do fim, se houver. Depois peça ao assistente conectado ao MCP para chamarmermaid_compatno mesmo arquivo e compare os avisos com o que aparece no desenho. -
Gitgraph passo a passo: Renderize o exemplo de pull request e abra o SVG no navegador:
pnpm archflow render examples/git-fluxo-pr.diagram -o assets/git-fluxo-pr.svgObserve a ordem em que os commits nascem e onde a etiqueta
v2.0aparece, depois reordene duas linhas do texto e veja o histórico mudar.
37. Glossário dos termos técnicos
- AST (Abstract Syntax Tree): árvore sintática abstrata gerada pelo compilador que representa a estrutura lógica do diagrama antes de calcular posições ou cores.
archflowBridge: módulo injetado no aplicativo web exposto no escopo global através dewindow.__archflow, permitindo controle programático da interface gráfica pelo Playwright.- Headless Browser: instância de um navegador web (como o Chromium) executada em segundo plano, sem janela gráfica visível, utilizada para renderização automatizada.
html-to-image: biblioteca que percorre a árvore DOM de um nó HTML, clona seus nós e computa estilos CSS para serializá-lo em formato vetorial SVG.- Corpus oficial: conjunto de exemplos da documentação do Mermaid usado como teste de qualidade do conversor, com uma linha de base por arquivo para detectar regressões.
- Desvio (detour): cotovelo de 90 graus que uma conexão faz para contornar um grupo que ela atravessaria em linha reta, com folga de 24 pixels.
- Gitgraph: elemento do ArchFlow que descreve o histórico de um repositório Git como uma lista de itens e o anima passo a passo.
- JSON-RPC 2.0: protocolo leve de chamada de procedimento remoto baseado em mensagens JSON, utilizado como base estrutural de comunicação do MCP.
- Modo de exportação: valor (
none,stillouanimated) que decide como um elemento animado por JavaScript se desenha na hora de exportar, já que o SVG final só pode animar com CSS. - Lazy Session: estratégia de inicialização diferida na qual recursos computacionalmente pesados (como o navegador headless) só são alocados no instante da primeira demanda real.
- MCP (Model Context Protocol): protocolo padronizado que conecta agentes de inteligência artificial a ferramentas locais de forma segura e extensível.
- stateAt: função que calcula o estado de um repositório depois de n itens do gitgraph, sem guardar esse estado em lugar nenhum.
- SMIL (Synchronized Multimedia Integration Language): especificação XML interna do padrão SVG responsável pelas animações dos pacotes correndo pelas arestas através da tag
<animateMotion>. - XYFlow: biblioteca moderna de construção de grafos e nós interativos para React utilizada como motor de canvas visual do ArchFlow.
38. Fontes e referências
- Repositório local e código fonte:
/Users/jeangrijp/Documents/Github/archflow(consultado em outubro de 2026). - Documentação da CLI e MCP:
docs/pt/cli-mcp.mdedocs/pt/referencia-formato.md. - Especificações do motor de captura WebP:
specs/features/animated_webp.mdetools/archflow/animate.ts. - Especificações dos recursos novos:
specs/features/mermaid_compat.md,specs/features/timeline_blocks_notes.md,specs/features/edge_routing_groups.mdespecs/features/gitgraph_elements.md, além doCHANGELOG.pt.md(seção “Não lançado”, consultada em 29 de outubro de 2026). - Especificação oficial do Model Context Protocol: modelcontextprotocol.io (consultado em outubro de 2026).
- Documentação oficial do Playwright Core: playwright.dev (consultado em outubro de 2026).