mcpField
C
chrome-agent

chrome-agent

github.com/sderosiauxエージェントワークフロー9668 回インストール2 週間前に更新
リポジトリ

chrome-agent について

chrome-agentは、ページの確認や要素操作、結果検証を行うAgent向けのコマンドラインブラウザー自動化スキルです。verdict、入力の到達確認、assertionにより、コマンド実行とページ上の変化を区別します。

主な機能

  1. 01ブラウザーの移動とページ確認
  2. 02UID・CSSセレクター・座標で要素指定
  3. 03フォーム書き込み後の値の再取得
  4. 04verdictとポインター到達確認
  5. 05ページ状態と内容のアサーション

活用シーン

  1. 01ログインやフォーム送信の自動化
  2. 02ページが期待した状態かの確認
  3. 03オーバーレイに阻まれたクリックの診断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sderosiaux/chrome-agent --skill chrome-agent

インストール後、Claude Code で/chrome-agentを入力して読み込まれたか確認します。

詳細

chrome-agent — ブラウザー自動化

which chrome-agent || npm install -g chrome-agent   # or: cargo install chrome-agent

応答の読み取り

状態を変更するすべての操作には、verdict + verdict_reason + next が含まれます。ポインターを対象にする操作には、これらに加えて delivery(イベントを送信する直前の座標でのヒットテスト)が含まれ、別の要素がイベントを受け取った場合は intercepted_by も含まれます。すべての書き込みには、value.requested のほかに、observed_after_ms の経過後に読み戻された value.actual も含まれます。fill、select、check/uncheck では、同じフィールドと時間枠が使われます。

ok:true はコマンドが実行されたことを意味し、ページが指示に従ったことを意味するわけではありません。verdict を確認し、成功を報告する前に、書き込み後の value.verbatim を確認してください。verdict の語ではなく、next に基づいて分岐してください。 next は、次の6つの固定トークンのいずれかです:proceed inspect retry confirm dismiss stop。

