Communitygithub.com

mildastudio/milda

Ler, escrever, revisar e corrigir sistemas de design Milda – arquivos `.milda` – e raciocinar no paradigma de Milda (tokens em camadas, grupos de contexto, arquétipos, partes neutras de plataforma, estados a partir de comportamentos). Use sempre que o usuário mencionar Milda, Milda Studio, o playground Milda ou um arquivo `.milda`, quando pedir para criar ou modificar tokens ou componentes de um sistema de design em Milda, ou quando quiser traduzir CSS, Figma ou uma biblioteca de componentes existente para Milda.

O que é milda?

A habilidade Milda capacita agentes de IA a trabalhar com o compilador/linguagem de sistemas de design Milda. O usuário fornece um arquivo `.milda`, que é a fonte única que define tokens, componentes, regras, documentação e assets. Desse arquivo, o Milda gera artefatos para diferentes plataformas: pacotes React, bibliotecas Figma, sites de documentação e arquivos legíveis por agentes. O agente nunca edita os artefatos gerados; ele altera o arquivo `.milda` e solicita a regeneração. A habilidade é útil porque impõe um paradigma rigoroso que evita armadilhas comuns de design systems. O desenvolvedor descreve **o que** um componente é (ex: `container`, `text`, `icon`) em termos neutros de plataforma, em vez de **como** ele é implementado (ex: `div`, `span`). Cores, espaçamentos e outros valores são referenciados por tokens organizados em camadas (Base e Semantic). Estados como `hovered`, `pressed` são derivados de comportamentos de arquétipos predefinidos. Contextos como tema claro/escuro são tratados como dimensões (`context-group`), não como cópias de componentes. A habilidade inclui um ciclo de feedback: após cada edição, o agente executa `milda-check --strict` e só finaliza quando o validador reporta zero erros e zero avisos. O agente usa dez regras fundamentais para pensar em Milda, uma tabela de equivalência de CSS/React para Milda, e referências a arquivos de especificação (sintaxe, vocabulário, arquétipos). A habilidade suporta as plataformas Claude Code, Cursor, Codex e similares, e é ativada automaticamente quando o usuário menciona Milda, arquivos `.milda`, ou pede para traduzir um design system existente para o formato Milda.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mildastudio/milda-skills/tree/main/skills/milda

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que milda faz?

Milda é um compilador com interface gráfica para sistemas de design. Um arquivo .milda é o sistema de design: fundamentos (tokens), componentes, regras de uso, documentação e assets. Pacotes React, bibliotecas Figma, sites de documentação e arquivos legíveis por agentes são gerados a partir dele. Você nunca edita uma saída; você altera o arquivo e regenera.

Esta habilidade tem como alvo a superfície de linguagem 0.10 com prelúdio 0.0.2. Cada arquivo que você escrever começa com esse cabeçalho.

O ciclo: escrever, verificar, corrigir

Nunca diga ao usuário que um arquivo .milda é válido até que o leitor confirme. Após cada edição, execute:

npx -y -p @mildastudio/milda-lsp milda-check --strict caminho/para/sistema/

Forneça o diretório, ou todos os arquivos do sistema juntos, porque tokens declarados em um arquivo resolvem referências em outro. Ele imprime caminho:linha:col severidade [código] mensagem, os mesmos diagnósticos que as extensões do editor mostram, e sai com código diferente de zero em caso de erro (ou, com --strict, qualquer aviso). Corrija o que ele reportar e execute novamente até que diga 0 erros, 0 avisos. Um aviso não é ruído: faceta desconhecida "background" ignorada significa que aquela linha não fez nada.

Para mostrar o resultado ao usuário, o playground em https://play.milda.dev renderiza um arquivo colado ao vivo, sem necessidade de conta.

Pensar em Milda: dez regras

