捕捉
サイドパネルcontent script の フレームごとのポートがすべての DOM イベントを service worker に転送します。Shadow DOM と同一オリジン iframe は透過的に貫通します。
- 6 段階のセレクタ解決(testid → id → aria → text → css → xpath)
- tabPorts: Map<tabId, Map<frameId, Port>>
- IME を認識する入力バッファ · paste · drag
Skill Recorder は Chrome 拡張機能で、あなたが一度だけブラウザタスクを通すのを見守ります — そして SKILL.md を書き出します。これは Claude Code(あるいは browse CLI 上のあらゆるエージェント)がセレクタもグルーコードも見守りも不要で再生できる、プレーンマークダウンの仕様書です。
私たちが出荷するのは、小さな Chrome MV3 拡張機能と 4 KB の蒸留パイプラインです。レコーダーは chrome.debugger にフックして DOM レベルの忠実度を出し、蒸留は service worker 内で完結し、再生は browse CLI が結果の SKILL.md を読みます。サーバーなし、グルーコードなし。
content script の フレームごとのポートがすべての DOM イベントを service worker に転送します。Shadow DOM と同一オリジン iframe は透過的に貫通します。
6 つの小さなパスがノイズの多いイベントログを決定的な仕様に変えます。自動パラメータ化は信頼度 0.7 以上でのみ発火し、それ以下では推測ではなく質問します。
browse CLI は SKILL.md をプレーンマークダウンとして読みます — スキーマなし、ランタイムなし、抜け穴なし。すべてのステップが監査可能です。
ブラウザはレコーダーの罠だらけです — ハッシュ化されたクラス、遅延モーダル、Shadow DOM、複数タブのフロー、IME 合成、ドラッグアンドドロップ。下の各行はプレイグラウンドの実在のフィクスチャです。クリックすれば自分で録画できます。
btn__primary--ab3f9c のような Tailwind 風クラスは毎デプロイで変わります。リゾルバは 6 段階(testid → id → aria → text → css → xpath)を辿るので、再ハッシュされたボタンも当たります。
A2 →文字どおり同じ "Pick" ボタンが 6 行 — 位置でしか区別できません。fingerprintIndex でクリックを固定するので、リストが並び替わっても正しい行をクリックします。
A3 →"Continue" / "続ける" / "Weiter" はすべて同じ data-i18n-key="action.continue" にマップされます。レコーダーはロケール非依存属性を優先するので、英語で録った Skill が日本語ページで再生されます。
A4 →pushState と hashchange の遷移はリロードなしで追跡されます。再生は空のコンテナをプロービングする代わりに新コンテンツのマウントを待ちます。
B1 →トリガーがクリックされた時点で Confirm ボタンは存在しません。elementVisible がターゲット出現までポーリングしてから次のステップをディスパッチします — フレーキーな timeout なし。
B3 →all_frames: true でフレームごとに注入。アクションには発火元 frameId が付与され、再レンダリング時に URL で再解決されるので、古い frameId が再生を止めません。
C1 →password / phone / クレジットカード / SSN 入力は type + autocomplete + name で検出され、ストレージに入る前に *** に置換されます。バイトはページから出ません。
C2 →カスタムの shadow セレクタ種別がパスを { host, inner } セグメントとしてエンコードし、リゾルバが各境界で shadowRoot.querySelector を歩きます。Web Components は一級市民です。
C3 →フローが新タブを開くとき — 印刷プレビュー、OAuth、見積生成 — 録画は chrome.tabs.onCreated で追随します。再生は chrome.tabs.create でタブを再生成します。
C4 →共通の DataTransfer を持つ dragstart → dragover → drop チェーンが 1 つの drag ステップに合成されます(ソース + ターゲット + 観測された型)。脆いピクセル座標なし。
D1 →単独の "k" は文字入力のノイズ。metaKey: true が付くと Cmd-K ショートカットです。レコーダーはコンボを残してノイズを捨て、修飾状態を再生に保ちます。
D3 →contenteditable で change イベントは絶対に発火しません。input + compositionend をフックし、300 ms デバウンスし、最終的な innerText で 1 つの change ステップを発します — テキスト入力と同じ形。
D4 →各クリックステップは comboboxContext(オプションテキスト、ルートセレクタ)で強化されます。再生時に直接クリックが失敗したら、テキスト入力 → aria-activedescendant が一致するまで ArrowDown → Enter にフォールバックします。
D6 →16 のうち 13。加えて 4 つの複合フィクスチャ — Notion、Linear、Jira、Salesforce — がこれらの技術を 12〜15 個まで一連のフローにつなぎます。プレイグラウンドを見る →
毎週月曜の朝、小さなサプライヤーの運用エンジニアは同じポータルを開き、新規発注書をクリックし、CSV から SKU を貼り、数量を入力し、送信をクリックします。そしてまたやります。週 200 行、毎週、14 か月続いています。スプレッドシートが終わるまで繰り返す 5 分の儀式です。
これはまさにレコーダーが売り込まれるタイプのタスクであり、ほとんどのレコーダーが失敗するタイプのタスクです。サプライヤーポータルはデプロイごとに Tailwind ハッシュクラスを回転させます。送信ボタンは保存のたびに再レンダリングされる動的な行の中にあります。認証 cookie は正午に期限切れになります。このページに対して書かれた Selenium スクリプトは平均 2 週間生き延び、その後静かに壊れ始めます。
エンジニアは拡張機能をツールバーに固定し、ポータルを開き、開始録画をクリックし、タスクをちょうど一度実行します。8 回のクリック、2 つの入力値、1 回の送信。サイドパネルにイベントのライブフィードが表示されます — ノイズも含めて:スクロール、focus、blur、ヘルプアイコンへのうっかりマウスムーブ。4.6 秒で 23 イベントを捕捉。
main.example.p4
エンジニアは生成された markdown を ~/.claude/skills/create-purchase-order/SKILL.md に置き、Claude Code に一文だけ入力します。エージェントは名前で Skill を見つけ、前提条件を解決し(保存された cookie は正午まで有効)、CSV の 50 行を反復処理して報告します。3 分 11 秒後、仕事は完了。誰も見ていませんでした。
オープンベータ期間中は無料。アカウント不要、アップロードなし、テレメトリなし。バンドル全体で 4.5 MB。録画はあなたのマシンに留まり、エクスポートを選ぶまで動きません。