Supapool: 並列コーディングエージェント向けエフェメラル Supabase インスタンス

Supapool は開発者と AI エージェントが約 400ms でクリーンで分離された Supabase インスタンスをリースできるようにします。これによりモックや遅いデータベースブランチングが不要になり、並列コーディングエージェントが実際の Supabase スタックに対してマイグレーションやデータベース操作を実行しても互いに干渉しません。

分離された Supabase スタックの高速デプロイ

Supapool は、Postgres、Auth、S3 互換ストレージを含む実際の Supabase 環境を提供し、エージェントが作業を実行している場所に近い場所に配置されます。標準的なデータベースブランチングは初期化に数分かかり、プロダクションレベルの課金が発生しますが、Supapool のインスタンスはエフェメラルで高速取得を前提に設計されています。

主な技術的利点は次のとおりです:

  • Zero Collision: 並列エージェントは完全に別々のインスタンスで動作し、実行中に互いのデータを上書きすることが防止されます。
  • No Mocks: テストは実際のスタック上で行われ、マイグレーションやデータベース操作が本物の Supabase インフラストラクチャで検証されます。
  • Colocation: インスタンスはエージェントの実行環境の近くで起動され、レイテンシを最小化します。
  • Agent-First Design: プラットフォームは CLI のみでダッシュボードはなく、アカウント情報、使用量、コストを API 経由で自動化システムに直接パイプできます。

CLI 統合とワークフロー

Supapool は主に @supapool/cli パッケージで管理されます。コアワークフローは既存のコマンドをラップして一時的な環境を注入することです。

コマンド実行

run コマンドを使用すると、Supapool はインスタンスをリースし、ラップされたコマンドの環境変数に必要な認証情報を注入します:

npx @supapool/cli run -- npm run dev

run が実行されると、CLI は以下の手順を実行します:

  1. クリーンなインスタンスを取得します。
  2. supabase/migrations にあるすべての .sql ファイルをファイル名順に適用します。
  3. インスタンスの認証情報を環境に設定した状態でコマンドを開始します。
  4. コマンドがアクティブな間、リースを更新し続けます。
  5. コマンドが終了したらインスタンスを解放します。

環境変数の注入

ラップされたコマンドは SUPABASE_URLSUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYDATABASE_URL といった標準的な Supabase 変数を受け取ります。さまざまなフレームワークとの互換性を確保するため、これらの値は Next.js、Vite、Astro、Svelte、Expo、Create React App、Gatsby、Nuxt、さらには Prisma や Postgres の URL エイリアスで使用される一般的な公開プレフィックスにもミラーされます。

リース管理とライフサイクル

すべての Supapool インスタンスはデフォルトで 30 分の TTL(Time‑to‑Live)を持つリースとして扱われます。CLI はプロセスがアクティブな間、5 分ごとに自動でリースを更新します。プロセスが終了するか更新ハートビートが止まると、リースは期限切れとなりインスタンスは消去されプールに戻されます。

インスタンスは使い捨てなので、リースが解放された後にデータが残ることはありません。

CI/CD とプログラム的アクセス

Supapool は SUPAPOOL_API_KEY 環境変数を通じて自動化環境をサポートします。CI 環境では、ユーザーは ~/.config/supapool/config.json から API キーをコピーし、シークレットとして設定することでブラウザベースの GitHub ログインを回避できます。

SUPAPOOL_API_KEY=sp_live_... npx @supapool/cli run -- pnpm test

より深い統合が必要な開発者向けに、@supapool/cli npm パッケージをライブラリとして使用できます。withInstance 関数はリースのライフサイクルを自動で管理します:

import { withInstance } from '@supapool/cli'

await withInstance(async (instance) => {
  const { SUPABASE_URL, SUPABASE_ANON_KEY, DATABASE_URL } = instance.env
  // テストやシードデータの実行
})

上級ユーザーはエクスポートされたライフサイクルプリミティブ acquirerenewreleasestartRenewer を利用して、カスタムリース境界管理を行うことができます。

Sources