コンテンツにスキップ

English · 日本語

Web UI(serve のブラウザアプリ)

bajutsu serve で開くブラウザ UI について、各タブが何をするか、どう操作するかをタスク指向で 説明します。起動フラグ、認証、ホスティングの詳細はこのページでは扱わず、 CLI リファレンスself-hosting に委ねます。ここで扱うのは 画面であって、コマンドラインではありません。

実装: bajutsu/serve/(stdlib のサーバ)。マークアップは bajutsu/templates/serve.html.j2 にあります。

関連: CLI リファレンス · scenarios · recording · reporting · selectors · configuration · self-hosting


Web UI とは何か、いつ使うか

Web UI は Tier 1 の利便性のための機能です。手で実行する CLI コマンドを、そのままブラウザから使える フロントエンドにしたものです。CI(継続的インテグレーション)ゲートには含まれません。決定的な run の判定が これに依存することはなく、ここで合否を下すものは何もありません。自然言語のゴールからシナリオを オーサリングする、シナリオを実行してレポートを読む、アプリを探索して画面マップが描かれていく 様子を見る、実際のスクリーンショットに対してシナリオを編集する、run 履歴を俯瞰する。これらを 1 つのアクティブな config に対して、ターミナルのコマンドを切り替えることなく行えます。

UI の操作の多くは CLI コマンド(recordruncrawlstatslint)に対応します。例外は Author タブで、その Capture / Edit / Enrich はシナリオファイルの作成と編集を助ける serve 専用の 機能で、対応する CLI コマンドはありません。ここでの説明でオプションの全体像が必要になったら、 CLI リファレンス が拠り所です。

起動する

リポジトリの checkout では、make serve でサーバを起動してください。これが一番手数の少ない方法です。 make servescripts/serve.sh)は、 iOS backend のオンデマンド依存(idb クライアントと idb_companion)を用意してからサーバを起動します。 これらが無いと、iOS の実行は no available actuator で失敗します。フラグは ARGS で渡します。

make serve                                                        # 既定ポート(8765)
make serve ARGS="--config demos/showcase/showcase.config.yaml --port 8766"   # ショーケースアプリ

リポジトリにはルートの bajutsu.config.yaml が無いため、ショーケースアプリにはこの config 指定が 必要です。

