Communitygithub.com

Milda (mildastudio/milda)

Milda設計システムの `.milda` ファイルの読み取り、書き込み、レビュー、修正を行い、Mildaのパラダイム(階層化トークン、コンテキストグループ、アーキタイプ、プラットフォーム中立のパーツ、振る舞いからの状態)で推論します。ユーザーがMilda、Milda Studio、Mildaプレイグラウンド、または `.milda` ファイルに言及したとき、あるいはMildaでデザインシステムのトークンやコンポーネントを作成・変更するよう依頼したとき、またはCSS、Figma、既存のコンポーネントライブラリをMildaに変換したいときに使用します。

milda) とは?

Mildaは、デザインシステム用のコンパイラ兼GUIツールです。`.milda` ファイル自体がデザインシステム全体(ファンデーション(トークン)、コンポーネント、使用ルール、ドキュメント、アセット)を表現し、Reactパッケージ、Figmaライブラリ、ドキュメントサイト、エージェント可読ファイルなどをそこから生成します。このスキルは、Mildaの言語仕様に従ってファイルを記述・検証し、プラットフォーム固有の記述(CSSプロパティやタグ、フレームワークのイベント名など)を一切使わず、純粋にMildaのパラダイムで設計意図を表現することを支援します。主なワークフローは「書く→チェック→修正」のループで、`milda-check --strict` コマンドでエラーや警告がゼロになるまで反復します。Mildaのプレイグラウンド (https://play.milda.dev) で結果を即座に視覚的に確認できます。本スキルは言語バージョン0.10、プレリュード0.0.2を対象とし、トークンは名前とレイヤーで管理、コンテキストグループによるバリアント、アーキタイプからのコンポーネント設計、ビヘイビア由来の状態管理など、10の基本ルールに従って記述します。また、CSSやReactからの変換対応表も提供し、既存のコードベースからの移行を容易にします。

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

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Milda

Mildaは、デザインシステムのためのGUI付きコンパイラです。.milda ファイルこそがデザインシステムです: ファンデーション(トークン)、コンポーネント、使用ルール、ドキュメント、アセット。Reactパッケージ、Figmaライブラリ、 ドキュメントサイト、エージェント可読ファイルはそこから生成されます。出力を編集することは決してありません。ファイルを変更して再生成します。

このスキルは、プレリュード 0.0.2 を伴う言語サーフェス 0.10 をターゲットにしています。あなたが作成するすべてのファイルは、そのヘッダーから始まります。

ループ:書く、チェックする、修正する

リーダーが同意するまで、.milda ファイルが有効であるとユーザーに伝えないでください。編集後は毎回、以下を実行してください:

npx -y -p @mildastudio/milda-lsp milda-check --strict path/to/system/

これにシステムのディレクトリ、またはシステムのすべてのファイルを一緒に渡します。なぜなら、あるファイルで宣言されたトークンが別のファイルの参照を解決するためです。path:line:col severity [code] message の形式で出力され、これはエディター拡張機能が表示するのと同じ診断メッセージです。エラーがあれば非ゼロで終了します(--strict の場合は、警告でも同様です)。報告された内容を修正し、0 errors, 0 warnings と表示されるまで再実行してください。警告は無視してはいけません:unknown facet "background" skipped は、その行が何も実行しなかったことを意味します。

ユーザーに結果を表示するには、https://play.milda.dev のプレイグラウンドでファイルを貼り付けてライブレンダリングできます。アカウントは不要です。

Mildaで考える:10のルール

ほとんどの間違いは、CSS、DOMツリー、ReactコンポーネントをMildaの構文で書こうとすることから生じます。これらのルールは、その構文が表現するために存在するものです。

  1. システムがソースであり、コードは出力です。 プラットフォームに関連するものはすべて生成時に決定されるため、ファイルにはCSSプロパティ、タグ、フレームワークのイベント名、擬似クラスは決して含まれません。
  2. 何が何でできているかではなく、何であるかを述べます。 パーツは中立的な種類(container、text、input、icon、control、...)を持ち、div や button を使うことはありません。各ターゲットは独自の要素を選択します。
  3. 値には名前があり、名前にはレイヤーがあります。 コンポーネントがリテラルで描画することはありません。ファセットはトークンを指します。SemanticレイヤーはリテラルのBaseレイヤーをエイリアスします。再スタイルはファンデーションの変更です。
  4. コンテキストはディメンションであり、コピーではありません。 ダークモード、密度、ブランド:それぞれが context-group であり、トークンはコンテキストごとに alias by Group { ... } で応答します。コンテキストグループによって型付けされるprop(variant)は、インスタンスごとに同じメカニズムを使用します。
  5. 状態はビヘイビアから生じます。 hovered、pressed、focus-visible、disabled、open、selected はアーキタイプのビヘイビアによって生成されます。state hovered { } でスタイル設定し、ポインターやプラットフォーム固有のものは決して使わないでください。リストは閉じており(reference/vocabulary.md)、リーダーは他の単語に対して警告を報告します:state hover は、意図されたスペルと共に報告されます。
  6. 契約がアイデンティティです。 props と events は、コンシューマーがコードで扱う対象であり、バージョン管理で差分をとる対象です。プラットフォームではなく、意味に基づいて名前を付けます(variant、checkedChange)。
  7. 既存のものから構築します。 プレリュードの archetype からコンポーネントを開始します:契約の形状、必要なパーツ、ビヘイビア(キーボード、ARIA、フォーカス)をもたらします。instance パーツを使って、より小さなコンポーネントからより大きなコンポーネントを構成します。
  8. すべての参照は名前で行います。 パーツはドット区切りパス(Header.Title)、トークンはパス(space.sm で space/sm)、コンポーネントは識別子で参照します。IDはありません。コメント(#)のみがラウンドトリップ後も保持されません。
  9. 継ぎ目を通じて拡張し、出力にパッチを当てることはしません。 語彙で表現できない場合は、slot、ターゲットごとのオプション、または最後の手段として、ターゲットでタグ付けされた foreign コンテンツを使用します。生成されたコードを編集することを提案しないでください。
  10. どのように使用されることを意図しているかを述べます。 インターフェース制約(required、required when、one-of)を props に、構成ルール(rule ... { never X within Y })をトップレベルに配置し、それぞれに理由を付けます。

ファイル:上から下まで

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 "主要なアクション。" {
  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
  }
}

順序:ヘッダー、meta、context-group、group(ライブラリセクション)、foundations、type、 component、rule、次に example、assets、icons、docs。ルートパーツはコンポーネントにちなんで名付けられます。他のパーツはアーキタイプの構造(label、icon、control、...)に従って、またはドット区切りパスで入れ子にして、あなたが名前を付けます。

CSSとReactからMildaへ

あなたが書くものMildaが言うこと
<div>, <span>, <button>part X: container / text / アーキタイプのルート
backgroundfill
colorink
padding, padding-inline-startinset, inset.inline-start
marginなし:親の gap、配置、または bleed
border, border-radiusborder <color> <width>, corner
box-shadow, outline (フォーカス)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
:hover, :focus-visible, :disabledstate hovered { }, state focus-visible { }, ...
.btn--secondary, [data-variant]when variant = Secondary { }
.card:hover .iconアイコンパーツに when ancestor Card hovered { }
@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(...)、トークン内のみ
color-mix(), calc()compute <token> in oklch { darken 10% }
onClick プロパティevents { click } + emits { click on activate }
{children}それらを保持するパーツに slot of content default
{cond && <X/>}パーツに present when <prop>
z-index, text-align, box-sizingなし:パーツ順序、コンテナー、ボックスは1つ

パーツ上のファセット、状態、条件

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

ファセットの値は最初にトークンとして解決されます。単独のリテラルは、その単語をトークンが主張しない場合にのみ受け入れられます(opacity 50、inset 0)。トークンを優先してください。when はプロパティにキーを置き、state はビヘイビア状態にキーを置き、両者は組み合わせられます。

プロパティ、イベント、制約

  archetype TextField

  props {
    label : string required "フィールドが何を求めるか。アクセシブルな名前でもあります。"
    value : string
    invalid : boolean = false
    error : string required when invalid "無効な間、コントロールの下に表示されます。"
    size : enum(sm, md) = md
    tone : context Tone = Neutral
  }

  events {
    valueChange
  }

型:string、number、boolean、enum(a, b)、context <Group>、array<T>、あなた自身の type。末尾の文字列はプロパティのドキュメントです。one-of a, b / any-of / exclusive はプロパティのグループを制約します。

次に参照すべき場所

  • reference/syntax.md: すべてのステートメントと確認済みの例(トークンと値、レイアウト、スロット、インスタンス、ビヘイビア、ルール、ドキュメント、アセット、アイコン)。
  • reference/vocabulary.md: 言語パッケージから生成されます。リーダーが受け入れるすべてのトークンタイプ、パーツの種類、ファセット、状態、レイアウトワード、リテラル関数。単語に迷ったら、推測せずにこちらを参照してください。
  • reference/archetypes.md: プレリュードから生成されます。各アーキタイプの契約、構造(必須のパーツ)、ビヘイビア。
  • examples/acme.milda: パターンをコピーするための、完全でクリーンなシステム。
  • 規範的な仕様: https://github.com/mildastudio/milda-lang/tree/main/spec(`FORMAT.md` はファイルの約束事、GRAMMAR.ebnf は構文、PRELUDE.md はアーキタイプについて)。
  • すでに公開されているデザインシステムについては、Milda MCPサーバーが正確なコンポーネントとトークンで応答します。https://milda.dev/mcp を参照してください。

終了前に確認すること

  • ヘッダーに milda 0.10 と prelude 0.0.2 が含まれていること。
  • コンポーネント内にリテラルの色、長さ、フォントがないこと。すべての値はトークン参照であること。
  • プラットフォーム用語(タグ、CSSプロパティ、擬似クラス、フレームワークのイベント名)がどこにも使われていないこと。
  • すべてのコンポーネントがアーキタイプから始まっているか、インスタンスの純粋な構成であること。
  • システム全体に対して milda-check --strict が 0 errors, 0 warnings を出力すること。

関連スキル