Communitygithub.com

mildastudio/milda

Lire, écrire, réviser et corriger les systèmes de design Milda - fichiers `.milda` - et raisonner dans le paradigme Milda (jetons en couches, groupes de contexte, archétypes, parties neutres vis-à-vis de la plateforme, états issus de comportements). À utiliser chaque fois que l'utilisateur mentionne Milda, Milda Studio, le playground Milda ou un fichier `.milda`, demande de créer ou modifier des jetons ou des composants d'un système de design dans Milda, ou souhaite traduire du CSS, Figma ou une bibliothèque de composants existante en Milda.

Qu'est-ce que milda ?

Cette compétence permet aux agents IA de manipuler des fichiers `.milda`, le format source unique du compilateur de systèmes de design Milda. Contrairement aux approches traditionnelles où les tokens, composants et documentation sont dispersés, un fichier `.milda` contient l'intégralité du système : foundations, composants, règles d'usage, documentation et assets. Les artefacts de livraison (packages React, bibliothèques Figma, sites de documentation) sont générés à partir de ce fichier unique, et ne doivent jamais être modifiés directement. La compétence applique un processus itératif rigoureux : après chaque modification, l'agent exécute `milda-check --strict` qui valide les diagnostics (aucune erreur ni avertissement n'est toléré) avant de présenter le résultat à l'utilisateur. Elle suit dix règles fondamentales de modélisation Milda : le système est la source unique, les valeurs sont nommées par des jetons et organisées en couches (Base puis Sémantique), les contextes (mode sombre, densité, marque) sont gérés par des groupes de contexte, les états proviennent des comportements des archétypes (jamais de pseudo-classes CSS), et les contraintes d'interface sont exprimées dans `props`. La compétence fournit également une table de conversion complète entre CSS/React et la syntaxe Milda (par exemple `background` → `fill`, `border-radius` → `corner`, `@media (prefers-color-scheme: dark)` → `context-group ColorScheme` + `alias by ColorScheme`). Elle s'applique aux agents travaillant avec Milda Studio, le playground https://play.milda.dev, et peut tirer parti d'un serveur MCP pour interroger des systèmes de design déjà publiés.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait milda ?

Milda est un compilateur avec interface graphique pour les systèmes de design. Un fichier .milda est le système de design : foundations (jetons), composants, règles d'usage, documentation et assets. Les packages React, les bibliothèques Figma, les sites de documentation et les fichiers lisibles par agent sont générés à partir de ce fichier. Vous ne modifiez jamais une sortie ; vous modifiez le fichier et régénérez.

Cette compétence cible la surface de langage 0.10 avec le prélude 0.0.2. Chaque fichier que vous écrivez commence par cet en-tête.

La boucle : écrire, vérifier, corriger

Ne dites jamais à l'utilisateur qu'un fichier .milda est valide tant que le lecteur n'est pas d'accord. Après chaque modification, exécutez :

npx -y -p @mildastudio/milda-lsp milda-check --strict chemin/vers/systeme/

Donnez-lui le répertoire, ou tous les fichiers du système ensemble, car les jetons déclarés dans un fichier résolvent des références dans un autre. Il affiche chemin:ligne:col sévérité [code] message, les mêmes diagnostics que les extensions d'éditeur montrent, et il se termine avec un code non nul en cas d'erreur (ou, avec --strict, en cas d'avertissement). Corrigez ce qu'il signale et exécutez-le à nouveau jusqu'à ce qu'il affiche 0 errors, 0 warnings. Un avertissement n'est pas négligeable : unknown facet "background" skipped signifie que cette ligne n'a rien fait.

Pour montrer le résultat à l'utilisateur, le playground sur https://play.milda.dev rend un fichier collé en direct, sans compte.

Penser en Milda : dix règles

La plupart des erreurs viennent de l'écriture de CSS, d'un arbre DOM ou d'un composant React dans la syntaxe de Milda. Ces règles sont ce que la syntaxe existe pour exprimer.

  1. Le système est la source ; le code est une sortie. Tout ce qui est façonné par la plateforme est décidé au moment de la génération, donc un fichier ne contient jamais une propriété CSS, une balise, un nom d'événement d'un framework ou une pseudo-classe.
  2. Dites ce qu'est une chose, jamais de quoi elle est faite. Une partie a un kind neutre (container, text, input, icon, control, ...), jamais div ou button. Chaque cible choisit son propre élément.
  3. Une valeur a un nom, et le nom a une couche. Les composants ne peignent jamais avec des littéraux. Une facette pointe vers un jeton ; une couche Semantic alias une couche Base de littéraux. Un restylage est un changement des foundations.
  4. Le contexte est une dimension, pas une copie. Mode sombre, densité, marque : chacun est un context-group, et un jeton répond par contexte avec alias by Group { ... }. Une prop typée par un groupe de contexte (une variant) utilise le même mécanisme par instance.
  5. Un état vient d'un comportement. hovered, pressed, focus-visible, disabled, open, selected sont émis par les comportements de l'archétype. Stylisez-les avec state hovered { }, jamais avec quelque chose de spécifique à un pointeur ou une plateforme. La liste est fermée (reference/vocabulary.md), et le lecteur signale tout autre mot : state hover est rapporté avec l'orthographe qu'il voulait dire.
  6. Le contrat est l'identité. props et events sont ce contre quoi les consommateurs codent et ce que le versionnement différencie. Nommez-les pour leur sens (variant, checkedChange), pas pour une plateforme.
  7. Construisez à partir de ce qui existe. Commencez un composant à partir d'un archetype dans le prélude : il apporte la forme du contrat, les parties requises et les comportements (clavier, ARIA, focus). Composez des composants plus grands à partir de plus petits avec des parties instance.
  8. Chaque référence est par nom. Parties par chemin pointé (Header.Title), jetons par chemin (space.sm pour space/sm), composants par identifiant. Pas d'identifiants. Les commentaires (#) sont la seule chose qui ne survit pas à un aller-retour.
  9. Étendez à travers des points de couture, jamais en modifiant la sortie. Lorsque le vocabulaire ne peut pas dire quelque chose, utilisez un slot, une option par cible, ou en dernier recours un contenu foreign marqué avec sa cible. Ne suggérez jamais de modifier le code généré.
  10. Dites comment cela est censé être utilisé. Mettez les contraintes d'interface (required, required when, one-of) dans props, et les règles de composition (rule ... { never X within Y }) au niveau supérieur, chacune avec sa raison.

Un fichier, de haut en bas

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 "L'action principale." {
  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
  }
}

