Flowは構造上ポータブルです。一度作成し、content-addressedなFlowSpecにコンパイルすれば、どこでも同一に実行できます。REST Launcherはそのfrontの1つです。同じエンジンをHTTPの背後に置くことで、任意のクライアントが入力を投稿し、実行時にAIを介さず、決定論的なRunを受け取れるようにします。

REST Launcher

browserflow serve は、Registry内のFlowをHTTPエンドポイントとして公開します。内部では Hono on Bun を使っており、ホストはNode、Bun、Deno、edgeランタイム間でポータブルに保たれます。ポータビリティ契約に従い、変わるのはLauncherのtransportだけで、エンジンとFlowSpecは一定のままなので、同じLauncherコードがそれらすべてで動作します。
browserflow serve --registry ./registry --port 8080
公開済みの各Flowは、単一のrouteになります。
POST /flows/:name/runs
Launcherは、この環境向けにcapabilityを配線してエンジンを呼び出す薄いホストです。serving process向けの buildRunDeps(どの Store、どの Secrets、どのbrowser providerか)を構築し、その後、解決済みのFlowSpecを実行します。手元のラップトップで検証したFlowは、FlowSpecとPack digestが同一であるため、ここでも再現されます。

Flowへ入力を投稿する

標準的な daily-price-watch Flowを実行するには、そのFlowのtyped inputをFlowの runs routeへ投稿します。このFlowでは、browser Tool(search-price@1.2.0)がtransformと、シークレットwebhookへの条件付き http.post に値を渡します。
curl -X POST http://localhost:8080/flows/daily-price-watch/runs \
  -H "Content-Type: application/json" \
  -d '{ "query": "wireless headphones" }'
レスポンスは Run、つまりFlowを実行した結果です。他のfrontと同じくJournalに裏付けられています。secret.WEBHOOK_URL として参照されるシークレットwebhook URLは、実行時にserving process上で解決され、secrets capabilityを宣言した手順にだけ注入されます。リクエスト、レスポンス、いかなるログにも流れません。
リクエストボディはFlowのtyped inputs です。daily-price-watch では、これは query フィールドです。Flowの入力schemaと一致しない入力を投稿すると、Runが開始する前に拒否されます。

同期またはfire-and-poll

Launcher仕様に従い、各routeは2つの方法のどちらかで応答できます。routeごとに選択できます。
モード呼び出し方法レスポンス使用する場面
同期POST /flows/:name/runs(デフォルト)完了した Run をinlineで返すFlowがすばやく完了し、呼び出し元が結果をinlineで受け取りたい場合
Fire-and-pollPOST /flows/:name/runs?mode=asyncHTTP 202 + run id。GET /runs/:id をpollするFlowの実行時間が長く、接続を開いたままにしたくない場合
どちらの場合も、同じ Rider が同じRunとJournalを生成します。違いは、Launcherがホスト向けに結果をどう整形するかだけです。
1

サーバーを起動する

browserflow serve --registry ./registry --port 8080 は、./registry 内のFlowに対してHTTPホストを立ち上げます。
2

入力を投稿する

Flowのtyped inputをJSONボディとして、POST /flows/daily-price-watch/runs へ送信します。
3

Run(またはrun id)を取得する

同期routeは完了したRunを返します。fire-and-poll routeは、長いFlowをpollするためのrun idを返します。

サービス層へデプロイする

自分で browserflow serve を実行する場合、インフラは不要です。チームがマネージドなデプロイを必要とする場合、オプションのコントロールプレーンによって、これを宣言的なデプロイにできます。PackをplaneのRegistryに公開し、その後、必要なfrontでそのFlowを公開します。
browserflow pack publish --registry https://plane.acme.dev   # versioned、digest固定
browserflow deploy daily-price-watch --as rest               # RESTで公開
デプロイは、どのFlow digestどのfront でliveかを記録するため、元に戻せます。ロールバックとは以前のdigestへ向け直すことであり、devからstaging、prodへ昇格する際にはdigestを移動します。つまり、テストしたものがそのまま出荷されます。サービスを採用しても、Flowの実行方法は変わりません。追加されるのはcoordinationであり、capabilityではありません。
browserflow deploy--as フラグを複数回受け取れるため、--as rest --as mcp により、同じdigestをRESTとMCPの両方で同時に公開できます。どのfrontから呼び出されても、Runは不変です。

API surface全体

上記のroute形状がREST frontの中核です。完全なリクエストschemaとレスポンスschema、pollingエンドポイント、error semanticsについては、専用のAPI Referenceを参照してください。

APIリファレンス

REST Launcherの完全なリクエストschemaとレスポンスschema。

Launcher

CLI、REST、MCP、cron、CI、containerの各frontと、ポータビリティ契約。

サービスへデプロイする

マネージドなコントロールプレーンでPackを公開し、Flow digestをデプロイします。