Vitral 0.2
IA

Agentes de código

Cada página deste site também é Markdown puro, e o conjunto todo cabe num arquivo só, para que um assistente leia a documentação em vez de adivinhá-la.

Um assistente que não leu a documentação escreve o que lembra de alguma outra biblioteca: classes utilitárias por cima dos componentes, uma folha de estilos brigando com o tema, imports de ícones que não existem. Nada disso é um problema difícil — é um problema de leitura. Por isso o build escreve este site duas vezes: uma como as páginas que você está vendo, e outra como Markdown, no formato que o llms.txt descreve.

O que é publicado

a cada build
/vitral/llms.txt         the index: every page, with a line on what it covers
/vitral/llms-full.txt    all of it in one file
/vitral/docs/theming.md  any page, with .md instead of the trailing slash
/vitral/components/select.md

llms.txt é o índice: os guias, cada componente e cada template, cada um com a linha que o descreve, apontando para o Markdown e não para a página. llms-full.txt é tudo, concatenado, para um modelo com contexto suficiente para comportá-lo. E qualquer página responde com .md no lugar da barra final, que é a coisa mais barata a entregar a um agente que só precisa de um componente.

O Markdown é gerado a partir da página renderizada, então traz a prosa, os títulos e as tabelas de API — que, por sua vez, são lidas do types.ts de cada componente em tempo de build. A página de um componente também recebe, no final, o código dos seus exemplos, porque no site eles ficam atrás de um botão, e um agente não tem como apertá-lo.

Aponte um agente para cá

Tudo cabe numa linha de prompt:

um prompt
Read https://vitralui.github.io/vitral/components/datagrid.md
and write me a table of invoices with sorting, filtering and paging.

Num projeto em que você trabalha todo dia, ponha as regras onde o agente as lê — AGENTS.md, CLAUDE.md, .cursor/rules, ou como quer que a sua ferramenta chame isso. Esta é a versão curta que vale colar, e ela trata das coisas que um modelo erra por hábito, e não por ignorância:

AGENTS.md
# Vitral

Docs: https://vitralui.github.io/vitral/llms.txt

- Import components from `@vitral/vue`: `import { Button, Select } from '@vitral/vue'`.
  In Nuxt they are global (`<VtButton>`) through `@vitral/nuxt`.
- Do not write utility classes and do not hand-write CSS to restyle a component.
  The look is tokens: `dt('button.background')`, a preset, or the `dt` prop.
- To change one instance's markup or classes, use pass-through (`pt`), not a wrapper.
- `unstyled` drops every class and keeps the behaviour and the ARIA.
- Icons are names resolved from `@vitral/icons`: `<Button icon="search" />`.
  Anything outside the base set has to be registered first.
- Fields are real controls: `<label for>`, `name` and `aria-describedby` reach
  them without extra props.

Por que essas regras

  • Tokens, não CSS. A aparência de cada componente são custom properties, que um preset define e a prop dt sobrescreve numa instância. Uma folha de estilos escrita ao lado funciona até o esquema de cores mudar.
  • Pass-through para a marcação. Todo elemento interno pode ser endereçado pelo nome, então um agente nunca precisa envolver um componente para alcançar o que há dentro dele.
  • Ícones são nomes registrados. Os componentes resolvem sozinhos o conjunto que usam; qualquer outro é um import nomeado, ou uma chamada a registerIcons. Um nome inventado vira uma classe, em silêncio.
  • A acessibilidade já está lá. Cada componente segue o seu padrão WAI-ARIA APG e é testado contra ele, então acrescentar atributos role e aria-* costuma quebrá-lo em vez de ajudar.

Mantendo tudo honesto

Nada aqui é escrito à mão, e essa é a ideia: o Markdown é o site, as tabelas de API são o código-fonte, e os dois são reconstruídos a cada push. Uma página que fica desatualizada fica desatualizada num lugar só.