make serve は内部で python -m bajutsu serve、すなわち CLI リファレンス が説明する bajutsu serve コマンドを実行します。checkout の外で Bajutsu を導入した場合(make が無い場合)は、 bajutsu serve(または python -m bajutsu serve)を直接実行してください。その場合、backend の依存は 自分で用意します。iOS ターゲットには idb クライアントと idb_companion が要りますが、web(Playwright) ターゲットには不要です。いずれの方法でも、サーバがブラウザを自動で開くことはありません。127.0.0.1 に bind するので、起動したら表示された URL(既定は http://127.0.0.1:8765--port を渡した場合はその ポート)を自分で開いてください。オプションの全体像(--port--config--root--runs--baselines--themes--host--token--max-concurrent-runs--evidence-store)は CLI リファレンス にあります。

画面の全体像

ヘッダには 9 つのトップレベルタブがあります。RecordReplayCrawlAuthorStatsFlakyUsageCoverage、そして Trash(ソフトデリートした run が並び、 保持期間内なら復元できます。Trashを参照してください) です。10 番目の Metrics は、 プロジェクトハブが存在するとき(プロジェクトが 2 件以上登録されているとき) だけ現れます。プロジェクトどうしを比較するタブだからです(プロジェクトを比較するを 参照してください)。その右に Open config(config を bind すると隣にその名前が出ます)と、 それを確認するための View ボタン(後述)、Settings、そして既定でシステム設定に追従するテーマ ピッカーがあります。各タブはそれぞれ独立した 1 画面で、タブを切り替えても別のタブの作業内容は失われません。

一部のフォームは backend によって変わります。iOS の Simulator(idb)では Device のピッカー、 Simulators の複数選択、erase device first が現れ、web ターゲット(Playwright / Chromium)では それらの代わりに show browser (headed) が現れます。それ以外は backend をまたいで共通です。 Replay タブには過去の run を並べる History の一覧もあります(後述)。

テーマ。 ヘッダのピッカーで見た目のテーマを選びます。登録済みのテーマがすべて並びます。組み込みの Midnight(ダーク)と Daylight(ライト)に加え、--themes でドロップインしたテーマ(CLI リファレンス を参照)も、ダークとライトに分けて並びます。自分で選ぶまでは OS の設定(または config の ui.default_theme)に 追従し、明示的に選ぶとその選択が(ブラウザのローカルストレージに)記憶されます。その後 OS 側の設定が変わると、 手動の上書きは破棄され、あらためてシステムのモードに追従します。

テーマは UI の動き、つまりビューやモーダル、パネルが切り替わるときのアニメーションも定義します。画面遷移は 作り込みで固定されたものではなく、テーマの一部です。ビューの切り替え、モーダルの開閉、タイル状ペインの再構成に ついて、その時間、イージング、開始と終了のアニメーションを、テーマが --motion-* トークンで決めます(色トークンと 同じく serve.themes.css に説明があります)。動きのトークンを何も設定しないテーマは、組み込みのアニメーションを そのまま使います。開始と終了のトークンを none にしたテーマは、その遷移を即座に描画します。

OS のアクセシビリティ 設定で「動きを減らす(reduce motion)」が有効なときは、すべての動きが即座の切り替えに変わるので、利用者の意向に 反してアニメーションすることはありません。run はこの設定を有効にした状態でブラウザを操作するため、アニメーションが 決定的な run に影響することもありません。

テーマエディタ。 ピッカーの横にある Edit ボタンをクリックすると、UI 内のテーマエディタが開きます。 エディタはトークン契約からフォームを自動生成します。上部に name(名前)と kind(ダーク/ライト)が並び、 続いて色トークンごとにネイティブのカラースウォッチ、モーショントークンごとにテキストフィールドが並びます。編集内容は ライブプレビューとしてそのまま反映され、ページのリロードは不要です。エディタからは次の操作ができます。

  • Save to Local Draft:編集中のテーマをブラウザのローカルストレージに保存し、ヘッダーのピッカーに custom として即座に追加して選択状態にします。ページを再読み込みしても残りますが、ブラウザ固有の保存であり、ほかの serve セッションとは共有されません。エディタを開き直すと、この下書きから編集を再開できます。
  • Upload to Server:テーマを --themes ディレクトリに書き込み、ドロップインとして登録します。その serve インスタンスのセッション間で共有され、次回の読み込みでピッカーに並びます。テーマの id は名前からサーバー側で決まります。 このボタンは、インスタンスを --themes 付きで起動したときにだけ表示されます。テーマディレクトリがなければ、書き込む 先がないためです。
  • Export:編集したテーマを <name>-theme.css としてダウンロードします。--themes が受け付けるドロップイン 形式と同じなので、ローカルで作成したテーマをリポジトリにコミットして共有できます。
  • Import:エクスポート済み(または手書き)の .css ファイルを読み込んでフォームに反映します。ファイル内に フォームフィールドに対応しないトークンがある場合は、無視せずステータスメッセージで通知します。

パネル操作(デスクトップ)。 デスクトップ幅のウィンドウでは、Record、Replay、Crawl の各タブが パネルをタイル状に並べます。二つのパネルのあいだの区切りをドラッグすると、その二枚だけで幅を 再配分します(ほかのパネルの取り分は変わりません)。パネルの グリップを別のパネルへドラッグ すると、中央に落とせば入れ替え、端に落とせばその側に分割して並べます。ビューごとのレイアウトは ブラウザのローカルストレージに保存されます。Record の run 結果ペインは、run の開始と閉じる操作に 合わせてこのタイルに加わり、また抜けます。

狭いウィンドウ。 スマートフォン幅ではタイルレイアウトの代わりに 1 列のスタックになり、各ビューに 小さな切替が付いて、一度に一つのペイン(フォーム、ログ、レポートなど)を全幅で表示します。失われる 機能はなく、配置だけが変わります。

Claude に到達できないとき。 Record と Crawl は AI provider を必要とします(Settings を参照)。Claude に到達できないあいだ(キーが無い、CLI がサインインしていない)、この二つのタブは 無効表示になり、開始ボタンはグレーアウトし、何が足りないかを名指しするバナーが Open Settings への ショートカットとともに出ます。provider を設定すると即座に解除されます。それ以外(Replay、Author、 Stats、Flaky、Usage、Coverage)は AI の設定なしで動きます。

アクティブな config を選ぶ

すべてのタブは 1 つのアクティブな config に対して動きます。Open config を押して bind します。 ダイアログには 3 つのソースがあります。

  • From a Git repository。 github:owner/repo@ref:path/to/bajutsu.config.yaml の形で spec を 入力し、Load を押します。ref はブランチ、タグ、またはコミット SHA です(既定はリポジトリの デフォルトブランチ)。部分木ごと取得するので、config のシナリオやビルド済みアプリも一緒に来ます。
  • Upload a bundle (.zip)。 Choose a .zip… を押す(またはボックスにファイルをドロップする)と、 ホストのファイルシステムに触れないまま、自分のスイートをホスト型のサーバへ持ち込めます。zip の中身は 動くローカル checkout そのもの、つまり bajutsu.config.yaml、その scenarios ツリー、config の appPath が指すビルド済みアプリバイナリです。秘匿情報は運びません。${secrets.*} はサーバの環境から 解決されます。
  • or browse the server。 サーバの --root 配下に限定されたファイルブラウザで、ローカルの .yml/.yaml の config を選びます。リモートの利用者はホストのファイルシステムと関係を持たないため、 ホスト型のデプロイではこのソースは隠れます。

各ソースの詳しい挙動(content-addressed な Git キャッシュ、バンドルのサンドボックス化と zip-slip 対策、 --root への封じ込め)は CLI リファレンス に書いてあります。bind できる config は同時に 1 つだけで、別の config を開くと置き換わります。

バインドしている config を確認する

config 名の隣の View を押すと、タブが実際に動かしている config を確認できます。ダイアログは最初に Structured ビューで開きます。折りたたみ可能な key-value のツリーで、入れ子になったオブジェクトやリストは それぞれトグルになっており、必要なところだけ展開できます。Raw に切り替えると、コメントも含めた生の YAML が表示されます。どちらのビューの上にも config のパスが出て、Git リポジトリから取得したものであれば取得元 (リポジトリ、指定した ref、解決されたコミット SHA)も表示されます。これが効くのは Git ソースのときです。 Git ソースのアクティブなパスは content-addressed なキャッシュ上の不透明な場所 (…/gitsrc/<host>/<owner>/<repo>/<sha>/…)になるため、パスだけではどのコミットが bind されているか わかりません。取得元の行が、実際に bind されているコミットを示します。config はそのまま表示します。 ${secrets.*} のプレースホルダは書かれたとおりに現れ、この画面で解決されることはなく(実行時にサーバの環境から 解決されます)、ファイル以上の開示はありません。ただし伏せ字にはしません。ローカルやアップロードした config に平文で書かれた秘匿情報は、そのまま表示されます。秘匿情報はファイルに書かず ${secrets.*} の 参照にしておくことが、この画面に出さないための前提です。ホスト型のデプロイでは、このエンドポイントは admin 限定です。

プロジェクトを切り替える

複数の config(複数のアプリ、あるいは一つのアプリの複数ターゲット)を扱うとき、serve はそれらを束ねる ハブであり、単一 config のランチャーではありません。プロジェクトは config ソースへの名前付きの バインディングです。ヘッダにはスイッチャー(config ビューアの隣のピッカー)が加わり、プロジェクトが 2 件以上登録されるまで隠れています。そしてハブの居場所となるトップレベルの Projects タブが加わります。 スイッチャーと違い、Projects タブは管理すべきプロジェクトが 1 件でもあれば現れます(単一 config も含みます)。 UI 自身からハブへ育てられるようにするためです。

Projects ページの各行は、プロジェクト名とその config ソース、最新の実行結果を示します。行の Switch を押すと そのプロジェクトが active になり、サーバは再起動なしでアクティブな config をそのソースへ貼り替え、どのタブ (Replay、Record、Crawl、Stats のダッシュボード)もそれに対して動きます(ヘッダのスイッチャーも同じ手早い 切り替えを行います)。ソースがアップロードされたバンドルのプロジェクトには切り替えられません(再展開する チェックアウトがないためです)。その config を bind するには、もう一度アップロードしてください。

ページ上でプロジェクトを追加するには、名前と 1 つの config ソース文字列を入力します。Git spec (github:owner/repo[@ref][:path])か、ローカルパスです。bajutsu project add --config が 受け取るのと同じソースで、任意の認証情報は非公開リポジトリ向けです。既存の名前で追加し直すと、そのソースを 再バインドします。Remove は確認のうえプロジェクトを登録解除します。実行履歴は残り、バインディングだけが 取り除かれます。bajutsu project の CLI も同じ共有ストアを編集するので、どちらで追加したプロジェクトも両方に 現れます。登録・削除・切り替えはいずれも config バインディングを貼り替えるので、ホスト型のデプロイでは config を bind するのと同じく admin の操作です。サーバがそれを強制し、拒否された操作はページ上にインラインで示されます。

プロジェクトを比較する

ハブが 2 件以上のプロジェクトを持つと、Metrics タブがそれらすべてを一度に横断する読み取り専用の 比較を開きます。単一プロジェクトの Stats ダッシュボードでは答えられない 問いに答えるものです。各プロジェクトが 1 行になり、実行回数、直近の合格率、フレーキ率(ウィンドウ内で フレーキと分類されたシナリオの割合)、実行あたり所要時間の中央値(p50)と 95 パーセンタイル(p95)、そして 合格率の推移を表すスパークラインを並べます。列見出しをクリックすると、合格率、フレーキ率、所要時間で 並べ替えられます。最初のクリックは最も注意すべきプロジェクト(合格率が最も低い、あるいはフレーキ率や 所要時間が最も高いもの)を先頭に出し、もう一度クリックすると順序が反転します。まだ実行のないプロジェクトは、 誤解を招く 0 ではなく空の行として表示されます。行をクリックするとそのプロジェクトへ切り替わり、その単一 config の Stats ダッシュボードが開きます。ほかの ダッシュボードと同じく助言専用で、run が既に下した判定を再表示するだけであり、何かを gate することは ありません。

Settings

Settings には、AI を使うパスが必要とする 2 つの選択があります。ここの内容はディスクには書かれません。 設定はそのセッションのあいだサーバのメモリ上に生き、serve を再起動するとリセットされます。再起動を またいで保持したい値は、serve を起動する前にシェルか .envANTHROPIC_API_KEY / AWS_* を 設定してください。

AI provider は、オーサリング(Record と Crawl)が使う backend を選びます。

  • Anthropic API:従量課金の API です。下で設定する Claude API キーで認証します。
  • Amazon Bedrock:AWS 経由の Claude です。標準の AWS 認証情報で認証し、AWS regionBedrock model id の欄が加わります(Bedrock の id はプロバイダ接頭辞を持ちます。例 global.anthropic.…。素の Anthropic id とは異なります)。
  • Anthropic CLI(ant):公式の Anthropic CLI が持つ OAuth/SSO サインインを通じて、Pro/Max/Console のシートで Claude を使います。API キーは不要で、どのパスでも画像入力(スクリーンショット)が使えます。 serve を起動した環境に CLI をインストールしておくと、Sign in with SSO ボタンがブラウザでの サインインを開始します(その環境で ant auth login を実行するのと同じです)。ボタンは serve が動く マシンでブラウザを開くので、ローカルの make serve で使えます。ホスト型のデプロイではサーバがこの要求を 拒否し(403)、運用者が別途ホスト側でサインインします。
  • Claude Code CLI(claude)claude CLI を介して、Claude Code の Pro/Max/Console サブスクリプションで Claude を使います。API キーは不要です。serve が動くマシンで一度 claude setup-token(または対話的な claude ログイン)でサインインしておきます。環境に ANTHROPIC_API_KEY があってもこの provider では 無視されるため、課金はサブスクリプション側に留まります。

ピッカーはプレースホルダから始まります。既定の provider はなく、明示的に選ぶまで Save は 拒否されます。各 provider 固有の欄(API キー、Bedrock の region と model id、CLI のサインイン)は、 その provider を選んだときだけ現れます。provider をまたいで効く上書きが三つあります。Model は 既定の代わりに特定のモデル id を使い(Bedrock は自前の接頭辞付き id 欄を保ちます)、Reasoning effort はオーサリングのエージェントについて速度と深さを釣り合わせ、Output languageBE-0188)は AI が生成する文章、すなわち recordfrom: 由来と crawl が逐次出力する推論テキストを、どの言語で書くかを固定します。 既定の auto は現状の挙動を保ちます(record はゴールに追従し、crawl は英語のままです)。決定論的な run の判定には触れず、対象のデバイス locale とは別物です。

