ink
JSON仕様からインタラクティブなターミナルUIを生成する、ink向けのターミナルレンダラーです。`@json-render/ink`を使用する場合、JSONからターミナルUIを構築する場合、ターミナル用コンポーネントカタログを作成する場合、またはAIが生成した仕様をターミナルでレンダリングする場合に活用してください。
description の原文を見る
Ink terminal renderer for json-render that turns JSON specs into interactive terminal UIs. Use when working with @json-render/ink, building terminal UIs from JSON, creating terminal component catalogs, or rendering AI-generated specs in the terminal.
SKILL.md 本文
@json-render/ink
JSON仕様をインタラクティブなターミナルコンポーネントツリーに変換するInkターミナルレンダラー。標準コンポーネント、データバインディング、表示条件、アクション、動的プロップに対応しています。
クイックスタート
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/ink/schema";
import {
standardComponentDefinitions,
standardActionDefinitions,
} from "@json-render/ink/catalog";
import { defineRegistry, Renderer, type Components } from "@json-render/ink";
import { z } from "zod";
// 標準コンポーネントとカスタムコンポーネントでカタログを作成
const catalog = defineCatalog(schema, {
components: {
...standardComponentDefinitions,
CustomWidget: {
props: z.object({ title: z.string() }),
slots: [],
description: "Custom widget",
},
},
actions: standardActionDefinitions,
});
// カスタムコンポーネントのみ登録(標準コンポーネントはビルトイン)
const { registry } = defineRegistry(catalog, {
components: {
CustomWidget: ({ props }) => <Text>{props.title}</Text>,
} as Components<typeof catalog>,
});
// レンダリング
function App({ spec }) {
return (
<JSONUIProvider initialState={{}}>
<Renderer spec={spec} registry={registry} />
</JSONUIProvider>
);
}
スペック構造(フラット要素マップ)
Ink スキーマはルートキーを持つフラット要素マップを使用します:
{
"root": "main",
"elements": {
"main": {
"type": "Box",
"props": { "flexDirection": "column", "padding": 1 },
"children": ["heading", "content"]
},
"heading": {
"type": "Heading",
"props": { "text": "Dashboard", "level": "h1" },
"children": []
},
"content": {
"type": "Text",
"props": { "text": "Hello from the terminal!" },
"children": []
}
}
}
標準コンポーネント
レイアウト
Box- Flexboxレイアウトコンテナ(ターミナルの<div>のような役割)。グループ化、スペーシング、ボーダー、配置に使用します。デフォルトのflexDirectionは row です。Text- テキスト出力とオプションのスタイリング(色、太字、斜体など)Newline- 空白行を挿入します。flexDirection が column の Box 内に配置する必要があります。Spacer- 主軸に沿って拡張される可変な空白スペース。
コンテンツ
Heading- セクション見出し(h1: 太字+下線、h2: 太字、h3: 太字+薄い、h4: 薄い)Divider- オプションの中央タイトル付き水平区切り線Badge- カラー付きインラインラベル(バリアント: default、info、success、warning、error)Spinner- オプションのラベル付きアニメーション読み込みスピナーProgressBar- 水平プログレスバー(0-1)Sparkline- Unicode ブロック文字を使用したインラインチャートBarChart- ラベルと値を持つ水平棒グラフTable- ヘッダーと行を持つ表形式データList- 箇条書きまたは番号付きリストListItem- タイトル、サブタイトル、先頭・末尾テキスト付きの構造化リスト行Card- オプションのタイトル付きボーダーコンテナKeyValue- キーバリューペア表示Link- クリック可能なURL(オプションのラベル付き)StatusLine- カラー付きアイコン(info、success、warning、error)付きステータスメッセージMarkdown- ターミナルスタイリング付きマークダウンテキストのレンダリング
インタラクティブ
TextInput- テキスト入力フィールド(イベント: submit、change)Select- 矢印キーナビゲーション付きセレクションメニュー(イベント: change)MultiSelect- スペースキーでトグル可能なマルチセレクション(イベント: change、submit)ConfirmInput- はい/いいえ確認プロンプト(イベント: confirm、deny)Tabs- 左右矢印キーナビゲーション付きタブバー(イベント: change)
表示条件
要素に visible を使用して、状態に基づいて表示/非表示を制御します。構文:{ "$state": "/path" }、{ "$state": "/path", "eq": value }、{ "$state": "/path", "not": true }、{ "$and": [cond1, cond2] } は AND、{ "$or": [cond1, cond2] } は OR です。
動的プロップ式
任意のプロップ値は、レンダリング時に解決されるデータドリブン式にすることができます:
{ "$state": "/state/key" }- 状態モデルから読み込み(ワンウェイ読み込み){ "$bindState": "/path" }- ツーウェイバインディング:フォームコンポーネントの自然な value プロップで使用{ "$bindItem": "field" }- repeat アイテムフィールドへのツーウェイバインディング{ "$cond": <condition>, "$then": <value>, "$else": <value> }- 条件付き値{ "$template": "Hello, ${/name}!" }- 文字列への状態値補間
コンポーネントはツーウェイバインディングに statePath プロップを使用しません。代わりに、自然な value プロップで { "$bindState": "/path" } を使用します。
イベントシステム
コンポーネントは emit を使用して名前付きイベントを発火します。要素の on フィールドはイベントをアクションバインディングにマップします:
CustomButton: ({ props, emit }) => (
<Box>
<Text>{props.label}</Text>
{/* emit("press") はスペックの on.press にバインドされたアクションをトリガー */}
</Box>
),
{
"type": "CustomButton",
"props": { "label": "Submit" },
"on": { "press": { "action": "submit" } },
"children": []
}
ビルトインアクション
setState、pushState、removeState はビルトインで自動的に処理されます:
{ "action": "setState", "params": { "statePath": "/activeTab", "value": "home" } }
{ "action": "pushState", "params": { "statePath": "/items", "value": { "text": "New" } } }
{ "action": "removeState", "params": { "statePath": "/items", "index": 0 } }
リピート(動的リスト)
コンテナ要素の repeat フィールドを使用して、状態配列から項目をレンダリングします:
{
"type": "Box",
"props": { "flexDirection": "column" },
"repeat": { "statePath": "/items", "key": "id" },
"children": ["item-row"]
}
リピートされた子要素内では、{ "$item": "field" } を使用して現在の項目から読み込み、{ "$index": true } を現在のインデックスに使用します。
ストリーミング
useUIStream を使用して JSONL パッチストリームから段階的にスペックをレンダリングします:
import { useUIStream } from "@json-render/ink";
const { spec, send, isStreaming } = useUIStream({ api: "/api/generate" });
サーバーサイドプロンプト生成
./server エクスポートを使用してカタログから AI システムプロンプトを生成します:
import { catalog } from "./catalog";
const systemPrompt = catalog.prompt({ system: "You are a terminal assistant." });
プロバイダー
| プロバイダー | 用途 |
|---|---|
StateProvider | コンポーネント間で状態を共有(JSON Pointer パス)。制御モード用のオプションの store プロップを受け付けます。 |
ActionProvider | イベントシステムを通じてディスパッチされたアクションを処理 |
VisibilityProvider | 状態に基づいて条件付きレンダリングを有効化 |
ValidationProvider | フォームフィールド検証 |
FocusProvider | インタラクティブコンポーネント間のフォーカス管理 |
JSONUIProvider | すべてのコンテキスト用の統合プロバイダー |
外部ストア(制御モード)
StateStore を StateProvider(または JSONUIProvider)に渡して、外部状態管理を使用します:
import { createStateStore, type StateStore } from "@json-render/ink";
const store = createStateStore({ count: 0 });
<StateProvider store={store}>{children}</StateProvider>
store.set("/count", 1); // React が自動的に再レンダリング
store が提供されている場合、initialState と onStateChange は無視されます。
createRenderer(高レベル API)
import { createRenderer } from "@json-render/ink";
import { standardComponents } from "@json-render/ink";
import { catalog } from "./catalog";
const InkRenderer = createRenderer(catalog, {
...standardComponents,
// カスタムコンポーネントオーバーライドをここに配置
});
// InkRenderer には全プロバイダー(状態、表示、アクション、フォーカス)が含まれます
render(
<InkRenderer spec={spec} state={{ activeTab: "overview" }} />
);
キーエクスポート
| エクスポート | 用途 |
|---|---|
defineRegistry | カタログから型安全なコンポーネントレジストリを作成 |
Renderer | レジストリを使用してスペックをレンダリング |
createRenderer | 高レベル:ビルトインプロバイダー付きコンポーネントを作成 |
JSONUIProvider | すべてのコンテキスト用の統合プロバイダー |
schema | Ink フラット要素マップスキーマ(ビルトイン状態アクション含む) |
standardComponentDefinitions | すべての標準コンポーネントのカタログ定義 |
standardActionDefinitions | 標準アクションのカタログ定義 |
standardComponents | プリビルドコンポーネント実装 |
useStateStore | 状態コンテキストにアクセス |
useStateValue | 状態から単一値を取得 |
useBoundProp | $bindState/$bindItem 式のツーウェイバインディング |
useActions | アクションコンテキストにアクセス |
useAction | 単一アクションディスパッチ関数を取得 |
useOptionalValidation | useValidation の非スロー変種 |
useUIStream | API エンドポイントからスペックをストリーム |
createStateStore | フレームワーク非依存のインメモリ StateStore を作成 |
StateStore | 外部状態管理を接続するためのインターフェース |
Components | 型付きコンポーネントマップ(カタログ対応) |
Actions | 型付きアクションマップ(カタログ対応) |
ComponentContext | 型付きコンポーネントコンテキスト(カタログ対応) |
flatToTree | フラット要素マップをツリー構造に変換 |
ターミナルUI デザインガイドライン
- レイアウトには Box を使用(flexDirection、padding、gap)。デフォルトの flexDirection は row です。
- ターミナル幅は約 80-120 列です。メイン構造には垂直レイアウト(flexDirection: column)が推奨されます。
- Box の borderStyle を視覚的なグループ化に使用(single、double、round、bold)。
- 名前付きターミナルカラーを使用:red、green、yellow、blue、magenta、cyan、white、gray。
- セクションタイトルに Heading、セクション分離に Divider、ステータスに Badge、ラベル付きデータに KeyValue、ボーダー付きグループに Card を使用します。
- マルチビューUI に Tabs を使用し、子コンテンツに表示条件を使用します。
- インライントレンドに Sparkline、値の比較に BarChart を使用します。
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- vercel-labs
- ライセンス
- Apache-2.0
- 最終更新
- 不明
Source: https://github.com/vercel-labs/json-render / ライセンス: Apache-2.0
関連スキル
agent-browser
AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。
anyskill
AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。
engram
AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。
skyvern
AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。
pinchbench
PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。
openui
OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。