verdictverdict_reasonnext対応
changedtree_deltaproceedページが移動しました。移動の内容は delta に示されています。
changednodes_movedproceed同じノードの順序が変わりました(ドラッグが反映されました)。
changedfocus_onlyproceedフォーカスのみが実際の要素に移動しました。ヒットテストのないパスでは、これがアクションの到達を示す唯一の手がかりです。focus.to は、クリックした要素のフォーカス可能な祖先を指すことがよくあります。狙った要素は uid で確認してください。フォーカスがドキュメントに移動した場合は、代わりに identical_tree が返されます。
changedvalue_keptproceed / inspect読み返したときに要素に値が保持されており、差分ではそのことを示せませんでした(シークレットは固定マーカーとして表示されます。また、最初のアクションには比較対象となるツリーがありません)。fill、select、check/uncheck はすべてこの行に該当します。根拠は value.verbatim です。next が理由だけでは決まらない唯一の行です。PAGE の読み取りにも失敗した場合は inspect が返されます。フィールドは確認済みですが、その周囲のページは一度も確認できていません。
changedvalues_lostconfirmページが移動し、値が入っていたフィールドが空になりました。values_lost:[{uid,role,name,was}] に該当する各フィールドが示されます。送信後にクリアされた場合と、送信せず破棄された場合を見分けることはできません。再入力する前に assert text --contains または network で確認してください。再送信すると作業内容が二重に送られる可能性があります。
navigateddocument_replacedinspect新しいドキュメントです。保存済みのすべての uid が無効になっています。
interceptedhit_test_receiverdismiss狙った地点に別の要素があり、その要素がイベントを受け取りました。intercepted_by にその要素が示されます(tag/id/class/uid/z_index/text/modal)。対象については何もわかっていません。実際に返されるのはこちらの行です。実サイト 61 件で発生した 8 件のインターセプトは、すべてこれに該当しました。z_index ではなく tag/id/class を確認してください。8 件中 7 件で auto でした。
interceptedmodal_dialogdismiss<dialog> が showModal() で開かれた場合(または全画面表示の要素がある場合)、最前面のレイヤーを占有し、その外側から届くすべてを受け取ります。まず Escape キーを押してください。まれなケースです。実サイト 61 件で 0 件でした。modal は el.matches(':modal') であるため、多くのサイトで使われている <div role="dialog"> のオーバーレイは、代わりに hit_test_receiver として返されます。
not_keptvalue_revertedstop書き込みは要素に届きましたが、その後は何も保持されていません。value.actual を確認してください。再入力しないでください。同じ書き込みを行っても、同じ結果になります。
not_keptvalue_rewrittenstop値が別のもの(マスク、トリマー、正規化処理)に変わっています。value.actual を確認し、それが望んでいた値か判断してください。
no_effectdelivered_no_changeconfirm対象への到達が証明され、observed_after_ms の間、ツリーに変化はありませんでした。得られる中で最も強い表現です。繰り返しても効果はありません。
unchangedidentical_treeconfirmツールが監視している間、ツリーに変化はありませんでした。到達は証明されていません。
unknownno_baselineinspectこのページでの最初のアクションです。比較対象はありません。
unknownread_failedinspectアクションは実行されましたが、その後のページの読み取りに失敗しました。
unknownidentity_unreadableinspect2 つのツリーが同じドキュメントに属しているとは限りません。
unknownaim_point_off_targetinspect2 回の読み取り結果は一致しましたが、地点を狙えませんでした。何もディスパッチされておらず、外れ方は安定しています。同じ方法で再試行しても、同じように外れます。aim で 2 つのパターンを見分けられます。画面上にあるものの、要素自体のボックスの外(折り返されたインラインボックス、クリップされたコンテナー)にある場合は、ボックスのある子要素を狙ってください。ビューポートの外(固定された壁、ロックされたスクロール)にある場合は、ページの状態を変更してください。スクロールしても移動しません。
unknownscroll_not_settledretry狙った地点の 2 回の読み取り結果が一致しませんでした。まだ移動中でした。何もディスパッチされておらず、外れ方は一時的で、再試行すれば解決します。wait してから繰り返してください。
not_checkedreporting_disabledproceed--verdict off を指定しました。通知されないのはページではなく、あなたの設定によるものです。
delivery はポインターで対象を指定するアクション(click、dblclick、check/uncheck によるクリック)で使われ、次の強い表現を使う根拠になります。
delivery意味根拠
target_hit狙った位置が対象、その子孫、ラベルのコントロール、またはシャドウホストに解決されました。no_effect を許可する唯一の値です。
intercepted狙った位置が、対象のフラットツリーの外側にある要素に属しています。→ verdict: intercepted。intercepted_by にはイベントを受け取った要素が示されます。
off_target狙いを定められる位置がなく、2 回のプローブで一致しました。要素自身のクライアント矩形の外側にあるか、ビューポートの外側でそこに固定されています。何もディスパッチされていないため、再試行しても何も重複しません。ただし、外れている状態は安定しているため、成功することもありません。したがって inspect です。
not_settled2 回のプローブで一致しませんでした。安定待ちの予算が尽きた時点でも、狙った位置が動いていました。何もディスパッチされておらず、外れている状態は一時的なため、安全に再試行でき、それが解決策です。したがって retry です。
jsJS の click()/MouseEvent を通しました。これらはヒットテストを実行しません。インターセプトは検出されなかったのではなく、適用されません。根拠にはなりません。
not_probedヒットテストが実行されなかったか、その結果が対象のドキュメントをカバーしていません(対象が iframe 内にある場合など)。証拠がない状態です。結論を出す根拠にはなりません。

--on-intercept には 3 つのモードがあります。dispatch(デフォルト)は、ポインターの動作と同じく、どの受け取り先にもイベントを送ります。refuse は、インターセプトが発生するたびにエラーにします。guard は、動作を伴わない受け取り先にはイベントを送り、コントロールと思われる受け取り先にはイベントを送らず、同じプローブ呼び出しの intercepted_by.actionable を読み取って判定します。該当するのは、ネイティブのインタラクティブタグ、ARIA のインタラクティブロール、tabIndex >= 0、または cursor: pointer です。<iframe> の受け取り先は、guard では常にイベント送信を拒否します。コンテンツが不透明なため、「動作を伴わない」と判断するには推測するしかないからです。拒否された場合は ok:false(終了コード 1)となり、ディスパッチ時と同じフィールドに加えて dispatched:false が含まれます。これは、狙いを定めたものの何も送信しなかったすべてのレスポンスに表示されます。next は dismiss を示し、狙い直しても何も重複しません。