Ordre : en-tête, meta, context-groups, groups (sections de bibliothèque), foundations, types, components, rules, puis examples, assets, icons, docs. La partie racine est nommée d'après le composant ; les autres parties sont nommées par l'anatomie de l'archétype (label, icon, control, ...) ou par vous, imbriquées avec des chemins pointés.

Du CSS et React à Milda

Vous écririezMilda dit
<div>, <span>, <button>part X: container / text / la racine de l'archétype
backgroundfill
colorink
padding, padding-inline-startinset, inset.inline-start
marginrien : gap sur le parent, alignement, ou bleed
border, border-radiusborder <couleur> <épaisseur>, corner
box-shadow, outline (focus)elevation, ring
font-size + line-height, font-weighttext <typographie ou jeton de taille de police>, weight
display: flex; flex-direction: rowlayout { stack row }
justify-content, align-items, flex: 1distribute, align, size fill
position: absolutelayout { stack layers } + position overlay sur l'enfant
:hover, :focus-visible, :disabledstate hovered { }, state focus-visible { }, ...
.btn--secondary, [data-variant]when variant = Secondary { }
.card:hover .iconwhen ancestor Card hovered { } sur la partie icône
@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(...), uniquement à l'intérieur d'un jeton
color-mix(), calc()compute <jeton> in oklch { darken 10% }
prop onClickevents { click } + emits { click on activate }
{children}slot of content default sur la partie qui les contient
{cond && <X/>}present when <prop> sur la partie
z-index, text-align, box-sizingrien : ordre des parties, le conteneur, il y a une boîte

Facettes, états et conditions sur une partie

  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
    }
  }

La valeur d'une facette se résout d'abord comme un jeton ; un littéral nu n'est accepté que là où aucun jeton ne revendique le mot (opacity 50, inset 0). Préférez les jetons. when se base sur les props, state sur les états de comportement, et les deux se combinent.

Props, événements et contraintes

  archetype TextField

  props {
    label : string required "Ce que le champ demande. Aussi son nom accessible."
    value : string
    invalid : boolean = false
    error : string required when invalid "Affiché sous le contrôle lorsqu'il est invalide."
    size : enum(sm, md) = md
    tone : context Tone = Neutral
  }

  events {
    valueChange
  }

Types : string, number, boolean, enum(a, b), context <Group>, array<T>, vos propres types. Une chaîne de caractères en fin de ligne est la documentation de la prop. one-of a, b / any-of / exclusive contraignent des groupes de props.

Où regarder ensuite

  • reference/syntax.md : chaque instruction avec un exemple vérifié (jetons et valeurs, disposition, slots, instances, comportements, règles, documentation, assets, icônes).
  • reference/vocabulary.md : généré à partir du package de langage. Chaque type de jeton, kind de partie, facette, état, mot de disposition et fonction littérale que le lecteur accepte. En cas de doute sur un mot, regardez ici plutôt que de deviner.
  • reference/archetypes.md : généré à partir du prélude. Chaque archétype avec son contrat, son anatomie (quelles parties sont requises) et ses comportements.
  • examples/acme.milda : un système complet et propre pour copier des motifs.
  • La spécification normative : https://github.com/mildastudio/milda-lang/tree/main/spec (FORMAT.md pour ce qu'un fichier promet, GRAMMAR.ebnf pour la syntaxe, PRELUDE.md pour les archétypes).
  • Pour un système de design déjà publié, le serveur MCP Milda répond avec ses composants et jetons exacts ; voir https://milda.dev/mcp.

Avant de terminer

  • L'en-tête dit milda 0.10 et prelude 0.0.2.
  • Aucune couleur, longueur ou police littérale dans un composant ; chaque valeur est une référence de jeton.
  • Aucun mot de plateforme nulle part : pas de balises, propriétés CSS, pseudo-classes ou noms d'événements de framework.
  • Chaque composant commence par un archétype sauf s'il s'agit d'une pure composition d'instances.
  • milda-check --strict sur l'ensemble du système affiche 0 errors, 0 warnings.

Skills associés