Claude API key(Anthropic API provider を選ぶと現れます)は write-once です。キーを入力して Save すると、以後はマスクした表示だけになり、 内容が再表示されることはありません。変更するには新しいキーを設定します。Clear で削除します。これは Anthropic API プロバイダとアラートガードで使われます(Bedrock は代わりに AWS 認証情報を使います)。 必要とするのは AI を使うパスだけです。RecordCrawl、そしてアラートガードを有効にした Replay です。

Scenario secretsBE-0274) は、バインド中の config が宣言するシークレット、つまりシナリオが ${secrets.X} として参照する secrets: の環境変数名を一覧します(シークレットBE-0032)。宣言された名前ごと に write-once のフィールドを並べ、API キーと同じくマスク表示だけで再表示はされません。これにより、 serve を起動する前に環境変数を export したり .env を手で編集したりしなくても、シナリオが必要とする 認証情報を Web UI から用意できます。ここで設定した値はその宣言済みの名前の環境変数に入り、spawn される Replay / Record / Crawl が引き継ぐので、run のなかで ${secrets.X} が解決します。バインド中の config がシークレットを宣言していないときは、このセクションは表示されません。secrets: の内容が異なる config に切り替えると、一覧は更新されます。設定できるのは config 自身が宣言している名前だけで、任意の 環境変数を設定することはできません。ロールで保護されたデプロイでは、設定は admin の操作です。

