> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Grafo interativo (@graphview)

> Renderiza um grafo interativo estilo Obsidian — force-directed, arrastável, com física — em um arquivo HTML autocontido aberto no navegador. Diferente do @diagram (imagem estática), o resultado fica vivo: você arrasta os nós, dá zoom, filtra por tipo e clica para focar. Motor de física em JavaScript embutido, sem CDN, sem rede e sem API key.

O tool **`@graphview`** renderiza um **grafo interativo estilo Obsidian** — force-directed, com física — em um **HTML autocontido** que abre no navegador. Você **arrasta** os nós e o resto reage, dá **zoom/pan**, **busca**, **filtra por tipo** e **clica para focar** numa região.

Diferente do [`@diagram`](/features/diagram), que produz uma **imagem estática** (PNG/SVG), aqui a saída é um **grafo vivo**: o motor de física é **JavaScript puro rodando num `<canvas>`**, embutido no binário via `go:embed`. **Sem CDN, sem rede e sem API key** — funciona offline já no primeiro uso, o mesmo DNA self-contained do Graphviz embedado, do TTS/STT e das notas de voz puro-Go.

<Tip>
  Para um **diagrama determinístico** de arquitetura/dependências como **imagem** (PNG/SVG), use o [`@diagram`](/features/diagram). Para **explorar relações de forma interativa** — mapear a conversa, conceitos, arquivos, tópicos — e poder **arrastar e focar**, use o `@graphview`.
</Tip>

***

## Uso

```text theme={"system"}
<tool_call name="@graphview" args='{"title":"Nossa conversa","nodes":[{"id":"cli","label":"ChatCLI","kind":"project"},{"id":"oauth","label":"OAuth login","kind":"topic"},{"id":"token","label":"Token exchange","kind":"topic"}],"edges":[{"source":"cli","target":"oauth"},{"source":"oauth","target":"token","weight":2}]}' />
<tool_call name="@graphview" args='{"source":"knowledge"}' />
<tool_call name="@graphview" args='{"source":"conversation"}' />
```

