Launcher は、ある環境向けの capability を構築し、Rider を呼び出す薄いホストです。このアーキテクチャ、つまり純粋なエンジンと注入される依存関係(原則 T4)の要点は、同じ FlowSpec がすべての Launcher の下で変更なしに実行されることです。これが「さまざまな場所で起動する」という目標です。

1. Launcher の形

すべての Launcher は同じ4つのことをします。
// 擬似的な形。どの Launcher でも約30行
async function launch(spec: FlowSpec, inputs: JsonValue) {
  const deps = buildRunDeps(env);     // 1. この環境向けの capability を配線する
  const rider = createRider(config);  // 2. エンジンを構築する
  const run = await rider.run(spec, inputs, deps); // 3. 実行する
  return present(run);                // 4. ホスト向けに結果を整形する
}
Launcher 間で変わる唯一のものは buildRunDeps です。どの Store か、どの Secrets か、どのブラウザープロバイダーか、どの並行処理かが変わります。エンジンと FlowSpec は一定です。したがって、新しい Launcher は一度で読み切れるほど小さくできます(原則 T5)。

2. Launcher

6つの Launcher が、同じ FlowSpec を別々の入口から起動します。詳細は以下の各セクションを参照してください。

CLI

browserflow run — ローカルファーストのデフォルト。SQLite store とローカル Chromium で、インフラ不要。

REST

browserflow serve — Hono on Bun を通じて Flow を HTTP エンドポイントとして公開。

MCP

browserflow mcp — Flow を MCPサーバーとして公開し、エージェントから呼び出し可能にする。

Cron / スケジュール

browserflow schedule — cron 式で Flow を定期実行する。

CIステップ

browserflow run / replay --verify — 通常のシェルステップとして CI に組み込む。

コンテナ / 組み込み

OCI イメージと @browserflow/core の直接 import(計画中)。

CLI — browserflow run

ローカルファーストのデフォルトです。SQLite store、ファイルシステム artifact、ファイルまたはOSキーチェーンのシークレット、ブラウザーツール向けのローカル Chromium を使います。インフラは不要です。
browserflow run daily-price-watch.yaml --input query="wireless headphones"
browserflow run @acme/pricing#daily-price-watch --input-file ./inputs.json

REST — browserflow serve

Hono on Bun(Node、Bun、Deno、edge runtime 間でポータブル)を通じて、Flow を HTTP エンドポイントとして公開します。公開された各 Flow は POST /flows/:name/runs になります。レスポンスは Run(または長い Flow のためにポーリングする Run ID)です。同期でも fire-and-poll でも、ルートごとに選べます。
browserflow serve --registry ./registry --port 8080
# POST /flows/daily-price-watch/runs   { "query": "..." }  → Run

MCP — browserflow mcp

@modelcontextprotocol/sdk と stdio transport(デスクトップエージェントクライアントの標準)を使って、Flow を MCPサーバー として公開します。各 Flow は MCPツールとして登録され、型付きの inputs は自動的にそのツールの inputSchema になります。エージェントが Flow を呼び出すことを決め、Flow は同じ Rider の下で決定論的に実行されます。
browserflow mcp --registry ./registry        # stdio transport
browserflow mcp daily-price-watch.yaml       # expose a single flow

Cron / スケジュール — browserflow schedule

cron スケジュールで Flow を実行します。スタンドアロンでは、これはローカル SQLite store 上の組み込み cron スケジューラー(croner によって動作)です。サービス層では、コントロールプレーンのスケジューラーが引き継ぎます(07)。
browserflow schedule daily-price-watch.yaml --cron "0 9 * * 1" --input query="..."
--cron <expr> は必須です。tick ごとに入力を変えることはサポートされていません。固定入力は --input k=v で渡します。

CIステップ

Flow は自然な CI ジョブです。決定論的で、pin され、リプレイ可能です。任意の CI システムで通常のシェルステップとして browserflow run を実行します(または、記録済み fixture に対して Tool のアップグレードをゲートするために browserflow replay --verify を実行します)。
browserflow run flows/smoke.yaml --input query="..." --yes
browserflow replay ./fix/smoke.journal.json --verify   # offline, no live deps
完全なワークフローは CIで実行 を参照してください。