ツールが確認していない成功を、決して報告しないでください。 オーバーレイにクリックが阻止された場合も unchanged と表示されます。再試行する前に assert で確認してください。再試行は実際に 2 回目のクリックを行うためです。unknown はツールが比較できなかったことを意味し、「何も起きなかった」という意味ではありません。inspect を 1 回実行し、確認できた内容に基づいて続行してください。例外は scroll_not_settled で、この場合は何もディスパッチされていません。waited_ms は、アクション後にページ読み込みを待った場合にのみ表示されます。Chrome がポインターイベントを 8 秒以内に確認応答しない場合は、--timeout の時間切れまで待たずに ok:false で失敗します。すでにページに到達している可能性があるため、再試行せず inspect を実行してください。click、dblclick、hover、drag は、最初にページを前面に表示します(バックグラウンドタブでは、ポインターイベントへの応答に 5 秒のタイマーが使われます)。

再試行しても解決できない、2 つの見落としがあります。 観測ウィンドウは 60 ms(observed_after_ms)に固定されています。この時間内に実行されるマイクロタスクキュー、setTimeout(0)、またはアニメーションフレームでの取り消しは検出できますが、400 ms 後にフィールドをクリアするバリデーターは検出できません。その場合は wait の後に assert value を実行してください。Canvas、WebGL、CSS のみで実現される効果はアクセシビリティツリーからは見えません。クラス、透明度、変形、再描画はいずれも unchanged または no_effect と表示されます。そのため、確認には screenshot または eval を使い、2 回目のクリックは決して行わないでください。

ワークフロー:inspect → act → assert

chrome-agent goto https://app.com/login --inspect   # uids
chrome-agent fill --uid n52 "[email protected]"         # value: what the page kept
chrome-agent click n63                              # verdict + delivery + next
chrome-agent assert text --contains "Dashboard"     # exit 0 = evidence you may quote

verdict が navigated の場合、next が inspect を示す場合、および SPA のルート変更(back、forward、再レンダリングを伴うクリックなど)の後には、必ず再度 inspect を実行してください。uid は再割り当てされます。SPA の詳細ページでは、モーダルが開くことのある click よりも、goto <direct-url> を優先してください。

assert:終了コードが答えです

タスクの完了を報告する前に、最終状態を検証してください。引用できる証拠は終了コード 0 だけです。

chrome-agent assert value --selector "#email" --equals "[email protected]"
chrome-agent assert text --selector "#status" --contains "Shipped"
chrome-agent assert url --matches "/orders/[0-9]+$"
chrome-agent assert state --selector "#terms" --checked        # native OR aria-checked
chrome-agent assert state --uid n15 --selected "California"    # a dropdown's current option
chrome-agent assert state --selector "#submit" --disabled      # :disabled OR aria-disabled
chrome-agent assert state --selector ".modal" --visible        # rendered, opaque, not hidden
chrome-agent assert exists --selector ".result" --count 10     # --min N, or --count 0 for absence
chrome-agent assert value --selector "#quantity" --equals "1" --within 5

結果が遅れて返る場合は --within N を指定してください(正の整数秒)。それ以外ではアサーションは 1 回だけ確認します。 繰り返されるのは読み取りだけで、最初に一致した観測結果で成功します。これは安定性を証明するものではありません。 JSON では assertion.wait に、within_ms、elapsed_ms、observations、timed_out が追加されます。期限切れの場合は、最後の比較結果とともに終了コード 2 になります。 読み取り不可の対象、読み取りのブロック、接続の切断は引き続き終了コード 1 となり、error、wait、および任意の last_observation が含まれます。値/テキスト/状態の対象が見つからない場合もエラーです。まず assert exists --within N で出現を待ってください。パイプとマクロでは、アサーションコマンドに "within":5 を指定できます。時間枠は読み取り全体を対象とします。--timeout は引き続き個々の CDP 呼び出しの上限を設定します。

  • 0 条件を満たした · 2 条件を満たさなかった(報告または修正してください) · 1 チェックを完了できなかった:ブラウザーがない、セレクターに一致するものがない、解析できない正規表現、CDP のタイムアウト。 条件を満たさなかった macro run のガードまたは discover step のアサーションも、終了コード 2 になります。 不正なフラグは終了コード 1 になります。pipe/batch 内のアサーションには独自の終了コードがありません。代わりに同じ assertion オブジェクトを含む ok:false となり、アサーションで停止した batch は 2 ではなく 1 で終了します。
  • assert は読み取りです。変更レポートも判定もなく、クリックすることもありません。シークレットは比較されますが、表示されません(応答には両方の長さが示されます)。--checked は check/uncheck が適用するものと同じ分類を読み取り、--selected は select が使うものと同じ値を読み取るため、アサーションと操作の結果が食い違うことはありません。
  • --matches は Rust の正規表現です。\d、\w、\s は ASCII のみを対象とし、\p{...} と後読み・先読みは使えません。大文字・小文字を区別しない場合は (?i) を使います。--contains は大文字・小文字を区別する通常の部分文字列検索です。

