HUB無効化(2026年10月2日、ユーザー指示による): NinjaBR Hubはクォータ切れで、
hub/hubv2/hubtsプロファイルは削除されました(バックアップは~/.agent-profiles/_removidos-hub-2026-10-02/にあります)。Hubを使用しないでください。hub-livre.shを実行しないでください(エラーで終了します)。Hubのプロファイルが解放されるのを待たないでください。画像:ChatGPT — アカウントのアップロードクォータが切れた場合は、gpt-noelia-7-10*↔gpt-noelia.empt*でアカウントを切り替えてください。動画:Google Flow(flow-video-playwright)。
flow-video-playwright は何をしますか?
画像+動画をGoogle Flow(labs.google/fx/pt/tools/flow)経由で生成するメカニクス。Hubの有効期限が切れた場合(2026年9月21日死亡、[[feedback-ninjabr-hub-acesso-expirado]]参照)の hub-video-playwright の代替です。
プロファイル
flow-enovalabs-pro(ポート9265)、Googleにログイン済み。時間を無駄にする前に、ブラウザで開いてログイン状態を確認してください:
agent-browser --session flow-enovalabs-pro navigate "https://labs.google/fx/pt/tools/flow"
ログイン画面が表示されたら、停止してユーザーに通知してください — 認証情報は .credentials.env にありません。
モデル
Omni 1.1 Flash — 2026年9月30日に本番環境で確認済み。Veo 3.1よりもクレジット消費が少ない。マルチモーダルで、画像と動画の両方をプロンプトのみ(アップロードなし)で生成します。
生成前に、設定(tuneボタン、aria-label「設定」)を開き、以下を確認してください:
- 生成前に確認する = しない(デフォルトは「常に」— クレジットを消費し、そのままにしておくと送信をブロックします)。
- デフォルトの動画生成モデル = Omni 1.1 Flash。
- 動画のアスペクト比 = crop_9_16 9:16(radio role="radio"、リスト内の2番目のcrop_9_16、現在のマッピングではインデックス10)。
保存します。
フロー(2026年10月1日確認済みのステップバイステップ)
- プロジェクトを作成:ダッシュボード → 「新規プロジェクト」ボタン → URLが
https://flow.google.com/project/<uuid>になります。 - コンポーザー:
[contenteditable=true]。クリップボード経由で貼り付け、innerTextは使用しないでください — 2026年10月1日測定:c.innerText = prompt; c.dispatchEvent(new InputEvent('input'))はテキストを貼り付けますが、「生成開始」ボタンがクリック時にdisabledになりません(Materialの「テキスト変更」ハンドラがトリガーされません)。2回クリックしても何も生成されません。- 正しい方法:
agent-browserのネイティブclipboard writeを使用し、その後コンポーザーでCtrl+A Ctrl+Vを実行:agent-browser --session flow-enovalabs-pro clipboard write "$PROMPT" agent-browser --session flow-enovalabs-pro click "[contenteditable=true]" agent-browser --session flow-enovalabs-pro press "Control+a" agent-browser --session flow-enovalabs-pro press "Control+v" - 送信前に
txtLen === prompt.lengthを確認してください。
- 送信:
click button[aria-label='生成開始']。ボタンがdisabled=trueになると = 送信受理。テキスト「キューに入りました」が表示され、その後「動画を概念化中」 / 「play_circle」 + パーセンテージが表示されます。 - 待機:ステータスが「動画を概念化中」(Flow)または「画像を作成中」(ChatGPT)に変わります。「停止」ボタンは生成中のみ表示されます。画像プロンプトのみで約50秒、動画の場合はそれ以上かかります。
- 結果:
<img src="blob:https://flow.google.com/...">が9:16の場合naturalWidth>800。fetch+blob+<a download>(ネイティブDOMリンク)でダウンロードします。
必須設定(初回送信前)
button[aria-label='設定'](tuneアイコン)を開く:
- 生成前に確認する = しない(ラジオグループ
mat-radio-group-2、value=2)。デフォルトは「常に」— クレジットを消費し、自動送信をブロックします。 - デフォルトの動画生成モデル = Omni 1.1 Flash(コンボボックス)。
- 動画のアスペクト比 = crop_9_16 9:16(button role="radio"、リスト内の2番目のcrop_9_16、インデックス10)。
input[type=radio]を直接操作してラジオボタンを設定します(mat-radio-buttonをクリックしても入力は反転しません):
// しない
const inputs = Array.from(document.querySelectorAll('input[type=radio]'));
inputs.find(r => r.closest('mat-radio-button')?.innerText.startsWith('しない')).click();
// 9:16動画(2番目のcrop_9_16)
const r916 = Array.from(document.querySelectorAll('button[role=radio]'))
.filter(b => b.innerText === 'crop_9_16\n9:16')[1];
r916.click();
// 保存
Array.from(document.querySelectorAll('button')).find(b => b.innerText?.trim() === '保存').click();
参照アップロード — 2026年9月30日ブロック済み
「メディアを追加」パネルの「メディアを送信」ボタンは、OSネイティブのファイルダイアログを開きます(CDP Page.fileChooserOpened、DOM内の<input type=file>ではありません)。agent-browser uploadは黙って失敗します。
回避策:プロンプトのみで生成します。OmniFlashはマルチモーダルで、説明的なプロンプトを解釈します。アップロードによる参照画像への忠実度は劣りますが、ファイルダイアログを回避できます。プロンプトのみで不十分な場合は、Page.setInterceptFileChooserを使用してbrowser-harnessをスケールアップします — 本番環境ではテストされていません。
プロンプトのみ — 基本テンプレート
A <ショットタイプ> shot of <構図>. <主語> doing <動作(単一、スロー)>.
<背景>. <照明>. Shot in vertical 9:16 aspect ratio. Photorealistic,
shot on iPhone, no text, no watermark. <アンチモーフィング>.
必須アンチモーフィング(FlowにはNEGATIVEフィールドが別途ないので、同じ文字列に含めます):
- "Hand never clips through the fabric"
- "Garment stays flat / never floats unsupported"
- "Single continuous motion, no jumping"
2026年9月30日確認:シーン1(女性の手がピンクのリブ生地を引っ張る、背景は白いベッド)がOmniFlashで約50秒で生成、出力941x1672、説得力のあるiPhone UGCルック。
ダウンロード(2026年10月1日確認)
動画はグリッドに<video>をレンダリングしません — モーダルでカードを開いた後にのみ表示されます。フロー:
- サムネイルをクリック(
img[alt="生成された動画のサムネイル"])— プレーヤーとヘッダーボタンがあるモーダルが開きます。 button[aria-label="メディアをダウンロード"]をクリック(ヘッダーのダウンロードアイコン)。- 品質メニューが開きます:270p(GIF)、720p(元のサイズ)、1080p(高品質)、4K(高品質)。
- 正しいオプションをDOMから直接クリック:
Array.from(document.querySelectorAll('button')) .find(b => b.innerText.trim() === '720p\n元のサイズ').click(); - ファイルは Flow タイトル名 + タイムスタンプ(
Hands_lifting_brown_skirt_fabric_20261001180016.mp4)で~/Downloads/に保存されます。プロジェクトのステージングディレクトリに移動し、名前を変更します。
画像の場合(動画なしで直接生成): <img src="blob:https://flow.google.com/..."> が生成後にグリッドに表示されます。fetch+blob+<a download> または直接スクリーンショットで保存します。
ダウンロード後の色ゲート
Flowからのメディアのほとんどは color_range/color_space/color_transfer/color_primaries = unknown で出力されます — 2026年10月1日にFlow Omni 1.1 Flashで確認済み。ゲート feedback-metadado-cor-video-final は不合格になります。クリップを準備完了としてマークする前に、bt709に再エンコードします:
ffmpeg -nostdin -i cena-1.mp4 \
-c:v libx264 -crf 18 -preset veryfast -pix_fmt yuv420p \
-x264-params "colorprim=bt709:transfer=bt709:colormatrix=bt709:fullrange=off" \
-color_primaries bt709 -color_trc bt709 -colorspace bt709 -color_range tv \
-c:a copy cena-1-fixed.mp4
mv cena-1-fixed.mp4 cena-1.mp4
ffprobe -show_entries stream=color_* で確認 — 4つのフィールドすべてが bt709/tv である必要があります。
Laneを取得する — 最初に、常に
複数のClaudeがこの同じブラウザを使用しています。Laneがないと、すべてが同じプロジェクトに落ちます:一方の「プロジェクト作成」が他方を上書きし、生成結果が混ざります。
~/.claude/bin/lane.sh take flow <lane> # 例:lane.sh take flow pov-bella
S=flow-<lane> # 今後すべてのコマンドで $S を使用
永続プロファイル ~/.agent-profiles/flow-enovalabs-pro、ポート9265、URL https://labs.google/fx/pt/tools/flow。決して agent-browser open を使用しないでください。press Escape も使用しないでください(タブを about:blank に送り、laneを壊します)。終了時:~/.claude/bin/lane.sh drop flow <lane>。
Flowのダウンロードエリアは FLOW であり、HUB や PLAYWRIGHT ではありません。最初に一度エクスポートします:
export LANE_AREA=FLOW
ファイルはFlowからタイトル名 + タイムスタンプ(例:Hands_lifting_brown_skirt_fabric_20261001180016.mp4)で出力され、~/Downloads/ に保存され、lane.sh collect が ~/Downloads/FLOW/$LANE/ → プロジェクトフォルダに移動します。何もDownloadsに放置されません。
送信チェックリスト — 「生成開始」をクリックする前に実行
Flowは生成間で何もクリアしません(Hubと同じ):コンポーザーのプロンプトが貼り付いたままになり、モデル/アスペクト比が送信後の再レンダリングでリセットされる可能性があります。以下の順序は、各ステップが適切でないと既にクレジットを消費した(無効な生成でも課金される)ために存在します。
1. 新しいプロジェクトを作成(または既存のものに切り替え)— 各バッチは新しいプロジェクトを使用します。 ダッシュボードの「新規プロジェクト」ボタン。URLが https://flow.google.com/project/<uuid> になります。古いプロジェクトを再利用すると、ゴミが蓄積され、ダウンロードの src 差分が混乱します(後述)。
2. 新しいプロジェクトのコンポーザーをクリア:
agent-browser --session $S click "[contenteditable=true]"
agent-browser --session $S press "Control+a"
agent-browser --session $S press "Delete"
確認:
echo '(()=>document.querySelector("[contenteditable=true]").textContent.length)()' \
| agent-browser --session $S eval --stdin # 0でなければなりません
3. 設定を確認: 「生成前に確認する」= しない、モデル = Omni 1.1 Flash、アスペクト比 = crop_9_16 9:16。スキルはデフォルトの間違った設定(常に + Liteモデル + 16:9)で開きます — 必須設定ブロックを参照してください。
4. クリップボード経由でプロンプトを書き込み(innerTextではなく)、確認 — 送信前に txtLen === prompt.length。詳細は以下のフローブロックを参照してください。
5. 送信し、コンポーザーがdisabledになったことを確認:
agent-browser --session $S click "button[aria-label='生成開始']"
sleep 2
echo '(()=>{const c=document.querySelector("[contenteditable=true]");return c.contentEditable==="false"||c.getAttribute("aria-disabled")==="true"?"ロック":"フリー";})()' \
| agent-browser --session $S eval --stdin
待機:3つの状態、3つの対応
送信後、ページ上のステータスは3つのフェーズを経ます。これらを混同すると、早期に中断して(クレジットを失う)か、待ちすぎて(既に完了しているのにスタックしたと思う)しまいます。
| 状態 | 画面のテキスト | 対応 |
|---|---|---|
| キュー | "X はスケジュールされ、需要が高いためキューに入れられました。数分後にステータスを確認してください。" | 待機。 1〜30分かかる場合があります。再送信しないでください。 |
| 生成中 | "動画を概念化中" + アイコン play_circle + パーセンテージ | 待機。 「停止」ボタンが表示されます。 |
| 完了 | カードに <img alt="生成された動画のサムネイル"> がグリッドに表示される | ダウンロード。 ダウンロードブロックを参照してください。 |
ハードリミット:キューで30分経過しても「生成中」に移行しない場合 = 中断。 2026年10月2日測定:Flowは flow-enovalabs-pro で「高需要」を45分間表示し、実際にステータスが変わったときには、ジョブは何も生成せずにクレジットを消費していました。症状:「高需要」が>30分続き、かつ前のコンポジションの「生成開始」ボタンが disabled=true のままロックされている — 実際のキューではなく、クォータロストです。
スタックした場合の回復手順:
# 1. 保留中のジョブをキャンセル(コンポーザーを解放して新しい送信を可能にする)
agent-browser --session $S click "button[aria-label='停止']" 2>/dev/null
sleep 2
# 2. コンポーザーがロック解除されない場合、ページ全体をリロード(現在のプロジェクトは失われます)
agent-browser --session $S navigate "https://labs.google/fx/pt/tools/flow"
# 3. 並列クローンを試す
S=flow-<lane>-2 # または -3, -4
flow-enovalabs-pro-2/3/4もログイン済みでキューにある場合は、並列で使用します(FlowはHubとは異なり、同じログインの複数のプロファイルを許可します)。ログイン確認:lane.sh take flow <lane> && agent-browser --session $S navigate "https://labs.google/fx/pt/tools/flow" — ログインを要求せずにダッシュボードに表示されればOKです。
短いポーリング、寛大な上限:
T0=$(date +%s)
for i in $(seq 1 360); do # 30分 × 6 = 360 × 5秒
STATE=$(echo '(()=>{const txt=document.body.innerText;
if(/需要が高い|alta demanda/i.test(txt)) return "キュー";
if(/概念化|Criando/i.test(txt)) return "生成中";
const imgs=document.querySelectorAll("img[alt=\\"生成された動画のサムネイル\\"]").length;
if(imgs>0) return "完了";
return "?")()' \
| agent-browser --session $S eval --stdin | tr -d '"' | tail -1)
echo " [$(( $(date +%s)-T0 ))s] $STATE"
[ "$STATE" = "完了" ] && break
[ "$STATE" = "?" ] && [ $i -gt 6 ] && { echo "中断:状態なしでコンポーザーロック"; break; }
sleep 5
done
コンテンツによるダウンロード — 以前を保存し、新しいものを選択
vs[vs.length-1] はFlowには存在しません(グリッドに<video>はありません)。Flowはグリッドにサムネイル(<img alt="生成された動画のサムネイル">)をレンダリングします。実際の動画は、モーダルでカードを開き、「メディアをダウンロード」をクリックした後にのみ表示されます。したがって、ダウンロード方法はHubとは異なります:
1. 送信の前に、既存のサムネイルのリストを保存します:
BEFORE=$(echo '(()=>[...document.querySelectorAll("img[alt=\\"生成された動画のサムネイル\\"]")].map(i=>i.src).join("|"))()' \
| agent-browser --session $S eval --stdin | tr -d '"')
2. その後、完了 になったら、新しいサムネイルを見つけます:
AFTER=$(echo '(()=>[...document.querySelectorAll("img[alt=\\"生成された動画のサムネイル\\"]")].map(i=>i.src).join("|"))()' \
| agent-browser --session $S eval --stdin | tr -d '"')
NEW=$(python3 -c "import sys;a=set('$AFTER'.split('|'));b=set('$BEFORE'.split('|'));print('|'.join(a-b))")
NEW が空の場合は、カードがまだ表示されていません — さらに10〜30秒待って再試行してください。
3. 新しいカードのモーダルを開き、720pをダウンロード:
# 新しいサムネイルをクリック
python3 -c "
import sys
srcs='$NEW'.split('|')
print('(()=>{const imgs=[...document.querySelectorAll(\"img[alt=\\\"生成された動画のサムネイル\\\"]\")];'
'const t=imgs.find(i=>i.src===\\