Interceptor について
Interceptorは、実際のWebサイトやネイティブアプリをテストするエージェント向けの、ブラウザーおよびmacOS操作スキルです。実ブラウザーのUIを介して動作し、DOMの確認、JavaScriptの実行、ネットワーク記録、操作の記録ができます。
主な機能
- 01実際のChromeとBraveの操作
- 02DOMの読み取りとJavaScript実行
- 03ネットワークリクエストと応答の記録
- 04ブラウザーとmacOSの入力操作
- 05ユーザーフローの記録と再生
活用シーン
- 01ログイン済みセッションでのWebサイトテスト
- 02実行時エラーやネットワーク問題の調査
- 03デプロイ後のページ表示の検証
MCP 対応
READMEには任意のMCPサーバーのインストールコマンド `interceptor mcp install` が記載されていますが、このスキルでは使用しないと明記されています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ danielmiessler/ lifeos --skill interceptorインストール後、Claude Code で/interceptorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreFlows/README.mdReferences/CommandReference.mdTools/FrameScrub.tsHealBridge.shCleanupTabs.shLaunchTestProfile.shEnsureTestProfile.shCapture.shVerifyImageProbe.tsVerifyViewport.tsPin.shZoom.tsPreflightIsolation.shWorkflows/DispatchAppleEvent.mdCaptureBackgroundedApp.mdDriveBackgroundedApp.mdDriveRichEditor.mdLaunchTestProfile.mdMultiPageCompare.mdOverrideXhr.mdReadAndExtract.mdReadAxTree.mdRecordAndReplayMacFlow.mdRecordFlow.mdReproduce.mdReplayFlow.mdScreenshotForVlm.mdTestForm.mdTrustedInputGate.md詳細
カスタマイズ
実行する前に、次の場所にユーザー設定があるか確認してください:
~/.claude/LIFEOS/USER/CUSTOMIZATIONS/SKILLS/Interceptor/
このディレクトリが存在する場合は、中にある PREFERENCES.md、設定、リソースを読み込んで適用してください。これらはデフォルトの動作より優先されます。ディレクトリが存在しない場合は、スキルのデフォルト設定に従ってください。
必須:音声通知(あらゆる操作の前に必須)
このスキルが呼び出されたら、ほかのことをする前に必ずこの通知を送信してください。
-
音声通知を送信する:
curl -s -X POST http://localhost:31337/notify \ -H "Content-Type: application/json" \ -d '{"message": "Running the WORKFLOWNAME workflow in the Interceptor skill to ACTION"}' \ > /dev/null 2>&1 & -
テキスト通知を出力する:
Running the **WorkflowName** workflow in the **Interceptor** skill to ACTION...
これは任意ではありません。このスキルが呼び出されたら、直ちにこの curl コマンドを実行してください。
Interceptor — 実ブラウザーの自動操作+macOS のコンピューター操作
何よりもまず守るべきルール:ブラウザーで何かをするようオペレーターに頼もうとしていることに気づいたら(URL を開く、クリックする、フォームに入力する、ログインする、値を貼り付ける、OAuth/同意ページで承認するなど)、それが Interceptor を使う合図です。自分で操作してください。唯一の例外は、本当に把握していない秘密情報が必要な手順(不明なパスワード、ハードウェアによる 2FA のタップなど)です。その場合も、その正確な箇所までは自分で操作し、最後に人間にしかできない操作だけを伝えてください。人間が行うクリック操作を説明することこそ、このスキルが防ぐべき失敗です。
概要
Interceptor は、実際の Chrome/Brave ブラウザーをブラウザー内から操作し、ブリッジがインストールされている場合は macOS のネイティブアプリも操作します。6 種類の機能を備え、それぞれ独自の動詞ツリーを持っています:画面キャプチャ、DOM 読み取り、JS 評価、ネットワークキャプチャ、入力、記録/再生です。実際のセッションへのログイン状態を維持し、主要なボット検出チェックをすべて通過します。また、デプロイの画面検証に必須のツールです。
課題
ヘッドレスブラウザーのツールは CDP で通信しますが、サイトはこれをフィンガープリントしてブロックできます。そのため、自動化されたブラウザーにはログイン済みの人間とは別のページが表示されたり、完全にブロックされたりすることがあります。また、認証情報のない別個のブラウザーインスタンスとして動作するため、ログイン済みのサイトにはアクセスできません。さらに、ページが壊れたとき(マウント後の真っ白な画面、ハイドレーションの不一致、一瞬表示されて消えるカードなど)、スクリーンショットだけでは原因がわかりません。Interceptor はこれらの問題をすべて解決します。実際のブラウザー UI を通して操作するため CDP のフィンガープリントはゼロで、ログイン済みの実際のセッションを使用し、ライブ DOM、コンソールエラー、ネットワーク通信を読み取って、スクリーンショットではわからない障害の原因を説明します。
動作の仕組み
Interceptor は、実際のブラウザー UI と、ネイティブアプリ、OS レベルの入力、オンデバイス VM へ同じ制御範囲を拡張するオプションの macOS ブリッジを通じて動作する Chrome 拡張機能です。
ツール: interceptor CLI — 内部から実際のブラウザーを操作する Chrome/Brave 拡張機能と、ネイティブアプリ、OS レベルの入力、VM のライフサイクル全体を操作する macOS ブリッジです。
リポジトリ: https://github.com/Hacker-Valley-Media/Interceptor
インストール: 上流リリースページにある署名済みの Interceptor-Browser-<v>.pkg / Interceptor-Full-<v>.pkg を使用するか、既存のインストールで interceptor upgrade --full を実行してください。ソースからのビルドは任意です。Workflows/Update.md を参照してください。
Chrome 拡張機能: 署名済みインストーラーが拡張機能を登録します。代わりにソースからビルドする場合は、Tools/Pin.sh がビルド済みの extension/dist を ~/.claude/skills/Interceptor/Extension/ にコピーします。このディレクトリはスキルには同梱されておらず、Pin.sh が作成します。Chrome は「Load unpacked」から拡張機能を読み込みます。出所情報は Extension/PINNED_FROM.txt(ソースパス、マニフェストのバージョン、コンテンツの SHA256、タイムスタンプ)に記録されます。マニフェストが更新されるたびに Chrome はアンパックされた拡張機能を無効にするため、ソースを再ビルドした後は、コピーを再度ピン留めして再読み込みする必要があります。上流の更新には自動追従しません。
ピン留めされたバイナリ: このスキルでは interceptor >= 0.23.16 が動作します。(メンテナーのマシンに関する注記 — 一般公開されているインストールについての説明ではありません:メンテナーのバイナリは、ローカルブランチ local-0.23.16、上流タグ v0.23.16、および --out を尊重して既定で ~/Downloads に保存する screenshot --save の修正をチェリーピックしたものからビルドされています。この修正が上流に取り込まれるまでは、アップグレードのたびに再度チェリーピックしてください。また、セルフアップデーターでパッチが消えるため、interceptor update ではなくソースからビルドしてください。標準のインストールでは、screenshot --save は作業ディレクトリに書き込みます。--out を明示的に指定してください。)上流版は3つのサーフェスを備えた制御プレーンです:Browser + macOS + iOS(所有する Developer Mode の iPhone を、WiFi 経由でオンデバイスの XCUITest ランナーから操作します — interceptor ios *)。タブのライフサイクルポリシー(0.23.3 の新機能): 名前付きグループの再利用がデフォルトで有効になり、アイドル状態の管理対象グループは 10 分後に自動的に閉じます。詳しくは以下の「タブの整理」を参照してください。
機能の概要 — 6 つの動詞ツリー
各行は独立した機能クラスです。それぞれデーモンから拡張機能への境界で異なる WebSocket メッセージタイプを使用するため、1 つの機能の停止が他に影響することはほとんどありません。ページの不具合をデバッグするときは、各行が独立した診断経路です。screenshot がハングしても、まず eval、net log、monitor を試さずに Interceptor を諦めないでください。
| 動詞ツリー | トップレベルの動詞 | 得られるもの |
|---|---|---|
| VISUAL | screenshot(デフォルトは DOM レンダリング — バックグラウンドでも動作)、screenshot --region、screenshot --pixel --full(ウィンドウが表示されている必要があります) | あらゆるサイズ、セレクター、領域に対応する PNG/WebP、またはスクロールしてつなぎ合わせた全ページの画像。Tools/Capture.sh 経由で実行し、生の interceptor screenshot は使用しないでください。Tools/Zoom.ts で細部を拡大できます。 |
| DOM READ | read [--markdown]、tree、text、html <ref>、find | アクセシビリティツリー、構造化された Markdown、生のマークアップ、参照 |
| JS EVAL | eval <code>、eval --main | 分離されたワールドまたはメインワールドで JavaScript を実行します — コンソールエラー、ランタイム例外、ハイドレーション警告、実行時の DOM 状態を読み取る方法です |
| NETWORK | net log、net headers、net export --format har|pcapng|json、override、headers add/remove | CDP のフィンガープリントを残さないパッシブなリクエストキャプチャ。Wireshark 用の HAR 1.2 および pcapng |
| INPUT | click、type、keys、act <ref> [--trusted]、drag、scroll、select、focus | ブラウザーおよび macOS ネイティブの入力。OS レベルの HID ソース状態には --trusted を使用します。click --selector <css> は CSS セレクターでクリックし(0.23.6 以降)、クリック可能な e<ref> を返します。合成クリックが拒否された場合は、OS レベルのクリックに自動で昇格します |
| RECORD/REPLAY | monitor start/stop、monitor export --plan、monitor export --format har | 決定論的なリプレイスクリプトとしての実際のユーザーフローのキャプチャ。複数セッション、ブラウザーおよび macOS AX イベントに対応します |
コンソールエラーの読み取りは、独立した動詞ではなく手順です。eval --main で console.error / window.error リスナーを注入し、イベントを window.__errs に保存してから、再度 eval を実行して読み取ります。ハイドレーションの不整合、React のエラーバウンダリー、読み込み時の JavaScript 例外、その他のサイレントなランタイム障害に役立ちます。インストール後、読み取り前にリロードすると、キャプチャしたエラーは失われます — キャプチャは読み込み後に行われるため、リロードで再現しても役に立ちません。代わりに次のユーザー操作からキャプチャするか、getEventListeners(window) / DOM ミューテーションオブザーバーをポーリングして障害の証拠を探してください。
実際の運用で重要な理由。 Astro ページのハイドレーション失敗、React のマウント後にページが空白になる問題、「カードが一瞬表示されて消える」といった問題は、いずれもスクリーンショットではなく、eval でライブ DOM の状態とコンソールのキャプチャを読み取ることで明らかになります。screenshot が停止しても、診断は妨げられません。ほかのすべての動詞ツリーを通じて、引き続きページを調査できます。
新しいサーフェスと動詞(0.17 → 0.22.37)
0.22.2 → 0.22.37 で追加された機能(2026-07 リリース):
- スクリーンショットの自動フォールバック(0.22.37) — DOM レンダリングによるキャプチャに失敗すると、自動的に
--pixelで再試行するようになりました(副作用は結果に明記されます。--no-fallbackで無効にできます)。これはレンダリングの失敗(インジェクションがブロックされたページ、ナビゲーション中など)に対応します。サイレントな合成ミスには対応しません。OPERATIONAL_RULES にあるアニメーションページの--pixel/DOM ジオメトリのクロスチェックルールは、引き続き有効です。 - WebSocket のハーフオープン検出(0.22.37) — デーモンのキープアライブ確認応答により、以前は気付かれないままハングしていた、切断済みなのにオープン状態の拡張機能接続を検出します。
- 決定論的なタブ指定(0.22.9–10) —
tab close <id>/tab switch <id>は、指定した ID(数値のみ)を対象に実行され、作業中のタブが対象になることはありません。 - ファイルアップロードの刷新(0.22.21) — サイズ制限なし、ドロップゾーン、ネイティブのファイル選択ダイアログに対応しました。
- Safari サーフェス(0.22.32) と MCP サーバー(0.22.35、
interceptor mcp install) — いずれも意図的にここでは使用しません。CLI 経由で Chrome のテストプロファイルを操作します。 - a11y の対象拡大(0.22.37) — 面積がゼロのインラインラッパー要素が、ツリーから除外されなくなりました。
上記の 6 つのブラウザー動詞ツリーが、引き続き中核です。0.16.9 からの変更点は次のとおりです。
- iOS(
interceptor ios *) — 所有していてロック解除済みの Developer-Mode iPhone を、デバイス上の XCUITest ランナー経由で WiFi 接続して操作します(WebDriverAgent ではありません)。動詞:tree、find、click、type、scroll、screenshot、app launch|activate|terminate。セットアップは Xcode によるセルフサービス、または Xcode 不要のloginで Apple ID を使ってランナーに署名し直す方法があります。 interceptor diagnose— 失敗後のスナップショットを 1 回で取得します。デーモン(実際の exec パスを含む)、接続中の各コンテキスト(並列でプローブ)、モニターの状態を確認できます。デーモンのスプリットブレインを検出します。Chrome があるデーモンバイナリを起動する一方、CLI は別のバイナリと通信し、以前は無言のまま 15 秒のタイムアウトになっていました。動作が固まったように見える場合は、まずこれを実行してください。interceptor manifest— 50 以上の動詞について、機械可読な仕様(使い方、フラグ、戻り値の仕様)を提供します。ヘルプテキストをスクレイピングせずに仕様を確認できます。- エージェントごとのタブグループ(
--group <label>/INTERCEPTOR_GROUP) — 各エージェントを独自の色付きで完全に分離されたタブグループに割り当て、複数のエージェントが相互に干渉せずに 1 つのブラウザーを共有できるようにします。interceptor group list|close <label>。--contextに加わる第 2 の分離レイヤーです。 interceptor save— ダウンロードフォルダーを経由せず、ライブページから生バイト列(Blob/ArrayBuffer/blob:)を直接ディスクに保存し、sha256 を返します。interceptor ocr/canvas ocr— オフラインの Tesseract ピクセル OCR を拡張機能にバンドルしました(ブリッジ不要、macOS 不要)。interceptor macos cdp *— Electron/Chromium デスクトップアプリ(Slack、VS Code、Notion、Descript)の Web コンテンツを、ブラウザータブと同じ方法で操作します。
CLI の仕様(0.22.1): 引数の順序に依存しなくなりました(open --text-only <url> が正しく解析されます)。また、ブラウザー専用のインストールでは macOS/iOS の動詞が非表示になります(--all-surfaces/INTERCEPTOR_ALL_SURFACES で上書き可能)。引数なしの interceptor/--help は簡潔な機能一覧を表示します。仕様全体を確認するには help <cmd> または interceptor manifest を使用してください。
Interceptor を使う理由
CDP ベースのブラウザー自動化は、サイトに検出されます。Interceptor は、実際のブラウザー UI を通じて動作する Chrome 拡張機能です。デバッガーも、自動化フラグも、別のブラウザーインスタンスも必要ありません。ログイン状態を維持し、ボット検出を通過でき、エージェントにはユーザーと同じ画面が見えます。オプションの macOS ブリッジを使うと、同じ操作サーフェスをネイティブアプリケーション、OS レベルの入力、デバイス上の VM にも拡張できます。この組み合わせが、このスキルにおける「コンピューター使用」の意味です。
Interceptor、Apify、BrightData — 規模 × 認証で選ぶ
「ページからデータを取得する」3 つのツールですが、用途はあまり重なりません。最後に使ったツールではなく、ページ数とログイン状態が重要かどうかで選んでください。
- Interceptor — 実際のログイン済みブラウザーを 1 つ操作します。自分のセッションにログインしていることが重要な場合、対象サイトがボットを積極的にブロックする場合、またはデプロイ後の確認、OAuth/ログイン/フォームのフロー、デバッグ、認証が必要なページを少数抽出するといった対話型の作業に使います。見分けるポイント:各ページを手動で開けて、ログインした自分の状態で表示できます。
- Apify — 名前の挙がったプラットフォーム(Instagram、LinkedIn、TikTok、YouTube、Facebook、Google Maps、Amazon)から大量に抽出するための、マネージドクラウドアクターです。数百〜数千件の項目を並列で構造化して取得し、プロキシローテーションを利用したい場合に使います。見分けるポイント:手動では開かない量で、対象プラットフォーム専用のアクターがあります。
- BrightData — 任意のサイト(名前の挙がったアクターはありません)を段階的にスクレイピングする、4 段階の仕組みです。クローラー規模で強力なボット検出や CAPTCHA に遭遇すると、住宅用プロキシへ自動的に切り替わります。
一行で判断するなら、ログインできる 1 ページ → Interceptor、名前の挙がったプラットフォームから N 件 → Apify、強力なボット検出のある任意のサイト全体 → BrightData です。Interceptor はこの Mac 上のブラウザーを 1 つ操作するツールです。マネージドな並列処理、プロキシプール、プラットフォームごとの抽出機能はありません。また、何千ものプロフィールを処理させると直列処理で時間がかかり、実際のアカウントにリスクが及びます。Apify の規模に代わるツールとして使ったり、ログイン済みユーザーとして 1、2 ページを操作する必要があるのに Apify を使ったりしないでください。
厳格な禁止事項 — すべての実行で適用
画面の検証は Interceptor だけで行います。以下は例外なく禁止です。
screencapture— macOS の標準スクリーンショットバイナリです。主要なツールとして使うことも、Interceptor が停止したときの代替手段として使うことも、「スクリーンショットを 1 枚だけ」撮るために使うことも禁止です。- Chrome の操作に使う
osascript—tell application "Google Chrome" to activate、set frontmost of process、set bounds of window、set active tab index、set index of window、その他のウィンドウ状態の変更は禁止です。 osascriptの System Events によるキー入力 —key code、keystroke、key downは禁止です。これらはフォーカスのある対象に入力を送るため、オペレーターの操作を横取りします。- 自動化を目的としたあらゆるフォーカスの移動 — スクリーンショットを撮るために Chrome(またはほかのアプリ)を前面に表示することは禁止です。ブリッジの CGS/DOM レンダリング経路なら、フォーカスを変更せずにキャプチャできます。
- あらゆるウィンドウ状態の変更 — Chrome ウィンドウの移動、サイズ変更、位置変更、並べ替えは禁止です。ウィンドウの配置はオペレーターが管理するものであり、エージェントが変更することはありません。
- AppleScript によるタブ切り替え —
set active tab index of window Nは、フォーカスを移動し、オペレーターが表示しているタブも変更するため、二重に禁止されています。
これらのルールは Interceptor が失敗した場合も変わりません。 Interceptor が停止しても、未加工の OS ツールを使ってよい理由にはなりません。Interceptor で証拠を取得できない場合は、Interceptor を修復する(以下の WebSocket-wedge の注意点を参照)か、処理を停止して今回の実行では検証結果をキャプチャできないことをオペレーターに伝えてください。代替手段に切り替えてはいけません。
ブリッジ経由の Computer Use は別扱いです。 interceptor macos open <app>、interceptor macos act <ref>、interceptor act <ref> --trusted(以前の --os)など、ブリッジ経由の操作は認可されたブリッジのインターフェースを通るため、ワークフローでネイティブアプリの操作が明示的に必要な場合は許可されます。上記の禁止事項は、(a)Interceptor を完全に迂回する未加工の OS レベルの経路、および(b)スクリーンショットの取得だけを目的としたフォーカス移動に適用されます。
事前チェック分離ゲート(必須)
すべてのブラウザワークフローの最初のステップです。例外はありません。
interceptor open|read|act|inspect|screenshot|navigate|tab|monitor|net|cookies|scroll|click|type が Chrome に到達する前に、ワークフローでゲートを実行します。自動復旧するエントリーポイントを優先してください。ゲートを実行し、テストプロファイルのウィンドウが開いていない場合は起動して、再検証してから戻ります。
bash ~/.claude/skills/Interceptor/Tools/EnsureTestProfile.sh # runs the gate; auto-launches the test profile on exit 5/6; prints READY on success
EnsureTestProfile.sh は PreflightIsolation.sh(自動起動なしで直接呼び出すこともできる基本ゲート)をラップしています。どちらも回復不能な失敗があればゼロ以外の終了コードを返します。ゼロ以外の場合は、処理を停止してその旨を示してください。Default にフォールバックしてはいけません。ゲートでは、次の不変条件を検証します。
- バイナリのバージョンが 0.16.0 以上であること — 古いビルドは
--contextを黙って無視し、デーモンが見つけた Chrome 接続にフォールバックします。このフォールバックによって、タブがオペレーターの Default ウィンドウに表示されます。 - 固定されたテストコンテキストに接続されていること — UUID 列全体と照合します(部分文字列での grep ではないため、ヘッダーや部分一致による誤検出はありません)。接続されていない場合、オペレーターの Default プロファイルが唯一の利用可能な対象になります。
- 対象が Default ではないこと。 次のコマンドが操作するコンテキストを特定し、タブに触れる前に Default および
INTERCEPTOR_WORKING_PROFILE_IDSの拒否リストと照合します。Default または作業プロファイルとの一致は、即時停止の対象です(終了コード 7)。 - 拡張機能の最新性(段階的に対応)。
Extension/PINNED_FROM.txt(マニフェストのバージョンとコンテンツの SHA256)を、存在する場合は上流の$INTERCEPTOR_SRC/extension/distと比較します。不一致の場合は、再固定の対処方法を示して失敗します。上流が存在しない場合(現在はこの状態です)は警告を表示して続行します。status --verboseは拡張機能のビルド情報を公開しないため、この確認には使用しません。
確認に失敗すると、スクリプトは構造化された対処メッセージを stderr に出力して、ゼロ以外の終了コードで終了します。ゼロ以外の終了コードが返された場合、ワークフローは必ず停止しなければなりません。 メッセージを示してください。いかなる場合も、Default プロファイルでの操作にフォールバックしてはいけません。「とりあえず試す」ことも禁止です。代わりに screencapture や osascript を使用してはいけません。
処理を区別する必要があるハンドラー向けの終了コード:
2— interceptor バイナリが PATH にありません3— バージョン文字列を解析できません4— バージョンが最小要件を下回っています(Workflows/Update.mdに従ってアップグレードしてください)5— 接続中のブラウザーコンテキストがありません(Chrome が閉じているか、拡張機能が停止しています)6— 固定されたテストコンテキストがありません(プロファイルの初回セットアップが必要です)7— 特定された対象が Default または作業プロファイルです(即時停止)
ゲートは絶対遵守事項です。読み取り専用の公開ページ取得、認証済みツールの検証、スクリーンショットの撮影を含む、あらゆる処理で例外なく実行します。デフォルトへのサイレントなフォールバックはすべてオペレーターのウィンドウへの違反となるため、「スキップしても安全」なケースはありません。
分離の原則(重大 — コードで強制される厳格なルール)
すべてのブラウザーコマンドは、固定された分離済みの Interceptor テストコンテキストに対して実行します。常にそのコンテキストを使い、オペレーターの Default プロファイルや、作業用/監視用プロファイルは決して使いません。 これは単なる推奨ではなく、憲法上のルールです。
- 対象コンテキストは
preferences.envのINTERCEPTOR_TEST_CONTEXT_IDです。 多くの場合、固定されているのは生のコンテキスト UUID です。恒久的な解決策は、生の UUID を、拡張機能のポップアップで設定したフレンドリー名interceptor-testに置き換えることです。フレンドリー名は再読み込み後も維持されますが、生の UUID は拡張機能を再読み込みするたびに無効になります(UUID のローテーションを参照)。 - 分離境界はユーザーデータディレクトリではなく、Chrome のプロファイルです。 テストプロファイルはオペレーターの Default プロファイルと同じ Chrome インストール内にありますが、Cookie、タブ、ウィンドウは分離されています。オペレーターのアカウント(Google、GitHub、Cloudflare、ブログ管理画面、その他の管理ダッシュボード)にはログイン済みです。それが目的です。
--user-data-dirのサンドボックスは、認証情報が一切なく、オペレーターがログイン済みのツールにもアクセスできないため、役に立ちません。 - オペレーターの Default プロファイルは、デフォルトで読み取り専用です。 オペレーターが明示的に「Default プロファイルで確認して」「メインウィンドウを使って」と指示しない限り、Default でタブを開いたり、クリック、入力、移動、記録を行ったりしてはいけません。指示があった場合は、
interceptor contextsで接続を確認したうえで、--context <default-id>を指定してください。 - 「別のアプリ」は安全策にはなりません。オペレーター自身のブラウザーも Chrome かもしれません。 オペレーターが別のアプリでブラウジングしている場合は、ウィンドウをテストコンテキストと取り違えても、自然に誤りに気づけます。両方が Chrome の場合はそうなりません。その場合、オペレーターのブラウジングと自動化を隔てているのはプロファイルの固定だけです。認識できない Chrome コンテキストはすべてオペレーターのものとして扱い、制御下のコンテキストで移動するのではなく、
open -a "Google Chrome" "<url>"(通常のプロファイル)で URL を渡してください。 - 一度限りのセットアップ手順は
Workflows/LaunchTestProfile.mdにあります。 オペレーターが Chrome のアバターメニューをクリックし、[プロフィールを追加]を選択してサインインし、Interceptor 拡張機能を読み込み、ポップアップでコンテキスト名を設定します。
廃止された動作。決して再び導き出してはいけません。 以前の「固定したコンテキストが見つからない場合は、最初に利用可能なコンテキスト/Default コンテキストにフォールバックする」というルールは削除されました。固定したコンテキストが見つからない、または古くなっている場合は、フォールバックではなく、修正手順を伴う即時停止が必要です。Default に自動的に振り分けるコードパスはありません。
コンテキストを指定しないコマンドが危険な理由。 2 つ以上のコンテキストが接続されている場合、デーモンは multiple extensions connected, use --context <id> というエラーで即座に停止します。このフェイルファスト動作だけが、現在、コンテキストを指定しないコマンドを保護しています。オペレーターが別のブラウザーウィンドウを閉じた瞬間(接続中のコンテキストが 1 つになると)、コンテキストを指定しないコマンドは、残った唯一のコンテキストに黙って自動で振り分けられます。そのため、すべてのブラウザー操作では --context "$INTERCEPTOR_TEST_CONTEXT_ID" を指定するか、Tools/Capture.sh 経由で振り分ける必要があり、これは任意ではありません。
UUID のローテーションと恒久的な解決策。 コンテキスト ID はプロファイルごとに安定した chrome.storage.local の UUID であり、変更されるのは拡張機能の再インストール/再読み込み時だけです(Chrome の再起動時には変更されません)。恒久的な解決策は、拡張機能のポップアップでフレンドリー名 interceptor-test を一度設定し、その名前を固定することです。それまでは、Tools/Capture.sh がガード付きの自動再バインドを行います。再バインドするのは、Default が明確に除外されている状態で、Default 以外のテストコンテキストがちょうど 1 つ接続されている場合に限ります。固定先が古くなっても、Default にフォールバックすることは決してありません。
これは好みではなく、運用原則です。 オペレーターの Default プロファイルには、現在作業中のタブと、オペレーターの DA が操作しているタブがあります。各コマンドにフラグを 1 つ追加するコストはゼロです。一方、作業中のウィンドウにテスト用タブが 1 つ紛れ込むと、クリックや予期しないリダイレクトが発生し、取り返しがつかず、作業の妨げになります。
context-not-connected に対する自動復旧は許可されています。ただし、EnsureTestProfile.sh を経由する必要があり、単独で起動してはいけません。 テストプロファイルのウィンドウが開いていない場合(PreflightIsolation.sh が 5=コンテキストなし、または 6=固定されたコンテキストが未接続で終了)、Tools/EnsureTestProfile.sh は設定済みのテストプロファイルを起動し、固定されたコンテキストが接続されるまでポーリングしながらゲートを再実行します。これは、次の不変条件があるため安全です。PreflightIsolation.sh 自体が 0 で終了した後にしか処理を進めません。このスクリプトは、接続されたコンテキストと INTERCEPTOR_TEST_CONTEXT_ID を全項目照合し、Default/作業用プロファイルを確実に拒否します。そのため、誤った --profile-directory を起動しても、エージェントがそのプロファイルを操作することはありません。プリフライトは引き続き失敗し、EnsureTestProfile は停止します。安全性を担保するのは起動後の再検証ループであり、プロファイル引数への信頼ではありません。終了コード 7(解決された対象が Default/作業用)と終了コード 8(テストコンテキストが未設定)の場合は、起動を絶対に行いません。これらの場合は問題を報告して停止します。また、再検証を行わない単独の LaunchTestProfile.sh も依然として危険です。必ず EnsureTestProfile.sh を経由してください。起動に成功しても固定されたコンテキストが接続されない場合(拡張機能の再読み込み後に UUID が変わった場合)、EnsureTestProfile は一度だけの永続的な修正方法(ポップアップでコンテキスト名を interceptor-test に設定する)を示して停止し、推測で処理を進めることはありません。
レンダリングライフサイクルゲート — 隠しタブの落とし穴(モーション/レスポンシブ対応では必須)
**Chrome は、ウィンドウが表示されていないタブ(最小化されている、別のウィンドウに完全に隠れている、または非アクティブな Space にあるタブ)のレンダリングライフサイクル全体を一時停止します。**その状態では、次のようになります。
| 引き続き動作するもの(そのため測定値は正常に見えます) | ひそかに停止するもの |
|---|---|
setTimeout / setInterval(約1秒に1回にスロットリング) | requestAnimationFrame |
getBoundingClientRect() — 必要に応じてレイアウトを強制 | ResizeObserver |
| CSS メディアクエリ/静的レイアウト | IntersectionObserver |
DOM の読み取り、screenshot(DOM レンダリング経路) | CSS トランジションとアニメーション、遅延読み込み、スクロール表示 |
これは危険な種類の不具合です。エラーは何も発生しません。レスポンシブページやアニメーションページは、何も起きなかったことを示す、確信に満ちた整った数値を返すため、「機能が発火しない」または「動作しているが、変化は検出されない」という自然な結論に至ってしまいます。2026-07-30 に実測したところ、実際の要素を2回リサイズして5秒間確認した際、固定されたテストコンテキストは visibilityState: hidden を報告し、rAF のティックは0回、ResizeObserver のコールバックも0回でした。一方、setInterval は5回ティックしました。
**ルール:アニメーション、トランジション、ResizeObserver/IntersectionObserver の動作、遅延読み込み、スクロール表示、またはビューポートに応じたレイアウトに関する主張は、必ず Tools/VerifyViewport.ts に基づく必要があります。標準のテストコンテキストに基づいてはなりません。**コンポーネント独自の再計算を手動で実行して「動作する」ことを証明するのは、自分の手でコードをテストしているだけで、ブラウザーを検証していることにはなりません。
bun ~/.claude/skills/Interceptor/Tools/VerifyViewport.ts check
bun ~/.claude/skills/Interceptor/Tools/VerifyViewport.ts probe <url> --widths 1440,1100,880 --expr @probe.js
bun ~/.claude/skills/Interceptor/Tools/VerifyViewport.ts shot <url> --width 880 --out ~/Downloads/x.png
bun ~/.claude/skills/Interceptor/Tools/VerifyViewport.ts stop
仕組みと、ほかの方法では実現できない理由。 スロットリングを無効にするオプション(--disable-backgrounding-occluded-windows、--disable-renderer-backgrounding、--disable-background-timer-throttling)は、ブラウザープロセスの起動時にのみ適用され、1つのブラウザープロセスが使用する --user-data-dir は1つだけです。そのため、すでに実行中の Chrome には適用できず、--profile-directory も同じプロセスを共有するため、プロファイルをいくら切り替えてもオペレーターのブラウザーの問題は解決しません。VerifyViewport は、これらのオプションを指定して、独自の --user-data-dir で独立したヘッドレス Chromeを実行します。ヘッドレスモードではウィンドウ自体が作成されないため、オペレーターのデスクトップに何も表示されず、依存するウィンドウの状態もありません。その一方で、同じレンダラーを使用し、ライフサイクル全体が有効な状態で実行されます。フローを自分の目で確認する必要がある場合は、INTERCEPTOR_VERIFY_HEADFUL=1 を指定すると、邪魔にならない場所に実際のウィンドウが表示されます。
拡張機能ではなく、CDP(interceptor macos cdp)経由で操作します。これは、現在の Chrome では --load-extension が機能しない(152 で確認済み。機能フラグによる回避策も含めて、警告なしに無視されます)うえ、カスタムの --user-data-dir では独自の空の NativeMessagingHosts が使われるためです。ビューポートサイズは Emulation.setDeviceMetricsOverride で設定します。これは実際のレイアウトビューポートの変更であり、ウィンドウの移動、サイズ変更、フォーカスを行わずに、ページ独自のオブザーバーを作動させます。これこそが要点です。検証は、オペレーターがウィンドウをどこに置いたかに依存してはなりません。
check とすべての probe/shot は、ライフサイクルが有効であること(visibilityState === visible かつ rAF が実際にティックしていること)をアサートし、そうでなければ0以外の終了コードで終了します。劣化モードはありません。ライフサイクルに問題があれば、静かな測定ではなく、処理を即時停止します。
これは機能の追加であり、これまで動作していたものには一切触れません。 オペレーターの Chrome、固定されたテストプロファイル、分離ゲート、CDP の痕跡を残さないステルス経路は、いずれも変更されません。認証済みページ、実際のセッション、ボット検出に注意が必要な作業には、引き続き拡張機能駆動のテストコンテキストを使用します。検証用インスタンスにはログイン情報がなく、ステルス性も保証されません。時間の経過に伴う動作がテスト対象となる公開ページに使用してください。
インストールモード(0.16.x)
インストールモードは2種類ありますが、CLI バイナリは共通です。interceptor status で確認し、mode: の行を参照してください。
| モード | インストールされるもの | 利用できる機能 |
|---|---|---|
mode: full(このスキルのデフォルト) | CLI + デーモン + 拡張機能 + Swift ブリッジ .app + LaunchAgent | ブラウザー自動化に加えてコンピューター操作:AX ツリー、OS レベルの信頼された入力、ScreenCaptureKit、Vision OCR、Speech、NLP、Apple Events、OSLogStore、ファイル監視、コンテナーランタイム、VM のライフサイクル管理 |
mode: browser-only | CLI + デーモン + 拡張機能 | ブラウザー自動化のみ。interceptor macos * は1秒以内に構造化された setup_required エラーを返します。TCC プロンプトは表示されません。 |
interceptor upgrade --full で browser-only インストールを full にアップグレードできます。bash scripts/uninstall.sh --bridge-only でダウングレードできます。
インストール方法(pkg インストーラーは v0.11+ で追加):
Interceptor-Browser-<v>.pkg→mode: browser-onlyInterceptor-Full-<v>.pkg→mode: fullbash scripts/install.sh --browser-only|--full→ 開発用の方法- Linux は browser-only に対応しています(v0.13.4 以降、Microsoft Edge と Vivaldi も認識されます)
運用ルール:ユーザーがネイティブ操作を求め、status が mode: browser-only を報告した場合は、*「browser-only インストールを使用しています。これを有効にするには、interceptor upgrade --full を実行してください。」*と回答してください。動作を確認するために macos コマンドを実行してはいけません。事前チェックで処理が短絡されますが、やり取りを無駄に消費します。
前提条件
- Interceptor 拡張機能を読み込んだ状態で Chrome または Brave(対応プラットフォームでは Edge/Vivaldi も可)が実行されていること。署名済みの
.pkgインストーラーが拡張機能を登録します。ソースからビルドした場合は、chrome://extensions/→ Developer Mode → 「Load unpacked」→Tools/Pin.shが作成するExtension/ディレクトリから、一度読み込んでください - PATH に
interceptorCLI があること(/opt/homebrew/bin/interceptor) - PATH に
interceptor-daemonがあること(/opt/homebrew/bin/interceptor-daemon) - Native Messaging マニフェストが登録されていること(署名済みの
.pkgが登録します。ソースからの場合はbash "$INTERCEPTOR_SRC"/scripts/install.sh --chrome --skip-extension) - macOS ブリッジが LaunchAgent としてインストールされていること(full モードのみ)。
Workflows/Update.mdを参照してください - Sparkle.framework が
/usr/local/Frameworks/Sparkle.frameworkにあること(full モード、v0.10.0+)。ブリッジの自動更新に必要です
簡単なヘルスチェック:
interceptor --version # → "interceptor 0.23.16 (<hash>, <date>)" — 0.23.16+ is what matters
interceptor status # → daemon: running, bridge: running, mode: full|browser-only
interceptor status --verbose # → adds extension reachability (NO extension-build field; with 2+ contexts it nags "multiple extensions connected" even with --context)
interceptor contexts # → list of connected browser contexts (multi-profile)
interceptor init # → one-time write of ~/.config/interceptor/config.toml
バックグラウンド優先の原則(0.16.x)
製品全体がバックグラウンド優先で動作します。通常の操作でユーザーのフォーカスが移動することはありません。
| 対象 | フォーカスを移動する動詞 | その他すべて |
|---|---|---|
| ブラウザー | open --activate、tab new --activate、tab switch <id>、window focus <id> | オペレーターが見ていた画面を維持します — click、type、read、inspect、screenshot、net、cookies、scroll、act。新しいタブはデフォルトでバックグラウンドに表示されます。 |
| macOS | app activate <app>、open <app> --activate | 最前面にあった画面を維持します — open(--activate なし)、すべての入力動詞、AX の読み取り、キャプチャ、メニュー、インテントのディスパッチ、ビジョン、オーバーレイ。 |
「フォーカスを移動する」列に記載されていない動詞を呼び出して最前面のアプリが変わる場合、それはバグです。
再利用の方法: open --reuse は、既存の管理対象タブに移動し、不要なタブを残しません。再利用するタブのフォーカス状態を維持します。ユーザーが明示的に前面に表示するよう求めた場合に限り、--activate と組み合わせてください。
マルチコンテキストルーティング(0.16.x)
複数のブラウザプロファイルが接続されている場合(例:個人用の Chrome +分離されたテスト用プロファイル+仕事用の Brave)、コマンドで操作対象を指定する必要があります。
interceptor contexts # List connected context IDs
interceptor open <url> --context "$INTERCEPTOR_TEST_CONTEXT_ID" # Route to the isolated test profile (DEFAULT)
interceptor open <url> --context <main-id> # Route to the operator's personal Chrome (only when explicitly requested)
--context を指定しない場合、ブラウザコマンドは接続されているコンテキストがちょうど 1 つの場合にのみ自動ルーティングされます。コンテキストが 1 つだけ残っていると、引数なしのコマンドは残っているコンテキストを黙って操作します。コンテキストが 0 個、または 2 個以上の場合は、構造化エラーを返して即座に失敗します。必ず --context "$INTERCEPTOR_TEST_CONTEXT_ID" を渡すか、Tools/Capture.sh 経由でルーティングしてください。自動ルーティングには依存しないでください。
コンテキスト ID は Interceptor 拡張機能のポップアップで設定します(ツールバーアイコンをクリック → Context ID フィールド → Save)。設定は初回のみで、デーモンは再起動後も設定を保持します。UUID が頻繁に変わる問題を避けるため、ここでわかりやすい名前 interceptor-test を設定してください。
常に使用する既定値: --context "$INTERCEPTOR_TEST_CONTEXT_ID"。初回設定については Workflows/LaunchTestProfile.md を参照してください。
コンピューター操作 — macOS ネイティブヘルパー
ブリッジは、ユーザーとして実行される Swift LaunchAgent であり、Chrome 拡張機能だけでは提供できない機能を公開します。
- OS レベルの信頼済み入力(
interceptor act <ref> --trusted、macos type --trusted、macos keys --trusted— HID ソースの状態を介してisTrustedチェックを回避します) - macOS ネイティブアプリの制御(
interceptor macos open/read/act/inspect— ブラウザと同じ操作で、実行中のあらゆるアプリを対象にします) - スクリーンショットを使わずに検査できる、実行中のあらゆるアプリのアクセシビリティツリー
- Chrome 以外の画面キャプチャ(全画面、タブ外、複数ディスプレイ、遮蔽されたウィンドウ)
- VM のライフサイクル(
interceptor macos vm create/clone/start/exec/snapshot/restore/stop/delete— Linux および macOS ゲストに対応し、Lume/Tart/UTM を置き換えます) - クリップボードの読み書き、音声のリスニングと音声認識、システム通知、Vision OCR、NLP、Apple Intelligence、HealthKit、ディスプレイ情報
- アクティベーションなしで、指定したバンドル ID に Apple Events を送信
- OSLogStore の述語クエリ、ファイルシステムの検索と監視、URL の取得
- Monitor(アプリをまたぐワークフローの記録。クリップボード/ファイル/ネットワーク/ログ/通知/音声の各チャンネル、および
--framesによるスクリーンショットキャプチャを任意で利用できます)
状態の確認: interceptor status は、起動中の場合は PID とソケットを伴う bridge: running を、起動していない場合はヒントを伴う bridge: not running を報告します。
ライフサイクル(インストール/検証/トラブルシューティング/アンインストール)については、Workflows/Update.md を参照してください。 Update ワークフローでは、バイナリの配置、Sparkle フレームワークのインストール、LaunchAgent plist、launchctl bootstrap、TCC プロンプトを適切な順序で処理します。
セキュリティモデル — インストール前にお読みください:
- 通信には
/tmp/interceptor-bridge.sockの UNIX ドメインソケット を使用します。ローカル限定であり、ネットワークリスナーはありません。 - ソケット認証はありません。 ユーザーとして実行されているローカルプロセスは、どれでも接続してすべてのブリッジアクションを実行できます。macOS の TCC 権限(アクセシビリティ、画面収録、マイク。
trustプローブのキーはaccessibility/screenRecording/microphoneであり、inputMonitoringフィールドはありません)はブリッジに一度付与され、そのすべてのソケットクライアントに引き継がれます。 - わずかなリスクはサプライチェーンにあります。 悪意のあるローカルパッケージは、独自に権限を取得しなくても、OS レベルの入力/画面/クリップボードにアクセスする手段を一段階で得ます。
- シングルユーザーの Mac の脅威モデルでは、ユーザーとして実行できるものはすでに手間をかければ同じ操作を行えるため、許容範囲です。マルチユーザーの Mac ではソケットの強化が必要です。
複合コマンド(推奨)
これらを使うと複数ステップのパターンを 1 回の呼び出しにまとめられ、ツール呼び出しとトークンを減らせます。
interceptor open <url> # Open + wait + return tree + text
interceptor open <url> --reuse # Navigate existing managed tab
interceptor open <url> --activate # Bring new/reused tab to front (explicit opt-in)
interceptor open <url> --tree-only|--text-only|--full|--no-wait|--include-frames
interceptor read # Tree + text for active tab
interceptor read <ref> # Subtree
interceptor read --markdown # Render page as markdown (preserves headings/tables/emphasis)
interceptor read --markdown --text-only # Markdown prose only, no tree
interceptor read --tree-only --tree-format compact # Actionable refs only
interceptor read --include-style|--include-frames
interceptor act <ref> # Click + wait + return updated tree + diff
interceptor act <ref> "value" # Type + wait + return updated tree
interceptor act <ref> --trusted # OS-level HID-sourced input (was --os; --os is deprecated alias)
interceptor act <ref> --keys "Enter" # Send keyboard shortcut
interceptor act <ref> --no-read # Skip post-action tree read
interceptor inspect # Tree + text + network log + headers
interceptor inspect --net-only|--filter <pattern>
--trusted と --os の違い: v0.13.3 で --os は --trusted(標準)に名称変更されました。--os は非推奨のエイリアスとして残されており、警告が表示されます。新しいコードでは --trusted を使用してください。
コマンドリファレンス(移動しました)
動詞ごとの CLI 一覧(macOS Native(Computer Use)、VM Lifecycle、Core Browser Commands、Network/Exports、Recording(Session Monitor)、Canvas、Scene Graph、LinkedIn、ChatGPT Agentic Bridge、Batch + Meta)は、References/CommandReference.md にあります。簡単な参照先は以下のとおりです。
| 動詞ツリー | リファレンスのセクション |
|---|---|
interceptor macos *(ネイティブアプリ、AX、信頼済み入力、Vision/Speech/NLP、Apple Events、ログ、fs、オーバーレイ) | macOS Native (Computer Use) |
interceptor macos vm *(Linux および macOS ゲスト、ゴールドイメージ、クローン/スナップショット) | VM Lifecycle — Workflows/VmLifecycle.md も参照 |
state、tree、find、click、type、navigate、tabs、screenshot、eval、style、cookies | Core Browser Commands |
net log/headers/export、override、network *、sse *、headers * | Network — Passive, CDP, and Exports |
monitor *(記録/再生) | Recording (Session Monitor) |
canvas *、scene * | Canvas / Scene Graph |
linkedin *、chatgpt *、batch、status、contexts、init、upgrade | LinkedIn / ChatGPT Bridge / Batch + Meta |
主なルール
- ブラウザーコマンドには、Chrome/Brave が起動している必要があります。スタンドアロンのバイナリではなく、拡張機能です。
act --trusted、macos *、全画面キャプチャ、VM のライフサイクルには、ブリッジが起動している必要があります。interceptor statusで確認できます。- 参照には eN 構文を使用します。
@e12ではなくe12です。参照は短時間で無効になるものとして扱い、ナビゲーション、再レンダリング、DOM の変更後はreadまたはfindを再実行してください。 - フレームをまたぐ参照:
read --include-framesは、トップ以外のフレームに対してe<frameId>_<n>のような参照を返します。 - デフォルトではプレーンテキストを使用します。スクリプトにパイプで渡す場合に限り、
--jsonを使用してください。文章で学習したモデルは、密度の高い JSON よりもツリー/テキスト出力を適切に理解できます。 - デーモンは自動で起動します。最初のコマンドで起動するため、手動で起動する必要はありません。
tab new+wait+treeのような手動のコマンド列ではなく、複合コマンド(open、read、act、inspect)を優先してください。- タスクが明示的に視覚またはピクセル単位のものでない限り、スクリーンショットより構造化された読み取りを優先してください。ツリー/テキスト/ネットワーク/シーン/AX データのほうが高速で、サイズが小さく、決定性も高くなります。
--trustedが正式な指定であり、--osは非推奨のエイリアスです。 v0.13.3 以降、新しいコードでは--trustedを使用してください。- 構造化された文章を取得するには
--markdownを使用します。 見出し、表、強調を保持します。視覚的な階層が回答の判別に役立つ場合は、--text-onlyの代わりに使用してください。 - 契約上、バックグラウンドが優先されます。フォーカスを移動するのは
--activate/app activate/明示的なtab switchのみです。 - 前後に
frontmostで確認してください。フォーカスを変えないとされるネイティブのワークフローでは、そのことを実証してください。 screencaptureは決して使わないでください。Chrome のフォーカス、境界、タブ、ウィンドウにosascriptを使うことも禁止です。ハード禁止事項に該当し、Interceptor の障害時も適用されます。- ライフサイクルに依存する処理はすべて
Tools/VerifyViewport.tsを通してください。アニメーション、トランジション、ResizeObserver/IntersectionObserver、遅延読み込み、スクロール表示、ビューポートに応じたレイアウトが対象です。ウィンドウが表示されていない場合、標準のテストコンテキストはこれらすべてのアクティビティを常にゼロと報告します。「Rendering-Lifecycle Gate」セクションを参照してください。 - スクリーンショットの取得には
Tools/Capture.shを使用し、生のinterceptor screenshotは決して使わないでください。Capture.sh は事前チェックゲートを実行し、Default を対象とする場合は拒否し、UUID ローテーション時の再バインドに対応し、DOM レンダリング経由の取得を優先し、レビュー用アーティファクトを$LIFEOS_DOWNLOADS_DIRに保存します(未設定時のデフォルトは~/Downloads/)。 - タブの整理:上流側で自動クリーンアップが行われるようになりました(Tab Lifecycle Policy、0.23.3 で追加)。
CleanupTabs.shは主要な仕組みではなく、最後の手段です。組み込みの動作は 2 つあり、どちらも拡張機能のポップアップ(唯一の設定変更元)からのみ設定できます。(1)名前付きグループの再利用(デフォルトで有効) —interceptor open <url> --group <label>は新しいタブを開く代わりに、そのグループで最後に使用されたタブに移動します(アドレスバーと同じ動作)。そのため、40 ステップの自動化でもタブは 40 個ではなく 1 個のままです。名前付きグループに限ります。共有のデフォルトグループでは「最後に使用されたタブ」が別のエージェントのものかもしれないため、グループを指定しないopenは引き続き新しいタブを作成します。--reuseはどの場所でも再利用を有効にし、--no-reuseは新しいタブを強制します。tab new(⌘T コマンド)は常に新しいタブを作成します。(2)アイドル状態のグループを閉じる(デフォルトは 10 分) — コマンドで操作されていない管理対象グループは自動的に閉じられます(0 にすると無効)。ただし、フォーカス中のウィンドウのアクティブなタブ、ピン留めされたタブ、音声を再生中のタブ、ウィンドウの最後のタブには触れません。各スイープのログが記録され、閉じたタブは ⌘⇧T/interceptor session restoreで復元できます。解決済みのポリシーはinterceptor status --verboseのtabLifecycleフィールドで確認できます。タスク中はopen --group <label>を優先し、再利用によって自動的にクリーンアップされるようにしてください。それでも最後の手段として、終了時にbash ~/.claude/skills/Interceptor/Tools/CleanupTabs.shを 1 回実行してください。これは PINNED テストコンテキスト内の非アクティブなタブのみを閉じ、アクティブなタブは保持します(ウィンドウは維持されます)。--keep-url <substr>を尊重し、Default/作業用プロファイルでは拒否され、コンテキストが接続されていない場合は 0 で終了します。アイドルスイープがまだ処理していない、グループ未指定のタブに対する念のための対策です。(過去の記録:ライフサイクルポリシー導入前の 2026-07-13 に、古いタブが 22 個確認されました。)
エージェントへの委任
Interceptor の作業でエージェントを起動する場合:
Agent(subagent_type="general-purpose", prompt="
Use interceptor CLI for all browser and macOS automation work.
Browser: open <url> --context "$INTERCEPTOR_TEST_CONTEXT_ID", read [--markdown], act eN, inspect. Screenshots go through Tools/Capture.sh, never raw screenshot.
Native (macOS): macos open <app>, macos read, macos act <ref>, macos inspect, macos vm *.
Compound commands preferred — they return tree + text in one call.
Refs use eN syntax (no @ prefix) from tree output. Treat refs as short-lived.
Background-first: only --activate and app activate move focus.
PROFILE ISOLATION (MANDATORY GATE): the FIRST action of this task is
bash ~/.claude/skills/Interceptor/Tools/PreflightIsolation.sh
If that script exits non-zero, STOP and surface the message verbatim — do NOT
fall back to operating against the Default profile, and do NOT use screencapture
or osascript as substitutes. After the preflight returns OK, every browser
command carries `--context "$INTERCEPTOR_TEST_CONTEXT_ID"`. Never operate in the
operator's main profile unless the parent agent explicitly says so.
`act --trusted` for OS-level HID input (was --os).
FINAL action after your work is done and evidence captured: run
bash ~/.claude/skills/Interceptor/Tools/CleanupTabs.sh
to close the tabs you opened in the test profile (keeps the active tab).
[your specific task instructions here]
")
ワークフローのルーティング
| ワークフロー | トリガー | ファイル | 備考 |
|---|---|---|---|
| LaunchTestProfile | "テストプロファイル", "テストプロファイルを起動", "分離されたブラウザー", "分離されたブラウザープロファイル", "別の Chrome ウィンドウ", "interceptor-test を起動" | Workflows/LaunchTestProfile.md | --profile-directory を使用した分離された Chrome プロファイルの初回セットアップと日々の起動、拡張機能の読み込み、コンテキスト ID の命名 |
| VerifyDeploy | "デプロイを検証", "デプロイを確認", "デプロイを確定", "デプロイ検証" | Workflows/VerifyDeploy.md | 実際の Chrome で URL を開き(--context interceptor-test を使用)、構造化された読み取りを行い、エラーと証拠を確認 |
| ScrubFlow | "フローをスクラブ", "フローを動画に記録", "モーションのバグ", "アニメーションのカクつき", "トランジションの途切れ", "ちらつき", "フローギャラリー", "スクリーンショットでは見逃す動きを検出" | Workflows/ScrubFlow.md | Web フローを動画に記録し、SSIM スコア付きフレームを抽出(Tools/FrameScrub.ts で調査・スクラブ)して、静止スクリーンショットでは見逃すモーション/アニメーション/フローのバグを検出 |
| Reproduce | "再現", "バグを再現", "ページをデバッグ", "ページを確認", "画面が真っ白" | Workflows/Reproduce.md | コードを分析する前に問題のあるページを開き、コンソールエラーとネットワークの 404 を取得 |
| ReadAndExtract | "値を抽出", "ページを読む", "事実を取得", "SPA の状態" | Workflows/ReadAndExtract.md | 読み取りと SPA の状態抽出を組み合わせ、タスクごとに適切なサーフェスを選択し、モード切り替えルールに従う |
| DriveRichEditor | "Canva を操作", "Docs を操作", "Slides を操作", "リッチエディター", "シーン", "シーングラフ", "キャンバス描画" | Workflows/DriveRichEditor.md | キャンバス描画型エディター向けのシーングラフとイベントディスパッチのレシピ |
| OverrideXhr | "リクエストをオーバーライド", "リクエストのオーバーライド", "500 を強制", "レスポンスを書き換え", "XHR を変更" | Workflows/OverrideXhr.md | パッシブオーバーライドを設定して実行し、検証して解除 |
| ScreenshotForVlm | "VLM 用スクリーンショット", "VLM スクリーンショット", "エージェントのスクリーンショット", "WebP 1568" | Workflows/ScreenshotForVlm.md | VLM の予算に合わせたスクリーンショットのレシピ。1 コマンドの予算。--save --format webp --target-max-long-edge |
| MultiPageCompare | "ページを比較", "複数ページを比較", "N ページにまたがる事実", "X がデザインしたものと Y がデザインしたもの" | Workflows/MultiPageCompare.md | ページごとに順番に open --text-only を実行し、タブを頻繁に切り替えない |
| CaptureBackgroundedApp | "Brave/Signal/Mail/X のスクリーンショット", "バックグラウンドアプリをキャプチャ", "遮られたウィンドウをキャプチャ" | Workflows/CaptureBackgroundedApp.md | アクティブ化せずに、指定したアプリのウィンドウを CGS でキャプチャ |
| DriveBackgroundedApp | "Mail をスクロール/TextEdit に入力", "バックグラウンドアプリを操作", "フォーカスなしでクリック" | Workflows/DriveBackgroundedApp.md | 最前面でないアプリへの入力に AX press、値の設定、postToPid を使用 |
| DispatchAppleEvent | "Brave で URL を開く", "Apple Event", "Apple Events", "インテントをディスパッチ", "指定したアプリで開く" | Workflows/DispatchAppleEvent.md | intent dispatch --bundle <id> --script — スクリプト内で activate は使用しません |
| ReadAxTree | "AX ツリー", "アクセシビリティツリー", "Cursor/Slack に何があるか", "アプリ内のボタンを見つける" | Workflows/ReadAxTree.md | AXManualAccessibility を使用して Electron を起動する macos tree |
| TrustedInputGate | "信頼された入力", "OS レベルの入力", "isTrusted", "サイトが合成入力を拒否", "HID ソースの状態" | Workflows/TrustedInputGate.md | --trusted によるエスカレーション、ブラウザー側の __interceptor_trust マーカー、使い分け |
| VmLifecycle | "VM を作成", "VM のライフサイクル", "Linux VM", "macOS VM", "ゴールドイメージ", "VM をクローン", "VM のスナップショット" | Workflows/VmLifecycle.md | ライフサイクル全体を扱う interceptor macos vm * と Lume 移行テーブル |
| RecordFlow | "フローを記録", "ワークフローを記録", "フローをキャプチャ", "モニターを開始" | Workflows/RecordFlow.md | モニターシステムでブラウザー操作を記録し、再生可能なプランスクリプトをエクスポート |
| RecordAndReplayMacFlow | "Mac のフローを記録", "ネイティブフローを記録", "Cursor/Mail/Finder での操作を見て" | Workflows/RecordAndReplayMacFlow.md | macos monitor で AX イベントを記録し、エクスポートして再生 |
| ReplayFlow | "フローを再生", "再生", "リグレッションチェック", "フローを実行" | Workflows/ReplayFlow.md | 記録されたプランスクリプトをステップごとに実行し、各ステップを検証してリグレッションを報告 |
| TestForm | "フォームをテスト", "フォームに入力", "フォームテスト", "フォームを確認" | Workflows/TestForm.md | フォームフィールドを検出し、テストデータを入力して送信し、結果を検証 |
| Update | "更新", "バージョンを確認", "再ビルド", "ブリッジをインストール", "Computer Use を有効化" | Workflows/Update.md | プル、再ビルド、再インストール、Computer Use 用ブリッジのインストール、エンドツーエンドの検証 |
例
- 「ブログのデプロイを検証して」→ VerifyDeploy:事前チェックの分離ゲートを実行し、
interceptor open <url> --context "$INTERCEPTOR_TEST_CONTEXT_ID"、read --markdown、Tools/Capture.shでキャプチャし、証拠とともに報告します。 - 「メニューのアニメーションが変に見える/チェックアウトのフローはきれいに表示される?」→ ScrubFlow:フローを動画に記録し、
bun Tools/FrameScrub.ts <recording> scrub --at <sec>を実行して、自動でフラグ付けされたフレームを読み取り、マニフェストを引用します。モーション/インタラクションの ISC には、単一の静止画ではなく、この方法かフローギャラリーが必要です(Algorithm Rule 1)。 - 「デプロイ後、このページが真っ白なのはなぜ?」→ 再現:まずページを開き、
eval --mainでコンソールエラーをキャプチャし、net logで失敗したリクエストを確認してから、コードを分析します。 - 「このフローを承認するところを記録して、その後毎晩再生して」→ RecordFlow + ReplayFlow:
monitor startを実行し、オペレーターが操作して、monitor export <sid> --planを実行します。後でプランスクリプトを再生します。
注意点
interceptorが rc=137 で即座に終了し、出力がゼロの場合、フリーズではなくコード署名が無効です。 署名が古くなったアドホック署名済みバイナリは、カーネルによって SIGKILL されます(システムイベントの後、2026-06-10 に両方のバイナリで発生を確認)。診断方法:バイナリを /tmp にcpし、コピーにcodesign -s - -fを実行してから起動します。コピーが動作する場合は、実際のバイナリに再署名します:codesign -s - -f /opt/homebrew/bin/interceptor && codesign -s - -f /opt/homebrew/bin/interceptor-daemon。両方とも再署名する必要があります。CLI はinterceptor-daemon --standaloneを起動するため、デーモンの署名が古いままだと「daemon failed to start. Check /tmp/interceptor.log」と表示されますが、ログは作成されません。(2026-06-10.)- スクリーンショット — 実際の動作(0.22.2)。 すべてのキャプチャを
Tools/Capture.sh経由にしてください。以下は、それがラップする生の動作です。- デフォルトの
interceptor screenshotは DOM レンダリング経路です — v0.18.3 以降は依存関係のないネイティブレンダラーです(html-to-imageは削除され、必要に応じてexecuteScript経由で注入されます)。ライブ DOM ツリーからレンダリングし、前面に表示されたタブである必要はありません。別の macOS Space にあるバックグラウンドタブでも問題なく、失敗時は即座に終了します(バックグラウンドタブでタイムアウトまでハングすることはなくなりました)。 --pixelはオプトアウト → 従来のcaptureVisibleTabを使います。ウィンドウのアクティブなタブをキャプチャするため、特定のバックグラウンドタブをキャプチャするには、一時的にそのタブをアクティブにしてフォーカスを戻します。画面が一瞬切り替わるのは仕様です。--pixelではウィンドウが最小化されておらず、表示されている必要があります。最小化されている場合は、すぐに正直なエラーを返します。全ページの--pixelは、ストリップの取得を 1100ms 間隔に制限し(Chrome の毎秒 2 回という上限)、サービスワーカーでつなぎ合わせます。- 信頼性はデフォルトの経路であり、フラグではありません。 「信頼性モード」の切り替え機能はありません。現在の堅牢性は、拡張機能内の最小化ウィンドウ事前チェック(約 30 秒のハングではなく即時失敗)と、CLI の 45 秒のスクリーンショットタイムアウトによるものです。
cli/lib/screenshot-selfheal.tsラッパーは休眠中で未接続のため、これを根拠として挙げないでください。 --saveは CLI の現在の作業ディレクトリに書き込み、filePathを返します(dataUrlは省略されます)。/tmp/pai-screenshots/には書き込みません。ワークフローがそこへcdするのは、--saveの保存先が CWD だからです。--output <path>フラグはありません。位置引数のパスは黙って無視されます。OPERATIONAL_RULES に従い、レビュー用アーティファクトは$LIFEOS_DOWNLOADS_DIR(未設定時はデフォルトで~/Downloads/)に、パイプライン中間生成物は/tmp/に保存します。Tools/Capture.shはこれを標準化します。--saveを指定しない場合、screenshotは完全な base64dataUrlをインラインで返します — PNG が 10MB 以上になり、トランスクリプトが埋め尽くされます。エージェントのコンテキストからは、必ず--saveを指定してください。- フラグ
--target-max-long-edge N(長辺を制限し、Skia の 16384 上限を回避)、--scale、--selector、--element N、--region X,Y,W,Hは DOM レンダリング内で実行されます。--clipは--regionの非推奨エイリアスです。
- デフォルトの
- DOM レンダリングのスクリーンショットでは、UA のデフォルトのウィジェット外観が描画されません。そのため、ボタンや入力欄のコントラスト不具合を見落とすことがあります。 CSS の
backgroundがない素の<button>は、実際のブラウザーでは UA の白または #efefef の背景で表示されます(iOS Safari で特に顕著です)。しかし、DOM レンダリングのキャプチャでは透明であるかのように描画されるため、白地に白文字のコントラスト不具合がスクリーンショット上では問題ないように見えます(2026-08-07:きれいに見えるキャプチャの後、Surface の共有ボタンがモバイルで読めない状態でリリースされました)。フォームコントロールのコントラストに関する主張は、getComputedStyle(...).backgroundColor(transparent なら UA の背景が表示されます)または--pixelキャプチャで確認してください。デフォルトの DOM レンダリングは使わないでください。プロパティで設定された textarea/input の値も同様に描画されません。 - DOM レンダリングのスクリーンショットでは、CSS 疑似要素が生成するコンテンツが欠落します。
::before/::afterのコンテンツ、特に CSS カウンターは、ライブブラウザーでは描画されますが、デフォルトの DOM レンダリングキャプチャでは消えるため、画面上では正常でもスクリーンショットではページが壊れているように見えることがあります。ページを「修正」する前にeval --mainで位置や計算済みスタイルを確認してください。自分で作成するコンテンツには、CSS カウンターより実際の DOM テキストを優先してください。(2026-07-11、欠落した番号付きレールが eval によって存在すると確認されたことから発見。) - DOM レンダリングのスクリーンショットは、デフォルトでスクロール位置を無視します。
interceptor screenshotはドキュメントの y=0 からキャプチャします。window.scrollTo/scrollIntoView/keys Endを実行しても、スクリーンショットのフレームは移動しません。縦長のページでは、--region X,Y,W,H、--selector <css>、--element <ref>、または--pixel --full(スクロールしてつなぎ合わせます。ウィンドウが表示されている必要があります)を使ってください。(2026-04-27、2026-06-17 時点でも該当。) - チェックボックスに対する
clickは、チェック状態が切り替わらなくてもclicked [eN]と報告することがあります。 実際のフォームで 2 回確認されています(2026-07-18):<input type="checkbox">がラベルで囲まれており、clickは成功しましたが、チェックボックスが未チェックのままフォームが送信され、同じ要素に対するact <ref>は「unsupported input type」エラーになりました。クリック後にチェックボックスの状態を確認してください(eval --main '...checked')。状態が反映されていない場合は、フォーム上でeval --mainを使ってchecked=trueを設定し、本物のフォームを送信します(form.submit())。これでも正規のセッション/CSRF/POST 経路が使われます。クリックが状態を切り替えたと決めつけないでください。 - 2 つのエージェントセッションがテストコンテキストを共有している場合、
--currentによるキャプチャと、引数なしのread/evalはアクティブなタブに従います。そのタブはもう一方のセッションによって変更され続けます。--pixelのページ違いと同じ類の問題です(2026-06-11)。2026-07-18 に再発し、Capture.sh --currentがもう一方のセッションのタブを撮影しました。必ず URL をCapture.sh <url>に渡してください(管理対象タブでの移動とキャプチャがアトミックに行われます)。また、read/evalをまとめて実行する前に、必ずopen --reuseをやり直してください。ウィンドウ内に他のセッションのタブがある場合はCleanupTabs.shを実行しないでください。自分の管理対象タブを 1 つ残すより、他のタブを閉じる方が問題です。 - 同じ URL のタブが複数あると、
--contextなしではルーティングが混乱します。 2 つのタブがどちらもlocalhost:5180/を読み込んでいるとき、tab switch <id>はokと報告しても、視覚的にアクティブな Chrome タブが切り替わらない場合があります。重複を閉じるか、新しく開いた単一のタブで作業するか、--context <id>を渡して明確にスコープを指定してください。 - ほとんどのサイトでは
evalが CSP によってブロックされます。 ページのメインワールドで実行するにはeval --mainを使ってください。--mainを指定しても、厳格な CSP(script-src 'self')では文字列の eval がブロックされます。短い式を渡し、Functionコンストラクターのパターンは避けてください。 - ブリッジには Sparkle.framework が必要です。 Apple Silicon 上でソースから再ビルドする場合、
Sparkle.frameworkが/usr/local/Frameworks/にインストールされるまでブリッジは読み込まれません。実行中のブリッジは~/.local/share/interceptor/interceptor-bridge.app/Contents/MacOS/interceptor-bridgeにある.appバンドル内のバイナリです(LaunchAgent はcom.interceptor.bridge、plist は~/Library/LaunchAgents/com.interceptor.bridge.plist)。/usr/local/bin/interceptor-bridge(古いコピー)ではありません。Update ワークフローがこれを処理します。設定を忘れた場合は、/tmp/interceptor-bridge.stderr.logにdyld[*]: Library not loaded: @rpath/Sparkle.framework/...と表示され、bridge: not runningになります。(2026-05-03、ブリッジの構成は 2026-06-17 に修正。) - マニフェストのバージョンを上げた場合、拡張機能の手動再読み込みと再ピン留めが必要です(ソースからのインストールの場合)。 Chrome はパッケージ化されていない拡張機能を自動で再読み込みしません。また、ピン留めされた
Extension/のコピーは上流の変更に自動で追従しません。ソースから再ビルドした後は、Update ワークフローで再ピン留めし、chrome://extensionsで既存の拡張機能カードを削除してから、ピン留めしたディレクトリから「Load Unpacked」を再度実行してください。拡張機能のkeyは決定的であるため、再読み込み後も拡張機能 ID は変わりません。署名済みの.pkgでインストールした場合は、インストーラーが処理します。 - 「native port disconnected」はスクリーンショットのエラーではありません。 Chrome の Native-Messaging stdio ポートが切断された(拡張機能の SW が再起動した/Chrome が閉じた)ことをデーモンがログに記録しているだけです。デーモンは稼働を続け、WebSocket トランスポートに切り替わります。WS もリレーも稼働していない場合、コマンドはキューに入り(上限 50)、タイムアウトします。解決策は拡張機能の再接続です(タブを再読み込みする/設定済みのブラウザーを開き直す)。デーモンを再起動する必要はありません。
- 「screenshot-runner.js could not load」はフレームごとの注入失敗を示します。 (以前の「html-to-image library not loaded」エラーはなくなりました。v0.18.3 でライブラリーがネイティブレンダラーに置き換えられたためです。)ページがスクリプト注入を許可していない(
chrome://、Web Store、PDF ビューアー、厳格な CSP が設定されたフレーム)、注入中にタブが移動した、または(バイナリーのアップグレード後に最も多く発生する)バンドル内の runner がデーモンと一致しない古い読み込み済み拡張機能が原因です。0.22.37 以降、DOM レンダリングのキャプチャに失敗すると自動で--pixelにフォールバックするため、通常は画像を取得できます(結果にフォールバックが明記されます。--no-fallbackで無効にできます)。ただし、古い拡張機能という根本原因は解消する必要があります。拡張機能を再読み込みしてください。署名済み.pkgから再インストールするか、ソースからのインストールの場合は、再ピン留めしてピン留め済みのExtension/ディレクトリから「Load Unpacked」を再度実行してください。 - デーモンと拡張機能の間の WebSocket は、半稼働状態で固まることがあります。Interceptor が使えないと断定する前に、まず別の動詞ツリーを試してください。 症状:
status/contexts/tabsは応答する(コントロールプレーンのメッセージタイプ)が、screenshot/evalはタイムアウトまでハングする(データプレーンのタイプ)。Capabilities Overview の動詞はそれぞれ異なる WebSocket メッセージタイプを使うため、screenshotのフリーズがeval、net log、tree、read --markdown、monitor、inspectに影響することはほとんどありません。復旧手順:(1)キャプチャ経路を切り替える(pixel↔DOM レンダリング — 異なるメッセージタイプを使うことで復旧することがあります)、または別の機能クラスの動詞に切り替えます。screenshotの代わりにread --markdown/eval --main document.body.innerText、失敗したリクエストの確認にはnet logを使います。(2)pkill -f interceptor-daemonを 1 回実行し、1 回だけ再試行します。(3)拡張機能を再読み込みします(画面に「Interceptor extension is wedged — please reload it from chrome://extensions.」と表示されます)。ここで停止します。3 つすべてに失敗した場合に限り、オペレーターに検証をキャプチャできないと伝えてください。screencapture/osascriptにフォールバックしてはいけません。 これによって防ぐべき繰り返しの誤りは、evalなら 1 回のツール呼び出しで答えられたのに、screenshotのタイムアウト 1 回で「Interceptor が壊れている」と主張することです。 (2026-05-13、2026-06-17 に内容を強化。) - ブリッジ停止時の自動修復(macOS の
macos_*経路のみ — ブラウザーのスクリーンショットにブリッジは不要です)。 「Loaded」は「running」を意味しません。launchctl listだけでなく、interceptor statusでプロセスを確認してください:
エージェントが実行するのはinterceptor status | grep -A2 '^bridge:' # running + pid/socket, or not running launchctl print "gui/$(id -u)/com.interceptor.bridge" 2>&1 | grep -E 'state|program|pid' launchctl kickstart -k "gui/$(id -u)/com.interceptor.bridge" # restart (loaded-but-dead).appバンドル内のバイナリ(~/.local/share/interceptor/interceptor-bridge.app/Contents/MacOS/interceptor-bridge)であり、/usr/local/bin/interceptor-bridge(古いコピー)ではありません。署名が古いアドホック署名済みのブリッジが SIGKILL されると、ThrottleIntervalによって約 5 秒ごとに再起動を繰り返します。/usr/local/binのコピーではなく、.appの MacOS バイナリに再署名してください。Tools/HealBridge.shは「読み込み済みだが停止」の検出と 1 回の kickstart をまとめて実行します。(2026-06-17.) AXEnhancedUserInterfaceはブリッジから削除されました(「VoiceOver が有効」と解釈され、AppKit アプリを前面に表示してしまう副作用があったためです)。ブリッジは Electron の起動にAXManualAccessibilityのみを使います。AXEnhancedUserInterfaceを設定する古いコードに基づく案内は無視してください。screenshot --pixel --tab <id>は別のページをキャプチャすることがあります —--pixelはアクティブなタブを追います。--pixelはcaptureVisibleTabであり、画面上でアクティブなタブを撮影します。直前のタブ切り替えが反映されていない場合、対象ではなくオペレーターの前面タブを撮影します(2026-06-11 に発生:テスト中の localhost サイトを要求したのに、オペレーターが表示していた無関係なサイトを撮影)。返された画像を必ず読み取り、証拠として引用する前に、指定したページであることを確認してください。これがTools/Capture.shが--pixelフォールバック経路で画像を読み返す理由です。この漏えいによって、オペレーターの機密ウィンドウを撮影する場合もあります(2026-07-18:デプロイ検証中の--pixel再キャプチャで、オペレーターが開いていた実際の非公開管理ダッシュボードが返されました。撮影は禁止されており、読み返し後にファイルを削除しました)。テストタブですでに開いているページを再検証するために再キャプチャする場合は、別の--pixelを試すより、デフォルトの DOM レンダリングとアセットのバイト比較を優先してください。AppleScript によるタブ切り替えは使わないでください。Hard Prohibitions により禁止されています。代わりに、視覚以外の動詞ツリー(read --markdown、eval --main、net log)で回答するか、上記の WebSocket フリーズ復旧手順に従ってください。(2026-06-11、AppleScript の回避策は 2026-06-13 に削除。)- 全ページのスクリーンショットだけでは、細部の見た目に関する主張を確定できません。まず拡大してください。 モデルが見る前に画像は長辺が約 1568px になるよう縮小されるため、幅 2000px のページにある 40px のロゴは、モデルにはぼやけて見えます。出力されたスクリーンショットを切り抜いても、細部は元に戻りません。縮小時にすでに失われているためです。
bun Tools/Zoom.ts <image> --x N --y N --w N --h Nは、フル解像度の元画像から切り抜き、予算内に収まるよう該当領域を拡大するため、テスト対象のピクセルが十分な大きさで表示されます。ロゴ、字形、フォントのレンダリング、アイコン、数ピクセル単位の間隔に関する主張では必ず使ってください。これは、要素が存在することは確認できても、それが正しい要素かは確認できていなかった、間違ったロゴの事例(2026-07-19)の原因となった種類の主張です。座標は元画像上の絶対ピクセルです。DOM 座標を読み取るにはevalを使い、その領域を渡してください。バックエンドはmagick、なければffmpegです。(public PR #1657, @elhoim.) - 機密アプリのゲート。 前面に表示されているアプリが拒否リストにあるバンドル(Keychain、1Password、Dashlane、LastPass、Bitwarden、System Settings、Chase、Bank of America、Wells Fargo)の場合、ブリッジは
type/keys/click x,y/dragを拒否します。拒否されたことを明示し、回避しないでください。 - VM の
paused-stateスナップショットには制限があります。--paused-stateを使うには、VM の設定でvalidateSaveRestoreSupport()が true を返す必要があります。macOS ゲストでは対応していますが、一部の Linux 設定では対応していません。--disk-onlyは常に使用できます。 - VM ホストの TCC 許可: ブリッジには
com.apple.security.virtualizationエンタイトルメントが必要です。インストール場所に関するsetup_requiredが表示される場合は、ブリッジを~/Documentsまたは~/Desktopの外に移動してください。 - ローカルの extract.ts カスタマイズは古くなりました。 スライス上限を 10M に引き上げる v0.13 より前のパッチは不要になりました。上流の
withTruncationMarker、--fullフラグ、アクションごとのmaxCharsによって、明示的な切り詰めマーカー(... (truncated: showed X of Y chars ...))付きで正しく処理されます。 - 古いバイナリが黙って Default にルーティングする — フォールバック事例(2026-05-23)。 再ビルドした成果物が
$INTERCEPTOR_SRC/dist/に配置されても、/opt/homebrew/bin/にコピーされないままだと、古いバージョンの CLI が残ります。古いバイナリは--contextとcontextsサブコマンドを認識しません。フラグをエラーなしで受け付けた後、デーモンが見つけた Chrome 接続(通常はオペレーターの Default プロファイル)を使ってコマンドをルーティングします。症状:エージェントがinterceptor open <url> --context "$INTERCEPTOR_TEST_CONTEXT_ID"を呼び出し、隔離されたタブを期待したのに、オペレーターが作業中のウィンドウにタブが開きます。検出方法:interceptor --versionが0.16.0より古い、またはinterceptor open --helpに--context関連のフラグが表示されない、またはinterceptor contextsが「unknown command」を返す場合です。緩和策:上記の Preflight Isolation Gate はバージョン不一致を終了コード 4 でハードフェイルします。すべてのワークフローで最初のステップとして実行してください。復旧するにはWorkflows/Update.mdを実行し、その後pkill -f interceptor-daemonを実行します。次の呼び出しで新しいデーモンが再起動されます。 - クラウド同期ディレクトリ内でブリッジをビルドすると、コード署名が壊れます。完全な署名手順は次のとおりです。 ソースのチェックアウトが iCloud Drive、Dropbox、Google Drive 内にある(またはそこへシンボリックリンクしている)場合、同期によってビルド済み
.appのコード署名エンベロープが削除されます(codesign -v→ "code has no resources but signature indicates they must be present")。そのバンドルを所定の場所にコピーすると壊れた状態が引き継がれ、ブリッジは SIGKILL ループに陥ります(launchctl print→last exit reason = OS_REASON_CODESIGNING)。根本的な解決策は、チェックアウトをローカルディスクに移すことです。 すでに壊れたバンドルを修復するには、ローカルのステージング済みコピー(~/.local/share/interceptor/interceptor-bridge.app)に対して、次の順で作業します。xattr -crを実行 →codesign --force --deep --sign - .../Contents/Frameworks/Sparkle.frameworkを実行 → MacOS バイナリ、次に .app に対してcodesign --force --sign - --entitlements "$INTERCEPTOR_SRC"/scripts/entitlements-bridge.plistを実行します(これはbuild-bridge.shの開発用署名フォールバックとまったく同じです)。アプリ全体にcodesign --deepを実行しないでください。ネストされた Sparkle の署名が誤った状態になり、codesign -vは通るのにカーネルが引き続き終了させます。 bash scripts/install.sh --chromeは、修復したばかりのブリッジを再び壊します。install-bridge.shを呼び出し、元の(まだ壊れたままの)バンドルを修復済みのものに上書きコピーするためです。実行後に再署名するか、ブリッジの署名後は再実行しないでください。kickstart -kを繰り返した後に launchd のjob state = spawn failedが発生します。 短時間に再起動を繰り返すと launchd がスロットリングされ、失敗状態になります(runsは増えますが、バイナリを直接起動すると正常に動作します)。復旧するにはlaunchctl bootout "gui/$(id -u)/com.interceptor.bridge"を実行し、その後、新たにlaunchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/com.interceptor.bridge.plistを実行します。kickstart をもう一度実行するのではありません。- デーモンは永続的な LaunchAgent(
com.interceptor.daemon、追加日 2026-07-04)として実行されます。これは、拡張機能のコンソールに「native keepalive ping failed / forcing reconnect」と表示され続ける問題への恒久的な解決策です。 このメッセージは、デーモンが一時的に停止している(アップグレード、クラッシュ、pkill)ときに表示されます。デーモンが落ちると拡張機能のネイティブメッセージングの中継ポートが切断され、再接続するまで SW にping failedが記録されます。それ以外の中継アーキテクチャは正常です。1 つのシングルトンがソケットを所有し、Chrome プロファイルごとに起動する薄い中継プロセスがシングルトンにつなぎます(relay: registered with singleton→received ping, sending pong)。シングルトンを常時起動(RunAtLoad+KeepAlive、plist~/Library/LaunchAgents/com.interceptor.daemon.plist→/opt/homebrew/bin/interceptor-daemon --standalone)しておけば、中継プロセスは常に稼働中のシングルトンを見つけられるため、エラーが発生せず、すぐに再接続できます。デーモンのバイナリをアップグレードしたら、launchctl kickstart -k "gui/$(id -u)/com.interceptor.daemon"を実行して新しいバイナリを読み込んでください(ブリッジと同じ手順です)。確認方法:interceptor statusのデーモン PID が launchd の PID と一致し、定常時の/tmp/interceptor.logの一定期間にping failed/forcing reconnectが 0 件であることを確認します。 - ブリッジにアドホック署名し直すと、TCC の許可がリセットされます。 新しいアドホック署名は新しいコード ID となるため、アクセシビリティ/画面収録/マイクの許可が
deniedになり、許可し直すまでコンピュータ操作が停止します(interceptor macos trust --walkthrough、または「システム設定」→「プライバシーとセキュリティ」から再度許可してください)。ブラウザーの機能には影響しません(拡張機能ベースで、TCC を使用しないためです)。公証済みのInterceptor-Full-<v>.pkgは Sparkle によるアップデート後も Developer-ID ID が維持され、これらの問題を回避できます。TCC の変更が問題になる場合は、ブリッジにこちらを使用してください。 - 非表示のタブではエラーなしにアニメーションやオブザーバーのアクティビティがゼロと報告されます。「機能が壊れている」とまったく同じように見えるため、注意が必要です。 ResizeObserver、トランジション、遅延読み込み、スクロール時の表示が発火しないと判断する前に、
document.visibilityStateを確認してください。値がhiddenの場合、スケジュールされた描画関連 API はすべて停止しているため、観測結果に意味はありません。Tools/VerifyViewport.tsを使って再実行してください(「Rendering-Lifecycle Gate」セクションを参照)。これが原因だと分かる兆候は、測定値に矛盾がなく、カウンターがちょうど 0 または 1 のままで、ページ独自のコールバックを手動で呼び出すと「修正」されることです。(2026-07-30、レスポンシブナビゲーションの検証中に発見。ピン留めしたテストウィンドウが、セカンダリディスプレイの非アクティブな領域に置かれていました。) interceptor macos cdp raw <method> '<json>'はパラメーターを位置指定で受け取ります。--params/--paramはどちらもerror: Invalid parametersで失敗します。CDP コンテキストが複数ある場合は、--contextも渡す必要があります。デーモンはナビゲーションのたびに URL 名のエイリアスコンテキストを作成するため、ホスト名由来の安定した ID(cdp:127-0-0-1)を指定し、エイリアスを削除してください。すべての CLI 応答には[id] → verbのトレース行が先頭に付きます。JSON を解析する前にこの行を取り除く必要があります。また、この行には[が含まれるため、単純なindexOf('[')ではペイロードではなくトレースが見つかります。interceptor macos windows --app "Google Chrome"は、メインの Chrome プロセスのウィンドウしか列挙しません。 独自の--user-data-dirを指定して起動した 2 つ目の Chrome はバンドル ID を共有しますが、そのウィンドウは表示されないため、AX は操作や観測に使える経路ではありません。CDP を使用してください。- 何かが応答しなくなったときは、まず
interceptor diagnoseを実行してください(0.22.2 以降)。 このコマンドはデーモンのスプリットブレイン、つまりソケットデーモン(CLI が通信する相手)と NMH マニフェストのパス(Chrome が起動する相手)の不一致を検出します。マニフェストのpathを正規のバイナリに向けることで修正できます。jq '.path="/opt/homebrew/bin/interceptor-daemon"'を~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.interceptor.host.json(および Brave のもの)に対して実行し、その後pkill -f interceptor-daemonを実行して、アクティブなコマンド(interceptor contexts)を 1 回実行し、正しい場所から再起動します。0.22.37 へのアップグレード時(2026-07-28)に、実環境で 2 つの落とし穴が見つかりました。Chrome の NMH マニフェストが$INTERCEPTOR_SRC/daemon/.generated/内のファイルへのシンボリックリンクになっていること(install.sh によってリポジトリツリーを指す状態で再作成されるため、/opt/homebrew/binを指す通常のファイルに置き換えてください)と、以前の iCloud チェックアウトから起動した古いスタンドアロンデーモンはpkill -f interceptor-daemonの後も残ることです。後者は diagnose の出力にある PID を使って終了させてください。 /opt/homebrew/bin/interceptor{,-daemon}をその場で上書きするとOS_REASON_CODESIGNINGが発生します。古いバイナリにcpで上書きした後、com.interceptor.daemonLaunchAgent の起動がカーネルによって SIGKILL されます(launchctl print→last exit reason = OS_REASON_CODESIGNING)。ビルド時にアドホック署名されていても発生します。インストール済みのコピーに対してその場で再署名し(codesign --force --sign - /opt/homebrew/bin/interceptor-daemonと.../interceptor)、その後launchctl kickstart "gui/$(id -u)/com.interceptor.daemon"を実行してください。(2026-07-28 のアップグレードで発生し、2026-08-10 に再発しました。77 分間に SIGKILL のクラッシュレポートが 92 件発生しました。アップデートワークフローの手順 4 が恒久的な解決策になりました。ステージング → 署名 → アトミックなmvの順に行い、稼働中のパスへのcpは決して実行しません。)- ソースからブリッジを再ビルドすると TCC の許可がリセットされます。古い行を再度オンにしても機能しません。 アドホック署名が変更されると、macOS は
interceptor-bridgeのアクセシビリティと画面収録の許可を削除します。その症状は、ブリッジが実行中なのに、すべてのアプリで a11y ツリーが空になり、windows: []が返され、Apple Events の許可ダイアログでmacos script runがタイムアウトすることです。interceptor macos trustで確認してください。古い「システム設定」の行は以前の署名にひも付いているため、それらを切り替えても何も変わりません(実環境で確認したところ、古いレコードが 5 件蓄積していました)。修正方法:tccutil reset Accessibility com.interceptor.bridge && tccutil reset ScreenCapture com.interceptor.bridgeを実行してブリッジを kickstart し、macos windowsを 1 回呼び出して再登録します。その後、担当者が「システム設定」→「プライバシーとセキュリティ」→「アクセシビリティ」と「画面収録」で新しい行をオンにします(行が表示されない場合は~/.local/share/interceptor/interceptor-bridge.appを追加します)。恒久的な解決策:ビルド前にINTERCEPTOR_SIGNING_IDENTITYに実際の Developer ID を設定し、再ビルド後も署名と TCC の許可が維持されるようにします。(2026-07-28 のアップグレード時に発生。) - マニフェストの更新後、拡張機能の再読み込みを何も操作せずに済ませられる場合があります。 上記の「カードを削除してから Load Unpacked を実行する」という手順に反し、Chrome を完全に終了して再起動すると、GUI 操作なしでピン留めしたアンパック済み拡張機能が新しいマニフェストバージョン(0.22.2 → 0.22.37)で再び有効になりました。コンテキストは自動的に再接続されました。まず再起動を試し、拡張機能のカードが無効状態で再表示される場合に限り、手動で再読み込みしてください。(2026-07-28 のアップグレード時に確認。)
- bash 5.2 以降では
Tools/Pin.shのチルダ除去処理が何もせずに終了していました(2026-07-04 に修正済み)。${SRC/#$HOME/~}は置換文字列のチルダ展開を行い、/Users/<name>に戻っていました。そのためPINNED_FROM.txtに絶対ホームパスが記録され、Pin.sh 自身の漏えい検出処理で FATAL が発生していました。引用符で囲んだ~${SRC#$HOME}の形式(rel_home())に修正済みです。「absolute home path survived the scrub」というメッセージで再ピン留めが FATAL になる場合は、bash のバージョンとこのヘルパーを確認してください。 - 自動起動による復旧(
EnsureTestProfile.sh)— 安全性を担保するのはプロフィール引数ではなく、再検証ループです(2026-07-07)。 テストプロフィールのウィンドウが開いていない場合、EnsureTestProfile.shは設定された--profile-directoryを起動し、PINNED コンテキストが接続されるまでPreflightIsolation.shをポーリングしてから処理を続行します。誤ったプロフィールをリスクなしで自動起動する可能性はあります。これは、PreflightIsolation.shがINTERCEPTOR_TEST_CONTEXT_IDとコンテキスト全体が一致し、Default を明示的に拒否した場合にのみ終了コード 0 を返すためです。誤ったプロフィールを起動すると、preflight は失敗し続けるため、エージェントがそのプロフィールを操作することはありません。実際の制限は 2 つあります。(1)macOS では、Chrome がすでに起動しているとopen -a "Google Chrome" --args --profile-directory=…は引数を無視します(既存のウィンドウをアクティブにするだけです)。LaunchTestProfile.shはCHROME_BINを直接使う分岐でこれを回避し、Chrome の起動中でも新しいプロフィールウィンドウを開きます。起動に「成功」したのに新しいウィンドウが表示されない場合は、openがすでに起動中の Chrome に対して実行されたケースです。この場合に実際に機能するのは、バイナリを直接使う分岐です。(2)起動によって新しいコンテキスト UUID が接続された場合(拡張機能の再読み込みによって UUID が変わった場合)、preflight は固定値と一致せず、EnsureTestProfileは永続的な解決方法を示して停止します(ポップアップでコンテキスト名をinterceptor-testに設定してください)。識別されていない UUID に再バインドすることはありません。自動起動するのは終了コード 5/6 の場合のみです。終了コード 7(Default/操作対象)および 8(設定未指定)では、自動起動しません。
Linux + Flatpak ブラウザー — 4 時間の授業(2026-07-19、Fedora)
Fedora で Chrome を Flatpak(com.google.Chrome)としてインストールした環境で、1 回のセッション中に 4 つすべてが明らかになりました(--filesystem=/tmp --filesystem=home --die-with-parent を追加する ~/.local/bin/google-chrome shim 経由で起動)。Linux インストールをデバッグする前に、このセクションをお読みください。最初の症状は拡張機能が応答しないように見えますが、原因は別にあります。(公開 PR #1682、@pkumaschow。)
- Flatpak サンドボックス内で作成されたデーモンソケットは、ソケットファイルがはっきり見えていてもホストの CLI から接続できません。
/tmpは双方向で本当に共有されています(ホストで書き込んだマーカーはサンドボックス内から読み取れ、その逆も同様です)。そのため、ls -la /tmp/interceptor.sockではファイルが表示されますが、同じ秒にinterceptor statusを実行してもdaemon: not runningと報告されます。エンドポイントはサンドボックスの名前空間にあり、見えているファイルは影です。解決策は、サンドボックス化されていないブラウザーを使うことであり、Flatpak の権限を変更することではありません。 Interceptor がサポートするブラウザーの 1 つにネイティブ版 Vivaldi があります。そのリレーのソケットにはホストからアクセスでき、CLI はすぐに接続します。先に NMH マニフェストをそのブラウザー専用のディレクトリ(例:~/.config/vivaldi/NativeMessagingHosts/)へコピーしてください。 - ウィンドウのない孤立した Flatpak インスタンスがポート 19222 を見えない状態で占有することがあり、確認できる PID に対して
pkillを実行しても解放されません。 オペレーターには Chrome のウィンドウが見えないため、「Chrome は開いていない」と報告するのももっともですが、bwrap --args N -- chrome --profile-directory=Xは生きたままで、デーモンがポートを占有し、あとから起動するすべてのリレー(別のブラウザーのものも含む)を妨げます。見えている子プロセスにkill <pid>を実行しても、bwrapには伝播しません。確実に解放するにはflatpak kill com.google.Chromeを使います。 リレーがポートの占有を報告しているのに、ブラウザーが見た目上起動していない場合は、必ずこれを確認してください。 - リレーが接続するのは自ら起動したシングルトンのみです。起動に失敗した重複プロセスは、終了時に先行プロセスのソケットを削除します。 ログには
spawning detached standalone daemon→ws port 19222 already held ... exiting this duplicate→detached standalone daemon did not become ready before timeout→falling back to in-process singleton→exiting so the existing daemon serves everyoneという特徴的な流れが記録されます。通常の ws クライアントとして接続する方法へフォールバックすることはありません。その結果、別のデーモンがポートを占有している間に CLI を呼び出すと、問題が悪化します。呼び出すたびに重複プロセスが自動起動して稼働中のソケットを削除するため、問題の診断によって問題が再発します。ソケットが消え続ける場合は、CLI コマンドの実行をやめ、まず所有者を解決してください。(上流で修正すべき点:デーモンは自ら作成していないソケットを削除してはいけません。) --load-extensionは機能しません(Chrome 137 以降。150 でも無視されることを確認済み)。 プロファイルにはデフォルトのコンポーネント拡張機能 5 つしか読み込まれません。拡張機能を読み込むには、chrome://extensions→「パッケージ化されていない拡張機能を読み込む」のファイル選択画面を使うしかありません。Flatpak ブラウザーでは XDG Document Portal 経由になるため、エラーには選択したパスが/run/flatpak/doc/<id>/...と表示されます。このプレフィックスは正常であり、原因ではありません。**~/.claudeはドットフォルダーで、GTK のファイル選択画面ではドットファイルが非表示です。ファイル選択画面で Ctrl+H を押してください。**そうしないと、オペレーターは拡張機能の場所まで移動できません。
同じセッションで発生したエージェント側の落とし穴: Bash から pkill -f interceptor-daemon を実行すると、起動元のシェル自身のコマンドラインにも一致してシェルが終了します。コマンドは終了コード 144 で停止して出力が途中で切れるため、処理が固まったように見えます。文字列を分割する(PAT="intercep""tor-daemon"; pkill -f "$PAT")か、PID を指定して終了してください。
ステルス性の検証
主要なボット検出をすべて通過します。
| チェック | 結果 |
|---|---|
| BrowserScan | 正常 |
| Pixelscan | 明らかに人間 |
| Sannysoft | すべて合格 |
| CreepJS | ヘッドレス判定 0% |
| Fingerprint.com | 未検出 |
| AreyouHeadless | ヘッドレスではない |
実行ログ
ワークフローを完了したら、JSONL エントリを 1 つ追加します。
echo '{"ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","skill":"Interceptor","workflow":"WORKFLOW_USED","input":"8_WORD_SUMMARY","status":"ok|error","duration_s":SECONDS}' >> ~/.claude/LIFEOS/MEMORY/SKILLS/execution.jsonl