対象指定には 3 つのモードがあります。uid(inspect で取得。例:n47。同じページの検査間では安定します)、--selector(CSS)、--xy(座標)です。対象を指定するすべての操作は、--selector で指定した場合でも、実際に解決した uid を返します。delta と照合してください。 click --selector は click <uid> と同じ動詞です。どちらもビューポートの中心を解決してネイティブ入力を送るため、Cookie バナーの背後にあるボタンに --selector を指定すると、バナーがクリックされます。ポインターの動作も同じであり、そのことは intercepted_by で確認できます。

コマンド

# Navigation
chrome-agent goto <url> [--inspect] [--wait-for "selector"] [--header "K: V"]
chrome-agent back [--inspect]                                # answers {url, title}
chrome-agent forward [--inspect]                             # at either end: a message, no url
chrome-agent scroll down|up|<uid>
chrome-agent wait network-idle [--idle-ms N] [--timeout N]   # deterministic SPA/XHR settle
chrome-agent wait text|url|selector "pattern" [--timeout N]
chrome-agent history [--filter "pattern"] [--limit N]
# Inspection — narrowing flags change what is PRINTED only; `diff` always compares the full tree
chrome-agent inspect [--max-depth N] [--filter "button,link"] [--uid nN] [--urls]
chrome-agent inspect --filter "article" --scroll --limit 50   # infinite-scroll feeds
chrome-agent inspect --max-chars 4000 [--offset 4000]         # cap/page huge trees
chrome-agent diff                                             # what changed since last inspect
# Pointer actions — uid, --selector or --xy
chrome-agent click <uid> [--inspect]
chrome-agent click --xy 100,200                           # or --selector "css"
chrome-agent dblclick <uid> [--inspect]
chrome-agent hover <uid>
chrome-agent drag <from-uid> <to-uid>                     # mouse events; NOT HTML5 DnD
# Writes
chrome-agent fill --uid <uid> <value> [--secret]           # or --selector "css"
chrome-agent fill-form n20="[email protected]" n30="password"       # one value report per field
chrome-agent type "text" [--selector "input.search"] [--secret]
# --secret reports lengths instead of the value. It only ADDS to what the element declares;
# there is no flag that turns redaction off.
chrome-agent press Enter|Tab|Escape                       # a single printable char types it
chrome-agent select --uid <uid> "Option text"             # option.value first, then visible text
chrome-agent check <uid> | chrome-agent uncheck <uid>     # idempotent; refuse what they cannot check
chrome-agent upload --uid <uid> /path/to/file.pdf         # --selector too (file inputs hide from a11y)
# Reads
chrome-agent read [--truncate N]                          # articles, via Readability
chrome-agent text [--selector "main"] [--truncate N]      # visible text
chrome-agent extract [--selector "css"] [--limit N] [--scroll] [--a11y]
chrome-agent eval "JSON.stringify(...)" [--selector "h1"]
chrome-agent network [--filter "pattern"] [--body] [--limit N]   # already loaded, stealth-safe
chrome-agent network --live 5 --body --filter "graphql"          # capture live traffic
chrome-agent network --abort "*tracking*" --live 30              # blocking; start before navigating
chrome-agent console [--level error] [--clear]
# --body with --filter fetches every match whatever its MIME; without --filter, textual types only
# Files — written 0600 under ~/.chrome-agent/tmp; path on stdout, never base64
chrome-agent screenshot [--format jpeg] [--quality N] [--max-width N] [--uid nN|--selector "css"]
chrome-agent pdf [--filename name] [--landscape] [--background]
chrome-agent download <url> [--out path] [--max-bytes N]        # in-page fetch, keeps the login
chrome-agent download <--uid nN|--selector "css"> [--out path]  # CLICK it, capture the download
# Device metrics — explicit values, scoped to one named page, no preset catalog
chrome-agent --page mobile emulate device --label "checkout phone" --width 412 --height 915 --dpr 2.625 --mobile --touch
chrome-agent --page mobile emulate status
chrome-agent --page mobile emulate reset
# Persisted per named page, reapplied on each connection; a Chrome restart discards it. Acting on
# an emulated page activates its tab and backgrounds siblings. Under --touch, click/check tap.
# WebMCP tools — document.modelContext.getTools()/.executeTool()
chrome-agent webmcp list                                          # name, description, inputSchema
chrome-agent inspect                                              # baseline first, like any action
chrome-agent webmcp call add_to_cart --args '{"item":"Espresso Blend"}'
# The protocol defines no outputSchema, so the accessibility-tree diff is the only corroboration
# for what a tool DECLARED: one that declares success and moves nothing reads
# unchanged/identical_tree. Under `frame` the response carries frame_scoped:true — an empty list
# there is unproven, not "none". Most installs lack native WebMCP: use --chrome-arg above.
# Multi-step — pipe keeps one connection, so uids stay valid across commands
echo '[{"cmd":"goto","url":"..."},{"cmd":"inspect"},{"cmd":"click","uid":"n12"}]' | chrome-agent --json batch
echo '{"cmd":"goto","url":"...","inspect":true}' | chrome-agent pipe
# Iframes — the frame switch lives on the connection, so use pipe/batch
printf '%s\n' \
  '{"cmd":"frame","target":"iframe[src*=\"checkout\"]"}' \
  '{"cmd":"inspect"}' \
  '{"cmd":"fill","uid":"n42","value":"..."}' \
  '{"cmd":"frame","target":"main"}' | chrome-agent pipe
