daily-price-watch のライフサイクル全体をたどります。ブラウザーToolが商品の価格を調べ、純粋なtransformがその形を整え、価格が下がったときだけ条件付きの http.post がシークレットのwebhookへ通知します。プロジェクトをスキャフォールドし、デモンストレーションからブラウザーToolを記録し、それらを接続し、content-addressedなFlowSpecへコンパイルし、実行し、実行をタイムトラベルし、オフラインでリプレイし、最後にRESTエンドポイントとして公開します。すべて同じアーティファクトを使い、実行時にモデルは介在しません。
このガイドは、すでにmonorepoをクローンし、workspaceをインストール済みであることを前提にしています。詳しくは インストール を参照してください。
@browserflow/cli はまだnpmに公開されていないため、以下のコマンドは npx 経由ではなく、クローン済みrepoの中から実行します。構築するもの
実行例は、標準的なdaily-price-watch Flowです。
エンドツーエンドのウォークスルー
プロジェクトをスキャフォールドする
browserflow init はプロジェクトを配置します。flows/ ディレクトリ、tools/ ディレクトリ、そしてすべてのPackをバージョンとdigestで固定する browserflow.lock ロックファイルです。out/ ディレクトリ配下に置かれます。たとえばテストフィクスチャとして保持するJournalのように、明示的に固定することを選ばない限り、生成物はコミットされません。ブラウザーRecordingを作成する
browserflow record は、解決済みのPlaywright操作リストからcontent-addressedなRecordingを生成します。操作はJSONファイルとして指定します(navigate、fill、click、extractなど)。コマンドはそれを正規化し、digestを計算し、Recordingを書き込みます。--ops <file> は必須です。生成されたRecordingは recordings/search-price.json に書き込まれます。--secret <slot> で宣言されたシークレットはRecordingには保存されません。スロット名だけで参照され、実行時に解決されます。対話的なPlaywrightライブキャプチャ(Chromiumを開き、クリック操作を進め、自動キャプチャする機能)は将来のリリースで予定されています。現時点では、
--ops で事前解決済みの操作を指定してください。Recordingモデルとops形式については ブラウザーTool を参照してください。Flowに接続する
次に、記録したToolを この2つのサーフェスはいくつかのことを代わりに行っています。
daily-price-watch Flowへ組み込みます。SDKとYAMLは1つの真実の2つの表現です(tenet T1)。どちらも同一の正準FlowSpecへコンパイルされ、相互に再生成できます。lookup → shape のedgeは c.steps.lookup.output への参照から推論されたため、通常は needs を手で書く必要はありません。.branch() の糖衣構文は notify 上の when 述語へloweringされ、no: noop("unchanged") のarmは効果を持たず後続からも参照されないため、dead noopとして取り除かれました。webhook 入力は参照だけで運ばれるシークレットです。c.secret.webhook は、secrets capabilityを持つ http.post Toolの内部でだけ実値に解決されます。コンパイルし、dry-runしてから実際に実行する
日常的なinner loopは、1秒未満で、破壊的なことをしないように設計されています。まずは純粋な 次に 問題なければ、実際に実行します。
--check から始めます。これはFlowを型チェックし、副作用なしでFlowSpecのdigestを出力します。ネットワークに触れるのは固定済みToolを解決する場合だけです。CIやpre-commit hookに最適です。--dry で実行を計画します。DAGを解決し、入力を検証し、どの手順が実行されるはずか、どの効果が発生するはずかを表示します。ただし、実際の効果は一切発生させません。これは外部に影響する処理に対する「実行前に確認する」ための機能です。実行をタイムトラベルする
すべての実行はJournalを生成します。これは、すべての手順遷移と記録された効果の、追記専用でcontent-addressedなログです。条件付き通知など、単一の手順へ直接移動するには
browserflow inspect は実行のtimeline、手順、Journalを再構築するため、何が起きたのかを正確に確認できます。直近のrun idを出力する browserflow runs last と組み合わせます。--step を渡します。完了済みの作業はJournal内でcontent-addressedになっているため、中断された実行も正確に再開できます。10手順中9手順目で失敗したFlowは、1手順目ではなく9手順目から再開され、1手順目から8手順目は再実行されません。詳しくは 実行 を参照してください。
オフラインでリプレイして再現する
記録済みのJournalは、ポータブルで実行可能なフィクスチャです。実行中に1つ記録しておけば、後からどこでもオフラインでリプレイできます。Hermetic replayがデフォルトです。注入される
net、clock、random、fs-read、browser capabilityはすべてJournalだけを元に動作します。外部呼び出しは行われず、シークレットも不要です。--verify フラグは、すべての手順出力が引き続き一致することをassertします。Toolのアップグレードで挙動が変わった場合、リプレイは最初に分岐した手順で明確に失敗します。これにより、「自分のリファクタリングで何か変わったか?」を、1コマンドの決定論的なチェックにできます。同じFlowをRESTとして提供する
実行してリプレイしたものと同じFlowSpecを、Flowを一切変更せずにHTTPで公開できます。このFlowは、まったく同じ決定論的なRiderによって駆動されるHTTPエンドポイントになりました。実行時にAIは介在しません。リクエストとレスポンスの完全なsurfaceについては、REST APIとしてデプロイ と Launcher を参照してください。
browserflow serve はREST Launcherを起動します。inner loopの概要
プロジェクトをスキャフォールドした後の日常的なサイクルは、次の数個のコマンドです。| コマンド | 内容 | 副作用 |
|---|---|---|
browserflow compile <flow> --check | 型チェックし、digestを出力する | なし(純粋) |
browserflow run <flow> --dry | DAGを計画し、入力を検証する | なし |
browserflow run <flow> | ローカルで実行し、Journalを書き込む | 効果を発火する(先に確認) |
browserflow inspect <run-id> | 実行timelineをタイムトラベルする | なし |
browserflow replay <journal> --verify | オフラインで再現し、出力をassertする | なし(hermetic) |
人間向けの進捗はstderrへ、機械可読な結果(
--json)はstdoutへ出力されるため、CLIはpipelineやscriptの中できれいに組み合わせられます。1つの文から決定論的ワークフローへ
一度記録したデモンストレーションから始め、どこでも同一に実行、再現、再デプロイできるcontent-addressedなFlowSpecまで到達しました。AIはブラウザーToolの作成を支援しましたが、Flowの実行方法には関与しません。次のステップ
SDKとYAML
2つの表現、1つの真実。TypeScriptまたはYAMLでFlowを作成し、相互にround-tripできます。
実行と再現性
RiderがDAGをスケジュールし、効果を記録し、決定論的にリプレイする仕組み。
Launcher
同じFlowSpecをCLI、REST API、MCPサーバー、またはスケジュールジョブとして実行します。
CLIリファレンス
browserflow binaryのすべてのコマンド、フラグ、例。