agent-panel について
Agent Panelは、GUI合成エディターの`ef-edit`イベント処理を扱うスキルです。意味のある編集を収集・重複排除し、セレクターごとにまとめて、コピー可能なコーディングエージェント向けプロンプトを作成します。
主な機能
- 01`ef-edit`イベントの取得
- 02要素とプロパティ単位で編集を重複排除
- 03セレクターごとに編集を整理
- 04コピー可能なコーディングエージェント向けプロンプトの作成
- 05イベントルーティングとテスト方法の説明
活用シーン
- 01GUI合成編集をコーディングエージェント向けに要約
- 02プロパティ変更の重複記録を防止
- 03編集対象ごとにプロンプトを生成
- 04DOMおよびShadow DOMの編集イベントをテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ editframe/ skills --skill agent-panelインストール後、Claude Code で/agent-panelを入力して読み込まれたか確認します。
詳細
エージェントパネル
EFAgentPanel は、GUI で意味のある編集操作が行われるたびにディスパッチされる ef-edit CustomEvents を取得し、キー付きレジストリを使って要素とプロパティの組み合わせごとに重複を排除します。さらに、セレクターごとにグループ化し、コピー可能なコーディングエージェント向けプロンプトを表示します。
イベントパイプライン
GUI interaction (canvas drag, inspector change, trim drag, loop toggle)
└─ component.dispatchEvent(createEditCustomEvent(editEvent))
└─ [bubbles: true, composed: true]
└─ EFWorkbench listener → agentPanel.addEdit(event)
└─ Map<editChangeKey, EditEvent> registry (deduplicates)
└─ groupEditsBySelector() → buildAgentPrompt() → copy button
EFWorkbench は、自身に addEventListener('ef-edit', ...) を登録します。ef-edit はバブルアップし、composed であるため、特別なルーティングなしで、どのスロット内のコンポーネントからでも(タイムライン、階層、キャンバスなど)ディスパッチできます。
主要な型(editEvents.ts)
// EditEvent — what the panel accumulates
interface EditEvent {
operation: EditOperation;
description: string; // human sentence
selector: string; // CSS path from composition root
elementHtml: string; // cleaned outerHTML snippet
timestamp: number;
}
// Operation union — extend here when adding new interaction types
type EditOperation =
| { type: "element-property-changed"; elementId; tagName; label; property; oldValue; newValue }
| { type: "element-moved"; elementId; tagName; label; fromX; fromY; toX; toY }
| { type: "element-resized"; elementId; tagName; label; x; y; width; height }
| { type: "element-rotated"; elementId; tagName; label; rotation }
レジストリキーの形式 — 重複排除の方法を決定します。
- プロパティ変更:
selector::prop:propName - 移動/サイズ変更/回転:
selector::move、selector::resize、selector::rotate
パターン:新しい ef-edit ディスパッチ箇所を追加する
import {
createEditCustomEvent, buildSelectorPath, getElementHtml,
buildEditDescription, type ElementPropertyChangedOperation,
} from "../../editEvents.js";
const oldValue = element.someProperty;
element.someProperty = newValue;
const op: ElementPropertyChangedOperation = {
type: "element-property-changed",
elementId: el.id,
tagName: el.tagName.toLowerCase(),
label: el.textContent?.trim().slice(0, 30) || el.id || el.tagName.toLowerCase(),
property: "attr-name", // attribute name as used in HTML source
oldValue,
newValue,
};
this.dispatchEvent(createEditCustomEvent({
operation: op,
description: buildEditDescription(op),
selector: buildSelectorPath(el),
elementHtml: getElementHtml(el),
timestamp: Date.now(),
}));
EFInspector.ts の buildPropertyEditEvent(element, property, oldValue, newValue) は、単純なプロパティ編集に使う短縮形です。
現在のディスパッチ箇所を確認する
# Every call site that produces an ef-edit event
rg 'createEditCustomEvent' elements/packages/elements/src/
# Track subclasses that override render() — each must bind @trim-change-end
rg 'override render' elements/packages/elements/src/gui/timeline/tracks/
# Registered element schemas
rg 'SCHEMA_REGISTRY' elements/packages/elements/src/gui/elementPropertySchema.ts
配線されていないもの(意図的)
再生コントロール(再生/一時停止/シーク)、パンとズーム/ズームレベル、ツールバーの設定は表示専用の状態であり、ef-edit イベントを生成すべきではありません。階層の並べ替え(EFHierarchy の hierarchy-reorder)には、新しい ElementReorderedOperation 型が必要ですが、まだ実装されていません。
Shadow DOM のイベントルーティングに関する注意点
trim-change-end は EFTrimHandles から composed: true でバブルアップします。TrackItem.render() は ef-trim-handles 要素に @trim-change-end をバインドします。EFVideoTrack は render() を全面的にオーバーライドし、独自の ef-trim-handles バインディングを提供します。今後、render() をオーバーライドして ef-trim-handles を含めるトラックサブクラスでは、@trim-change と @trim-change-end の両方をバインドする必要があります。render() をオーバーライドすると、基底クラス TrackItem.render() のハンドラーは継承されません。
要素プロパティのスキーマ(elementPropertySchema.ts)
静的ディスクリプターがインスペクター UI を制御します。新しい要素型は、末尾の SCHEMA_REGISTRY に登録します。次のファクトリー関数を使用してください。
timeDescriptor(attr, label, opts)— 時間値(${ms}ms属性として保存)enumDescriptor(attr, label, options, condition?)boolDescriptor(attr, label, condition?)numberDescriptor(attr, label, opts)stringDescriptor(attr, label)
レジストリー項目がない要素は、インスペクターに表示されません。テストのパターンは elementPropertySchema.test.ts を確認してください。
ef-edit イベントのテスト
ユニットテスト(Node/vitest):editEvents.ts のヘルパー(editChangeKey、rollUpEdits、groupEditsBySelector、buildAgentPrompt)に使用します。
ブラウザーテスト(Chromium/vitest):DOM イベントまたは Shadow DOM が関係するテストには必須です。
トリムの ef-edit をテストする場合は、ef-trim-handles のホスト要素で trim-change-end を直接ディスパッチしてください。テスト環境ではポインターキャプチャの動作が不安定なため、Shadow DOM のレイヤーを通してポインターイベント全体をシミュレートしようとしないでください。
const trimHandles = track.shadowRoot?.querySelector("ef-trim-handles");
trimHandles?.dispatchEvent(new CustomEvent("trim-change-end", {
detail: { elementId: video.id, type: "start" },
bubbles: true, composed: true,
}));
ループの ef-edit をテストする場合は、ループボタンをクリックします:shadowRoot.querySelector("button[title='Loop']").click()。
document レベルでリッスンしてください。ef-edit は bubbles: true, composed: true であるため、どのコンポーネントからでも document まで伝播します。