# Separate CLI calls (frame then inspect) do NOT work — each is a fresh connection.
# frame scopes eval + inspect, NOT --selector targeting. Act by uid after switching.
# Session, tabs, and paths that already worked
chrome-agent status                                              # browsers, pids, orphan= lines
chrome-agent tabs
chrome-agent macro list                                          # named paths, with their guards
chrome-agent macro check checkout --var [email protected]    # validate offline before opening Chrome
chrome-agent macro run checkout --var [email protected]      # stops at the first failed guard
chrome-agent replay recording.jsonl                              # a pipe --record file, no guards
chrome-agent close [--purge] [--orphans]                         # --orphans: browsers no session claims

マクロ。 macro record <name> --from-recording <file>(または、直前に実行したパイプセッション内で {"cmd":"macro","action":"record","name":"x"})は、操作、待機、アサーション、読み取り、ダウンロード、サポート対象のコンテキストを抽出します。検出時のスナップショット、差分、履歴は除外されます。失敗したステップ、未配信のステップ、サポートされていないロケーターがある場合、保存やマクロの置き換えは行われず、記録全体が拒否されます。導出されるガードは delivery: target_hit、verdict: changed|navigated、verbatim: true、downloaded: true、パス上の url_matches です。uid で指定されたステップは、ロールとアクセシブル名で記録されるか、拒否されます。シークレットフィールドは宣言済みパラメーターになり、保存されないため、macro run は --var がないと拒否されます。ガードが成立しない場合、実行は停止し、ステップのインデックス、ガード、観測された内容、操作自体の next を示して、stopped_by: "guard" とともに終了コード 2 で終了します。アサーションの失敗と同じ種類の判定であるため、同じ終了コードです。その他の理由(ステップの失敗、ページを読み取れない、該当するマクロがない)で停止した実行は、stopped_by: "error" とともに終了コード 1 で終了します。何も保証できないステップには unguarded のマークが付き、両方のレポートで件数が示されます。実行が成功したように見えても、その件数を確認してから信頼してください。明示的なアサーションと待機はチェックとして数えられます。

