このディレクトリには LiminalPalette の詳細ドキュメントが置かれている。最初に読む順序の推奨:
- getting-started — インストールと最初のコマンド (5 分)
- integrations — R3 + VContainer 統合 (必須)
- commands —
[LiminalCommand]/[LiminalObservableField]でできることのすべて - scenarios —
[LiminalScenario]でコマンドチェイン (= デバッグ再現 + 統合テスト) - ui — Editor Window と Runtime UI の使い分け、Current values セクション
- ipc — AI Agent / curl から叩く HTTP API (
/state//scenarios含む) - extensibility —
ITypeConverter/IParameterEditor/IInstanceResolverで拡張する - asmdef — どの asmdef がどこに依存するか (内部構造)
- security — localhost / トークン / Production 除外の原則
- troubleshooting — 困ったとき
[ ユーザーのコード ]
│
│ [LiminalCommand] 属性
↓
[ AttributeScanner ] ← 起動時に全 Assembly をリフレクションスキャン
↓
[ CommandRegistry ] ← Path → CommandDescriptor のテーブル
│
↓
[ CommandExecutor ] ← 引数バインド / async unwrap / Log capture / try-catch
↑ ↑ ↑
[Editor] [Runtime] [HTTP API] ← 3 つのホスト
Cmd+K Cmd+K /api/v1/execute
中核は CommandRegistry + CommandExecutor の 2 つ。UI と IPC はその上に乗る対称なクライアントとして実装されている。
| 用語 | 意味 |
|---|---|
| Path | コマンドの識別子。Category/Subcategory/Action 形式 (例: Player/Health/Set) |
| Descriptor | コマンドの不変メタデータ (CommandDescriptor)。Path / 引数スキーマ / 戻り値型を持つ |
| Result | 実行結果 (CommandResult)。Success / Value / Error / Logs / Duration |
| Invocation | 1 回の実行記録 (CommandInvocation)。Path + 引数 + Result + Timestamp |
| Palette | UI 全体 (PaletteView、VisualElement)。Editor / Runtime で同じものをホストする |
| Host | パレットを表示する側 (Editor: LiminalPaletteWindow、Runtime: LiminalPaletteRuntime) |
| IPC | HTTP API のこと。HttpServer + 7 エンドポイント (health / commands / execute / logs / state / scenarios / scenarios/run) |
| InstanceResolver | インスタンスメソッド [LiminalCommand] のインスタンス解決経路 (IInstanceResolver)。VContainer 統合経由で設定される |
| ObservableField | [LiminalObservableField] で公開された読み取り専用状態。ReactiveProperty<T> / Observable<T> を保持し、UI が R3 push 駆動で表示 |
| Scenario | [LiminalScenario] で宣言したコマンドチェイン。Run / Wait / Assert ステップを順次実行し、デバッグ再現 + 統合テストとして使う |
ほとんどのケースで Void2610.LiminalPalette.LiminalPalette の static メソッドだけ使えば足りる:
using Void2610.LiminalPalette;
// コマンド実行 (文字列引数)
var result = await LiminalPalette.ExecuteAsync("Player/Health/Set",
new Dictionary<string, string> { ["value"] = "100" });
// 型解決済み引数で実行 (UI 経路)
var result2 = await LiminalPalette.ExecuteWithTypedArgsAsync("Test/Vector",
new Dictionary<string, object> { ["v"] = new Vector3(1, 2, 3) });
// Registry にアクセス (動的登録 / 検索)
var commands = LiminalPalette.Registry.All;
// 利用側 ITypeConverter 登録
LiminalPalette.RegisterTypeConverter(new MyCustomConverter());
// インスタンス解決経路の差替 (通常は Integration.VContainer の LiminalPaletteEntryPoint が自動でやる)
LiminalPalette.SetInstanceResolver(new MyCustomResolver());
// シナリオ実行 (名前指定 / ad-hoc)
var sr = await LiminalPalette.RunScenarioAsync("Combat/EnemyTakesDamage");詳細は commands.md / scenarios.md / extensibility.md を参照。
Assets/Plugins/配置: プロジェクトのR3.Subject自動置換 CodeFix を回避するため、event Action<T>ベースを維持- 外部依存ゼロ:
Newtonsoft.Json/Utf8Json/UniTask等を引き込まない - Editor / Runtime 共有シングルトン:
CommandRegistry.DefaultとInvocationStore.Instanceはプロセス共通 - 三重防御の Production 除外: asmdef
defineConstraints+ProductionGuard+ 設定フラグで HTTP / 機能を Player ビルドから完全に外せる - localhost only HTTP:
127.0.0.1とlocalhostのみバインド。0.0.0.0には絶対にしない
詳細は security.md と asmdef.md を参照。