Na prática você **não escreve isso à mão**: basta pedir em linguagem natural — *"faça um grafo interativo do que a gente discutiu"* — e o modelo monta os nós e arestas e chama o `@graphview` sozinho. Funciona em **agent**, **coder** e **chat** (veja [Disponibilidade](#disponibilidade)).

***

## Fontes de dados (`source`)

O argumento `source` decide de onde vêm os nós e arestas:

| Fonte              | O que renderiza                                                                                                                                                                                                                                              |
| :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `json` *(default)* | Os nós/arestas que **você (o modelo) fornece** em `nodes`/`edges`. É como "mapear a conversa": o modelo já tem o contexto e emite o grafo semântico. Também aceita um arquivo JSON via `file`.                                                               |
| `knowledge`        | O **grafo de conhecimento interno** (memória, skills, tópicos, projetos, tags) — o mesmo substrato do comando [`/graph`](/features/knowledge-base), mas interativo.                                                                                          |
| `conversation`     | **Tudo da sessão atual** num único grafo: o fio da conversa (turnos por papel) + as **tools** invocadas + **todos os contextos anexados** com `/context` (incluindo seus arquivos) + as **knowledge bases** anexadas — tudo pendurado num nó-raiz da sessão. |

<Tip>
  Quer um grafo **temático/semântico** do que conversaram? Deixe o modelo extrair as entidades e relações e passar como `nodes`/`edges` (`source=json`). Quer um grafo **estrutural** do que está na sessão e anexado? Use `source=conversation`.
</Tip>

***

## Argumentos

| Argumento | Descrição                                                                                                                                               | Default     |
| :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------- |
| `source`  | `json` \| `knowledge` \| `conversation`                                                                                                                 | `json`      |
| `nodes`   | `source=json`: array de `{id, label, kind?, summary?, weight?}`. O `kind` define a **cor** do nó (ex.: `topic`, `project`, `file`, `person`, `entity`). | *(json)*    |
| `edges`   | `source=json`: array de `{source, target, weight?}` entre ids de nós. O `weight` engrossa a aresta.                                                     | *(json)*    |
| `file`    | Caminho para um arquivo JSON `{"nodes":[...],"edges":[...]}` — para grafos grandes, em vez de inline.                                                   | —           |
| `title`   | Título mostrado na barra de ferramentas.                                                                                                                | *("Grafo")* |
| `theme`   | `dark` \| `light`                                                                                                                                       | `dark`      |
| `output`  | Caminho do `.html` a gravar. Omitido, grava num arquivo temporário e retorna o caminho.                                                                 | *(temp)*    |
| `open`    | Abre o resultado no navegador padrão.                                                                                                                   | `true`      |

Aliases tolerados na entrada (caso o modelo varie a forma): nó aceita `title`/`name` como label e `type`/`group` como kind; aresta aceita `from`/`to` como source/target. Nós duplicados são deduplicados por `id` e arestas pendentes/auto-laços são descartadas, então o grafo sai sempre bem-formado.

***

## A experiência interativa

O HTML gerado é uma aplicação completa de visualização — tudo client-side, sem rede:

* **Arrastar + física** — arraste qualquer nó; a simulação force-directed (repulsão + molas + gravidade + amortecimento) reacomoda o resto. Duplo-clique **fixa/solta** um nó.
* **Zoom & pan** — scroll/trackpad para zoom; arraste o fundo para mover. Em **touch**, **pinça** para zoom e dois dedos para pan.
* **Clicar para focar (expandir)** — clique/toque num **nó** para selecioná-lo: a vizinhança é destacada, o resto escurece, abre um **painel de detalhe** (tipo, título, resumo, conexões) e a câmera **desliza e dá zoom** para enquadrar o nó e seus vizinhos. Clique numa **aresta** para destacá-la e ver o peso. Clique no vazio para limpar.
* **Busca** — a caixa de busca destaca os nós que casam e esmaece o resto.
* **Filtro por tipo** — clique num tipo na **legenda** para mostrar/ocultar aquele `kind`. Cada tipo tem cor própria; o tamanho do nó reflete grau + peso.
* **Tema** — alterna **escuro/claro** pelo botão `◐`.
* **Fit / Reheat** — `Fit` reenquadra o grafo (e retoma o auto-enquadramento); `Reheat` reaquece a simulação.

### Responsivo

A página é **responsiva de verdade**: o `<canvas>` preenche a janela inteira e **reenquadra ao redimensionar/maximizar**. As interações usam **Pointer Events** (mouse, trackpad e toque unificados), e em telas estreitas o layout reflui — a barra quebra em linhas, a busca expande e a legenda vira uma faixa rolável embaixo. Funciona no desktop e no celular/tablet.

***

## Disponibilidade

O `@graphview` funciona quando solicitado nos três modos:

* **Agent / Coder** — entra automaticamente no catálogo de tools; o modelo o invoca quando você pede uma visualização.
* **Chat** — o chat é **tool-less por design**, então o `@graphview` é uma **exceção sancionada** (a terceira, junto de `ask_user` e da consulta read-only de knowledge): quando você pede um grafo, o modelo pode chamá-lo **uma vez** naquele turno. É controlada por `CHATCLI_CHAT_GRAPHVIEW` (**ligada por padrão**) e alternável em runtime com `/config chat graphview on|off`.

***

## Configuração

```text theme={"system"}
/config graphview              # panorama: tema, auto-open e a exceção do chat
/config chat graphview on|off  # liga/desliga a renderização de grafo no chat
```

Variáveis de ambiente (process-wide; lidas a cada chamada/turno):

| Variável                  | Valores           | Default | Efeito                                       |
| :------------------------ | :---------------- | :------ | :------------------------------------------- |
| `CHATCLI_GRAPHVIEW_THEME` | `dark` \| `light` | `dark`  | Tema padrão do grafo.                        |
| `CHATCLI_GRAPHVIEW_OPEN`  | `true` \| `false` | `true`  | Se abre o HTML no navegador após renderizar. |
| `CHATCLI_CHAT_GRAPHVIEW`  | `true` \| `false` | `true`  | Habilita a exceção do `@graphview` no chat.  |

O argumento `open` por chamada sobrepõe `CHATCLI_GRAPHVIEW_OPEN`. A abertura do navegador é **gated por TTY**: em execução sem terminal (gateway/daemon ou saída em pipe) o arquivo é gravado mas **não** abre uma janela.

***

## Saída

O tool grava o `.html` (em `output` ou num arquivo temporário), abre no navegador quando há terminal e retorna um resumo:

```text theme={"system"}
Grafo interativo renderizado → /tmp/chatcli-graph-1234.html (12 nós, 18 arestas)
Aberto no navegador padrão. Arraste os nós, scroll para zoom, arraste o fundo para mover, clique num tipo na legenda para filtrar.
```

***

## Notas

* **É read-only** do ponto de vista do workspace: o tool só **visualiza** dados num HTML novo e abre um viewer — não altera seus arquivos —, então **não pede confirmação de segurança** no agent. Não é concurrency-safe (grava um arquivo e pode abrir o navegador), então não entra em lotes paralelos.
* **Autocontido de verdade**: o motor de física é JavaScript embutido num `<canvas>`, sem CDN, sem rede e sem API key. O `.html` funciona offline para sempre.
* **Teto de nós**: a simulação é O(n²) por quadro, então o grafo é limitado a alguns milhares de nós para manter o arrasto fluido; acima disso, reduza o conjunto ou renderize um subgrafo.

<Tip>
  Combine com o [`@context`/`@knowledge`](/features/knowledge-base): anexe uma base de conhecimento do projeto e peça `source=conversation` — o grafo mostra a conversa, as tools usadas e **a base anexada com seus arquivos** num só lugar. Para um diagrama estático de arquitetura, use o [`@diagram`](/features/diagram).
</Tip>