macro check は、すべてのコマンド、パラメーター、ガードをオフラインで準備します。macro run も、操作を開始する前に同じ準備を行います。複数の入力には --var を繰り返し指定します。カンマは値の一部として扱われます。コマンドとガードの文字列値に対して、置換は一度だけ行われます。CSS、JavaScript、ライブページの条件はリプレイ中にチェックされます。--json を使うと、各完了済みステップの steps[].result と、データ、アサーションの証拠、ダウンロードパスを含む停止したステップの result を取得できます。宣言済みのシークレット入力はマスキングされます。タスクを成功とするには、呼び出し側が明示的な結果アサーションを指定する必要があります。

新しい会話でも引き継がれる検出情報

不慣れなタスクを調査する際に、別のプロセスが作業を引き継ぐ可能性がある場合は、discover を使います。推論はユーザーが行い、CLI は目的、仮説、不明点、コマンドの応答を保持します。ブラウザーコマンドが成功しただけでタスクの完了を推定することはありません。

chrome-agent --json discover start discovery.json --goal "Read the entry page" --url https://example.com --max-commands 10
chrome-agent --json discover step discovery.json --proposal '{"id":"open","revision":0,"reason":"Observe the entry page","command":{"cmd":"goto","url":"https://example.com"},"checks":[{"cmd":"assert","what":"exists","selector":"h1"}]}'
chrome-agent --json discover show discovery.json
chrome-agent --json discover export discovery.json --name entry-page --steps open

次の提案には、返されたリビジョンと、開始時に指定されたブラウザー名とページ名を使います。同じ ID の同一の提案を送ると、以前の記録が返されます(replayed:true)。同じ ID で内容を変更した提案は拒否されます。プロセスが失われると、結果が不明な保留中の実験が残ります。記録を読み、新しい観測結果を送信してください。以前のステップを何も考えずに繰り返してはいけません。

初期プロファイルで許可されるのは、同一オリジンへの goto、inspect、read、text、extract、assert、wait です。最初の実験では、エントリー URL に移動する必要があります。デフォルトは、コマンド間の時間を含めて50コマンド、1,800秒です。チェック、失敗した試行、未解決の試行も予算を消費します。64 KiB を超える応答は不確実な結果として停止されるため、次の読み取り範囲を絞ってください。ファイルには入力と観測結果が未加工のまま保存され、ローカルにとどまります。サイトの JavaScript が外部への影響を引き起こす可能性はあります。このコマンドプロファイルは、信頼できないレシピを実行するためのサンドボックスではありません。

エクスポートでは、成功した実験を順番に選択し、開始時のナビゲーションと最終アサーションを必須とし、ドキュメント uid を拒否して、新しいマクロ名を作成します。パラメーターテンプレートは保持されますが、入力のデフォルト値は保持されません。候補は、なお新しい入力でリプレイし、結果を独立して確認する必要があります。従来の macro run は、検出時のオリジンや予算を適用しません。discover step は、観測されたコマンドやチェックに対して終了コード 0、成立しなかったアサーションに対して 2、エラーまたは不確実な結果に対して 1 で終了します。start、show、export は Chrome を開きません。

グローバルフラグ

動詞の前後どちらでも指定できます。例外は --timeout と --max-depth の 2 つです。コマンドが独自に宣言している場合は、動詞の後に指定します(wait selector ".x" --timeout 5)。それ以外の場所では、動詞の前に指定する必要があります。宣言されていない場所で指定すると、使用できる呼び出し方を示すエラーメッセージとともに終了コード 1 が返されます。

--stealth          # 7 anti-detection CDP patches
--json             # structured JSON on stdout; errors exit 1 with {"ok":false,...} still on stdout
--browser <name>   # isolate parallel agents — sharing "default" corrupts sessions
--page <name>      # named tabs
--max-depth N      # limit inspect tree depth
--verdict MODE     # auto (default): report what changed. off: report the action only
--budget N         # cap the change report, in chars (default 1200; 0 = uncapped)
--on-intercept M   # dispatch (default) | guard | refuse
--timeout N        # deadline on every CDP call (default 30s)
--headed           # show the window
--connect URL      # attach to a real Chrome (DataDome/Kasada)
--proxy-server URL # http(s)/socks4/5://host:port; launch-only
--copy-cookies     # use cookies from your real Chrome profile
--chrome-arg FLAG  # extra flag for the launched Chrome (repeatable); launch-only
--dialog MODE      # accept (default) | dismiss | manual · --dialog-text for prompt()