A maioria dos erros vem de escrever CSS, uma árvore DOM ou um componente React na sintaxe de Milda. Estas regras são o que a sintaxe existe para expressar.

  1. O sistema é a fonte; o código é uma saída. Tudo que tem forma de plataforma é decidido no momento da geração, então um arquivo nunca contém uma propriedade CSS, uma tag, um nome de evento de um framework ou uma pseudo-classe.
  2. Diga o que uma coisa é, nunca do que ela é feita. Uma parte tem um tipo neutro (container, text, input, icon, control, ...), nunca div ou button. Cada destino escolhe seu próprio elemento.
  3. Um valor tem um nome, e o nome tem uma camada. Componentes nunca pintam com literais. Uma faceta aponta para um token; uma camada Semantic cria um alias para uma camada Base de literais. Uma reformulação é uma alteração nos fundamentos.
  4. Contexto é uma dimensão, não uma cópia. Modo escuro, densidade, marca: cada um é um context-group, e um token responde por contexto com alias by Group { ... }. Uma propriedade tipada por um grupo de contexto (uma variant) usa o mesmo mecanismo por instância.
  5. Um estado vem de um comportamento. hovered, pressed, focus-visible, disabled, open, selected são emitidos pelos comportamentos do arquétipo. Estilize-os com state hovered { }, nunca com algo específico de ponteiro ou plataforma. A lista é fechada (reference/vocabulary.md), e o leitor avisa sobre qualquer outra palavra: state hover é reportado com a grafia que ele pretendia.
  6. O contrato é a identidade. props e events são contra o que os consumidores programam e o que as diferenças de versionamento usam. Nomeie-os pelo significado (variant, checkedChange), não por uma plataforma.
  7. Construa a partir do que existe. Comece um componente a partir de um archetype no prelúdio: ele traz a forma do contrato, as partes necessárias e os comportamentos (teclado, ARIA, foco). Componha componentes maiores a partir de menores com partes instance.
  8. Toda referência é por nome. Partes por caminho pontuado (Header.Title), tokens por caminho (space.sm para space/sm), componentes por identificador. Sem IDs. Comentários (#) são a única coisa que não sobrevive a uma ida e volta.
  9. Estenda através de pontos de extensão, nunca remendando a saída. Quando o vocabulário não puder dizer algo, use um slot, uma opção por destino ou, como último recurso, conteúdo foreign marcado com seu destino. Nunca sugira editar código gerado.
  10. Diga como deve ser usado. Coloque restrições de interface (required, required when, one-of) em props, e regras de composição (rule ... { never X within Y }) no nível superior, cada uma com sua justificativa.

Um arquivo, de cima a baixo

milda 0.10
prelude 0.0.2

meta { name "Acme" }

context-group ColorScheme { Light Dark }

foundations {
  layer Base {
    token violet/600 : color = hex(7c3aed)
    token white : color = hex(ffffff)
    token gray/900 : color = hex(0f172a)
  }
  layer Semantic {
    token accent : color = alias by ColorScheme { default -> violet.600 }
    token on-accent : color = alias by ColorScheme { default -> white; Dark -> gray.900 }
    token space/sm : spacing = 8px
    token radius/sm : radius = 6px
  }
}

component Button "A ação primária." {
  archetype Button

  props {
    label : string = "Get started"
  }

  events {
    click
  }

  part Button: container {
    emits { click on activate }
    layout { stack row; gap space.sm; align center }
    fill accent
    ink on-accent
    corner radius.sm
    inset space.sm
    state focus-visible {
      ring accent
    }
  }

  part label: text {
    content bind label
  }
}

Ordem: cabeçalho, meta, context-groups, groups (seções da biblioteca), foundations, types, components, rules, depois examples, assets, icons, docs. A parte raiz recebe o nome do componente; outras partes são nomeadas pela anatomia do arquétipo (label, icon, control, ...) ou por você, aninhadas com caminhos pontuados.

De CSS e React para Milda

Você escreveriaMilda diz
<div>, <span>, <button>part X: container / text / a raiz do arquétipo
backgroundfill
colorink
padding, padding-inline-startinset, inset.inline-start
marginnada: gap no pai, alinhamento, ou bleed
border, border-radiusborder <color> <width>, corner
box-shadow, outline (foco)elevation, ring
font-size + line-height, font-weighttext <typography or font-size token>, weight
display: flex; flex-direction: rowlayout { stack row }
justify-content, align-items, flex: 1distribute, align, size fill
position: absolutelayout { stack layers } + position overlay no filho
:hover, :focus-visible, :disabledstate hovered { }, state focus-visible { }, ...
.btn--secondary, [data-variant]when variant = Secondary { }
.card:hover .iconwhen ancestor Card hovered { } na parte do ícone
@media (prefers-color-scheme: dark)context-group ColorScheme + alias by ColorScheme
--space-sm: 8px / var(--space-sm)token space/sm : spacing = 8px / space.sm
#7c3aed, oklch(...)hex(7c3aed), oklch(...), apenas dentro de um token
color-mix(), calc()compute <token> in oklch { darken 10% }
prop onClickevents { click } + emits { click on activate }
{children}slot of content default na parte que os contém
{cond && <X/>}present when <prop> na parte
z-index, text-align, box-sizingnada: ordem das partes, o contêiner, existe uma caixa

Facetas, estados e condições em uma parte

  part Panel: container {
    layout { stack column; gap space.sm; size fill fit }
    fill surface
    ink text
    border line hairline
    corner radius.sm
    inset space.sm space.md
    when tone = danger {
      border danger hairline
    }
    state hovered {
      fill surface-raised
    }
    state hovered when tone = danger {
      fill danger-subtle
    }
  }

O valor de uma faceta resolve como um token primeiro; um literal simples é aceito apenas onde nenhum token reivindica a palavra (opacity 50, inset 0). Prefira tokens. when chaveia em props, state em estados de comportamento, e os dois se combinam.

Props, eventos e restrições

  archetype TextField

  props {
    label : string required "O que o campo pede. Também seu nome acessível."
    value : string
    invalid : boolean = false
    error : string required when invalid "Mostrado abaixo do controle enquanto inválido."
    size : enum(sm, md) = md
    tone : context Tone = Neutral
  }

  events {
    valueChange
  }

Tipos: string, number, boolean, enum(a, b), context <Group>, array<T>, seus próprios types. Uma string ao final é a documentação da prop. one-of a, b / any-of / exclusive restringem grupos de props.

Onde consultar a seguir

  • reference/syntax.md: cada declaração com um exemplo verificado (tokens e valores, layout, slots, instâncias, comportamentos, regras, documentação, assets, ícones).
  • reference/vocabulary.md: gerado a partir do pacote da linguagem. Cada tipo de token, tipo de parte, faceta, estado, palavra de layout e função literal que o leitor aceita. Em caso de dúvida sobre uma palavra, consulte aqui em vez de adivinhar.
  • reference/archetypes.md: gerado a partir do prelúdio. Cada arquétipo com seu contrato, anatomia (quais partes são necessárias) e comportamentos.
  • examples/acme.milda: um sistema completo e limpo para copiar padrões.
  • A especificação normativa: https://github.com/mildastudio/milda-lang/tree/main/spec (FORMAT.md para o que um arquivo promete, GRAMMAR.ebnf para a sintaxe, PRELUDE.md para os arquétipos).
  • Para um sistema de design já publicado, o servidor MCP Milda responde com seus componentes e tokens exatos; veja https://milda.dev/mcp.

Antes de finalizar

  • O cabeçalho diz milda 0.10 e prelude 0.0.2.
  • Nenhum literal de cor, comprimento ou fonte em um componente; todo valor é uma referência a token.
  • Nenhuma palavra de plataforma em lugar algum: sem tags, propriedades CSS, pseudo-classes ou nomes de eventos de framework.
  • Todo componente começa a partir de um arquétipo, a menos que seja uma composição pura de instâncias.
  • milda-check --strict em todo o sistema imprime 0 erros, 0 avisos.

Habilidades Relacionadas