Record — ゴールからシナリオをオーサリングする

何をする画面か。 自然言語のゴールに向けて AI で探索し、その結果のシナリオを 1 手ずつ書き出します。 record コマンドをブラウザにしたものです。

操作手順。

  1. 目的を Goal (natural language) に書きます(例「カウンタを 2 回増やして 2 と表示されるか確認する」)。
  2. Target を選びます。iOS では Device も選びます(隣の更新ボタンでシミュレータを再取得できます)。 web では show browser (headed) にチェックを入れると、既定のヘッドレスではなく、目に見える Chromium のウィンドウがオーサリングを低速再生する様子を見られます。
  3. 必要なら Save as にシナリオのファイル名を入れます。空なら generated.yaml が既定になり、同名が すでにあれば run の日時が付くので上書きされません。
  4. iOS のオプション:erase device first はシミュレータを初期化してアプリをオンボーディングから 始めます。disable alert-dismiss はこのオーサリング実行で vision のアラートガードを止めます。
  5. Generate scenario を押します(Stop で中止)。エージェントの 1 手ずつの進捗がログに流れます。

結果どうなるか。 オーサリングが終わると、Generated scenario パネルに YAML が出ます。必要なら その場で編集し、Save(保存するものが無いあいだは無効)を押します。シナリオはターゲットの scenarios ディレクトリに書き込まれるので、Replay タブの Scenario ピッカーに現れ、そのまま 実行できます。オーサリングループとアラートガードの仕組みは recording を参照してください。