--chrome-arg は、chrome-agent が Chrome を起動する場合にのみ適用されます(--connect の使用時は無視されず、拒否されます)。名前付きブラウザーの存続中は設定が固定されます。変更するには、そのブラウザーを閉じるか削除してください。次のフラグは拒否されます:--user-data-dir、--remote-debugging-port、--remote-debugging-pipe、--proxy-server(グローバルのものを使用してください)、--headless(--headed を使用してください)。

終了コード:0 成功 · 1 エラー(不正なフラグや、停止した batch --stop-on-error を含む) · 2 アサーション(discover step を含む)または macro run のガード条件が成立しなかった · 130 Ctrl+C。JS ダイアログは自動で承認されるため、ページが応答しなくなることはありません。

ボット対策
サイトの保護解決策測定結果
なしchrome-agent goto ...—
Cloudflare JS チャレンジ(「Just a moment…」)chrome-agent --stealth goto ...shop.app:使用しない場合は 403/6 ノード、使用した場合は 200/実際のページ
Cloudflare 管理型 Turnstile--stealth では突破できませんnowsecure.nl:使用時も未使用時も 10 ノード
ログインが必要なサイト(X、Gmail)chrome-agent --stealth --copy-cookies goto ...—
DataDome/Kasadagoogle-chrome --remote-debugging-port=9222 & の後に chrome-agent --connect http://127.0.0.1:9222 goto ...leboncoin.fr:--stealth の使用時も未使用時も 403

2 つの Cloudflare の行は、それぞれ異なる製品を示しています。「Just a moment…」は 7 つのパッチで突破できる JS チャレンジですが、管理型 Turnstile はブラウザーのフィンガープリントを識別するため、バイナリー内のパッチでは突破できません。この場合や DataDome では、実際の Chrome への --connect だけが有効な方法です。フラグが機能したと思い込まず、ページに移動した後に内容を確認してください。

レスポンス形式(--json)

