stream-flutter について
stream-flutterは、FlutterプロジェクトでのStream関連作業を依頼内容に応じて振り分け、新規作成、統合、リファレンス検索、移行の手順を案内します。チャットUIの方針やコンポーネントのカスタマイズ、デザイン確認も扱います。
主な機能
- 01依頼内容に応じたフロー分類
- 02作成・統合・移行の振り分け
- 03チャットUI方針の案内
- 04コンポーネント調整とデザイン確認
活用シーン
- 01FlutterアプリにStream Chatを追加
- 02StreamのビデオまたはFeedsアプリを作成
- 03Stream Flutterのドキュメントやウィジェットを検索
- 04FlutterアプリをSendbirdから移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ getstream/ agent-skills --skill stream-flutterインストール後、Claude Code で/stream-flutterを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
builder.mdcustom-ui.mddesign-matching.mdRULES.mdsdk.mdsendbird-migration.mdreferences/CHAT-ADVANCED-FLUTTER-blueprints.mdCHAT-ADVANCED-FLUTTER.mdCHAT-CORE-blueprints.mdCHAT-CORE.mdCHAT-FLUTTER-blueprints.mdCHAT-FLUTTER.mdFEEDS-FLUTTER-blueprints.mdFEEDS-FLUTTER.mdLIVESTREAM-FLUTTER-blueprints.mdLIVESTREAM-FLUTTER.mdRINGING-FLUTTER-blueprints.mdRINGING-FLUTTER.mdVIDEO-ADVANCED-FLUTTER-blueprints.mdVIDEO-ADVANCED-FLUTTER.mdVIDEO-FLUTTER-blueprints.mdVIDEO-FLUTTER.md詳細
Stream Flutter - スキルルーター + 実行フロー
ルール: セッションごとに RULES.md を一度読みます。妥協できないルールはすべてここに記載されており、ほかの場所にはありません。
このファイルは、Flutter アプリで Stream を使用する際の、意図の分類、ローカルプロジェクトの検出、モジュールへのポインターをまとめた唯一のエントリーポイントです。
ステップ 0:意図の分類(最初に必ず実施。省略禁止)
ツールを呼び出す前に、ユーザーの入力だけをもとにトラックを決定します。事前の調査は行いません。
シグナル -> トラック
| ユーザー入力に含まれるシグナル | トラック |
|---|---|
明示的なパッケージ/ウィジェットのトークン:stream_chat_flutter、StreamChannelListView、StreamMessageListView、StreamChatClient など | C - リファレンスの検索 |
明示的なビデオのトークン:stream_video_flutter、StreamCallContainer、StreamVideo、StreamVideoRenderer、goLive、stopLive、livestream の通話タイプ | C - リファレンスの検索 |
明示的なフィードのトークン:stream_feed、stream_feed_flutter_core、StreamFeedClient、FlatFeedCore、FlatFeed、FeedBloc、activity feed、feeds flutter | C - リファレンスの検索 |
| Stream Flutter に関する作業で「docs」または「documentation」という単語がある | C - リファレンスの検索 |
| 「Flutterで{X}するには?」「{widget/method}は何をしますか?」 | C - リファレンスの検索 |
| 「新しいFlutterアプリを作って」「Flutterチャットアプリを作成して」+ Stream | A - 新規アプリ |
| 「Flutterビデオ通話アプリを作って」「Flutterでライブ配信アプリを作成して」 | A - 新規アプリ(VIDEO-FLUTTER.md + VIDEO-FLUTTER-blueprints.md または LIVESTREAM-FLUTTER.md + LIVESTREAM-FLUTTER-blueprints.md を読み込む) |
| 「オーディオルーム/Twitter Spacesクローンを作って」「TikTok風のライブフィード」「ライブ配信しながら通話」「ビデオ通話付きチャット」「同時に2つの通話」 | AまたはB(Video/Livestreamのペアに加えて、VIDEO-ADVANCED-FLUTTER.md + VIDEO-ADVANCED-FLUTTER-blueprints.md を読み込む) |
| 「呼び出し/着信通話を追加して」「プッシュ通知付きビデオ通話」「CallKit」「VoIPプッシュ」「FCM着信」「不在着信通知」 | AまたはB(Videoのペアに加えて、RINGING-FLUTTER.md + RINGING-FLUTTER-blueprints.md を読み込む) |
| 「Flutterフィードアプリを作って」「アクティビティフィードアプリを作成して」「Flutterでソーシャルフィードを作って」「Twitter/Instagramクローンを作成して」 | A - 新規アプリ(FEEDS-FLUTTER.md + FEEDS-FLUTTER-blueprints.md を読み込む。ユーザーが明示的に指定しない限り、Twitter風のUIを使用する) |
| 「このアプリにStreamを追加/統合して」「FlutterプロジェクトにChatを組み込んで」 | B - 既存アプリ |
| 「Flutterアプリにビデオ通話を追加して」「既存アプリにStream Videoを統合して」 | B - 既存アプリ(VIDEO-FLUTTER.md + VIDEO-FLUTTER-blueprints.md を読み込む) |
| 「Flutterアプリにフィードを追加して」「既存アプリにStream Feedsを統合して」「アクティビティフィードを追加して」 | B - 既存アプリ(FEEDS-FLUTTER.md + FEEDS-FLUTTER-blueprints.md を読み込む。ユーザーが明示的に指定しない限り、Twitter風のUIを使用する) |
| より広範な機能のリクエストを伴わない「Streamパッケージをインストールして」「FlutterでStreamをセットアップして」「認証/トークンを組み込んで」 | D - 初期セットアップ |
「FlutterアプリをSendbirdから移行して」「sendbird_chat_sdk/sendbird_uikit をStreamに置き換えて」「Sendbird/SendbirdUIKitから切り替えて」 | M - Sendbirdからの移行(sendbird-migration.md) |
引数なしの単独の /stream-flutter | トラックを簡潔に一覧表示して待機する |
スタイリングの深さを決めるフラグ(Track A/B/C/Dとは独立)
リクエストに目標とする外観(添付されたスクリーンショット、Figma フレーム、「WhatsApp / iMessage / Telegram / Slack / のような見た目にする」など)が含まれている場合、機能の実装(Track A または B)に進む前に、まず次の方針決定を実施してください(コンポーネントかカスタムか)。
- コンポーネント →
design-matching.mdを実行します。手順部分をすべて読みます。つまり、# Referenceの区切りより上のすべて(Step 1~5)です。途中で切れていて2回の Read が必要になる場合があるため、手順の途中で切れた箇所の先までページを進めてください。実装時には、領域ごとに Reference 部分を Grep します。 - カスタム(ライブ配信/オーバーレイ/独自デザイン)→ 代わりに
custom-ui.mdを実行します。領域ごとに同じ厳密さで進めますが、仕組みは異なります。
このセクションの残りは、コンポーネントの場合(一般的なケース)について説明します。参照デザインは、領域(ヘッダー、コンポーザーのボタン、タイムスタンプと既読確認の表示位置、吹き出しの形状としっぽ、日付の区切り、添付ファイルなど)のチェックリストです。その大半は、色だけでなく構造的にStream のデフォルトと異なります。壁紙と吹き出しの色だけで済ませてはいけません。これはよくある失敗パターンです。まず各領域を(色だけでなく寸法も含めて)分解し、それぞれを次の2つの軸のいずれかに振り分けてください。
- テーマ設定 —
StreamTheme(MaterialApp.theme.extensions上のThemeExtension)は、デザインの基盤(間隔/角丸/タイポグラフィ/色)に加え、細部や末端のスタイルすべて(メッセージ行全体のスタイルであるmessageItemThemeの吹き出し/テキスト/添付ファイル/メタデータ、reactionsTheme、reactionPickerTheme、avatarTheme、textInputTheme、mediaViewerThemeなど)を管理します。一方、StreamChatThemeData(StreamChat(themeData:)に渡します)が管理するのは、チャット複合ウィジェットのスロットのみです(3つのヘッダー、メッセージリストの背景/壁紙、チャンネルリストのアイテム、引用されたメッセージ、スレッドタイル、投票テーマ)。 - ウィジェットの置き換え — コンポーネントファクトリーは、
StreamComponentBuilders(...)のコアの名前付きスロット(約48個の末端スロット:messageBubble、messageText、reactions、reactionPicker、mediaViewer、jumpToUnreadButton、textInput、avatarなど)と、streamChatComponentBuilders(...) → extensions:のチャットスロット(約30個の複合スロット:messageItem、messageComposerとそのサブスロット、channelListItem、添付ファイルごとのビルダーなど)を使って構成します。これらは、グローバルにはStreamChat(componentBuilders: StreamComponentBuilders(...))に、スコープ単位ではStreamComponentFactory(builders: …, child: …)に渡します。さらに、単一のインスタンスにはウィジェットごとのビルダー(messageBuilder、itemBuilder)を使います。
このドキュメントで注意を促している、繰り返し発生する落とし穴:
- (a) 複合ウィジェット(
messageItemビルダー、messageComposerビルダー、StreamMessageListViewのmessageBuilder)を上書きすると、デフォルトで描画されていたサブ機能(受信メッセージのアバター、グループ化、リアクション、返信、ステータス、送信/音声/編集/低速モードのボタン)が、気づかないうちに失われます。デフォルトのbuild()を読んで、それらを再現しない限り失われたままです(グループ化の状態は、カスタムmessageItem内でStreamMessageLayout.of(context)を使って取得できます)。 - (b) モデルに基づくタイトルのロジックは、チャンネルリストの
itemBuilderとヘッダーの両方で使う共有ヘルパーにまとめる必要があります。これにより、2つの表示箇所で内容が食い違うのを防げます。 - (c) 適切に振り分けてください。吹き出しのパディング/色/形状は**
StreamTheme**(StreamTheme.messageItemTheme.bubble)で設定します。フィールドの外側に送信ボタンを置く、吹き出し内にメタデータを表示する、吹き出しにしっぽを付ける、Slack 風のフラットな行にするといった構造の変更には、ウィジェットの置き換え(コンポーネントファクトリーまたはウィジェットごとのビルダー)が必要です。 各領域をトリガーするデータを投入して実行し、実際のナビゲーション経路で領域ごとにリファレンスと比較し、反復するまで、マッチしたとは言えません(design-matching.mdのステップ 5)。使い捨ての検証用足場はすべて削除してください。UI はリファレンスにできる限り近づける必要があり、おおよそ似ているだけでは不十分です。コンポーザーも含め、すべての領域を実装してください。「既知の見た目上の差分」と残りの領域にラベルを付けて、不完全なマッチを納品してはいけません。SDK のデフォルトのままの領域があれば、それは FAIL であり、脚注ではありません。また、作業はまとめて行ってください。固定した SDK バージョンとローカルチェックアウトを最初に一度確認し、必要なソースをまとめて読み、一度にすべての領域を実装してから、ホットリロードで一度検証してください。小さな変更のたびにビルドとスクリーンショット撮影を繰り返してはいけません。
チャットのみ:最初に UI 戦略を選択してください(コードを書く前に)
Stream Chat には2 つのレイヤーがあり、どちらを選ぶかは、スタイリングの選択をはるかに上回るアーキテクチャ上の決定です。誤った選択をすると、いずれにしても 1 日を無駄にします。そのため、慎重に判断し、事前構築済みコンポーネントをデフォルトとして選択してください。
| 戦略 | デザインが次のような場合に使用 | 仕組み | 手順書 |
|---|---|---|---|
事前構築済み UI コンポーネント(stream_chat_flutter) — デフォルト | メッセンジャー:吹き出し、またはチャンネルリストから会話への遷移、メッセージごとのアバター/タイムスタンプ/既読通知/リアクション/添付ファイル。ソーシャル、マーケットプレイス、職場、サポート、DM。「WhatsApp/iMessage/Telegram/Slack のような見た目にする」。 | 2 つの軸でカスタマイズします。テーマ設定(基盤とメッセージ行/リーフウィジェットには StreamTheme、チャット複合ウィジェットには StreamChatThemeData)と、ウィジェットの置き換え(コンポーネントファクトリー StreamComponentBuilders/streamChatComponentBuilders/StreamComponentFactory に加え、ウィジェットごとのビルダー)です。 | design-matching.md |
stream_chat_flutter_core 上のカスタム UI — 例外 | メッセンジャーではないもの:吹き出しがなく、投稿者情報が本文内に表示されるフラットなフィード、動画上のオーバーレイ/ティッカー、大量の一時的なライブ配信チャット(Twitch/YouTube/Kalshi)、ライブショッピング、または投稿者を大幅に上回る匿名/ゲストの読み取り専用閲覧者(→ livestream チャンネルタイプ)。すべてのメッセージを同一に描画し、その周囲に独自のアプリ UI を構築する場合です。 | ヘッドレスの stream_chat_flutter_core コントローラー(および低レベルのクライアント)上に独自のウィジェットを構築します。stream_chat_flutter のウィジェットは使用しません。 | custom-ui.md |
コンポーネントを強く優先してください。 コンポーネントはカスタマイズできるように作られています。判断基準は、2 つの軸、つまりテーマ設定(StreamTheme と StreamChatThemeData)といくつかのコンポーネントビルダーのスロットで実現できるなら、コンポーネントを使うべきということです。メッセンジャーの大幅なリスキンでも同様です。カスタムを選ぶのは、デザインに合わせるためにメッセージ行、コンポーザー、ヘッダー、リストをすべて一度に置き換える必要がある場合、つまり SDK をウィジェットとしてではなく、単なるデータソースとして使う場合だけです。カスタムを選びすぎる(手作業で劣るメッセンジャーを再構築し、アバター/グループ化/リアクション/スレッド/添付ファイル/入力中表示/既読通知/ピッカーを失う)のは、よくある高くつく誤りです。コンポーネントを選びすぎても、レイアウト調整に数時間かかる程度です。迷ったら、まずコンポーネント版を作ってください。採用するか却下するかを確認するほうが早いからです。また、「ライブ配信」や「ライブショッピング」はラベルではなく判断材料として扱ってください。フラットで同一の行、オーバーレイ/ティッカー、大量のメッセージ、読み取り専用の閲覧者という形式に当てはまる場合に限り、カスタムを選びます。通常の吹き出し/チャンネルリスト形式のチャットパネルを求めるライブ配信アプリは、コンポーネントを使います。これが判断基準の全体です。カスタムを選んだ後に参照する実装手順書が custom-ui.md であり、どちらを選ぶか判断するために読むドキュメントではありません。
Workplace/Slack 風のハイブリッドもコンポーネントを使う構成です。 Slack/Teams/Discord の画面は、チャンネル一覧+メッセージ一覧+コンポーザーで構成されるため、既製コンポーネントを使います。ただし、メッセンジャーとは異なる次の2点を合わせる必要があります。1)メッセージ行はフラットで左寄せです(上部にアバターを置いた角丸四角形、作成者・カスタムステータス・タイムスタンプのヘッダー行、本文、下部のリアクションピル、スレッド返信の概要)で、受信/送信の吹き出しの区別はありません。messageItem コンポーネントビルダー(複合スロット — サブ機能も再現してください)をオーバーライドして再現します。2)ヘッダーと周辺 UI はカスタムです。Workplace の全体的なアーキタイプは design-matching.md にあります。Workplace アプリはスレッド優先でもあるため、スレッド返信の概要とスレッド画面を接続してください。
この戦略では、チャンネルの種類と権限モデル(例:ソーシャル/マーケットプレイスではメンバーシップ制限付きの messaging、ライブ配信では匿名の閲覧者に公開された livestream)も選択します。詳細は RULES.md →「権限の前提条件を事前に確認する」と、ステップ0.5 →「権限の把握」を参照してください。2つの軸を併せて決めてください。
本当に判断がつかない場合は、質問を1つだけしてください。
このチャットは、標準的なメッセンジャー(チャンネル一覧+吹き出し)のような見た目ですか。それとも、ライブ配信/オーバーレイチャットのような独自の画面ですか? 既製コンポーネントをカスタマイズするか、
stream_chat_flutter_core上にカスタム UI を構築するかが決まります。
判別フロー
依頼が構築/統合とリファレンスの照会のどちらか曖昧な場合は、短い質問を1つして返答を待ちます。
これをプロジェクトに組み込みますか。それとも、Flutter SDK のパターンとウィジェットを整理するだけでよいですか?
分類後
- トラック A、B、D -> セッションごとに一度だけプロジェクトシグナルを実行し、その後
builder.mdとsdk.mdに進みます。スタイリング深度フラグが立っている場合は、UI 戦略の判断に従ってデザイン照合フェーズも並行して実行します。既製コンポーネントの場合はdesign-matching.md(通常はこちらです。手順部分全体、つまり# Referenceの区切りより上を最後まで読みます。2回に分けて読む場合があります。その後、各領域の Reference 部分を Grep してください)、独自のstream_chat_flutter_core画面の場合はcustom-ui.mdを参照します(デザイン照合の厳密な実施は必須フェーズであり、任意の追加作業ではありません)。 - トラック C -> 製品とパッケージが明示されている場合は、プローブを省略します。SDK レイヤーが曖昧な場合に限り、必要に応じて実行します。
- トラック M ->
sendbird-migration.mdを実行します。既存の Sendbird 統合の形を検出し、パッケージ/初期化/ビュー/チャンネル/メッセージを置き換え、2つの軸に沿ってテーマを再適用し、Sendbird の元の画面と照らして画面ごとにデザインと機能の忠実性を検証します。ステップ0.5の認証情報とdesign-matching.md/custom-ui.mdの厳密さを再利用します。コード移行が完了したら、共通のデータ移行ランブックに引き継ぎます。
ステップ0.5:認証情報、トークン、シードデータ(トラック A、B、D — およびフェーズ M2 のトラック M)
これをセッションごとに一度、意図の分類直後、プロジェクトシグナルのプローブ前に実行します。
目標
コードに触れる前に Stream のAPI キーとユーザートークンを取得し、必要に応じてチャンネルや通話をシードします。これにより、アプリの初回実行から実データを表示できます。
最初に行う質問(正確に一度だけ質問し、すぐに対応する)
関連するすべての項目をまとめて尋ねるメッセージを1つ投稿します。複数回に分けて質問しないでください。
チャットプロジェクトの場合:
実データに接続するため、いくつか簡単な質問があります。
- 認証情報 - ダッシュボードから API キーを取得し、Stream CLI 経由でトークンを生成しましょうか。それとも、ご自身で貼り付けますか?
- トークンの有効期限 - トークンをこちらで生成する場合、有効期限を設定しますか?(例:
1h、1d、30m)、それとも無期限にしますか?- シードチャンネル - アプリですぐに表示できるよう、ランダムなユーザー名でいくつかチャンネルを事前に作成しましょうか?
すべてご自身で設定する場合は、API キーとトークンを貼り付け、チャンネルにシードデータを追加するかどうかをお知らせください。
Video プロジェクトの場合(通話は一時的なため、シードデータは不要です):
すべてを接続するため、いくつか簡単な質問があります。
- 認証情報 - ダッシュボードから API キーを取得し、Stream CLI 経由でトークンを生成しましょうか。それとも、ご自身で貼り付けますか?
- トークンの有効期限 - トークンをこちらで生成する場合、有効期限を設定しますか?(例:
1h、1d、30m)、それとも無期限にしますか?すべてご自身で設定する場合は、API キーとトークンを貼り付けてください。
ゲスト視聴者に関する要件 — 視聴者をゲストとしてサインインさせるアプリを構築する前に、必ずこの要件を伝えてください。ゲストはデフォルトで最小限の機能しか持たない
guestロールで接続します。livestream通話タイプでは、インテグレーターがguestロールに権限を付与するまで、ゲストは通話を読み取ることも参加することもできません。ゲストを使った視聴者フローが対象となる場合、関連する通話タイプの Stream Dashboard → Video & Audio → Call Types → → Roles & Permissions から(または API を使用して)、guestロールにread-callとjoin-call(ホストより先に視聴者が通話を開始する場合はcreate-callも)を付与することが前提条件であることをインテグレーターに伝えてください。または、認証済みのUser.regular視聴者を使用してください。詳細は、references/VIDEO-FLUTTER.md→ Guest users と、references/LIVESTREAM-FLUTTER.md→ Roles, permissions, and backstage security を参照してください。
Feeds プロジェクトの場合(組み込み済み UI はなく、フィードグループが必要です):
セットアップに関する質問はすべてまとめて1 回のメッセージで尋ねてください。複数回に分けてはいけません。
すべてを接続するため、いくつか簡単な質問があります。
- 認証情報 - ダッシュボードから API キーを取得し、Stream CLI 経由でトークンを生成しましょうか。それとも、ご自身で貼り付けますか?
- トークンの有効期限 - トークンをこちらで生成する場合、有効期限を設定しますか?(例:
1h、1d、30m)、それとも無期限にしますか?- フィードグループ - Stream プロジェクトに 3 つのフィードグループ(user、timeline、notification)を作成する必要があります。こちらで自動的に設定しましょうか。それとも、すでに作成済みですか?
- シード投稿 - 初回実行時からフィードにコンテンツが表示されるよう、サンプル投稿をいくつか追加しましょうか?
認証情報をご自身で設定する場合は、API キーとトークンを貼り付けてください。
ユーザーの返信後は、途中で確認を挟まず、すべての手順を実行してください。フィードグループについて、ユーザーが「自動的に設定」と回答した場合:
getstream api CreateFeedGroup --request '{"id": "user", "type": "flat"}'
getstream api CreateFeedGroup --request '{"id": "timeline", "type": "flat"}'
getstream api CreateFeedGroup --request '{"id": "notification", "type": "notification"}'
CLI コマンドが失敗した場合(Feeds API は Chat とは異なるエンドポイントを使用することがあります)、次の内容を一度だけユーザーに伝えてください。
Stream Dashboard → Activity Feeds → Feed Groups で、次のフィードグループを作成してください:
user(Flat)、timeline(Flat)、notification(Notification)。
Feeds プロジェクトでは、connect() の後、main 内に次の 2 つのヘルパーを必ず別々に生成してください。
_setupFollows(client)— 必ず無条件で呼び出してください。timelineがuserをフォローするように設定し、ユーザー自身の投稿がそこに表示されるようにします。これをシード処理に統合してはいけません。シードデータが存在するとガード節で早期に戻るため、フォロー処理が実行されなくなるからです。_seedPosts(client)— ユーザーがシードデータの追加を希望した場合にのみ実行します。サンプルアクティビティを追加し、データがすでに存在する場合は早期に終了します。
両方の実装については、references/FEEDS-FLUTTER.md を参照してください。
パッケージは stream_feeds: ^0.5.1 です。非推奨の stream_feed または stream_feed_flutter_core ではありません。
ユーザーが回答した後 — 追加の確認なしで実行
ユーザーの回答後、確認を挟まずにすべての CLI 手順を順番に実行します。各手順では、進行しながら簡潔に説明してください(アクションごとに1行)。「続行してよいですか?」と尋ねて中断してはいけません。
ステップ A — API キー
getstream env --target flutter
これにより公開 API キーが dart_defines.json に書き込まれます。アプリは String.fromEnvironment('STREAM_API_KEY') を介してこれを読み込み、flutter run --dart-define-from-file=dart_defines.json で実行されます。コマンドが 401 エラーを返した場合、CLI セッションの有効期限が切れています。再認証するために getstream login を実行してから、もう一度試してください。
getstream がインストールされていない場合(command not found):ユーザーに https://getstream.io からインストールするよう依頼し、完了を待ちます。または、ユーザーが希望する場合は CLI を完全に省略し、API キーとユーザーごとのトークンを貼り付けてもらいます(Dashboard -> Explorer にトークンジェネレーターがあります)。最初に確認した認証情報に関する質問へのユーザーの回答に基づいて判断し、停滞させないでください。
ステップ B — トークン
# Never-expiring
getstream token <user_id>
# Expiring
getstream token <user_id> --ttl <duration>
トークンはコンテキスト内に保持します。すべてのコードスニペットで、API キーとともにこのトークンを使用してください。プレースホルダー文字列は使用しないでください。
ステップ C — チャンネルのシード(ユーザーが「はい」と答えた場合のみ)
現実的なランダムなユーザー名を使って、3〜5 個のチャンネルを作成します。デフォルトのチャンネルタイプには messaging を使用してください。
サブステップ C1 — すべてのユーザーを upsert(シードユーザー + トークンユーザー):
getstream api UpdateUsers --request '{
"users": {
"<token_user_id>": {"id": "<token_user_id>", "name": "<Display Name>"},
"alice": {"id": "alice", "name": "Alice"},
"bob": {"id": "bob", "name": "Bob"},
"carol": {"id": "carol", "name": "Carol"},
"dave": {"id": "dave", "name": "Dave"}
}
}'
サブステップ C2 — 各チャンネルを作成(本文にメンバーを含めないでください。メンバーは C3 で追加します):
getstream api GetOrCreateChannel --type messaging --id <channel-id> \
--request '{"data": {"created_by_id": "<token_user_id>", "custom": {"name": "<Channel Name>"}}}'
各チャンネル(例:general、random、team-alpha)について繰り返します。
サブステップ C3 — add_members を使って各チャンネルにメンバーを追加。トークンユーザーは、アプリ内の Filter.in_('members', [userId]) クエリで結果が返るように、すべてのチャンネルに含める必要があります。
getstream api UpdateChannel --type messaging --id <channel-id> \
--request '{
"add_members": [
{"user_id": "<token_user_id>"},
{"user_id": "alice"},
{"user_id": "bob"}
],
"user_id": "<token_user_id>"
}'
短く覚えやすいチャンネル ID(例:general、random、team-alpha)を生成し、少数のランダムなユーザー名(例:alice、bob、carol、dave)を使用します。チャンネル一覧のフィルターは Filter.in_('members', [tokenUserId]) であり、ユーザーが含まれていないと結果は何も返されないため、トークンユーザーはすべてのチャンネルに追加する必要があります。
サブステップ C4 — メッセージをシード。message.user_id を使って、サーバー側で送信者を指定します。リストにプレビューが表示され、チャンネル画面が空にならないよう、各チャンネルに数件送信します。スレッド返信でレスポンスを解析せずに参照できるよう、返信先にするメッセージには明示的な message.id を設定してください。
getstream api SendMessage --type messaging --id <channel-id> \
--request '{"message":{"id":"<channel-id>-m1","user_id":"alice","text":"Morning - anyone up for a sync today?"}}'
# Threaded reply into that message
getstream api SendMessage --type messaging --id <channel-id> \
--request '{"message":{"user_id":"bob","text":"I will bring the numbers","parent_id":"<channel-id>-m1"}}'
シード後、簡潔な概要を出力します。
作成したチャンネル:
general(token_user、alice、bob)、random(token_user、carol、dave)、team-alpha(token_user、alice、carol)
ステップ D — 自動的に続行
すべての CLI 手順が成功したら、中断せずに続行します。追加の確認は不要です。トラック A/B/D は Project signals に進み、その後 builder.md に進みます。トラック M は sendbird-migration.md に戻ります(フェーズ M2)。いずれかの CLI 手順が失敗した場合は、エラーを簡潔に説明し、不足している値を手動で貼り付けるようユーザーに依頼してから続行してください。
してはいけないこと
- アプリのコードに API シークレットを決して含めないでください。CLI はサーバー側でのみ使用します。
- 認証情報を捏造したり、作り上げたりしないでください。
- ステップ A、B、C、D の間で「続行してよいですか?」と尋ねないでください。ユーザーが最初に回答したら、一連の手順をすべて実行してください。
権限への配慮(チャット — 事前に積極的に伝える)
Stream Chat では、クライアント側の呼び出しごとに、ロールとスコープに応じて権限がチェックされます。ただし、サーバー側の呼び出し(CLI および API secret を使用するバックエンド)では、すべてのチェックが回避されます。この非対称性が、「シード時には成功したのに、アプリでは 403 が発生する」主な原因です。CLI 経由でのチャンネルのシードは権限設定に関係なく成功しますが、アプリから同じクエリや参加を行うと、接続中のユーザーのロールが適用され、失敗します。
これから構築するアプリで、ユーザーがすでに参加しているチャンネル内でのチャット以外の操作を行う場合は、機能を書く前に、該当する権限設定をインテグレーターに伝えてください。実行時に 403 が発生するまで待たないでください。 シナリオに応じた権限設定は次のとおりです。
| 構築するアプリの動作 | 接続するロールに必要なチャンネルタイプの権限 | user/guest のデフォルト messaging |
|---|---|---|
ユーザーが作成していないグループを見つける/閲覧する(members フィルターなしの queryChannels) | Read Channel(ReadChannel) | 多くの場合オフ |
既存のグループに参加する(channel.addMembers([myId])) | Add Own Channel Membership(AddOwnChannelMembership) | 多くの場合オフ |
グループから退出する(channel.removeMembers([myId])) | Remove Own Channel Membership(RemoveOwnChannelMembership) | 場合による |
| グループを作成する | Create Channel(CreateChannel) | 通常はオン |
guest ユーザー(名前のみ/バックエンドを使わないサインイン)は user より制限が厳しくなります。アプリでゲスト認証を使う場合は、同じ権限を guest ロールにも追加する必要があります。インテグレーターには、ロールと messaging タイプの権限設定として Dashboard → Chat → Roles & Permissions(permissions v2)を案内するか、API/CLI 経由の UpdateChannelType を案内してください。詳細と正確なエラーメッセージについては、references/CHAT-FLUTTER.md → Channel permissions & roles を参照してください(カスタム UI のビルドでは references/CHAT-CORE.md)。
これは事前に伝えるための注意事項であり、実装を止めるものではありません。依頼どおりに機能を構築しつつ、初回実行時にグループの検索、参加、作成が気づかないまま失敗しないよう、同じターンで前提条件を伝えてください。
プロジェクトの状態確認(トラック A/B/D/M — セッションごとに 1 回。トラック C は必要な場合のみ)
読み取り専用のローカル確認です。ユーザーが Flutter プロジェクト内にいるか、空のディレクトリにいるかを判定するために使用します。
bash -c 'echo "=== FLUTTER ==="; find . -maxdepth 2 -name "pubspec.yaml" -print 2>/dev/null; echo "=== STREAM ==="; grep -rE "stream_chat|stream_video|stream_feed" . --include="pubspec.yaml" -l 2>/dev/null; echo "=== EMPTY ==="; test -z "$(ls -A 2>/dev/null)" && echo "EMPTY_CWD" || echo "NON_EMPTY"'
結果を会話のコンテキストに保持してください。ユーザーがディレクトリを変更した場合、またはプロジェクトの構成が明らかに変化した場合を除き、再実行しないでください。
結果を使って、次のような1 行のステータスを提示してください。
Flutter app detected - stream_chat_flutter already in pubspec.yamlFlutter app detected - stream_video_flutter already in pubspec.yamlFlutter app detected - stream_feed already in pubspec.yamlFlutter app detected - no Stream dependency yet, ready to installNo Flutter project found - empty directory
バージョンの前提条件(Chat - 既存プロジェクト)
Stream Chat の依存関係がすでに存在する場合は、解決されたバージョン(pubspec.yaml の制約または pubspec.lock の version:)を確認してください。**これらのスキルは stream_chat_flutter / stream_chat_flutter_core v10 のみを対象としています。**プロジェクトが 9.x 以前に固定されている場合は、コードを編集する前に作業を中止し、次のようにユーザーに伝えてください。
お使いのプロジェクトでは
stream_chat_flutterv が使用されています。この手順は v10 を対象としています。v9 と v10 の間では多くの変更(ウィジェット名、コントローラー、テーマ設定、リアクション/削除 API)がありました。公式の移行ガイドは https://github.com/GetStream/stream-chat-flutter/tree/master/migrations にあります。手順に沿って移行するには、該当するバージョンのガイドを参照してください。v10 になれば、すべての機能に対応できます。
ユーザーが移行自体のサポートを求めた場合は、上記 URL から該当する移行ドキュメントを取得し、手順を追って案内してください。
解決される依存関係が v10(^10.0.0)になってから、Chat の作業を進めてください。新規インストールでは常に ^10.0.0 を使用するため、この確認は既存の統合にのみ適用されます。
モジュールマップ
| トラック | モジュール |
|---|---|
| A - 新規アプリ | builder.md + sdk.md + 関連するリファレンスファイル |
| B - 既存アプリ | builder.md + sdk.md + 関連するリファレンスファイル |
| C - リファレンス検索 | sdk.md + 関連するリファレンスファイル |
| D - ブートストラップ/セットアップ | builder.md + sdk.md |
| M - Sendbird からの移行 | sendbird-migration.md(+ design-matching.md/custom-ui.md、sdk.md、../stream/sendbird-data-migration.md) |
| スタイリングの深さを示すフラグ(スクリーンショット/Figma/「〜のように」) | まず UI 戦略を選択してください(ステップ 0)。コンポーネントの場合は design-matching.md(手順部分全体、つまり # Reference 区切りより上。2 回の読み込みに分かれる場合があります。リファレンス部分は各領域ごとに参照)。独自 UI/ライブ配信/オーバーレイの場合は custom-ui.md を参照してください。トラック A/B では機能の作業に着手する前に実施してください。どちらの場合も、領域ごとに厳密に進め、検証ループを実施します。 |
フィードに関する注記(トラック A/B): デフォルトでは Twitter 風の UI を使用してください。ユーザーが別のスタイル(例:「Instagram のグリッド」「Reddit 風の投票」)を明示的に求めた場合のみ変更してください。
リファレンスの構成
Flutter/Dart 共通のパターンは sdk.md にあります。
製品やパッケージ固有の情報は、フラットな命名規則を使用して references/ 以下に配置します。
- リファレンス:
references/<PRODUCT>-<PACKAGE>.md - ブループリント:
references/<PRODUCT>-<PACKAGE>-blueprints.md
現在抽出済みのモジュール:
- チャット+事前構築済み UI(
stream_chat_flutter):references/CHAT-FLUTTER.md+references/CHAT-FLUTTER-blueprints.md - チャット+カスタム UI(
stream_chat_flutter_core):references/CHAT-CORE.md+references/CHAT-CORE-blueprints.md - チャットの高度な機能(プッシュ通知、オフライン、ライフサイクル — 両方の UI 層):
references/CHAT-ADVANCED-FLUTTER.md+references/CHAT-ADVANCED-FLUTTER-blueprints.md- プッシュ通知、オフライン/ローカル永続化、接続ライフサイクルとバックグラウンド化 - ビデオ(
stream_video_flutter):references/VIDEO-FLUTTER.md+references/VIDEO-FLUTTER-blueprints.md - ライブストリーミング(
stream_video_flutter):references/LIVESTREAM-FLUTTER.md+references/LIVESTREAM-FLUTTER-blueprints.md - ビデオの高度なユースケース(
stream_video_flutter):references/VIDEO-ADVANCED-FLUTTER.md+references/VIDEO-ADVANCED-FLUTTER-blueprints.md- オーディオルーム、複数人通話、チャット+ビデオ、ライブストリーミングフィード、クエリ/イベント/設定/モデレーション - 呼び出し音/着信+プッシュ通知(
stream_video_flutter+stream_video_push_notification):references/RINGING-FLUTTER.md+references/RINGING-FLUTTER-blueprints.md- 発信時の呼び出し音、フォアグラウンド/バックグラウンド/終了状態での着信、CallKit(iOS)+ FCM(Android) - フィード(
stream_feed/stream_feed_flutter_core):references/FEEDS-FLUTTER.md+references/FEEDS-FLUTTER-blueprints.md
Stream 製品の追加情報も、トップレベルのスキルを増やすのではなく、この命名規則に沿って配置してください。
トラック A - 新規アプリ
詳細: builder.md — 新規プロジェクトの手順を使用します。
| フェーズ | 名前 | 作業内容 |
|---|---|---|
| A1 | 検出 | プロジェクトのシグナルを確認します。Flutter アプリがまだない場合は、まず flutter create my_app を実行するようユーザーに伝えます。 |
| A2 | レーンを選択 | パッケージの選択を確認します。stream_chat_flutter(構築済み UI、最速)、stream_chat_flutter_core(カスタム UI)、stream_video_flutter(動画/ライブ配信)、または stream_feed / stream_feed_flutter_core(アクティビティフィード、構築済み UI なし)から選びます。Chat の場合、これはステップ 0 の「まず UI 戦略を選ぶ」と同じ、コンポーネントかカスタムかの判断です。デフォルトでは stream_chat_flutter を選択してください。Core を選ぶのは、メッセンジャーとは本質的に異なる UI の場合に限ります(custom-ui.md)。フィードの場合、デフォルトでは Twitter 風の UI を選びます。 |
| A3 | インストールと接続 | builder.md と sdk.md に従い、必要なリファレンスファイルだけを読み込みます。 |
| A4 | 検証 | flutter pub get が成功すること、クライアントが接続すること、最初の画面が描画されることを確認します。アプリでチャンネルを検索/参加する場合、またはゲスト認証を使用する場合は、権限の前提条件を再度伝えます(ステップ 0.5 → 権限の確認)。これにより、初回実行時にこれらのフローが 403 エラーにならないようにします。 |
トラック B - 既存アプリ
詳細: builder.md — 既存プロジェクトの手順を使用します。
| フェーズ | 名前 | 作業内容 |
|---|---|---|
| B1 | 検出 | プロジェクトのシグナルを確認し、編集前に既存アプリの構成を調べます。 |
| B2 | 維持 | ユーザーから変更の依頼がない限り、現在のナビゲーション、状態管理、ウィジェットのアーキテクチャを維持します。 |
| B3 | 統合 | 共通の接続には sdk.md を使用し、必要なリファレンスファイルだけを読み込みます。 |
| B4 | 検証 | 要求された Stream のフローが、既存アプリ内でビルドされ、描画されることを確認します。チャンネルを検索/参加する場合、またはゲスト認証を使用する場合は、権限の前提条件を再度伝えます(ステップ 0.5 → 権限の確認)。これにより、初回実行時にこれらのフローが 403 エラーにならないようにします。 |
トラック C - リファレンスの参照
要求されたパッケージに関連するファイルのみを読み込みます。
- 共通のライフサイクル/認証/状態/クライアント所有権のパターン ->
sdk.md - チャットの高度な本番環境向けの考慮事項 — プッシュ通知、オフライン/ローカル永続化、接続ライフサイクルとバックグラウンド処理(両方の UI 層) ->
references/CHAT-ADVANCED-FLUTTER.md - チャットの高度な配線ブループリント(FCM のセットアップとバックグラウンドハンドラー、永続化の初期化、遅延接続ゲート) ->
references/CHAT-ADVANCED-FLUTTER-blueprints.md - チャットの事前構築済み UI のセットアップ、ウィジェット、テーマ設定、メンバー/ユーザーリスト、メッセージ検索、コンポーザーのフラグ(音声/投票/下書き)、フィルター演算子、権限 ->
references/CHAT-FLUTTER.md - チャットの事前構築済み UI ウィジェットのブループリント ->
references/CHAT-FLUTTER-blueprints.md - チャットのカスタム UI のセットアップとコントローラー ->
references/CHAT-CORE.md - チャットのカスタム UI ウィジェットのブループリント ->
references/CHAT-CORE-blueprints.md - ビデオのセットアップ、通話タイプ、コントロール、状態、StreamCallContainer ->
references/VIDEO-FLUTTER.md - ビデオウィジェットのブループリント(エントリーポイント、参加、通話コンテナ、コントロール、参加者タイル) ->
references/VIDEO-FLUTTER-blueprints.md - ライブ配信 SDK のパターン(通話タイプ、バックステージ、goLive/stopLive、HLS) ->
references/LIVESTREAM-FLUTTER.md - ライブ配信ウィジェットのブループリント(モード選択、配信者、WebRTC 視聴者、HLS 視聴者) ->
references/LIVESTREAM-FLUTTER-blueprints.md - ビデオの高度なパターン(オーディオルーム、マルチコール、チャットとビデオの配線、queryCalls、通話イベント、設定、モデレーション、セッションタイマー、ネットワーク処理) ->
references/VIDEO-ADVANCED-FLUTTER.md - ビデオの高度なユースケースのブループリント(オーディオルーム画面、TikTok 風ライブ配信フィード、フローティング通話パネル、ビデオ通話付きチャット) ->
references/VIDEO-ADVANCED-FLUTTER-blueprints.md - 呼び出し SDK のパターン(プッシュ通知対応の初期化、発信時の呼び出し、フォアグラウンド/バックグラウンド/終了状態での着信、CallKit/FCM のセットアップ、応答/拒否/終了、カスタマイズ、不在着信) ->
references/RINGING-FLUTTER.md - 呼び出しのブループリント(プッシュ通知の初期化、バックグラウンド FCM ハンドラー、ホーム画面のオブザーバー、発信時の呼び出し、通話画面、iOS AppDelegate、Android manifest/Gradle) ->
references/RINGING-FLUTTER-blueprints.md - フィード SDK のセットアップ、StreamFeedClient、フィードタイプ、アクティビティ、リアクション、フォロー/フォロー解除、リアルタイム処理 ->
references/FEEDS-FLUTTER.md - フィードウィジェットのブループリント(デフォルトは Twitter 風:ホームフィード、アクティビティカード、投稿作成、プロフィール、通知。Instagram/Reddit 風のバリエーションもあります) ->
references/FEEDS-FLUTTER-blueprints.md
トラック D - ブートストラップ/セットアップ
機能を構築することよりも、インストールと配線の手順をユーザーが求めている場合に使用します。
- プロジェクトの構成を判別する
stream_chat_flutterとstream_chat_flutter_coreのどちらを使うか選択するpubspec.yamlに Stream の依存関係を追加し、flutter pub getを実行するsdk.mdに従ってStreamChatClientとStreamChatウィジェットを配線する- 選択したパッケージに必要なプラットフォームのセットアップ(Android の権限、iOS の Info.plist キー)を完了する
- ユーザーがセットアップのみを求めている場合は、製品固有の UI に進む前に止める
トラック M - Sendbird からの移行
詳細: sendbird-migration.md。移行は既存アプリを維持する統合型のため、Sendbird 固有の手順書を使うトラック B と同様に進めます。
| フェーズ | 名前 | 実施内容 |
|---|---|---|
| M1 | 検出 | プロジェクトのシグナルを実行し、Sendbird の使用箇所を grep して、各タッチポイントの形状を分類します(sendbird-migration.md §0)。Sendbird のベースラインを記録します(§0.5 の習慣 0)。コードを変更する前にソースアプリを実行し、Sendbird を使用する画面/バリエーションをすべてスクリーンショットに撮ります(アプリ全体ではなく、§0 のタッチポイントが対象)。リストとチャット、受信と送信の両方を撮影します。これらの画像が仕様になります。 |
| M2 | 置き換えと接続 | sendbird_chat_sdk/sendbird_uikit を削除して Stream パッケージを追加します。認証情報を取得し(Step 0.5)、既存のブートストラップのパブリック API を変更せずに参照先を切り替え、StreamChatClient と StreamChat プロバイダーを 1 つ接続します(§1~§2)。 |
| M3 | 再実装 | 各タッチポイントをパターンに沿って移行します。ビューとナビゲーション(§3)、チャンネル(§4)、メッセージとカスタム添付ファイル(§5)を移行し、2 つの軸に沿ってテーマを再適用します(§6、design-matching.md)。 |
| M4 | 検証 | すべての領域をベースラインと比較し、すべての操作を実行します(§0.5 の習慣 2~3 と design-matching.md の Step 5)。完了の判断基準はこの比較であり、ビルドの成功ではありません。 各領域をネイティブスケールでベースライン画像と照合します(既存の表示を維持する場合、見た目を一切変更しません)。ソースに実際にある操作(返信/編集からのコンポーザー表示、ピッカー、長押し、リアクション、スレッド)をデバイスで実行します。画面が描画されても、操作が機能しない場合があります。一致しない箇所は、具体的な阻害要因(API 名を明示した、根拠のある SDK API の不足)とともに報告し、Stream のデフォルトのまま黙ってリリースすることは避けます。Sendbird の依存関係がすべて削除されていることを確認します。 |
| M5 | データ移行を提案 | コードの移行がビルドでき、接続され、一致したら、Sendbird のデータも移行するか確認し、../stream/sendbird-data-migration.md(§10)に引き継ぎます。 |