その場で実行する。 Save の隣の ▶ Run ボタン(同じく YAML ができるまで無効)は、パネルの 現在の内容(オーサリングしたばかりのシナリオ、あるいは手で貼り付け・編集した YAML)をタブを 切り替えずに実行します。run 結果ペインが開いてライブのログと完了後のレポートを表示し、Stop で 中止、閉じるボタンでペインを畳めます。合否は Replay タブと同じ決定的なランナーのものです。

Readiness(doctor)。 フォームには Check ボタン付きの Readiness パネルがあります。 doctor コマンドをブラウザにしたもので、Record と Replay の両タブで共通です。報告は二部構成です。 実行可能性のチェック(必要なツールが揃っているか、Simulator が起動しているか、web ターゲットの ページに到達できるか)と、環境が実行可能なら現在の画面の慣習スコア(Ready / Partial / Blocked のグレード、stable-id のカバレッジ、直すべき点の一覧(名前のないコントロール、 名前空間外の id、重複))です。ホスト環境を調べる読み取り専用かつ AI 不使用の診断で、run を ゲートすることはありません。

Replay — シナリオを実行してレポートを読む

何をする画面か。 シナリオを決定的に実行し、そのレポートを埋め込みます。run コマンドをブラウザに したものです。サブタブは RunHistory の 2 つです。

Run。

  1. ScenarioTarget を選びます。
  2. iOS では、実行する Simulators を選びます(停止中のものは先に起動されます。2 台以上選ぶと、 シナリオをそれらのあいだで並列に実行し、Workers がその台数に追従します)。erase device firstdisable alert-dismiss は Record と同じです。web では show browser (headed) にチェックを入れると、 目に見える Chromium のウィンドウで実行を見られます。
  3. Run を押します(Stop で中止)。出力がログにライブ表示され、完了するとその run の report.html が隣に埋め込まれます。run の前には、Record と同じ Readiness パネル(前述)が、 「環境は整っているか、アプリはアドレスできるか」にワンクリックで答えます(助言のみです)。

ログパネルの下には Generate code バーがあり、選択中のシナリオをネイティブテストとして書き出します。 Author タブ(後述)と同じ codegen を、シナリオを走らせたその場所に置いたものです。

埋め込まれたレポートの中で、visual チェックの Approve ボタンは、その run が撮影した スクリーンショットを visual ベースラインへ昇格させます(approve CLI コマンドと同じ昇格です)。以後の run はそれと比較されます。これは run → 確認 → approve → 再 run というループの確認のステップです。 レポートの各セクションが何を示すかは reporting を参照してください。

History。 このサブタブは過去の run を新しい順に並べ、それぞれに pass/fail のドットとシナリオの 要約が付きます。クリックするとそのレポートを再表示します。更新ボタンで再取得します。

run を削除するBE-0239)。 各行にはゴミ箱ボタンがあり、その run(レポート、スクリーンショット、動画、ネットワークキャプチャ)を Trashへ移します。すぐに消し去るのではなく、保持期間の あいだは復元できる状態で残ります。まとめて片付けたいときは、各行のチェックボックス(または select all)で 選び、一覧の上のバーの Delete selected を使います。どちらも editor 権限の操作です。ソフトデリートした run は履歴からすぐに消え、復元すれば元の履歴に戻ります。

失敗した run を triage する。 run が失敗すると、レポートバーに Triage ボタンが現れます(実行直後の レポートでも、History から失敗した run を開き直したときでも表示されます)。triage コマンドをブラウザに したもので、ターミナルに移らずに「なぜ失敗したのか」をその場で調べられます。ボタンを押して Diagnose を クリックすると、triage はその run が残した失敗コンテキストを読み、根本原因の要約、問題のステップ、対処の 候補を示します。既定は決定的なルールベースのエージェントです。Claude にチェックを入れると(AI プロバイダを 設定しているときだけ有効になります。Settings を参照してください)、Claude の調査エージェントで 診断します。triage がセレクタ id の改名、一致の絞り込み、タイムアウトの引き上げといった機械的な修正を 提案できるときは、その修正を、いま選んでいるシナリオのソースに対する diff として表示します。Apply fix は、その差分を Author タブと同じ検証済みの保存経路を通して書き戻します。Apply & re-run は書き戻したうえで すぐにシナリオを再実行し、修正が効いたかを確認します。修正が書き込まれるのは、この明示的なクリックのときだけ です。自動では何も編集しませんし、run の合否は決定的な run が出したものを読み取るだけで、AI が計算し直すことは ありません。triage は Run サブタブでいま選んでいるシナリオに対してプレビューと適用を行うので、History から run を triage するときは、対応するシナリオとターゲットを先に選んでおいてください。