Success: {"ok":true, ...}
Error:   {"ok":false, "error":"message", "hint":"what to do next"}
  • goto → {"url","title","landed":{"requested","final","redirected","http_status","serving","challenge_from"?}}。 redirectedを確認してください。期限切れのセッションがログイン画面に遷移すると、そうでなければ成功した 読み込みのように見えます。フラグメントのみ、または末尾のスラッシュの違いはリダイレクトではありません。http_statusは最後の ホップのステータスです。ブラウザーから報告がない場合は省略されます(0にはなりません)。/login、/signin、/auth、 /ssoへのリダイレクトでは、URLから推測したhintが追加されます。gotoに判定結果は含まれません。

  • servingは応答したものを示すフィールドで、分岐に使います。

    serving意味対応
    page読み込みに反する測定結果はありません続行します
    challengeサイト独自のフォームがない状態で、ボット対策ベンダーのフレームまたはスクリプトが存在します。challenge_fromはベンダーのホスト名を示します実際のChromeに--connectします。これらには--stealthは効果がありません
    errorサーバーが4xx/5xxで応答しました。http_statusを確認してくださいURLを修正する(404)、認証する(401/403)、または待機する(429/5xx)
    nothing_actionableリンクもフォームコントロールもスクリプトもなく、テキストもほとんどありませんあきらめる前にinspectします
    unreadable形状プローブを実行できませんでしたinspectします

    pageは証拠がないことを示すもので、保証ではありません。ペイウォール、クッキーウォール、不明な CAPTCHAベンダーも、いずれもpageとして報告されます。nothing_actionableは測定結果であり、 ブロックされたという主張ではありません。エッジサーバーが返した拒否と、レンダリングが完了していないページは同じように見えます。

  • click/fill/select/check/… → {"message", "uid", "verdict", "verdict_reason", "next", "verdict_hint"?, "changed":{"added","removed","changed","unchanged","moved","anonymous", "document_changed","identity_known"}, "delta":"+ uid=n88 heading \"Saved\""}。フォーカスが移動した場合は "focus":{"from","to"}も含まれます(意図的にコンテンツの変更には数えません)。

  • fillには"value":{"requested","actual","verbatim","observed_after_ms","caveat"?}も含まれます。シークレット フィールド(type=password、またはパスワード/カード/CVC/ワンタイムコードを示すautocomplete)では、代わりに {"redacted":true,"requested_length","actual_length","verbatim"}が報告されます。書き込みがmaxlengthを超えた場合はcaveatが付きます。fill-form/fill_and_submitでは、各フィールドについて1つずつ"values":[...]が返され、同様に値が秘匿されます。fill_and_submitでは、フォームが移動した後に変更レポートが実行されるため、これが唯一の確認手段です。

  • selectはオプションのテキストを"value"として返します。check/uncheckはchecked/unchecked(混合状態のネイティブチェックボックスではindeterminate)を"value"として返します。どちらもトップレベルにobserved_after_msを設定し、監視時間内にページが状態を元に戻した場合は失敗します(終了コードは0以外)。要素がすでにその状態だった場合、valueは省略されます。何もディスパッチされないため、そのレスポンスはno_baseline/identical_treeを示し、このアクションで何かが変わった証拠にはなりません。

  • ポインターを対象とするアクションでは"delivery"、"aim":[x,y]、インターセプトされた場合は"intercepted_by":{...}が返されます。

  • inspect --max-chars → {"total_chars","truncated","next_offset"} · read/text → {"text"} · eval → {"result"} · network → {"requests":[...]} · console → {"messages":[...]} · batch → {"results":[...]} · screenshot/pdf → {"path"} · download <url> → {"via":"fetch","downloaded","path","bytes","mime"}。

  • download --uid/--selectorはクリックしてブラウザー標準のダウンロードをキャプチャします。これは、ページが独自に生成するファイル(Blob)や、アンカーで指定されていないPOSTから配信されるファイルを取得する唯一の方法です。okではなく、必ずdownloadedで分岐してください。クリックが実行されてもファイルが生成されなかった場合、ok:trueとdownloaded:falseが返され、再試行を禁じるヒントが含まれます。--timeoutはウィンドウ全体(開始と終了の両方)の制限時間を設定します。--max-bytesを超えると処理をキャンセルし、不完全なファイルを削除します。対象はURL、--uid、--selectorのいずれか1つだけです。対象が指定されていない場合、または2つ指定された場合は、ブラウザーの解決前に使用法エラーとなり、標準エラー出力に表示されて終了コード1で終了します。

低コストで読み取る:適切なツールを選びましょう

リストのように見えるものには、まず extract を使いましょう。数値は Hacker News のトップページで測定したものです。ページに応じて変わるため、相対値として参考にしてください。

ツール用途HN でのトークン数
extract繰り返しのレコード:グリッド、フィード、テーブル、検索結果。セレクターは不要です。すべての 30 件で約 1,570
read記事、ブログ投稿、製品ページ(Mozilla Readability)約 950
text --selector "main"範囲を指定した表示テキスト範囲指定なしで約 1,040
network --filter "api"ページが XHR 経由でデータを取得している場合は、そのペイロードを取得します多くの場合、最もすっきりしています
eval "JSON.stringify(...)"レコードビューに含まれない属性さまざま
inspect --filter "button,link"コンテンツを読むのではなく、操作対象を見つける場合約 1,735
inspectuid を含む完全なツリー約 5,650

extract --scroll はスクロールし、遅延読み込みコンテンツを取得するために MutationObserver で待機します。extract --a11y は、DOM に安定した構造がない React SPA(X.com)でも動作します。

予算に注意しましょう。screenshot より inspect を優先してください(スクリーンショットには uid がないため、結局 inspect が必要になります)。--filter "button,link"、--max-depth 2、read --truncate 1000、text --selector "main" --truncate 500 で範囲を絞り込みましょう。--budget N は変更レポートを制限し、--verdict off は操作後の読み取りを完全に省略します。その場合、このファイル冒頭のすべての保証もなくなります。複数ステップのフローには pipe/batch を使いましょう。接続は 1 回で済み、uid は有効なまま維持され、コマンドごとの約 12 ms のオーバーヘッドを削減できます(読み取りストリームで 1.5 倍、入力とクリックで 1.1 倍を測定)。速度ではなく、安定した uid が必要な場合に使いましょう。

コメント