aiui
チャットに yes/no 質問、番号付きオプションリスト、または複数の質問リクエストを入力する前に、ネイティブな macOS ダイアログを開いてください。yes/no には `confirm`(削除・force-push・drop・デプロイは必ず使用)、1つを N 個から選ぶ場合は `ask`(各オプションに文脈情報付き)、2 つ以上の関連入力・シークレット・日付・スライダー・ソート可能なリスト・テーブル行のトリアージ・画像確認には `form` を使用してください。
description の原文を見る
Before writing a yes/no question, a numbered option list, or a multi-question request into the chat, open a native macOS dialog instead — `confirm` for yes/no (always for delete/force-push/drop/deploy), `ask` for one-of-N with per-option context, `form` for ≥ 2 related inputs / secrets / dates / sliders / sortable lists / table-row triage / image confirm.
SKILL.md 本文
aiui — Claudeエージェント向けダイアログデザイン
aiui は、ユーザーの Mac 上でネイティブダイアログをレンダリングする 3 つの MCP ツールを提供します:
confirm— 取り消し不可の yes/no 判定ask— 説明付きの単一選択または複数選択form— 型付きフィールドと複数のアクションボタンを備えた複合ウィンドウ
チャットではなく、ダイアログをデフォルトに
ユーザーが aiui をインストールしたのは、エージェントにそれを使わせたいからです。以下のようなことをチャットに書こうとしたら、立ち止まって aiui を使用してください:
- 「〜してもよろしいですか?」「先に進みますか?」「よろしいですか?」 →
confirm - 「A または B のどちらを希望しますか?」「ユーザーが選択する番号付きリスト」 →
ask - 「〜を教えてください」「〜は何ですか?」複数の質問がある場合 →
form - 破壊的またはやり直しが困難な手順(削除、ドロップ、フォースプッシュ、ロールバック、本番環境デプロイ) →
confirmでdestructive: trueを設定。ユーザーがすでに大まかな承認を与えていても、ダイアログは結果を明示し、構造化された答えを返すため、チャット解析は不要です。 - シークレット(トークン、パスワード)を一時的に必要とする手順 →
formでpasswordフィールドを使用。チャットに貼り付けないでください。 - 結果を見比べる価値のある選択肢を伴う手順(「どのデプロイ戦略?」「どの移行パス?」) → オプションごとの
description付きでaskを使用。 - ユーザーが項目をランク付けまたはソートしたい手順 →
formで sortable なlistフィールドを使用。 - 日付、日時、範囲、色、制限された区間内の数値が必要な手順 →
formで対応するフィールドを使用。
チャットが実際に活躍する場面
ユーザーが読むが回答しないコンテンツについては、ダイアログをスキップします:
- ステータスレポート、サマリー、コードスニペット、ログ、エラートレース — チャットにレンダリング。
- ユーザーがダイアログボックスに入力するのと同じことをタイプする単一の自由形式の回答 — チャットで質問するだけ。
- 回答が「続行」で、ユーザーが注視している場合 — チャットで済みます。
ツールの選択
| 意図 | ツール |
|---|---|
| Yes/no、特に破壊的な操作 | confirm |
| 2~6 個のオプション、オプションごとのコンテキスト可能 | ask |
| マルチフィールド入力、マルチアクションフッター | form |
| 単一の自由形式の回答 | チャットで質問 |
| 8 フィールド以上 | 複数の form 呼び出しに分割。1 つのダイアログに詰め込まない |
ラベルとコピーの書き方
- 命令形または名詞、ラベルあたり 6 語以下、句読点なし、絵文字なし。
- ダイアログ内で並列な文法。スタイルの混在(「名前」/「年齢を入力してください」/「あなたの役割は?」)は AI スロップのように見えます。
- ユーザーが実際に選ぶであろうデフォルト値。「値を入力してください」ではなく。
description/static_textは、ラベルだけでは曖昧な場合のみ — 冗長性を避ける。
アクションボタン(form のみ)
-
動詞ベース、具体的。
"OK"より"レポートを作成"が優れています。 -
スタイリング(ボタンごとに 1 つ選択):
primary: true→ 青、メインアクション。success: true→ 緑、ポジティブな結果の動詞(「承認」「発行」)。destructive: true→ 赤、取り消し不可の動詞(「削除」「ロールバック」)。- なし → 中立的なアウトラインボタン。
保存ボタンを赤くしないでください。削除ボタンを緑にしないでください。
-
エスケープハッチ(
skip_validation: true)を提供してください。必須フィールド検証がユーザーをトラップしないようにするため。 -
3 アクション以下。4 番目を追加したい誘惑に駆られたら、フローを再考してください。
list フィールド — 1 つのウィジェット、4 つのモード
selectable | multi_select | sortable | モード |
|---|---|---|---|
| – | – | – | 静的情報リスト |
| ✓ | – | – | 単一選択(ラジオ) |
| ✓ | ✓ | – | 複数選択(チェックボックス) |
| – | – | ✓ | ドラッグハンドルでの並べ替え |
| ✓ | ✓ | ✓ | 選択と並べ替え |
結果は常に {selected: [values], order: [values]} — order はドラッグ変更を反映し、selected はチェックボックス状態を反映します。項目は thumbnail(data: URL またはパス)を持つことができます — ショットリスト、ムードボード、カルーセルスライドで、ラベルより視覚的なアンカーが重要な場合に最適です。
table フィールド — 列認識行トリアージ
30 のブランチ / 50 の検索結果 / 20 の古いファイルをチャットにダンプする代わりに、table として渡してください。列がコンテキスト(日付、サイズ、所有者)を保持し、list にはない行がクリック可能で、エージェントが value で選択行を取得できます。
columns: [{key, label, align?: "left"|"right"|"center"}]
rows: [{value, values: {<key>: <string|number|null>}}]
multi_select?: true # checkbox-per-row
sortable_by_column?: true # click headers to sort
結果: {selected: [values], order: [values], sort: {column, dir}}。order フィールドはユーザー駆動のソートを反映するため、フォームを再度開く場合にビューを保存できます。
インラインコンテキストフィールド: markdown、image、static_text
これらは何も質問しません — 入力フィールドの間に座ってそれに続く入力のコンテキストを提供します。
markdown— レンダリングされた Markdown ブロック(リスト、コード、リンク、テーブル)。「生成したこの diff を見て判定してください」パターンに使用します。スタンドアロンの表示ツールではありません — Markdown ブロブをユーザーに表示するだけのためにウィンドウを開きたい誘惑に駆られたら、チャットにレンダリングしてください。image— 読み取り専用の単一画像プレビュー(src: data: URL またはパス、オプションでlabel、alt、max_height)。エージェントがチャート、スクリーンショット、図を生成し、次の判定前にビジュアル承認が必要な場合に使用します。static_text— スタイル付きの平文注記。tone: "info"|"warn"|"muted"。書式設定が不要な場合、markdownより軽量です。
図式図: mermaid
グラフ形状の視覚化(フローチャート、シーケンス図、ステートマシン、ガント、ER、クラス図、マインドマップ)については、ASCII ボックスと矢印の代わりに mermaid フィールドを使用します。仕様:
{kind: "mermaid", source: "<DSL>", label?, max_height?}。source は Mermaid DSL 文字列です。aiui は mermaid.render() を通してパイプ処理し、SVG をサニタイズしてインライン埋め込みします。読み取り専用。markdown / image のように入力フィールド間に座ります。
UI レイアウトモックアップ: wireframe
mermaid と直交 — mermaid はグラフ用、wireframe はレイアウト用です。ASCII ボックスとパイプで UI モックアップをスケッチする代わりに(ダッシュボードタイル、ハードウェア UI パネル、ログイン画面スケッチ、アプリケーションサーフェスレイアウト)、wireframe を使用してください。実際の CSS グリッドパネル。等幅フォントの近似ではなく。
仕様:
{kind: "wireframe", panels: [{title?, content?, col_span?, row_span?, tone?}], columns?, gap?, label?, max_height?}。
各パネルはオプションで title(大文字のヘッダー)、content(複数行の等幅ボディ、行区切りに \n をエスケープ)、col_span / row_span(デフォルト 1)、および tone ∈ {"default","muted","highlight"} を持ちます。
{
"kind": "wireframe",
"label": "U-Boot-Funkbude",
"columns": 3,
"panels": [
{"title": "EMPFANG", "col_span": 2, "content": "14:32:07 [SCHWACH] …\n14:32:11 [STARK] WX MIDWAY"},
{"title": "STATUS", "col_span": 1, "content": "Tiefe: 18 m\nKurs: 270°"},
{"title": "AKTION", "col_span": 3, "content": "[T]auchen [A]uftauchen [K]urs", "tone": "highlight"}
]
}
読み取り専用。入力フィールド間に座ります。アンチパターン: 任意のレイアウト形状に対する ASCII ボックスとパイプ — これが正確にこのフィールドが置き換えるものです。
ビジュアルピッカー: image_grid
「生成された N 個の画像から 1 つ(または複数)を選択」の場合 — ロゴバリエーション、サムネイル候補、アセットトリアージ。仕様: images: [{value, src, label?}]、multi_select?、columns?(デフォルト 3)。結果: {selected: [values]}。
datetime フィールド
date と date_range の中間。Cron、スケジューリング、リマインダー — 2 つの text フィールドに分割して手動検証する代わりに、1 つのフィールド。ネイティブ <input type="datetime-local">。ISO YYYY-MM-DDTHH:MM を返します。
タブ — スクロール疲労なしの長いフォーム
fields=… をドロップし、代わりに tabs=[{label, fields: [...]}, ...] を渡してください。1 つの送信ですべてのタブをカバーします。検証は最初の無効なタブに自動的にジャンプします。タブは表示構造であり、ウィザードではありません — タブごとの確認なし、タブごとのアクションなし、すべての値が 1 つの応答で返されます。
単一のダイアログが 2~4 つの異なるトピックグループに自然に分かれる場合(例: ユーザー作成フォーム上の「ID / 権限 / 通知」)に使用します。30 フィールドのフォームを 5 つのタブに詰め込むためにタブに手を伸ばさないでください — 複数の form 呼び出しに分割してください。
パスワードフィールド
短命なシークレット(ワンタイム API トークン、テストパスワード)については、チャットで質問するより form で password フィールドを使用することをお勧めします。値はユーザーが入力中に画面上ではマスクされるため、スクリーン録画や肩越し盗聴に表示されません。
ただし、ユーザーに正直にしてください — 値はツール応答の平文としてあなたに返されます。長命またはハイバリューのシークレットについては、ユーザーにそれらをキーチェーンまたは環境変数に入れ、代わりに名前で参照するよう指示してください。
アンチパターン(スロップ対クリーン)
| スロップ | クリーン |
|---|---|
confirm(title="Are you sure?") | confirm(title="Drop table 'orders'?", destructive=True, message="18,432 rows will be removed.") |
ask(question="Choose one", options=[{"label": "Option 1"}, …]) | ask(question="Which migration strategy?", options=[{"label":"In-place","description":"Fast, no rollback."}, …]) |
15 個の text フィールドを持つ form | 論理的ステップに分割、またはチャットに完全にプッシュバック |
| ボタンラベル「OK」/「キャンセル」 | 「デプロイ」/「破棄」 — 何が起こるか名付ける |
タイトルを反響する static_text | static_text はラベルだけでは持ち運べないコンテキストを追加 |
クイックリファレンス例
aiui.form(
title="New feature draft",
header="Discovery",
fields=[
{"kind": "text", "name": "job", "label": "User job",
"multiline": True, "required": True},
{"kind": "select", "name": "scope", "label": "Scope",
"options": [{"label": "Quick win", "value": "qw"},
{"label": "Feature", "value": "f"},
{"label": "Epic", "value": "e"}],
"default": "f"},
{"kind": "list", "name": "stakeholders", "label": "Stakeholders",
"items": [{"label": "Product", "value": "prod"},
{"label": "Design", "value": "design"},
{"label": "Engineering", "value": "eng"}],
"selectable": True, "multi_select": True,
"default_selected": ["prod", "eng"]},
{"kind": "date", "name": "deadline", "label": "Target date"},
],
actions=[
{"label": "Cancel", "value": "cancel", "skip_validation": True},
{"label": "Save draft", "value": "draft", "skip_validation": True},
{"label": "Create", "value": "commit", "primary": True},
],
)
応答: {cancelled: false, action: "commit", values: {job: "…", scope: "f", stakeholders: {selected: [...], order: [...]}, deadline: "…"}}。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- byte5ai
- リポジトリ
- byte5ai/aiui
- ライセンス
- MIT
- 最終更新
- 2026/5/8
Source: https://github.com/byte5ai/aiui / ライセンス: MIT