Crawl — アプリを探索して画面マップをその場で描く

何をする画面か。 アプリを幅優先で探索し、到達できる画面と画面間の遷移を、発見に合わせて描きます。 crawl コマンドをブラウザにしたものです。これは発見のためのツールで、合否ゲートには決してなりません。 探索エンジン(画面の同一性、遷移、クラッシュ判定)は決定的で、Settings で選んだ AI プロバイダは 「何を試すか」を提案するだけです。

操作手順。

  1. Target を選び、Workers(並列のブラウザプロセス数。iOS では 1 つの画面マップを共有する シミュレータ数)を設定します。iOS では、クロールする Simulators も選びます。
  2. 予算を設定します。Max screens(既定 50)と Max steps(既定 200)です。クロールは先に達した方で 停止します。
  3. iOS には erase device firstdisable alert-dismiss、web には show browser (headed) が あります。
  4. Start crawl を押します(Stop で中止)。進捗はステータス行と Console に出ます。

得られるもの(フォームの隣の 3 つのビュー)。

  • Screen map:発見した画面と遷移のグラフで、クロールの進行に合わせてライブで描かれます。 / リセット / + で拡大縮小します。同じ UI で一時的な状態だけが違う画面(未入力と入力済みのフォームなど)は 1 つのノードにまとまり、その場で展開できます。
  • Exploration plan:画面ごとの未試行操作を並べた計画ツリーで、進捗バーが付きます。show pruned は、 クロールが重複するグローバルコントロール(一度だけ探索したタブやナビゲーションバー)として刈り込んだ 操作の表示を切り替えます。それらは取り消し線付きで表示され、クリックすると探索を再開できます。
  • Console:クロールの進捗ログです。

マップの画面をクリックするとスクリーンショットのライトボックスが開きます。拡大された画面に / が付き、その画面への遷移や、その画面からの遷移へ移動できます。ホットスポットは、各遷移がどこで 起きたかを示します。

