自然言語セレクタの解決
.demo スクリプトは、その意図を明確に記述します:
selectors:
composer = ask "チャット下部にあるメッセージボックス"
あなたの仕事は、それが実際のDOM内で何であるかを特定し、その結果を
scripts/<name>.selectors.json に書き込むことです。これにより、script.mjs がそれを通常のセレクタにコンパイルし、driver.mjs が決定論的なテイクを録画できるようになります。
あなたがリゾルバーです。 パイプライン内のどの処理もモデルを呼び出しません。script.mjs はサイドカーファイルを読み取り、それがなければコンパイルを拒否します。解決は録画前に一度だけ行われます。なぜなら、テイクのタイミングはビデオのタイムラインであり、実行中にモデルの往復が発生すると、完成したビデオに無音・無映像の空白が生じてしまうからです。
開始前の準備
- アプリにアクセス可能であり、ログインが必要な場合は、ユーザーのChromeで既にサインインしている必要があります。これが拡張機能を使用するポイントです:実際のセッションにアクセスするため、SSOの儀式やメールコードの入力は不要です。
- 最初にスクリプトを読んでください。URLのための
app:/target:ヘッダーとビートが必要です。なぜなら、セレクタはフロー順に解決する必要があるからです(後述)。
手順
-
作業リストを取得します。
cd pipeline node script.mjs ../scripts/<name>.demo --intents標準出力にJSONが出力されます:すべての
askセレクタ、そのインテント、および現在の解決状態(未解決の場合はnull)。nullのものを解決してください。ユーザーがフローが壊れていると言わない限り、残りのものは再解決しないでください。 -
ブラウザツールを1回のToolSearch呼び出しでロードし、その後、他のすべてに先立って
tabs_context_mcpを呼び出します。ユーザーが既存のタブを指定しない限り、tabs_create_mcpで新しいタブを作成します。 -
フローをビート順にたどります。 これは間違いやすい部分です:多くのセレクタはランディングページには存在しません。結果テーブルは質問が送信された後にのみ表示されます。「停止」コントロールは何かが生成されている間だけ存在します。そのため、スクリプトのビートを順に実行し、各
askの要素が画面に表示された瞬間に解決します。ライブデータ。 何かを作成、変更、送信、削除するステップの前には必ず停止してユーザーに確認してください。
feature.demoは実際のSalesmessageアカウントに4つのメッセージを送信します。クリックではなくホバーを使用して要素を特定するだけにし、破壊的なコントロールを「それが何かを見るため」にクリックしないでください。 -
要素を見つけ、最も耐久性のあるハンドルを選択します。 優先順位は以下の通りです:
優先 理由 [data-testid=...]、data-test、data-qa選択されるために配置されており、リデザインにも耐えます 安定した id生成されたように見えない限り有効( :r3a:、id-1a2bなど)正確なアクセシブル名によるボタン/リンク → btn:Nameドライバの btn:はテキスト、aria-label、内部のimg[alt]にマッチします[aria-label=...]、[role=...]安定しており、通常はセマンティックです セマンティック構造( main table、nav a[href="/teams"])スタイル変更に耐えます 決して使用しないでください:
nth-childチェーン、生成されたクラス名(css-1a2b3c、長いTailwindスタック)、または生成されたコンテンツに基づくもの。最後のものは、この機能全体が避けようとしている落とし穴です。モデルの回答は実行ごとに異なる表現になるため、そのテキストに一致するセレクタはコインフリップです。代わりに、コンテナまたは完了シグナルにアンカーしてください。 -
書き込む前に検証します。 各候補について、
javascript_toolを使用して、それが正確に1つの要素にマッチし、その要素が可視であることを確認します:const q = 'div[data-testid="chat-input"]'; const n = document.querySelectorAll(q); console.log(JSON.stringify({ q, count: n.length, visible: n[0] ? !!(n[0].offsetWidth || n[0].offsetHeight) : false, tag: n[0]?.tagName, editable: n[0]?.isContentEditable, }));read_console_messagesで結果を読み取ります。複数のマッチ、または0件のマッチは、さらに探し続ける必要があることを意味します。マッチを確認していないセレクタを書き込まないでください。 -
サイドカーファイル
scripts/<name>.selectors.jsonを書き込みます:{ "resolvedAgainst": "https://claude.ai/new", "resolvedAt": "2026-08-10T09:00:00Z", "resolvedBy": "claude-in-chrome", "selectors": { "チャット下部にあるメッセージボックス": { "spec": "div[data-testid=\"chat-input\"]", "evidence": "contenteditable tiptap div, aria-label 'メッセージを書く', 1個マッチ、可視" } } }キーはインテントテキスト、スクリプトからそのままコピーしたものです。セレクタの名前変更やブロックの並べ替えによって解決が孤立してはいけません。
specはドライバが受け入れる任意の形式です:生のpuppeteerセレクタ、btn:テキスト|代替テキスト、または::-p-text(部分文字列)など。evidenceは実際に観察した内容です。後で他の人がそれがまだ有効かどうかを判断できるように記述してください。 -
確認して引き継ぎます。
node script.mjs ../scripts/<name>.demo --intents # 未解決が0であることを確認 node script.mjs ../scripts/<name>.demo --print # コンパイル解決した内容、どの候補の間で推測する必要があったか、および破壊的なステップが必要なためスキップしたものを報告してください。
解決できない場合
その旨を伝えて停止してください。セレクタをでっち上げないでください。未解決のインテントは、Chromeが起動する前にきれいなコンパイルエラーとなります。間違ったセレクタは、録画開始後のテイク途中で失敗します。これはコストのかかる失敗の場所です。説明に等しく一致する2つの要素がある場合は、自分で選ぶのではなく、ユーザーにどちらを意図しているか尋ねてください。
注意点
| 症状 | 原因 / 修正 |
|---|---|
| 要素がページに存在しない | フローの後半に現れます。ビートを順にたどり、各インテントが実際に画面に表示された時点で解決してください |
| 2つの要素がマッチする | 説明が曖昧です。ユーザーと絞り込み、スクリプト内の ask も言い換えて、次回の解決が曖昧にならないようにしてください |
| セレクタは今動作するが、次回の実行で壊れる | 生成されたコンテンツまたは生成されたクラスに基づいています。testid、role、またはコンテナに再アンカーしてください |
wait ... gone アンカー | これらは本質的に一時的なものです(生成中の停止ボタンなど)。画面上にある間に解決し、aria-label を優先してください。テキストよりも変更が少ないです |
| リデザイン後に解決がずれた | サイドカーファイルからそのキーだけを削除し、再実行してください。.demo は変更されません。それがポイントです |
| ダイアログが拡張機能をブロックする | confirm/alert を開くようなものをクリックしないでください。モーダルダイアログは手動で閉じられるまで拡張機能をフリーズします |