コンテナと組み込みライブラリ(計画中)

コンテナイメージ(OCI。エンジン + Chromium + entrypoint としての browserflow)と組み込みライブラリモード(@browserflow/core から直接 import される createRider)は自然なデプロイ先です。エンジンがすでに、注入された capability に対する純粋関数だからです。どちらもまだ事前ビルド済みイメージとしては出荷されていませんが、ポータビリティ契約は整っています。

3. ポータビリティ契約

「どこでも変更なしに実行される」という主張を、単なる願望ではなく真実にしているものは次のとおりです。
関心事インターフェイスローカルデフォルトスケールアウト時の差し替え
run/journal storageStore.browserflow/store.sqlite の SQLitePostgres / object store
secretsSecretsfile / OS keychainVault / cloud secret manager
subprocess (shell.run)SpawnCapabilitylocal shell@browserflow/e2b sandbox
filesystem (fs.*)FsCapabilitylocal filesystem@browserflow/e2b sandbox
browserBrowserCapabilitylocal Chromium (Playwright)remote/cloud browser pool
artifactsStore (blobs)filesystemS3 / GCS
transport(launcher)CLI / HonoAPI gateway / queue
concurrencyconfigCPU-boundworker pool / autoscale
すべての行はローカルデフォルトを持つインターフェイスです。エンジン内ではどのベンダー名も指定しません。ラップトップからクラウドへの移行は書き換えではなく、buildRunDeps の変更です。そして、ラップトップで検証済みの Flow はクラウドでも再現されます。FlowSpec と Pack の digest が同一だからです(原則 T3)。

実例: shell.run / fs.* を E2B sandbox で実行する

E2B はオンデマンドの Linux microVM です。@browserflow/e2b パッケージは E2B SDK 上に SpawnCapabilityFsCapability を実装しているため、shell.runfs.* Tool はローカルマシン上ではなく、リモート sandbox 内で実行されます。FlowSpec は変更されず、注入される capability だけが異なります。
export E2B_API_KEY=e2b_
# env のデフォルトとして指定するか…
BROWSERFLOW_SANDBOX=e2b browserflow run ./flows/build.yaml --yes
# …呼び出しごとに指定して env を上書きする:
browserflow run ./flows/build.yaml --sandbox e2b --yes
browserflow bin(composition root)だけが E2B_API_KEY を読み取り、クラウド SDK を import します。エンジンはベンダーフリーのままです。sandbox は初回利用時に遅延作成され、Run の終了時に破棄されます。Rider は各 subprocess/filesystem の結果を effect として記録するため、--record-journal でキャプチャしてから browserflow replay --verify すると、その実行を オフライン で再現できます。sandbox もネットワークも不要です。任意の調整項目は BROWSERFLOW_SANDBOX_TEMPLATEBROWSERFLOW_SANDBOX_TIMEOUT_MS です。

4. エアギャップ & オンプレミス

最も強いポータビリティの主張は、FlowSpec、その pin された Pack、そして(任意で)記録済みの Journal をネットワーク分離環境に持ち込み、接続ゼロで結果を再現できることです。
1

自己完結したバンドルを export する

browserflow pack export @acme/pricing@2.3.0 --out pricing.pack — 自己完結した、digest 検証済みのバンドルです。
2

境界を越えて移動する

それを移動します(USB、内部ミラー、その境界が許す任意の手段)。
3

境界内で install して run する

境界内で browserflow install ./pricing.pack && browserflow run … を実行します。
4

監査のために再現する

監査レベルの再現には、Journal も一緒に運び、browserflow replay --verify を実行します。
シークレットはいずれの artifact にも含まれて移動しません。シークレットは実行時に、分離環境自身の Secrets provider から供給されます。

5. 1つのFlow、多くの入口 — 実例

daily-price-watch Flow は、変更なしで次のようになります。 Flow の結果は、どの入口から呼び出されたかには依存しません。その不変性こそがプロダクトです。

サービス(コントロールプレーン)

ホスト型スケジューラー、Registry、マルチテナントのコントロールプレーン。

Tool と Pack

digest で pin された Pack と、Launcher が配線する capability Interface。