履歴。crawl は manifest.json を書かないため、Replay タブの History には現れません。crawl の run は、Crawl タブ自身の History サブタブに一覧されます。どの crawl も書き出す screenmap.json を手が かりにしていて、各エントリには run の ID と、画面・遷移・クラッシュの件数が新しい順に並びます。エント リを選ぶと、その crawl の画面マップが読み取り専用で開きます。保存済みのマップから描き直すだけで、 crawl はやり直しません。実行中の run と取り違えないように past crawl バッジが付き、表示している間は 入力フォームが無効になります。マップの隣には、その run の crashes/*.yaml(再現できるクラッシュ)と flows/*.yaml(到達できる画面)のシナリオファイルへのリンクが並びます。いずれも生の YAML が開き、 bajutsu run でそのまま実行できます。Form サブタブに戻ると、実行用の crawl フォームに戻ります。

crawl を削除するBE-0239)。 Replay の History と同じく、各 crawl の行にゴミ箱ボタンがあり、select allDelete selected の バーでまとめて片付けられます。削除した crawl は共通の Trashへ 移り、保持期間内なら復元できます。

過去のクロールの続きから探索するBE-0181)。 開いている過去の run が予算で止まり、まだ探索していない画面が残っている場合は、マップのヘッダに ▸ continue exploring ボタンが現れます。これを押すと読み取り専用の履歴表示を抜け、その run を続きから 探索します。残りのフロンティア全体(未試行の操作が残るすべての画面)を再探索し、同じマップに追記します。 このとき現在の Max screens / Max steps をそのまま使うので、同じ操作で予算を上げられます。また Workers や選んだシミュレータで continuation を並列に実行します。過去の run を開いた状態で、取り消し線の 付いた pruned 操作をタップすると、その 1 つのブランチだけを続きから探索します。どちらも明示的な操作 です。履歴表示は探索を指示するまで読み取り専用のままなので、過去のマップを誤って動かすことはありません。

画面マップ、画面を同定する fingerprint、web と iOS の違いは CLI リファレンス で扱います。

Trash — 削除した run を復元するか完全に削除する

何をする画面かBE-0239)。 Replay や Crawl の History で削除した run が、ここにゴミ箱として並びます。通常の run と crawl の run は 1 つのゴミ箱を共有し、それぞれに削除した時刻が付きます。ソフトデリートは消し去る操作ではありません。run は 履歴の一覧から外れますが実体は残るので、Restore を押せば元の履歴へそのまま戻ります。

保持期間。 ゴミ箱に入った run は、保持期間(BAJUTSU_RUN_RETENTION_DAYS。既定は 30 日で、0 にすると手で削除するまで残ります)を過ぎると完全に削除されます。この掃除は遅延実行で、次に履歴かゴミ箱を 読んだときに行われ、バックグラウンドのタイマーは使いません。サーバがアイドルのあいだは何も動きません。 ヘッダには、いま効いている保持期間が表示されます。

完全に削除する。 ゴミ箱の各 run には、保持期間を待たずにその実体をすぐ消す Delete forever の操作も あります。取り消せない操作なので、ホスト型のデプロイでは admin 権限に限ります(ローカルの単一ユーザーの serve には権限の区別が無いため、そちらでは常に使えます)。確認ダイアログも、通常の削除とは別の、より強い 警告のものになります。削除・復元・完全削除はいずれも監査ログに記録され、oplog イベント (run.soft_deleted / run.restored / run.purged)としても出ます。運用担当者は、誰がどの run を いつ消したかを追えます。

Author — 1 つのシナリオを capture・edit・enrich する

何をする画面か。 1 つの開いているシナリオを、Capture / Edit / Enrich のボタンで選ぶ 3 つのモードで扱います。モードを切り替えても、シナリオが読み直されたり未保存の YAML 編集が失われたりは しません。

Capture:実際のスクリーンショットをクリックしてシナリオを組み立てます。

  1. Target を選び、Start capture を押してライブセッションを始めます。
  2. Action modetaptype にし(type のときは Text to type を埋めます)、 スクリーンショットをクリックして各操作を記録します。
  3. Finish & save を押して、記録したフローを書き出します。

Edit:過去の run か、ライブセッションのスクリーンショットに対してステップを直します。

  1. Scenario を選んで Load を押します。Run ピッカーにはそのシナリオ自身の過去の run だけが並ぶので、選んだ run のステップが読み込んだシナリオと食い違わずに対応します。Run を選ぶと、その run が撮影したスクリーンショットをたどれます。
  2. 過去の run がないときは、Start live session を押すとターゲットを起動して現在の画面に対して要素を選べます。Edit に run は要りません。Stop session で保存せずに終了します。
  3. ← Prev / Next → でステップを移動します。ラベルにどのステップを読み込んでいるかが出ます。
  4. スクリーンショットをクリックして読み込んだステップの対象を付け替え、Apply でその変更を YAML に反映します。

Enrich:提案されたアサーションを加えます。

  1. シナリオを読み込み、Enrich を押します。
  2. Proposed assertions パネルに提案が並びます。Accept で YAML に取り込み、Dismiss で 破棄します。

YAML エディタ(3 モード共通)は入力しながら検証します。デバウンスしたチェックが bajutsu lint と 同じルールを実行し、行に紐づく診断を、該当行のガターのマーカーと、クリックできる問題リストとして 表示します。問題をクリックするとその行へ移動します。シナリオの JSON Schema は、軽量なキー補完 (Ctrl/⌘+Space)と hover の説明表示にも使われます。これは決定的で、AI を使いません。Save で シナリオを書き出します。これらのチェックが従う文法は scenarios、セレクタの採点方法は selectors を参照してください。

決定性の監査バッジは、lint と同じライブの YAML を安定性の観点で採点します。グレードのバッジ (Stable / Moderate / Fragile と、id ベースのセレクタの割合)がエディタのヘッダに表示され、 エディタの下の findings 一覧が決定性リスクを一つずつ挙げます。安定性ラダーより下のセレクタ、具体的な条件を 持たない wait、生座標のジェスチャです。これは audit コマンドの静的スコアをブラウザに出した もので、読み取り専用でデバイスも AI も使わず、あくまで参考情報でありゲートにはなりません。Replay タブ でも、選択中のシナリオに対して同じバッジを表示します。シナリオを書く場所でも実行する場所でも、安定性の シグナルが見えるようにするためです。

Generate code:読み込んだシナリオを、ブラウザを離れずにネイティブテストとして書き出します。 シナリオを読み込んで Generate code を押すと、結果が読み取り専用のビューアに開き、Copy で コピー、Download でダウンロードできます(ファイル名はシナリオと出力先から導きます。例: LoginUITests.swift / login.spec.ts)。出力先はターゲットの backend に従い、iOS なら XCUITest、 web なら Playwright になるので、そのターゲットが対応する形式だけを提示します。これは codegen コマンドを UI に出したもので、シナリオを出力先フレームワークの流儀へ構造的に 対応づけるだけです。デバイスも AI も動かさず、合否も計算しません。未対応の限界は codegen 自身のものです。

Stats — run 履歴のダッシュボード

何をする画面か。 サーバの run 履歴を横断した集計 run 統計ダッシュボードを描きます。stats コマンドを ブラウザにしたものです。これは読み取り専用かつ助言的で、判定ではありません。合格率の推移、遅い シナリオと flaky なシナリオ、失敗ホットスポット、run のボリュームを、各 run の保存済み manifest.json から 集計します。

操作手順。 タブを開くとダッシュボードが読み込まれます。更新ボタンで、現在の run 履歴に対して 再集計します。デバイスも AI も run も関わりません。

Flaky — ランク付きのフレーキシナリオ一覧

何をする画面か。 サーバの run 履歴を、各シナリオの判定がフィンガープリント一定のままどれだけ反転するかで 並べ替えます。flakiness コマンドをブラウザにしたものです。これは読み取り専用かつ助言的で、判定ではありません。 シナリオを判定の反転率で flaky を先頭に並べ、各行は pass/fail の数と分類(flaky / deterministic / unproven。 決定性監査から再利用します)を示し、代表的な合格 run と失敗 run の証跡へリンクします。データベースを配線している ときは各 run の行に刻まれた provenance から直接グルーピングし(org スコープ)、そうでなければ各 run の保存済み manifest.json から同じレコードを組み立てます。

操作手順。 タブを開くとランキングが読み込まれます。更新ボタンで、現在の run 履歴に対して再集計します。 フィンガープリントを持たない run や、判定が記録されていない run はグルーピングできず、スキップとして報告します。 デバイスも AI も run も関わりません。

フラッキーなシナリオを診断する。 AI による Run 横断の修正提案は、CLI の機能 bajutsu triage --flaky です (このパネルが名指ししたシナリオの成功 run と失敗 run をまとめて読み、差分を説明します。CLI リファレンスを参照)。これは設計上 CLI 専用です。この パネルは決定的なランキング(AI 不使用)である一方、Run 横断の提案は AI プロバイダを必要とし、人がレビューして 適用するための差分にとどまるためです。

Usage — AI トークン利用量とコストのダッシュボード

何をする画面か。 AI パス(record、crawl、triage、アラートロケータ)が記録した属性付きの利用 ledger を もとに、AI の利用量とコストのダッシュボードを描きます。Stats と同じく読み取り専用で助言的であり、判定にも ゲートにもなりません。期間内の合計(トークン数とドル)、provider・model・command・scenario 別の内訳、 provider と model の比較(1 コールあたり・1 シナリオあたりのコスト)、日次のコスト推移を示します。どの数字も ledger 上の決定的な合計で、モデルは使いません。サブスクリプションの provider や未知の model はトークン単価を 持たないため、そのコールはドル額を捏造せず未価格(「—」)として示します。

操作手順。 タブを開くとダッシュボードが読み込まれます。更新ボタンで、現在の ledger に対して再集計します。 まだ利用が記録されていないとき(AI パスを一度も実行していない、または永続化を無効にしている場合)は、記録を 有効にする方法を説明する空の状態を表示します(ledger の既定は runs/usage.jsonl で、ai.usageLedger で 移動でき、空文字で無効化できます)。デバイスも AI も run も関わりません。

Coverage — E2E カバレッジマップ

何をする画面か。 ターゲットの E2E カバレッジマップを描きます。coverage コマンドをブラウザにした ものです。シナリオスイートが参照する安定 id を、アプリが宣言した idNamespaces と突き合わせ、名前空間 ごとのカバレッジ、不足の一覧(どのシナリオも触れていない宣言済み名前空間)、名前空間から外れた id を 示します。過去の run を選ぶと、run の証跡に基づく次元が加わります。観測されたエンドポイントとアサート されたエンドポイントの比(選んだ run の network.json の和集合を、スイートのネットワークアサーションと 突き合わせたもの)と、観測された id と宣言済み名前空間の比(各 run の elements.json から)です。Stats と 同じく読み取り専用で助言的であり、判定にもゲートにもなりません。どの数字も決定的な数え上げで、モデルは 使いません。

操作手順。 ターゲットを選び、run の証跡に基づく次元を加えたいときは run を選んでから、Compute を 押すとマップが描かれます。デバイスも AI も run も関わりません。

セキュリティとホスティング

既定の make serve127.0.0.1 に無認証で bind します。loopback インターフェースでのみ安全です。 自分のマシンの外に公開するにはトークン(--token)が要ります。トークンは認証と CSRF 対策を有効にし、 非 loopback の --host への bind にはトークンが必須です。単一 Mac でのチーム向けホスティング (--emit-launchagent)や本格的なコントロールプレーンの backend(--backend server)、そして --max-concurrent-runs--evidence-store は、CLI リファレンスself-hosting で扱います。

サインイン。 認証付きのサーバでは、最初に未認証で返ってきた要求がサインインの入り口になります。 GitHub OAuth が設定されていればブラウザがそこへ送られ、そうでなければトークンの入力プロンプトが 出ます。共有トークンを入力すると、以後はセッションクッキーがサインイン状態を保ちます。ローカルの 無認証サーバでは、どちらも現れません。


各タブのスクリーンショットは今後追加する予定です。現時点では本文だけの案内です。